summaryrefslogtreecommitdiff
path: root/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch')
-rw-r--r--target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch73
1 files changed, 73 insertions, 0 deletions
diff --git a/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch b/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch
new file mode 100644
index 0000000..2511e0a
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch
@@ -0,0 +1,73 @@
+From a4abd7a80addb4a9547f7dfc7812566b60ec505c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Wed, 6 Dec 2017 20:21:24 +0100
+Subject: [PATCH] usbnet: fix alignment for frames with no ethernet header
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The qmi_wwan minidriver support a 'raw-ip' mode where frames are
+received without any ethernet header. This causes alignment issues
+because the skbs allocated by usbnet are "IP aligned".
+
+Fix by allowing minidrivers to disable the additional alignment
+offset. This is implemented using a per-device flag, since the same
+minidriver also supports 'ethernet' mode.
+
+Fixes: 32f7adf633b9 ("net: qmi_wwan: support "raw IP" mode")
+Reported-and-tested-by: Jay Foster <jay@systech.com>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 2 ++
+ drivers/net/usb/usbnet.c | 5 ++++-
+ include/linux/usb/usbnet.h | 1 +
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index c750cf7c042b..304ec6555cd8 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -261,9 +261,11 @@ static void qmi_wwan_netdev_setup(struct net_device *net)
+ net->hard_header_len = 0;
+ net->addr_len = 0;
+ net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++ set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
+ netdev_dbg(net, "mode: raw IP\n");
+ } else if (!net->header_ops) { /* don't bother if already set */
+ ether_setup(net);
++ clear_bit(EVENT_NO_IP_ALIGN, &dev->flags);
+ netdev_dbg(net, "mode: Ethernet\n");
+ }
+
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 80348b6a8646..d56fe32bf48d 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -484,7 +484,10 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
+ return -ENOLINK;
+ }
+
+- skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
++ if (test_bit(EVENT_NO_IP_ALIGN, &dev->flags))
++ skb = __netdev_alloc_skb(dev->net, size, flags);
++ else
++ skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
+ if (!skb) {
+ netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
+ usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
+diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
+index a69877734c4e..e2ec3582e549 100644
+--- a/include/linux/usb/usbnet.h
++++ b/include/linux/usb/usbnet.h
+@@ -82,6 +82,7 @@ struct usbnet {
+ # define EVENT_RX_KILL 10
+ # define EVENT_LINK_CHANGE 11
+ # define EVENT_SET_RX_MODE 12
++# define EVENT_NO_IP_ALIGN 13
+ };
+
+ static inline struct usb_driver *driver_of(struct usb_interface *intf)
+--
+2.7.4
+