mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
qmi_wwan: allow max_mtu above hard_mtu to control rx_urb_size
Commitc7159e960f("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:c7159e960f("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>
This commit is contained in:
committed by
Jakub Kicinski
parent
03910cdc21
commit
55f854dd5b
@@ -928,7 +928,7 @@ err:
|
||||
|
||||
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,
|
||||
|
||||
@@ -1829,11 +1829,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);
|
||||
|
||||
@@ -132,6 +132,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 *);
|
||||
|
||||
Reference in New Issue
Block a user