summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoen Vandeputte2026-03-18 16:02:20 +0000
committerKoen Vandeputte2026-03-18 16:02:20 +0000
commit3a7d0ef4eee0c1185067ec60eb23f279cbc69f85 (patch)
treede658b2a29c3015251b5cfbf723d3839a6a69b9f
parent9bfe8b22b80a23a6a3bd73cd88285e4a06724a69 (diff)
downloadxback-master.tar.gz
kernel: backport qmi patchHEADmaster
This fixes setting required large MTU sizes when combining qmi_wwan with rmnet Signed-off-by: Koen Vandeputte <koen.vandeputte@citymesh.com>
-rw-r--r--target/linux/generic/pending-6.12/742-qmi_wwan-allow-max_mtu-above-hard_mtu-to-control-rx_.patch97
1 files changed, 97 insertions, 0 deletions
diff --git a/target/linux/generic/pending-6.12/742-qmi_wwan-allow-max_mtu-above-hard_mtu-to-control-rx_.patch b/target/linux/generic/pending-6.12/742-qmi_wwan-allow-max_mtu-above-hard_mtu-to-control-rx_.patch
new file mode 100644
index 0000000000..0203c4ada7
--- /dev/null
+++ b/target/linux/generic/pending-6.12/742-qmi_wwan-allow-max_mtu-above-hard_mtu-to-control-rx_.patch
@@ -0,0 +1,97 @@
+From 0a1029416173bb345b1d8060193307f3ace2538a Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 4 Mar 2026 14:43:38 +0100
+Subject: [PATCH] qmi_wwan: allow max_mtu above hard_mtu to control rx_urb_size
+
+commit 55f854dd5bdd8e19b936a00ef1f8d776ac32c7b0 upstream.
+
+Commit c7159e960f14 ("usbnet: limit max_mtu based on device's hard_mtu")
+capped net->max_mtu to the device's hard_mtu in usbnet_probe(). While
+this correctly prevents oversized packets on standard USB network
+devices, it breaks the qmi_wwan driver.
+
+qmi_wwan relies on userspace (e.g. ModemManager) setting a large MTU on
+the wwan0 interface to configure rx_urb_size via usbnet_change_mtu().
+QMI modems negotiate USB transfer sizes of 16,383 or 32,767 bytes, and
+the USB receive buffers must be sized accordingly. With max_mtu capped
+to hard_mtu (~1500 bytes), userspace can no longer raise the MTU, the
+receive buffers remain small, and download speeds drop from >300 Mbps
+to ~0.8 Mbps.
+
+Introduce a FLAG_NOMAXMTU driver flag that allows individual usbnet
+drivers to opt out of the max_mtu cap. Set this flag in qmi_wwan's
+driver_info structures to restore the previous behavior for QMI devices,
+while keeping the safety fix in place for all other usbnet drivers.
+
+Fixes: c7159e960f14 ("usbnet: limit max_mtu based on device's hard_mtu")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/lkml/CAPh3n803k8JcBPV5qEzUB-oKzWkAs-D5CU7z=Vd_nLRCr5ZqQg@mail.gmail.com/
+Reported-by: Koen Vandeputte <koen.vandeputte@citymesh.com>
+Tested-by: Daniele Palmas <dnlplm@gmail.com>
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Link: https://patch.msgid.link/20260304134338.1785002-1-lvivier@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c | 4 ++--
+ drivers/net/usb/usbnet.c | 7 ++++---
+ include/linux/usb/usbnet.h | 1 +
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index bd51435ed418..fd8d7cb1870a 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -928,7 +928,7 @@ static int qmi_wwan_resume(struct usb_interface *intf)
+
+ static const struct driver_info qmi_wwan_info = {
+ .description = "WWAN/QMI device",
+- .flags = FLAG_WWAN | FLAG_SEND_ZLP,
++ .flags = FLAG_WWAN | FLAG_NOMAXMTU | FLAG_SEND_ZLP,
+ .bind = qmi_wwan_bind,
+ .unbind = qmi_wwan_unbind,
+ .manage_power = qmi_wwan_manage_power,
+@@ -937,7 +937,7 @@ static const struct driver_info qmi_wwan_info = {
+
+ static const struct driver_info qmi_wwan_info_quirk_dtr = {
+ .description = "WWAN/QMI device",
+- .flags = FLAG_WWAN | FLAG_SEND_ZLP,
++ .flags = FLAG_WWAN | FLAG_NOMAXMTU | FLAG_SEND_ZLP,
+ .bind = qmi_wwan_bind,
+ .unbind = qmi_wwan_unbind,
+ .manage_power = qmi_wwan_manage_power,
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index f4a05737abf7..30585ef53ae3 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1797,11 +1797,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
+ if ((dev->driver_info->flags & FLAG_NOARP) != 0)
+ net->flags |= IFF_NOARP;
+
+- if (net->max_mtu > (dev->hard_mtu - net->hard_header_len))
++ if ((dev->driver_info->flags & FLAG_NOMAXMTU) == 0 &&
++ net->max_mtu > (dev->hard_mtu - net->hard_header_len))
+ net->max_mtu = dev->hard_mtu - net->hard_header_len;
+
+- if (net->mtu > net->max_mtu)
+- net->mtu = net->max_mtu;
++ if (net->mtu > (dev->hard_mtu - net->hard_header_len))
++ net->mtu = dev->hard_mtu - net->hard_header_len;
+
+ } else if (!info->in || !info->out)
+ status = usbnet_get_endpoints (dev, udev);
+diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
+index 4bc6bb01a0eb..b593473d8d32 100644
+--- a/include/linux/usb/usbnet.h
++++ b/include/linux/usb/usbnet.h
+@@ -130,6 +130,7 @@ struct driver_info {
+ #define FLAG_MULTI_PACKET 0x2000
+ #define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */
+ #define FLAG_NOARP 0x8000 /* device can't do ARP */
++#define FLAG_NOMAXMTU 0x10000 /* allow max_mtu above hard_mtu */
+
+ /* init device ... can sleep, or cause probe() failure */
+ int (*bind)(struct usbnet *, struct usb_interface *);
+--
+2.43.0
+