]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.7/usbnet-fix-alignment-for-frames-with-no-ethernet-header.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / releases / 4.14.7 / usbnet-fix-alignment-for-frames-with-no-ethernet-header.patch
1 From foo@baz Thu Dec 14 11:45:40 CET 2017
2 From: Bjørn Mork <bjorn@mork.no>
3 Date: Wed, 6 Dec 2017 20:21:24 +0100
4 Subject: usbnet: fix alignment for frames with no ethernet header
5
6 From: Bjørn Mork <bjorn@mork.no>
7
8
9 [ Upstream commit a4abd7a80addb4a9547f7dfc7812566b60ec505c ]
10
11 The qmi_wwan minidriver support a 'raw-ip' mode where frames are
12 received without any ethernet header. This causes alignment issues
13 because the skbs allocated by usbnet are "IP aligned".
14
15 Fix by allowing minidrivers to disable the additional alignment
16 offset. This is implemented using a per-device flag, since the same
17 minidriver also supports 'ethernet' mode.
18
19 Fixes: 32f7adf633b9 ("net: qmi_wwan: support "raw IP" mode")
20 Reported-and-tested-by: Jay Foster <jay@systech.com>
21 Signed-off-by: Bjørn Mork <bjorn@mork.no>
22 Signed-off-by: David S. Miller <davem@davemloft.net>
23 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 ---
25 drivers/net/usb/qmi_wwan.c | 2 ++
26 drivers/net/usb/usbnet.c | 5 ++++-
27 include/linux/usb/usbnet.h | 1 +
28 3 files changed, 7 insertions(+), 1 deletion(-)
29
30 --- a/drivers/net/usb/qmi_wwan.c
31 +++ b/drivers/net/usb/qmi_wwan.c
32 @@ -261,9 +261,11 @@ static void qmi_wwan_netdev_setup(struct
33 net->hard_header_len = 0;
34 net->addr_len = 0;
35 net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
36 + set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
37 netdev_dbg(net, "mode: raw IP\n");
38 } else if (!net->header_ops) { /* don't bother if already set */
39 ether_setup(net);
40 + clear_bit(EVENT_NO_IP_ALIGN, &dev->flags);
41 netdev_dbg(net, "mode: Ethernet\n");
42 }
43
44 --- a/drivers/net/usb/usbnet.c
45 +++ b/drivers/net/usb/usbnet.c
46 @@ -484,7 +484,10 @@ static int rx_submit (struct usbnet *dev
47 return -ENOLINK;
48 }
49
50 - skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
51 + if (test_bit(EVENT_NO_IP_ALIGN, &dev->flags))
52 + skb = __netdev_alloc_skb(dev->net, size, flags);
53 + else
54 + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
55 if (!skb) {
56 netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
57 usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
58 --- a/include/linux/usb/usbnet.h
59 +++ b/include/linux/usb/usbnet.h
60 @@ -81,6 +81,7 @@ struct usbnet {
61 # define EVENT_RX_KILL 10
62 # define EVENT_LINK_CHANGE 11
63 # define EVENT_SET_RX_MODE 12
64 +# define EVENT_NO_IP_ALIGN 13
65 };
66
67 static inline struct usb_driver *driver_of(struct usb_interface *intf)