Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next] ipcomp: Convert struct xt_ipcomp spis into 16bits
From: Fan Du @ 2014-01-20  1:55 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: steffen.klassert, davem, netdev, netfilter-devel
In-Reply-To: <20140118122437.GA4309@localhost>



On 2014年01月18日 20:24, Pablo Neira Ayuso wrote:
> On Sat, Jan 18, 2014 at 10:16:14AM +0800, Fan Du wrote:
>> >  sparse warnings: (new ones prefixed by>>)
>> >
>>>>>> >  >>  >>  net/netfilter/xt_ipcomp.c:63:26: sparse: restricted __be16 degrades to integer
>>>>>> >  >>  >>  net/netfilter/xt_ipcomp.c:63:26: sparse: cast to restricted __be32
>> >
>> >  Fix this by using 16bits long spi, as IPcomp CPI is only valid for 16bits.
>> >
>> >  Signed-off-by: Fan Du<fan.du@windriver.com>
>> >  ---
>> >    include/uapi/linux/netfilter/xt_ipcomp.h |    2 +-
>> >    net/netfilter/xt_ipcomp.c                |    4 ++--
>> >    2 files changed, 3 insertions(+), 3 deletions(-)
>> >
>> >  diff --git a/include/uapi/linux/netfilter/xt_ipcomp.h b/include/uapi/linux/netfilter/xt_ipcomp.h
>> >  index 45c7e40..ca82ebb 100644
>> >  --- a/include/uapi/linux/netfilter/xt_ipcomp.h
>> >  +++ b/include/uapi/linux/netfilter/xt_ipcomp.h
>> >  @@ -4,7 +4,7 @@
>> >    #include<linux/types.h>
>> >
>> >    struct xt_ipcomp {
>> >  -	__u32 spis[2];	/* Security Parameter Index */
>> >  +	__u16 spis[2];	/* Security Parameter Index */
> This changes the binary interface so it break userspace (iptables
> needs to be recompiled), we're still in time to make such change as
> this is net-next stuff, but what I understand from the patch
> description is that this aims to fix a sparse warning, which is a bit
> of intrusive change.
>
> Didn't you find any way to fix this without change the layout of
> xt_ipcomp?
>

My bad for not catching this in the initial ipcomp version.
It would be easier to just use ntohs here to ease sparse checking.


 From dbf796e63d600256fd40000669b83227ddccebc4 Mon Sep 17 00:00:00 2001
From: Fan Du <fan.du@windriver.com>
Date: Mon, 20 Jan 2014 09:42:12 +0800
Subject: [PATCHv2 net-next] ipcomp: Use ntohs to ease sparse warning

0-DAY kernel build testing backend reported:

sparse warnings: (new ones prefixed by >>)

 >> >> net/netfilter/xt_ipcomp.c:63:26: sparse: restricted __be16 degrades to integer
 >> >> net/netfilter/xt_ipcomp.c:63:26: sparse: cast to restricted __be32

Fix this by using ntohs without shifting.

Tested with: make C=1 CF=-D__CHECK_ENDIAN__

Signed-off-by: Fan Du <fan.du@windriver.com>
---
  net/netfilter/xt_ipcomp.c |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netfilter/xt_ipcomp.c b/net/netfilter/xt_ipcomp.c
index a4c7561..89d5310 100644
--- a/net/netfilter/xt_ipcomp.c
+++ b/net/netfilter/xt_ipcomp.c
@@ -60,7 +60,7 @@ static bool comp_mt(const struct sk_buff *skb, struct xt_action_param *par)
  	}

  	return spi_match(compinfo->spis[0], compinfo->spis[1],
-			 ntohl(chdr->cpi << 16),
+			 ntohs(chdr->cpi),
  			 !!(compinfo->invflags & XT_IPCOMP_INV_SPI));
  }

-- 
1.7.9.5


-- 
浮沉随浪只记今朝笑

--fan

^ permalink raw reply related

* Re: [PATCH] net: gre: don't pull skb if dealing with icmp message
From: Duan Jiong @ 2014-01-20  1:37 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: David Miller, Daniel Borkmann, netdev
In-Reply-To: <CALnjE+qtB4fEw4HdUZy6nXU6gSAjeSCiBn0EaQR9o_d2SY3yNQ@mail.gmail.com>

于 2014年01月20日 05:08, Pravin Shelar 写道:
> On Sun, Jan 19, 2014 at 12:35 AM, Duan Jiong <duanj.fnst@cn.fujitsu.com> wrote:
>>
>> When dealing with icmp messages, the skb->data points the
>> ip header that triggered the sending of the icmp message.
>>
>> In gre_cisco_err(), the parse_gre_header() is called, and the
>> iptunnel_pull_header() is called to pull the skb at the end of
>> the parse_gre_header(). Unfortunately, the ipgre_err still needs
>> the skb->data points the ip header following the icmp layer,
>> and those ip addresses in ip header will be used to look up
>> tunnel by ip_tunnel_lookup().
>>
> This looks like bug.
> Can you use ip_hdr() rather than skb->data in ipgre_err().
> Same is done in ipgre_rcv().

That's maybe not a good idea. The ip_hdr() will the return the outmost
ip header, but we need inner ip header following the icmp layer.

Thanks,
  Duan

> --
> 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
> 

^ permalink raw reply

* Re: [PATCH net-next] sch_netem: replace magic numbers with enumerate
From: David Miller @ 2014-01-20  1:17 UTC (permalink / raw)
  To: yangyingliang; +Cc: netdev, stephen
In-Reply-To: <1390040011-13296-1-git-send-email-yangyingliang@huawei.com>

From: Yang Yingliang <yangyingliang@huawei.com>
Date: Sat, 18 Jan 2014 18:13:31 +0800

> Replace some magic numbers which describe states of 4-state model
> loss generator with enumerate.
> 
> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>

Applied, thank you.

^ permalink raw reply

* Re: [PATCH v4 net-next 3/3] ipv6: add flowlabel_consistency sysctl
From: David Miller @ 2014-01-20  1:13 UTC (permalink / raw)
  To: florent.fourcot; +Cc: netdev
In-Reply-To: <1389975305-12477-3-git-send-email-florent.fourcot@enst-bretagne.fr>

From: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
Date: Fri, 17 Jan 2014 17:15:05 +0100

> With the introduction of IPV6_FL_F_REFLECT, there is no guarantee of
> flow label unicity. This patch introduces a new sysctl to protect the old
> behaviour, enable by default.
> 
> Changelog of V3:
>  * rename ip6_flowlabel_consistency to flowlabel_consistency
>  * use net_info_ratelimited()
>  * checkpatch cleanups
> 
> Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr>

Applied.

^ permalink raw reply

* Re: [PATCH V4 net-next 2/3] ipv6: add a flag to get the flow label used remotly
From: David Miller @ 2014-01-20  1:12 UTC (permalink / raw)
  To: florent.fourcot; +Cc: netdev
In-Reply-To: <1389975305-12477-2-git-send-email-florent.fourcot@enst-bretagne.fr>

From: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
Date: Fri, 17 Jan 2014 17:15:04 +0100

> This information is already available via IPV6_FLOWINFO
> of IPV6_2292PKTOPTIONS, and them a filtering to get the flow label
> information. But it is probably logical and easier for users to add this
> here, and to control both sent/received flow label values with the
> IPV6_FLOWLABEL_MGR option.
> 
> Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr>

Applied.

^ permalink raw reply

* Re: [PATCH V4 net-next 1/3] ipv6: add the IPV6_FL_F_REFLECT flag to IPV6_FL_A_GET
From: David Miller @ 2014-01-20  1:12 UTC (permalink / raw)
  To: florent.fourcot; +Cc: netdev
In-Reply-To: <1389975305-12477-1-git-send-email-florent.fourcot@enst-bretagne.fr>

From: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
Date: Fri, 17 Jan 2014 17:15:03 +0100

> With this option, the socket will reply with the flow label value read
> on received packets.
> 
> The goal is to have a connection with the same flow label in both
> direction of the communication.
> 
> Changelog of V4:
>  * Do not erase the flow label on the listening socket. Use pktopts to
>  store the received value
> 
> Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr>

Applied.

^ permalink raw reply

* Re: ping [PATCH v3] WAN: Adding support for Lantiq PEF2256 E1 chipset (FALC56)
From: Rob Landley @ 2014-01-20  0:50 UTC (permalink / raw)
  To: Joe Perches, Christophe Leroy
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Grant Likely, Krzysztof Halasa,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, marc.balemboy-GgN8y9CXRhA
In-Reply-To: <1390160095.2290.9.camel@joe-AO722>

On 01/19/14 13:34, Joe Perches wrote:
> On Sun, 2014-01-19 at 19:07 +0100, Christophe Leroy wrote:
>> Pinging this watch as we got no feedback since 22 Nov, although we have taken
>> into account reviews from v1 and v2.
>>
>> The patch adds WAN support for Lantiq FALC56 - PEF2256 E1 Chipset.
...
>> +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;
>> +	unsigned long value;
>> +	int ret = kstrtoul(buf, 16, (long int *)&value);
>
> unportable cast

How is that not portable? It's long == pointer on Linux, which supports 
LP64 on all targets. (As do BSD, MacOSX, android, and iOS.)

   http://www.unix.org/whitepapers/64bit.html
   http://www.unix.org/version2/whatsnew/lp64_wp.html

Do you mean it's not portable to Windows?

   http://blogs.msdn.com/oldnewthing/archive/2005/01/31/363790.aspx

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] rtlwifi: Add firmware for r8723au
From: Ben Hutchings @ 2014-01-19 23:35 UTC (permalink / raw)
  To: Larry Finger; +Cc: dwmw2, linux-wireless, netdev
In-Reply-To: <1388709729-28496-1-git-send-email-Larry.Finger@lwfinger.net>

[-- Attachment #1: Type: text/plain, Size: 827 bytes --]

On Thu, 2014-01-02 at 18:42 -0600, Larry Finger wrote:
> This firmware is for a driver that will soon be submitted to the kernel.
> It occurs as data statements in Realtek driver rtl8723A_WiFi_linux_v4.1.3_6044.20121224.
> 
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
>  WHENCE                         |  13 +++++++++++++
>  rtlwifi/rtl8723aufw_A.bin      | Bin 0 -> 22172 bytes
>  rtlwifi/rtl8723aufw_B.bin      | Bin 0 -> 24118 bytes
>  rtlwifi/rtl8723aufw_B_NoBT.bin | Bin 0 -> 19200 bytes
>  4 files changed, 13 insertions(+)
>  create mode 100644 rtlwifi/rtl8723aufw_A.bin
>  create mode 100644 rtlwifi/rtl8723aufw_B.bin
>  create mode 100644 rtlwifi/rtl8723aufw_B_NoBT.bin
[...]

Applied, thanks.

Ben.

-- 
Ben Hutchings
friends: People who know you well, but like you anyway.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH net-next] sctp: fix missing SCTP mailing list address update
From: Daniel Borkmann @ 2014-01-19 22:44 UTC (permalink / raw)
  To: Jean Sacren; +Cc: Vlad Yasevich, Neil Horman, linux-sctp, netdev
In-Reply-To: <1390170293-15851-1-git-send-email-sakiwit@gmail.com>

On 01/19/2014 11:24 PM, Jean Sacren wrote:
> The commit 91705c61b5202 ("net: sctp: trivial: update mailing list
> address") updated almost all the SCTP mailing list address from
>
> 	"lksctp-developers@lists.sourceforge.net"
> to
> 	"linux-sctp@vger.kernel.org"
>
> except for the one in include/linux/sctp.h file. Fix this way trivial
> one so that all is updated.
>
> Signed-off-by: Jean Sacren <sakiwit@gmail.com>
> Cc: Daniel Borkmann <dborkman@redhat.com>

Absolutely, thanks!

Acked-by: Daniel Borkmann <dborkman@redhat.com>

^ permalink raw reply

* [PATCH net-next] sctp: fix missing SCTP mailing list address update
From: Jean Sacren @ 2014-01-19 22:24 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman; +Cc: linux-sctp, netdev, Daniel Borkmann

The commit 91705c61b5202 ("net: sctp: trivial: update mailing list
address") updated almost all the SCTP mailing list address from

	"lksctp-developers@lists.sourceforge.net"
to
	"linux-sctp@vger.kernel.org"

except for the one in include/linux/sctp.h file. Fix this way trivial
one so that all is updated.

Signed-off-by: Jean Sacren <sakiwit@gmail.com>
Cc: Daniel Borkmann <dborkman@redhat.com>
---
 include/linux/sctp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index c4c5eba26d9f..a9414fd49dc6 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -28,7 +28,7 @@
  *
  * Please send any bug reports or fixes you make to the
  * email address(es):
- *    lksctp developers <lksctp-developerst@lists.sourceforge.net>
+ *    lksctp developers <linux-sctp@vger.kernel.org>
  *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp

^ permalink raw reply related

* issues with vxlan RX checksum offload under OVS datapath
From: Or Gerlitz @ 2014-01-19 22:05 UTC (permalink / raw)
  To: Pravin B Shelar, Joseph Gasparakis; +Cc: netdev

Hi Pravin,

While testing the gro udp patches over a setup with openvswitch I noted 
that the RX checksum offload support introduced by Joseph's commit 
0afb166 "vxlan: Add capability of Rx checksum offload for inner packet" 
works fine when you use a setup made of

NIC --> IP stack --> vxlan device --> bridge --> tap

but not when its

NIC --> IP stack --> ovs vxlan port --> OVS DP --> tap

I narrowed it down to the fact the when going the OVS 
pathskb->encapsulation remains true also after the decap is done. 
Basically, this is the original hunk


> @@ -607,7 +607,17 @@ static int vxlan_udp_encap_recv(struct sock *sk, 
> struct sk_buff *skb)
>
>         __skb_tunnel_rx(skb, vxlan->dev);
>         skb_reset_network_header(skb);
> -       skb->ip_summed = CHECKSUM_NONE;
> +
> +       /* If the NIC driver gave us an encapsulated packet with
> +        * CHECKSUM_UNNECESSARY and Rx checksum feature is enabled,
> +        * leave the CHECKSUM_UNNECESSARY, the device checksummed it
> +        * for us. Otherwise force the upper layers to verify it.
> +        */
> +       if (skb->ip_summed != CHECKSUM_UNNECESSARY || 
> !skb->encapsulation ||
> +           !(vxlan->dev->features & NETIF_F_RXCSUM))
> +               skb->ip_summed = CHECKSUM_NONE;
> +
> +       skb->encapsulation = 0;

which was moved by your commits

5cfccc5 vxlan: Add vxlan recv demux.
7ce0475 vxlan: Restructure vxlan receive.

to a code which isn't shared by the vxlan driver and ovs vxlan datapath 
code, and I was thinking lets just move it back to vxlan_udp_encap_recv. 
However, we can't really make the "vxlan->dev->features & 
NETIF_F_RXCSUM" check - since there's no vxlan device for ovs datapath, 
any idea how to overcome this.

Moving this to shared code (while removing the check for 
vxlan->dev->features) made things to work on my setup, but this misses 
one of the original conditions, ideas?

I believe its too late for 3.13 unless there is going to be -rc9, but 
lets first see what's the right fix.

Or.

^ permalink raw reply

* [PATCH] gss_krb5: use lcm from kernel lib
From: Luis Henriques @ 2014-01-19 21:50 UTC (permalink / raw)
  To: Trond Myklebust, J. Bruce Fields, David S. Miller
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Replace hardcoded lowest common multiple algorithm by the lcm()
function in kernel lib.

Signed-off-by: Luis Henriques <luis.henriques-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
---
 net/sunrpc/auth_gss/gss_krb5_keys.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 76e42e6..a16c5b6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -59,6 +59,7 @@
 #include <linux/crypto.h>
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/lcm.h>
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY        RPCDBG_AUTH
@@ -72,7 +73,7 @@
 static void krb5_nfold(u32 inbits, const u8 *in,
 		       u32 outbits, u8 *out)
 {
-	int a, b, c, lcm;
+	unsigned long ulcm;
 	int byte, i, msbit;
 
 	/* the code below is more readable if I make these bytes
@@ -82,17 +83,7 @@ static void krb5_nfold(u32 inbits, const u8 *in,
 	outbits >>= 3;
 
 	/* first compute lcm(n,k) */
-
-	a = outbits;
-	b = inbits;
-
-	while (b != 0) {
-		c = b;
-		b = a%b;
-		a = c;
-	}
-
-	lcm = outbits*inbits/a;
+	ulcm = lcm(inbits, outbits);
 
 	/* now do the real work */
 
@@ -101,7 +92,7 @@ static void krb5_nfold(u32 inbits, const u8 *in,
 
 	/* this will end up cycling through k lcm(k,n)/k times, which
 	   is correct */
-	for (i = lcm-1; i >= 0; i--) {
+	for (i = ulcm-1; i >= 0; i--) {
 		/* compute the msbit in k which gets added into this byte */
 		msbit = (
 			/* first, start with the msbit in the first,
-- 
1.8.3.2

Cheers,
--
Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH] net: gre: don't pull skb if dealing with icmp message
From: Pravin Shelar @ 2014-01-19 21:08 UTC (permalink / raw)
  To: Duan Jiong; +Cc: David Miller, Daniel Borkmann, netdev
In-Reply-To: <52DB8E4A.7050809@cn.fujitsu.com>

On Sun, Jan 19, 2014 at 12:35 AM, Duan Jiong <duanj.fnst@cn.fujitsu.com> wrote:
>
> When dealing with icmp messages, the skb->data points the
> ip header that triggered the sending of the icmp message.
>
> In gre_cisco_err(), the parse_gre_header() is called, and the
> iptunnel_pull_header() is called to pull the skb at the end of
> the parse_gre_header(). Unfortunately, the ipgre_err still needs
> the skb->data points the ip header following the icmp layer,
> and those ip addresses in ip header will be used to look up
> tunnel by ip_tunnel_lookup().
>
This looks like bug.
Can you use ip_hdr() rather than skb->data in ipgre_err().
Same is done in ipgre_rcv().

^ permalink raw reply

* [PATCH net-next] ipv6: optimize link local address search
From: Hannes Frederic Sowa @ 2014-01-19 20:58 UTC (permalink / raw)
  To: netdev; +Cc: brian.haley

ipv6_link_dev_addr sorts newly added addresses by scope in
ifp->addr_list. Smaller scope addresses are added to the tail of the
list. Use this fact to iterate in reverse over addr_list and break out
as soon as a higher scoped one showes up, so we can spare some cycles
on machines with lot's of addresses.

The ordering of the addresses is not relevant and we are more likely to
get the eui64 generated address with this change anyway.

Suggested-by: Brian Haley <brian.haley@hp.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
 net/ipv6/addrconf.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f91e107..31bdedc 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1437,7 +1437,9 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
 	struct inet6_ifaddr *ifp;
 	int err = -EADDRNOTAVAIL;
 
-	list_for_each_entry(ifp, &idev->addr_list, if_list) {
+	list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) {
+		if (ifp->scope > IFA_LINK)
+			break;
 		if (ifp->scope == IFA_LINK &&
 		    !(ifp->flags & banned_flags)) {
 			*addr = ifp->addr;
@@ -1858,7 +1860,9 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
 	struct inet6_ifaddr *ifp;
 
 	read_lock_bh(&idev->lock);
-	list_for_each_entry(ifp, &idev->addr_list, if_list) {
+	list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) {
+		if (ifp->scope > IFA_LINK)
+			break;
 		if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
 			memcpy(eui, ifp->addr.s6_addr+8, 8);
 			err = 0;
@@ -3239,7 +3243,9 @@ static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp)
 	struct inet6_ifaddr *ifpiter;
 	struct inet6_dev *idev = ifp->idev;
 
-	list_for_each_entry(ifpiter, &idev->addr_list, if_list) {
+	list_for_each_entry_reverse(ifpiter, &idev->addr_list, if_list) {
+		if (ifpiter->scope > IFA_LINK)
+			break;
 		if (ifp != ifpiter && ifpiter->scope == IFA_LINK &&
 		    (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE|
 				       IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) ==
-- 
1.8.4.2

^ permalink raw reply related

* Re: Linux kernel patch: elide fib_validate_source() completely when possible - bad side effect?
From: gregory hoggarth @ 2014-01-19 20:49 UTC (permalink / raw)
  To: Julian Anastasov; +Cc: netdev
In-Reply-To: <alpine.LFD.2.11.1401170953370.1827@ja.home.ssi.bg>

Hi Julian,
 
>>> Julian Anastasov <ja@ssi.bg> 17/1/14 09:24 PM >>> 
> 
> 	Hello,
> 
> On Fri, 17 Jan 2014, gregory hoggarth wrote:
> 
>> Hi,
>> 
>> I work for Allied Telesis, a company that manufactures and sells routers and 
>> switches.
>> 
>> Earlier in the year we upgraded the linux kernel on our L3 switch firmware to 
>> v3.6.2 which includes this patch. Our testers have picked up a change in 
>> behaviour which I have traced back to this patch and I'd like to get comments 
>> on whether this is a bug or not.
>> 
>> We found that in a configuration with a device under test (DUT) that has an 
>> IP address 192.168.0.1 / 24, sending an ICMP echo request with a source IP 
>> address of 192.168.0.255 will now be accepted by the DUT, which will send an 
>> ICMP echo reply back to the 192.168.0.255 address with a broadcast MAC 
>> address of FFFF.FFFF.FFFF, meaning any other devices in the L2 domain will 
>> pick up and process the ICMP reply.
> 
> ...
> 
>> Initially we were thinking that a device configured with 192.168.0.255 / 23 
>> sending a ping to 192.168.0.1 / 24 should expect to get a reply, even 
>> though this is somewhat of a misconfiguration in that the subnets aren't 
>> matching and that some things may not work properly. For example ping from 
>> a device with IP address 192.168.0.254 would behave correctly, so it seemed 
>> correct that a ping from 192.168.0.255 should also work properly. However 
>> it appears that some other part of the kernel is detecting that the echo 
>> reply packet sent by the DUT has a destination IP address of the subnet 
>> broadcast, so instead of sending it with a unicast MAC address it sends it 
>> with the broadcast MAC address, which means all other devices on the subnet 
>> would process the ICMP echo reply. This therefore makes it seem like the 
>> ICMP echo request should have been dropped in the first place.
>>
>> The patch added the "if (!r && !fib_num_tclassid_users)" check to 
>> fib_validate_source, which for our devices evaluates to true, hence 
>> returning early and the source address check inside __fib_validate_source 
>> is not carried out.
>> 
>> 
>> Does anyone have comments as to what the correct behaviour should be in 
>> this case, and whether this is an unexpected side-effect from the patch or 
>> not?
>
>	It seems only __fib_validate_source can reject all kind
> of broadcast addresses in saddr. ip_route_input_slow() rejects
> only the well known broadcasts. Without rp_filter may be we
> can at least drop attempts to send replies back to broadcast
> addresses? For example, checking result of ip_route_output_key() in
> icmp_reply():
>
>	if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
>		=> ip_rt_put()
>
>	For icmp_send() in icmp_route_lookup() ?
>
>	For TCP in inet_csk_route_req() ?
>
>	I did not checked all places...
>
> Regards
>
> --
> Julian Anastasov <ja@ssi.bg>

Thank you for your reply.

While I think your solution may work, isn't the proper approach to drop these 
rogue packets, rather than wasting CPU and other resources processing them, 
and then beginning to craft responses which are in turn dropped?

Also seems better to drop the initial rogue packet, as that should cover all 
(?) different types of packets, rather than having to add small patches into 
ICMP, TCP and any other places that may need it.


So my question really is was the original patch correct and there's something
wrong with our device configuration, or is this an overlooked / untested side-
effect from that patch that as a result means the patch should be re-worked?


Thanks,
Greg

^ permalink raw reply

* Re: US$200 Million Humanitarian Projects
From: Mr. Wllliam Billington @ 2014-01-19 17:19 UTC (permalink / raw)
  To: Recipients

Good day,

This is based on blind trust hoping you can be trusted. The above sum is avaliable for worldwide Humanitarian projects and you will get 20% of the total sum for your involvement if interested.

Regards,
Mr. William Billington

^ permalink raw reply

* [PATCH net-next] phy: cleanup 10g code
From: Stephen Hemminger @ 2014-01-19 19:48 UTC (permalink / raw)
  To: Andy Fleming, David Miller; +Cc: netdev

Code should avoid needless exports, don't export something unless it used.
Make local functions static and remove unused stubs.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>


--- a/drivers/net/phy/phy_device.c	2014-01-14 09:46:20.709651675 -0800
+++ b/drivers/net/phy/phy_device.c	2014-01-18 14:29:37.163405318 -0800
@@ -767,12 +767,6 @@ static int genphy_config_advert(struct p
 	return changed;
 }
 
-int gen10g_config_advert(struct phy_device *dev)
-{
-	return 0;
-}
-EXPORT_SYMBOL(gen10g_config_advert);
-
 /**
  * genphy_setup_forced - configures/forces speed/duplex from @phydev
  * @phydev: target phy_device struct
@@ -820,12 +814,6 @@ int genphy_restart_aneg(struct phy_devic
 }
 EXPORT_SYMBOL(genphy_restart_aneg);
 
-int gen10g_restart_aneg(struct phy_device *phydev)
-{
-	return 0;
-}
-EXPORT_SYMBOL(gen10g_restart_aneg);
-
 /**
  * genphy_config_aneg - restart auto-negotiation or write BMCR
  * @phydev: target phy_device struct
@@ -867,11 +855,10 @@ int genphy_config_aneg(struct phy_device
 }
 EXPORT_SYMBOL(genphy_config_aneg);
 
-int gen10g_config_aneg(struct phy_device *phydev)
+static int gen10g_config_aneg(struct phy_device *phydev)
 {
 	return 0;
 }
-EXPORT_SYMBOL(gen10g_config_aneg);
 
 /**
  * genphy_update_link - update link status in @phydev
@@ -1004,7 +991,7 @@ int genphy_read_status(struct phy_device
 }
 EXPORT_SYMBOL(genphy_read_status);
 
-int gen10g_read_status(struct phy_device *phydev)
+static int gen10g_read_status(struct phy_device *phydev)
 {
 	int devad, reg;
 	u32 mmd_mask = phydev->c45_ids.devices_in_package;
@@ -1030,7 +1017,6 @@ int gen10g_read_status(struct phy_device
 
 	return 0;
 }
-EXPORT_SYMBOL(gen10g_read_status);
 
 static int genphy_config_init(struct phy_device *phydev)
 {
@@ -1102,11 +1088,10 @@ int genphy_suspend(struct phy_device *ph
 }
 EXPORT_SYMBOL(genphy_suspend);
 
-int gen10g_suspend(struct phy_device *phydev)
+static int gen10g_suspend(struct phy_device *phydev)
 {
 	return 0;
 }
-EXPORT_SYMBOL(gen10g_suspend);
 
 int genphy_resume(struct phy_device *phydev)
 {
@@ -1123,11 +1108,10 @@ int genphy_resume(struct phy_device *phy
 }
 EXPORT_SYMBOL(genphy_resume);
 
-int gen10g_resume(struct phy_device *phydev)
+static int gen10g_resume(struct phy_device *phydev)
 {
 	return 0;
 }
-EXPORT_SYMBOL(gen10g_resume);
 
 /**
  * phy_probe - probe and init a PHY device

^ permalink raw reply

* [ PATCH net-next vw] qlcnic: fix sparse warnings
From: Stephen Hemminger @ 2014-01-19 19:37 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20140118.230924.161581406065831782.davem@davemloft.net>

From: Fengguang Wu <fengguang.wu@intel.com>
Subject: [PATCH net-next] qlcnic: fix sparse warnings

Previous patch changed prototypes, but forgot functions.

Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>

---
v2 - fix indentation

 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c	2014-01-18 13:41:07.000000000 -0800
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c	2014-01-19 10:55:19.207423506 -0800
@@ -2066,8 +2066,8 @@ void qlcnic_83xx_change_l2_filter(struct
 	qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
 }
 
-void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
-			       u8 type, struct qlcnic_cmd_args *cmd)
+static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
+				      u8 type, struct qlcnic_cmd_args *cmd)
 {
 	switch (type) {
 	case QLCNIC_SET_STATION_MAC:
@@ -2170,7 +2170,7 @@ static void qlcnic_83xx_handle_link_aen(
 	qlcnic_advert_link_change(adapter, link_status);
 }
 
-irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
+static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
 {
 	struct qlcnic_adapter *adapter = data;
 	struct qlcnic_mailbox *mbx;
@@ -3517,7 +3517,7 @@ int qlcnic_83xx_flash_test(struct qlcnic
 	return 0;
 }
 
-int qlcnic_83xx_shutdown(struct pci_dev *pdev)
+static int qlcnic_83xx_shutdown(struct pci_dev *pdev)
 {
 	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
 	struct net_device *netdev = adapter->netdev;
@@ -3892,8 +3892,8 @@ int qlcnic_83xx_init_mailbox_work(struct
 	return 0;
 }
 
-pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *pdev,
-					       pci_channel_state_t state)
+static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *pdev,
+						      pci_channel_state_t state)
 {
 	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
 
@@ -3914,7 +3914,7 @@ pci_ers_result_t qlcnic_83xx_io_error_de
 	return PCI_ERS_RESULT_NEED_RESET;
 }
 
-pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
+static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
 {
 	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
 	int err = 0;
@@ -3937,7 +3937,7 @@ disconnect:
 	return PCI_ERS_RESULT_DISCONNECT;
 }
 
-void qlcnic_83xx_io_resume(struct pci_dev *pdev)
+static void qlcnic_83xx_io_resume(struct pci_dev *pdev)
 {
 	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
 

^ permalink raw reply

* Re: ping [PATCH v3] WAN: Adding support for Lantiq PEF2256 E1 chipset (FALC56)
From: Joe Perches @ 2014-01-19 19:34 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Rob Landley, Grant Likely, Krzysztof Halasa,
	devicetree, linux-doc, linux-kernel, netdev, marc.balemboy
In-Reply-To: <20140119180732.A1D99432AF@localhost.localdomain>

On Sun, 2014-01-19 at 19:07 +0100, Christophe Leroy wrote:
> Pinging this watch as we got no feedback since 22 Nov, although we have taken
> into account reviews from v1 and v2.
> 
> The patch adds WAN support for Lantiq FALC56 - PEF2256 E1 Chipset.

trivia:

> diff -urN a/drivers/net/wan/pef2256.c b/drivers/net/wan/pef2256.c
[]
> +static void config_hdlc_timeslot(struct pef2256_dev_priv *priv, int ts)
> +{
> +	static struct {
> +		u32 ttr;
> +		u32 rtr;
> +	} regs[] = {
> +		{ TTR1, RTR1 },
> +		{ TTR2, RTR2 },
> +		{ TTR3, RTR3 },
> +		{ TTR4, RTR4 },
> +	};

const

> +	int cfg_bit = 1 << (31 - ts);
> +	int reg_bit = 1 << (7 - (ts % 8));
> +	int j = ts / 8;

looks endian specific

> +
> +	if (j >= 4)
> +		return;
> +
> +	if (priv->Tx_TS & cfg_bit)
> +		pef2256_s8(priv, regs[j].ttr, 1 << reg_bit);
> +
> +	if (priv->Rx_TS & cfg_bit)
> +		pef2256_s8(priv, regs[j].rtr, 1 << reg_bit);
> +}

> +static void init_falc(struct pef2256_dev_priv *priv)
> +{

a lot of the below looks like it should use
switch/case blocks.

> +	/* Clocking rate for FALC56 */
> +
> +	/* Nothing to do for clocking rate 2M  */
> +
> +	/* clocking rate 4M  */
> +	if (priv->clock_rate == CLOCK_RATE_4M)
> +		pef2256_s8(priv, SIC1, SIC1_SSC0);
> +
> +	/* clocking rate 8M  */
> +	if (priv->clock_rate == CLOCK_RATE_8M)
> +		pef2256_s8(priv, SIC1, SIC1_SSC1);
> +
> +	/* clocking rate 16M  */
> +	if (priv->clock_rate == CLOCK_RATE_16M) {
> +		pef2256_s8(priv, SIC1, SIC1_SSC0);
> +		pef2256_s8(priv, SIC1, SIC1_SSC1);
> +	}
> +
> +	/* data rate for FALC56 */
> +
> +	/* Nothing to do for data rate 2M on the system data bus */
> +
> +	/* data rate 4M on the system data bus */
> +	if (priv->data_rate == DATA_RATE_4M)
> +		pef2256_s8(priv, FMR1, FMR1_SSD0);
> +
> +	/* data rate 8M on the system data bus */
> +	if (priv->data_rate == DATA_RATE_8M)
> +		pef2256_s8(priv, SIC1, SIC1_SSD1);
> +
> +	/* data rate 16M on the system data bus */
> +	if (priv->data_rate == DATA_RATE_16M) {
> +		pef2256_s8(priv, FMR1, FMR1_SSD0);
> +		pef2256_s8(priv, SIC1, SIC1_SSD1);
> +	}
> +
> +	/* channel phase for FALC56 */
> +
> +	/* Nothing to do for channel phase 1 */
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_2)
> +		pef2256_s8(priv, SIC2, SIC2_SICS0);
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_3)
> +		pef2256_s8(priv, SIC2, SIC2_SICS1);
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_4) {
> +		pef2256_s8(priv, SIC2, SIC2_SICS0);
> +		pef2256_s8(priv, SIC2, SIC2_SICS1);
> +	}
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_5)
> +		pef2256_s8(priv, SIC2, SIC2_SICS2);
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_6) {
> +		pef2256_s8(priv, SIC2, SIC2_SICS0);
> +		pef2256_s8(priv, SIC2, SIC2_SICS2);
> +	}
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_7) {
> +		pef2256_s8(priv, SIC2, SIC2_SICS1);
> +		pef2256_s8(priv, SIC2, SIC2_SICS2);
> +	}
> +
> +	if (priv->channel_phase == CHANNEL_PHASE_8) {
> +		pef2256_s8(priv, SIC2, SIC2_SICS0);
> +		pef2256_s8(priv, SIC2, SIC2_SICS1);
> +		pef2256_s8(priv, SIC2, SIC2_SICS2);
> +	}

> +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;
> +	long int value;
> +	int ret = kstrtol(buf, 10, &value);
> +	int reconfigure = (value != priv->mode);

Ugly test and set before determining if the previous
function was successful.

> +	if (value != MASTER_MODE && value != SLAVE_MODE)
> +		ret = -EINVAL;
> +
> +	if (ret < 0)
> +		netdev_info(ndev, "Invalid mode (0 or 1 expected\n");
> +	else {
> +		priv->mode = value;
> +		if (reconfigure && netif_carrier_ok(ndev))
> +			init_falc(priv);
> +	}
> +
> +	return strnlen(buf, count);

odd that you set ret and then don't use it.


> +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;
> +	unsigned long value;
> +	int ret = kstrtoul(buf, 16, (long int *)&value);

unportable cast

> +	int reconfigure = (value != priv->mode);

again with the test/set before determining function success.

^ permalink raw reply

* Re: [PATCH 2/4 ethtool] ethtool: Support for configurable RSS hash key.
From: Ben Hutchings @ 2014-01-19 18:35 UTC (permalink / raw)
  To: Venkata Duvvuru; +Cc: netdev@vger.kernel.org
In-Reply-To: <BF3270C86E8B1349A26C34E4EC1C44CB2C83D8D4@CMEXMB1.ad.emulex.com>

[-- Attachment #1: Type: text/plain, Size: 1826 bytes --]

On Fri, 2014-01-17 at 13:02 +0000, Venkata Duvvuru wrote:
> This ethtool patch will primarily implement the parser for the options provided by the user for set and get hashkey before invoking the ioctl.
> This patch also has Ethtool man page changes which describes the Usage of set and get hashkey options.

I'd prefer to have this combined with the -x/-X options (and add new
long options to reflect that they cover the key as well).

[...]
> diff --git a/ethtool.c b/ethtool.c
> index b06dfa3..4b05b0c 100644
> --- a/ethtool.c
> +++ b/ethtool.c
> @@ -471,6 +471,59 @@ static int rxflow_str_to_type(const char *str)
>  	return flow_type;
>  }
>  
> +static inline int is_hkey_char_valid(const char rss_hkey_string) {

A char is not a string.

> +	/* Are there any invalid characters in the string */
> +	return ((rss_hkey_string >= '0' && rss_hkey_string <= '9') ||
> +	       (rss_hkey_string >= 'a' && rss_hkey_string <= 'f') ||
> +	       (rss_hkey_string >= 'A' && rss_hkey_string <= 'F')); }

