* [PATCH RFC] xfrm: Don't queue retransmitted packets if the original is still on the host
From: Steffen Klassert @ 2013-10-16 11:42 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <20131016094549.GZ7660@secunet.com>
It does not make sense to queue retransmitted packets if the
original packet is still in some queue of this host. So add
a check to xdst_queue_output() and drop the packet if the
original packet is not yet sent.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_policy.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ed38d5d..e09edfc 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1832,6 +1832,13 @@ static int xdst_queue_output(struct sk_buff *skb)
struct dst_entry *dst = skb_dst(skb);
struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
struct xfrm_policy_queue *pq = &xdst->pols[0]->polq;
+ const struct sk_buff *fclone = skb + 1;
+
+ if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
+ fclone->fclone == SKB_FCLONE_CLONE)) {
+ kfree_skb(skb);
+ return 0;
+ }
if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) {
kfree_skb(skb);
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH 2/2] be2net: drop non-tso frames longer than mtu
From: Sathya Perla @ 2013-10-16 12:08 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev@vger.kernel.org
In-Reply-To: <1381844840.2045.37.camel@edumazet-glaptop.roam.corp.google.com>
> -----Original Message-----
> From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
> >
> > Pktgen can generate non-TSO frames of arbitrary length disregarding
> > the MTU value of the physical interface. Drop such frames in the driver
> > instead of sending them to HW as it cannot handle such frames.
> >
> > Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com>
> > Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
> > ---
> > drivers/net/ethernet/emulex/benet/be_main.c | 9 +++++++--
> > 1 files changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/emulex/benet/be_main.c
> b/drivers/net/ethernet/emulex/benet/be_main.c
> > index 2c38cc4..76057b8 100644
> > --- a/drivers/net/ethernet/emulex/benet/be_main.c
> > +++ b/drivers/net/ethernet/emulex/benet/be_main.c
> > @@ -855,6 +855,13 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter
> *adapter,
> > unsigned int eth_hdr_len;
> > struct iphdr *ip;
> >
> > + /* Don't allow non-TSO packets longer than MTU */
> > + eth_hdr_len = (ntohs(skb->protocol) == ETH_P_8021Q) ?
> > + VLAN_ETH_HLEN : ETH_HLEN;
> > + if (!skb_is_gso(skb) &&
> > + (skb->len - eth_hdr_len) > adapter->netdev->mtu)
> > + goto tx_drop;
> > +
>
> When you say 'cannot handle them', is it some kind of nasty thing like
> hang / crash ?
This chip goes into an unrecoverable error state (needing a server reboot to rectify.)
>
> One could imagine gso_size + sizeof(headers) > mtu, and give the same
> problem ?
Won't the mss (gso_size) value for TCP pkts be derived from the mtu of the out-going interface?
In that case when will gso_size + headers > mtu?
In any case, for TSO pkts, the HW just drops pkts when frames after segmentation
are longer than 9018bytes (or in recent FW versions 9200b)
>
>
> AFAIK, we have no check in net/core/dev.c.
>
> Maybe we should instead add them there (and in pktgen)
I agree; doing this will solve issues with any other drivers/devices if they have a similar problem.
thanks,
-Sathya
^ permalink raw reply
* Re: [PATCH ipsec] xfrm: prevent ipcomp scratch buffer race condition
From: Herbert Xu @ 2013-10-16 12:32 UTC (permalink / raw)
To: Michal Kubecek; +Cc: Steffen Klassert, David S. Miller, netdev
In-Reply-To: <20131014160334.BCCDDE8A31@unicorn.suse.cz>
On Mon, Oct 14, 2013 at 06:03:34PM +0200, Michal Kubecek wrote:
> In ipcomp_compress(), sortirq is enabled too early, allowing the
> per-cpu scratch buffer to be rewritten by ipcomp_decompress()
> (called on the same CPU in softirq context) between populating
> the buffer and copying the compressed data to the skb.
Good catch.
> Add similar protection into ipcomp_decompress() as it can be
> called from process context as well (even if such scenario seems
> a bit artificial).
I don't think this is possible or otherwise xfrm_input will
dead-lock.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] net/ethernet: cpsw: Bugfix interrupts before enabling napi
From: Mugunthan V N @ 2013-10-16 12:58 UTC (permalink / raw)
To: Markus Pargmann, David S. Miller
Cc: kernel, netdev, Peter Korsgaard, Florian Fainelli,
linux-arm-kernel
In-Reply-To: <1381691821-25498-1-git-send-email-mpa@pengutronix.de>
On Monday 14 October 2013 12:47 AM, Markus Pargmann wrote:
> If interrupts happen before napi_enable was called, the driver will not
> work as expected. Network transmissions are impossible in this state.
> This bug can be reproduced easily by restarting the network interface in
> a loop. After some time any network transmissions on the network
> interface will fail.
>
> This patch fixes the bug by enabling napi before enabling the network
> interface interrupts.
>
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Regards
Mugunthan V N
^ permalink raw reply
* Re: [Xen-devel] DomU's network interface will hung when Dom0 running 32bit
From: jianhai luan @ 2013-10-16 13:08 UTC (permalink / raw)
To: annie li; +Cc: Wei Liu, xen-devel, Ian Campbell, netdev
In-Reply-To: <525E5EDF.4030904@oracle.com>
On 2013-10-16 17:39, annie li wrote:
>
> On 2013-10-16 15:35, jianhai luan wrote:
>>
>> On 2013-10-15 20:58, Wei Liu wrote:
>>> On Tue, Oct 15, 2013 at 07:26:31PM +0800, jianhai luan wrote:
>>> [...]
>>>>>>> Can you propose a patch?
>>>>>> Because credit_timeout.expire always after jiffies, i judge the
>>>>>> value over the range of time_after_eq() by time_before(now,
>>>>>> vif->credit_timeout.expires). please check the patch.
>>>>> I don't think this really fix the issue for you. You still have
>>>>> chance
>>>>> that now wraps around and falls between expires and next_credit.
>>>>> In that
>>>>> case it's stalled again.
>>>> if time_before(now, vif->credit_timeout.expires) is true, time wrap
>>>> and do operation. Otherwise time_before(now,
>>>> vif->credit_timeout.expires) isn't true, now -
>>>> vif->credit_timeout.expires should be letter than ULONG_MAX/2.
>>>> Because next_credit large than vif->credit_timeout.expires
>>>> (next_crdit = vif->credit_timeout.expires +
>>>> msecs_to_jiffies(vif->credit_usec/1000)), the delta between now and
>>>> next_credit should be in range of time_after_eq(). So
>>>> time_after_eq() do correctly judge.
>>>>
>>> Not sure I understand you. Consider "now" is placed like this:
>>>
>>> expires now next_credit
>>> ----time increases this direction--->
>>>
>>> * time_after_eq(now, next_credit) -> false
>>> * time_before(now, expires) -> false
>>>
>>> Then it's stuck again. You're merely narrowing the window, not fixing
>>> the real problem.
>>
>> The above environment isn't stack again. The netback will pending one
>> timer to process the environment.
>>
>> The attachment program will prove if !(time_after_eq(now,
>> next_credit) || time_before(now, vif->credit_timeout.expires)), now
>> will only be placed in above environment [ expires next_credit), and
>> the above environment will be processed by timer in soon.
>
> Or check following to see what the if condition really do,
>
> ----------expires-------now-------credit---------- is the only case
> where we need to add a timer.
>
> Other cases like following would match the if condition above, then no
> timer is added.
> ----------expires----------credit------now------
> -----now-----expires----------credit----------
>
> Or we can consider the extreme condition, when the rate control does
> not exist, "credit_usec" is zero, and "next_credit" is equal to
> "expires". The above if condition would cover all conditions, and no
> rate control really happens. If credit_usec is not zero, the "if
> condition" would cover the range outside of that from expires to
> next_credit.
>
> Even if "now" is wrapped again into the range from "expires" to
> "next_credit", the "next_credit" that is set in __mod_timer is
> reasonable value(this can be gotten from credit_usec), and the timer
> would be hit soon.
Thanks Annie's express, my option is consistent with Annie.
Jason
>
> Thanks
> Annie
>>>
>>> Wei.
>>>
>>>> Jason
>>>>> Wei.
>> Jason.
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> http://lists.xen.org/xen-devel
>
^ permalink raw reply
* Re: [PATCH v4 net 1/3] net: dst: provide accessor function to dst->xfrm
From: Neil Horman @ 2013-10-16 13:31 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, linux-sctp, fan.du
In-Reply-To: <1381888891-31186-2-git-send-email-vyasevich@gmail.com>
On Tue, Oct 15, 2013 at 10:01:29PM -0400, Vlad Yasevich wrote:
> dst->xfrm is conditionally defined. Provide accessor funtion that
> is always available.
>
> Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
> ---
> include/net/dst.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/include/net/dst.h b/include/net/dst.h
> index 3bc4865..3c4c944 100644
> --- a/include/net/dst.h
> +++ b/include/net/dst.h
> @@ -479,10 +479,22 @@ static inline struct dst_entry *xfrm_lookup(struct net *net,
> {
> return dst_orig;
> }
> +
> +static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
> +{
> + return NULL;
> +}
> +
> #else
> extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
> const struct flowi *fl, struct sock *sk,
> int flags);
> +
> +/* skb attached with this dst needs transformation if dst->xfrm is valid */
> +static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
> +{
> + return dst->xfrm;
> +}
> #endif
>
> #endif /* _NET_DST_H */
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [PATCH v4 net 2/3] sctp: Use software crc32 checksum when xfrm transform will happen.
From: Neil Horman @ 2013-10-16 13:32 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, linux-sctp, fan.du, Steffen Klassert
In-Reply-To: <1381888891-31186-3-git-send-email-vyasevich@gmail.com>
On Tue, Oct 15, 2013 at 10:01:30PM -0400, Vlad Yasevich wrote:
> From: Fan Du <fan.du@windriver.com>
>
> igb/ixgbe have hardware sctp checksum support, when this feature is enabled
> and also IPsec is armed to protect sctp traffic, ugly things happened as
> xfrm_output checks CHECKSUM_PARTIAL to do checksum operation(sum every thing
> up and pack the 16bits result in the checksum field). The result is fail
> establishment of sctp communication.
>
> Cc: Neil Horman <nhorman@tuxdriver.com>
> Cc: Steffen Klassert <steffen.klassert@secunet.com>
> Signed-off-by: Fan Du <fan.du@windriver.com>
> Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
> ---
> net/sctp/output.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/sctp/output.c b/net/sctp/output.c
> index 0ac3a65..d35b54c 100644
> --- a/net/sctp/output.c
> +++ b/net/sctp/output.c
> @@ -536,7 +536,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
> * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
> */
> if (!sctp_checksum_disable) {
> - if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) {
> + if (!(dst->dev->features & NETIF_F_SCTP_CSUM) ||
> + (dst_xfrm(dst) != NULL)) {
> __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
>
> /* 3) Put the resultant value into the checksum field in the
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [PATCH v4 net 3/3] sctp: Perform software checksum if packet has to be fragmented.
From: Neil Horman @ 2013-10-16 13:34 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, linux-sctp, fan.du
In-Reply-To: <1381888891-31186-4-git-send-email-vyasevich@gmail.com>
On Tue, Oct 15, 2013 at 10:01:31PM -0400, Vlad Yasevich wrote:
> IP/IPv6 fragmentation knows how to compute only TCP/UDP checksum.
> This causes problems if SCTP packets has to be fragmented and
> ipsummed has been set to PARTIAL due to checksum offload support.
> This condition can happen when retransmitting after MTU discover,
> or when INIT or other control chunks are larger then MTU.
> Check for the rare fragmentation condition in SCTP and use software
> checksum calculation in this case.
>
> CC: Fan Du <fan.du@windriver.com>
> Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
> ---
> net/sctp/output.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/sctp/output.c b/net/sctp/output.c
> index d35b54c..3191373 100644
> --- a/net/sctp/output.c
> +++ b/net/sctp/output.c
> @@ -537,7 +537,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
> */
> if (!sctp_checksum_disable) {
> if (!(dst->dev->features & NETIF_F_SCTP_CSUM) ||
> - (dst_xfrm(dst) != NULL)) {
> + (dst_xfrm(dst) != NULL) || packet->ipfragok) {
> __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
>
> /* 3) Put the resultant value into the checksum field in the
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [Xen-devel] DomU's network interface will hung when Dom0 running 32bit
From: Wei Liu @ 2013-10-16 13:47 UTC (permalink / raw)
To: jianhai luan; +Cc: annie li, Wei Liu, xen-devel, Ian Campbell, netdev
In-Reply-To: <525E8FB3.8000606@oracle.com>
On Wed, Oct 16, 2013 at 09:08:03PM +0800, jianhai luan wrote:
[...]
> >>>
> >>> expires now next_credit
> >>> ----time increases this direction--->
> >>>
> >>>* time_after_eq(now, next_credit) -> false
> >>>* time_before(now, expires) -> false
> >>>
> >>>Then it's stuck again. You're merely narrowing the window, not fixing
> >>>the real problem.
> >>
> >>The above environment isn't stack again. The netback will
> >>pending one timer to process the environment.
> >>
> >>The attachment program will prove if !(time_after_eq(now,
> >>next_credit) || time_before(now, vif->credit_timeout.expires)),
> >>now will only be placed in above environment [ expires
> >>next_credit), and the above environment will be processed by
> >>timer in soon.
> >
> >Or check following to see what the if condition really do,
> >
> >----------expires-------now-------credit---------- is the only
> >case where we need to add a timer.
> >
> >Other cases like following would match the if condition above,
> >then no timer is added.
> >----------expires----------credit------now------
> >-----now-----expires----------credit----------
> >
> >Or we can consider the extreme condition, when the rate control
> >does not exist, "credit_usec" is zero, and "next_credit" is equal
> >to "expires". The above if condition would cover all conditions,
> >and no rate control really happens. If credit_usec is not zero,
> >the "if condition" would cover the range outside of that from
> >expires to next_credit.
> >
> >Even if "now" is wrapped again into the range from "expires" to
> >"next_credit", the "next_credit" that is set in __mod_timer is
> >reasonable value(this can be gotten from credit_usec), and the
> >timer would be hit soon.
>
> Thanks Annie's express, my option is consistent with Annie.
>
OK, thanks for the explanation. I think I get the idea.
In any case, could you use !time_in_range / !time_in_range_open instead
of open coded one-liner? Though I presume one-liner open coding would
not hurt.
Wei.
^ permalink raw reply
* RE: [PATCH 2/2] be2net: drop non-tso frames longer than mtu
From: Eric Dumazet @ 2013-10-16 13:54 UTC (permalink / raw)
To: Sathya Perla; +Cc: netdev@vger.kernel.org
In-Reply-To: <CF9D1877D81D214CB0CA0669EFAE020C26A2A3A4@CMEXMB1.ad.emulex.com>
On Wed, 2013-10-16 at 12:08 +0000, Sathya Perla wrote:
> Won't the mss (gso_size) value for TCP pkts be derived from the mtu of the out-going interface?
> In that case when will gso_size + headers > mtu?
Not on forwarding :(
Let see we have two ethernet devices, with different mtu : 1500 and 1400
GRO could aggregate GRO packets with MSS=1460 (gso_size=1460), then
we hapilly send this GSO packet to the other device, and apparently we
have no check against the lower mtu.
In the best case GRO packet is lost, but in some other cases, the device
hangs...
> In any case, for TSO pkts, the HW just drops pkts when frames after segmentation
> are longer than 9018bytes (or in recent FW versions 9200b)
^ permalink raw reply
* Re: [RFC] bridge and friends: reduce TheLinuxWay(tm)
From: Jamal Hadi Salim @ 2013-10-16 13:54 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Stephen Hemminger, Vlad Yasevich, netdev@vger.kernel.org
In-Reply-To: <20131014144156.6dc52a78@nehalam.linuxnetplumber.net>
On 10/14/13 17:41, Stephen Hemminger wrote:
> Unfortunately, by now this is all set in ABI.
> It was a side effect of the per-feature evolutionary style of development.
Sadly, I agree. This is the dark side of "have code will travel";
you let these things out in the wild, they breed and you cant
take them back.
BTW: I dont think what i suggested will be a harmful refactoring because
no existing interfaces are removed - your call.
In similar vein:
What is the motivation behind IFLA_EXT_MASK? Could you not have used
ifm ifindex to relay the interface of interest? Currently the ifindex is
not used at all. IMO, the following interfaces are useful:
- get attributes for all bridge ports (this is there)
- get attributes for bridge interface XXX; there using IFLA_EXT_MASK
I think it should be using ifm->ifindex
- get attributes for all bridge ports for bridge br-blah (not there)
you could also use the ifindex of br-blah here instead
Separate issue:
To provide equivalence to brctl:
- PF_BRIDGE should allow me to attach a bridge port to bridge of choice
with SETLINK
cheers,
jamal
^ permalink raw reply
* Re: [RFC] bridge and friends: reduce TheLinuxWay(tm)
From: Jamal Hadi Salim @ 2013-10-16 14:05 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Stephen Hemminger, Vlad Yasevich, netdev@vger.kernel.org
In-Reply-To: <525E9AB1.6090502@mojatatu.com>
On 10/16/13 09:54, Jamal Hadi Salim wrote:
> - get attributes for bridge interface XXX; there using IFLA_EXT_MASK
> I think it should be using ifm->ifindex
No this doesnt work. Filtering needs to be done in user space ;-<
IMO: The behavior here should be no different then when getting a link.
Will you accept a patch for this?
cheers,
jamal
^ permalink raw reply
* Re: [RFC net-next] ipv6: Use destination address determined by IPVS
From: Hannes Frederic Sowa @ 2013-10-16 14:32 UTC (permalink / raw)
To: Julian Anastasov
Cc: Simon Horman,
YOSHIFUJI Hideaki / 吉藤英明, lvs-devel,
netdev, Mark Brooks
In-Reply-To: <alpine.LFD.2.03.1310161015550.1560@ssi.bg>
On Wed, Oct 16, 2013 at 10:27:47AM +0300, Julian Anastasov wrote:
>
> Hello,
>
> On Wed, 16 Oct 2013, Simon Horman wrote:
>
> > In v3.9 6fd6ce2056de2709 ("ipv6: Do not depend on rt->n in
> > ip6_finish_output2()") changed the behaviour of ip6_finish_output2()
> > such that it creates and uses a neigh entry if none is found.
> > Subsequently the 'n' field was removed from struct rt6_info.
>
> Similar change in IPv4 opened the Pandora box:
> IPVS, xt_TEE, raw.c (IP_HDRINCL). May be the corrsponding
> places in IPv6 have the same problem.
>
> I don't know the IPv6 routing but if we find a way
> to keep the desired nexthop in rt6i_gateway and to add
> RTF_GATEWAY checks here and there such solution would be more
> general. FLOWI_FLAG_KNOWN_NH flag can help, if needed.
I thought about this yesterday but did not see an easy way. How does the IPv4
implementation accomplish this?
ipvs caches the dst in its own infrastructure, so we need to be sure we don't
disconnect this dst from the ipv6 routing table, otherwise ip6_dst_check won't
recognize when relookups should be done. Playing games with RTF_GATEWAY seems
dangerous then.
I am currently thinking about using a new flag to replace the nexthop
information with rt6i_dst in these circumstances. The flag would have
to be included in the skb somewhere.
Greetings,
Hannes
^ permalink raw reply
* [PATCH: Iproute bridge] remove redundant check
From: Jamal Hadi Salim @ 2013-10-16 14:33 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 26 bytes --]
attached,
cheers,
jamal
[-- Attachment #2: patch-simp1 --]
[-- Type: text/plain, Size: 1038 bytes --]
commit 355c2d4679e81c1e1c2ae12e03b6a2ced5ebb7d0
Author: Jamal Hadi Salim <jhs@mojatatu.com>
Date: Wed Oct 16 10:30:01 2013 -0400
[Iproute: bridge] Remove redundant check
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
diff --git a/bridge/link.c b/bridge/link.c
index 38dfaea..ab4a5d5 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -271,7 +271,7 @@ static int brlink_modify(int argc, char **argv)
exit(-1);
} else if (strcmp(*argv, "hairpin") == 0) {
NEXT_ARG();
- if (!on_off("hairping", &hairpin, *argv))
+ if (!on_off("hairpin", &hairpin, *argv))
exit(-1);
} else if (strcmp(*argv, "fastleave") == 0) {
NEXT_ARG();
@@ -357,9 +357,7 @@ static int brlink_modify(int argc, char **argv)
nest = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);
addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags);
-
- if (mode >= 0)
- addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode);
+ addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode);
addattr_nest_end(&req.n, nest);
}
^ permalink raw reply related
* Re: [PATCH net v2] be2net: Warn users of possible broken functionality on BE2 cards with very old FW versions with latest driver
From: Ivan Vecera @ 2013-10-16 14:59 UTC (permalink / raw)
To: somnath.kotur; +Cc: David Miller, netdev
In-Reply-To: <20131007.123116.1462434377931881914.davem@davemloft.net>
On 10/07/2013 06:31 PM, David Miller wrote:
> From: Somnath Kotur <somnath.kotur@emulex.com>
> Date: Thu, 3 Oct 2013 15:34:29 +0530
>
>> + if (BE2_chip(adapter) && memcmp(adapter->fw_ver, "4.", 2) < 0) {
>> + dev_err(dev, "Firmware version is too old.IRQs may not work\n");
>
> So many grammatical mistakes in one line.
>
> First sentence got a period, second one did not.
>
> Missing space between period and second sentence.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Som, any plan to send v3?
Ivan
^ permalink raw reply
* Re: [Xen-devel] DomU's network interface will hung when Dom0 running 32bit
From: jianhai luan @ 2013-10-16 15:04 UTC (permalink / raw)
To: Wei Liu; +Cc: annie li, xen-devel, Ian Campbell, netdev
In-Reply-To: <20131016134740.GG16371@zion.uk.xensource.com>
[-- Attachment #1: Type: text/plain, Size: 2170 bytes --]
On 2013-10-16 21:47, Wei Liu wrote:
> On Wed, Oct 16, 2013 at 09:08:03PM +0800, jianhai luan wrote:
> [...]
>>>>> expires now next_credit
>>>>> ----time increases this direction--->
>>>>>
>>>>> * time_after_eq(now, next_credit) -> false
>>>>> * time_before(now, expires) -> false
>>>>>
>>>>> Then it's stuck again. You're merely narrowing the window, not fixing
>>>>> the real problem.
>>>> The above environment isn't stack again. The netback will
>>>> pending one timer to process the environment.
>>>>
>>>> The attachment program will prove if !(time_after_eq(now,
>>>> next_credit) || time_before(now, vif->credit_timeout.expires)),
>>>> now will only be placed in above environment [ expires
>>>> next_credit), and the above environment will be processed by
>>>> timer in soon.
>>> Or check following to see what the if condition really do,
>>>
>>> ----------expires-------now-------credit---------- is the only
>>> case where we need to add a timer.
>>>
>>> Other cases like following would match the if condition above,
>>> then no timer is added.
>>> ----------expires----------credit------now------
>>> -----now-----expires----------credit----------
>>>
>>> Or we can consider the extreme condition, when the rate control
>>> does not exist, "credit_usec" is zero, and "next_credit" is equal
>>> to "expires". The above if condition would cover all conditions,
>>> and no rate control really happens. If credit_usec is not zero,
>>> the "if condition" would cover the range outside of that from
>>> expires to next_credit.
>>>
>>> Even if "now" is wrapped again into the range from "expires" to
>>> "next_credit", the "next_credit" that is set in __mod_timer is
>>> reasonable value(this can be gotten from credit_usec), and the
>>> timer would be hit soon.
>> Thanks Annie's express, my option is consistent with Annie.
>>
> OK, thanks for the explanation. I think I get the idea.
>
> In any case, could you use !time_in_range / !time_in_range_open instead
> of open coded one-liner? Though I presume one-liner open coding would
> not hurt.
I agree above the suggest. The attachment patch may be better than
previous patch.
Jason
>
> Wei.
[-- Attachment #2: 0001-xen-netback-pending-timer-only-in-the-range-expire-n.patch --]
[-- Type: text/plain, Size: 1627 bytes --]
>From ef02403a10173896c5c102f768741d0700b8a3a2 Mon Sep 17 00:00:00 2001
From: Jason Luan <jianhai.luan@oracle.com>
Date: Tue, 15 Oct 2013 17:07:49 +0800
Subject: [PATCH] xen-netback: pending timer only in the range [expire,
next_credit)
The function time_after_eq() do correct judge in range of MAX_UNLONG/2.
If net-front send lesser package, the delta between now and next_credit
will out of the range and time_after_eq() will do wrong judge in result
to net-front hung. For example:
expire next_credit .... next_credit+MAX_UNLONG/2 now
-----------------time increases this direction----------------->
We should be add the environment which now beyond next_credit+MAX_UNLONG/2.
Because the fact now mustn't before expire, time_before(now, expire) == true
will show the environment.
time_after_eq(now, next_credit) || time_before (now, expire)
==
!time_in_range_open(now, expire, next_credit)
Signed-off-by: Jason Luan <jianhai.luan@oracle.com>
---
drivers/net/xen-netback/netback.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index f3e591c..62492f0 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1195,7 +1195,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
return true;
/* Passed the point where we can replenish credit? */
- if (time_after_eq(now, next_credit)) {
+ if (!time_in_range(now, vif->credit_timeout.expires, next_credit)) {
vif->credit_timeout.expires = now;
tx_add_credit(vif);
}
--
1.7.6.5
^ permalink raw reply related
* Re: SW csum errors
From: Kyle Hubert @ 2013-10-16 15:10 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20131014135859.74f38507@nehalam.linuxnetplumber.net>
On Mon, Oct 14, 2013 at 4:58 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Mon, 14 Oct 2013 16:13:15 -0400
> Kyle Hubert <khubert@gmail.com> wrote:
>
>> My problem is rather specific. I am working on an RDMA device, and we
>> have full end to end reliability. However, one of the initial spins of
>> our chip had some errors, since fixed, where the csum was unreliable.
>> So, we did exactly what Dave Miller warned not to do in the linked
>> message. We ran outgoing IP packets through the SKB checksum
>> function.. Unfortunately, we occasionally saw NFS csum errors on full
>> MTU packets.
>>
>> Here is his response:
>>
>> http://marc.info/?l=linux-netdev&m=128286758300676&w=2
>>
>> Relevant portion:
>>
>> "
>> Paged SKBs can have references to page cache pages and similar. These
>> can be updated asynchronously to the transmit, there is no locking at
>> all to freeze the contents, and therefore full checksum offload is
>> required to support SG correctly.
>>
>> So don't get the idea to do the checksum in software in the infiniband
>> layer, and advertize hw checksumming support, to get around this :-)
>> "
>>
>> Now that those chips have long gone, I am left pondering about these
>> packets "corrupted" before the device transfers them. Can I get more
>> information about these paged SKBs with asynchronous modifications?
>> How does NFS use them?
>
> You would have to either mark the pages as copy on write or copy the data.
> Setting COW is expensive because you have to coordinate with other CPU's
> on SMP. Not sure exactly how.
>
> You can demonstrate this with either sendfile() or NFS where underlying
> file contents are being modified while packet is in the queue.
Thanks, I didn't realize it was as simple as file backed pages being
changed. Yes, our device does support SG, so we do have zero-copy
sendfile() support. I'll concoct a simple test to prove this.
-Kyle
^ permalink raw reply
* Re: [PATCH net-next] {selinux, af_key} Rework pfkey_sadb2xfrm_user_sec_ctx
From: Paul Moore @ 2013-10-16 15:15 UTC (permalink / raw)
To: Fan Du; +Cc: steffen.klassert, davem, netdev
In-Reply-To: <1381904114-29556-1-git-send-email-fan.du@windriver.com>
On Wednesday, October 16, 2013 02:15:14 PM Fan Du wrote:
> Taking advantages of sadb_x_sec_ctx and xfrm_user_sec_ctx share the same
> structure arrangement, rework pfkey_sadb2xfrm_user_sec_ctx by casting
> sadb_x_sec_ctx into xfrm_user_sec_ctx with minor len fix.
>
> Then we can:
> -Avoid kmalloc/free memory for xfrm_user_sec_ctx, sadb_x_sec_ctx would be
> fine.
> -Fix missing return value check bug for pfkey_compile_policy when
> kmalloc fails
>
> Signed-off-by: Fan Du <fan.du@windriver.com>
> ---
> net/key/af_key.c | 33 +--------------------------------
> 1 file changed, 1 insertion(+), 32 deletions(-)
>
> diff --git a/net/key/af_key.c b/net/key/af_key.c
> index 9d58537..c7d304d 100644
> --- a/net/key/af_key.c
> +++ b/net/key/af_key.c
> @@ -435,22 +435,9 @@ static inline int verify_sec_ctx_len(const void *p)
>
> static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(const
> struct sadb_x_sec_ctx *sec_ctx) {
> - struct xfrm_user_sec_ctx *uctx = NULL;
> - int ctx_size = sec_ctx->sadb_x_ctx_len;
> -
> - uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
> -
> - if (!uctx)
> - return NULL;
> + struct xfrm_user_sec_ctx *uctx = (struct xfrm_user_sec_ctx *)sec_ctx;
>
> uctx->len = pfkey_sec_ctx_len(sec_ctx);
> - uctx->exttype = sec_ctx->sadb_x_sec_exttype;
> - uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi;
> - uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg;
> - uctx->ctx_len = sec_ctx->sadb_x_ctx_len;
> - memcpy(uctx + 1, sec_ctx + 1,
> - uctx->ctx_len);
> -
> return uctx;
> }
The fact that you are now changing sadb_x_sec_ctx->sadb_x_sec_len whenever
pfkey_sadb2xfrm_user_sec_ctx() is called raises an eyebrow. Can you elaborate
on why this is not a problem?
--
paul moore
www.paul-moore.com
^ permalink raw reply
* Re: [Xen-devel] DomU's network interface will hung when Dom0 running 32bit
From: Wei Liu @ 2013-10-16 15:17 UTC (permalink / raw)
To: jianhai luan; +Cc: Wei Liu, annie li, xen-devel, Ian Campbell, netdev
In-Reply-To: <525EAB02.9050207@oracle.com>
On Wed, Oct 16, 2013 at 11:04:34PM +0800, jianhai luan wrote:
[...]
> >From ef02403a10173896c5c102f768741d0700b8a3a2 Mon Sep 17 00:00:00 2001
> From: Jason Luan <jianhai.luan@oracle.com>
> Date: Tue, 15 Oct 2013 17:07:49 +0800
> Subject: [PATCH] xen-netback: pending timer only in the range [expire,
> next_credit)
>
> The function time_after_eq() do correct judge in range of MAX_UNLONG/2.
> If net-front send lesser package, the delta between now and next_credit
> will out of the range and time_after_eq() will do wrong judge in result
> to net-front hung. For example:
> expire next_credit .... next_credit+MAX_UNLONG/2 now
> -----------------time increases this direction----------------->
>
> We should be add the environment which now beyond next_credit+MAX_UNLONG/2.
> Because the fact now mustn't before expire, time_before(now, expire) == true
> will show the environment.
> time_after_eq(now, next_credit) || time_before (now, expire)
> ==
> !time_in_range_open(now, expire, next_credit)
>
OK, you say !time_in_range_open here but the code below has
!time_in_range. I suppose it is a typo?
Your patch should go against "net" tree so you need to have
"[PATCH net]" as prefix.
Also don't send your patch as attachment, send it inline. You can use
git format-patch, git send-email to do this.
Could you please fix the above issues and resend the patch to netdev,
with Ian and me CC'ed.
You can find out how netdev works in
Documentation/networking/netdev-FAQ.txt.
Last but not least, thanks for your contribution!
Wei.
> Signed-off-by: Jason Luan <jianhai.luan@oracle.com>
> ---
> drivers/net/xen-netback/netback.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index f3e591c..62492f0 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -1195,7 +1195,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
> return true;
>
> /* Passed the point where we can replenish credit? */
> - if (time_after_eq(now, next_credit)) {
> + if (!time_in_range(now, vif->credit_timeout.expires, next_credit)) {
> vif->credit_timeout.expires = now;
> tx_add_credit(vif);
> }
> --
> 1.7.6.5
>
^ permalink raw reply
* Re: SW csum errors
From: Eric Dumazet @ 2013-10-16 15:24 UTC (permalink / raw)
To: Kyle Hubert; +Cc: Stephen Hemminger, netdev
In-Reply-To: <CAJoZ4U0PNtk2e_x4D3N_fFN32uTVe6Z+FPg7ofG69KjQzsZ7xA@mail.gmail.com>
On Wed, 2013-10-16 at 11:10 -0400, Kyle Hubert wrote:
> Thanks, I didn't realize it was as simple as file backed pages being
> changed. Yes, our device does support SG, so we do have zero-copy
> sendfile() support. I'll concoct a simple test to prove this.
You also can use vmsplice()/splice() and touch anonymous memory,
no need to play with a file ;)
^ permalink raw reply
* [PATCH] WAN: Adding support for Infineon PEF2256 E1 chipset
From: Christophe Leroy @ 2013-10-16 15:25 UTC (permalink / raw)
To: Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Rob Landley, Grant Likely, Krzysztof Halasa
Cc: devicetree, linux-doc, linux-kernel, netdev, devicetree,
jerome.chantelauze
The patch adds WAN support for Infineon PEF2256 E1 Chipset.
Signed-off-by: Jerome Chantelauze <jerome.chantelauze@c-s.fr>
Acked-by: Christophe Leroy <christophe.leroy@c-s.fr>
diff -urN a/drivers/net/wan/pef2256.c b/drivers/net/wan/pef2256.c
--- a/drivers/net/wan/pef2256.c 1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/wan/pef2256.c 2013-10-13 13:05:01.000000000 +0200
@@ -0,0 +1,1124 @@
+/*
+ * drivers/net/wan/pef2256.c : a PEF2256 HDLC driver for Linux
+ *
+ * This software may be used and distributed according to the terms of the
+ * GNU General Public License.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <linux/cache.h>
+#include <asm/byteorder.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+
+#include <linux/if_arp.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/hdlc.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/etherdevice.h>
+#include "pef2256.h"
+
+static irqreturn_t pef2256_irq(int irq, void *dev_priv);
+static int Config_HDLC(struct pef2256_dev_priv *priv);
+static int init_FALC(struct pef2256_dev_priv *priv);
+static int pef2256_open(struct net_device *netdev);
+static int pef2256_close(struct net_device *netdev);
+
+void print_regs(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+ struct pef2256_regs *base_addr = (struct pef2256_regs *)priv->base_addr;
+
+ netdev_info(ndev, " MODE = 0x%02x\n", base_addr->MODE);
+ netdev_info(ndev, " RAH1 = 0x%02x\n", base_addr->RAH1);
+ netdev_info(ndev, " RAH2 = 0x%02x\n", base_addr->RAH2);
+ netdev_info(ndev, " RAL1 = 0x%02x\n", base_addr->RAL1);
+ netdev_info(ndev, " RAL2 = 0x%02x\n", base_addr->RAL2);
+ netdev_info(ndev, " IPC = 0x%02x\n", base_addr->IPC);
+ netdev_info(ndev, " CCR1 = 0x%02x\n", base_addr->CCR1);
+ netdev_info(ndev, " CCR2 = 0x%02x\n", base_addr->CCR2);
+ netdev_info(ndev, " RTR1 = 0x%02x\n", base_addr->RTR1);
+ netdev_info(ndev, " RTR2 = 0x%02x\n", base_addr->RTR2);
+ netdev_info(ndev, " RTR3 = 0x%02x\n", base_addr->RTR3);
+ netdev_info(ndev, " RTR4 = 0x%02x\n", base_addr->RTR4);
+ netdev_info(ndev, " TTR1 = 0x%02x\n", base_addr->TTR1);
+ netdev_info(ndev, " TTR2 = 0x%02x\n", base_addr->TTR2);
+ netdev_info(ndev, " TTR3 = 0x%02x\n", base_addr->TTR3);
+ netdev_info(ndev, " TTR4 = 0x%02x\n", base_addr->TTR4);
+ netdev_info(ndev, " IMR0 = 0x%02x\n", base_addr->IMR0);
+ netdev_info(ndev, " IMR1 = 0x%02x\n", base_addr->IMR1);
+ netdev_info(ndev, " IMR2 = 0x%02x\n", base_addr->IMR2);
+ netdev_info(ndev, " IMR3 = 0x%02x\n", base_addr->IMR3);
+ netdev_info(ndev, " IMR4 = 0x%02x\n", base_addr->IMR4);
+ netdev_info(ndev, " IMR5 = 0x%02x\n", base_addr->IMR5);
+ netdev_info(ndev, " IERR = 0x%02x\n", base_addr->IERR);
+ netdev_info(ndev, " FMR0 = 0x%02x\n", base_addr->FMR0);
+ netdev_info(ndev, " FMR1 = 0x%02x\n", base_addr->FMR1);
+ netdev_info(ndev, " FMR2 = 0x%02x\n", base_addr->FMR2);
+ netdev_info(ndev, " LOOP = 0x%02x\n", base_addr->LOOP);
+ netdev_info(ndev, " XSW = 0x%02x\n", base_addr->XSW);
+ netdev_info(ndev, " XSP = 0x%02x\n", base_addr->XSP);
+ netdev_info(ndev, " XC0 = 0x%02x\n", base_addr->XC0);
+ netdev_info(ndev, " XC1 = 0x%02x\n", base_addr->XC1);
+ netdev_info(ndev, " RC0 = 0x%02x\n", base_addr->RC0);
+ netdev_info(ndev, " RC1 = 0x%02x\n", base_addr->RC1);
+ netdev_info(ndev, " XPM0 = 0x%02x\n", base_addr->XPM0);
+ netdev_info(ndev, " XPM1 = 0x%02x\n", base_addr->XPM1);
+ netdev_info(ndev, " XPM2 = 0x%02x\n", base_addr->XPM2);
+ netdev_info(ndev, " TSWM = 0x%02x\n", base_addr->TSWM);
+ netdev_info(ndev, " IDLE = 0x%02x\n", base_addr->IDLE);
+ netdev_info(ndev, " XSA4 = 0x%02x\n", base_addr->XSA4);
+ netdev_info(ndev, " XSA5 = 0x%02x\n", base_addr->XSA5);
+ netdev_info(ndev, " XSA6 = 0x%02x\n", base_addr->XSA6);
+ netdev_info(ndev, " XSA7 = 0x%02x\n", base_addr->XSA7);
+ netdev_info(ndev, " XSA8 = 0x%02x\n", base_addr->XSA8);
+ netdev_info(ndev, " FMR3 = 0x%02x\n", base_addr->FMR3);
+ netdev_info(ndev, " ICB1 = 0x%02x\n", base_addr->ICB1);
+ netdev_info(ndev, " ICB2 = 0x%02x\n", base_addr->ICB2);
+ netdev_info(ndev, " ICB3 = 0x%02x\n", base_addr->ICB3);
+ netdev_info(ndev, " ICB4 = 0x%02x\n", base_addr->ICB4);
+ netdev_info(ndev, " LIM0 = 0x%02x\n", base_addr->LIM0);
+ netdev_info(ndev, " LIM1 = 0x%02x\n", base_addr->LIM1);
+ netdev_info(ndev, " PCD = 0x%02x\n", base_addr->PCD);
+ netdev_info(ndev, " PCR = 0x%02x\n", base_addr->PCR);
+ netdev_info(ndev, " LIM2 = 0x%02x\n", base_addr->LIM2);
+ netdev_info(ndev, " LCR1 = 0x%02x\n", base_addr->LCR1);
+ netdev_info(ndev, " LCR2 = 0x%02x\n", base_addr->LCR2);
+ netdev_info(ndev, " LCR3 = 0x%02x\n", base_addr->LCR3);
+ netdev_info(ndev, " SIC1 = 0x%02x\n", base_addr->SIC1);
+ netdev_info(ndev, " SIC2 = 0x%02x\n", base_addr->SIC2);
+ netdev_info(ndev, " SIC3 = 0x%02x\n", base_addr->SIC3);
+ netdev_info(ndev, " CMR1 = 0x%02x\n", base_addr->CMR1);
+ netdev_info(ndev, " CMR2 = 0x%02x\n", base_addr->CMR2);
+ netdev_info(ndev, " GCR = 0x%02x\n", base_addr->GCR);
+ netdev_info(ndev, " ESM = 0x%02x\n", base_addr->ESM);
+ netdev_info(ndev, " CMR3 = 0x%02x\n", base_addr->CMR3);
+ netdev_info(ndev, " PC1 = 0x%02x\n", base_addr->PC1);
+ netdev_info(ndev, " PC2 = 0x%02x\n", base_addr->PC2);
+ netdev_info(ndev, " PC3 = 0x%02x\n", base_addr->PC3);
+ netdev_info(ndev, " PC4 = 0x%02x\n", base_addr->PC4);
+ netdev_info(ndev, " PC5 = 0x%02x\n", base_addr->PC5);
+ netdev_info(ndev, " GPC1 = 0x%02x\n", base_addr->GPC1);
+ netdev_info(ndev, " PC6 = 0x%02x\n", base_addr->PC6);
+ netdev_info(ndev, " CCR3 = 0x%02x\n", base_addr->CCR3);
+ netdev_info(ndev, " CCR4 = 0x%02x\n", base_addr->CCR4);
+ netdev_info(ndev, " CCR5 = 0x%02x\n", base_addr->CCR5);
+ netdev_info(ndev, " MODE2 = 0x%02x\n", base_addr->MODE2);
+ netdev_info(ndev, " MODE3 = 0x%02x\n", base_addr->MODE3);
+ netdev_info(ndev, " RBC2 = 0x%02x\n", base_addr->RBC2);
+ netdev_info(ndev, " RBC3 = 0x%02x\n", base_addr->RBC3);
+ netdev_info(ndev, " GCM1 = 0x%02x\n", base_addr->GCM1);
+ netdev_info(ndev, " GCM2 = 0x%02x\n", base_addr->GCM2);
+ netdev_info(ndev, " GCM3 = 0x%02x\n", base_addr->GCM3);
+ netdev_info(ndev, " GCM4 = 0x%02x\n", base_addr->GCM4);
+ netdev_info(ndev, " GCM5 = 0x%02x\n", base_addr->GCM5);
+ netdev_info(ndev, " GCM6 = 0x%02x\n", base_addr->GCM6);
+ netdev_info(ndev, " SIS2/GCM7 = 0x%02x\n", base_addr->Dif1.SIS2);
+ netdev_info(ndev, " RSIS2/GCM8 = 0x%02x\n",
+ base_addr->Dif2.RSIS2);
+ netdev_info(ndev, " TSEO = 0x%02x\n", base_addr->TSEO);
+ netdev_info(ndev, " TSBS1 = 0x%02x\n", base_addr->TSBS1);
+ netdev_info(ndev, " TSBS2 = 0x%02x\n", base_addr->TSBS2);
+ netdev_info(ndev, " TSBS3 = 0x%02x\n", base_addr->TSBS3);
+ netdev_info(ndev, " TSS2 = 0x%02x\n", base_addr->TSS2);
+ netdev_info(ndev, " TSS3 = 0x%02x\n", base_addr->TSS3);
+ netdev_info(ndev, " Res10 = 0x%02x\n", base_addr->Res10);
+ netdev_info(ndev, " Res11 = 0x%02x\n", base_addr->Res11);
+ netdev_info(ndev, " TPC0 = 0x%02x\n", base_addr->TPC0);
+ netdev_info(ndev, " GLC1 = 0x%02x\n", base_addr->GLC1);
+}
+
+static ssize_t fs_attr_regs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ print_regs(dev);
+ return sprintf(buf, "*** printk DEBUG ***\n");
+}
+
+static DEVICE_ATTR(regs, S_IRUGO, fs_attr_regs_show, NULL);
+
+static ssize_t fs_attr_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+
+ return sprintf(buf, "%d\n", priv->mode);
+}
+
+
+static ssize_t fs_attr_mode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+ u32 value;
+ int ret = kstrtol(buf, 10, (long int *)&value);
+ int reconfigure = (value != priv->mode);
+
+ if (ret != 0)
+ return ret;
+
+ if (value != MASTER_MODE && value != SLAVE_MODE)
+ return -EINVAL;
+
+ priv->mode = value;
+ if (reconfigure && priv->init_done) {
+ pef2256_close(ndev);
+ init_FALC(priv);
+ pef2256_open(ndev);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, fs_attr_mode_show,
+ fs_attr_mode_store);
+
+
+
+static ssize_t fs_attr_Tx_TS_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+
+ return sprintf(buf, "0x%08x\n", priv->Tx_TS);
+}
+
+
+static ssize_t fs_attr_Tx_TS_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+ u32 value;
+ int ret = kstrtol(buf, 10, (long int *)&value);
+ int reconfigure = (value != priv->mode);
+
+ if (ret != 0)
+ return ret;
+
+ /* TS 0 is reserved */
+ if (value & 0x80000000)
+ return -EINVAL;
+
+ priv->Tx_TS = value;
+ if (reconfigure && priv->init_done)
+ Config_HDLC(priv);
+
+ return count;
+}
+
+static DEVICE_ATTR(Tx_TS, S_IRUGO | S_IWUSR, fs_attr_Tx_TS_show,
+ fs_attr_Tx_TS_store);
+
+
+static ssize_t fs_attr_Rx_TS_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+
+ return sprintf(buf, "0x%08x\n", priv->Rx_TS);
+}
+
+
+static ssize_t fs_attr_Rx_TS_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+ u32 value;
+ int ret = kstrtol(buf, 10, (long int *)&value);
+ int reconfigure = (value != priv->mode);
+
+ if (ret != 0)
+ return ret;
+
+ /* TS 0 is reserved */
+ if (value & 0x80000000)
+ return -EINVAL;
+
+ priv->Rx_TS = value;
+ if (reconfigure && priv->init_done)
+ Config_HDLC(priv);
+
+ return count;
+}
+
+static DEVICE_ATTR(Rx_TS, S_IRUGO | S_IWUSR, fs_attr_Rx_TS_show,
+ fs_attr_Rx_TS_store);
+
+/*
+ * Setting up HDLC channel
+ */
+int Config_HDLC(struct pef2256_dev_priv *priv)
+{
+ int i;
+ int TS_idx;
+ struct pef2256_regs *base_addr;
+ u8 dummy;
+
+ /* Set framer E1 address */
+ base_addr = (struct pef2256_regs *)priv->base_addr;
+
+ /* Read to remove pending IT */
+ dummy = base_addr->ISR0;
+ dummy = base_addr->ISR1;
+
+ /* Mask HDLC 1 Transmit IT */
+ base_addr->IMR1 |= 1;
+ base_addr->IMR1 |= 1 << 4;
+ base_addr->IMR1 |= 1 << 5;
+
+ /* Mask HDLC 1 Receive IT */
+ base_addr->IMR0 |= 1;
+ base_addr->IMR0 |= 1 << 7;
+ base_addr->IMR1 |= 1 << 6;
+
+ udelay((2 * 32) * 125);
+
+ /* MODE.HRAC = 0 (Receiver inactive)
+ MODE.DIV = 0 (Data normal operation)
+ for FALC V2.2 : MODE.HDLCI = 0 (normal operation) */
+ /* MODE.MDS2:0 = 100 (No address comparison) */
+ /* MODE.HRAC = 1 (Receiver active) */
+ out_8(&(base_addr->MODE), 1 << 3);
+ /* CCR1.EITS = 1 (Enable internal Time Slot 31:0 Signaling)
+ CCR1.XMFA = 0 (No transmit multiframe alignment)
+ CCR1.RFT1:0 = 00 (RFIFO sur 32 bytes) */
+ /* setting up Interframe Time Fill */
+ /* CCR1.ITF = 1 (Interframe Time Fill Continuous flag) */
+ out_8(&(base_addr->CCR1), 0x10 | (1 << 3));
+ /* CCR2.XCRC = 0 (Transmit CRC ON)
+ CCR2.RCRC = 0 (Receive CRC ON, no write in RFIFO)
+ CCR2.RADD = 0 (No write address in RFIFO) */
+ out_8(&(base_addr->CCR2), 0x00);
+
+ udelay((2 * 32) * 125);
+
+ /* MODE.HRAC = 0 (Receiver inactive)
+ MODE.DIV = 0 (Data normal operation)
+ for FALC V2.2 : MODE.HDLCI = 0 (normal operation) */
+ /* MODE.MDS2:0 = 100 (No address comparison) */
+ /* MODE.HRAC = 1 (Receiver active) */
+ out_8(&(base_addr->MODE), 1 << 3);
+ /* CCR1.EITS = 1 (Enable internal Time Slot 31:0 Signaling)
+ CCR1.XMFA = 0 (No transmit multiframe alignment)
+ CCR1.RFT1:0 = 00 (RFIFO sur 32 bytes) */
+ /* setting up Interframe Time Fill */
+ /* CCR1.ITF = 1 (Interframe Time Fill Continuous flag) */
+ out_8(&(base_addr->CCR1), 0x10 | (1 << 3));
+ /* CCR2.XCRC = 0 (Transmit CRC ON)
+ CCR2.RCRC = 0 (Receive CRC ON, no write in RFIFO)
+ CCR2.RADD = 0 (No write address in RFIFO) */
+ out_8(&(base_addr->CCR2), 0x00);
+
+ udelay((2 * 32) * 125);
+
+ /* MODE.HRAC = 0 (Receiver inactive)
+ MODE.DIV = 0 (Data normal operation)
+ for FALC V2.2 : MODE.HDLCI = 0 (normal operation) */
+ /* MODE.MDS2:0 = 100 (No address comparison) */
+ /* MODE.HRAC = 1 (Receiver active) */
+ out_8(&(base_addr->MODE), 1 << 3);
+ /* CCR1.EITS = 1 (Enable internal Time Slot 31:0 Signaling)
+ CCR1.XMFA = 0 (No transmit multiframe alignment)
+ CCR1.RFT1:0 = 00 (RFIFO sur 32 bytes) */
+ /* setting up Interframe Time Fill */
+ /* CCR1.ITF = 1 (Interframe Time Fill Continuous flag) */
+ out_8(&(base_addr->CCR1), 0x10 | (1 << 3));
+ /* CCR2.XCRC = 0 (Transmit CRC ON)
+ CCR2.RCRC = 0 (Receive CRC ON, no write in RFIFO)
+ CCR2.RADD = 0 (No write address in RFIFO) */
+ out_8(&(base_addr->CCR2), 0x00);
+
+ udelay((2 * 32) * 125);
+
+ /* Init Time Slot select */
+ out_8(&(base_addr->TTR1), 0x00);
+ out_8(&(base_addr->TTR2), 0x00);
+ out_8(&(base_addr->TTR3), 0x00);
+ out_8(&(base_addr->TTR4), 0x00);
+ out_8(&(base_addr->RTR1), 0x00);
+ out_8(&(base_addr->RTR2), 0x00);
+ out_8(&(base_addr->RTR3), 0x00);
+ out_8(&(base_addr->RTR4), 0x00);
+ /* Set selected TS bits */
+ /* Starting at TS 1, TS 0 is reserved */
+ for (TS_idx = 1; TS_idx < 32; TS_idx++) {
+ i = 7 - (TS_idx % 8);
+ switch (TS_idx / 8) {
+ case 0:
+ if (priv->Tx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->TTR1), 1 << i);
+ if (priv->Rx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->RTR1), 1 << i);
+ break;
+ case 1:
+ if (priv->Tx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->TTR2), 1 << i);
+ if (priv->Rx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->RTR2), 1 << i);
+ break;
+ case 2:
+ if (priv->Tx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->TTR3), 1 << i);
+ if (priv->Rx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->RTR3), 1 << i);
+ break;
+ case 3:
+ if (priv->Tx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->TTR4), 1 << i);
+ if (priv->Rx_TS & (1 << (31 - TS_idx)))
+ setbits8(&(base_addr->RTR4), 1 << i);
+ break;
+ }
+ }
+
+ /* Unmask HDLC 1 Transmit IT */
+ base_addr->IMR1 &= ~1;
+ base_addr->IMR1 &= ~(1 << 4);
+ base_addr->IMR1 &= ~(1 << 5);
+
+ /* Unmask HDLC 1 Receive IT */
+ base_addr->IMR0 &= ~1;
+ base_addr->IMR0 &= ~(1 << 7);
+ base_addr->IMR1 &= ~(1 << 6);
+
+ return 0;
+}
+
+
+/*
+ * Init FALC56
+ */
+static int init_FALC(struct pef2256_dev_priv *priv)
+{
+ struct pef2256_regs *base_addr;
+ int Version;
+
+ /* Get controller version */
+ Version = priv->component_id;
+
+ /* Init FALC56 */
+ base_addr = (struct pef2256_regs *)priv->base_addr;
+ /* RCLK output : DPLL clock, DCO-X enabled, DCO-X internal reference
+ clock */
+ out_8(&(base_addr->CMR1), 0x00);
+ /* SCLKR selected, SCLKX selected, receive synchro pulse sourced by
+ SYPR, transmit synchro pulse sourced by SYPX */
+ out_8(&(base_addr->CMR2), 0x00);
+ /* NRZ coding, no alarm simulation */
+ out_8(&(base_addr->FMR0), 0x00);
+ /* E1 double frame format, 2 Mbit/s system data rate, no AIS
+ transmission to remote end or system interface, payload loop
+ off, transmit remote alarm on */
+ out_8(&(base_addr->FMR1), 0x00);
+ out_8(&(base_addr->FMR2), 0x02);
+ /* E1 default for LIM2 */
+ out_8(&(base_addr->LIM2), 0x20);
+ if (priv->mode == MASTER_MODE)
+ /* SEC input, active high */
+ out_8(&(base_addr->GPC1), 0x00);
+ else
+ /* FSC output, active high */
+ out_8(&(base_addr->GPC1), 0x40);
+ /* internal second timer, power on */
+ out_8(&(base_addr->GCR), 0x00);
+ /* slave mode, local loop off, mode short-haul */
+ if (Version == VERSION_1_2)
+ out_8(&(base_addr->LIM0), 0x00);
+ else
+ out_8(&(base_addr->LIM0), 0x08);
+ /* analog interface selected, remote loop off */
+ out_8(&(base_addr->LIM1), 0x00);
+ if (Version == VERSION_1_2) {
+ /* function of ports RP(A to D) : output receive sync pulse
+ function of ports XP(A to D) : output transmit line clock */
+ out_8(&(base_addr->PC1), 0x77);
+ out_8(&(base_addr->PC2), 0x77);
+ out_8(&(base_addr->PC3), 0x77);
+ out_8(&(base_addr->PC4), 0x77);
+ } else {
+ /* function of ports RP(A to D) : output high
+ function of ports XP(A to D) : output high */
+ out_8(&(base_addr->PC1), 0xAA);
+ out_8(&(base_addr->PC2), 0xAA);
+ out_8(&(base_addr->PC3), 0xAA);
+ out_8(&(base_addr->PC4), 0xAA);
+ }
+ /* function of port RPA : input SYPR
+ function of port XPA : input SYPX */
+ out_8(&(base_addr->PC1), 0x00);
+ /* SCLKR, SCLKX, RCLK configured to inputs,
+ XFMS active low, CLK1 and CLK2 pin configuration */
+ out_8(&(base_addr->PC5), 0x00);
+ out_8(&(base_addr->PC6), 0x00);
+ /* the receive clock offset is cleared
+ the receive time slot offset is cleared */
+ out_8(&(base_addr->RC0), 0x00);
+ out_8(&(base_addr->RC1), 0x9C);
+ /* 2.048 MHz system clocking rate, receive buffer 2 frames, transmit
+ buffer bypass, data sampled and transmitted on the falling edge of
+ SCLKR/X, automatic freeze signaling, data is active in the first
+ channel phase */
+ out_8(&(base_addr->SIC1), 0x00);
+ out_8(&(base_addr->SIC2), 0x00);
+ out_8(&(base_addr->SIC3), 0x00);
+ /* channel loop-back and single frame mode are disabled */
+ out_8(&(base_addr->LOOP), 0x00);
+ /* all bits of the transmitted service word are cleared */
+ out_8(&(base_addr->XSW), 0x1F);
+ /* spare bit values are cleared */
+ out_8(&(base_addr->XSP), 0x00);
+ /* no transparent mode active */
+ out_8(&(base_addr->TSWM), 0x00);
+ /* the transmit clock offset is cleared
+ the transmit time slot offset is cleared */
+ out_8(&(base_addr->XC0), 0x00);
+ out_8(&(base_addr->XC1), 0x9C);
+ /* transmitter in tristate mode */
+ out_8(&(base_addr->XPM2), 0x40);
+ /* transmit pulse mask */
+ if (Version != VERSION_1_2)
+ out_8(&(base_addr->XPM0), 0x9C);
+
+ if (Version == VERSION_1_2) {
+ /* master clock is 16,384 MHz (flexible master clock) */
+ out_8(&(base_addr->GCM2), 0x58);
+ out_8(&(base_addr->GCM3), 0xD2);
+ out_8(&(base_addr->GCM4), 0xC2);
+ out_8(&(base_addr->GCM5), 0x07);
+ out_8(&(base_addr->GCM6), 0x10);
+ } else {
+ /* master clock is 16,384 MHz (flexible master clock) */
+ out_8(&(base_addr->GCM2), 0x18);
+ out_8(&(base_addr->GCM3), 0xFB);
+ out_8(&(base_addr->GCM4), 0x0B);
+ out_8(&(base_addr->GCM5), 0x01);
+ out_8(&(base_addr->GCM6), 0x0B);
+ out_8(&(base_addr->Dif1.GCM7), 0xDB);
+ out_8(&(base_addr->Dif2.GCM8), 0xDF);
+ }
+
+ /* master mode => LIM0.MAS = 1 (bit 0) */
+ if (priv->mode == MASTER_MODE)
+ setbits8(&(base_addr->LIM0), 1 << 0);
+
+ /* transmit line in normal operation => XPM2.XLT = 0 (bit 6) */
+ clrbits8(&(base_addr->XPM2), 1 << 6);
+
+ if (Version == VERSION_1_2) {
+ /* receive input threshold = 0,21V =>
+ LIM1.RIL2:0 = 101 (bits 6, 5 et 4) */
+ setbits8(&(base_addr->LIM1), 1 << 4);
+ setbits8(&(base_addr->LIM1), 1 << 6);
+ } else {
+ /* receive input threshold = 0,21V =>
+ LIM1.RIL2:0 = 100 (bits 6, 5 et 4) */
+ setbits8(&(base_addr->LIM1), 1 << 6);
+ }
+ /* transmit line coding = HDB3 => FMR0.XC1:0 = 11 (bits 7 et 6) */
+ setbits8(&(base_addr->FMR0), 1 << 6);
+ setbits8(&(base_addr->FMR0), 1 << 7);
+ /* receive line coding = HDB3 => FMR0.RC1:0 = 11 (bits 5 et 4) */
+ setbits8(&(base_addr->FMR0), 1 << 4);
+ setbits8(&(base_addr->FMR0), 1 << 5);
+ /* detection of LOS alarm = 176 pulses (soit (10 + 1) * 16) */
+ out_8(&(base_addr->PCD), 10);
+ /* recovery of LOS alarm = 22 pulses (soit 21 + 1) */
+ out_8(&(base_addr->PCR), 21);
+ /* DCO-X center frequency => CMR2.DCOXC = 1 (bit 5) */
+ setbits8(&(base_addr->CMR2), 1 << 5);
+ if (priv->mode == SLAVE_MODE) {
+ /* select RCLK source = 2M => CMR1.RS(1:0) = 10 (bits 5 et 4) */
+ setbits8(&(base_addr->CMR1), 1 << 5);
+ /* disable switching RCLK -> SYNC => CMR1.DCS = 1 (bit 3) */
+ setbits8(&(base_addr->CMR1), 1 << 3);
+ }
+ if (Version != VERSION_1_2)
+ /* during inactive channel phase RDO into tri-state mode */
+ setbits8(&(base_addr->SIC3), 1 << 5);
+ if (!strcmp(priv->rising_edge_sync_pulse, "transmit")) {
+ /* rising edge sync pulse transmit => SIC3.RESX = 1 (bit 3) */
+ setbits8(&(base_addr->SIC3), 1 << 3);
+ } else {
+ /* rising edge sync pulse receive => SIC3.RESR = 1 (bit 2) */
+ setbits8(&(base_addr->SIC3), 1 << 2);
+ }
+ /* transmit offset counter = 4
+ => XC0.XCO10:8 = 000 (bits 2, 1 et 0);
+ XC1.XCO7:0 = 4 (bits 7 ... 0) */
+ out_8(&(base_addr->XC1), 4);
+ /* receive offset counter = 4
+ => RC0.RCO10:8 = 000 (bits 2, 1 et 0);
+ RC1.RCO7:0 = 4 (bits 7 ... 0) */
+ out_8(&(base_addr->RC1), 4);
+
+ /* clocking rate 8M and data rate 2M on the system highway */
+ setbits8(&(base_addr->SIC1), 1 << 7);
+ /* data rate 4M on the system highway */
+ if (priv->data_rate == DATA_RATE_4M)
+ setbits8(&(base_addr->FMR1), 1 << 1);
+ /* data rate 8M on the system highway */
+ if (priv->data_rate == DATA_RATE_8M)
+ setbits8(&(base_addr->SIC1), 1 << 6);
+ /* channel phase for FALC56 */
+ if ((priv->channel_phase == CHANNEL_PHASE_1)
+ || (priv->channel_phase == CHANNEL_PHASE_3))
+ setbits8(&(base_addr->SIC2), 1 << 1);
+ if ((priv->channel_phase == CHANNEL_PHASE_2)
+ || (priv->channel_phase == CHANNEL_PHASE_3))
+ setbits8(&(base_addr->SIC2), 1 << 2);
+
+ if (priv->mode == SLAVE_MODE) {
+ /* transmit buffer size = 2 frames =>
+ SIC1.XBS1:0 = 10 (bits 1 et 0) */
+ setbits8(&(base_addr->SIC1), 1 << 1);
+ }
+
+ /* transmit in multiframe => FMR1.XFS = 1 (bit 3) */
+ setbits8(&(base_addr->FMR1), 1 << 3);
+ /* receive in multiframe => FMR2.RFS1:0 = 10 (bits 7 et 6) */
+ setbits8(&(base_addr->FMR2), 1 << 7);
+ /* Automatic transmission of submultiframe status =>
+ XSP.AXS = 1 (bit 3) */
+ setbits8(&(base_addr->XSP), 1 << 3);
+
+ /* error counter mode toutes les 1s => FMR1.ECM = 1 (bit 2) */
+ setbits8(&(base_addr->FMR1), 1 << 2);
+ /* error counter mode COFA => GCR.ECMC = 1 (bit 4) */
+ setbits8(&(base_addr->GCR), 1 << 4);
+ /* errors in service words with no influence => RC0.SWD = 1 (bit 7) */
+ setbits8(&(base_addr->RC0), 1 << 7);
+ /* 4 consecutive incorrect FAS = loss of sync => RC0.ASY4 = 1 (bit 6) */
+ setbits8(&(base_addr->RC0), 1 << 6);
+ /* Si-Bit in service word from XDI => XSW.XSIS = 1 (bit 7) */
+ setbits8(&(base_addr->XSW), 1 << 7);
+ /* Si-Bit in FAS word from XDI => XSP.XSIF = 1 (bit 2) */
+ setbits8(&(base_addr->XSP), 1 << 2);
+
+ /* port RCLK is output => PC5.CRP = 1 (bit 0) */
+ setbits8(&(base_addr->PC5), 1 << 0);
+ /* visibility of the masked interrupts => GCR.VIS = 1 (bit 7) */
+ setbits8(&(base_addr->GCR), 1 << 7);
+ /* reset lines
+ => CMDR.RRES = 1 (bit 6); CMDR.XRES = 1 (bit 4);
+ CMDR.SRES = 1 (bit 0) */
+ out_8(&(base_addr->CMDR), 0x51);
+
+ return 0;
+}
+
+
+
+static int pef2256_open(struct net_device *netdev)
+{
+ struct pef2256_dev_priv *priv = dev_to_hdlc(netdev)->priv;
+ struct pef2256_regs *base_addr = (struct pef2256_regs *)priv->base_addr;
+ int ret;
+
+ if (hdlc_open(netdev))
+ return -EAGAIN;
+
+ ret = request_irq(priv->irq, pef2256_irq, 0, "e1-wan", priv);
+ if (ret) {
+ dev_err(priv->dev, "Cannot request irq. Device seems busy.\n");
+ return -EBUSY;
+ }
+
+ if (priv->component_id != VERSION_UNDEF) {
+ ret = init_FALC(priv);
+ } else {
+ dev_err(priv->dev, "Composant ident (%X/%X) = %d\n",
+ base_addr->VSTR, base_addr->WID, priv->component_id);
+ ret = -ENODEV;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ priv->tx_skb = NULL;
+ priv->rx_len = 0;
+
+ Config_HDLC(priv);
+
+ netif_carrier_on(netdev);
+ netif_start_queue(netdev);
+
+ priv->init_done = 1;
+
+ return 0;
+}
+
+
+static int pef2256_close(struct net_device *netdev)
+{
+ struct pef2256_dev_priv *priv = dev_to_hdlc(netdev)->priv;
+
+ if (!priv->init_done)
+ return 0;
+
+ priv->init_done = 0;
+ netif_stop_queue(netdev);
+ hdlc_close(netdev);
+ free_irq(priv->irq, priv);
+
+ /* Do E1 stuff */
+
+ return 0;
+}
+
+
+
+static int pef2256_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ int ret;
+
+ ret = hdlc_ioctl(dev, ifr, cmd);
+ return ret;
+}
+
+static int pef2256_rx(struct pef2256_dev_priv *priv)
+{
+ struct sk_buff *skb;
+ int idx, size;
+ struct pef2256_regs *base_addr;
+
+ base_addr = priv->base_addr;
+
+ /* RDO has been received -> wait for RME */
+ if (priv->rx_len == -1) {
+ /* Acknowledge the FIFO */
+ setbits8(&(base_addr->CMDR), 1 << 7);
+
+ if (priv->ISR0 & (1 << 7))
+ priv->rx_len = 0;
+
+ return 0;
+ }
+
+ /* RPF : a block is available in the receive FIFO */
+ if (priv->ISR0 & 1) {
+ for (idx = 0; idx < 32; idx++)
+ priv->rx_buff[priv->rx_len + idx] =
+ base_addr->FIFO.RFIFO[idx & 1];
+
+ /* Acknowledge the FIFO */
+ setbits8(&(base_addr->CMDR), 1 << 7);
+
+ priv->rx_len += 32;
+ }
+
+ /* RME : Message end : Read the receive FIFO */
+ if (priv->ISR0 & (1 << 7)) {
+ /* Get size of last block */
+ size = base_addr->RBCL & 0x1F;
+
+ /* Read last block */
+ for (idx = 0; idx < size; idx++)
+ priv->rx_buff[priv->rx_len + idx] =
+ base_addr->FIFO.RFIFO[idx & 1];
+
+ /* Acknowledge the FIFO */
+ setbits8(&(base_addr->CMDR), 1 << 7);
+
+ priv->rx_len += size;
+
+ /* Packet received */
+ if (priv->rx_len > 0) {
+ skb = dev_alloc_skb(priv->rx_len);
+ if (!skb) {
+ priv->rx_len = 0;
+ priv->netdev->stats.rx_dropped++;
+ return -ENOMEM;
+ }
+ memcpy(skb->data, priv->rx_buff, priv->rx_len);
+ skb_put(skb, priv->rx_len);
+ priv->rx_len = 0;
+ skb->protocol = hdlc_type_trans(skb, priv->netdev);
+ priv->netdev->stats.rx_packets++;
+ priv->netdev->stats.rx_bytes += skb->len;
+ netif_rx(skb);
+ }
+ }
+
+ return 0;
+}
+
+
+static int pef2256_tx(struct pef2256_dev_priv *priv)
+{
+ int idx, size;
+ struct pef2256_regs *base_addr;
+ u8 *tx_buff = priv->tx_skb->data;
+
+ base_addr = (struct pef2256_regs *)priv->base_addr;
+
+ /* ALLS : transmit all done */
+ if (priv->ISR1 & (1 << 5)) {
+ priv->netdev->stats.tx_packets++;
+ priv->netdev->stats.tx_bytes += priv->tx_skb->len;
+ /* dev_kfree_skb(priv->tx_skb); */
+ priv->tx_skb = NULL;
+ priv->tx_len = 0;
+ netif_wake_queue(priv->netdev);
+ }
+ /* XPR : write a new block in transmit FIFO */
+ else if (priv->tx_len < priv->tx_skb->len) {
+ size = priv->tx_skb->len - priv->tx_len;
+ if (size > 32)
+ size = 32;
+
+ for (idx = 0; idx < size; idx++)
+ base_addr->FIFO.XFIFO[idx & 1] =
+ tx_buff[priv->tx_len + idx];
+
+ priv->tx_len += size;
+
+ if (priv->tx_len == priv->tx_skb->len)
+ base_addr->CMDR |= ((1 << 3) | (1 << 1));
+ else
+ setbits8(&(base_addr->CMDR), 1 << 3);
+ }
+
+ return 0;
+}
+
+
+irqreturn_t pef2256_irq(int irq, void *dev_priv)
+{
+ struct pef2256_dev_priv *priv = (struct pef2256_dev_priv *)dev_priv;
+ struct pef2256_regs *base_addr;
+ u8 GIS;
+
+ base_addr = (struct pef2256_regs *)priv->base_addr;
+ GIS = base_addr->GIS;
+
+ priv->ISR0 = priv->ISR1 = 0;
+
+ /* We only care about ISR0 and ISR1 */
+ /* ISR0 */
+ if (GIS & 1)
+ priv->ISR0 = base_addr->ISR0 & ~(base_addr->IMR0);
+ /* ISR1 */
+ if (GIS & (1 << 1))
+ priv->ISR1 = base_addr->ISR1 & ~(base_addr->IMR1);
+
+ /* Don't do anything else before init is done */
+ if (!priv->init_done)
+ return IRQ_HANDLED;
+
+ /* RDO : Receive data overflow -> RX error */
+ if (priv->ISR1 & (1 << 6)) {
+ /* Acknowledge the FIFO */
+ setbits8(&(base_addr->CMDR), 1 << 7);
+ priv->netdev->stats.rx_errors++;
+ /* RME received ? */
+ if (priv->ISR0 & (1 << 7))
+ priv->rx_len = 0;
+ else
+ priv->rx_len = -1;
+ return IRQ_HANDLED;
+ }
+
+ /* XDU : Transmit data underrun -> TX error */
+ if (priv->ISR1 & (1 << 4)) {
+ priv->netdev->stats.tx_errors++;
+ /* dev_kfree_skb(priv->tx_skb); */
+ priv->tx_skb = NULL;
+ netif_wake_queue(priv->netdev);
+ return IRQ_HANDLED;
+ }
+
+ /* RPF or RME : FIFO received */
+ if (priv->ISR0 & (1 | (1 << 7)))
+ pef2256_rx(priv);
+
+ /* XPR or ALLS : FIFO sent */
+ if (priv->ISR1 & (1 | (1 << 5)))
+ pef2256_tx(priv);
+
+ return IRQ_HANDLED;
+}
+
+
+static netdev_tx_t pef2256_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct pef2256_dev_priv *priv = dev_to_hdlc(netdev)->priv;
+ int idx, size;
+ struct pef2256_regs *base_addr;
+ u8 *tx_buff = skb->data;
+
+ base_addr = (struct pef2256_regs *)priv->base_addr;
+
+ priv->tx_skb = skb;
+ priv->tx_len = 0;
+
+ size = priv->tx_skb->len - priv->tx_len;
+ if (size > 32)
+ size = 32;
+
+ for (idx = 0; idx < size; idx++)
+ base_addr->FIFO.XFIFO[idx & 1] = tx_buff[priv->tx_len + idx];
+
+ priv->tx_len += size;
+
+ setbits8(&(base_addr->CMDR), 1 << 3);
+ if (priv->tx_len == priv->tx_skb->len)
+ setbits8(&(base_addr->CMDR), 1 << 1);
+
+ netif_stop_queue(netdev);
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops pef2256_ops = {
+ .ndo_open = pef2256_open,
+ .ndo_stop = pef2256_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = pef2256_ioctl,
+};
+
+
+static int pef2256_hdlc_attach(struct net_device *netdev,
+ unsigned short encoding, unsigned short parity)
+{
+ struct pef2256_dev_priv *priv = dev_to_hdlc(netdev)->priv;
+
+ if (encoding != ENCODING_NRZ &&
+ encoding != ENCODING_NRZI &&
+ encoding != ENCODING_FM_MARK &&
+ encoding != ENCODING_FM_SPACE &&
+ encoding != ENCODING_MANCHESTER)
+ return -EINVAL;
+
+ if (parity != PARITY_NONE &&
+ parity != PARITY_CRC16_PR0_CCITT &&
+ parity != PARITY_CRC16_PR1_CCITT &&
+ parity != PARITY_CRC32_PR0_CCITT &&
+ parity != PARITY_CRC32_PR1_CCITT)
+ return -EINVAL;
+
+ priv->encoding = encoding;
+ priv->parity = parity;
+ return 0;
+}
+
+
+/*
+ * Loading module
+ */
+static const struct of_device_id pef2256_match[];
+static int pef2256_probe(struct platform_device *ofdev)
+{
+ const struct of_device_id *match;
+ struct pef2256_dev_priv *priv;
+ int ret = -ENOMEM;
+ struct net_device *netdev;
+ hdlc_device *hdlc;
+ int sys_ret;
+ struct pef2256_regs *base_addr;
+ struct device_node *np = (&ofdev->dev)->of_node;
+ const u32 *data;
+ int len;
+
+ match = of_match_device(pef2256_match, &ofdev->dev);
+ if (!match)
+ return -EINVAL;
+
+ dev_err(&ofdev->dev, "Found PEF2256\n");
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return ret;
+
+ priv->dev = &ofdev->dev;
+
+ data = of_get_property(np, "data-rate", &len);
+ if (!data || len != 4) {
+ dev_err(&ofdev->dev, "failed to read data-rate -> using 8Mb\n");
+ priv->data_rate = DATA_RATE_8M;
+ } else
+ priv->data_rate = *data;
+
+ data = of_get_property(np, "channel-phase", &len);
+ if (!data || len != 4) {
+ dev_err(&ofdev->dev, "failed to read channel phase -> using 0\n");
+ priv->channel_phase = CHANNEL_PHASE_0;
+ } else
+ priv->channel_phase = *data;
+
+ data = of_get_property(np, "rising-edge-sync-pulse", NULL);
+ if (!data) {
+ dev_err(&ofdev->dev, "failed to read rising edge sync pulse -> using \"transmit\"\n");
+ strcpy(priv->rising_edge_sync_pulse, "transmit");
+ } else if (strcmp((char *)data, "transmit") &&
+ strcmp((char *)data, "receive")) {
+ dev_err(&ofdev->dev, "invalid rising edge sync pulse -> using \"transmit\"\n");
+ strcpy(priv->rising_edge_sync_pulse, "transmit");
+ } else
+ strncpy(priv->rising_edge_sync_pulse, (char *)data, 10);
+
+ priv->irq = of_irq_to_resource(np, 0, NULL);
+ if (!priv->irq) {
+ dev_err(priv->dev, "no irq defined\n");
+ return -EINVAL;
+ }
+
+ priv->base_addr = of_iomap(np, 0);
+ if (!priv->base_addr) {
+ dev_err(&ofdev->dev, "of_iomap failed\n");
+ kfree(priv);
+ return ret;
+ }
+
+ /* Get the component Id */
+ base_addr = (struct pef2256_regs *)priv->base_addr;
+ priv->component_id = VERSION_UNDEF;
+ if (base_addr->VSTR == 0x00) {
+ if ((base_addr->WID & WID_IDENT_1) ==
+ WID_IDENT_1_2)
+ priv->component_id = VERSION_1_2;
+ } else if (base_addr->VSTR == 0x05) {
+ if ((base_addr->WID & WID_IDENT_2) ==
+ WID_IDENT_2_1)
+ priv->component_id = VERSION_2_1;
+ else if ((base_addr->WID & WID_IDENT_2) == WID_IDENT_2_2)
+ priv->component_id = VERSION_2_2;
+ }
+
+ priv->tx_skb = NULL;
+
+ /* Default settings ; Rx and Tx use TS 1, mode = MASTER */
+ priv->Rx_TS = 0x40000000;
+ priv->Tx_TS = 0x40000000;
+ priv->mode = 0;
+
+ netdev = alloc_hdlcdev(priv);
+ if (!netdev) {
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ priv->netdev = netdev;
+ hdlc = dev_to_hdlc(netdev);
+ netdev->netdev_ops = &pef2256_ops;
+ SET_NETDEV_DEV(netdev, &ofdev->dev);
+ hdlc->attach = pef2256_hdlc_attach;
+ hdlc->xmit = pef2256_start_xmit;
+
+ dev_set_drvdata(&ofdev->dev, netdev);
+
+ ret = register_hdlc_device(netdev);
+ if (ret < 0) {
+ pr_err("unable to register\n");
+ return ret;
+ }
+
+ sys_ret = 0;
+ sys_ret |= device_create_file(priv->dev, &dev_attr_mode);
+ sys_ret |= device_create_file(priv->dev, &dev_attr_Tx_TS);
+ sys_ret |= device_create_file(priv->dev, &dev_attr_Rx_TS);
+ sys_ret |= device_create_file(priv->dev, &dev_attr_regs);
+
+ if (sys_ret) {
+ device_remove_file(priv->dev, &dev_attr_mode);
+ unregister_hdlc_device(priv->netdev);
+ free_netdev(priv->netdev);
+ }
+
+ priv->init_done = 0;
+
+ return 0;
+}
+
+
+/*
+ * Suppression du module
+ */
+static int pef2256_remove(struct platform_device *ofdev)
+{
+ struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+ struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+
+ device_remove_file(priv->dev, &dev_attr_Rx_TS);
+ device_remove_file(priv->dev, &dev_attr_Tx_TS);
+ device_remove_file(priv->dev, &dev_attr_mode);
+
+ unregister_hdlc_device(priv->netdev);
+ free_netdev(priv->netdev);
+
+ /* Do E1 stuff */
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(ofdev);
+ return 0;
+}
+
+static const struct of_device_id pef2256_match[] = {
+ {
+ .compatible = "infineon,pef2256",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, pef2256_match);
+
+
+static struct platform_driver pef2256_driver = {
+ .probe = pef2256_probe,
+ .remove = pef2256_remove,
+ .driver = {
+ .name = "pef2256",
+ .owner = THIS_MODULE,
+ .of_match_table = pef2256_match,
+ },
+};
+
+
+static int __init pef2256_init(void)
+{
+ int ret;
+ ret = platform_driver_register(&pef2256_driver);
+ return ret;
+}
+module_init(pef2256_init);
+
+
+static void __exit pef2256_exit(void)
+{
+ platform_driver_unregister(&pef2256_driver);
+}
+module_exit(pef2256_exit);
+
+
+/* GENERAL INFORMATIONS */
+MODULE_AUTHOR("CHANTELAUZE Jerome - April 2013");
+MODULE_VERSION("0.1");
+MODULE_DESCRIPTION("Infineon PEF 2256 E1 Controller");
+MODULE_LICENSE("GPL");
diff -urN a/drivers/net/wan/pef2256.h b/drivers/net/wan/pef2256.h
--- a/drivers/net/wan/pef2256.h 1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/wan/pef2256.h 2013-10-13 13:06:00.000000000 +0200
@@ -0,0 +1,269 @@
+/*
+ * drivers/net/wan/pef2256.c : a PEF2256 HDLC driver for Linux
+ *
+ * This software may be used and distributed according to the terms of the
+ * GNU General Public License.
+ *
+ */
+
+#ifndef _PEF2256_H
+#define _PEF2256_H
+
+#define MASTER_MODE 0
+#define SLAVE_MODE 1
+
+#define CHANNEL_PHASE_0 0
+#define CHANNEL_PHASE_1 1
+#define CHANNEL_PHASE_2 2
+#define CHANNEL_PHASE_3 3
+
+#define DATA_RATE_4M 4
+#define DATA_RATE_8M 8
+
+#define RX_TIMEOUT 500
+
+enum versions {
+ VERSION_UNDEF = 0,
+ VERSION_1_2 = 0x12,
+ VERSION_2_1 = 0x21,
+ VERSION_2_2 = 0x22,
+};
+
+#define WID_IDENT_1 0x03
+#define WID_IDENT_1_2 0x03
+#define WID_IDENT_2 0xC0
+#define WID_IDENT_2_1 0x00
+#define WID_IDENT_2_2 0x40
+
+
+struct pef2256_dev_priv {
+ struct sk_buff *tx_skb;
+ u16 tx_len;
+ struct device *dev;
+
+ int init_done;
+
+ void *base_addr;
+ int component_id;
+ int mode; /* MASTER or SLAVE */
+ int board_type;
+ int channel_phase;
+ int data_rate;
+ char rising_edge_sync_pulse[10];
+
+ u16 rx_len;
+ u8 rx_buff[2048];
+
+ u32 Tx_TS; /* Transmit Time Slots */
+ u32 Rx_TS; /* Receive Time Slots */
+
+ unsigned short encoding;
+ unsigned short parity;
+ struct net_device *netdev;
+
+ int irq;
+
+ u8 ISR0; /* ISR0 register */
+ u8 ISR1; /* ISR1 register */
+};
+
+
+/* Framer E1 registers */
+union pef2256_Fifo {
+ u8 XFIFO[sizeof(u16)]; /* Transmit FIFO */
+ u8 RFIFO[sizeof(u16)]; /* Receive FIFO */
+};
+
+union pef2256_60 {
+ unsigned char DEC; /* Disable Error Counter */
+ unsigned char RSA8; /* Receive Sa8-Bit Regiter */
+};
+
+union pef2256_CAS {
+ unsigned char XS; /* Transmit CAS Register */
+ unsigned char RS; /* Receive CAS Regiter */
+};
+
+union pef2256_Dif1 {
+ unsigned char SIS2; /* V1.2 : Signaling Status Register 2 */
+ unsigned char GCM7; /* V2.2 : Global Counter Mode 7 */
+};
+
+union pef2256_Dif2 {
+ unsigned char RSIS2; /* V1.2 : Rx Signaling Status Register 2 */
+ unsigned char GCM8; /* V2.2 : Global Counter Mode 8 */
+};
+
+struct pef2256_regs {
+ union pef2256_Fifo FIFO; /* 0x00/0x01 FIFO (Tx or rx) */
+ unsigned char CMDR; /* 0x02 Command Register */
+ unsigned char MODE; /* 0x03 Mode Register */
+ unsigned char RAH1; /* 0x04 Receive Address High 1 */
+ unsigned char RAH2; /* 0x05 Receive Address High 2 */
+ unsigned char RAL1; /* 0x06 Receive Address Low 1 */
+ unsigned char RAL2; /* 0x07 Receive Address Low 2 */
+ unsigned char IPC; /* 0x08 Interrupt Port Configuration */
+ unsigned char CCR1; /* 0x09 Common Configuration Register 1 */
+ unsigned char CCR2; /* 0x0A Common Configuration Register 2 */
+ unsigned char Res1; /* 0x0B Free Register 1 */
+ unsigned char RTR1; /* 0x0C Receive Time Slot Register 1 */
+ unsigned char RTR2; /* 0x0D Receive Time Slot Register 2 */
+ unsigned char RTR3; /* 0x0E Receive Time Slot Register 3 */
+ unsigned char RTR4; /* 0x0F Receive Time Slot Register 4 */
+ unsigned char TTR1; /* 0x10 Transmit Time Slot Register 1 */
+ unsigned char TTR2; /* 0x11 Transmit Time Slot Register 2 */
+ unsigned char TTR3; /* 0x12 Transmit Time Slot Register 3 */
+ unsigned char TTR4; /* 0x13 Transmit Time Slot Register 4 */
+ unsigned char IMR0; /* 0x14 Interrupt Mask Register 0 */
+ unsigned char IMR1; /* 0x15 Interrupt Mask Register 1 */
+ unsigned char IMR2; /* 0x16 Interrupt Mask Register 2 */
+ unsigned char IMR3; /* 0x17 Interrupt Mask Register 3 */
+ unsigned char IMR4; /* 0x18 Interrupt Mask Register 4 */
+ unsigned char IMR5; /* 0x19 Interrupt Mask Register 5 */
+ unsigned char Res2; /* 0x1A Free Register 2 */
+ unsigned char IERR; /* 0x1B Single Bit Error Insertion Register */
+ unsigned char FMR0; /* 0x1C Framer Mode Register 0 */
+ unsigned char FMR1; /* 0x1D Framer Mode Register 1 */
+ unsigned char FMR2; /* 0x1E Framer Mode Register 2 */
+ unsigned char LOOP; /* 0x1F Channel Loop-Back */
+ unsigned char XSW; /* 0x20 Transmit Service Word */
+ unsigned char XSP; /* 0x21 Transmit Spare Bits */
+ unsigned char XC0; /* 0x22 Transmit Control 0 */
+ unsigned char XC1; /* 0x23 Transmit Control 1 */
+ unsigned char RC0; /* 0x24 Receive Control 0 */
+ unsigned char RC1; /* 0x25 Receive Control 1 */
+ unsigned char XPM0; /* 0x26 Transmit Pulse Mask 0 */
+ unsigned char XPM1; /* 0x27 Transmit Pulse Mask 1 */
+ unsigned char XPM2; /* 0x28 Transmit Pulse Mask 2 */
+ unsigned char TSWM; /* 0x29 Transparent Service Word Mask */
+ unsigned char Res3; /* 0x2A Free Register 3 */
+ unsigned char IDLE; /* 0x2B Idle Channel Code */
+ unsigned char XSA4; /* 0x2C Transmit Sa4-Bit Register */
+ unsigned char XSA5; /* 0x2D Transmit Sa5-Bit Register */
+ unsigned char XSA6; /* 0x2E Transmit Sa6-Bit Register */
+ unsigned char XSA7; /* 0x2F Transmit Sa7-Bit Register */
+ unsigned char XSA8; /* 0x30 Transmit Sa8-Bit Register */
+ unsigned char FMR3; /* 0x31 Framer Mode Register 3 */
+ unsigned char ICB1; /* 0x32 Idle Channel Register 1 */
+ unsigned char ICB2; /* 0x33 Idle Channel Register 2 */
+ unsigned char ICB3; /* 0x34 Idle Channel Register 3 */
+ unsigned char ICB4; /* 0x35 Idle Channel Register 4 */
+ unsigned char LIM0; /* 0x36 Line Interface Mode 0 */
+ unsigned char LIM1; /* 0x37 Line Interface Mode 1 */
+ unsigned char PCD; /* 0x38 Pulse Count Detection */
+ unsigned char PCR; /* 0x39 Pulse Count Recovery */
+ unsigned char LIM2; /* 0x3A Line Interface Mode 2 */
+ unsigned char LCR1; /* 0x3B Loop Code Register 1 */
+ unsigned char LCR2; /* 0x3C Loop Code Register 2 */
+ unsigned char LCR3; /* 0x3D Loop Code Register 3 */
+ unsigned char SIC1; /* 0x3E System Interface Control 1 */
+ unsigned char SIC2; /* 0x3F System Interface Control 2 */
+ unsigned char SIC3; /* 0x40 System Interface Control 3 */
+ unsigned char Res4; /* 0x41 Free Register 4 */
+ unsigned char Res5; /* 0x42 Free Register 5 */
+ unsigned char Res6; /* 0x43 Free Register 6 */
+ unsigned char CMR1; /* 0x44 Clock Mode Register 1 */
+ unsigned char CMR2; /* 0x45 Clock Mode Register 2 */
+ unsigned char GCR; /* 0x46 Global Configuration Register */
+ unsigned char ESM; /* 0x47 Errored Second Mask */
+ unsigned char CMR3; /* 0x48 Clock Mode Register 3 en V2.2 */
+ unsigned char RBD; /* 0x49 Receive Buffer Delay */
+ unsigned char VSTR; /* 0x4A Version Status Regiter */
+ unsigned char RES; /* 0x4B Receive Equalizer Status */
+ unsigned char FRS0; /* 0x4C Framer Receive Status 0 */
+ unsigned char FRS1; /* 0x4D Framer Receive Status 1 */
+ unsigned char RSW; /* 0x4E Receive Service Word */
+ unsigned char RSP; /* 0x4F Receive Spare Bits */
+ unsigned short FEC; /* 0x50/0x51 Framing Error Counter */
+ unsigned short CVC; /* 0x52/0x53 Code Violation Counter */
+ unsigned short CEC1; /* 0x54/0x55 CRC Error Counter 1 */
+ unsigned short EBC; /* 0x56/0x57 E-Bit Error Counter */
+ unsigned short CEC2; /* 0x58/0x59 CRC Error Counter 2 */
+ unsigned short CEC3; /* 0x5A/0x5B CRC Error Counter 3 */
+ unsigned char RSA4; /* 0x5C Receive Sa4-Bit Register */
+ unsigned char RSA5; /* 0x5D Receive Sa5-Bit Register */
+ unsigned char RSA6; /* 0x5E Receive Sa6-Bit Register */
+ unsigned char RSA7; /* 0x5F Receive Sa7-Bit Register */
+ union pef2256_60 Reg60; /* 0x60 Common Register */
+ unsigned char RSA6S; /* 0x61 Receive Sa6-Bit Status Register */
+ unsigned char RSP1; /* 0x62 Receive Signaling Pointer 1 */
+ unsigned char RSP2; /* 0x63 Receive Signaling Pointer 2 */
+ unsigned char SIS; /* 0x64 Signaling Status Register */
+ unsigned char RSIS; /* 0x65 Receive Signaling Status Register */
+ unsigned char RBCL; /* 0x66 Receive Byte Control */
+ unsigned char RBCH; /* 0x67 Receive Byte Control */
+ unsigned char ISR0; /* 0x68 Interrupt Status Register 0 */
+ unsigned char ISR1; /* 0x69 Interrupt Status Register 1 */
+ unsigned char ISR2; /* 0x6A Interrupt Status Register 2 */
+ unsigned char ISR3; /* 0x6B Interrupt Status Register 3 */
+ unsigned char ISR4; /* 0x6C Interrupt Status Register 4 */
+ unsigned char ISR5; /* 0x6D Interrupt Status Register 5 */
+ unsigned char GIS; /* 0x6E Global Interrupt Status */
+ unsigned char Res8; /* 0x6F Free Register 8 */
+ union pef2256_CAS CAS1; /* 0x70 CAS Register 1 */
+ union pef2256_CAS CAS2; /* 0x71 CAS Register 2 */
+ union pef2256_CAS CAS3; /* 0x72 CAS Register 3 */
+ union pef2256_CAS CAS4; /* 0x73 CAS Register 4 */
+ union pef2256_CAS CAS5; /* 0x74 CAS Register 5 */
+ union pef2256_CAS CAS6; /* 0x75 CAS Register 6 */
+ union pef2256_CAS CAS7; /* 0x76 CAS Register 7 */
+ union pef2256_CAS CAS8; /* 0x77 CAS Register 8 */
+ union pef2256_CAS CAS9; /* 0x78 CAS Register 9 */
+ union pef2256_CAS CAS10; /* 0x79 CAS Register 10 */
+ union pef2256_CAS CAS11; /* 0x7A CAS Register 11 */
+ union pef2256_CAS CAS12; /* 0x7B CAS Register 12 */
+ union pef2256_CAS CAS13; /* 0x7C CAS Register 13 */
+ union pef2256_CAS CAS14; /* 0x7D CAS Register 14 */
+ union pef2256_CAS CAS15; /* 0x7E CAS Register 15 */
+ union pef2256_CAS CAS16; /* 0x7F CAS Register 16 */
+ unsigned char PC1; /* 0x80 Port Configuration 1 */
+ unsigned char PC2; /* 0x81 Port Configuration 2 */
+ unsigned char PC3; /* 0x82 Port Configuration 3 */
+ unsigned char PC4; /* 0x83 Port Configuration 4 */
+ unsigned char PC5; /* 0x84 Port Configuration 5 */
+ unsigned char GPC1; /* 0x85 Global Port Configuration 1 */
+ unsigned char PC6; /* 0x86 Port Configuration 6 */
+ unsigned char CMDR2; /* 0x87 Command Register 2 */
+ unsigned char CMDR3; /* 0x88 Command Register 3 */
+ unsigned char CMDR4; /* 0x89 Command Register 4 */
+ unsigned char Res9; /* 0x8A Free Register 9 */
+ unsigned char CCR3; /* 0x8B Common Control Register 3 */
+ unsigned char CCR4; /* 0x8C Common Control Register 4 */
+ unsigned char CCR5; /* 0x8D Common Control Register 5 */
+ unsigned char MODE2; /* 0x8E Mode Register 2 */
+ unsigned char MODE3; /* 0x8F Mode Register 3 */
+ unsigned char RBC2; /* 0x90 Receive Byte Count Register 2 */
+ unsigned char RBC3; /* 0x91 Receive Byte Count Register 3 */
+ unsigned char GCM1; /* 0x92 Global Counter Mode 1 */
+ unsigned char GCM2; /* 0x93 Global Counter Mode 2 */
+ unsigned char GCM3; /* 0x94 Global Counter Mode 3 */
+ unsigned char GCM4; /* 0x95 Global Counter Mode 4 */
+ unsigned char GCM5; /* 0x96 Global Counter Mode 5 */
+ unsigned char GCM6; /* 0x97 Global Counter Mode 6 */
+ union pef2256_Dif1 Dif1; /* 0x98 SIS2 en V1.2, GCM7 en V2.2 */
+ union pef2256_Dif2 Dif2; /* 0x99 RSIS2 en V1.2, GCM8 en V2.2 */
+ unsigned char SIS3; /* 0x9A Signaling Status Register 3 */
+ unsigned char RSIS3; /* 0x9B Receive Signaling Status Register 3 */
+ union pef2256_Fifo FIFO2; /* 0x9C/0x9D FIFO 2 (Tx or rx) */
+ union pef2256_Fifo FIFO3; /* 0x9E/0x9F FIFO 3 (Tx or rx) */
+ unsigned char TSEO; /* 0xA0 Time Slot Even/Odd select */
+ unsigned char TSBS1; /* 0xA1 Time Slot Bit select 1 */
+ unsigned char TSBS2; /* 0xA2 Time Slot Bit select 2 */
+ unsigned char TSBS3; /* 0xA3 Time Slot Bit select 3 */
+ unsigned char TSS2; /* 0xA4 Time Slot select 2 */
+ unsigned char TSS3; /* 0xA5 Time Slot select 3 */
+ unsigned char Res10; /* 0xA6 Free Register 10 */
+ unsigned char Res11; /* 0xA7 Free Register 11 */
+ unsigned char TPC0; /* 0xA8 Test Pattern Control Register 0 */
+ unsigned char SIS2; /* 0xA9 Signaling Status Register 2 (V2.2) */
+ unsigned char RSIS2; /* 0xAA Rx Signaling Status Register 2 (V2.2) */
+ unsigned char MFPI; /* 0xAB Multi Function Port Input Status */
+ unsigned char Res12; /* 0xAC Free Register 12 */
+ unsigned char Res13; /* 0xAD Free Register 13 */
+ unsigned char Res14; /* 0xAE Free Register 14 */
+ unsigned char GLC1; /* 0xAF Global Line Control Register 1 */
+ unsigned char Res[0xEB-0xAF]; /* 0xB0/0xEB Free Registers */
+ unsigned char WID; /* 0xEC Identification Register */
+};
+
+#endif /* _PEF2256_H */
diff -urN a/Documentation/devicetree/bindings/net/pef2256.txt b/Documentation/devicetree/bindings/net/pef2256.txt
--- a/Documentation/devicetree/bindings/net/pef2256.txt 1970-01-01 01:00:00.000000000 +0100
+++ b/Documentation/devicetree/bindings/net/pef2256.txt 2013-10-13 15:05:42.000000000 +0200
@@ -0,0 +1,29 @@
+* Wan on Infineon pef2256 E1 controller
+
+Required properties:
+- compatible: Should be "infineon,pef2256"
+- reg: Address and length of the register set for the device
+- interrupts: Should contain interrupts
+
+Optional properties:
+- data-rate: Data rate on the system highway.
+ Supported values are: 2, 4, 8, 16.
+ 8 if not defined.
+- channel-phase: First time slot transmission channel phase.
+ Supported values are: 0, 1, 2, 3, 4, 5, 6, 7.
+ 0 if not defined.
+- rising-edge-sync-pulse: rising edge synchronous pulse.
+ Supported values are: "receive", "transmit".
+ "transmit" if not defined.
+
+Examples:
+
+ e1-wan@4,2000000 {
+ compatible = "infineon,pef2256";
+ reg = <4 0x2000000 0xFF>;
+ interrupts = <8 1>;
+ interrupt-parent = <&PIC>;
+ data-rate = <4>;
+ channel-phase = <1>;
+ rising-edge-sync-pulse = "transmit";
+ };
diff -urN a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
--- a/drivers/net/wan/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/wan/Makefile 2013-10-13 13:05:01.000000000 +0200
@@ -22,6 +22,7 @@
obj-$(CONFIG_COSA) += cosa.o
obj-$(CONFIG_FARSYNC) += farsync.o
obj-$(CONFIG_DSCC4) += dscc4.o
+obj-$(CONFIG_PEF2256) += pef2256.o
obj-$(CONFIG_X25_ASY) += x25_asy.o
obj-$(CONFIG_LANMEDIA) += lmc/
diff -urN a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
--- a/drivers/net/wan/Kconfig 1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/wan/Kconfig 2013-10-13 13:05:01.000000000 +0200
@@ -266,6 +266,16 @@
To compile this driver as a module, choose M here: the
module will be called farsync.
+config PEF2256
+ tristate "PEF2256 support"
+ depends on HDLC && OF && SYSFS
+ help
+ Driver for Infineon FALC56 E1/T1/J1 Framer and Line Interface
+ based on PEF2256 chipset.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pef2256.
+
config DSCC4
tristate "Etinc PCISYNC serial board support"
depends on HDLC && PCI && m
^ permalink raw reply
* Re: [Xen-devel] DomU's network interface will hung when Dom0 running 32bit
From: annie li @ 2013-10-16 15:26 UTC (permalink / raw)
To: jianhai luan; +Cc: Wei Liu, xen-devel, Ian Campbell, netdev
In-Reply-To: <525EAB02.9050207@oracle.com>
On 2013-10-16 23:04, jianhai luan wrote:
>
> From ef02403a10173896c5c102f768741d0700b8a3a2 Mon Sep 17 00:00:00 2001
> From: Jason Luan<jianhai.luan@oracle.com>
> Date: Tue, 15 Oct 2013 17:07:49 +0800
> Subject: [PATCH] xen-netback: pending timer only in the range [expire,
> next_credit)
>
> The function time_after_eq() do correct judge in range of MAX_UNLONG/2.
> If net-front send lesser package, the delta between now and next_credit
> will out of the range and time_after_eq() will do wrong judge in result
> to net-front hung. For example:
> expire next_credit .... next_credit+MAX_UNLONG/2 now
> -----------------time increases this direction----------------->
>
> We should be add the environment which now beyond next_credit+MAX_UNLONG/2.
> Because the fact now mustn't before expire, time_before(now, expire) == true
> will show the environment.
> time_after_eq(now, next_credit) || time_before (now, expire)
> ==
> !time_in_range_open(now, expire, next_credit)
>
> Signed-off-by: Jason Luan<jianhai.luan@oracle.com>
> ---
> drivers/net/xen-netback/netback.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index f3e591c..62492f0 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -1195,7 +1195,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
> return true;
>
> /* Passed the point where we can replenish credit? */
I think the comments above can be removed, and it is better to explain
the if condition here briefly.
Thanks
Annie
> - if (time_after_eq(now, next_credit)) {
> + if (!time_in_range(now, vif->credit_timeout.expires, next_credit)) {
> vif->credit_timeout.expires = now;
> tx_add_credit(vif);
> }
^ permalink raw reply
* [PATCH RFC 0/5] net:stmmac: fix jumbo frames handling and optimisation
From: Jimmy Perchet @ 2013-10-16 15:24 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev, Jimmy Perchet
Hello,
I began using Synopsys IP few weeks ago and figured out that jumbo frames
are not well supported by stmmac driver.
This patch series addresses several issues which prevent them from working
properly :
*(1/5) Threshold dma mode is needed on rx path if jumbo frames are expected.
*(2/5) RX buffers are not allocated with the needed size because
priv->dma_buf_sz is updated too late (i.e. after stmmac_init_rx_buffers call)
*(3/5) On low speed link (10MBit/s), some TX descriptors can remain dirty
if the tx coalescence timer expires before they were treated. Re-arm timer
in this case.
*(4/5) There is several confusions regarding descriptor's max buffer size,
typically the "-1" is often forgotten.
*(4/5) Jumbo frames' last descriptor is never "closed", resulting in truncated
frames transfer.
*(4/5) Frags could not be jumbo.
Regarding these last points, I didn't find simpler way than writing
new "prepare frame" functions for both ring and chain mode and update
xmit function accordingly.
The last patch is not related to jumbo frames but concern a possible
optimisation :
*(5/5) Tx descriptor's cleanup and preparation are serialized, which is not
necessary and decrease performance. In addition TX descriptor's cleanup is
performed on NET_-RX- softirq, this is confusing.
By taking care of "cur_tx" and "dirty_tx" it is possible to avoid serialization
and defer cleanup in workqueue.
On my smp embedded system, with 1Gbit/s link which is cpu bound, it increases
througput by about 90MBit/s (400MBit/s to 490MBit/s).
Best Regards,
Jimmy Perchet
Jimmy Perchet (5):
net:stmmac: set threshold/store and forward mode according to mtu
size.
net:stmmac: fix rx buffer allocation.
net:stmmac: ensure we reclaim all dirty descriptors.
net:stmmac: fix jumbo frame handling.
net:stmmac: asynchronous tx_clean
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 99 +++++-----
drivers/net/ethernet/stmicro/stmmac/common.h | 6 +
drivers/net/ethernet/stmicro/stmmac/descs_com.h | 8 +-
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 6 +
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 6 +
drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 90 ++++-----
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 219 +++++++++++++---------
8 files changed, 233 insertions(+), 207 deletions(-)
--
1.8.1.2
^ permalink raw reply
* [PATCH RFC 1/5] net:stmmac: set threshold/store and forward mode according to mtu size.
From: Jimmy Perchet @ 2013-10-16 15:24 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev, Jimmy Perchet
In-Reply-To: <1381937052-8999-1-git-send-email-jimmy.perchet@parrot.com>
Threshold mode dma is needed on rx path if jumbo frames are expected.
Signed-off-by: Jimmy Perchet <jimmy.perchet@parrot.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 48 ++++++++++++++++-------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 8d4ccd3..170f043 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1222,22 +1222,40 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
* Description: it sets the DMA operation mode: tx/rx DMA thresholds
* or Store-And-Forward capability.
*/
-static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
-{
- if (priv->plat->force_thresh_dma_mode)
- priv->hw->dma->dma_mode(priv->ioaddr, tc, tc);
- else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
- /*
- * In case of GMAC, SF mode can be enabled
- * to perform the TX COE in HW. This depends on:
- * 1) TX COE if actually supported
- * 2) There is no bugged Jumbo frame support
- * that needs to not insert csum in the TDES.
- */
- priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE);
+static void stmmac_dma_operation_mode(int mtu, struct stmmac_priv *priv)
+{
+ int rx_tc, tx_tc;
+
+ /*
+ * In case of GMAC, SF mode can be enabled
+ * to perform the TX COE in HW. This depends on:
+ * 1) TX COE if actually supported
+ * 2) There is no bugged Jumbo frame support
+ * that needs to not insert csum in the TDES.
+ */
+ if (priv->plat->tx_coe &&
+ !(priv->plat->bugged_jumbo && (mtu > ETH_DATA_LEN))) {
tc = SF_DMA_MODE;
+ tx_tc = SF_DMA_MODE;
} else
- priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
+ tx_tc = tc;
+
+ if (mtu > ETH_DATA_LEN && priv->hw_cap_support
+ && !priv->dma_cap.rxfifo_over_2048)
+ rx_tc = tc;
+ else
+ rx_tc = SF_DMA_MODE;
+
+ if (priv->plat->force_sf_dma_mode) {
+ tc = SF_DMA_MODE;
+ tx_tc = SF_DMA_MODE;
+ rx_tc = SF_DMA_MODE;
+ } else if (priv->plat->force_thresh_dma_mode) {
+ tx_tc = tc;
+ rx_tc = tc;
+ }
+
+ priv->hw->dma->dma_mode(priv->ioaddr, tx_tc, rx_tc);
}
/**
@@ -1687,7 +1705,7 @@ static int stmmac_open(struct net_device *dev)
stmmac_set_mac(priv->ioaddr, true);
/* Set the HW DMA mode and the COE */
- stmmac_dma_operation_mode(priv);
+ stmmac_dma_operation_mode(dev->mtu, priv);
/* Extra statistics */
memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
--
1.8.1.2
^ permalink raw reply related
* [PATCH RFC 2/5] net:stmmac: fix rx buffer allocation.
From: Jimmy Perchet @ 2013-10-16 15:24 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev, Jimmy Perchet
In-Reply-To: <1381937052-8999-1-git-send-email-jimmy.perchet@parrot.com>
Rx buffers used wrong size, because priv->dma_buf_sz was updated after allocation.
Signed-off-by: Jimmy Perchet <jimmy.perchet@parrot.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 170f043..0015175 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -998,6 +998,9 @@ static int init_dma_desc_rings(struct net_device *dev)
if (bfsize < BUF_SIZE_16KiB)
bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
+ priv->dma_buf_sz = bfsize;
+ buf_sz = bfsize;
+
if (netif_msg_probe(priv))
pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__,
txsize, rxsize, bfsize);
@@ -1087,8 +1090,6 @@ static int init_dma_desc_rings(struct net_device *dev)
}
priv->cur_rx = 0;
priv->dirty_rx = (unsigned int)(i - rxsize);
- priv->dma_buf_sz = bfsize;
- buf_sz = bfsize;
/* Setup the chained descriptor addresses */
if (priv->mode == STMMAC_CHAIN_MODE) {
--
1.8.1.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox