| From foo@baz Mon 16 Sep 2019 01:07:00 PM CEST |
| From: "Bjørn Mork" <bjorn@mork.no> |
| Date: Thu, 12 Sep 2019 10:42:00 +0200 |
| Subject: cdc_ether: fix rndis support for Mediatek based smartphones |
| |
| From: "Bjørn Mork" <bjorn@mork.no> |
| |
| [ Upstream commit 4d7ffcf3bf1be98d876c570cab8fc31d9fa92725 ] |
| |
| A Mediatek based smartphone owner reports problems with USB |
| tethering in Linux. The verbose USB listing shows a rndis_host |
| interface pair (e0/01/03 + 10/00/00), but the driver fails to |
| bind with |
| |
| [ 355.960428] usb 1-4: bad CDC descriptors |
| |
| The problem is a failsafe test intended to filter out ACM serial |
| functions using the same 02/02/ff class/subclass/protocol as RNDIS. |
| The serial functions are recognized by their non-zero bmCapabilities. |
| |
| No RNDIS function with non-zero bmCapabilities were known at the time |
| this failsafe was added. But it turns out that some Wireless class |
| RNDIS functions are using the bmCapabilities field. These functions |
| are uniquely identified as RNDIS by their class/subclass/protocol, so |
| the failing test can safely be disabled. The same applies to the two |
| types of Misc class RNDIS functions. |
| |
| Applying the failsafe to Communication class functions only retains |
| the original functionality, and fixes the problem for the Mediatek based |
| smartphone. |
| |
| Tow examples of CDC functional descriptors with non-zero bmCapabilities |
| from Wireless class RNDIS functions are: |
| |
| 0e8d:000a Mediatek Crosscall Spider X5 3G Phone |
| |
| CDC Header: |
| bcdCDC 1.10 |
| CDC ACM: |
| bmCapabilities 0x0f |
| connection notifications |
| sends break |
| line coding and serial state |
| get/set/clear comm features |
| CDC Union: |
| bMasterInterface 0 |
| bSlaveInterface 1 |
| CDC Call Management: |
| bmCapabilities 0x03 |
| call management |
| use DataInterface |
| bDataInterface 1 |
| |
| and |
| |
| 19d2:1023 ZTE K4201-z |
| |
| CDC Header: |
| bcdCDC 1.10 |
| CDC ACM: |
| bmCapabilities 0x02 |
| line coding and serial state |
| CDC Call Management: |
| bmCapabilities 0x03 |
| call management |
| use DataInterface |
| bDataInterface 1 |
| CDC Union: |
| bMasterInterface 0 |
| bSlaveInterface 1 |
| |
| The Mediatek example is believed to apply to most smartphones with |
| Mediatek firmware. The ZTE example is most likely also part of a larger |
| family of devices/firmwares. |
| |
| Suggested-by: Lars Melin <larsm17@gmail.com> |
| Signed-off-by: Bjørn Mork <bjorn@mork.no> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/usb/cdc_ether.c | 13 ++++++++++--- |
| 1 file changed, 10 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/net/usb/cdc_ether.c |
| +++ b/drivers/net/usb/cdc_ether.c |
| @@ -221,9 +221,16 @@ int usbnet_generic_cdc_bind(struct usbne |
| goto bad_desc; |
| } |
| skip: |
| - if ( rndis && |
| - header.usb_cdc_acm_descriptor && |
| - header.usb_cdc_acm_descriptor->bmCapabilities) { |
| + /* Communcation class functions with bmCapabilities are not |
| + * RNDIS. But some Wireless class RNDIS functions use |
| + * bmCapabilities for their own purpose. The failsafe is |
| + * therefore applied only to Communication class RNDIS |
| + * functions. The rndis test is redundant, but a cheap |
| + * optimization. |
| + */ |
| + if (rndis && is_rndis(&intf->cur_altsetting->desc) && |
| + header.usb_cdc_acm_descriptor && |
| + header.usb_cdc_acm_descriptor->bmCapabilities) { |
| dev_dbg(&intf->dev, |
| "ACM capabilities %02x, not really RNDIS?\n", |
| header.usb_cdc_acm_descriptor->bmCapabilities); |