Braces are in the wrong places.  And the whole function is redundant
with isxdigit() anyway.

> +static int convert_string_to_hashkey(struct ethtool_rss_hkey *rss_hkey,
> +				      const char *rss_hkey_string)
> +{
> +	int i = 0;
> +	int hex_byte;
> +
> +	do {
> +		if (i > (RSS_HASH_KEY_LEN - 1)) {

Comparing with the wrong limit.

[...]
> +static int get_hashkey(struct cmd_context *ctx) {

Brace in the wrong place.

[...]
> +	for (i = 0; i < RSS_HASH_KEY_LEN; i++) {
> +		if (i == (RSS_HASH_KEY_LEN - 1))

Wrong length.

> +			printf("%02x\n", rss_hkey->data[i]);
> +		else
> +			printf("%02x:", rss_hkey->data[i]);
> +	}
> +
> +done:
> +	free(rss_hkey);
> +	return rc;
> +}
[...]

-- 
Ben Hutchings
friends: People who know you well, but like you anyway.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH net-next 3/4] ethtool: Support for configurable RSS hash key.
From: Ben Hutchings @ 2014-01-19 18:27 UTC (permalink / raw)
  To: Venkata Duvvuru; +Cc: netdev@vger.kernel.org
In-Reply-To: <BF3270C86E8B1349A26C34E4EC1C44CB2C83D8E5@CMEXMB1.ad.emulex.com>

[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]

On Fri, 2014-01-17 at 13:02 +0000, Venkata Duvvuru wrote:
> This ethtool patch primarily copies the ioctl command data structures from/to the User space and invokes the driver hook.
[...]
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
> @@ -678,6 +678,22 @@ struct ethtool_rx_ntuple {
>  	struct ethtool_rx_ntuple_flow_spec	fs;
>  };
>  
> +
> +/**
> + * struct ethtool_rss_hkey - command to set/get RSS hash key of the device.
> + * @cmd: Command number - %ETHTOOL_SET_RSS_HKEY/ETHTOOL_GET_RSS_HKEY
> + * @data: 40 or 16 byte rss hash key
> + * @data_len: rss hash key length
> + */
> +
> +#define RSS_HASH_KEY_LEN	40

This should have an 'ETHTOOL_' or 'ETH_' prefix.  But I wonder whether
there should actually be a static maximum length.

> +/* RSS Hash key */
> +struct ethtool_rss_hkey {
> +	__u32   cmd;            /* ETHTOOL_SET/GET_RSS_HKEY */
> +	__u8    data[RSS_HASH_KEY_LEN];
> +	__u32	data_len;
> +};
[...]

How about putting data after the data_len and giving it a length of 0,
so this is extensible to an arbitrary length key?

If we're extending the RSS configuration interface, there are a few
other things that might be worth doing at the same time:

- Single commands to get/set both the key and the indirection table at
the same time
- Add a field to distinguish multiple RSS contexts (some hardware can
use RSS contexts together with filters, though RX NFC does not support
that yet)

Ben.

-- 
Ben Hutchings
friends: People who know you well, but like you anyway.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: IGMP joins come from the wrong SA/interface
From: Hannes Frederic Sowa @ 2014-01-19 18:18 UTC (permalink / raw)
  To: Steinar H. Gunderson; +Cc: netdev
In-Reply-To: <20140118191107.GA21979@sesse.net>

On Sat, Jan 18, 2014 at 08:11:07PM +0100, Steinar H. Gunderson wrote:
> It doesn't matter if I drop the “multicast” token from the ip route line.
> Behavior is still exactly the same; it comes out of eth0 instead of eth0.2,
> with the wrong source address.
> 
> This used to work, once upon a time, but I fear it broke during a
> kernel upgrade. It's hard for me to say exactly when; probably
> a few months ago. Any ideas?

I currently only remember one commit 0a7e22609067ff ("ipv4: fix
ineffective source address selection") which did affect multicast source
address selection in recent times.

Maybe try a revert?

Greetings,

  Hannes

^ permalink raw reply

* ping [PATCH v3] WAN: Adding support for Lantiq PEF2256 E1 chipset (FALC56)
From: Christophe Leroy @ 2014-01-19 18:07 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,
	marc.balemboy

Pinging this watch as we got no feedback since 22 Nov, although we have taken
into account reviews from v1 and v2.

The patch adds WAN support for Lantiq FALC56 - PEF2256 E1 Chipset.

Signed-off-by: Jerome Chantelauze <jerome.chantelauze.ext@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,1113 @@
+/* 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 int pef2256_open(struct net_device *netdev);
+static int pef2256_close(struct net_device *netdev);
+
+/* helper function - Read a register */
+static u8 pef2256_r8(struct pef2256_dev_priv *priv, u32 offset)
+{
+	return ioread8(priv->ioaddr + offset);
+}
+
+/* helper function - Write a value to a register */
+static void pef2256_w8(struct pef2256_dev_priv *priv, u32 offset, u8 val)
+{
+	iowrite8(val, priv->ioaddr + offset);
+}
+
+/* helper function - Clear bits in a register */
+static void pef2256_c8(struct pef2256_dev_priv *priv, u32 offset, u8 mask)
+{
+	u8 val = pef2256_r8(priv, offset);
+	iowrite8(val & ~mask, priv->ioaddr + offset);
+}
+
+/* helper function - Set bits in a register */
+static void pef2256_s8(struct pef2256_dev_priv *priv, u32 offset, u8 mask)
+{
+	u8 val = pef2256_r8(priv, offset);
+	iowrite8(val | mask, priv->ioaddr + offset);
+}
+
+static void config_hdlc_timeslot(struct pef2256_dev_priv *priv, int ts)
+{
+	static struct {
+		u32 ttr;
+		u32 rtr;
+	} regs[] = {
+		{ TTR1, RTR1 },
+		{ TTR2, RTR2 },
+		{ TTR3, RTR3 },
+		{ TTR4, RTR4 },
+	};
+	int cfg_bit = 1 << (31 - ts);
+	int reg_bit = 1 << (7 - (ts % 8));
+	int j = ts / 8;
+
+	if (j >= 4)
+		return;
+
+	if (priv->Tx_TS & cfg_bit)
+		pef2256_s8(priv, regs[j].ttr, 1 << reg_bit);
+
+	if (priv->Rx_TS & cfg_bit)
+		pef2256_s8(priv, regs[j].rtr, 1 << reg_bit);
+}
+
+
+/* Setting up HDLC channel */
+static void config_hdlc(struct pef2256_dev_priv *priv)
+{
+	int TS_idx;
+	u8 dummy;
+
+	/* Read to remove pending IT */
+	dummy = pef2256_r8(priv, ISR0);
+	dummy = pef2256_r8(priv, ISR1);
+	dummy = pef2256_r8(priv, ISR2);
+
+	/* Mask HDLC 1 Transmit IT */
+	pef2256_s8(priv, IMR1, IMR1_XPR);
+	pef2256_s8(priv, IMR1, IMR1_XDU);
+	pef2256_s8(priv, IMR1, IMR1_ALLS);
+
+	/* Mask HDLC 1 Receive IT */
+	pef2256_s8(priv, IMR0, IMR0_RPF);
+	pef2256_s8(priv, IMR0, IMR0_RME);
+	pef2256_s8(priv, IMR1, IMR1_RDO);
+
+	/* Mask errors IT */
+	pef2256_s8(priv, IMR0, IMR0_PDEN);
+	pef2256_s8(priv, IMR2, IMR2_LOS);
+	pef2256_s8(priv, IMR2, IMR2_AIS);
+
+	udelay(FALC_HW_CMD_DELAY_US);
+
+	/* 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)
+	 */
+	pef2256_w8(priv, 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 is 32 bytes)
+	 * setting up Interframe Time Fill
+	 * CCR1.ITF = 1 (Interframe Time Fill Continuous flag)
+	 */
+	pef2256_w8(priv, 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)
+	 */
+	pef2256_w8(priv, CCR2, 0x00);
+
+	udelay(FALC_HW_CMD_DELAY_US);
+
+	/* 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)
+	 */
+	pef2256_w8(priv, 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 is 32 bytes)
+	 * setting up Interframe Time Fill
+	 * CCR1.ITF = 1 (Interframe Time Fill Continuous flag)
+	 */
+	pef2256_w8(priv, 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)
+	 */
+	pef2256_w8(priv, CCR2, 0x00);
+
+	udelay(FALC_HW_CMD_DELAY_US);
+
+	/* 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)
+	 */
+	pef2256_w8(priv, 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 is 32 bytes)
+	 * setting up Interframe Time Fill
+	 * CCR1.ITF = 1 (Interframe Time Fill Continuous flag)
+	 */
+	pef2256_w8(priv, 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)
+	 */
+	pef2256_w8(priv, CCR2, 0x00);
+
+	udelay(FALC_HW_CMD_DELAY_US);
+
+	/* Init  Time Slot select */
+	pef2256_w8(priv, TTR1, 0x00);
+	pef2256_w8(priv, TTR2, 0x00);
+	pef2256_w8(priv, TTR3, 0x00);
+	pef2256_w8(priv, TTR4, 0x00);
+	pef2256_w8(priv, RTR1, 0x00);
+	pef2256_w8(priv, RTR2, 0x00);
+	pef2256_w8(priv, RTR3, 0x00);
+	pef2256_w8(priv, RTR4, 0x00);
+	/* Set selected TS bits */
+	/* Starting at TS 1, TS 0 is reserved */
+	for (TS_idx = 1; TS_idx < 32; TS_idx++)
+		config_hdlc_timeslot(priv, TS_idx);
+
+	udelay(FALC_HW_CMD_DELAY_US);
+
+	/* Unmask HDLC 1 Transmit IT */
+	pef2256_c8(priv, IMR1, IMR1_XPR);
+	pef2256_c8(priv, IMR1, IMR1_XDU);
+	pef2256_c8(priv, IMR1, IMR1_ALLS);
+
+	/* Unmask HDLC 1 Receive IT */
+	pef2256_c8(priv, IMR0, IMR0_RPF);
+	pef2256_c8(priv, IMR0, IMR0_RME);
+	pef2256_c8(priv, IMR1, IMR1_RDO);
+
+	/* Unmask errors IT */
+	pef2256_c8(priv, IMR0, IMR0_PDEN);
+	pef2256_c8(priv, IMR2, IMR2_LOS);
+	pef2256_c8(priv, IMR2, IMR2_AIS);
+}
+
+
+static void init_falc(struct pef2256_dev_priv *priv)
+{
+	int version;
+
+	/* Get controller version */
+	version = priv->component_id;
+
+	/* Init FALC56 */
+	/* RCLK output : DPLL clock, DCO-X enabled, DCO-X internal reference
+	 * clock
+	 */
+	pef2256_w8(priv, CMR1, 0x00);
+	/* SCLKR selected, SCLKX selected, receive synchro pulse sourced by
+	 * SYPR, transmit synchro pulse sourced by SYPX
+	 */
+	pef2256_w8(priv, CMR2, 0x00);
+	/* NRZ coding, no alarm simulation */
+	pef2256_w8(priv, 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
+	 */
+	pef2256_w8(priv, FMR1, 0x00);
+	pef2256_w8(priv, FMR2, 0x02);
+	/* E1 default for LIM2 */
+	pef2256_w8(priv, LIM2, 0x20);
+	if (priv->mode == MASTER_MODE)
+		/* SEC input, active high */
+		pef2256_w8(priv, GPC1, 0x00);
+	else
+		/* FSC output, active high */
+		pef2256_w8(priv, GPC1, 0x40);
+	/* internal second timer, power on */
+	pef2256_w8(priv, GCR, 0x00);
+	/* slave mode, local loop off, mode short-haul */
+	if (version == VERSION_1_2)
+		pef2256_w8(priv, LIM0, 0x00);
+	else
+		pef2256_w8(priv, LIM0, 0x08);
+	/* analog interface selected, remote loop off */
+	pef2256_w8(priv, 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
+		 */
+		pef2256_w8(priv, PC1, 0x77);
+		pef2256_w8(priv, PC2, 0x77);
+		pef2256_w8(priv, PC3, 0x77);
+		pef2256_w8(priv, PC4, 0x77);
+	} else {
+		/* function of ports RP(A to D) : output high
+		 * function of ports XP(A to D) : output high
+		 */
+		pef2256_w8(priv, PC1, 0xAA);
+		pef2256_w8(priv, PC2, 0xAA);
+		pef2256_w8(priv, PC3, 0xAA);
+		pef2256_w8(priv, PC4, 0xAA);
+	}
+	/* function of port RPA : input SYPR
+	 * function of port XPA : input SYPX
+	 */
+	pef2256_w8(priv, PC1, 0x00);
+	/* SCLKR, SCLKX, RCLK configured to inputs,
+	 * XFMS active low, CLK1 and CLK2 pin configuration
+	 */
+	pef2256_w8(priv, PC5, 0x00);
+	pef2256_w8(priv, PC6, 0x00);
+	/* the receive clock offset is cleared
+	 * the receive time slot offset is cleared
+	 */
+	pef2256_w8(priv, RC0, 0x00);
+	pef2256_w8(priv, 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
+	 */
+	pef2256_w8(priv, SIC1, 0x00);
+	pef2256_w8(priv, SIC2, 0x00);
+	pef2256_w8(priv, SIC3, 0x00);
+	/* channel loop-back and single frame mode are disabled */
+	pef2256_w8(priv, LOOP, 0x00);
+	/* all bits of the transmitted service word are cleared */
+	pef2256_w8(priv, XSW, 0x1F);
+	/* spare bit values are cleared */
+	pef2256_w8(priv, XSP, 0x00);
+	/* no transparent mode active */
+	pef2256_w8(priv, TSWM, 0x00);
+	/* the transmit clock offset is cleared
+	 * the transmit time slot offset is cleared
+	 */
+	pef2256_w8(priv, XC0, 0x00);
+	pef2256_w8(priv, XC1, 0x9C);
+	/* transmitter in tristate mode */
+	pef2256_w8(priv, XPM2, 0x40);
+	/* transmit pulse mask */
+	if (version != VERSION_1_2)
+		pef2256_w8(priv, XPM0, 0x9C);
+
+	if (version == VERSION_1_2) {
+		/* master clock is 16,384 MHz (flexible master clock) */
+		pef2256_w8(priv, GCM2, 0x58);
+		pef2256_w8(priv, GCM3, 0xD2);
+		pef2256_w8(priv, GCM4, 0xC2);
+		pef2256_w8(priv, GCM5, 0x07);
+		pef2256_w8(priv, GCM6, 0x10);
+	} else {
+		/* master clock is 16,384 MHz (flexible master clock) */
+		pef2256_w8(priv, GCM2, 0x18);
+		pef2256_w8(priv, GCM3, 0xFB);
+		pef2256_w8(priv, GCM4, 0x0B);
+		pef2256_w8(priv, GCM5, 0x01);
+		pef2256_w8(priv, GCM6, 0x0B);
+		pef2256_w8(priv, GCM7, 0xDB);
+		pef2256_w8(priv, GCM8, 0xDF);
+	}
+
+	/* master mode */
+	if (priv->mode == MASTER_MODE)
+		pef2256_s8(priv, LIM0, LIM0_MAS);
+
+	/* transmit line in normal operation */
+	pef2256_c8(priv, XPM2, XPM2_XLT);
+
+	if (version == VERSION_1_2) {
+		/* receive input threshold = 0,21V */
+		pef2256_s8(priv, LIM1, LIM1_RIL0);
+		pef2256_c8(priv, LIM1, LIM1_RIL1);
+		pef2256_s8(priv, LIM1, LIM1_RIL2);
+	} else {
+		/* receive input threshold = 0,21V */
+		pef2256_c8(priv, LIM1, LIM1_RIL0);
+		pef2256_c8(priv, LIM1, LIM1_RIL1);
+		pef2256_s8(priv, LIM1, LIM1_RIL2);
+	}
+	/* transmit line coding = HDB3 */
+	pef2256_s8(priv, FMR0, FMR0_XC0);
+	pef2256_s8(priv, FMR0, FMR0_XC1);
+	/* receive line coding = HDB3 */
+	pef2256_s8(priv, FMR0, FMR0_RC0);
+	pef2256_s8(priv, FMR0, FMR0_RC1);
+	/* detection of LOS alarm = 176 pulses (soit (10 + 1) * 16) */
+	pef2256_w8(priv, PCD, 10);
+	/* recovery of LOS alarm = 22 pulses (soit 21 + 1) */
+	pef2256_w8(priv, PCR, 21);
+	/* DCO-X center frequency => CMR2.DCOXC */
+	pef2256_s8(priv, CMR2, CMR2_DCOXC);
+	if (priv->mode == SLAVE_MODE) {
+		/* select RCLK source = 2M */
+		pef2256_c8(priv, CMR1, CMR1_RS0);
+		pef2256_s8(priv, CMR1, CMR1_RS1);
+		/* disable switching RCLK -> SYNC */
+		pef2256_s8(priv, CMR1, CMR1_DCS);
+	}
+	if (version != VERSION_1_2)
+		/* during inactive channel phase RDO into tri-state mode */
+		pef2256_s8(priv, SIC3, 1 << 5);
+	if (!strcmp(priv->rising_edge_sync_pulse, "transmit")) {
+		/* rising edge sync pulse transmit */
+		pef2256_c8(priv, SIC3, SIC3_RESR);
+		pef2256_s8(priv, SIC3, SIC3_RESX);
+	} else {
+		/* rising edge sync pulse receive */
+		pef2256_c8(priv, SIC3, SIC3_RESX);
+		pef2256_s8(priv, SIC3, SIC3_RESR);
+	}
+	/* transmit offset counter = 4
+	 *  => XC0.XCO10:8 = 000 (bits 2, 1 et 0);
+	 *     XC1.XCO7:0 = 4 (bits 7 ... 0)
+	 */
+	pef2256_w8(priv, XC1, 4);
+	/* receive offset counter = 4
+	 * => RC0.RCO10:8 = 000 (bits 2, 1 et 0);
+	 *    RC1.RCO7:0 = 4 (bits 7 ... 0)
+	 */
+	pef2256_w8(priv, RC1, 4);
+
+	/* Clocking rate for FALC56 */
+
+	/* Nothing to do for clocking rate 2M  */
+
+	/* clocking rate 4M  */
+	if (priv->clock_rate == CLOCK_RATE_4M)
+		pef2256_s8(priv, SIC1, SIC1_SSC0);
+
+	/* clocking rate 8M  */
+	if (priv->clock_rate == CLOCK_RATE_8M)
+		pef2256_s8(priv, SIC1, SIC1_SSC1);
+
+	/* clocking rate 16M  */
+	if (priv->clock_rate == CLOCK_RATE_16M) {
+		pef2256_s8(priv, SIC1, SIC1_SSC0);
+		pef2256_s8(priv, SIC1, SIC1_SSC1);
+	}
+
+	/* data rate for FALC56 */
+
+	/* Nothing to do for data rate 2M on the system data bus */
+
+	/* data rate 4M on the system data bus */
+	if (priv->data_rate == DATA_RATE_4M)
+		pef2256_s8(priv, FMR1, FMR1_SSD0);
+
+	/* data rate 8M on the system data bus */
+	if (priv->data_rate == DATA_RATE_8M)
+		pef2256_s8(priv, SIC1, SIC1_SSD1);
+
+	/* data rate 16M on the system data bus */
+	if (priv->data_rate == DATA_RATE_16M) {
+		pef2256_s8(priv, FMR1, FMR1_SSD0);
+		pef2256_s8(priv, SIC1, SIC1_SSD1);
+	}
+
+	/* channel phase for FALC56 */
+
+	/* Nothing to do for channel phase 1 */
+
+	if (priv->channel_phase == CHANNEL_PHASE_2)
+		pef2256_s8(priv, SIC2, SIC2_SICS0);
+
+	if (priv->channel_phase == CHANNEL_PHASE_3)
+		pef2256_s8(priv, SIC2, SIC2_SICS1);
+
+	if (priv->channel_phase == CHANNEL_PHASE_4) {
+		pef2256_s8(priv, SIC2, SIC2_SICS0);
+		pef2256_s8(priv, SIC2, SIC2_SICS1);
+	}
+
+	if (priv->channel_phase == CHANNEL_PHASE_5)
+		pef2256_s8(priv, SIC2, SIC2_SICS2);
+
+	if (priv->channel_phase == CHANNEL_PHASE_6) {
+		pef2256_s8(priv, SIC2, SIC2_SICS0);
+		pef2256_s8(priv, SIC2, SIC2_SICS2);
+	}
+
+	if (priv->channel_phase == CHANNEL_PHASE_7) {
+		pef2256_s8(priv, SIC2, SIC2_SICS1);
+		pef2256_s8(priv, SIC2, SIC2_SICS2);
+	}
+
+	if (priv->channel_phase == CHANNEL_PHASE_8) {
+		pef2256_s8(priv, SIC2, SIC2_SICS0);
+		pef2256_s8(priv, SIC2, SIC2_SICS1);
+		pef2256_s8(priv, SIC2, SIC2_SICS2);
+	}
+
+	if (priv->mode == SLAVE_MODE)
+		/* transmit buffer size = 2 frames */
+		pef2256_s8(priv, SIC1, SIC1_XBS1);
+
+	/* transmit in multiframe */
+	pef2256_s8(priv, FMR1, FMR1_XFS);
+	/* receive in multiframe */
+	pef2256_s8(priv, FMR2, FMR2_RFS1);
+	/* Automatic transmission of submultiframe status */
+	pef2256_s8(priv, XSP, XSP_AXS);
+
+	/* error counter mode toutes les 1s */
+	pef2256_s8(priv, FMR1, FMR1_ECM);
+	/* error counter mode COFA => GCR.ECMC = 1 (bit 4) */
+	pef2256_s8(priv, GCR, GCR_ECMC);
+	/* errors in service words with no influence */
+	pef2256_s8(priv, RC0, RC0_SWD);
+	/* 4 consecutive incorrect FAS = loss of sync */
+	pef2256_s8(priv, RC0, RC0_ASY4);
+	/* Si-Bit in service word from XDI */
+	pef2256_s8(priv, XSW, XSW_XSIS);
+	/* Si-Bit in FAS word from XDI */
+	pef2256_s8(priv, XSP, XSP_XSIF);
+
+	/* port RCLK is output */
+	pef2256_s8(priv, PC5, PC5_CRP);
+	/* visibility of the masked interrupts */
+	pef2256_s8(priv, GCR, GCR_VIS);
+	/* reset lines
+	 *  => CMDR.RRES = 1 (bit 6); CMDR.XRES = 1 (bit 4);
+	 *     CMDR.SRES = 1 (bit 0)
+	 */
+	pef2256_w8(priv, CMDR, 0x51);
+}
+
+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;
+	long int value;
+	int ret = kstrtol(buf, 10, &value);
+	int reconfigure = (value != priv->mode);
+
+	if (value != MASTER_MODE && value != SLAVE_MODE)
+		ret = -EINVAL;
+
+	if (ret < 0)
+		netdev_info(ndev, "Invalid mode (0 or 1 expected\n");
+	else {
+		priv->mode = value;
+		if (reconfigure && netif_carrier_ok(ndev))
+			init_falc(priv);
+	}
+
+	return strnlen(buf, 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;
+	unsigned long value;
+	int ret = kstrtoul(buf, 16, (long int *)&value);
+	int reconfigure = (value != priv->mode);
+
+	/* TS 0 is reserved */
+	if (ret < 0 || value > TS_0)
+		ret = -EINVAL;
+
+	if (ret < 0)
+		netdev_info(ndev, "Invalid Tx_TS (hex number > 0 and < 0x80000000 expected\n");
+	else {
+		priv->Tx_TS = value;
+		if (reconfigure && netif_carrier_ok(ndev))
+			config_hdlc(priv);
+	}
+
+	return strnlen(buf, 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;
+	unsigned long value;
+	int ret = kstrtoul(buf, 16, &value);
+	int reconfigure = (value != priv->mode);
+
+	/* TS 0 is reserved */
+	if (ret < 0 || value > TS_0)
+		ret = -EINVAL;
+
+	if (ret < 0)
+		netdev_info(ndev, "Invalid Rx_TS (hex number > 0 and < 0x80000000 expected\n");
+	else {
+		priv->Rx_TS = value;
+		if (reconfigure && netif_carrier_ok(ndev))
+			config_hdlc(priv);
+	}
+
+	return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(Rx_TS, S_IRUGO | S_IWUSR, fs_attr_Rx_TS_show,
+	 fs_attr_Rx_TS_store);
+
+
+static void pef2256_fifo_ack(struct pef2256_dev_priv *priv)
+{
+	pef2256_s8(priv, CMDR, 1 << 7);
+}
+
+
+static void pef2256_rx(struct pef2256_dev_priv *priv)
+{
+	int idx;
+
+	/* RDO has been received -> wait for RME */
+	if (priv->stats.rx_bytes == -1) {
+		pef2256_fifo_ack(priv);
+
+		if (priv->r_isr0 & ISR0_RME)
+			priv->stats.rx_bytes = 0;
+
+		return;
+	}
+
+	/* RPF : a block is available in the receive FIFO */
+	if (priv->r_isr0 & ISR0_RPF) {
+		for (idx = 0; idx < 32; idx++)
+			priv->rx_buff[priv->stats.rx_bytes + idx] =
+				pef2256_r8(priv, RFIFO + (idx & 1));
+
+		pef2256_fifo_ack(priv);
+
+		priv->stats.rx_bytes += 32;
+	}
+
+	/* RME : Message end : Read the receive FIFO */
+	if (priv->r_isr0 & ISR0_RME) {
+		/* Get size of last block */
+		int size = pef2256_r8(priv, RBCL) & 0x1F;
+
+		/* Read last block */
+		for (idx = 0; idx < size; idx++)
+			priv->rx_buff[priv->stats.rx_bytes + idx] =
+				pef2256_r8(priv, RFIFO + (idx & 1));
+
+		pef2256_fifo_ack(priv);
+
+		priv->stats.rx_bytes += size;
+
+		/* Packet received */
+		if (priv->stats.rx_bytes > 0) {
+			struct sk_buff *skb =
+				dev_alloc_skb(priv->stats.rx_bytes);
+
+			if (!skb) {
+				priv->stats.rx_bytes = 0;
+				priv->netdev->stats.rx_dropped++;
+				return;
+			}
+			memcpy(skb->data, priv->rx_buff, priv->stats.rx_bytes);
+			skb_put(skb, priv->stats.rx_bytes);
+			priv->stats.rx_bytes = 0;
+			skb->protocol = hdlc_type_trans(skb, priv->netdev);
+			priv->netdev->stats.rx_packets++;
+			priv->netdev->stats.rx_bytes += skb->len;
+			netif_rx(skb);
+		}
+	}
+}
+
+
+static void pef2256_tx(struct pef2256_dev_priv *priv)
+{
+	int idx, size;
+	u8 *tx_buff = priv->tx_skb->data;
+
+	/* ALLS : transmit all done */
+	if (priv->r_isr1 & ISR1_ALLS) {
+		priv->netdev->stats.tx_packets++;
+		priv->netdev->stats.tx_bytes += priv->tx_skb->len;
+		priv->tx_skb = NULL;
+		priv->stats.tx_bytes = 0;
+		netif_wake_queue(priv->netdev);
+	} else
+		/* XPR : write a new block in transmit FIFO */
+		if (priv->stats.tx_bytes < priv->tx_skb->len) {
+			size = priv->tx_skb->len - priv->stats.tx_bytes;
+			if (size > 32)
+				size = 32;
+
+			for (idx = 0; idx < size; idx++)
+				pef2256_w8(priv, XFIFO + (idx & 1),
+					tx_buff[priv->stats.tx_bytes + idx]);
+
+			priv->stats.tx_bytes += size;
+
+			if (priv->stats.tx_bytes == priv->tx_skb->len)
+				pef2256_s8(priv, CMDR, (1 << 3) | (1 << 1));
+			else
+				pef2256_s8(priv, CMDR, 1 << 3);
+		}
+}
+
+static void pef2256_errors(struct pef2256_dev_priv *priv)
+{
+	if (pef2256_r8(priv, FRS1) & FRS1_PDEN ||
+	    pef2256_r8(priv, FRS0) & (FRS0_LOS | FRS0_AIS)) {
+		if (priv->tx_skb) {
+			priv->netdev->stats.tx_errors++;
+			priv->tx_skb = NULL;
+			priv->stats.tx_bytes = 0;
+			netif_wake_queue(priv->netdev);
+		}
+		if (priv->stats.rx_bytes > 0) {
+			priv->netdev->stats.rx_errors++;
+			priv->stats.rx_bytes = 0;
+		}
+		netif_carrier_off(priv->netdev);
+	} else
+		netif_carrier_on(priv->netdev);
+}
+
+static irqreturn_t pef2256_irq(int irq, void *dev_priv)
+{
+	struct pef2256_dev_priv *priv = (struct pef2256_dev_priv *)dev_priv;
+	u8 r_gis;
+
+	r_gis = pef2256_r8(priv, GIS);
+
+	priv->r_isr0 = priv->r_isr1 = 0;
+
+	/* We only care about ISR0, ISR1 and ISR2 */
+	/* ISR0 */
+	if (r_gis & GIS_ISR0)
+		priv->r_isr0 =
+			pef2256_r8(priv, ISR0) & ~(pef2256_r8(priv, IMR0));
+
+	/* ISR1 */
+	if (r_gis & GIS_ISR1)
+		priv->r_isr1 =
+			pef2256_r8(priv, ISR1) & ~(pef2256_r8(priv, IMR1));
+
+	/* ISR2 */
+	if (r_gis & GIS_ISR2)
+		priv->r_isr2 =
+			pef2256_r8(priv, ISR2) & ~(pef2256_r8(priv, IMR2));
+
+	/* An error status has changed */
+	if (priv->r_isr0 & ISR0_PDEN || priv->r_isr2 & ISR2_LOS ||
+	    priv->r_isr2 & ISR2_AIS)
+		pef2256_errors(priv);
+
+	/* RDO : Receive data overflow -> RX error */
+	if (priv->r_isr1 & ISR1_RDO) {
+		pef2256_fifo_ack(priv);
+		priv->netdev->stats.rx_errors++;
+		/* RME received ? */
+		if (priv->r_isr0 & ISR0_RME)
+			priv->stats.rx_bytes = 0;
+		else
+			priv->stats.rx_bytes = -1;
+	} else
+		/* RPF or RME : FIFO received */
+		if (priv->r_isr0 & (ISR0_RPF | ISR0_RME))
+			pef2256_rx(priv);
+
+	/* XDU : Transmit data underrun -> TX error */
+	if (priv->r_isr1 & ISR1_XDU) {
+		priv->netdev->stats.tx_errors++;
+		priv->tx_skb = NULL;
+		netif_wake_queue(priv->netdev);
+	} else
+		/* XPR or ALLS : FIFO sent */
+		if (priv->r_isr1 & (ISR1_XPR | ISR1_ALLS))
+			pef2256_tx(priv);
+
+	return IRQ_HANDLED;
+}
+
+
+static int pef2256_open(struct net_device *netdev)
+{
+	struct pef2256_dev_priv *priv = dev_to_hdlc(netdev)->priv;
+	int ret;
+	u8 dummy;
+
+	if (priv->component_id == VERSION_UNDEF) {
+		dev_err(priv->dev, "Composant ident (%X/%X) = %d\n",
+			pef2256_r8(priv, VSTR), pef2256_r8(priv, WID),
+				priv->component_id);
+		return -ENODEV;
+	}
+
+	ret = hdlc_open(netdev);
+	if (ret)
+		return ret;
+
+	/* We mask HDLC 1 receive/transmit IT to prevent the component sending
+	 * such interrupts before it is initialized and configured.
+	*/
+
+	/* Read to remove pending IT */
+	dummy = pef2256_r8(priv, ISR0);
+	dummy = pef2256_r8(priv, ISR1);
+	dummy = pef2256_r8(priv, ISR2);
+
+	/* Mask HDLC 1 Transmit IT */
+	pef2256_s8(priv, IMR1, IMR1_XPR);
+	pef2256_s8(priv, IMR1, IMR1_XDU);
+	pef2256_s8(priv, IMR1, IMR1_ALLS);
+
+	/* Mask HDLC 1 Receive IT */
+	pef2256_s8(priv, IMR0, IMR0_RPF);
+	pef2256_s8(priv, IMR0, IMR0_RME);
+	pef2256_s8(priv, IMR1, IMR1_RDO);
+
+	/* Mask errors IT */
+	pef2256_s8(priv, IMR0, IMR0_PDEN);
+	pef2256_s8(priv, IMR2, IMR2_LOS);
+	pef2256_s8(priv, IMR2, IMR2_AIS);
+
+	ret = request_irq(priv->irq, pef2256_irq, 0, "e1-wan", priv);
+	if (ret) {
+		dev_err(priv->dev, "Cannot request irq. Device seems busy.\n");
+		hdlc_close(netdev);
+		return -EBUSY;
+	}
+
+	init_falc(priv);
+
+	priv->tx_skb = NULL;
+	priv->stats.rx_bytes = 0;
+
+	config_hdlc(priv);
+
+	netif_start_queue(netdev);
+	pef2256_errors(priv);
+
+	return 0;
+}
+
+
+static int pef2256_close(struct net_device *netdev)
+{
+	struct pef2256_dev_priv *priv = dev_to_hdlc(netdev)->priv;
+
+	netif_stop_queue(netdev);
+	netif_carrier_off(netdev);
+	hdlc_close(netdev);
+	free_irq(priv->irq, priv);
+
+	return 0;
+}
+
+
+
+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;
+	u8 *tx_buff = skb->data;
+
+	priv->tx_skb = skb;
+	priv->stats.tx_bytes = 0;
+
+	size = priv->tx_skb->len - priv->stats.tx_bytes;
+	if (size > 32)
+		size = 32;
+
+	for (idx = 0; idx < size; idx++)
+		pef2256_w8(priv, XFIFO + (idx & 1),
+			tx_buff[priv->stats.tx_bytes + idx]);
+
+	priv->stats.tx_bytes += size;
+
+	pef2256_s8(priv, CMDR, 1 << 3);
+	if (priv->stats.tx_bytes == priv->tx_skb->len)
+		pef2256_s8(priv, 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   = hdlc_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;
+}
+
+
+static int pef2256_probe(struct platform_device *pdev)
+{
+	struct pef2256_dev_priv *priv;
+	int ret = -ENOMEM;
+	struct net_device *netdev;
+	hdlc_device *hdlc;
+	struct device_node *np = (&pdev->dev)->of_node;
+	const char *str_data;
+
+	if (!pdev->dev.of_node)
+		return -EINVAL;
+
+	dev_err(&pdev->dev, "Found PEF2256\n");
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return ret;
+
+	priv->dev = &pdev->dev;
+
+	if (of_property_read_u32(np, "clock-rate", &priv->clock_rate)) {
+		dev_err(&pdev->dev, "failed to read clock-rate -> using 8Mhz\n");
+		priv->clock_rate = CLOCK_RATE_8M;
+	}
+
+	if (of_property_read_u32(np, "data-rate", &priv->data_rate)) {
+		dev_err(&pdev->dev, "failed to read data-rate -> using 8Mb\n");
+		priv->data_rate = DATA_RATE_8M;
+	}
+
+	if (of_property_read_u32(np, "channel-phase", &priv->channel_phase)) {
+		dev_err(&pdev->dev, "failed to read channel phase -> using 0\n");
+		priv->channel_phase = CHANNEL_PHASE_0;
+	}
+
+	if (of_property_read_string(np, "rising-edge-sync-pulse", &str_data)) {
+		dev_err(&pdev->dev,
+"failed to read rising edge sync pulse -> using \"transmit\"\n");
+		strcpy(priv->rising_edge_sync_pulse, "transmit");
+	} else if (strcmp(str_data, "transmit") &&
+		   strcmp(str_data, "receive")) {
+		dev_err(&pdev->dev,
+"invalid rising edge sync pulse \"%s\" -> using \"transmit\"\n", str_data);
+		strcpy(priv->rising_edge_sync_pulse, "transmit");
+	} else
+		strncpy(priv->rising_edge_sync_pulse, str_data, 10);
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (!priv->irq) {
+		dev_err(priv->dev, "no irq defined\n");
+		goto free_priv;
+	}
+
+	priv->ioaddr = of_iomap(np, 0);
+	if (!priv->ioaddr) {
+		dev_err(&pdev->dev, "of_iomap failed\n");
+		goto free_priv;
+	}
+
+	/* Get the component Id */
+	priv->component_id = VERSION_UNDEF;
+	if (pef2256_r8(priv, VSTR) == 0x00) {
+		if ((pef2256_r8(priv, WID) & WID_IDENT_1) ==
+			WID_IDENT_1_2)
+			priv->component_id = VERSION_1_2;
+	} else if (pef2256_r8(priv, VSTR) == 0x05) {
+		if ((pef2256_r8(priv, WID) & WID_IDENT_2) ==
+			WID_IDENT_2_1)
+			priv->component_id = VERSION_2_1;
+		else if ((pef2256_r8(priv, 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) {
+		dev_err(&pdev->dev, "alloc_hdlcdev failed\n");
+		ret = -ENOMEM;
+		goto free_regs;
+	}
+
+	priv->netdev = netdev;
+	hdlc = dev_to_hdlc(netdev);
+	netdev->netdev_ops = &pef2256_ops;
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+	hdlc->attach = pef2256_hdlc_attach;
+	hdlc->xmit = pef2256_start_xmit;
+
+	dev_set_drvdata(&pdev->dev, netdev);
+
+	ret = register_hdlc_device(netdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Can't register hdlc device\n");
+		goto free_dev;
+	}
+
+	/* These files are required to configure HDLC : mode
+	 * (master or slave), time slots used to transmit and
+	 * receive data. They are mandatory.
+	 */
+	ret = device_create_file(priv->dev, &dev_attr_mode);
+	ret |= device_create_file(priv->dev, &dev_attr_Tx_TS);
+	ret |= device_create_file(priv->dev, &dev_attr_Rx_TS);
+
+	if (ret)
+		goto remove_files;
+
+	return 0;
+
+remove_files:
+	device_remove_file(priv->dev, &dev_attr_Tx_TS);
+	device_remove_file(priv->dev, &dev_attr_Rx_TS);
+	device_remove_file(priv->dev, &dev_attr_mode);
+
+	unregister_hdlc_device(priv->netdev);
+free_dev:
+	free_netdev(priv->netdev);
+free_regs:
+	iounmap(priv->ioaddr);
+free_priv:;
+	kfree(priv);
+
+	return ret;
+}
+
+
+static int pef2256_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
+	struct pef2256_dev_priv *priv = dev_to_hdlc(ndev)->priv;
+
+
+	device_remove_file(priv->dev, &dev_attr_Tx_TS);
+	device_remove_file(priv->dev, &dev_attr_Rx_TS);
+	device_remove_file(priv->dev, &dev_attr_mode);
+
+	unregister_hdlc_device(priv->netdev);
+
+	free_netdev(priv->netdev);
+
+	iounmap(priv->ioaddr);
+
+	kfree(priv);
+
+	kfree(pdev);
+	return 0;
+}
+
+static const struct of_device_id pef2256_match[] = {
+	{
+		.compatible = "lantiq,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,
+	},
+};
+
+
+module_platform_driver(pef2256_driver);
+
+/* GENERAL INFORMATIONS */
+MODULE_AUTHOR("CHANTELAUZE Jerome - April 2013");
+MODULE_VERSION("0.1");
+MODULE_DESCRIPTION("Lantiq 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,327 @@
+/* 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 CHANNEL_PHASE_4 4
+#define CHANNEL_PHASE_5 5
+#define CHANNEL_PHASE_6 6
+#define CHANNEL_PHASE_7 7
+#define CHANNEL_PHASE_8 8
+
+#define CLOCK_RATE_2M 2
+#define CLOCK_RATE_4M 4
+#define CLOCK_RATE_8M 8
+#define CLOCK_RATE_16M 16
+
+#define DATA_RATE_2M 2
+#define DATA_RATE_4M 4
+#define DATA_RATE_8M 8
+#define DATA_RATE_16M 16
+
+#define RX_TIMEOUT 500
+
+#define TS_0 0x80000000
+
+/* The hardware requires a delay up to 2*32*125 usec to take commands
+ * into account
+ */
+#define FALC_HW_CMD_DELAY_US (2 * 32 * 125)
+
+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
+
+/* Registers' bits */
+#define GIS_ISR0			1
+#define GIS_ISR1			(1 << 1)
+#define GIS_ISR2			(1 << 2)
+#define ISR0_RPF			1
+#define ISR0_PDEN			(1 << 1)
+#define ISR0_RME			(1 << 7)
+#define ISR1_XPR			1
+#define ISR1_XDU			(1 << 4)
+#define ISR1_ALLS			(1 << 5)
+#define ISR1_RDO			(1 << 6)
+#define ISR2_LOS			(1 << 2)
+#define ISR2_AIS			(1 << 3)
+#define IMR0_RPF			1
+#define IMR0_PDEN			1
+#define IMR0_RME			(1 << 7)
+#define IMR1_XPR			1
+#define IMR1_XDU			(1 << 4)
+#define IMR1_ALLS			(1 << 5)
+#define IMR1_RDO			(1 << 6)
+#define IMR2_LOS			(1 << 2)
+#define IMR2_AIS			(1 << 3)
+#define LIM0_MAS			1
+#define LIM1_RIL0			(1 << 4)
+#define LIM1_RIL1			(1 << 5)
+#define LIM1_RIL2			(1 << 6)
+#define FMR0_RC0			(1 << 4)
+#define FMR0_RC1			(1 << 5)
+#define FMR0_XC0			(1 << 6)
+#define FMR0_XC1			(1 << 7)
+#define FMR1_SSD0			(1 << 1)
+#define FMR1_ECM			(1 << 2)
+#define FMR1_XFS			(1 << 3)
+#define FMR2_RFS0			(1 << 6)
+#define FMR2_RFS1			(1 << 7)
+#define FRS0_AIS			(1 << 7)
+#define FRS0_LOS			(1 << 6)
+#define FRS1_PDEN			(1 << 6)
+#define CMR2_DCOXC			(1 << 5)
+#define CMR1_DCS			(1 << 3)
+#define CMR1_RS0			(1 << 4)
+#define CMR1_RS1			(1 << 5)
+#define SIC3_RESR			(1 << 2)
+#define SIC3_RESX			(1 << 3)
+#define SIC2_SICS0			(1 << 1)
+#define SIC2_SICS1			(1 << 2)
+#define SIC2_SICS2			(1 << 3)
+#define SIC1_XBS0			(1 << 1)
+#define SIC1_XBS1			(1 << 1)
+#define SIC1_SSC0			(1 << 3)
+#define SIC1_SSD1			(1 << 6)
+#define SIC1_SSC1			(1 << 7)
+#define XSP_XSIF			(1 << 2)
+#define XSP_AXS				(1 << 3)
+#define GCR_ECMC			(1 << 4)
+#define GCR_SCI				(1 << 6)
+#define GCR_VIS				(1 << 7)
+#define RC0_SWD				(1 << 7)
+#define RC0_ASY4			(1 << 6)
+#define XSW_XSIS			(1 << 7)
+#define PC5_CRP				1
+#define XPM2_XLT			(1 << 6)
+
+struct pef2256_dev_priv {
+	struct sk_buff *tx_skb;
+	struct device *dev;
+
+	void __iomem *ioaddr;
+	int component_id;
+	int mode;	/* MASTER or SLAVE */
+	int board_type;
+	int channel_phase;
+	int clock_rate;
+	int data_rate;
+	char rising_edge_sync_pulse[10];
+
+	u8 rx_buff[2048];
+
+	struct net_device_stats stats;
+
+	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 r_isr0;			/* ISR0 register */
+	u8 r_isr1;			/* ISR1 register */
+	u8 r_isr2;			/* ISR2 register */
+};
+
+
+/* Framer E1 registers offsets */
+#define XFIFO	0x00	/* 0x00/0x01	Tx FIFO */
+#define RFIFO	0x00	/* 0x00/0x01	Rx FIFO */
+#define	CMDR	0x02	/* 0x02	Command Register */
+#define	MODE	0x03	/* 0x03	Mode Register */
+#define	RAH1	0x04	/* 0x04	Receive Address High 1 */
+#define	RAH2	0x05	/* 0x05	Receive Address High 2 */
+#define	RAL1	0x06	/* 0x06	Receive Address Low 1 */
+#define	RAL2	0x07	/* 0x07	Receive Address Low 2 */
+#define	IPC	0x08	/* 0x08	Interrupt Port Configuration */
+#define	CCR1	0x09	/* 0x09	Common Configuration Register 1 */
+#define	CCR2	0x0A	/* 0x0A	Common Configuration Register 2 */
+#define	Res1	0x0B	/* 0x0B	Free Register 1 */
+#define	RTR1	0x0C	/* 0x0C	Receive Time Slot Register 1 */
+#define	RTR2	0x0D	/* 0x0D	Receive Time Slot Register 2 */
+#define	RTR3	0x0E	/* 0x0E	Receive Time Slot Register 3 */
+#define	RTR4	0x0F	/* 0x0F	Receive Time Slot Register 4 */
+#define	TTR1	0x10	/* 0x10	Transmit Time Slot Register 1 */
+#define	TTR2	0x11	/* 0x11	Transmit Time Slot Register 2 */
+#define	TTR3	0x12	/* 0x12	Transmit Time Slot Register 3 */
+#define	TTR4	0x13	/* 0x13	Transmit Time Slot Register 4 */
+#define	IMR0	0x14	/* 0x14	Interrupt Mask Register 0 */
+#define	IMR1	0x15	/* 0x15	Interrupt Mask Register 1 */
+#define	IMR2	0x16	/* 0x16	Interrupt Mask Register 2 */
+#define	IMR3	0x17	/* 0x17	Interrupt Mask Register 3 */
+#define	IMR4	0x18	/* 0x18	Interrupt Mask Register 4 */
+#define	IMR5	0x19	/* 0x19	Interrupt Mask Register 5 */
+#define	Res2	0x1A	/* 0x1A	Free Register 2 */
+#define	IERR	0x1B	/* 0x1B	Single Bit Error Insertion Register */
+#define	FMR0	0x1C	/* 0x1C	Framer Mode Register 0 */
+#define	FMR1	0x1D	/* 0x1D	Framer Mode Register 1 */
+#define	FMR2	0x1E	/* 0x1E	Framer Mode Register 2 */
+#define	LOOP	0x1F	/* 0x1F	Channel Loop-Back */
+#define	XSW	0x20	/* 0x20	Transmit Service Word */
+#define	XSP	0x21	/* 0x21	Transmit Spare Bits */
+#define	XC0	0x22	/* 0x22	Transmit Control 0 */
+#define	XC1	0x23	/* 0x23	Transmit Control 1 */
+#define	RC0	0x24	/* 0x24	Receive Control 0 */
+#define	RC1	0x25	/* 0x25	Receive Control 1 */
+#define	XPM0	0x26	/* 0x26	Transmit Pulse Mask 0 */
+#define	XPM1	0x27	/* 0x27	Transmit Pulse Mask 1 */
+#define	XPM2	0x28	/* 0x28	Transmit Pulse Mask 2 */
+#define	TSWM	0x29	/* 0x29	Transparent Service Word Mask */
+#define	Res3	0x2A	/* 0x2A	Free Register 3 */
+#define	IDLE	0x2B	/* 0x2B	Idle Channel Code */
+#define	XSA4	0x2C	/* 0x2C	Transmit Sa4-Bit Register */
+#define	XSA5	0x2D	/* 0x2D	Transmit Sa5-Bit Register */
+#define	XSA6	0x2E	/* 0x2E	Transmit Sa6-Bit Register */
+#define	XSA7	0x2F	/* 0x2F	Transmit Sa7-Bit Register */
+#define	XSA8	0x30	/* 0x30	Transmit Sa8-Bit Register */
+#define	FMR3	0x31	/* 0x31	Framer Mode Register 3 */
+#define	ICB1	0x32	/* 0x32	Idle Channel Register 1 */
+#define	ICB2	0x33	/* 0x33	Idle Channel Register 2 */
+#define	ICB3	0x34	/* 0x34	Idle Channel Register 3 */
+#define	ICB4	0x35	/* 0x35	Idle Channel Register 4 */
+#define	LIM0	0x36	/* 0x36	Line Interface Mode 0 */
+#define	LIM1	0x37	/* 0x37	Line Interface Mode 1 */
+#define	PCD	0x38	/* 0x38	Pulse Count Detection */
+#define	PCR	0x39	/* 0x39	Pulse Count Recovery */
+#define	LIM2	0x3A	/* 0x3A	Line Interface Mode 2 */
+#define	LCR1	0x3B	/* 0x3B	Loop Code Register 1 */
+#define	LCR2	0x3C	/* 0x3C	Loop Code Register 2 */
+#define	LCR3	0x3D	/* 0x3D	Loop Code Register 3 */
+#define	SIC1	0x3E	/* 0x3E	System Interface Control 1 */
+#define	SIC2	0x3F	/* 0x3F	System Interface Control 2 */
+#define	SIC3	0x40	/* 0x40	System Interface Control 3 */
+#define	Res4	0x41	/* 0x41	Free Register 4 */
+#define	Res5	0x42	/* 0x42	Free Register 5 */
+#define	Res6	0x43	/* 0x43	Free Register 6 */
+#define	CMR1	0x44	/* 0x44	Clock Mode Register 1 */
+#define	CMR2	0x45	/* 0x45	Clock Mode Register 2 */
+#define	GCR	0x46	/* 0x46	Global Configuration Register */
+#define	ESM	0x47	/* 0x47	Errored Second Mask */
+#define	CMR3	0x48	/* 0x48	Clock Mode Register 3 en V2.2 */
+#define	RBD	0x49	/* 0x49	Receive Buffer Delay */
+#define	VSTR	0x4A	/* 0x4A	Version Status Regiter */
+#define	RES	0x4B	/* 0x4B	Receive Equalizer Status */
+#define	FRS0	0x4C	/* 0x4C	Framer Receive Status 0 */
+#define	FRS1	0x4D	/* 0x4D	Framer Receive Status 1 */
+#define	RSW	0x4E	/* 0x4E	Receive Service Word */
+#define	RSP	0x4F	/* 0x4F	Receive Spare Bits */
+#define	FEC	0x50	/* 0x50/0x51 Framing Error Counter */
+#define	CVC	0x52	/* 0x52/0x53 Code Violation Counter */
+#define	CEC1	0x54	/* 0x54/0x55 CRC Error Counter 1 */
+#define	EBC	0x56	/* 0x56/0x57 E-Bit Error Counter */
+#define	CEC2	0x58	/* 0x58/0x59 CRC Error Counter 2 */
+#define	CEC3	0x5A	/* 0x5A/0x5B CRC Error Counter 3 */
+#define	RSA4	0x5C	/* 0x5C	Receive Sa4-Bit Register */
+#define	RSA5	0x5D	/* 0x5D	Receive Sa5-Bit Register */
+#define	RSA6	0x5E	/* 0x5E	Receive Sa6-Bit Register */
+#define	RSA7	0x5F	/* 0x5F	Receive Sa7-Bit Register */
+#define DEC	0x60	/* 0x60 Common Register - Disable Error Counter */
+#define RSA8	0x60	/* 0x60 Common Register - Receive Sa8-Bit Regiter */
+#define	RSA6S	0x61	/* 0x61	Receive Sa6-Bit Status Register */
+#define	RSP1	0x62	/* 0x62	Receive Signaling Pointer 1 */
+#define	RSP2	0x63	/* 0x63	Receive Signaling Pointer 2 */
+#define	SIS	0x64	/* 0x64	Signaling Status Register */
+#define	RSIS	0x65	/* 0x65	Receive Signaling Status Register */
+#define	RBCL	0x66	/* 0x66	Receive Byte Control */
+#define	RBCH	0x67	/* 0x67	Receive Byte Control */
+#define	ISR0	0x68	/* 0x68	Interrupt Status Register 0 */
+#define	ISR1	0x69	/* 0x69	Interrupt Status Register 1 */
+#define	ISR2	0x6A	/* 0x6A	Interrupt Status Register 2 */
+#define	ISR3	0x6B	/* 0x6B	Interrupt Status Register 3 */
+#define	ISR4	0x6C	/* 0x6C	Interrupt Status Register 4 */
+#define	ISR5	0x6D	/* 0x6D	Interrupt Status Register 5 */
+#define	GIS	0x6E	/* 0x6E	Global Interrupt Status */
+#define	Res8	0x6F	/* 0x6F	Free Register 8 */
+#define	CAS1	0x70	/* 0x70	CAS Register 1 */
+#define	CAS2	0x71	/* 0x71	CAS Register 2 */
+#define	CAS3	0x72	/* 0x72	CAS Register 3 */
+#define	CAS4	0x73	/* 0x73	CAS Register 4 */
+#define	CAS5	0x74	/* 0x74	CAS Register 5 */
+#define	CAS6	0x75	/* 0x75	CAS Register 6 */
+#define	CAS7	0x76	/* 0x76	CAS Register 7 */
+#define	CAS8	0x77	/* 0x77	CAS Register 8 */
+#define	CAS9	0x78	/* 0x78	CAS Register 9 */
+#define	CAS10	0x79	/* 0x79	CAS Register 10 */
+#define	CAS11	0x7A	/* 0x7A	CAS Register 11 */
+#define	CAS12	0x7B	/* 0x7B	CAS Register 12 */
+#define	CAS13	0x7C	/* 0x7C	CAS Register 13 */
+#define	CAS14	0x7D	/* 0x7D	CAS Register 14 */
+#define	CAS15	0x7E	/* 0x7E	CAS Register 15 */
+#define	CAS16	0x7F	/* 0x7F	CAS Register 16 */
+#define	PC1	0x80	/* 0x80	Port Configuration 1 */
+#define	PC2	0x81	/* 0x81	Port Configuration 2 */
+#define	PC3	0x82	/* 0x82	Port Configuration 3 */
+#define	PC4	0x83	/* 0x83	Port Configuration 4 */
+#define	PC5	0x84	/* 0x84	Port Configuration 5 */
+#define	GPC1	0x85	/* 0x85	Global Port Configuration 1 */
+#define	PC6	0x86	/* 0x86	Port Configuration 6 */
+#define	CMDR2	0x87	/* 0x87	Command Register 2 */
+#define	CMDR3	0x88	/* 0x88	Command Register 3 */
+#define	CMDR4	0x89	/* 0x89	Command Register 4 */
+#define	Res9	0x8A	/* 0x8A	Free Register 9 */
+#define	CCR3	0x8B	/* 0x8B	Common Control Register 3 */
+#define	CCR4	0x8C	/* 0x8C	Common Control Register 4 */
+#define	CCR5	0x8D	/* 0x8D	Common Control Register 5 */
+#define	MODE2	0x8E	/* 0x8E	Mode Register 2 */
+#define	MODE3	0x8F	/* 0x8F	Mode Register 3 */
+#define	RBC2	0x90	/* 0x90	Receive Byte Count Register 2 */
+#define	RBC3	0x91	/* 0x91	Receive Byte Count Register 3 */
+#define	GCM1	0x92	/* 0x92	Global Counter Mode 1 */
+#define	GCM2	0x93	/* 0x93	Global Counter Mode 2 */
+#define	GCM3	0x94	/* 0x94	Global Counter Mode 3 */
+#define	GCM4	0x95	/* 0x95	Global Counter Mode 4 */
+#define	GCM5	0x96	/* 0x96	Global Counter Mode 5 */
+#define	GCM6	0x97	/* 0x97	Global Counter Mode 6 */
+#define SIS2_1	0x98	/* 0x98 V1.2 : Signaling Status Register 2 */
+#define GCM7	0x98	/* 0x98 V2.2 : Global Counter Mode 7 */
+#define RSIS2_1	0x99	/* 0x99 V1.2 : Rx Signaling Status Register 2 */
+#define GCM8	0x99	/* 0x99 V2.2 : Global Counter Mode 8 */
+#define	SIS3	0x9A	/* 0x9A	Signaling Status Register 3 */
+#define	RSIS3	0x9B	/* 0x9B	Receive Signaling Status Register 3 */
+#define XFIFO2	0x9C	/* 0x9C/0x9D	Tx FIFO 2 */
+#define RFIFO2	0x9C	/* 0x9C/0x9D	Rx FIFO 2 */
+#define XFIFO3	0x9E	/* 0x9E/0x9F	Tx FIFO 3 */
+#define RFIFO3	0x9E	/* 0x9E/0x9F	Rx FIFO 3 */
+#define	TSEO	0xA0	/* 0xA0	Time Slot Even/Odd select */
+#define	TSBS1	0xA1	/* 0xA1	Time Slot Bit select 1 */
+#define	TSBS2	0xA2	/* 0xA2	Time Slot Bit select 2 */
+#define	TSBS3	0xA3	/* 0xA3	Time Slot Bit select 3 */
+#define	TSS2	0xA4	/* 0xA4	Time Slot select 2 */
+#define	TSS3	0xA5	/* 0xA5	Time Slot select 3 */
+#define	Res10	0xA6	/* 0xA6	Free Register 10 */
+#define	Res11	0xA7	/* 0xA7	Free Register 11 */
+#define	TPC0	0xA8	/* 0xA8	Test Pattern Control Register 0 */
+#define	SIS2	0xA9	/* 0xA9	Signaling Status Register 2 (V2.2) */
+#define	RSIS2	0xAA	/* 0xAA	Rx Signaling Status Register 2 (V2.2) */
+#define	MFPI	0xAB	/* 0xAB	Multi Function Port Input Status */
+#define	Res12	0xAC	/* 0xAC	Free Register 12 */
+#define	Res13	0xAD	/* 0xAD	Free Register 13 */
+#define	Res14	0xAE	/* 0xAE	Free Register 14 */
+#define	GLC1	0xAF	/* 0xAF	Global Line Control Register 1 */
+#define Res15	0xB0	/* 0xB0/0xEB Free Registers */
+#define WID	0xEC	/* 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,77 @@
+* Wan on Lantiq PEF2256 E1 controller, also known as FALC56
+
+This chip was originally called "Infineon PEF2256" before the transfer of the
+former "wire-line" business-unit into an own company.
+
+The PEF2256 is a E1/T1/J1 Framer and Line Interface Component for Long- and
+Short-Haul Applications.
+Its datashhet can be downloaded at
+http://www.datasheetcatalog.com/datasheets_pdf/P/E/F/2/PEF2256E.shtml
+
+The FALC56 framer and line interface component is designed to fulfill all
+required interfacing between analog E1 lines and the digital PCM system
+highway, H.100/H.110 or H-MVIP bus.
+
+Required properties:
+- compatible: Should contain "lantiq,pef2256"
+- reg: Address and length of the register set for the device.
+  There should be a single continuous bank.
+- interrupts: Should contain the single interrupt used by the component to
+  notify special events (error, data received, data transmitted, ...).
+
+Optional properties:
+
+These properties can be defined to adjust the system interface in E1 mode.
+
+The FALC56 offers a flexible feature for system designers where for transmit and
+receive direction different system clocks and system pulses are necessary. The
+interface to the receive system highway is realized by two data buses, one for
+the data RDO and one for the signaling data RSIG. The receive highway is clocked
+on pin SCLKR, while the interface to the transmit system highway is
+independently clocked on pin SCLKX. The frequency of these working clocks and
+the data rate of 2.048/4.096/8.192/16.384 Mbit/s for the receive and transmit
+system interface is programmable.
+
+- clock-rate:
+  Supported values are: 2 (2.048 Mhz), 4 (4.096 Mhz), 8 (8.192 Mhz),
+    16 (16.384 Mhz).
+  8 if not defined.
+
+- data-rate:
+  Supported values are: 2 (2.048 Mbit/sec), 4 (4.096 Mbit/sec),
+    8 (8.192 Mbit/sec), 16 (16.384 Mbit/sec).
+  8 if not defined.
+
+Adjusting the frame begin (time slot 0, bit 0) relative to SYPR/X or XMFS is
+possible in the range of 0 to 125 5s. The minimum shift of varying the
+time slot 0 begin can be programmed between 1 bit and 1/8 bit depending of the
+system clocking and data rate, e.g. with a clocking/data rate of 2.048 MHz
+shifting is done bit by bit, while running the FALC56 with 16.384 MHz and
+2.048 Mbit/s data rate it is done by 1/8 bit
+
+- channel-phase: First time slot transmission channel phase.
+  Supported values are: 0, 1, 2, 3, 4, 5, 6, 7. 8
+  0 if not defined.
+
+All transmit or receive system interface data and marker are clocked or sampled
+with the following active edge :
+* Latched with the first falling edge of the selected PCM highway clock.
+* Latched with the first rising edge of the selected PCM highway clock.
+The behaviour of "transmit" and "receive" signals is inverse.
+
+- rising-edge-sync-pulse: rising edge synchronous pulse.
+  Supported values are: "receive", "transmit".
+  "transmit" if not defined.
+
+Examples:
+
+	e1-wan@4,2000000 {
+		compatible = "lantiq,pef2256";
+		reg = <4 0x2000000 0xFF>;
+		interrupts = <8 1>;
+		interrupt-parent = <&PIC>;
+		clock-rate = <4>;
+		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 Lantiq (ex. 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

---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com

^ permalink raw reply

* [PATCH net-next v2] ipv6: enable anycast addresses as source addresses in ICMPv6 error messages
From: Francois-Xavier Le Bail @ 2014-01-19 16:00 UTC (permalink / raw)
  To: netdev
  Cc: David Stevens, Bill Fink, Hannes Frederic Sowa, David S. Miller,
	Alexey Kuznetsov, James Morris, Hideaki Yoshifuji,
	Patrick McHardy, Francois-Xavier Le Bail

- Uses ipv6_anycast_destination() in icmp6_send().

Suggested-by: Bill Fink <billfink@mindspring.com>
Signed-off-by: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
---
v2: Consideration of a Hannes's concern : No sysctl is needed for this change.
    No need for a new check function.

 net/ipv6/icmp.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 902405d..f81f596 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -413,7 +413,8 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 	 */
 	addr_type = ipv6_addr_type(&hdr->daddr);
 
-	if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0))
+	if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
+	    ipv6_anycast_destination(skb))
 		saddr = &hdr->daddr;
 
 	/*

^ permalink raw reply related

* Re: [PATCH V3] net/dt: Add support for overriding phy configuration from device tree
From: Ben Hutchings @ 2014-01-19 15:34 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: netdev, devicetree, linux-kernel, kishon
In-Reply-To: <1389999459-9483-1-git-send-email-matthew.garrett@nebula.com>

[-- Attachment #1: Type: text/plain, Size: 2093 bytes --]

On Fri, 2014-01-17 at 17:57 -0500, Matthew Garrett wrote:
> Some hardware may be broken in interesting and board-specific ways, such
> that various bits of functionality don't work. This patch provides a
> mechanism for overriding mii registers during init based on the contents of
> the device tree data, allowing board-specific fixups without having to
> pollute generic code.
[...]
> --- a/Documentation/devicetree/bindings/net/phy.txt
> +++ b/Documentation/devicetree/bindings/net/phy.txt
> @@ -23,6 +23,21 @@ Optional Properties:
>    assume clause 22. The compatible list may also contain other
>    elements.
>  
> +The following properties may be added to either the phy node or the parent
> +ethernet device. If not present, the hardware defaults will be used.
> +
> +- phy-mii-advertise-10half: 1 to advertise half-duplex 10MBit, 0 to disable
> +- phy-mii-advertise-10full: 1 to advertise full-duplex 10MBit, 0 to disable
> +- phy-mii-advertise-100half: 1 to advertise half-duplex 100MBit, 0 to disable
> +- phy-mii-advertise-100full: 1 to advertise full-duplex 100MBit, 0 to disable
> +- phy-mii-advertise-100base4: 1 to advertise 100base4, 0 to disable
> +- phy-mii-advertise-1000half: 1 to advertise half-duplex 1000MBit, 0 to disable
> +- phy-mii-advertise-1000full: 1 to advertise full-duplex 1000MBit, 0 to disable

Are these really all needed?  Apparently there is a standard 'max-speed'
property on Ethernet devices already, which I think is probably
sufficient to express the actual restrictions of some boards.

> +- phy-mii-manual-master: 1 to enable manual master/slave configuration, 0
> +  to disable manual master/slave configuration
[...]

Although the standard calls this 'manual', if it's set in the DT it
won't really be a manual setting.  The description should probably
clarify that.

I think the name should include 'master-slave' or 'clock-role' rather
than just 'master', as currently it suggests only the master role can be
forced.

Ben.

-- 
Ben Hutchings
friends: People who know you well, but like you anyway.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox