Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v3] packet: fix use after free race in send path when dev is released
From: Ben Greear @ 2013-11-21 22:40 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev, Salam Noureddine, Eric Dumazet
In-Reply-To: <1385049058-1946-1-git-send-email-dborkman@redhat.com>

On 11/21/2013 07:50 AM, Daniel Borkmann wrote:
> Salam reported a use after free bug in PF_PACKET that occurs when
> we're sending out frames on a socket bound device and suddenly the
> net device is being unregistered. It appears that commit 827d9780
> introduced a possible race condition between {t,}packet_snd() and
> packet_notifier(). In the case of a bound socket, packet_notifier()
> can drop the last reference to the net_device and {t,}packet_snd()
> might end up suddenly sending a packet over a freed net_device.


Thank you all for finding and fixing this!

Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* [PATCH 0/1] Bridge mirroring function
From: Glenn FEUNTEUN @ 2013-11-21 22:33 UTC (permalink / raw)
  To: netdev
In-Reply-To: <322017e8-c793-4729-8937-7edc3328f14b@zmail220>

Hello

I am working on a school project whose goal is to implement a traffic mirroring function inside bridge kernel module.

I implemented the function that lets :
- select the mirrored interface(s)
- select ingress, egress or both traffic to be mirrored
- select the output interface(s)

Examples :

a)

brctl mirror br0 eth0 ingress
brclt mirror br0 eth1 destination

All incoming traffic on eth0 will be mirrored on eth1.

b)

brctl mirror br0 eth0 egress
brclt mirror br0 eth1 destination

All outgoing traffic from eth0 will be mirrored on eth1.

c)

brctl mirror br0 eth0 both
brclt mirror br0 eth1 destination

All incoming and outgoing traffic coming on or from eth0 will be mirrored on eth1.

Following is the patch against kernel v3.12.

I also implemented the userspace counterpart, I'll send the patch in another mail.

Thank you for giving some feedback on the code and about its possible commit into kernel main tree.


diff -urBb old/br_forward.c new/br_forward.c
--- old/br_forward.c	2013-11-12 14:55:59.054134721 +0100
+++ new/br_forward.c	2013-11-12 14:35:28.262134745 +0100
@@ -62,6 +62,30 @@
 
 }
 
+void br_mirror_xmit(const struct net_bridge_port *p, struct sk_buff *skb, u8 mask)
+{ 
+    struct net_bridge_port *pos;
+    struct sk_buff *clone;
+    /* See if port has mirroring activated on incoming packet
+       ,outgoing packet or both depending on mask */
+	if(p->mirror_state & mask)
+	{
+		/* Look at each bridge port if one is a mirroring destination */
+
+		list_for_each_entry(pos,&p->br->port_list,list)
+		{
+			if(pos->mirror_state & BR_MIRROR_DST)
+			{
+			    /* Set clone device so it is sent on destination port */
+			        clone = skb_copy(skb, GFP_ATOMIC);
+				clone->dev = pos->dev;
+				skb_push(clone, ETH_HLEN);
+				dev_queue_xmit(clone);
+			}
+		}
+	}
+}
+
 static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 {
 	skb = br_handle_vlan(to->br, nbp_get_vlan_info(to), skb);
@@ -70,6 +94,8 @@
 
 	skb->dev = to->dev;
 
+	br_mirror_xmit(to,skb,BR_MIRROR_TX);
+
 	if (unlikely(netpoll_tx_running(to->br->dev))) {
 		if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
 			kfree_skb(skb);
diff -urBb old/br_input.c new/br_input.c
--- old/br_input.c	2013-11-12 14:55:59.054134721 +0100
+++ new/br_input.c	2013-11-12 14:35:28.262134745 +0100
@@ -216,6 +216,8 @@
 		}
 	}
 
+	br_mirror_xmit(p,skb,BR_MIRROR_RX);
+
 forward:
 	switch (p->state) {
 	case BR_STATE_FORWARDING:
diff -urBb old/br_private.h new/br_private.h
--- old/br_private.h	2013-11-12 14:55:59.054134721 +0100
+++ new/br_private.h	2013-11-13 15:57:33.668402893 +0100
@@ -159,6 +159,12 @@
 	u32				designated_cost;
 	unsigned long			designated_age;
 
+	/* Mirroring */
+#define BR_MIRROR_RX 0x01
+#define BR_MIRROR_TX 0x02
+#define BR_MIRROR_DST 0x04
+	u8				mirror_state;
+
 	struct timer_list		forward_delay_timer;
 	struct timer_list		hold_timer;
 	struct timer_list		message_age_timer;
@@ -424,6 +430,7 @@
 			     bool unicast);
 extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
 			     struct sk_buff *skb2, bool unicast);
+extern void br_mirror_xmit(const struct net_bridge_port *p, struct sk_buff *skb, u8 mask);
 
 /* br_if.c */
 extern void br_port_carrier_check(struct net_bridge_port *p);
diff -urBb old/br_sysfs_if.c new/br_sysfs_if.c
--- old/br_sysfs_if.c	2013-11-12 14:55:59.054134721 +0100
+++ new/br_sysfs_if.c	2013-11-12 14:35:28.262134745 +0100
@@ -161,6 +161,18 @@
 BRPORT_ATTR_FLAG(learning, BR_LEARNING);
 BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD);
 
+static ssize_t show_mirror_state(struct net_bridge_port *p, char *buf)
+{
+	return sprintf(buf, "%d\n", p->mirror_state);
+}
+static int store_mirror_state(struct net_bridge_port *p, unsigned long v)
+{
+	p->mirror_state = v;
+	return 0;
+}
+static BRPORT_ATTR(mirror_state, S_IRUGO | S_IWUSR,
+		   show_mirror_state, store_mirror_state);
+
 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
 {
@@ -199,6 +211,7 @@
 	&brport_attr_root_block,
 	&brport_attr_learning,
 	&brport_attr_unicast_flood,
+	&brport_attr_mirror_state,
 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 	&brport_attr_multicast_router,
 	&brport_attr_multicast_fast_leave,

^ permalink raw reply

* [PATCH 1/1] Bridge mirroring function
From: Glenn FEUNTEUN @ 2013-11-21 22:37 UTC (permalink / raw)
  To: netdev
In-Reply-To: <3968895e-7775-4b2b-8209-db349184e64a@zmail220>

Userspace patch for the bridge mirroring function made against bridge-utils 1.5

diff -urBb old/brctl/brctl_cmd.c new1/brctl/brctl_cmd.c
--- old/brctl/brctl_cmd.c	2013-11-13 10:37:48.635728832 +0100
+++ new1/brctl/brctl_cmd.c	2013-11-13 10:59:58.915775559 +0100
@@ -438,6 +438,56 @@
 	return err != 0;
 }
 
+static int br_cmd_mirror(int argc, char *const* argv)
+{
+ 	int mirror_state = 0, err;
+ 	const char *brname = *++argv;
+ 	const char *ifname = *++argv;
+ 	const char *ifmode = *++argv;
+ 
+ 	if (!strcmp(ifmode, "dst") || !strcmp(ifmode, "destination")
+ 	    || !strcmp(ifmode, "4"))
+ 		mirror_state |= BR_MIRROR_DST ;
+ 
+ 	else if (!strcmp(ifmode, "both") || !strcmp(ifmode, "all")
+ 	    || !strcmp(ifmode, "3"))
+ 		mirror_state |= (BR_MIRROR_RX | BR_MIRROR_TX);
+ 
+ 	else if (!strcmp(ifmode, "tx") || !strcmp(ifmode, "egress")
+ 	    || !strcmp(ifmode, "2"))
+ 		mirror_state |= BR_MIRROR_TX;
+ 
+ 	else if (!strcmp(ifmode, "rx") || !strcmp(ifmode, "ingress")
+ 	    || !strcmp(ifmode, "1"))
+ 		mirror_state |= BR_MIRROR_RX;
+ 
+ 	else if (!strcmp(ifmode, "off") || !strcmp(ifmode, "no")
+ 		 || !strcmp(ifmode, "0"))
+ 		mirror_state &= BR_MIRROR_OFF;
+ 
+ 	else {
+ 		fprintf(stderr, "expect rx/tx/both/off/dst for argument\n");
+ 		return 1;
+ 	}
+ 	if (if_nametoindex(ifname) == 0) {
+ 		fprintf(stderr, "interface %s does not exist!\n",
+ 			ifname);
+ 		return 1;
+ 	} else if (if_nametoindex(brname) == 0) {
+ 		fprintf(stderr, "bridge %s does not exist!\n",
+ 			brname);
+ 		return 1;
+ 	}
+ 
+ 	err = br_set_mirror_state(brname, ifname, mirror_state);
+ 
+ 	if (err) {
+ 		fprintf(stderr, "can't set %s to %s state on bridge %s: %s\n",
+ 			ifname,ifmode,brname, strerror(err));
+ 	}
+	return err != 0;
+}
+
 static const struct command commands[] = {
 	{ 1, "addbr", br_cmd_addbr, "<bridge>\t\tadd bridge" },
 	{ 1, "delbr", br_cmd_delbr, "<bridge>\t\tdelete bridge" },
@@ -469,6 +519,8 @@
 	  "<bridge>\t\tshow bridge stp info"},
 	{ 2, "stp", br_cmd_stp,
 	  "<bridge> {on|off}\tturn stp on/off" },
+	{ 3, "mirror", br_cmd_mirror,
+	  "<bridge> <interface> {rx|tx|both|off|dst}\tset interface mirroring state" },
 };
 
 const struct command *command_lookup(const char *cmd)
diff -urBb old/libbridge/libbridge_devif.c new1/libbridge/libbridge_devif.c
--- old/libbridge/libbridge_devif.c	2013-11-13 10:37:39.767722700 +0100
+++ new1/libbridge/libbridge_devif.c	2013-11-13 11:05:23.431777935 +0100
@@ -272,6 +272,7 @@
 	fetch_tv(path, "forward_delay_timer", &info->forward_delay_timer_value);
 	fetch_tv(path, "hold_timer", &info->hold_timer_value);
 	info->hairpin_mode = fetch_int(path, "hairpin_mode");
+	info->mirror_state = fetch_int(path, "mirror_state");
 
 	closedir(d);
 
@@ -388,6 +389,11 @@
 	return port_set(bridge, port, "hairpin_mode", hairpin_mode, 0);
 }
 
+int br_set_mirror_state(const char *bridge, const char *port, int mirror_state)
+{
+	return port_set(bridge, port, "mirror_state", mirror_state, 0);
+}
+
 static inline void __copy_fdb(struct fdb_entry *ent, 
 			      const struct __fdb_entry *f)
 {
diff -urBb old/libbridge/libbridge.h new1/libbridge/libbridge.h
--- old/libbridge/libbridge.h	2013-11-13 10:51:53.359776785 +0100
+++ new1/libbridge/libbridge.h	2013-11-13 11:09:32.159787057 +0100
@@ -82,8 +82,14 @@
 	struct timeval forward_delay_timer_value;
 	struct timeval hold_timer_value;
 	unsigned char hairpin_mode;
+	unsigned char mirror_state;
 };
 
+#define BR_MIRROR_OFF 0x00
+#define BR_MIRROR_RX 0x01
+#define BR_MIRROR_TX 0x02
+#define BR_MIRROR_DST 0x04
+
 extern int br_init(void);
 extern int br_refresh(void);
 extern void br_shutdown(void);
@@ -117,4 +123,6 @@
 		       unsigned long skip, int num);
 extern int br_set_hairpin_mode(const char *bridge, const char *dev,
 			       int hairpin_mode);
+extern int br_set_mirror_state(const char *brname, const char *dev,
+                               int mirror_state);
 #endif

^ permalink raw reply

* Re: [PATCH 1/1] Workaround for Suspend/Resume issue of AX88772B under ChromeOS
From: Grant Grundler @ 2013-11-21 22:48 UTC (permalink / raw)
  To: David Miller
  Cc: Freddy Xin, netdev, linux-usb, LKML, davemloft,
	ASIX Louis [蘇威陸], Allan Chou, Daniel_ASIX
In-Reply-To: <CANEJEGtXOjxj+85QVfWFGH6WuxxCz6uAfEuUo7bv9YEwh_8OAw@mail.gmail.com>

On Wed, Nov 20, 2013 at 11:32 AM, Grant Grundler <grundler@google.com> wrote:
> Seems like this should be part of usbnet_resume code based on whether
> the driver provides mdio_write hook (most USBNET drivers do).

Just to be clear: I don't think this is feasible for the now obvious
reason that not all device lose phy stat on resume. :/

Freddy sent me a patch that saves/restores MII_ADVERTISE and MII_BMCR
registers. Testing that now and he'll post if that all works out.

thanks,
grant

^ permalink raw reply

* Re: [BUG,REGRESSION?] 3.11.6+,3.12: GbE iface rate drops to few KB/s
From: Arnaud Ebalard @ 2013-11-21 22:55 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Willy Tarreau, Thomas Petazzoni, Florian Fainelli, simon.guinot,
	netdev, edumazet, Cong Wang, linux-arm-kernel
In-Reply-To: <1385071201.10637.69.camel@edumazet-glaptop2.roam.corp.google.com>

Hi eric,

Eric Dumazet <eric.dumazet@gmail.com> writes:

>> > I tested it on my RN2120 (2-core armada XP): I got no problem and the
>> > link saturated w/ apache, nginx and netperf. Good work!
>> 
>> Great, thanks for your tests Arnaud. I forgot to mention that all my
>> tests this evening involved this patch as well.
>
> Now you might try to set a lower value
> for /proc/sys/net/ipv4/tcp_limit_output_bytes

On the RN2120, for a file served from /run/shm (for apache and nginx):

          Apache     nginx       netperf
131072:  102 MB/s   112 MB/s   941.11 Mb/s
 65536:  102 MB/s   112 MB/s   935.97 Mb/s
 32768:  101 MB/s   105 MB/s   940.49 Mb/s
 16384:   94 MB/s    90 MB/s   770.07 Mb/s
  8192:   83 MB/s    66 MB/s   556.79 Mb/s

On the RN102, this time for apache and nginx, the file is served from
disks (ext4/lvm/raid1):

          Apache     nginx       netperf
131072:  66 MB/s   105 MB/s   925.63 Mb/s
 65536:  59 MB/s   105 MB/s   862.55 Mb/s
 32768:  62 MB/s   105 MB/s   918.99 Mb/s
 16384:  65 MB/s   105 MB/s   927.71 Mb/s
  8192:  60 MB/s   104 MB/s   915.63 Mb/s

Values above are for a single flow though.

Cheers,

a+

^ permalink raw reply

* Re: [BUG,REGRESSION?] 3.11.6+,3.12: GbE iface rate drops to few KB/s
From: Rick Jones @ 2013-11-21 23:23 UTC (permalink / raw)
  To: Arnaud Ebalard, Eric Dumazet
  Cc: Willy Tarreau, Thomas Petazzoni, Florian Fainelli, simon.guinot,
	netdev, edumazet, Cong Wang, linux-arm-kernel
In-Reply-To: <87txf54b76.fsf@natisbad.org>

On 11/21/2013 02:55 PM, Arnaud Ebalard wrote:
> On the RN2120, for a file served from /run/shm (for apache and nginx):
>
>            Apache     nginx       netperf
> 131072:  102 MB/s   112 MB/s   941.11 Mb/s
>   65536:  102 MB/s   112 MB/s   935.97 Mb/s
>   32768:  101 MB/s   105 MB/s   940.49 Mb/s
>   16384:   94 MB/s    90 MB/s   770.07 Mb/s
>    8192:   83 MB/s    66 MB/s   556.79 Mb/s

If you want to make the units common across all three tests, netperf 
accepts a global -f option to alter the output units.  If you add -f M 
netperf will then emit results in MB/s (M == 1048576).  I'm assuming of 
course that the MB/s of Apache and nginx are also M == 1048576.

happy benchmarking,

rick jones

^ permalink raw reply

* Re: [PATCH 0/1] Bridge mirroring function
From: Stephen Hemminger @ 2013-11-21 23:28 UTC (permalink / raw)
  To: Glenn FEUNTEUN; +Cc: netdev
In-Reply-To: <166a058a-ed18-4a95-9b5a-64a2641bf2c1@zmail220>

On Thu, 21 Nov 2013 23:33:11 +0100 (CET)
Glenn FEUNTEUN <glenn.feunteun@telecom-bretagne.eu> wrote:

> Hello
> 
> I am working on a school project whose goal is to implement a traffic mirroring function inside bridge kernel module.
> 
> I implemented the function that lets :
> - select the mirrored interface(s)
> - select ingress, egress or both traffic to be mirrored
> - select the output interface(s)
> 
> Examples :
> 
> a)
> 
> brctl mirror br0 eth0 ingress
> brclt mirror br0 eth1 destination
> 
> All incoming traffic on eth0 will be mirrored on eth1.
> 
> b)
> 
> brctl mirror br0 eth0 egress
> brclt mirror br0 eth1 destination
> 
> All outgoing traffic from eth0 will be mirrored on eth1.
> 
> c)
> 
> brctl mirror br0 eth0 both
> brclt mirror br0 eth1 destination
> 
> All incoming and outgoing traffic coming on or from eth0 will be mirrored on eth1.
> 
> Following is the patch against kernel v3.12.
> 
> I also implemented the userspace counterpart, I'll send the patch in another mail.
> 
> Thank you for giving some feedback on the code and about its possible commit into kernel main tree.
> 
> 
> diff -urBb old/br_forward.c new/br_forward.c
> --- old/br_forward.c	2013-11-12 14:55:59.054134721 +0100
> +++ new/br_forward.c	2013-11-12 14:35:28.262134745 +0100
> @@ -62,6 +62,30 @@
>  
>  }
>  
> +void br_mirror_xmit(const struct net_bridge_port *p, struct sk_buff *skb, u8 mask)
> +{ 
> +    struct net_bridge_port *pos;
> +    struct sk_buff *clone;
> +    /* See if port has mirroring activated on incoming packet
> +       ,outgoing packet or both depending on mask */
> +	if(p->mirror_state & mask)
> +	{
> +		/* Look at each bridge port if one is a mirroring destination */
> +
> +		list_for_each_entry(pos,&p->br->port_list,list)
> +		{
> +			if(pos->mirror_state & BR_MIRROR_DST)
> +			{
> +			    /* Set clone device so it is sent on destination port */
> +			        clone = skb_copy(skb, GFP_ATOMIC);
> +				clone->dev = pos->dev;
> +				skb_push(clone, ETH_HLEN);
> +				dev_queue_xmit(clone);
> +			}
> +		}
> +	}
> +}
> +
>  static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
>  {
>  	skb = br_handle_vlan(to->br, nbp_get_vlan_info(to), skb);
> @@ -70,6 +94,8 @@
>  
>  	skb->dev = to->dev;
>  
> +	br_mirror_xmit(to,skb,BR_MIRROR_TX);
> +
>  	if (unlikely(netpoll_tx_running(to->br->dev))) {
>  		if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
>  			kfree_skb(skb);
> diff -urBb old/br_input.c new/br_input.c
> --- old/br_input.c	2013-11-12 14:55:59.054134721 +0100
> +++ new/br_input.c	2013-11-12 14:35:28.262134745 +0100
> @@ -216,6 +216,8 @@
>  		}
>  	}
>  
> +	br_mirror_xmit(p,skb,BR_MIRROR_RX);
> +
>  forward:
>  	switch (p->state) {
>  	case BR_STATE_FORWARDING:
> diff -urBb old/br_private.h new/br_private.h
> --- old/br_private.h	2013-11-12 14:55:59.054134721 +0100
> +++ new/br_private.h	2013-11-13 15:57:33.668402893 +0100
> @@ -159,6 +159,12 @@
>  	u32				designated_cost;
>  	unsigned long			designated_age;
>  
> +	/* Mirroring */
> +#define BR_MIRROR_RX 0x01
> +#define BR_MIRROR_TX 0x02
> +#define BR_MIRROR_DST 0x04
> +	u8				mirror_state;
> +
>  	struct timer_list		forward_delay_timer;
>  	struct timer_list		hold_timer;
>  	struct timer_list		message_age_timer;
> @@ -424,6 +430,7 @@
>  			     bool unicast);
>  extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
>  			     struct sk_buff *skb2, bool unicast);
> +extern void br_mirror_xmit(const struct net_bridge_port *p, struct sk_buff *skb, u8 mask);
>  
>  /* br_if.c */
>  extern void br_port_carrier_check(struct net_bridge_port *p);
> diff -urBb old/br_sysfs_if.c new/br_sysfs_if.c
> --- old/br_sysfs_if.c	2013-11-12 14:55:59.054134721 +0100
> +++ new/br_sysfs_if.c	2013-11-12 14:35:28.262134745 +0100
> @@ -161,6 +161,18 @@
>  BRPORT_ATTR_FLAG(learning, BR_LEARNING);
>  BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD);
>  
> +static ssize_t show_mirror_state(struct net_bridge_port *p, char *buf)
> +{
> +	return sprintf(buf, "%d\n", p->mirror_state);
> +}
> +static int store_mirror_state(struct net_bridge_port *p, unsigned long v)
> +{
> +	p->mirror_state = v;
> +	return 0;
> +}
> +static BRPORT_ATTR(mirror_state, S_IRUGO | S_IWUSR,
> +		   show_mirror_state, store_mirror_state);
> +
>  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
>  static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
>  {
> @@ -199,6 +211,7 @@
>  	&brport_attr_root_block,
>  	&brport_attr_learning,
>  	&brport_attr_unicast_flood,
> +	&brport_attr_mirror_state,
>  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
>  	&brport_attr_multicast_router,
>  	&brport_attr_multicast_fast_leave,
> --
> 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

This already possible with 'tc mirred action'.

^ permalink raw reply

* [PATCH linux-next] hisax: disable build for big-endian arm
From: Vincent Stehlé @ 2013-11-21 23:49 UTC (permalink / raw)
  To: netdev, linux-kernel, linux-next; +Cc: Vincent Stehlé, Karsten Keil

Teles PCI and HFC PCI-bus refuse to build on big-endian ARM; disable them in
Kconfig.

Signed-off-by: Vincent Stehlé <vincent.stehle@laposte.net>
Cc: Karsten Keil <isdn@linux-pingi.de>
---

Hi,

This can be seen on e.g. linux next-20131121 with arm allyesconfig.

Best regards,

V.

 drivers/isdn/hisax/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index d9edcc9..53dbb75 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -109,7 +109,7 @@ config HISAX_16_3
 
 config HISAX_TELESPCI
 	bool "Teles PCI"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN) || (ARM && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the Teles PCI.
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -318,7 +318,7 @@ config HISAX_GAZEL
 
 config HISAX_HFC_PCI
 	bool "HFC PCI-Bus cards"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN) || (ARM && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
-- 
1.8.4.2

^ permalink raw reply related

* Re: [PATCH net-next 7/8] openvswitch: Drop user features if old user space attempted to create datapath
From: Jesse Gross @ 2013-11-21 23:50 UTC (permalink / raw)
  To: Thomas Graf
  Cc: Ben Hutchings, David Miller, dev@openvswitch.org, netdev,
	Daniel Borkmann, ffusco, fleitner, Eric Dumazet
In-Reply-To: <20131121222047.GA14252@casper.infradead.org>

On Thu, Nov 21, 2013 at 2:20 PM, Thomas Graf <tgraf@suug.ch> wrote:
> On 11/21/13 at 06:23pm, Ben Hutchings wrote:
>> On Thu, 2013-11-21 at 19:13 +0100, Thomas Graf wrote:
>> > +
>> > +/**
>> > + * V2:
>>
>> This is not kernel-doc format so don't use '/**'.
>
> I was hoping kernel-doc would pick it up but it doesn't.
> I'll convert it.
>
>> > +           if (info->genlhdr->version < OVS_DP_VER_FEATURES) {
>> > +                   WARN_ONCE(dp->user_features, "Dropping previously "
>> > +                             "announced user features");
>>
>> Log messages shouldn't be split like this as it makes them harder to
>> find.  There should also be a newline at the end of the message.
>
> Right, I'll fix this up. We seem to have many of these unfixed.
>
> Jesse, do you want a full respin or just a v2 of this patch?

Whichever is easier is fine.

^ permalink raw reply

* [PATCH] rebalance locks by converting write_lock_bh to write_lock+local_bh_disable
From: Nicholas Mc Guire @ 2013-11-21 23:54 UTC (permalink / raw)
  To: Alexey Kuznetsov; +Cc: Eric Dumazet, Pedro Roque, Peter Zijlstra, netdev

>From 2c8e669b691b825c0ed2a02bd7a698d8ed5c6d29 Mon Sep 17 00:00:00 2001
From: Nicholas Mc Guire <der.herr@hofr.at>
Date: Thu, 21 Nov 2013 18:22:55 -0500
Subject: [PATCH] rebalance locks by converting write_lock_bh to write_lock+local_bh_disable
 

 in __neigh_event_send write_lock_bh(&neigh->lock) is implicitly balanced by
 write_unlock(&neigh->lock)+local_bh_disable() - while this is equivalent with
 respect to the effective low level locking primitives it breaks balancing
 in the locking api. This makes automatic lock-checking trigger false 
 positives, creates an implicit dependency between *_lock_bh and *_lock 
 functions as well as making the extremly simply locking of net core even
 easier to understand.

 The api inbalance was introduced in:
 commit cd28ca0a3dd17c68d24b839602a0e6268ad28b5d
 Author: Eric Dumazet <eric.dumazet@gmail.com>
 This patch just rebalances the lock api

 No change of functionality

Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
---
 net/core/neighbour.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ca15f32..d681c75 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -966,7 +966,8 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 	int rc;
 	bool immediate_probe = false;
 
-	write_lock_bh(&neigh->lock);
+	local_bh_disable();
+	write_lock(&neigh->lock);
 
 	rc = 0;
 	if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
-- 
1.7.2.5

^ permalink raw reply related

* Re: [PATCH] bonding: If IP route look-up to send an ARP fails, mark in bonding structure as no ARP sent.
From: rama nichanamatlu @ 2013-11-22  0:34 UTC (permalink / raw)
  To: Jay Vosburgh; +Cc: Veaceslav Falico, netdev
In-Reply-To: <17860.1385068379@death.nxdomain>

On 11/21/2013 1:12 PM, Jay Vosburgh wrote:
> rama nichanamatlu <rama.nichanamatlu@oracle.com> wrote:
> 
>> On 11/21/2013 3:10 AM, Veaceslav Falico wrote:
>>> On Wed, Nov 20, 2013 at 04:53:20PM -0800, rama nichanamatlu wrote:
>>>> During the creation of VLAN's atop bonding the underlying interfaces
>>>> are made part of VLAN's, and at the same bonding driver gets aware
>>>> that VLAN's exists above it and hence would consult IP routing for
>>>> every ARP to  be sent to determine the route which tells bonding
>>>> driver the correct VLAN tag to attach to the outgoing ARP packet. But,
>>>> during the VLAN creation when vlan driver puts the underlying
>>>> interface into default vlan and then actual vlan, in-between this if
>>>> bonding driver consults the IP for a route, IP fails to provide a
>>>> correct route and upon which bonding driver drops the ARP packet. ARP
>>>> monitor when it
>>>> comes around next time, sees no ARP response and fails-over to the
>>>> next available slave. Consulting for a IP route,
>>>> ip_route_output(),happens in bond_arp_send_all().
>>>
>>> bonding works as expected - nothing to fix here. And even as a
>>> workaround/hack - I'm not sure we need that to suppress one failover *only*
>>> when vlan is added on top.
>>>
>>>>
>> Thank U.
>> With *out* this change our systems failed system testing, to
>> consistently be on designated primary interface on *every* single
>> reboot. With this change the behavior was as expected even after a few
>> thousand reboots & System testing could move to next level catching an
>> another bug in sr-iov :). And Without, the outcome was less predictable
>> after a reboot and bonding was on a different slave each time.
>> -Rama
> 
> 	By "designated primary" you mean the bonding primary option,
> correct?  
Yes correct. Bonding primary param is set.
ex: primary=eth1 and primary_reselect=2.
Hence it is expected to be on primary on every reboot.
-Rama
>If not, 

^ permalink raw reply

* Re: [PATCH 1/1] Workaround for Suspend/Resume issue of AX88772B under ChromeOS
From: Florian Fainelli @ 2013-11-22  1:58 UTC (permalink / raw)
  To: Grant Grundler
  Cc: David Miller, Freddy Xin, netdev, linux-usb, LKML, davemloft,
	ASIX Louis [蘇威陸], Allan Chou, Daniel_ASIX
In-Reply-To: <CANEJEGu_2YdVOjcnzh30RPMiP0KC5bL6JasxMS_+1xV9poxgQw@mail.gmail.com>

2013/11/21 Grant Grundler <grundler@google.com>:
> On Wed, Nov 20, 2013 at 11:32 AM, Grant Grundler <grundler@google.com> wrote:
>> Seems like this should be part of usbnet_resume code based on whether
>> the driver provides mdio_write hook (most USBNET drivers do).
>
> Just to be clear: I don't think this is feasible for the now obvious
> reason that not all device lose phy stat on resume. :/
>
> Freddy sent me a patch that saves/restores MII_ADVERTISE and MII_BMCR
> registers. Testing that now and he'll post if that all works out.

That should be enough to ensure the PHY is put back into a consistent
state. So long as you are suspending/resuming from a configuration
where autoneg was enabled, I would not expect anything bad to happen.
If the link was forced, that is a different story.

One way to make sure this work properly without driver-specific code
is to include that functionality into the PHY library. As far as I can
see it the asix drivers do not use it but implement the old-style
mii_bus interface so that would be a first step.
-- 
Florian

^ permalink raw reply

* [PATCH 0/8] IBM Akebono/PPC476GTR Support
From: Alistair Popple @ 2013-11-22  2:07 UTC (permalink / raw)
  To: benh
  Cc: netdev, linux-usb, linux-mmc, linuxppc-dev, stern,
	Alistair Popple, cjb, davem

The IBM Akebono board is a development board for the new PPC476GTR
system on chip (SoC).

Changes from V1:
 * Update device-tree compatible strings to reflect the name of the
   SoC rather than the board when those components are integrated into
   the SoC.
 * Updates to allow the new EMAC PHY interface to be compile tested.
 * Rather than adding a new compatible string for EHCI support
   usb-ehci is used and the corresponding driver (ehci-ppc-of)
   is merged into the generic EHCI platform driver.
 * A generic (usb-ohci) compatible string is used for OHCI.
 * PCI MSI support has been added via the HSTA module.

Alistair Popple (8):
  IBM Akebono: Add support to AHCI platform driver
  IBM Akebono: Add a SDHCI platform driver
  IBM Akebono: Add support for a new PHY interface to the IBM emac
    driver
  IBM Akebono: Add support to the OHCI platform driver for PPC476GTR
  ECHI Platform: Merge ppc-of EHCI driver into the ehci-platform driver
  IBM Currituck: Clean up board specific code before adding Akebono
    code
  IBM Akebono: Add the Akebono platform
  powerpc: Added PCI MSI support using the HSTA module

 .../devicetree/bindings/powerpc/4xx/akebono.txt    |   54 +++
 .../devicetree/bindings/powerpc/4xx/emac.txt       |    9 +
 arch/powerpc/boot/Makefile                         |    3 +
 arch/powerpc/boot/dcr.h                            |    4 +
 arch/powerpc/boot/dts/akebono.dts                  |  415 ++++++++++++++++++++
 arch/powerpc/boot/treeboot-akebono.c               |  179 +++++++++
 arch/powerpc/boot/wrapper                          |    3 +
 arch/powerpc/configs/44x/akebono_defconfig         |  148 +++++++
 arch/powerpc/platforms/44x/Kconfig                 |   32 +-
 arch/powerpc/platforms/44x/Makefile                |    3 +-
 arch/powerpc/platforms/44x/currituck.c             |  233 -----------
 arch/powerpc/platforms/44x/ppc476.c                |  299 ++++++++++++++
 arch/powerpc/sysdev/Kconfig                        |    6 +
 arch/powerpc/sysdev/Makefile                       |    1 +
 arch/powerpc/sysdev/ppc4xx_hsta_msi.c              |  266 +++++++++++++
 arch/powerpc/sysdev/ppc4xx_pci.c                   |   41 +-
 arch/powerpc/sysdev/ppc4xx_pci.h                   |    4 +-
 drivers/ata/ahci_platform.c                        |    1 +
 drivers/mmc/host/Kconfig                           |   12 +
 drivers/mmc/host/Makefile                          |    1 +
 drivers/mmc/host/sdhci-of-476gtr.c                 |   60 +++
 drivers/net/ethernet/ibm/emac/Kconfig              |    4 +
 drivers/net/ethernet/ibm/emac/Makefile             |    1 +
 drivers/net/ethernet/ibm/emac/core.c               |   50 ++-
 drivers/net/ethernet/ibm/emac/core.h               |   12 +
 drivers/net/ethernet/ibm/emac/rgmii_wol.c          |  243 ++++++++++++
 drivers/net/ethernet/ibm/emac/rgmii_wol.h          |   62 +++
 drivers/usb/host/Kconfig                           |    7 +-
 drivers/usb/host/ehci-hcd.c                        |    5 -
 drivers/usb/host/ehci-platform.c                   |   86 +++-
 drivers/usb/host/ehci-ppc-of.c                     |  236 -----------
 drivers/usb/host/ohci-platform.c                   |   22 +-
 32 files changed, 1992 insertions(+), 510 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
 create mode 100644 arch/powerpc/boot/dts/akebono.dts
 create mode 100644 arch/powerpc/boot/treeboot-akebono.c
 create mode 100644 arch/powerpc/configs/44x/akebono_defconfig
 delete mode 100644 arch/powerpc/platforms/44x/currituck.c
 create mode 100644 arch/powerpc/platforms/44x/ppc476.c
 create mode 100644 arch/powerpc/sysdev/ppc4xx_hsta_msi.c
 create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h
 delete mode 100644 drivers/usb/host/ehci-ppc-of.c

-- 
1.7.10.4

^ permalink raw reply

* [PATCH 3/8] IBM Akebono: Add support for a new PHY interface to the IBM emac driver
From: Alistair Popple @ 2013-11-22  2:08 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, netdev, David S. Miller, Alistair Popple
In-Reply-To: <1385086057-10884-1-git-send-email-alistair@popple.id.au>

The IBM PPC476GTR SoC that is used on the Akebono board uses a
different ethernet PHY interface that has wake on lan (WOL) support
with the IBM emac. This patch adds support to the IBM emac driver for
this new PHY interface.

At this stage the wake on lan functionality has not been implemented.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
 .../devicetree/bindings/powerpc/4xx/emac.txt       |    9 +
 drivers/net/ethernet/ibm/emac/Kconfig              |    4 +
 drivers/net/ethernet/ibm/emac/Makefile             |    1 +
 drivers/net/ethernet/ibm/emac/core.c               |   50 +++-
 drivers/net/ethernet/ibm/emac/core.h               |   12 +
 drivers/net/ethernet/ibm/emac/rgmii_wol.c          |  243 ++++++++++++++++++++
 drivers/net/ethernet/ibm/emac/rgmii_wol.h          |   62 +++++
 7 files changed, 375 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6..9928d9d 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -61,6 +61,8 @@
 			  Fox Axon: present, whatever value is appropriate for each
 			  EMAC, that is the content of the current (bogus) "phy-port"
 			  property.
+    - rgmii-wol-device  : 1 cell, required iff conntect to a RGMII in the WKUP
+                          power domain. phandle of the RGMII-WOL device node.
 
     Optional properties:
     - phy-address       : 1 cell, optional, MDIO address of the PHY. If absent,
@@ -146,3 +148,10 @@
 			   available.
 			   For Axon: 0x0000012a
 
+      iv) RGMII-WOL node
+
+    Required properties:
+    - compatible         : compatible list, containing 2 entries, first is
+			   "ibm,rgmii-wol-CHIP" where CHIP is the host ASIC (like
+			   EMAC) and the second is "ibm,rgmii-wol".
+    - reg                : <registers mapping>
diff --git a/drivers/net/ethernet/ibm/emac/Kconfig b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30..56ea346 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -55,6 +55,10 @@ config IBM_EMAC_RGMII
 	bool
 	default n
 
+config IBM_EMAC_RGMII_WOL
+	bool "IBM EMAC RGMII wake-on-LAN support" if COMPILE_TEST
+	default n
+
 config IBM_EMAC_TAH
 	bool
 	default n
diff --git a/drivers/net/ethernet/ibm/emac/Makefile b/drivers/net/ethernet/ibm/emac/Makefile
index eba2183..8843803 100644
--- a/drivers/net/ethernet/ibm/emac/Makefile
+++ b/drivers/net/ethernet/ibm/emac/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
 ibm_emac-y := mal.o core.o phy.o
 ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += zmii.o
 ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII_WOL) += rgmii_wol.o
 ibm_emac-$(CONFIG_IBM_EMAC_TAH) += tah.o
 ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += debug.o
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 6b5c722..fc1a775 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -630,6 +630,8 @@ static int emac_configure(struct emac_instance *dev)
 	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
 		rgmii_set_speed(dev->rgmii_dev, dev->rgmii_port,
 				dev->phy.speed);
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+		rgmii_wol_set_speed(dev->rgmii_wol_dev, dev->phy.speed);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
 		zmii_set_speed(dev->zmii_dev, dev->zmii_port, dev->phy.speed);
 
@@ -797,6 +799,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
 		zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
 		rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+		rgmii_wol_get_mdio(dev->rgmii_wol_dev);
 
 	/* Wait for management interface to become idle */
 	n = 20;
@@ -844,6 +848,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
 	DBG2(dev, "mdio_read -> %04x" NL, r);
 	err = 0;
  bail:
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+		rgmii_wol_put_mdio(dev->rgmii_wol_dev);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
 		rgmii_put_mdio(dev->rgmii_dev, dev->rgmii_port);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
@@ -869,6 +875,8 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
 		zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
 		rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+		rgmii_wol_get_mdio(dev->rgmii_wol_dev);
 
 	/* Wait for management interface to be idle */
 	n = 20;
@@ -907,6 +915,8 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
 	}
 	err = 0;
  bail:
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+		rgmii_wol_put_mdio(dev->rgmii_wol_dev);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
 		rgmii_put_mdio(dev->rgmii_dev, dev->rgmii_port);
 	if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
@@ -2275,10 +2285,11 @@ struct emac_depentry {
 #define	EMAC_DEP_MAL_IDX	0
 #define	EMAC_DEP_ZMII_IDX	1
 #define	EMAC_DEP_RGMII_IDX	2
-#define	EMAC_DEP_TAH_IDX	3
-#define	EMAC_DEP_MDIO_IDX	4
-#define	EMAC_DEP_PREV_IDX	5
-#define	EMAC_DEP_COUNT		6
+#define EMAC_DEP_RGMII_WOL_IDX  3
+#define	EMAC_DEP_TAH_IDX	4
+#define	EMAC_DEP_MDIO_IDX	5
+#define	EMAC_DEP_PREV_IDX	6
+#define	EMAC_DEP_COUNT		7
 
 static int emac_check_deps(struct emac_instance *dev,
 			   struct emac_depentry *deps)
@@ -2356,6 +2367,7 @@ static int emac_wait_deps(struct emac_instance *dev)
 	deps[EMAC_DEP_MAL_IDX].phandle = dev->mal_ph;
 	deps[EMAC_DEP_ZMII_IDX].phandle = dev->zmii_ph;
 	deps[EMAC_DEP_RGMII_IDX].phandle = dev->rgmii_ph;
+	deps[EMAC_DEP_RGMII_WOL_IDX].phandle = dev->rgmii_wol_ph;
 	if (dev->tah_ph)
 		deps[EMAC_DEP_TAH_IDX].phandle = dev->tah_ph;
 	if (dev->mdio_ph)
@@ -2378,6 +2390,7 @@ static int emac_wait_deps(struct emac_instance *dev)
 		dev->mal_dev = deps[EMAC_DEP_MAL_IDX].ofdev;
 		dev->zmii_dev = deps[EMAC_DEP_ZMII_IDX].ofdev;
 		dev->rgmii_dev = deps[EMAC_DEP_RGMII_IDX].ofdev;
+		dev->rgmii_wol_dev = deps[EMAC_DEP_RGMII_WOL_IDX].ofdev;
 		dev->tah_dev = deps[EMAC_DEP_TAH_IDX].ofdev;
 		dev->mdio_dev = deps[EMAC_DEP_MDIO_IDX].ofdev;
 	}
@@ -2583,6 +2596,8 @@ static int emac_init_config(struct emac_instance *dev)
 		dev->rgmii_ph = 0;
 	if (emac_read_uint_prop(np, "rgmii-channel", &dev->rgmii_port, 0))
 		dev->rgmii_port = 0xffffffff;
+	if (emac_read_uint_prop(np, "rgmii-wol-device", &dev->rgmii_wol_ph, 0))
+		dev->rgmii_wol_ph = 0;
 	if (emac_read_uint_prop(np, "fifo-entry-size", &dev->fifo_entry_size, 0))
 		dev->fifo_entry_size = 16;
 	if (emac_read_uint_prop(np, "mal-burst-size", &dev->mal_burst_size, 0))
@@ -2669,6 +2684,16 @@ static int emac_init_config(struct emac_instance *dev)
 #endif
 	}
 
+	if (dev->rgmii_wol_ph != 0) {
+#ifdef CONFIG_IBM_EMAC_RGMII_WOL
+		dev->features |= EMAC_FTR_HAS_RGMII_WOL;
+#else
+		printk(KERN_ERR "%s: RGMII WOL support not enabled !\n",
+		       np->full_name);
+		return -ENXIO;
+#endif
+	}
+
 	/* Read MAC-address */
 	p = of_get_property(np, "local-mac-address", NULL);
 	if (p == NULL) {
@@ -2842,10 +2867,15 @@ static int emac_probe(struct platform_device *ofdev)
 	    (err = rgmii_attach(dev->rgmii_dev, dev->rgmii_port, dev->phy_mode)) != 0)
 		goto err_detach_zmii;
 
+	/* Attach to RGMII_WOL, if needed */
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL) &&
+	    (err = rgmii_wol_attach(dev->rgmii_wol_dev, dev->phy_mode)) != 0)
+		goto err_detach_rgmii;
+
 	/* Attach to TAH, if needed */
 	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH) &&
 	    (err = tah_attach(dev->tah_dev, dev->tah_port)) != 0)
-		goto err_detach_rgmii;
+		goto err_detach_rgmii_wol;
 
 	/* Set some link defaults before we can find out real parameters */
 	dev->phy.speed = SPEED_100;
@@ -2918,6 +2948,9 @@ static int emac_probe(struct platform_device *ofdev)
  err_detach_tah:
 	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
 		tah_detach(dev->tah_dev, dev->tah_port);
+ err_detach_rgmii_wol:
+	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+		rgmii_wol_detach(dev->rgmii_wol_dev);
  err_detach_rgmii:
 	if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
 		rgmii_detach(dev->rgmii_dev, dev->rgmii_port);
@@ -3079,12 +3112,17 @@ static int __init emac_init(void)
 	rc = tah_init();
 	if (rc)
 		goto err_rgmii;
-	rc = platform_driver_register(&emac_driver);
+	rc = rgmii_wol_init();
 	if (rc)
 		goto err_tah;
+	rc = platform_driver_register(&emac_driver);
+	if (rc)
+		goto err_rgmii_wol;
 
 	return 0;
 
+ err_rgmii_wol:
+	rgmii_wol_exit();
  err_tah:
 	tah_exit();
  err_rgmii:
diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h
index 7007479..930a6f6 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -43,6 +43,7 @@
 #include "phy.h"
 #include "zmii.h"
 #include "rgmii.h"
+#include "rgmii_wol.h"
 #include "mal.h"
 #include "tah.h"
 #include "debug.h"
@@ -210,6 +211,10 @@ struct emac_instance {
 	u32				rgmii_port;
 	struct platform_device		*rgmii_dev;
 
+	/* RGMII WOL infos if any */
+	u32				rgmii_wol_ph;
+	struct platform_device		*rgmii_wol_dev;
+
 	/* TAH infos if any */
 	u32				tah_ph;
 	u32				tah_port;
@@ -333,6 +338,10 @@ struct emac_instance {
  * APM821xx does not support Half Duplex mode
  */
 #define EMAC_FTR_APM821XX_NO_HALF_DUPLEX	0x00001000
+/*
+ * Set if we have a RGMII with wake on LAN.
+ */
+#define EMAC_FTR_HAS_RGMII_WOL		0x00020000
 
 /* Right now, we don't quite handle the always/possible masks on the
  * most optimal way as we don't have a way to say something like
@@ -356,6 +365,9 @@ enum {
 #ifdef CONFIG_IBM_EMAC_RGMII
 	    EMAC_FTR_HAS_RGMII	|
 #endif
+#ifdef CONFIG_IBM_EMAC_RGMII_WOL
+	    EMAC_FTR_HAS_RGMII_WOL	|
+#endif
 #ifdef CONFIG_IBM_EMAC_NO_FLOW_CTRL
 	    EMAC_FTR_NO_FLOW_CONTROL_40x |
 #endif
diff --git a/drivers/net/ethernet/ibm/emac/rgmii_wol.c b/drivers/net/ethernet/ibm/emac/rgmii_wol.c
new file mode 100644
index 0000000..aeeb5dd
--- /dev/null
+++ b/drivers/net/ethernet/ibm/emac/rgmii_wol.c
@@ -0,0 +1,243 @@
+/* drivers/net/ethernet/ibm/emac/rgmii_wol.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge with
+ * wake on LAN support.
+ *
+ * Copyright 2013 Alistair Popple, IBM Corp.
+ *                <alistair@popple.id.au>
+ *
+ * Based on rgmii.h:
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/io.h>
+
+#include "emac.h"
+#include "debug.h"
+
+/* RGMII_WOL_REG */
+
+#define WKUP_ETH_RGSPD      0xC0000000
+#define WKUP_ETH_FCSEN      0x20000000
+#define WKUP_ETH_CRSEN      0x02000000
+#define WKUP_ETH_COLEN      0x01000000
+#define WKUP_ETH_TX_OE      0x00040000
+#define WKUP_ETH_RX_IE      0x00020000
+#define WKUP_ETH_RGMIIEN    0x00010000
+
+#define WKUP_ETH_RGSPD_10   0x00000000
+#define WKUP_ETH_RGSPD_100  0x40000000
+#define WKUP_ETH_RGSPD_1000 0x80000000
+
+/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
+static inline int rgmii_valid_mode(int phy_mode)
+{
+	return  phy_mode == PHY_MODE_GMII ||
+		phy_mode == PHY_MODE_MII ||
+		phy_mode == PHY_MODE_RGMII ||
+		phy_mode == PHY_MODE_TBI ||
+		phy_mode == PHY_MODE_RTBI;
+}
+
+int rgmii_wol_attach(struct platform_device *ofdev, int mode)
+{
+	struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+
+	dev_dbg(&ofdev->dev, "attach\n");
+
+	/* Check if we need to attach to a RGMII */
+	if (!rgmii_valid_mode(mode)) {
+		dev_err(&ofdev->dev, "unsupported settings !\n");
+		return -ENODEV;
+	}
+
+	mutex_lock(&dev->lock);
+
+	/* Enable this input */
+	out_be32(dev->reg, in_be32(dev->reg) | WKUP_ETH_RGMIIEN
+		 | WKUP_ETH_TX_OE | WKUP_ETH_RX_IE);
+
+	++dev->users;
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+void rgmii_wol_set_speed(struct platform_device *ofdev, int speed)
+{
+	struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+	u32 reg;
+
+	mutex_lock(&dev->lock);
+
+	reg = in_be32(dev->reg) & ~WKUP_ETH_RGSPD;
+
+	dev_dbg(&ofdev->dev, "speed(%d)\n", speed);
+
+	switch (speed) {
+	case SPEED_1000:
+		reg |= WKUP_ETH_RGSPD_1000;
+		break;
+	case SPEED_100:
+		reg |= WKUP_ETH_RGSPD_100;
+		break;
+	case SPEED_10:
+		reg |= WKUP_ETH_RGSPD_10;
+		break;
+	default:
+		dev_err(&ofdev->dev, "invalid speed set!\n");
+	}
+
+	out_be32(dev->reg, reg);
+
+	mutex_unlock(&dev->lock);
+}
+
+void rgmii_wol_get_mdio(struct platform_device *ofdev)
+{
+	/* MDIO is always enabled when RGMII_WOL is enabled, so we
+	 * don't have to do anything here.
+	 */
+	dev_dbg(&ofdev->dev, "get_mdio\n");
+}
+
+void rgmii_wol_put_mdio(struct platform_device *ofdev)
+{
+	dev_dbg(&ofdev->dev, "put_mdio\n");
+}
+
+void rgmii_wol_detach(struct platform_device *ofdev)
+{
+	struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+
+	BUG_ON(!dev || dev->users == 0);
+
+	mutex_lock(&dev->lock);
+
+	dev_dbg(&ofdev->dev, "detach\n");
+
+	/* Disable this input */
+	out_be32(dev->reg, 0);
+
+	--dev->users;
+
+	mutex_unlock(&dev->lock);
+}
+
+int rgmii_wol_get_regs_len(struct platform_device *ofdev)
+{
+	return sizeof(struct emac_ethtool_regs_subhdr) +
+		sizeof(u32);
+}
+
+void *rgmii_wol_dump_regs(struct platform_device *ofdev, void *buf)
+{
+	struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+	struct emac_ethtool_regs_subhdr *hdr = buf;
+	u32 *regs = (u32 *)(hdr + 1);
+
+	hdr->version = 0;
+	hdr->index = 0; /* for now, are there chips with more than one
+			 * rgmii ? if yes, then we'll add a cell_index
+			 * like we do for emac
+			 */
+	memcpy_fromio(regs, dev->reg, sizeof(u32));
+	return regs + 1;
+}
+
+
+static int rgmii_wol_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct rgmii_wol_instance *dev;
+	int rc;
+
+	rc = -ENOMEM;
+	dev = kzalloc(sizeof(struct rgmii_wol_instance), GFP_KERNEL);
+	if (dev == NULL)
+		goto err_gone;
+
+	mutex_init(&dev->lock);
+
+	dev->reg = of_iomap(np, 0);
+	if (!dev->reg) {
+		dev_err(&ofdev->dev, "Can't map registers\n");
+		rc = -ENXIO;
+		goto err_free;
+	}
+
+	/* Check for RGMII flags */
+	if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL))
+		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
+
+	dev_dbg(&ofdev->dev, " Boot REG = 0x%08x\n", in_be32(dev->reg));
+
+	/* Disable all inputs by default */
+	out_be32(dev->reg, 0);
+
+	dev_info(&ofdev->dev,
+	       "RGMII %s initialized with%s MDIO support\n",
+	       ofdev->dev.of_node->full_name,
+	       (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
+
+	wmb();
+	platform_set_drvdata(ofdev, dev);
+
+	return 0;
+
+ err_free:
+	kfree(dev);
+ err_gone:
+	return rc;
+}
+
+static int rgmii_wol_remove(struct platform_device *ofdev)
+{
+	struct rgmii_wol_instance *dev = platform_get_drvdata(ofdev);
+
+	WARN_ON(dev->users != 0);
+
+	iounmap(dev->reg);
+	kfree(dev);
+
+	return 0;
+}
+
+static struct of_device_id rgmii_wol_match[] = {
+	{
+		.compatible	= "ibm,rgmii-wol",
+	},
+	{
+		.type		= "emac-rgmii-wol",
+	},
+	{},
+};
+
+static struct platform_driver rgmii_wol_driver = {
+	.driver = {
+		.name = "emac-rgmii-wol",
+		.owner = THIS_MODULE,
+		.of_match_table = rgmii_wol_match,
+	},
+	.probe = rgmii_wol_probe,
+	.remove = rgmii_wol_remove,
+};
+
+int __init rgmii_wol_init(void)
+{
+	return platform_driver_register(&rgmii_wol_driver);
+}
+
+void rgmii_wol_exit(void)
+{
+	platform_driver_unregister(&rgmii_wol_driver);
+}
diff --git a/drivers/net/ethernet/ibm/emac/rgmii_wol.h b/drivers/net/ethernet/ibm/emac/rgmii_wol.h
new file mode 100644
index 0000000..9f0b589
--- /dev/null
+++ b/drivers/net/ethernet/ibm/emac/rgmii_wol.h
@@ -0,0 +1,62 @@
+/* drivers/net/ethernet/ibm/emac/rgmii_wol.h
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge with
+ * wake on LAN support.
+ *
+ * Copyright 2013 Alistair Popple, IBM Corp.
+ *                <alistair@popple.id.au>
+ *
+ * Based on rgmii.h:
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __IBM_NEWEMAC_RGMII_WOL_H
+#define __IBM_NEWEMAC_RGMII_WOL_H
+
+/* RGMII device */
+struct rgmii_wol_instance {
+	u32 __iomem			*reg;
+
+	/* RGMII bridge flags */
+	int				flags;
+#define EMAC_RGMII_FLAG_HAS_MDIO	0x00000001
+
+	/* Only one EMAC whacks us at a time */
+	struct mutex			lock;
+
+	/* number of EMACs using this RGMII bridge */
+	int				users;
+};
+
+#ifdef CONFIG_IBM_EMAC_RGMII_WOL
+
+extern int rgmii_wol_init(void);
+extern void rgmii_wol_exit(void);
+extern int rgmii_wol_attach(struct platform_device *ofdev, int mode);
+extern void rgmii_wol_detach(struct platform_device *ofdev);
+extern void rgmii_wol_get_mdio(struct platform_device *ofdev);
+extern void rgmii_wol_put_mdio(struct platform_device *ofdev);
+extern void rgmii_wol_set_speed(struct platform_device *ofdev, int speed);
+extern int rgmii_wol_get_regs_len(struct platform_device *ofdev);
+extern void *rgmii_wol_dump_regs(struct platform_device *ofdev, void *buf);
+
+#else
+
+# define rgmii_wol_init()		0
+# define rgmii_wol_exit()		do { } while (0)
+# define rgmii_wol_attach(x, y)		(-ENXIO)
+# define rgmii_wol_detach(x)		do { } while (0)
+# define rgmii_wol_get_mdio(o)		do { } while (0)
+# define rgmii_wol_put_mdio(o)		do { } while (0)
+# define rgmii_wol_set_speed(x, y)	do { } while (0)
+# define rgmii_wol_get_regs_len(x)	0
+# define rgmii_wol_dump_regs(x, buf)	(buf)
+#endif				/* !CONFIG_IBM_EMAC_RGMII_WOL */
+
+#endif /* __IBM_NEWEMAC_RGMII_WOL_H */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH net v2] bonding: disable arp and enable mii monitoring when bond change to no uses arp mode
From: Ding Tianhong @ 2013-11-22  2:12 UTC (permalink / raw)
  To: Andy Gospodarek, Dan Williams, David Miller
  Cc: fubar, nikolay, vfalico, netdev
In-Reply-To: <528ACD8A.1010409@greyhouse.net>

Because the ARP monitoring is not support for 802.3ad, but I still
could change the mode to 802.3ad from ab mode while ARP monitoring
is running, it is incorrect.

So add a check for 802.3ad in bonding_store_mode to fix the problem,
and make a new macro BOND_NO_USES_ARP() to simplify the code.

v2: according to the Dan Williams's suggestion, bond mode is the most
    important bond option, it should override any of the other sub-options.
    So when the mode is changed, the conficting values should be cleared
    or reset, otherwise the user has to duplicate more operations to modify
    the logic. I disable the arp and enable mii monitoring when the bond mode
    is changed to AB, TB and 8023AD if the arp interval is true.

Suggested-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 drivers/net/bonding/bond_options.c | 13 +++++++++----
 drivers/net/bonding/bonding.h      |  5 +++++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 9a5223c..04364f7a 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -45,10 +45,15 @@ int bond_option_mode_set(struct bonding *bond, int mode)
 		return -EPERM;
 	}
 
-	if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) {
-		pr_err("%s: %s mode is incompatible with arp monitoring.\n",
-		       bond->dev->name, bond_mode_tbl[mode].modename);
-		return -EINVAL;
+	if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) {
+		pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
+			bond->dev->name, bond_mode_tbl[mode].modename);
+		/* disable arp monitoring */
+		bond->params.arp_interval = 0;
+		/* set miimon to default value */
+		bond->params.miimon = 100;
+		pr_info("%s: Setting MII monitoring interval to %d.\n",
+			bond->dev->name, bond->params.miimon);
 	}
 
 	/* don't cache arp_validate between modes */
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ca31286..a310fb5 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -55,6 +55,11 @@
 		 ((mode) == BOND_MODE_TLB)          ||	\
 		 ((mode) == BOND_MODE_ALB))
 
+#define BOND_NO_USES_ARP(mode)				\
+		(((mode) == BOND_MODE_8023AD)	||	\
+		 ((mode) == BOND_MODE_TLB)	||	\
+		 ((mode) == BOND_MODE_ALB))
+
 #define TX_QUEUE_OVERRIDE(mode)				\
 			(((mode) == BOND_MODE_ACTIVEBACKUP) ||	\
 			 ((mode) == BOND_MODE_ROUNDROBIN))
-- 
1.8.0

^ permalink raw reply related

* Re: [PATCH 1/1] Workaround for Suspend/Resume issue of AX88772B under ChromeOS
From: Grant Grundler @ 2013-11-22  2:26 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: David Miller, Freddy Xin, netdev,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, LKML,
	davemloft-fT/PcQaiUtIeIZ0/mPfg9Q,
	ASIX Louis [蘇威陸], Allan Chou, Daniel_ASIX
In-Reply-To: <CAGVrzcase25NosVHA74OLnviJj7nU_2Rxki_hvi8bOwznDuWGg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Thu, Nov 21, 2013 at 5:58 PM, Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
...
>> Freddy sent me a patch that saves/restores MII_ADVERTISE and MII_BMCR
>> registers. Testing that now and he'll post if that all works out.

Bad News: Freddy's patch didn't work and needs to be rework it.

> That should be enough to ensure the PHY is put back into a consistent
> state. So long as you are suspending/resuming from a configuration
> where autoneg was enabled, I would not expect anything bad to happen.

Well, I think davem NACK'd that approach (the original patch in this
thread did that).

> If the link was forced, that is a different story.
>
> One way to make sure this work properly without driver-specific code
> is to include that functionality into the PHY library. As far as I can
> see it the asix drivers do not use it but implement the old-style
> mii_bus interface so that would be a first step.

AFAICT, many USBNET drivers support mii_bus interface. Can you point
at a good example of a USBNET driver that is supporting PHY lib?

I also didn't see anything in usbnet_resume() code path that calls
into a phy lib. So it seems that some infrastructure still needs to
happen if that's considered a feasible.

thanks,
grant

> --
> Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 v3] net: Do not include padding in TCP GRO checksum
From: Herbert Xu @ 2013-11-22  2:30 UTC (permalink / raw)
  To: David Miller; +Cc: alexander.h.duyck, alexander.duyck, netdev, edumazet
In-Reply-To: <20131121.133501.272071098922555423.davem@davemloft.net>

On Thu, Nov 21, 2013 at 01:35:01PM -0500, David Miller wrote:
> 
> I've lost track of this dicussion, Herbert could you post the patches
> I should apply?  I think it was this one and a follow-on simplification
> to the checksum handling?

OK I'll respost.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [1/2] gro: Only verify TCP checksums for candidates
From: Herbert Xu @ 2013-11-22  2:31 UTC (permalink / raw)
  To: David Miller; +Cc: alexander.h.duyck, alexander.duyck, netdev, edumazet
In-Reply-To: <20131122023013.GA6387@gondor.apana.org.au>

In some cases we may receive IP packets that are longer than
their stated lengths.  Such packets are never merged in GRO.
However, we may end up computing their checksums incorrectly
and end up allowing packets with a bogus checksum enter our
stack with the checksum status set as verified.

Since such packets are rare and not performance-critical, this
patch simply skips the checksum verification for them.

Reported-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>

diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index a2b68a1..55aeec9 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -276,6 +276,10 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *
 	__wsum wsum;
 	__sum16 sum;
 
+	/* Don't bother verifying checksum if we're going to flush anyway. */
+	if (NAPI_GRO_CB(skb)->flush)
+		goto skip_csum;
+
 	switch (skb->ip_summed) {
 	case CHECKSUM_COMPLETE:
 		if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
@@ -301,6 +305,7 @@ flush:
 		break;
 	}
 
+skip_csum:
 	return tcp_gro_receive(head, skb);
 }
 
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index c1097c7..71923d1 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -39,6 +39,10 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
 	__wsum wsum;
 	__sum16 sum;
 
+	/* Don't bother verifying checksum if we're going to flush anyway. */
+	if (NAPI_GRO_CB(skb)->flush)
+		goto skip_csum;
+
 	switch (skb->ip_summed) {
 	case CHECKSUM_COMPLETE:
 		if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
@@ -65,6 +69,7 @@ flush:
 		break;
 	}
 
+skip_csum:
 	return tcp_gro_receive(head, skb);
 }

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* [2/2] gro: Clean up tcpX_gro_receive checksum verification
From: Herbert Xu @ 2013-11-22  2:32 UTC (permalink / raw)
  To: David Miller; +Cc: alexander.h.duyck, alexander.duyck, netdev, edumazet
In-Reply-To: <20131122023013.GA6387@gondor.apana.org.au>

This patch simplifies the checksum verification in tcpX_gro_receive
by reusing the CHECKSUM_COMPLETE code for CHECKSUM_NONE.  All it
does for CHECKSUM_NONE is compute the partial checksum and then
treat it as if it came from the hardware (CHECKSUM_COMPLETE).
    
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index 55aeec9..0560635 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -274,35 +274,29 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *
 {
 	const struct iphdr *iph = skb_gro_network_header(skb);
 	__wsum wsum;
-	__sum16 sum;
 
 	/* Don't bother verifying checksum if we're going to flush anyway. */
 	if (NAPI_GRO_CB(skb)->flush)
 		goto skip_csum;
 
+	wsum = skb->csum;
+
 	switch (skb->ip_summed) {
+	case CHECKSUM_NONE:
+		wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+				    0);
+
+		/* fall through */
+
 	case CHECKSUM_COMPLETE:
 		if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
-				  skb->csum)) {
+				  wsum)) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			break;
 		}
-flush:
+
 		NAPI_GRO_CB(skb)->flush = 1;
 		return NULL;
-
-	case CHECKSUM_NONE:
-		wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-					  skb_gro_len(skb), IPPROTO_TCP, 0);
-		sum = csum_fold(skb_checksum(skb,
-					     skb_gro_offset(skb),
-					     skb_gro_len(skb),
-					     wsum));
-		if (sum)
-			goto flush;
-
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		break;
 	}
 
 skip_csum:
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index 71923d1..6d18157 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -37,36 +37,29 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
 {
 	const struct ipv6hdr *iph = skb_gro_network_header(skb);
 	__wsum wsum;
-	__sum16 sum;
 
 	/* Don't bother verifying checksum if we're going to flush anyway. */
 	if (NAPI_GRO_CB(skb)->flush)
 		goto skip_csum;
 
+	wsum = skb->csum;
+
 	switch (skb->ip_summed) {
+	case CHECKSUM_NONE:
+		wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+				    wsum);
+
+		/* fall through */
+
 	case CHECKSUM_COMPLETE:
 		if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
-				  skb->csum)) {
+				  wsum)) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			break;
 		}
-flush:
+
 		NAPI_GRO_CB(skb)->flush = 1;
 		return NULL;
-
-	case CHECKSUM_NONE:
-		wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
-						    skb_gro_len(skb),
-						    IPPROTO_TCP, 0));
-		sum = csum_fold(skb_checksum(skb,
-					     skb_gro_offset(skb),
-					     skb_gro_len(skb),
-					     wsum));
-		if (sum)
-			goto flush;
-
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		break;
 	}
 
 skip_csum:

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* Re: [PATCH 1/1] Workaround for Suspend/Resume issue of AX88772B under ChromeOS
From: Florian Fainelli @ 2013-11-22  2:42 UTC (permalink / raw)
  To: Grant Grundler
  Cc: David Miller, Freddy Xin, netdev, linux-usb, LKML, davemloft,
	ASIX Louis [蘇威陸], Allan Chou, Daniel_ASIX
In-Reply-To: <CANEJEGuo4rbz4hP=RfN8A+4ozjuJ7oZmtLcmkjbkxrGZrpRr5A@mail.gmail.com>

2013/11/21 Grant Grundler <grundler@google.com>:
> On Thu, Nov 21, 2013 at 5:58 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> ...
>>> Freddy sent me a patch that saves/restores MII_ADVERTISE and MII_BMCR
>>> registers. Testing that now and he'll post if that all works out.
>
> Bad News: Freddy's patch didn't work and needs to be rework it.
>
>> That should be enough to ensure the PHY is put back into a consistent
>> state. So long as you are suspending/resuming from a configuration
>> where autoneg was enabled, I would not expect anything bad to happen.
>
> Well, I think davem NACK'd that approach (the original patch in this
> thread did that).
>
>> If the link was forced, that is a different story.
>>
>> One way to make sure this work properly without driver-specific code
>> is to include that functionality into the PHY library. As far as I can
>> see it the asix drivers do not use it but implement the old-style
>> mii_bus interface so that would be a first step.
>
> AFAICT, many USBNET drivers support mii_bus interface. Can you point
> at a good example of a USBNET driver that is supporting PHY lib?

drivers/net/usb/ax88172a.c implements the PHY library calls.

>
> I also didn't see anything in usbnet_resume() code path that calls
> into a phy lib. So it seems that some infrastructure still needs to
> happen if that's considered a feasible.

There are still some pending patches to make sure that suspend/resume
are properly being taken care of when issuing phy_stop/phy_start, but
once that is done, you would not have to call anything in
usbnet_resume(), the driver's ndo_open() callback would call
phy_start() which would resume the PHY into the state it was before
suspending.
-- 
Florian

^ permalink raw reply

* Re: [PATCH] bonding: If IP route look-up to send an ARP fails, mark in bonding structure as no ARP sent.
From: Jay Vosburgh @ 2013-11-22  2:43 UTC (permalink / raw)
  To: rama nichanamatlu; +Cc: Veaceslav Falico, netdev
In-Reply-To: <528EA6A1.5040209@oracle.com>

rama nichanamatlu <rama.nichanamatlu@oracle.com> wrote:

>On 11/21/2013 1:12 PM, Jay Vosburgh wrote:
>> rama nichanamatlu <rama.nichanamatlu@oracle.com> wrote:
>> 
>>> On 11/21/2013 3:10 AM, Veaceslav Falico wrote:
>>>> On Wed, Nov 20, 2013 at 04:53:20PM -0800, rama nichanamatlu wrote:
>>>>> During the creation of VLAN's atop bonding the underlying interfaces
>>>>> are made part of VLAN's, and at the same bonding driver gets aware
>>>>> that VLAN's exists above it and hence would consult IP routing for
>>>>> every ARP to  be sent to determine the route which tells bonding
>>>>> driver the correct VLAN tag to attach to the outgoing ARP packet. But,
>>>>> during the VLAN creation when vlan driver puts the underlying
>>>>> interface into default vlan and then actual vlan, in-between this if
>>>>> bonding driver consults the IP for a route, IP fails to provide a
>>>>> correct route and upon which bonding driver drops the ARP packet. ARP
>>>>> monitor when it
>>>>> comes around next time, sees no ARP response and fails-over to the
>>>>> next available slave. Consulting for a IP route,
>>>>> ip_route_output(),happens in bond_arp_send_all().
>>>>
>>>> bonding works as expected - nothing to fix here. And even as a
>>>> workaround/hack - I'm not sure we need that to suppress one failover *only*
>>>> when vlan is added on top.
>>>>
>>>>>
>>> Thank U.
>>> With *out* this change our systems failed system testing, to
>>> consistently be on designated primary interface on *every* single
>>> reboot. With this change the behavior was as expected even after a few
>>> thousand reboots & System testing could move to next level catching an
>>> another bug in sr-iov :). And Without, the outcome was less predictable
>>> after a reboot and bonding was on a different slave each time.
>>> -Rama
>> 
>> 	By "designated primary" you mean the bonding primary option,
>> correct?  
>Yes correct. Bonding primary param is set.
>ex: primary=eth1 and primary_reselect=2.
>Hence it is expected to be on primary on every reboot.

	If I set up a basic bonding configuration like:

[ eth3, eth4 ] -> bond0 -> bond0.66, with primary=eth3 primary_reselect=2

	Then look at dmesg, I see this sequence:

	The bond is set up first, with an arp_ip_target on a VLAN
destination.  The slaves are added to the bond.

	The VLAN interface is configured above the bond, and brought up.

	The slaves become link up after autonegotiation, the ARP monitor
commences, and eth3 is made the active slave.  Even if eth4 is set by
the bond to be "link status up," eth3 becomes the active slave when it
becomes "link status up."

	What network device are you using for the slaves?  Are they
virtualized devices of some kind?  My suspicion is that Ethernet
autonegotiation either does not take place or occurs so quickly that the
slaves are carrier up before the VLAN is even added.

	Can you check your dmesg output for the sequence of events?  In
my test, I do not see the slaves go "NIC Link is Up 1000 Mbps Full
Duplex" until about 3 seconds after the VLAN interface has been
configured.


	-J

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* Re: Question about IPv6 neighbor discovery and 6lowpan
From: Marcel Holtmann @ 2013-11-22  3:29 UTC (permalink / raw)
  To: Jukka Rissanen; +Cc: Alexander Aring, David S. Miller, netdev
In-Reply-To: <1385049135.2723.25.camel@jrissane-mobl.ger.corp.intel.com>

Hi Jukka,

>>> I am investigating RFC 6775 (Neighbor Discovery Optimization for IPv6
>>> over Low-Power Wireless Personal Area Networks (6LoWPANs))
>>> http://tools.ietf.org/html/rfc6775
>>> 
>>> The RFC suggests some changes to neighbor discovery procedure for the
>>> 6LoWPAN networks. I was looking net/ipv6/ndisc.c and it seems that
>>> ARPHRD type (from type field in net_device struct) is the only way to
>>> detect and change the discovery procedure in the ndisc.c code. Am I
>>> right with this assumption here?
>>> 
>> I think you are right, there was some patches on linux-zigbee-devel who
>> use exact the same idea to check the ARPHRD type.
> 
> Ok. The reason I was interested in about this is that I proposed new
> ARPHRD_RAWIP earlier that I could use in BT LE 6lowpan code. Now I think
> that type might be too generic and perhaps I should have ARPHRD_6LOWPAN
> or even ARPHRD_BT_6LOWPAN.

if it can be shared between 802.15.4 and Bluetooth, then I would propose to use ARPHRD_6LOWPAN and also convert the 802.15.4 stack to use that one.

Regards

Marcel

^ permalink raw reply

* gretap IP fragmentation
From: "Oleg A. Arkhangelsky" @ 2013-11-22  4:20 UTC (permalink / raw)
  To: netdev

Hello,

Trying to investigate problems transmitting IP packets of specific size
from gretap interface which is member of bridge device. To correctly
forward near-1500 byte L2 packets MTU of GRE-interface should be 1500.
But I don't understand why in case of IP packet tunnel code just copies
DF flag from the inner IP header to the outer header even when
"nopmtudisc" for gretap device is set? In this way fragmentation doesn't
performed and packet silently dropped.

Is this an intentional behavior of gretap or some kind of bug?

Thank you!

-- 
wbr, Oleg.

"Anarchy is about taking complete responsibility for yourself."
      Alan Moore.

^ permalink raw reply

* Re: Question about IPv6 neighbor discovery and 6lowpan
From: Alexander Aring @ 2013-11-22  5:30 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Jukka Rissanen, David S. Miller, netdev
In-Reply-To: <692AEC23-372B-48A9-BEA7-02C2F6C13A47@holtmann.org>

On Fri, Nov 22, 2013 at 10:29:06AM +0700, Marcel Holtmann wrote:
> Hi Jukka,
> 
> >>> I am investigating RFC 6775 (Neighbor Discovery Optimization for IPv6
> >>> over Low-Power Wireless Personal Area Networks (6LoWPANs))
> >>> http://tools.ietf.org/html/rfc6775
> >>> 
> >>> The RFC suggests some changes to neighbor discovery procedure for the
> >>> 6LoWPAN networks. I was looking net/ipv6/ndisc.c and it seems that
> >>> ARPHRD type (from type field in net_device struct) is the only way to
> >>> detect and change the discovery procedure in the ndisc.c code. Am I
> >>> right with this assumption here?
> >>> 
> >> I think you are right, there was some patches on linux-zigbee-devel who
> >> use exact the same idea to check the ARPHRD type.
> > 
> > Ok. The reason I was interested in about this is that I proposed new
> > ARPHRD_RAWIP earlier that I could use in BT LE 6lowpan code. Now I think
> > that type might be too generic and perhaps I should have ARPHRD_6LOWPAN
> > or even ARPHRD_BT_6LOWPAN.
> 
> if it can be shared between 802.15.4 and Bluetooth, then I would propose to use ARPHRD_6LOWPAN and also convert the 802.15.4 stack to use that one.
> 
Yea, that would be great. :-)

- Alex

^ permalink raw reply

* Re: [1/2] gro: Only verify TCP checksums for candidates
From: Eric Dumazet @ 2013-11-22  5:55 UTC (permalink / raw)
  To: Herbert Xu
  Cc: David Miller, alexander.h.duyck, alexander.duyck, netdev,
	edumazet
In-Reply-To: <20131122023129.GA6506@gondor.apana.org.au>

On Fri, 2013-11-22 at 10:31 +0800, Herbert Xu wrote:
> In some cases we may receive IP packets that are longer than
> their stated lengths.  Such packets are never merged in GRO.
> However, we may end up computing their checksums incorrectly
> and end up allowing packets with a bogus checksum enter our
> stack with the checksum status set as verified.
> 
> Since such packets are rare and not performance-critical, this
> patch simply skips the checksum verification for them.
> 
> Reported-by: Alexander Duyck <alexander.h.duyck@intel.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>

Acked-by: Eric Dumazet <edumazet@google.com>

^ 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