| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | * CDC Ethernet based networking peripherals | 
|---|
| 3 | 4 | * Copyright (C) 2003-2005 by David Brownell | 
|---|
| 4 | 5 | * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) | 
|---|
| 5 |  | - * | 
|---|
| 6 |  | - * This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |  | - * it under the terms of the GNU General Public License as published by | 
|---|
| 8 |  | - * the Free Software Foundation; either version 2 of the License, or | 
|---|
| 9 |  | - * (at your option) any later version. | 
|---|
| 10 |  | - * | 
|---|
| 11 |  | - * This program is distributed in the hope that it will be useful, | 
|---|
| 12 |  | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 13 |  | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 14 |  | - * GNU General Public License for more details. | 
|---|
| 15 |  | - * | 
|---|
| 16 |  | - * You should have received a copy of the GNU General Public License | 
|---|
| 17 |  | - * along with this program; if not, see <http://www.gnu.org/licenses/>. | 
|---|
| 18 | 6 | */ | 
|---|
| 19 | 7 |  | 
|---|
| 20 | 8 | // #define	DEBUG			// error path messages, extra info | 
|---|
| .. | .. | 
|---|
| 75 | 63 | 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a, | 
|---|
| 76 | 64 | }; | 
|---|
| 77 | 65 |  | 
|---|
| 78 |  | -static void usbnet_cdc_update_filter(struct usbnet *dev) | 
|---|
|  | 66 | +void usbnet_cdc_update_filter(struct usbnet *dev) | 
|---|
| 79 | 67 | { | 
|---|
| 80 |  | -	struct cdc_state	*info = (void *) &dev->data; | 
|---|
| 81 |  | -	struct usb_interface	*intf = info->control; | 
|---|
| 82 | 68 | struct net_device	*net = dev->net; | 
|---|
| 83 | 69 |  | 
|---|
| 84 | 70 | u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED | 
|---|
| .. | .. | 
|---|
| 98 | 84 | USB_CDC_SET_ETHERNET_PACKET_FILTER, | 
|---|
| 99 | 85 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 
|---|
| 100 | 86 | cdc_filter, | 
|---|
| 101 |  | -			intf->cur_altsetting->desc.bInterfaceNumber, | 
|---|
|  | 87 | +			dev->intf->cur_altsetting->desc.bInterfaceNumber, | 
|---|
| 102 | 88 | NULL, | 
|---|
| 103 | 89 | 0, | 
|---|
| 104 | 90 | USB_CTRL_SET_TIMEOUT | 
|---|
| 105 | 91 | ); | 
|---|
| 106 | 92 | } | 
|---|
|  | 93 | +EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter); | 
|---|
| 107 | 94 |  | 
|---|
| 108 | 95 | /* probes control interface, claims data interface, collects the bulk | 
|---|
| 109 | 96 | * endpoints, activates data interface (if needed), maybe sets MTU. | 
|---|
| .. | .. | 
|---|
| 179 | 166 | * probed with) and a slave/data interface; union | 
|---|
| 180 | 167 | * descriptors sort this all out. | 
|---|
| 181 | 168 | */ | 
|---|
| 182 |  | -	info->control = usb_ifnum_to_if(dev->udev, | 
|---|
| 183 |  | -	info->u->bMasterInterface0); | 
|---|
| 184 |  | -	info->data = usb_ifnum_to_if(dev->udev, | 
|---|
| 185 |  | -		info->u->bSlaveInterface0); | 
|---|
|  | 169 | +	info->control = usb_ifnum_to_if(dev->udev, info->u->bMasterInterface0); | 
|---|
|  | 170 | +	info->data = usb_ifnum_to_if(dev->udev, info->u->bSlaveInterface0); | 
|---|
| 186 | 171 | if (!info->control || !info->data) { | 
|---|
| 187 | 172 | dev_dbg(&intf->dev, | 
|---|
| 188 | 173 | "master #%u/%p slave #%u/%p\n", | 
|---|
| .. | .. | 
|---|
| 216 | 201 | /* a data interface altsetting does the real i/o */ | 
|---|
| 217 | 202 | d = &info->data->cur_altsetting->desc; | 
|---|
| 218 | 203 | if (d->bInterfaceClass != USB_CLASS_CDC_DATA) { | 
|---|
| 219 |  | -		dev_dbg(&intf->dev, "slave class %u\n", | 
|---|
| 220 |  | -			d->bInterfaceClass); | 
|---|
|  | 204 | +		dev_dbg(&intf->dev, "slave class %u\n", d->bInterfaceClass); | 
|---|
| 221 | 205 | goto bad_desc; | 
|---|
| 222 | 206 | } | 
|---|
| 223 | 207 | skip: | 
|---|
| .. | .. | 
|---|
| 231 | 215 | if (rndis && is_rndis(&intf->cur_altsetting->desc) && | 
|---|
| 232 | 216 | header.usb_cdc_acm_descriptor && | 
|---|
| 233 | 217 | header.usb_cdc_acm_descriptor->bmCapabilities) { | 
|---|
| 234 |  | -			dev_dbg(&intf->dev, | 
|---|
| 235 |  | -				"ACM capabilities %02x, not really RNDIS?\n", | 
|---|
| 236 |  | -				header.usb_cdc_acm_descriptor->bmCapabilities); | 
|---|
| 237 |  | -			goto bad_desc; | 
|---|
|  | 218 | +		dev_dbg(&intf->dev, | 
|---|
|  | 219 | +			"ACM capabilities %02x, not really RNDIS?\n", | 
|---|
|  | 220 | +			header.usb_cdc_acm_descriptor->bmCapabilities); | 
|---|
|  | 221 | +		goto bad_desc; | 
|---|
| 238 | 222 | } | 
|---|
| 239 | 223 |  | 
|---|
| 240 | 224 | if (header.usb_cdc_ether_desc && info->ether->wMaxSegmentSize) { | 
|---|
| .. | .. | 
|---|
| 245 | 229 | } | 
|---|
| 246 | 230 |  | 
|---|
| 247 | 231 | if (header.usb_cdc_mdlm_desc && | 
|---|
| 248 |  | -		memcmp(header.usb_cdc_mdlm_desc->bGUID, mbm_guid, 16)) { | 
|---|
|  | 232 | +	    memcmp(header.usb_cdc_mdlm_desc->bGUID, mbm_guid, 16)) { | 
|---|
| 249 | 233 | dev_dbg(&intf->dev, "GUID doesn't match\n"); | 
|---|
| 250 | 234 | goto bad_desc; | 
|---|
| 251 | 235 | } | 
|---|
| .. | .. | 
|---|
| 309 | 293 | if (info->control->cur_altsetting->desc.bNumEndpoints == 1) { | 
|---|
| 310 | 294 | struct usb_endpoint_descriptor	*desc; | 
|---|
| 311 | 295 |  | 
|---|
| 312 |  | -		dev->status = &info->control->cur_altsetting->endpoint [0]; | 
|---|
|  | 296 | +		dev->status = &info->control->cur_altsetting->endpoint[0]; | 
|---|
| 313 | 297 | desc = &dev->status->desc; | 
|---|
| 314 | 298 | if (!usb_endpoint_is_int_in(desc) || | 
|---|
| 315 | 299 | (le16_to_cpu(desc->wMaxPacketSize) | 
|---|
| .. | .. | 
|---|
| 554 | 538 | .manage_power =	usbnet_manage_power, | 
|---|
| 555 | 539 | }; | 
|---|
| 556 | 540 |  | 
|---|
| 557 |  | -static const struct driver_info lte_info = { | 
|---|
| 558 |  | -	.description =  "CDC Ethernet Device(lte)", | 
|---|
| 559 |  | -	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_LTE, | 
|---|
| 560 |  | -	.bind =		usbnet_cdc_bind, | 
|---|
| 561 |  | -	.unbind =	usbnet_cdc_unbind, | 
|---|
| 562 |  | -	.status =	usbnet_cdc_status, | 
|---|
| 563 |  | -	.set_rx_mode =	usbnet_cdc_update_filter, | 
|---|
| 564 |  | -	.manage_power =	usbnet_manage_power, | 
|---|
| 565 |  | -}; | 
|---|
| 566 |  | - | 
|---|
| 567 | 541 | /*-------------------------------------------------------------------------*/ | 
|---|
| 568 | 542 |  | 
|---|
| 569 | 543 | #define HUAWEI_VENDOR_ID	0x12D1 | 
|---|
| .. | .. | 
|---|
| 579 | 553 | #define MICROSOFT_VENDOR_ID	0x045e | 
|---|
| 580 | 554 | #define UBLOX_VENDOR_ID		0x1546 | 
|---|
| 581 | 555 | #define TPLINK_VENDOR_ID	0x2357 | 
|---|
|  | 556 | +#define AQUANTIA_VENDOR_ID	0x2eca | 
|---|
|  | 557 | +#define ASIX_VENDOR_ID		0x0b95 | 
|---|
| 582 | 558 |  | 
|---|
| 583 | 559 | static const struct usb_device_id	products[] = { | 
|---|
| 584 | 560 | /* BLACKLIST !! | 
|---|
| .. | .. | 
|---|
| 787 | 763 | }, | 
|---|
| 788 | 764 | #endif | 
|---|
| 789 | 765 |  | 
|---|
|  | 766 | +/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */ | 
|---|
|  | 767 | +{ | 
|---|
|  | 768 | +	USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM, | 
|---|
|  | 769 | +			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | 
|---|
|  | 770 | +	.driver_info = 0, | 
|---|
|  | 771 | +}, | 
|---|
|  | 772 | + | 
|---|
| 790 | 773 | /* ThinkPad USB-C Dock (based on Realtek RTL8153) */ | 
|---|
| 791 | 774 | { | 
|---|
| 792 | 775 | USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, | 
|---|
| .. | .. | 
|---|
| 797 | 780 | /* ThinkPad Thunderbolt 3 Dock (based on Realtek RTL8153) */ | 
|---|
| 798 | 781 | { | 
|---|
| 799 | 782 | USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3069, USB_CLASS_COMM, | 
|---|
|  | 783 | +			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | 
|---|
|  | 784 | +	.driver_info = 0, | 
|---|
|  | 785 | +}, | 
|---|
|  | 786 | + | 
|---|
|  | 787 | +/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ | 
|---|
|  | 788 | +{ | 
|---|
|  | 789 | +	USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, | 
|---|
| 800 | 790 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | 
|---|
| 801 | 791 | .driver_info = 0, | 
|---|
| 802 | 792 | }, | 
|---|
| .. | .. | 
|---|
| 868 | 858 | { | 
|---|
| 869 | 859 | USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, | 
|---|
| 870 | 860 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | 
|---|
|  | 861 | +	.driver_info = 0, | 
|---|
|  | 862 | +}, | 
|---|
|  | 863 | + | 
|---|
|  | 864 | +/* Aquantia AQtion USB to 5GbE Controller (based on AQC111U) */ | 
|---|
|  | 865 | +{ | 
|---|
|  | 866 | +	USB_DEVICE_AND_INTERFACE_INFO(AQUANTIA_VENDOR_ID, 0xc101, | 
|---|
|  | 867 | +				      USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, | 
|---|
|  | 868 | +				      USB_CDC_PROTO_NONE), | 
|---|
|  | 869 | +	.driver_info = 0, | 
|---|
|  | 870 | +}, | 
|---|
|  | 871 | + | 
|---|
|  | 872 | +/* ASIX USB 3.1 Gen1 to 5G Multi-Gigabit Ethernet Adapter(based on AQC111U) */ | 
|---|
|  | 873 | +{ | 
|---|
|  | 874 | +	USB_DEVICE_AND_INTERFACE_INFO(ASIX_VENDOR_ID, 0x2790, USB_CLASS_COMM, | 
|---|
|  | 875 | +				      USB_CDC_SUBCLASS_ETHERNET, | 
|---|
|  | 876 | +				      USB_CDC_PROTO_NONE), | 
|---|
|  | 877 | +	.driver_info = 0, | 
|---|
|  | 878 | +}, | 
|---|
|  | 879 | + | 
|---|
|  | 880 | +/* ASIX USB 3.1 Gen1 to 2.5G Multi-Gigabit Ethernet Adapter(based on AQC112U) */ | 
|---|
|  | 881 | +{ | 
|---|
|  | 882 | +	USB_DEVICE_AND_INTERFACE_INFO(ASIX_VENDOR_ID, 0x2791, USB_CLASS_COMM, | 
|---|
|  | 883 | +				      USB_CDC_SUBCLASS_ETHERNET, | 
|---|
|  | 884 | +				      USB_CDC_PROTO_NONE), | 
|---|
|  | 885 | +	.driver_info = 0, | 
|---|
|  | 886 | +}, | 
|---|
|  | 887 | + | 
|---|
|  | 888 | +/* USB-C 3.1 to 5GBASE-T Ethernet Adapter (based on AQC111U) */ | 
|---|
|  | 889 | +{ | 
|---|
|  | 890 | +	USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0xe05a, USB_CLASS_COMM, | 
|---|
|  | 891 | +				      USB_CDC_SUBCLASS_ETHERNET, | 
|---|
|  | 892 | +				      USB_CDC_PROTO_NONE), | 
|---|
|  | 893 | +	.driver_info = 0, | 
|---|
|  | 894 | +}, | 
|---|
|  | 895 | + | 
|---|
|  | 896 | +/* QNAP QNA-UC5G1T USB to 5GbE Adapter (based on AQC111U) */ | 
|---|
|  | 897 | +{ | 
|---|
|  | 898 | +	USB_DEVICE_AND_INTERFACE_INFO(0x1c04, 0x0015, USB_CLASS_COMM, | 
|---|
|  | 899 | +				      USB_CDC_SUBCLASS_ETHERNET, | 
|---|
|  | 900 | +				      USB_CDC_PROTO_NONE), | 
|---|
| 871 | 901 | .driver_info = 0, | 
|---|
| 872 | 902 | }, | 
|---|
| 873 | 903 |  | 
|---|
| .. | .. | 
|---|
| 957 | 987 | USB_CDC_SUBCLASS_ETHERNET, | 
|---|
| 958 | 988 | USB_CDC_PROTO_NONE), | 
|---|
| 959 | 989 | .driver_info = (unsigned long)&wwan_info, | 
|---|
| 960 |  | -}, { | 
|---|
| 961 |  | -	/* RM310 modules*/ | 
|---|
| 962 |  | -	USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x4E3C, USB_CLASS_COMM, | 
|---|
| 963 |  | -				      USB_CDC_SUBCLASS_ETHERNET, | 
|---|
| 964 |  | -				      USB_CDC_PROTO_NONE), | 
|---|
| 965 |  | -	.driver_info = (unsigned long)<e_info, | 
|---|
| 966 | 990 | }, { | 
|---|
| 967 | 991 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, | 
|---|
| 968 | 992 | USB_CDC_PROTO_NONE), | 
|---|