mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 04:53:36 +01:00
Fix for packets being rejected in the ring buffer used by the xHCI controller. When a packet larger than MTU arrives in Linux from the modem, it is discarded with -EOVERFLOW error (Babble error). This is seen on USB3.0 and USB2.0 busses. This is essentially because the MRU (Max Receive Size) is not a separate entity to the MTU (Max Transmit Size) and the received packets can be larger than those transmitted. Following the babble error there were an endless supply of zero-length URBs which are rejected with -EPROTO (increasing the rx input error counter each time). This is only seen on USB3.0. These continue to come ad infinitum until the modem is shutdown. There appears to be a bug in the core USB handling code in Linux that doesn't deal well with network MTUs smaller than 1500 bytes. By default the dev->hard_mtu (the real MTU) is in lockstep with dev->rx_urb_size (essentially an MRU), and it's the latter that is causing trouble. This has nothing to do with the modems; the issue can be reproduced by getting a USB-Ethernet dongle, setting the MTU to 1430, and pinging with size greater than 1406.
This commit is contained in:
parent
45d0b75b98
commit
637f847b68
1 changed files with 7 additions and 0 deletions
|
@ -815,6 +815,13 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
}
|
}
|
||||||
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
||||||
dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
|
dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
|
||||||
|
/* LTE Networks don't always respect their own MTU on receive side;
|
||||||
|
* e.g. AT&T pushes 1430 MTU but still allows 1500 byte packets from
|
||||||
|
* far-end network. Make receive buffer large enough to accommodate
|
||||||
|
* them, and add four bytes so MTU does not equal MRU on network
|
||||||
|
* with 1500 MTU otherwise usbnet_change_mtu() will change both.
|
||||||
|
*/
|
||||||
|
dev->rx_urb_size = ETH_DATA_LEN + 4;
|
||||||
err:
|
err:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue