netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
@ 2025-09-28  1:46 yicongsrfy
  2025-09-28  1:46 ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy
  0 siblings, 1 reply; 35+ messages in thread
From: yicongsrfy @ 2025-09-28  1:46 UTC (permalink / raw)
  To: oliver, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.

Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
driver. However, this driver lacks functionality and performs worse than
the vendor's proprietary driver. In my testing, I have identified the
following issues:

1. The cdc_ncm driver does not support changing the link speed via
   ethtool because the corresponding callback function is set to NULL.
2. The CDC protocol does not support retrieving the network duplex status.
3. In TCP_RR and UDP_RR tests, the performance of the cdc_ncm driver
   is significantly lower than that of the vendor's driver:
Average of three netperf runs: `netperf -t {TCP/UDP_RR} -H serverIP -l 120`
- cdc_ncm.ko: TCP_RR: 740, UDP_RR: 750
- ax88179_178a.ko: TCP_RR: 8900, UDP_RR: 9200

Issues related to the vendor's driver ax88179_178a.ko will be addressed
in the next patch.

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index b034ef8a73ea..29cbe9ddd610 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1885,55 +1885,55 @@ static const struct driver_info at_umc2000sp_info = {
 static const struct usb_device_id products[] = {
 {
 	/* ASIX AX88179 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x1790),
 	.driver_info = (unsigned long)&ax88179_info,
 }, {
 	/* ASIX AX88178A 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x178a, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x178a),
 	.driver_info = (unsigned long)&ax88178a_info,
 }, {
 	/* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04b4, 0x3610, 0xff, 0xff, 0),
+	USB_DEVICE(0x04b4, 0x3610),
 	.driver_info = (unsigned long)&cypress_GX3_info,
 }, {
 	/* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x4a00, 0xff, 0xff, 0),
+	USB_DEVICE(0x2001, 0x4a00),
 	.driver_info = (unsigned long)&dlink_dub1312_info,
 }, {
 	/* Sitecom USB 3.0 to Gigabit Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0072, 0xff, 0xff, 0),
+	USB_DEVICE(0x0df6, 0x0072),
 	.driver_info = (unsigned long)&sitecom_info,
 }, {
 	/* Samsung USB Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04e8, 0xa100, 0xff, 0xff, 0),
+	USB_DEVICE(0x04e8, 0xa100),
 	.driver_info = (unsigned long)&samsung_info,
 }, {
 	/* Lenovo OneLinkDock Gigabit LAN */
-	USB_DEVICE_AND_INTERFACE_INFO(0x17ef, 0x304b, 0xff, 0xff, 0),
+	USB_DEVICE(0x17ef, 0x304b),
 	.driver_info = (unsigned long)&lenovo_info,
 }, {
 	/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x0128, 0xff, 0xff, 0),
+	USB_DEVICE(0x050d, 0x0128),
 	.driver_info = (unsigned long)&belkin_info,
 }, {
 	/* Toshiba USB 3.0 GBit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x0a13, 0xff, 0xff, 0),
+	USB_DEVICE(0x0930, 0x0a13),
 	.driver_info = (unsigned long)&toshiba_info,
 }, {
 	/* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0711, 0x0179, 0xff, 0xff, 0),
+	USB_DEVICE(0x0711, 0x0179),
 	.driver_info = (unsigned long)&mct_info,
 }, {
 	/* Allied Telesis AT-UMC2000 USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000e, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000e),
 	.driver_info = (unsigned long)&at_umc2000_info,
 }, {
 	/* Allied Telesis AT-UMC200 USB 3.0/USB 3.1 Gen 1 to Fast Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000f, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000f),
 	.driver_info = (unsigned long)&at_umc200_info,
 }, {
 	/* Allied Telesis AT-UMC2000/SP USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x0010, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x0010),
 	.driver_info = (unsigned long)&at_umc2000sp_info,
 },
 	{ },
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 2/2] net: usb: support quirks in usbnet
  2025-09-28  1:46 [PATCH 1/2] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
@ 2025-09-28  1:46 ` yicongsrfy
  2025-09-29  4:23   ` Jakub Kicinski
  2025-09-29  8:45   ` [PATCH 2/2] net: usb: support quirks in usbnet Oliver Neukum
  0 siblings, 2 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-28  1:46 UTC (permalink / raw)
  To: oliver, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

Some vendors' USB network interface controllers (NICs) may be compatible
with multiple drivers.

I consulted with relevant vendors. Taking the AX88179 chip as an example,
NICs based on this chip may be used across various OS—for instance,
cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
on Linux (despite a previous patch having disabled it).
Therefore, the firmware must support multiple protocols.

Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
Supporting both drivers simultaneously leads to the following issues:

1. Inconsistent driver loading order during reboot stress testing:
   The order in which drivers are loaded can vary across reboots,
   potentially resulting in the unintended driver being loaded. For
   example:
[    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
[    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
[    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
[    4.240627] usbcore: registered new interface driver cdc_ncm
[    4.240908] usbcore: registered new interface driver ax88179_178a

In this case, network connectivity functions, but the cdc_ncm driver is
loaded instead of the expected ax88179_178a.

2. Similar issues during cable plug/unplug testing:
   The same race condition can occur when reconnecting the USB device:
[   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
[   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
1790, bcdDevice= 2.00
[   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[   79.905191] usb 4-1: Product: AX88179B
[   79.905198] usb 4-1: Manufacturer: ASIX
[   79.905201] usb 4-1: SerialNumber: 00EF998E
[   79.915215] ax88179_probe, bConfigurationValue:2
[   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
[   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
[   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
[   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
00.2-1, CDC NCM (NO ZLP)

At this point, the network becomes unusable.

To resolve these issues, introduce a *quirks* mechanism into the usbnet
module. By adding chip-specific identification within the generic usbnet
framework, we can skip the usbnet probe process for devices that require a
dedicated driver.

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/cdc_ncm.c       |  2 +-
 drivers/net/usb/usbnet.c        | 14 +++++++++++
 drivers/net/usb/usbnet_quirks.h | 42 +++++++++++++++++++++++++++++++++
 include/linux/usb/usbnet.h      |  2 ++
 4 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/usb/usbnet_quirks.h

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 5d123df0a866..6fa03e5bd054 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -2117,7 +2117,7 @@ MODULE_DEVICE_TABLE(usb, cdc_devs);
 static struct usb_driver cdc_ncm_driver = {
 	.name = "cdc_ncm",
 	.id_table = cdc_devs,
-	.probe = usbnet_probe,
+	.probe = usbnet_probe_quirks,
 	.disconnect = usbnet_disconnect,
 	.suspend = usbnet_suspend,
 	.resume = usbnet_resume,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 511c4154cf74..51ba466057f9 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -31,6 +31,7 @@
 #include <linux/kernel.h>
 #include <linux/pm_runtime.h>
 
+#include "usbnet_quirks.h"
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1697,6 +1698,19 @@ static const struct device_type wwan_type = {
 	.name	= "wwan",
 };
 
+int usbnet_probe_quirks(struct usb_interface *udev,
+			const struct usb_device_id *prod)
+{
+	/* Should it be ignored? */
+	if (unlikely(usbnet_ignore(udev))) {
+		dev_dbg(&udev->dev, "usbnet ignore this device!\n");
+		return -ENODEV;
+	}
+
+	return usbnet_probe(udev, prod);
+}
+EXPORT_SYMBOL_GPL(usbnet_probe_quirks);
+
 int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
diff --git a/drivers/net/usb/usbnet_quirks.h b/drivers/net/usb/usbnet_quirks.h
new file mode 100644
index 000000000000..85c29237f2b2
--- /dev/null
+++ b/drivers/net/usb/usbnet_quirks.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Operations on the network namespace
+ */
+
+#ifndef __USB_NET_IGNORE_H__
+#define __USB_NET_IGNORE_H__
+
+#include <linux/usb.h>
+
+/* usbnet_ignore_list:
+ * Chip info which already support int vendor specific driver,
+ * and then should be ignored in generic usbnet
+ */
+static const struct usb_device_id usbnet_ignore_list[] = {
+	/* Chips already support in ax88179_178a.c */
+	{ USB_DEVICE(0x0b95, 0x1790) },
+	{ USB_DEVICE(0x0b95, 0x178a) },
+	{ USB_DEVICE(0x04b4, 0x3610) },
+	{ USB_DEVICE(0x2001, 0x4a00) },
+	{ USB_DEVICE(0x0df6, 0x0072) },
+	{ USB_DEVICE(0x04e8, 0xa100) },
+	{ USB_DEVICE(0x17ef, 0x304b) },
+	{ USB_DEVICE(0x050d, 0x0128) },
+	{ USB_DEVICE(0x0930, 0x0a13) },
+	{ USB_DEVICE(0x0711, 0x0179) },
+	{ USB_DEVICE(0x07c9, 0x000e) },
+	{ USB_DEVICE(0x07c9, 0x000f) },
+	{ USB_DEVICE(0x07c9, 0x0010) },
+	/* End of support in ax88179_178a.c */
+
+	{ } /*END*/
+};
+
+static inline bool usbnet_ignore(struct usb_interface *intf)
+{
+	const struct usb_device_id *match = usb_match_id(intf,
+							 usbnet_ignore_list);
+
+	return match == NULL ? false : true;
+}
+#endif
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index a2d54122823d..de198fcaf76d 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -188,6 +188,8 @@ struct driver_info {
  * much everything except custom framing and chip-specific stuff.
  */
 extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
+extern int usbnet_probe_quirks(struct usb_interface *udev,
+			       const struct usb_device_id *prod);
 extern int usbnet_suspend(struct usb_interface *, pm_message_t);
 extern int usbnet_resume(struct usb_interface *);
 extern void usbnet_disconnect(struct usb_interface *);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 2/2] net: usb: support quirks in usbnet
  2025-09-28  1:46 ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy
@ 2025-09-29  4:23   ` Jakub Kicinski
  2025-09-29  5:31     ` [PATCH v2 0/3] ax88179 driver optimization yicongsrfy
  2025-09-29  8:45   ` [PATCH 2/2] net: usb: support quirks in usbnet Oliver Neukum
  1 sibling, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2025-09-29  4:23 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oliver, andrew+netdev, davem, edumazet, marcan, pabeni, linux-usb,
	netdev, yicong

On Sun, 28 Sep 2025 09:46:31 +0800 yicongsrfy@163.com wrote:
> +	const struct usb_device_id *match = usb_match_id(intf,
> +							 usbnet_ignore_list);
> +
> +	return match == NULL ? false : true;

coccicheck says:

drivers/net/usb/usbnet_quirks.h:40:24-29: WARNING: conversion to bool not needed here

this function could be simply:

{
	return !usb_match_id(intf, usbnet_ignore_list);
}

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v2 0/3] ax88179 driver optimization
  2025-09-29  4:23   ` Jakub Kicinski
@ 2025-09-29  5:31     ` yicongsrfy
  2025-09-29  5:31       ` [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
                         ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  5:31 UTC (permalink / raw)
  To: oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

This series of patches first reverts the previous changes to allow
the vendor-specific driver to be loaded, then fixes the issues
related to the vendor driver.

Yi Cong (3):
  Revert "net: usb: ax88179_178a: Bind only to vendor-specific
    interface"
  net: usb: support quirks in usbnet
  net: usb: ax88179_178a: add USB device driver for config selection

 drivers/net/usb/ax88179_178a.c  | 98 +++++++++++++++++++++++++++------
 drivers/net/usb/cdc_ncm.c       |  2 +-
 drivers/net/usb/usbnet.c        | 14 +++++
 drivers/net/usb/usbnet_quirks.h | 39 +++++++++++++
 include/linux/usb/usbnet.h      |  2 +
 5 files changed, 138 insertions(+), 17 deletions(-)
 create mode 100644 drivers/net/usb/usbnet_quirks.h

Changes since v1:
- Patch 1: Revert "net: usb: ax88179_178a: Bind only to
 vendor-specific interface"(No changes)
- Patch 2: net: usb: support quirks in usbnet (Correct the description of
 usbnet_quirks.h and modify the code style)
- Patch 3: net: usb: ax88179_178a: add USB device driver for
 config selection (New patch)

--
2.25.1


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-29  5:31     ` [PATCH v2 0/3] ax88179 driver optimization yicongsrfy
@ 2025-09-29  5:31       ` yicongsrfy
  2025-09-29  7:02         ` Michal Pecio
  2025-09-29  5:31       ` [PATCH v2 2/3] net: usb: support quirks in usbnet yicongsrfy
  2025-09-29  5:31       ` [PATCH v2 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
  2 siblings, 1 reply; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  5:31 UTC (permalink / raw)
  To: oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.

Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
driver. However, this driver lacks functionality and performs worse than
the vendor's proprietary driver. In my testing, I have identified the
following issues:

1. The cdc_ncm driver does not support changing the link speed via
   ethtool because the corresponding callback function is set to NULL.
2. The CDC protocol does not support retrieving the network duplex status.
3. In TCP_RR and UDP_RR tests, the performance of the cdc_ncm driver
   is significantly lower than that of the vendor's driver:
Average of three netperf runs: `netperf -t {TCP/UDP_RR} -H serverIP -l 120`
- cdc_ncm.ko: TCP_RR: 740, UDP_RR: 750
- ax88179_178a.ko: TCP_RR: 8900, UDP_RR: 9200

Issues related to the vendor's driver ax88179_178a.ko will be addressed
in the next patch.

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index b034ef8a73ea..29cbe9ddd610 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1885,55 +1885,55 @@ static const struct driver_info at_umc2000sp_info = {
 static const struct usb_device_id products[] = {
 {
 	/* ASIX AX88179 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x1790),
 	.driver_info = (unsigned long)&ax88179_info,
 }, {
 	/* ASIX AX88178A 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x178a, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x178a),
 	.driver_info = (unsigned long)&ax88178a_info,
 }, {
 	/* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04b4, 0x3610, 0xff, 0xff, 0),
+	USB_DEVICE(0x04b4, 0x3610),
 	.driver_info = (unsigned long)&cypress_GX3_info,
 }, {
 	/* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x4a00, 0xff, 0xff, 0),
+	USB_DEVICE(0x2001, 0x4a00),
 	.driver_info = (unsigned long)&dlink_dub1312_info,
 }, {
 	/* Sitecom USB 3.0 to Gigabit Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0072, 0xff, 0xff, 0),
+	USB_DEVICE(0x0df6, 0x0072),
 	.driver_info = (unsigned long)&sitecom_info,
 }, {
 	/* Samsung USB Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04e8, 0xa100, 0xff, 0xff, 0),
+	USB_DEVICE(0x04e8, 0xa100),
 	.driver_info = (unsigned long)&samsung_info,
 }, {
 	/* Lenovo OneLinkDock Gigabit LAN */
-	USB_DEVICE_AND_INTERFACE_INFO(0x17ef, 0x304b, 0xff, 0xff, 0),
+	USB_DEVICE(0x17ef, 0x304b),
 	.driver_info = (unsigned long)&lenovo_info,
 }, {
 	/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x0128, 0xff, 0xff, 0),
+	USB_DEVICE(0x050d, 0x0128),
 	.driver_info = (unsigned long)&belkin_info,
 }, {
 	/* Toshiba USB 3.0 GBit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x0a13, 0xff, 0xff, 0),
+	USB_DEVICE(0x0930, 0x0a13),
 	.driver_info = (unsigned long)&toshiba_info,
 }, {
 	/* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0711, 0x0179, 0xff, 0xff, 0),
+	USB_DEVICE(0x0711, 0x0179),
 	.driver_info = (unsigned long)&mct_info,
 }, {
 	/* Allied Telesis AT-UMC2000 USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000e, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000e),
 	.driver_info = (unsigned long)&at_umc2000_info,
 }, {
 	/* Allied Telesis AT-UMC200 USB 3.0/USB 3.1 Gen 1 to Fast Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000f, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000f),
 	.driver_info = (unsigned long)&at_umc200_info,
 }, {
 	/* Allied Telesis AT-UMC2000/SP USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x0010, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x0010),
 	.driver_info = (unsigned long)&at_umc2000sp_info,
 },
 	{ },
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 2/3] net: usb: support quirks in usbnet
  2025-09-29  5:31     ` [PATCH v2 0/3] ax88179 driver optimization yicongsrfy
  2025-09-29  5:31       ` [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
@ 2025-09-29  5:31       ` yicongsrfy
  2025-09-29  7:11         ` Michal Pecio
  2025-09-29  5:31       ` [PATCH v2 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
  2 siblings, 1 reply; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  5:31 UTC (permalink / raw)
  To: oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

Some vendors' USB network interface controllers (NICs) may be compatible
with multiple drivers.

I consulted with relevant vendors. Taking the AX88179 chip as an example,
NICs based on this chip may be used across various OS—for instance,
cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
on Linux (despite a previous patch having disabled it).
Therefore, the firmware must support multiple protocols.

Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
Supporting both drivers simultaneously leads to the following issues:

1. Inconsistent driver loading order during reboot stress testing:
   The order in which drivers are loaded can vary across reboots,
   potentially resulting in the unintended driver being loaded. For
   example:
[    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
[    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
[    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
[    4.240627] usbcore: registered new interface driver cdc_ncm
[    4.240908] usbcore: registered new interface driver ax88179_178a

In this case, network connectivity functions, but the cdc_ncm driver is
loaded instead of the expected ax88179_178a.

2. Similar issues during cable plug/unplug testing:
   The same race condition can occur when reconnecting the USB device:
[   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
[   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
1790, bcdDevice= 2.00
[   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[   79.905191] usb 4-1: Product: AX88179B
[   79.905198] usb 4-1: Manufacturer: ASIX
[   79.905201] usb 4-1: SerialNumber: 00EF998E
[   79.915215] ax88179_probe, bConfigurationValue:2
[   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
[   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
[   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
[   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
00.2-1, CDC NCM (NO ZLP)

At this point, the network becomes unusable.

To resolve these issues, introduce a *quirks* mechanism into the usbnet
module. By adding chip-specific identification within the generic usbnet
framework, we can skip the usbnet probe process for devices that require a
dedicated driver.

v2: Correct the description of usbnet_quirks.h and modify the code style

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/cdc_ncm.c       |  2 +-
 drivers/net/usb/usbnet.c        | 14 ++++++++++++
 drivers/net/usb/usbnet_quirks.h | 39 +++++++++++++++++++++++++++++++++
 include/linux/usb/usbnet.h      |  2 ++
 4 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/usb/usbnet_quirks.h

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 5d123df0a866..6fa03e5bd054 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -2117,7 +2117,7 @@ MODULE_DEVICE_TABLE(usb, cdc_devs);
 static struct usb_driver cdc_ncm_driver = {
 	.name = "cdc_ncm",
 	.id_table = cdc_devs,
-	.probe = usbnet_probe,
+	.probe = usbnet_probe_quirks,
 	.disconnect = usbnet_disconnect,
 	.suspend = usbnet_suspend,
 	.resume = usbnet_resume,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 511c4154cf74..51ba466057f9 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -31,6 +31,7 @@
 #include <linux/kernel.h>
 #include <linux/pm_runtime.h>
 
+#include "usbnet_quirks.h"
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1697,6 +1698,19 @@ static const struct device_type wwan_type = {
 	.name	= "wwan",
 };
 
+int usbnet_probe_quirks(struct usb_interface *udev,
+			const struct usb_device_id *prod)
+{
+	/* Should it be ignored? */
+	if (unlikely(usbnet_ignore(udev))) {
+		dev_dbg(&udev->dev, "usbnet ignore this device!\n");
+		return -ENODEV;
+	}
+
+	return usbnet_probe(udev, prod);
+}
+EXPORT_SYMBOL_GPL(usbnet_probe_quirks);
+
 int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
diff --git a/drivers/net/usb/usbnet_quirks.h b/drivers/net/usb/usbnet_quirks.h
new file mode 100644
index 000000000000..5b0e52f6bf93
--- /dev/null
+++ b/drivers/net/usb/usbnet_quirks.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A collection of chip information to be ignored
+ */
+
+#ifndef __USB_NET_IGNORE_H__
+#define __USB_NET_IGNORE_H__
+
+#include <linux/usb.h>
+
+/* usbnet_ignore_list:
+ * Chip info which already support int vendor specific driver,
+ * and then should be ignored in generic usbnet
+ */
+static const struct usb_device_id usbnet_ignore_list[] = {
+	/* Chips already support in ax88179_178a.c */
+	{ USB_DEVICE(0x0b95, 0x1790) },
+	{ USB_DEVICE(0x0b95, 0x178a) },
+	{ USB_DEVICE(0x04b4, 0x3610) },
+	{ USB_DEVICE(0x2001, 0x4a00) },
+	{ USB_DEVICE(0x0df6, 0x0072) },
+	{ USB_DEVICE(0x04e8, 0xa100) },
+	{ USB_DEVICE(0x17ef, 0x304b) },
+	{ USB_DEVICE(0x050d, 0x0128) },
+	{ USB_DEVICE(0x0930, 0x0a13) },
+	{ USB_DEVICE(0x0711, 0x0179) },
+	{ USB_DEVICE(0x07c9, 0x000e) },
+	{ USB_DEVICE(0x07c9, 0x000f) },
+	{ USB_DEVICE(0x07c9, 0x0010) },
+	/* End of support in ax88179_178a.c */
+
+	{ } /*END*/
+};
+
+static inline bool usbnet_ignore(struct usb_interface *intf)
+{
+	return !!usb_match_id(intf, usbnet_ignore_list);
+}
+#endif
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index a2d54122823d..de198fcaf76d 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -188,6 +188,8 @@ struct driver_info {
  * much everything except custom framing and chip-specific stuff.
  */
 extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
+extern int usbnet_probe_quirks(struct usb_interface *udev,
+			       const struct usb_device_id *prod);
 extern int usbnet_suspend(struct usb_interface *, pm_message_t);
 extern int usbnet_resume(struct usb_interface *);
 extern void usbnet_disconnect(struct usb_interface *);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-29  5:31     ` [PATCH v2 0/3] ax88179 driver optimization yicongsrfy
  2025-09-29  5:31       ` [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  2025-09-29  5:31       ` [PATCH v2 2/3] net: usb: support quirks in usbnet yicongsrfy
@ 2025-09-29  5:31       ` yicongsrfy
  2025-09-29  5:42         ` yicongsrfy
  2 siblings, 1 reply; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  5:31 UTC (permalink / raw)
  To: oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

A similar reason was raised in ec51fbd1b8a2
(r8152: add USB device driver for config selection):
Linux prioritizes probing non-vendor-specific configurations.

Referring to the implementation of this patch, cfgselect is also
used for ax88179 to override the default configuration selection.

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 72 ++++++++++++++++++++++++++++++++--
 1 file changed, 69 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 29cbe9ddd610..965d2a66695d 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -14,6 +14,7 @@
 #include <uapi/linux/mdio.h>
 #include <linux/mdio.h>
 
+#define MODULENAME "ax88179_178a"
 #define AX88179_PHY_ID				0x03
 #define AX_EEPROM_LEN				0x100
 #define AX88179_EEPROM_MAGIC			0x17900b95
@@ -1713,6 +1714,16 @@ static int ax88179_stop(struct usbnet *dev)
 	return 0;
 }
 
+static int ax88179_probe(struct usb_interface *intf, const struct usb_device_id *i)
+{
+	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) {
+		printk("[YCDBG][%s:%d] bInterfaceClass:%d\n", __func__, __LINE__, intf->cur_altsetting->desc.bInterfaceClass);
+		return -ENODEV;
+	}
+
+	return usbnet_probe(intf, i);
+}
+
 static const struct driver_info ax88179_info = {
 	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
 	.bind = ax88179_bind,
@@ -1941,9 +1952,9 @@ static const struct usb_device_id products[] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver ax88179_178a_driver = {
-	.name =		"ax88179_178a",
+	.name =		MODULENAME,
 	.id_table =	products,
-	.probe =	usbnet_probe,
+	.probe =	ax88179_probe,
 	.suspend =	ax88179_suspend,
 	.resume =	ax88179_resume,
 	.reset_resume =	ax88179_resume,
@@ -1952,7 +1963,62 @@ static struct usb_driver ax88179_178a_driver = {
 	.disable_hub_initiated_lpm = 1,
 };
 
-module_usb_driver(ax88179_178a_driver);
+static int ax88179_cfgselector_probe(struct usb_device *udev)
+{
+	struct usb_host_config *c;
+	int i, num_configs;
+
+	/* The vendor mode is not always config #1, so to find it out. */
+	c = udev->config;
+	num_configs = udev->descriptor.bNumConfigurations;
+	for (i = 0; i < num_configs; (i++, c++)) {
+		struct usb_interface_descriptor	*desc = NULL;
+
+		if (!c->desc.bNumInterfaces)
+			continue;
+		desc = &c->intf_cache[0]->altsetting->desc;
+		if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+			break;
+	}
+
+	if (i == num_configs)
+		return -ENODEV;
+
+	if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
+		dev_err(&udev->dev, "Failed to set configuration %d\n",
+			c->desc.bConfigurationValue);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct usb_device_driver ax88179_cfgselector_driver = {
+	.name =		MODULENAME "-cfgselector",
+	.probe =	ax88179_cfgselector_probe,
+	.id_table =	products,
+	.generic_subclass = 1,
+	.supports_autosuspend = 1,
+};
+
+static int __init ax88179_driver_init(void)
+{
+	int ret;
+
+	ret = usb_register_device_driver(&ax88179_cfgselector_driver, THIS_MODULE);
+	if (ret)
+		return ret;
+	return usb_register(&ax88179_178a_driver);
+}
+
+static void __exit ax88179_driver_exit(void)
+{
+	usb_deregister(&ax88179_178a_driver);
+	usb_deregister_device_driver(&ax88179_cfgselector_driver);
+}
+
+module_init(ax88179_driver_init);
+module_exit(ax88179_driver_exit);
 
 MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
 MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-29  5:31       ` [PATCH v2 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
@ 2025-09-29  5:42         ` yicongsrfy
  2025-09-29  7:53           ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  0 siblings, 1 reply; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  5:42 UTC (permalink / raw)
  To: oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

A similar reason was raised in commit ec51fbd1b8a2 ("r8152: add USB
device driver for config selection"):
Linux prioritizes probing non-vendor-specific configurations.

Referring to the implementation of this patch, cfgselect is also
used for ax88179 to override the default configuration selection.

v2: fix warning from checkpatch

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 70 ++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 29cbe9ddd610..f2e86b9256dc 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -14,6 +14,7 @@
 #include <uapi/linux/mdio.h>
 #include <linux/mdio.h>
 
+#define MODULENAME "ax88179_178a"
 #define AX88179_PHY_ID				0x03
 #define AX_EEPROM_LEN				0x100
 #define AX88179_EEPROM_MAGIC			0x17900b95
@@ -1713,6 +1714,14 @@ static int ax88179_stop(struct usbnet *dev)
 	return 0;
 }
 
+static int ax88179_probe(struct usb_interface *intf, const struct usb_device_id *i)
+{
+	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+		return -ENODEV;
+
+	return usbnet_probe(intf, i);
+}
+
 static const struct driver_info ax88179_info = {
 	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
 	.bind = ax88179_bind,
@@ -1941,9 +1950,9 @@ static const struct usb_device_id products[] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver ax88179_178a_driver = {
-	.name =		"ax88179_178a",
+	.name =		MODULENAME,
 	.id_table =	products,
-	.probe =	usbnet_probe,
+	.probe =	ax88179_probe,
 	.suspend =	ax88179_suspend,
 	.resume =	ax88179_resume,
 	.reset_resume =	ax88179_resume,
@@ -1952,7 +1961,62 @@ static struct usb_driver ax88179_178a_driver = {
 	.disable_hub_initiated_lpm = 1,
 };
 
-module_usb_driver(ax88179_178a_driver);
+static int ax88179_cfgselector_probe(struct usb_device *udev)
+{
+	struct usb_host_config *c;
+	int i, num_configs;
+
+	/* The vendor mode is not always config #1, so to find it out. */
+	c = udev->config;
+	num_configs = udev->descriptor.bNumConfigurations;
+	for (i = 0; i < num_configs; (i++, c++)) {
+		struct usb_interface_descriptor	*desc = NULL;
+
+		if (!c->desc.bNumInterfaces)
+			continue;
+		desc = &c->intf_cache[0]->altsetting->desc;
+		if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+			break;
+	}
+
+	if (i == num_configs)
+		return -ENODEV;
+
+	if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
+		dev_err(&udev->dev, "Failed to set configuration %d\n",
+			c->desc.bConfigurationValue);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct usb_device_driver ax88179_cfgselector_driver = {
+	.name =		MODULENAME "-cfgselector",
+	.probe =	ax88179_cfgselector_probe,
+	.id_table =	products,
+	.generic_subclass = 1,
+	.supports_autosuspend = 1,
+};
+
+static int __init ax88179_driver_init(void)
+{
+	int ret;
+
+	ret = usb_register_device_driver(&ax88179_cfgselector_driver, THIS_MODULE);
+	if (ret)
+		return ret;
+	return usb_register(&ax88179_178a_driver);
+}
+
+static void __exit ax88179_driver_exit(void)
+{
+	usb_deregister(&ax88179_178a_driver);
+	usb_deregister_device_driver(&ax88179_cfgselector_driver);
+}
+
+module_init(ax88179_driver_init);
+module_exit(ax88179_driver_exit);
 
 MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
 MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-29  5:31       ` [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
@ 2025-09-29  7:02         ` Michal Pecio
  2025-09-29  7:25           ` yicongsrfy
  0 siblings, 1 reply; 35+ messages in thread
From: Michal Pecio @ 2025-09-29  7:02 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, marcan, pabeni,
	linux-usb, netdev, yicong

On Mon, 29 Sep 2025 13:31:43 +0800, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.
> 
> Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
> driver.

Only those with a CDC configuration. Mine doesn't have any.

> However, this driver lacks functionality and performs worse than
> the vendor's proprietary driver.

Is this reason to revert a commit which prevents the vendor driver
binding to CDC or other unwanted interfaces?

The original commit assumed that the vendor driver will never need
to bind to them. What has changed?

Isn't it a regression?

Regards,
Michal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/3] net: usb: support quirks in usbnet
  2025-09-29  5:31       ` [PATCH v2 2/3] net: usb: support quirks in usbnet yicongsrfy
@ 2025-09-29  7:11         ` Michal Pecio
  2025-09-29  7:29           ` yicongsrfy
  0 siblings, 1 reply; 35+ messages in thread
From: Michal Pecio @ 2025-09-29  7:11 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, marcan, pabeni,
	linux-usb, netdev, yicong

On Mon, 29 Sep 2025 13:31:44 +0800, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> Some vendors' USB network interface controllers (NICs) may be compatible
> with multiple drivers.
> 
> I consulted with relevant vendors. Taking the AX88179 chip as an example,
> NICs based on this chip may be used across various OS—for instance,
> cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
> on Linux (despite a previous patch having disabled it).
> Therefore, the firmware must support multiple protocols.
> 
> Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
> Supporting both drivers simultaneously leads to the following issues:
> 
> 1. Inconsistent driver loading order during reboot stress testing:
>    The order in which drivers are loaded can vary across reboots,
>    potentially resulting in the unintended driver being loaded. For
>    example:
> [    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
> [    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
> [    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
> [    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
> xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
> [    4.240627] usbcore: registered new interface driver cdc_ncm
> [    4.240908] usbcore: registered new interface driver ax88179_178a
> 
> In this case, network connectivity functions, but the cdc_ncm driver is
> loaded instead of the expected ax88179_178a.
> 
> 2. Similar issues during cable plug/unplug testing:
>    The same race condition can occur when reconnecting the USB device:
> [   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
> [   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
> 1790, bcdDevice= 2.00
> [   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
> SerialNumber=3
> [   79.905191] usb 4-1: Product: AX88179B
> [   79.905198] usb 4-1: Manufacturer: ASIX
> [   79.905201] usb 4-1: SerialNumber: 00EF998E
> [   79.915215] ax88179_probe, bConfigurationValue:2
> [   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
> [   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
> [   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
> [   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
> 00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
> [   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
> 00.2-1, CDC NCM (NO ZLP)
> 
> At this point, the network becomes unusable.
> 
> To resolve these issues, introduce a *quirks* mechanism into the usbnet
> module. By adding chip-specific identification within the generic usbnet
> framework, we can skip the usbnet probe process for devices that require a
> dedicated driver.

And if the vendor driver is not available then the device won't work at
all, for a completely artificial reason. We have had such problems.

At the very least, this should check if CONFIG_AX88179 is enabled.

Regards,
Michal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-29  7:02         ` Michal Pecio
@ 2025-09-29  7:25           ` yicongsrfy
  0 siblings, 0 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  7:25 UTC (permalink / raw)
  To: michal.pecio, oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

On Mon, 29 Sep 2025 09:02:29 +0200, Michal Pecio <michal.pecio@gmail.com> wrote:
>
> On Mon, 29 Sep 2025 13:31:43 +0800, yicongsrfy@163.com wrote:
> > From: Yi Cong <yicong@kylinos.cn>

> > However, this driver lacks functionality and performs worse than
> > the vendor's proprietary driver.
>
> Is this reason to revert a commit which prevents the vendor driver
> binding to CDC or other unwanted interfaces?
>
> The original commit assumed that the vendor driver will never need
> to bind to them. What has changed?
>
> Isn't it a regression?

This series of patches aims to resolve the compatibility issues of devices
that have both CDC configurations and vendor-specific configurations.

In my understanding, avoiding the use of the vendor driver when it could
be used is merely a workaround; a better approach is to directly address
and solve the underlying problem.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/3] net: usb: support quirks in usbnet
  2025-09-29  7:11         ` Michal Pecio
@ 2025-09-29  7:29           ` yicongsrfy
  0 siblings, 0 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  7:29 UTC (permalink / raw)
  To: michal.pecio, oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

On Mon, 29 Sep 2025 09:11:53 +0200, Michal Pecio <michal.pecio@gmail.com> wrote:
>
> On Mon, 29 Sep 2025 13:31:44 +0800, yicongsrfy@163.com wrote:
> > From: Yi Cong <yicong@kylinos.cn>
> >
> > To resolve these issues, introduce a *quirks* mechanism into the usbnet
> > module. By adding chip-specific identification within the generic usbnet
> > framework, we can skip the usbnet probe process for devices that require a
> > dedicated driver.
>
> And if the vendor driver is not available then the device won't work at
> all, for a completely artificial reason. We have had such problems.
>
> At the very least, this should check if CONFIG_AX88179 is enabled.

Thank you for your suggestion!
I will add the CONFIG_AX88179 configuration check in
the next version of the patch.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-29  5:42         ` yicongsrfy
@ 2025-09-29  7:53           ` yicongsrfy
  2025-09-29  7:54             ` [PATCH v3 2/3] net: usb: support quirks in usbnet yicongsrfy
                               ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  7:53 UTC (permalink / raw)
  To: michal.pecio, oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.

Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
driver. However, this driver lacks functionality and performs worse than
the vendor's proprietary driver. In my testing, I have identified the
following issues:

1. The cdc_ncm driver does not support changing the link speed via
   ethtool because the corresponding callback function is set to NULL.
2. The CDC protocol does not support retrieving the network duplex status.
3. In TCP_RR and UDP_RR tests, the performance of the cdc_ncm driver
   is significantly lower than that of the vendor's driver:
Average of three netperf runs: `netperf -t {TCP/UDP_RR} -H serverIP -l 120`
- cdc_ncm.ko: TCP_RR: 740, UDP_RR: 750
- ax88179_178a.ko: TCP_RR: 8900, UDP_RR: 9200

Issues related to the vendor's driver ax88179_178a.ko will be addressed
in the next patch.

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index b034ef8a73ea..29cbe9ddd610 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1885,55 +1885,55 @@ static const struct driver_info at_umc2000sp_info = {
 static const struct usb_device_id products[] = {
 {
 	/* ASIX AX88179 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x1790),
 	.driver_info = (unsigned long)&ax88179_info,
 }, {
 	/* ASIX AX88178A 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x178a, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x178a),
 	.driver_info = (unsigned long)&ax88178a_info,
 }, {
 	/* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04b4, 0x3610, 0xff, 0xff, 0),
+	USB_DEVICE(0x04b4, 0x3610),
 	.driver_info = (unsigned long)&cypress_GX3_info,
 }, {
 	/* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x4a00, 0xff, 0xff, 0),
+	USB_DEVICE(0x2001, 0x4a00),
 	.driver_info = (unsigned long)&dlink_dub1312_info,
 }, {
 	/* Sitecom USB 3.0 to Gigabit Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0072, 0xff, 0xff, 0),
+	USB_DEVICE(0x0df6, 0x0072),
 	.driver_info = (unsigned long)&sitecom_info,
 }, {
 	/* Samsung USB Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04e8, 0xa100, 0xff, 0xff, 0),
+	USB_DEVICE(0x04e8, 0xa100),
 	.driver_info = (unsigned long)&samsung_info,
 }, {
 	/* Lenovo OneLinkDock Gigabit LAN */
-	USB_DEVICE_AND_INTERFACE_INFO(0x17ef, 0x304b, 0xff, 0xff, 0),
+	USB_DEVICE(0x17ef, 0x304b),
 	.driver_info = (unsigned long)&lenovo_info,
 }, {
 	/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x0128, 0xff, 0xff, 0),
+	USB_DEVICE(0x050d, 0x0128),
 	.driver_info = (unsigned long)&belkin_info,
 }, {
 	/* Toshiba USB 3.0 GBit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x0a13, 0xff, 0xff, 0),
+	USB_DEVICE(0x0930, 0x0a13),
 	.driver_info = (unsigned long)&toshiba_info,
 }, {
 	/* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0711, 0x0179, 0xff, 0xff, 0),
+	USB_DEVICE(0x0711, 0x0179),
 	.driver_info = (unsigned long)&mct_info,
 }, {
 	/* Allied Telesis AT-UMC2000 USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000e, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000e),
 	.driver_info = (unsigned long)&at_umc2000_info,
 }, {
 	/* Allied Telesis AT-UMC200 USB 3.0/USB 3.1 Gen 1 to Fast Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000f, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000f),
 	.driver_info = (unsigned long)&at_umc200_info,
 }, {
 	/* Allied Telesis AT-UMC2000/SP USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x0010, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x0010),
 	.driver_info = (unsigned long)&at_umc2000sp_info,
 },
 	{ },
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 2/3] net: usb: support quirks in usbnet
  2025-09-29  7:53           ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
@ 2025-09-29  7:54             ` yicongsrfy
  2025-09-29  7:54             ` [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
  2025-09-29 11:15             ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" Oliver Neukum
  2 siblings, 0 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  7:54 UTC (permalink / raw)
  To: michal.pecio, oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

Some vendors' USB network interface controllers (NICs) may be compatible
with multiple drivers.

I consulted with relevant vendors. Taking the AX88179 chip as an example,
NICs based on this chip may be used across various OS—for instance,
cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
on Linux (despite a previous patch having disabled it).
Therefore, the firmware must support multiple protocols.

Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
Supporting both drivers simultaneously leads to the following issues:

1. Inconsistent driver loading order during reboot stress testing:
   The order in which drivers are loaded can vary across reboots,
   potentially resulting in the unintended driver being loaded. For
   example:
[    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
[    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
[    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
[    4.240627] usbcore: registered new interface driver cdc_ncm
[    4.240908] usbcore: registered new interface driver ax88179_178a

In this case, network connectivity functions, but the cdc_ncm driver is
loaded instead of the expected ax88179_178a.

2. Similar issues during cable plug/unplug testing:
   The same race condition can occur when reconnecting the USB device:
[   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
[   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
1790, bcdDevice= 2.00
[   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[   79.905191] usb 4-1: Product: AX88179B
[   79.905198] usb 4-1: Manufacturer: ASIX
[   79.905201] usb 4-1: SerialNumber: 00EF998E
[   79.915215] ax88179_probe, bConfigurationValue:2
[   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
[   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
[   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
[   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
00.2-1, CDC NCM (NO ZLP)

At this point, the network becomes unusable.

To resolve these issues, introduce a *quirks* mechanism into the usbnet
module. By adding chip-specific identification within the generic usbnet
framework, we can skip the usbnet probe process for devices that require a
dedicated driver.

v2: Correct the description of usbnet_quirks.h and modify the code style
v3: Add checking whether the CONFIG_USB_NET_AX88179_178A is enabled

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/cdc_ncm.c       |  2 +-
 drivers/net/usb/usbnet.c        | 14 +++++++++++
 drivers/net/usb/usbnet_quirks.h | 41 +++++++++++++++++++++++++++++++++
 include/linux/usb/usbnet.h      |  2 ++
 4 files changed, 58 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/usb/usbnet_quirks.h

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 5d123df0a866..6fa03e5bd054 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -2117,7 +2117,7 @@ MODULE_DEVICE_TABLE(usb, cdc_devs);
 static struct usb_driver cdc_ncm_driver = {
 	.name = "cdc_ncm",
 	.id_table = cdc_devs,
-	.probe = usbnet_probe,
+	.probe = usbnet_probe_quirks,
 	.disconnect = usbnet_disconnect,
 	.suspend = usbnet_suspend,
 	.resume = usbnet_resume,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 511c4154cf74..51ba466057f9 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -31,6 +31,7 @@
 #include <linux/kernel.h>
 #include <linux/pm_runtime.h>
 
+#include "usbnet_quirks.h"
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1697,6 +1698,19 @@ static const struct device_type wwan_type = {
 	.name	= "wwan",
 };
 
+int usbnet_probe_quirks(struct usb_interface *udev,
+			const struct usb_device_id *prod)
+{
+	/* Should it be ignored? */
+	if (unlikely(usbnet_ignore(udev))) {
+		dev_dbg(&udev->dev, "usbnet ignore this device!\n");
+		return -ENODEV;
+	}
+
+	return usbnet_probe(udev, prod);
+}
+EXPORT_SYMBOL_GPL(usbnet_probe_quirks);
+
 int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
diff --git a/drivers/net/usb/usbnet_quirks.h b/drivers/net/usb/usbnet_quirks.h
new file mode 100644
index 000000000000..859004046a86
--- /dev/null
+++ b/drivers/net/usb/usbnet_quirks.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A collection of chip information to be ignored
+ */
+
+#ifndef __USB_NET_IGNORE_H__
+#define __USB_NET_IGNORE_H__
+
+#include <linux/usb.h>
+
+/* usbnet_ignore_list:
+ * Chip info which already support int vendor specific driver,
+ * and then should be ignored in generic usbnet
+ */
+static const struct usb_device_id usbnet_ignore_list[] = {
+#if IS_ENABLED(CONFIG_USB_NET_AX88179_178A)
+	/* Chips already support in ax88179_178a.c */
+	{ USB_DEVICE(0x0b95, 0x1790) },
+	{ USB_DEVICE(0x0b95, 0x178a) },
+	{ USB_DEVICE(0x04b4, 0x3610) },
+	{ USB_DEVICE(0x2001, 0x4a00) },
+	{ USB_DEVICE(0x0df6, 0x0072) },
+	{ USB_DEVICE(0x04e8, 0xa100) },
+	{ USB_DEVICE(0x17ef, 0x304b) },
+	{ USB_DEVICE(0x050d, 0x0128) },
+	{ USB_DEVICE(0x0930, 0x0a13) },
+	{ USB_DEVICE(0x0711, 0x0179) },
+	{ USB_DEVICE(0x07c9, 0x000e) },
+	{ USB_DEVICE(0x07c9, 0x000f) },
+	{ USB_DEVICE(0x07c9, 0x0010) },
+	/* End of support in ax88179_178a.c */
+#endif
+
+	{ } /*END*/
+};
+
+static inline bool usbnet_ignore(struct usb_interface *intf)
+{
+	return !!usb_match_id(intf, usbnet_ignore_list);
+}
+#endif
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index a2d54122823d..de198fcaf76d 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -188,6 +188,8 @@ struct driver_info {
  * much everything except custom framing and chip-specific stuff.
  */
 extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
+extern int usbnet_probe_quirks(struct usb_interface *udev,
+			       const struct usb_device_id *prod);
 extern int usbnet_suspend(struct usb_interface *, pm_message_t);
 extern int usbnet_resume(struct usb_interface *);
 extern void usbnet_disconnect(struct usb_interface *);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-29  7:53           ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  2025-09-29  7:54             ` [PATCH v3 2/3] net: usb: support quirks in usbnet yicongsrfy
@ 2025-09-29  7:54             ` yicongsrfy
  2025-09-29 11:20               ` Oliver Neukum
  2025-09-29 16:11               ` Jakub Kicinski
  2025-09-29 11:15             ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" Oliver Neukum
  2 siblings, 2 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  7:54 UTC (permalink / raw)
  To: michal.pecio, oneukum, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

From: Yi Cong <yicong@kylinos.cn>

A similar reason was raised in commit ec51fbd1b8a2 ("r8152: add USB
device driver for config selection"):
Linux prioritizes probing non-vendor-specific configurations.

Referring to the implementation of this patch, cfgselect is also
used for ax88179 to override the default configuration selection.

v2: fix warning from checkpatch

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 70 ++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 29cbe9ddd610..f2e86b9256dc 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -14,6 +14,7 @@
 #include <uapi/linux/mdio.h>
 #include <linux/mdio.h>
 
+#define MODULENAME "ax88179_178a"
 #define AX88179_PHY_ID				0x03
 #define AX_EEPROM_LEN				0x100
 #define AX88179_EEPROM_MAGIC			0x17900b95
@@ -1713,6 +1714,14 @@ static int ax88179_stop(struct usbnet *dev)
 	return 0;
 }
 
+static int ax88179_probe(struct usb_interface *intf, const struct usb_device_id *i)
+{
+	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+		return -ENODEV;
+
+	return usbnet_probe(intf, i);
+}
+
 static const struct driver_info ax88179_info = {
 	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
 	.bind = ax88179_bind,
@@ -1941,9 +1950,9 @@ static const struct usb_device_id products[] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver ax88179_178a_driver = {
-	.name =		"ax88179_178a",
+	.name =		MODULENAME,
 	.id_table =	products,
-	.probe =	usbnet_probe,
+	.probe =	ax88179_probe,
 	.suspend =	ax88179_suspend,
 	.resume =	ax88179_resume,
 	.reset_resume =	ax88179_resume,
@@ -1952,7 +1961,62 @@ static struct usb_driver ax88179_178a_driver = {
 	.disable_hub_initiated_lpm = 1,
 };
 
-module_usb_driver(ax88179_178a_driver);
+static int ax88179_cfgselector_probe(struct usb_device *udev)
+{
+	struct usb_host_config *c;
+	int i, num_configs;
+
+	/* The vendor mode is not always config #1, so to find it out. */
+	c = udev->config;
+	num_configs = udev->descriptor.bNumConfigurations;
+	for (i = 0; i < num_configs; (i++, c++)) {
+		struct usb_interface_descriptor	*desc = NULL;
+
+		if (!c->desc.bNumInterfaces)
+			continue;
+		desc = &c->intf_cache[0]->altsetting->desc;
+		if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+			break;
+	}
+
+	if (i == num_configs)
+		return -ENODEV;
+
+	if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
+		dev_err(&udev->dev, "Failed to set configuration %d\n",
+			c->desc.bConfigurationValue);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct usb_device_driver ax88179_cfgselector_driver = {
+	.name =		MODULENAME "-cfgselector",
+	.probe =	ax88179_cfgselector_probe,
+	.id_table =	products,
+	.generic_subclass = 1,
+	.supports_autosuspend = 1,
+};
+
+static int __init ax88179_driver_init(void)
+{
+	int ret;
+
+	ret = usb_register_device_driver(&ax88179_cfgselector_driver, THIS_MODULE);
+	if (ret)
+		return ret;
+	return usb_register(&ax88179_178a_driver);
+}
+
+static void __exit ax88179_driver_exit(void)
+{
+	usb_deregister(&ax88179_178a_driver);
+	usb_deregister_device_driver(&ax88179_cfgselector_driver);
+}
+
+module_init(ax88179_driver_init);
+module_exit(ax88179_driver_exit);
 
 MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
 MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 2/2] net: usb: support quirks in usbnet
  2025-09-28  1:46 ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy
  2025-09-29  4:23   ` Jakub Kicinski
@ 2025-09-29  8:45   ` Oliver Neukum
  2025-09-29  9:29     ` yicongsrfy
  1 sibling, 1 reply; 35+ messages in thread
From: Oliver Neukum @ 2025-09-29  8:45 UTC (permalink / raw)
  To: yicongsrfy, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

Hi,

On 28.09.25 03:46, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> Some vendors' USB network interface controllers (NICs) may be compatible
> with multiple drivers.
And here is the basic problem. This issue is not an issue specific to
usbnet. It arises everywhere we have a specific and a general
driver. Hence it ought to be solved in generic way in usbcore.

Nor can we do this with a simple list of devices, as we cannot
assume that the more specific driver is compiled in all systems.
An unconditional quirk is acceptable _only_ if usbnet would
not work.

Please get in contact with the core USB developers. The problem
needs to be solved, but this is not a solution.

	Regards
		Oliver

Nacked-by: Oliver Neukum <oneukum@suse.com>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 2/2] net: usb: support quirks in usbnet
  2025-09-29  8:45   ` [PATCH 2/2] net: usb: support quirks in usbnet Oliver Neukum
@ 2025-09-29  9:29     ` yicongsrfy
  2025-09-29 10:21       ` Oliver Neukum
  0 siblings, 1 reply; 35+ messages in thread
From: yicongsrfy @ 2025-09-29  9:29 UTC (permalink / raw)
  To: oneukum
  Cc: andrew+netdev, davem, edumazet, kuba, linux-usb, marcan, netdev,
	pabeni, yicong

On Mon, 29 Sep 2025 10:45:19 +0200, Oliver Neukum <oneukum@suse.com> wrote:

> On 28.09.25 03:46, yicongsrfy@163.com wrote:
> > From: Yi Cong <yicong@kylinos.cn>
> >
> > Some vendors' USB network interface controllers (NICs) may be compatible
> > with multiple drivers.
> And here is the basic problem. This issue is not an issue specific to
> usbnet. It arises everywhere we have a specific and a general
> driver. Hence it ought to be solved in generic way in usbcore.
>
> Nor can we do this with a simple list of devices, as we cannot
> assume that the more specific driver is compiled in all systems.
> An unconditional quirk is acceptable _only_ if usbnet would
> not work.
>
> Please get in contact with the core USB developers. The problem
> needs to be solved, but this is not a solution.

Thank you for your reply!

Should I add the AX88179 chip information into the `usb_quirk_list`
in `drivers/usb/core/quirks.c`? (Of course, it will also include a
 check for whether `CONFIG_USB_NET_AX88179_178A` is enabled.)

This way, `usbnet_probe` can detect the blacklisted information.

usbnet_probe (...)
{
	...
	info = (const struct driver_info *) prod->driver_info;
	if (!info) {
		dev_dbg (&udev->dev, "blacklisted by %s\n", name);
		return -ENODEV;
	}
	...
}

From an implementation standpoint, this approach is indeed cleaner
and simpler than my current solution.
Is the method mentioned above an appropriate approach?


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 2/2] net: usb: support quirks in usbnet
  2025-09-29  9:29     ` yicongsrfy
@ 2025-09-29 10:21       ` Oliver Neukum
  2025-09-30  8:07         ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  2025-09-30  8:14         ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy
  0 siblings, 2 replies; 35+ messages in thread
From: Oliver Neukum @ 2025-09-29 10:21 UTC (permalink / raw)
  To: yicongsrfy
  Cc: andrew+netdev, davem, edumazet, kuba, linux-usb, marcan, netdev,
	pabeni, yicong

On 29.09.25 11:29, yicongsrfy@163.com wrote:
> On Mon, 29 Sep 2025 10:45:19 +0200, Oliver Neukum <oneukum@suse.com> wrote:

>> Please get in contact with the core USB developers. The problem
>> needs to be solved, but this is not a solution.
> 
> Thank you for your reply!
> 
> Should I add the AX88179 chip information into the `usb_quirk_list`
> in `drivers/usb/core/quirks.c`? (Of course, it will also include a
>   check for whether `CONFIG_USB_NET_AX88179_178A` is enabled.)

That would need to be discussed.
Ideally the probe() method of cdc_ncm would never be called.
But there is the possibility that cdc_ncm is already loaded
and the other driver is not.
>  From an implementation standpoint, this approach is indeed cleaner
> and simpler than my current solution.
> Is the method mentioned above an appropriate approach?
Well, no. Declining devices is not usbnet's job. If the logic
needs to go into a device driver, it needs to go into cdc-ncm,
which would need to check quirks.

	Regards
		Oliver



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-29  7:53           ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  2025-09-29  7:54             ` [PATCH v3 2/3] net: usb: support quirks in usbnet yicongsrfy
  2025-09-29  7:54             ` [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
@ 2025-09-29 11:15             ` Oliver Neukum
  2 siblings, 0 replies; 35+ messages in thread
From: Oliver Neukum @ 2025-09-29 11:15 UTC (permalink / raw)
  To: yicongsrfy, michal.pecio, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

Hi,

On 29.09.25 09:53, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.
> 
> Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
> driver. However, this driver lacks functionality and performs worse than
> the vendor's proprietary driver. In my testing, I have identified the
> following issues:

True, so we prefer the vendor specific driver if it is available
for a certain number of devices. We accept that as a given. The
exact reasons for this preference do not matter.

Now , lets look at the change log of the patch you want to revert:

     Change all the ID matches to specifically match the vendor-specific
     interface. By default the device comes up in CDC mode and is bound by
     that driver (which works fine); users may switch it to the vendor
     interface using sysfs to set bConfigurationValue, at which point the
     device actually goes through a reconnect cycle and comes back as a
     vendor specific only device, and then this driver binds and works too.

This tells us that usbcore selects the wrong configuration for these
devices. Can we remedy this via udev? Not well, there would be a race
with the wrong driver triggering an unwanted network setup.
This would be better solved in usbcore with quirks.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-29  7:54             ` [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
@ 2025-09-29 11:20               ` Oliver Neukum
  2025-09-29 16:11               ` Jakub Kicinski
  1 sibling, 0 replies; 35+ messages in thread
From: Oliver Neukum @ 2025-09-29 11:20 UTC (permalink / raw)
  To: yicongsrfy, michal.pecio, andrew+netdev, davem, edumazet, kuba
  Cc: marcan, pabeni, linux-usb, netdev, yicong

Hi,

On 29.09.25 09:54, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> A similar reason was raised in commit ec51fbd1b8a2 ("r8152: add USB
> device driver for config selection"):
> Linux prioritizes probing non-vendor-specific configurations.
> 
> Referring to the implementation of this patch, cfgselect is also
> used for ax88179 to override the default configuration selection.
> 
> v2: fix warning from checkpatch
> 
> Signed-off-by: Yi Cong <yicong@kylinos.cn>
> ---
>   drivers/net/usb/ax88179_178a.c | 70 ++++++++++++++++++++++++++++++++--
>   1 file changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
> index 29cbe9ddd610..f2e86b9256dc 100644
> --- a/drivers/net/usb/ax88179_178a.c
> +++ b/drivers/net/usb/ax88179_178a.c
> @@ -14,6 +14,7 @@
>   #include <uapi/linux/mdio.h>
>   #include <linux/mdio.h>
>   
> +#define MODULENAME "ax88179_178a"
>   #define AX88179_PHY_ID				0x03
>   #define AX_EEPROM_LEN				0x100
>   #define AX88179_EEPROM_MAGIC			0x17900b95
> @@ -1713,6 +1714,14 @@ static int ax88179_stop(struct usbnet *dev)
>   	return 0;
>   }
>   
> +static int ax88179_probe(struct usb_interface *intf, const struct usb_device_id *i)
> +{
> +	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
> +		return -ENODEV;

And here you need to work around the problem the
first patch in the series creates. The solution
in this case is to drop it.

> +
> +	return usbnet_probe(intf, i);
> +}
> +
>   static const struct driver_info ax88179_info = {
>   	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
>   	.bind = ax88179_bind,
> @@ -1941,9 +1950,9 @@ static const struct usb_device_id products[] = {
>   MODULE_DEVICE_TABLE(usb, products);
>   
>   static struct usb_driver ax88179_178a_driver = {
> -	.name =		"ax88179_178a",
> +	.name =		MODULENAME,
>   	.id_table =	products,
> -	.probe =	usbnet_probe,
> +	.probe =	ax88179_probe,
>   	.suspend =	ax88179_suspend,
>   	.resume =	ax88179_resume,
>   	.reset_resume =	ax88179_resume,
> @@ -1952,7 +1961,62 @@ static struct usb_driver ax88179_178a_driver = {
>   	.disable_hub_initiated_lpm = 1,
>   };
>   
> -module_usb_driver(ax88179_178a_driver);
> +static int ax88179_cfgselector_probe(struct usb_device *udev)

And this should run only if you match the device ID and the generic
class.

That is, if you want this approach at all. If this should o into
kernel space at all, it blongs into usbcore.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-29  7:54             ` [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
  2025-09-29 11:20               ` Oliver Neukum
@ 2025-09-29 16:11               ` Jakub Kicinski
  1 sibling, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2025-09-29 16:11 UTC (permalink / raw)
  To: yicongsrfy
  Cc: michal.pecio, oneukum, andrew+netdev, davem, edumazet, marcan,
	pabeni, linux-usb, netdev, yicong

On Mon, 29 Sep 2025 15:54:01 +0800 yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>

Please slow down. Per:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html
you need to wait 24 between postings.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-29 10:21       ` Oliver Neukum
@ 2025-09-30  8:07         ` yicongsrfy
  2025-09-30  8:07           ` [PATCH v4 2/3] net: usb: support quirks in cdc_ncm yicongsrfy
                             ` (2 more replies)
  2025-09-30  8:14         ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy
  1 sibling, 3 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-30  8:07 UTC (permalink / raw)
  To: oneukum, andrew+netdev
  Cc: davem, edumazet, kuba, linux-usb, marcan, netdev, pabeni, yicong

From: Yi Cong <yicong@kylinos.cn>

This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.

Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
driver. However, this driver lacks functionality and performs worse than
the vendor's proprietary driver. In my testing, I have identified the
following issues:

1. The cdc_ncm driver does not support changing the link speed via
   ethtool because the corresponding callback function is set to NULL.
2. The CDC protocol does not support retrieving the network duplex status.
3. In TCP_RR and UDP_RR tests, the performance of the cdc_ncm driver
   is significantly lower than that of the vendor's driver:
Average of three netperf runs: `netperf -t {TCP/UDP_RR} -H serverIP -l 120`
- cdc_ncm.ko: TCP_RR: 740, UDP_RR: 750
- ax88179_178a.ko: TCP_RR: 8900, UDP_RR: 9200

Issues related to the vendor's driver ax88179_178a.ko will be addressed
in the next patch.

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index b034ef8a73ea..29cbe9ddd610 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1885,55 +1885,55 @@ static const struct driver_info at_umc2000sp_info = {
 static const struct usb_device_id products[] = {
 {
 	/* ASIX AX88179 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x1790),
 	.driver_info = (unsigned long)&ax88179_info,
 }, {
 	/* ASIX AX88178A 10/100/1000 */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x178a, 0xff, 0xff, 0),
+	USB_DEVICE(0x0b95, 0x178a),
 	.driver_info = (unsigned long)&ax88178a_info,
 }, {
 	/* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04b4, 0x3610, 0xff, 0xff, 0),
+	USB_DEVICE(0x04b4, 0x3610),
 	.driver_info = (unsigned long)&cypress_GX3_info,
 }, {
 	/* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x4a00, 0xff, 0xff, 0),
+	USB_DEVICE(0x2001, 0x4a00),
 	.driver_info = (unsigned long)&dlink_dub1312_info,
 }, {
 	/* Sitecom USB 3.0 to Gigabit Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0072, 0xff, 0xff, 0),
+	USB_DEVICE(0x0df6, 0x0072),
 	.driver_info = (unsigned long)&sitecom_info,
 }, {
 	/* Samsung USB Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x04e8, 0xa100, 0xff, 0xff, 0),
+	USB_DEVICE(0x04e8, 0xa100),
 	.driver_info = (unsigned long)&samsung_info,
 }, {
 	/* Lenovo OneLinkDock Gigabit LAN */
-	USB_DEVICE_AND_INTERFACE_INFO(0x17ef, 0x304b, 0xff, 0xff, 0),
+	USB_DEVICE(0x17ef, 0x304b),
 	.driver_info = (unsigned long)&lenovo_info,
 }, {
 	/* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x0128, 0xff, 0xff, 0),
+	USB_DEVICE(0x050d, 0x0128),
 	.driver_info = (unsigned long)&belkin_info,
 }, {
 	/* Toshiba USB 3.0 GBit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x0a13, 0xff, 0xff, 0),
+	USB_DEVICE(0x0930, 0x0a13),
 	.driver_info = (unsigned long)&toshiba_info,
 }, {
 	/* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x0711, 0x0179, 0xff, 0xff, 0),
+	USB_DEVICE(0x0711, 0x0179),
 	.driver_info = (unsigned long)&mct_info,
 }, {
 	/* Allied Telesis AT-UMC2000 USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000e, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000e),
 	.driver_info = (unsigned long)&at_umc2000_info,
 }, {
 	/* Allied Telesis AT-UMC200 USB 3.0/USB 3.1 Gen 1 to Fast Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x000f, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x000f),
 	.driver_info = (unsigned long)&at_umc200_info,
 }, {
 	/* Allied Telesis AT-UMC2000/SP USB 3.0/USB 3.1 Gen 1 to Gigabit Ethernet Adapter */
-	USB_DEVICE_AND_INTERFACE_INFO(0x07c9, 0x0010, 0xff, 0xff, 0),
+	USB_DEVICE(0x07c9, 0x0010),
 	.driver_info = (unsigned long)&at_umc2000sp_info,
 },
 	{ },
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 2/3] net: usb: support quirks in cdc_ncm
  2025-09-30  8:07         ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
@ 2025-09-30  8:07           ` yicongsrfy
  2025-09-30  8:37             ` Greg KH
  2025-09-30  8:38             ` Greg KH
  2025-09-30  8:07           ` [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
  2025-10-06 16:33           ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" Andrew Lunn
  2 siblings, 2 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-30  8:07 UTC (permalink / raw)
  To: oneukum, andrew+netdev
  Cc: davem, edumazet, kuba, linux-usb, marcan, netdev, pabeni, yicong

From: Yi Cong <yicong@kylinos.cn>

Some vendors' USB network interface controllers (NICs) may be compatible
with multiple drivers.

I consulted with relevant vendors. Taking the AX88179 chip as an example,
NICs based on this chip may be used across various OS—for instance,
cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
on Linux (despite a previous patch having disabled it).
Therefore, the firmware must support multiple protocols.

Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
Supporting both drivers simultaneously leads to the following issues:

1. Inconsistent driver loading order during reboot stress testing:
   The order in which drivers are loaded can vary across reboots,
   potentially resulting in the unintended driver being loaded. For
   example:
[    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
[    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
[    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
[    4.240627] usbcore: registered new interface driver cdc_ncm
[    4.240908] usbcore: registered new interface driver ax88179_178a

In this case, network connectivity functions, but the cdc_ncm driver is
loaded instead of the expected ax88179_178a.

2. Similar issues during cable plug/unplug testing:
   The same race condition can occur when reconnecting the USB device:
[   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
[   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
1790, bcdDevice= 2.00
[   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[   79.905191] usb 4-1: Product: AX88179B
[   79.905198] usb 4-1: Manufacturer: ASIX
[   79.905201] usb 4-1: SerialNumber: 00EF998E
[   79.915215] ax88179_probe, bConfigurationValue:2
[   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
[   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
[   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
[   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
[   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
00.2-1, CDC NCM (NO ZLP)

At this point, the network becomes unusable.

To resolve these issues, introduce a *quirks* mechanism into the usbnet
module. By adding chip-specific identification within the generic usbnet
framework, we can skip the usbnet probe process for devices that require a
dedicated driver.

v2: Correct the description of usbnet_quirks.h and modify the code style
v3: Add checking whether the CONFIG_USB_NET_AX88179_178A is enabled
v4: Move quirks from usbnet.ko to cdc_ncm.ko

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/cdc_ncm.c        | 15 +++++++++++-
 drivers/net/usb/cdc_ncm_quirks.h | 41 ++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/usb/cdc_ncm_quirks.h

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 5d123df0a866..fc8416af3f11 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -54,6 +54,8 @@
 #include <linux/usb/cdc.h>
 #include <linux/usb/cdc_ncm.h>
 
+#include "cdc_ncm_quirks.h"
+
 #if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
 static bool prefer_mbim = true;
 #else
@@ -2114,10 +2116,21 @@ static const struct usb_device_id cdc_devs[] = {
 };
 MODULE_DEVICE_TABLE(usb, cdc_devs);
 
+static int cdc_ncm_probe(struct usb_interface *intf, const struct usb_device_id *prod)
+{
+	/* Should it be ignored? */
+	if (unlikely(cdc_ncm_ignore(intf))) {
+		dev_dbg(&intf->dev, "cdc_ncm ignore this device!\n");
+		return -ENODEV;
+	}
+
+	return usbnet_probe(intf, prod);
+}
+
 static struct usb_driver cdc_ncm_driver = {
 	.name = "cdc_ncm",
 	.id_table = cdc_devs,
-	.probe = usbnet_probe,
+	.probe = cdc_ncm_probe,
 	.disconnect = usbnet_disconnect,
 	.suspend = usbnet_suspend,
 	.resume = usbnet_resume,
diff --git a/drivers/net/usb/cdc_ncm_quirks.h b/drivers/net/usb/cdc_ncm_quirks.h
new file mode 100644
index 000000000000..e5ae2265b1d7
--- /dev/null
+++ b/drivers/net/usb/cdc_ncm_quirks.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A collection of chip information to be ignored
+ */
+
+#ifndef __CDC_NCM_IGNORE_H__
+#define __CDC_NCM_IGNORE_H__
+
+#include <linux/usb.h>
+
+/* cdc_ncm_ignore_list:
+ * Chip info which already support int vendor specific driver,
+ * and then should be ignored in generic cdc_ncm
+ */
+static const struct usb_device_id cdc_ncm_ignore_list[] = {
+#if IS_ENABLED(CONFIG_USB_NET_AX88179_178A)
+	/* Chips already support in ax88179_178a.c */
+	{ USB_DEVICE(0x0b95, 0x1790) },
+	{ USB_DEVICE(0x0b95, 0x178a) },
+	{ USB_DEVICE(0x04b4, 0x3610) },
+	{ USB_DEVICE(0x2001, 0x4a00) },
+	{ USB_DEVICE(0x0df6, 0x0072) },
+	{ USB_DEVICE(0x04e8, 0xa100) },
+	{ USB_DEVICE(0x17ef, 0x304b) },
+	{ USB_DEVICE(0x050d, 0x0128) },
+	{ USB_DEVICE(0x0930, 0x0a13) },
+	{ USB_DEVICE(0x0711, 0x0179) },
+	{ USB_DEVICE(0x07c9, 0x000e) },
+	{ USB_DEVICE(0x07c9, 0x000f) },
+	{ USB_DEVICE(0x07c9, 0x0010) },
+	/* End of support in ax88179_178a.c */
+#endif
+
+	{ } /*END*/
+};
+
+static inline bool cdc_ncm_ignore(struct usb_interface *intf)
+{
+	return !!usb_match_id(intf, cdc_ncm_ignore_list);
+}
+#endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-30  8:07         ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  2025-09-30  8:07           ` [PATCH v4 2/3] net: usb: support quirks in cdc_ncm yicongsrfy
@ 2025-09-30  8:07           ` yicongsrfy
  2025-09-30  8:38             ` Greg KH
  2025-09-30  8:57             ` Oliver Neukum
  2025-10-06 16:33           ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" Andrew Lunn
  2 siblings, 2 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-30  8:07 UTC (permalink / raw)
  To: oneukum, andrew+netdev
  Cc: davem, edumazet, kuba, linux-usb, marcan, netdev, pabeni, yicong

From: Yi Cong <yicong@kylinos.cn>

A similar reason was raised in commit ec51fbd1b8a2 ("r8152: add USB
device driver for config selection"):
Linux prioritizes probing non-vendor-specific configurations.

Referring to the implementation of this patch, cfgselect is also
used for ax88179 to override the default configuration selection.

v2: fix warning from checkpatch

Signed-off-by: Yi Cong <yicong@kylinos.cn>
---
 drivers/net/usb/ax88179_178a.c | 70 ++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 29cbe9ddd610..f2e86b9256dc 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -14,6 +14,7 @@
 #include <uapi/linux/mdio.h>
 #include <linux/mdio.h>
 
+#define MODULENAME "ax88179_178a"
 #define AX88179_PHY_ID				0x03
 #define AX_EEPROM_LEN				0x100
 #define AX88179_EEPROM_MAGIC			0x17900b95
@@ -1713,6 +1714,14 @@ static int ax88179_stop(struct usbnet *dev)
 	return 0;
 }
 
+static int ax88179_probe(struct usb_interface *intf, const struct usb_device_id *i)
+{
+	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+		return -ENODEV;
+
+	return usbnet_probe(intf, i);
+}
+
 static const struct driver_info ax88179_info = {
 	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
 	.bind = ax88179_bind,
@@ -1941,9 +1950,9 @@ static const struct usb_device_id products[] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver ax88179_178a_driver = {
-	.name =		"ax88179_178a",
+	.name =		MODULENAME,
 	.id_table =	products,
-	.probe =	usbnet_probe,
+	.probe =	ax88179_probe,
 	.suspend =	ax88179_suspend,
 	.resume =	ax88179_resume,
 	.reset_resume =	ax88179_resume,
@@ -1952,7 +1961,62 @@ static struct usb_driver ax88179_178a_driver = {
 	.disable_hub_initiated_lpm = 1,
 };
 
-module_usb_driver(ax88179_178a_driver);
+static int ax88179_cfgselector_probe(struct usb_device *udev)
+{
+	struct usb_host_config *c;
+	int i, num_configs;
+
+	/* The vendor mode is not always config #1, so to find it out. */
+	c = udev->config;
+	num_configs = udev->descriptor.bNumConfigurations;
+	for (i = 0; i < num_configs; (i++, c++)) {
+		struct usb_interface_descriptor	*desc = NULL;
+
+		if (!c->desc.bNumInterfaces)
+			continue;
+		desc = &c->intf_cache[0]->altsetting->desc;
+		if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+			break;
+	}
+
+	if (i == num_configs)
+		return -ENODEV;
+
+	if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
+		dev_err(&udev->dev, "Failed to set configuration %d\n",
+			c->desc.bConfigurationValue);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct usb_device_driver ax88179_cfgselector_driver = {
+	.name =		MODULENAME "-cfgselector",
+	.probe =	ax88179_cfgselector_probe,
+	.id_table =	products,
+	.generic_subclass = 1,
+	.supports_autosuspend = 1,
+};
+
+static int __init ax88179_driver_init(void)
+{
+	int ret;
+
+	ret = usb_register_device_driver(&ax88179_cfgselector_driver, THIS_MODULE);
+	if (ret)
+		return ret;
+	return usb_register(&ax88179_178a_driver);
+}
+
+static void __exit ax88179_driver_exit(void)
+{
+	usb_deregister(&ax88179_178a_driver);
+	usb_deregister_device_driver(&ax88179_cfgselector_driver);
+}
+
+module_init(ax88179_driver_init);
+module_exit(ax88179_driver_exit);
 
 MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
 MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 2/2] net: usb: support quirks in usbnet
  2025-09-29 10:21       ` Oliver Neukum
  2025-09-30  8:07         ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
@ 2025-09-30  8:14         ` yicongsrfy
  1 sibling, 0 replies; 35+ messages in thread
From: yicongsrfy @ 2025-09-30  8:14 UTC (permalink / raw)
  To: oneukum
  Cc: andrew+netdev, davem, edumazet, kuba, linux-usb, marcan, netdev,
	pabeni, yicong

On Mon, 29 Sep 2025 12:21:30 +0200, Oliver Neukum <oneukum@suse.com> wrote:
>
> On 29.09.25 11:29, yicongsrfy@163.com wrote:
> > On Mon, 29 Sep 2025 10:45:19 +0200, Oliver Neukum <oneukum@suse.com> wrote:
>
> >> Please get in contact with the core USB developers. The problem
> >> needs to be solved, but this is not a solution.
> >
> > Thank you for your reply!
> >
> > Should I add the AX88179 chip information into the `usb_quirk_list`
> > in `drivers/usb/core/quirks.c`? (Of course, it will also include a
> >   check for whether `CONFIG_USB_NET_AX88179_178A` is enabled.)
>
> That would need to be discussed.
> Ideally the probe() method of cdc_ncm would never be called.
> But there is the possibility that cdc_ncm is already loaded
> and the other driver is not.
> >  From an implementation standpoint, this approach is indeed cleaner
> > and simpler than my current solution.
> > Is the method mentioned above an appropriate approach?
> Well, no. Declining devices is not usbnet's job. If the logic
> needs to go into a device driver, it needs to go into cdc-ncm,
> which would need to check quirks.

Thank you for your suggestions!

I've placed the quirk in cdc_ncm and modified its probe
method accordingly. Could you please review whether the
v4 version of the patch is appropriate?


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 2/3] net: usb: support quirks in cdc_ncm
  2025-09-30  8:07           ` [PATCH v4 2/3] net: usb: support quirks in cdc_ncm yicongsrfy
@ 2025-09-30  8:37             ` Greg KH
  2025-09-30  8:38             ` Greg KH
  1 sibling, 0 replies; 35+ messages in thread
From: Greg KH @ 2025-09-30  8:37 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, linux-usb, marcan,
	netdev, pabeni, yicong

On Tue, Sep 30, 2025 at 04:07:08PM +0800, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> Some vendors' USB network interface controllers (NICs) may be compatible
> with multiple drivers.
> 
> I consulted with relevant vendors. Taking the AX88179 chip as an example,
> NICs based on this chip may be used across various OS—for instance,
> cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
> on Linux (despite a previous patch having disabled it).
> Therefore, the firmware must support multiple protocols.
> 
> Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
> Supporting both drivers simultaneously leads to the following issues:
> 
> 1. Inconsistent driver loading order during reboot stress testing:
>    The order in which drivers are loaded can vary across reboots,
>    potentially resulting in the unintended driver being loaded. For
>    example:
> [    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
> [    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
> [    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
> [    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
> xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
> [    4.240627] usbcore: registered new interface driver cdc_ncm
> [    4.240908] usbcore: registered new interface driver ax88179_178a
> 
> In this case, network connectivity functions, but the cdc_ncm driver is
> loaded instead of the expected ax88179_178a.
> 
> 2. Similar issues during cable plug/unplug testing:
>    The same race condition can occur when reconnecting the USB device:
> [   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
> [   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
> 1790, bcdDevice= 2.00
> [   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
> SerialNumber=3
> [   79.905191] usb 4-1: Product: AX88179B
> [   79.905198] usb 4-1: Manufacturer: ASIX
> [   79.905201] usb 4-1: SerialNumber: 00EF998E
> [   79.915215] ax88179_probe, bConfigurationValue:2
> [   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
> [   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
> [   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
> [   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
> 00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
> [   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
> 00.2-1, CDC NCM (NO ZLP)
> 
> At this point, the network becomes unusable.
> 
> To resolve these issues, introduce a *quirks* mechanism into the usbnet
> module. By adding chip-specific identification within the generic usbnet
> framework, we can skip the usbnet probe process for devices that require a
> dedicated driver.
> 
> v2: Correct the description of usbnet_quirks.h and modify the code style
> v3: Add checking whether the CONFIG_USB_NET_AX88179_178A is enabled
> v4: Move quirks from usbnet.ko to cdc_ncm.ko

These "version" lines go below the  --- line.

> Signed-off-by: Yi Cong <yicong@kylinos.cn>
> ---
>  drivers/net/usb/cdc_ncm.c        | 15 +++++++++++-
>  drivers/net/usb/cdc_ncm_quirks.h | 41 ++++++++++++++++++++++++++++++++

No need for this to be a .h file, just put it in the .c file please.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 2/3] net: usb: support quirks in cdc_ncm
  2025-09-30  8:07           ` [PATCH v4 2/3] net: usb: support quirks in cdc_ncm yicongsrfy
  2025-09-30  8:37             ` Greg KH
@ 2025-09-30  8:38             ` Greg KH
  1 sibling, 0 replies; 35+ messages in thread
From: Greg KH @ 2025-09-30  8:38 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, linux-usb, marcan,
	netdev, pabeni, yicong

On Tue, Sep 30, 2025 at 04:07:08PM +0800, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> Some vendors' USB network interface controllers (NICs) may be compatible
> with multiple drivers.
> 
> I consulted with relevant vendors. Taking the AX88179 chip as an example,
> NICs based on this chip may be used across various OS—for instance,
> cdc_ncm is used on macOS, while ax88179_178a.ko is the intended driver
> on Linux (despite a previous patch having disabled it).
> Therefore, the firmware must support multiple protocols.
> 
> Currently, both cdc_ncm and ax88179_178a coexist in the Linux kernel.
> Supporting both drivers simultaneously leads to the following issues:
> 
> 1. Inconsistent driver loading order during reboot stress testing:
>    The order in which drivers are loaded can vary across reboots,
>    potentially resulting in the unintended driver being loaded. For
>    example:
> [    4.239893] cdc_ncm 2-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
> [    4.239897] cdc_ncm 2-1:2.0: setting rx_max = 16384
> [    4.240149] cdc_ncm 2-1:2.0: setting tx_max = 16384
> [    4.240583] cdc_ncm 2-1:2.0 usb0: register 'cdc_ncm' at usb-
> xxxxx:00-1, CDC NCM, c8:a3:62:ef:99:8e
> [    4.240627] usbcore: registered new interface driver cdc_ncm
> [    4.240908] usbcore: registered new interface driver ax88179_178a
> 
> In this case, network connectivity functions, but the cdc_ncm driver is
> loaded instead of the expected ax88179_178a.
> 
> 2. Similar issues during cable plug/unplug testing:
>    The same race condition can occur when reconnecting the USB device:
> [   79.879922] usb 4-1: new SuperSpeed USB device number 3 using xhci_hcd
> [   79.905168] usb 4-1: New USB device found, idVendor=0b95, idProduct=
> 1790, bcdDevice= 2.00
> [   79.905185] usb 4-1: New USB device strings: Mfr=1, Product=2,
> SerialNumber=3
> [   79.905191] usb 4-1: Product: AX88179B
> [   79.905198] usb 4-1: Manufacturer: ASIX
> [   79.905201] usb 4-1: SerialNumber: 00EF998E
> [   79.915215] ax88179_probe, bConfigurationValue:2
> [   79.952638] cdc_ncm 4-1:2.0: MAC-Address: c8:a3:62:ef:99:8e
> [   79.952654] cdc_ncm 4-1:2.0: setting rx_max = 16384
> [   79.952919] cdc_ncm 4-1:2.0: setting tx_max = 16384
> [   79.953598] cdc_ncm 4-1:2.0 eth0: register 'cdc_ncm' at usb-0000:04:
> 00.2-1, CDC NCM (NO ZLP), c8:a3:62:ef:99:8e
> [   79.954029] cdc_ncm 4-1:2.0 eth0: unregister 'cdc_ncm' usb-0000:04:
> 00.2-1, CDC NCM (NO ZLP)
> 
> At this point, the network becomes unusable.
> 
> To resolve these issues, introduce a *quirks* mechanism into the usbnet
> module. By adding chip-specific identification within the generic usbnet
> framework, we can skip the usbnet probe process for devices that require a
> dedicated driver.
> 
> v2: Correct the description of usbnet_quirks.h and modify the code style
> v3: Add checking whether the CONFIG_USB_NET_AX88179_178A is enabled
> v4: Move quirks from usbnet.ko to cdc_ncm.ko
> 
> Signed-off-by: Yi Cong <yicong@kylinos.cn>
> ---
>  drivers/net/usb/cdc_ncm.c        | 15 +++++++++++-
>  drivers/net/usb/cdc_ncm_quirks.h | 41 ++++++++++++++++++++++++++++++++
>  2 files changed, 55 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/usb/cdc_ncm_quirks.h
> 
> diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
> index 5d123df0a866..fc8416af3f11 100644
> --- a/drivers/net/usb/cdc_ncm.c
> +++ b/drivers/net/usb/cdc_ncm.c
> @@ -54,6 +54,8 @@
>  #include <linux/usb/cdc.h>
>  #include <linux/usb/cdc_ncm.h>
>  
> +#include "cdc_ncm_quirks.h"
> +
>  #if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
>  static bool prefer_mbim = true;
>  #else
> @@ -2114,10 +2116,21 @@ static const struct usb_device_id cdc_devs[] = {
>  };
>  MODULE_DEVICE_TABLE(usb, cdc_devs);
>  
> +static int cdc_ncm_probe(struct usb_interface *intf, const struct usb_device_id *prod)
> +{
> +	/* Should it be ignored? */
> +	if (unlikely(cdc_ncm_ignore(intf))) {

There is no performance issue here, so please do not use unlikely/likely
unless you can prove with a benchmark that it is needed.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-30  8:07           ` [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
@ 2025-09-30  8:38             ` Greg KH
  2025-09-30  8:57             ` Oliver Neukum
  1 sibling, 0 replies; 35+ messages in thread
From: Greg KH @ 2025-09-30  8:38 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, linux-usb, marcan,
	netdev, pabeni, yicong

On Tue, Sep 30, 2025 at 04:07:09PM +0800, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> A similar reason was raised in commit ec51fbd1b8a2 ("r8152: add USB
> device driver for config selection"):
> Linux prioritizes probing non-vendor-specific configurations.
> 
> Referring to the implementation of this patch, cfgselect is also
> used for ax88179 to override the default configuration selection.
> 
> v2: fix warning from checkpatch
> 
> Signed-off-by: Yi Cong <yicong@kylinos.cn>
> ---
>  drivers/net/usb/ax88179_178a.c | 70 ++++++++++++++++++++++++++++++++--
>  1 file changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
> index 29cbe9ddd610..f2e86b9256dc 100644
> --- a/drivers/net/usb/ax88179_178a.c
> +++ b/drivers/net/usb/ax88179_178a.c
> @@ -14,6 +14,7 @@
>  #include <uapi/linux/mdio.h>
>  #include <linux/mdio.h>
>  
> +#define MODULENAME "ax88179_178a"

Please just use KBUILD_MODNAME

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-30  8:07           ` [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
  2025-09-30  8:38             ` Greg KH
@ 2025-09-30  8:57             ` Oliver Neukum
  2025-10-09  7:34               ` yicongsrfy
  2025-10-13  5:59               ` Michal Pecio
  1 sibling, 2 replies; 35+ messages in thread
From: Oliver Neukum @ 2025-09-30  8:57 UTC (permalink / raw)
  To: yicongsrfy, oneukum, andrew+netdev
  Cc: davem, edumazet, kuba, linux-usb, marcan, netdev, pabeni, yicong

Hi,

On 30.09.25 10:07, yicongsrfy@163.com wrote:
   
> +static int ax88179_probe(struct usb_interface *intf, const struct usb_device_id *i)
> +{
> +	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
> +		return -ENODEV;

This check is only necessary because you have disabled the checking
done in usbcore with the first patch in your series.
The patch you are reverting with first patch is correct however.
ax88179 can drive these devices only if they are in the vendor
specific mode.

> +	return usbnet_probe(intf, i);
> +}

> +
>   static const struct driver_info ax88179_info = {
>   	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
>   	.bind = ax88179_bind,
> @@ -1941,9 +1950,9 @@ static const struct usb_device_id products[] = {
>   MODULE_DEVICE_TABLE(usb, products);
>   
>   static struct usb_driver ax88179_178a_driver = {
> -	.name =		"ax88179_178a",
> +	.name =		MODULENAME,
>   	.id_table =	products,
> -	.probe =	usbnet_probe,
> +	.probe =	ax88179_probe,
>   	.suspend =	ax88179_suspend,
>   	.resume =	ax88179_resume,
>   	.reset_resume =	ax88179_resume,
> @@ -1952,7 +1961,62 @@ static struct usb_driver ax88179_178a_driver = {
>   	.disable_hub_initiated_lpm = 1,
>   };
>   
> -module_usb_driver(ax88179_178a_driver);
> +static int ax88179_cfgselector_probe(struct usb_device *udev)
> +{
> +	struct usb_host_config *c;
> +	int i, num_configs;
> +
> +	/* The vendor mode is not always config #1, so to find it out. */
> +	c = udev->config;
> +	num_configs = udev->descriptor.bNumConfigurations;
> +	for (i = 0; i < num_configs; (i++, c++)) {
> +		struct usb_interface_descriptor	*desc = NULL;
> +
> +		if (!c->desc.bNumInterfaces)
> +			continue;
> +		desc = &c->intf_cache[0]->altsetting->desc;
> +		if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
> +			break;
> +	}
> +
> +	if (i == num_configs)
> +		return -ENODEV;
> +
> +	if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
> +		dev_err(&udev->dev, "Failed to set configuration %d\n",
> +			c->desc.bConfigurationValue);
> +		return -ENODEV;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct usb_device_driver ax88179_cfgselector_driver = {
> +	.name =		MODULENAME "-cfgselector",
> +	.probe =	ax88179_cfgselector_probe,

You want this to only run if the device is in the generic mode.

> +	.id_table =	products,
But here you check only for the product ID, not for the class code.> +	.generic_subclass = 1,> +	.supports_autosuspend = 1,

You do not. It does not matter, but it is wrong.

> +};
> +
> +static int __init ax88179_driver_init(void)
> +{
> +	int ret;
> +
> +	ret = usb_register_device_driver(&ax88179_cfgselector_driver, THIS_MODULE);
> +	if (ret)
> +		return ret;
> +	return usb_register(&ax88179_178a_driver);

Missing error handling. If you cannot register ax88179_178a_driver
you definitely do not want to keep ax88179_cfgselector_driver

> +}
> +
> +static void __exit ax88179_driver_exit(void)
> +{
> +	usb_deregister(&ax88179_178a_driver);

The window for the race

> +	usb_deregister_device_driver(&ax88179_cfgselector_driver);

Wrong order. I you remove ax88179_178a_driver before you remove
ax88179_cfgselector_driver, you'll leave a window during which
devices would be switched to a mode no driver exists for.

	Regards
		Oliver



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface"
  2025-09-30  8:07         ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
  2025-09-30  8:07           ` [PATCH v4 2/3] net: usb: support quirks in cdc_ncm yicongsrfy
  2025-09-30  8:07           ` [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
@ 2025-10-06 16:33           ` Andrew Lunn
  2 siblings, 0 replies; 35+ messages in thread
From: Andrew Lunn @ 2025-10-06 16:33 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, linux-usb, marcan,
	netdev, pabeni, yicong

On Tue, Sep 30, 2025 at 04:07:07PM +0800, yicongsrfy@163.com wrote:
> From: Yi Cong <yicong@kylinos.cn>
> 
> This reverts commit c67cc4315a8e605ec875bd3a1210a549e3562ddc.
> 
> Currently, in the Linux kernel, USB NIC with ASIX chips use the cdc_ncm
> driver. However, this driver lacks functionality and performs worse than
> the vendor's proprietary driver. In my testing, I have identified the
> following issues:
> 
> 1. The cdc_ncm driver does not support changing the link speed via
>    ethtool because the corresponding callback function is set to NULL.
> 2. The CDC protocol does not support retrieving the network duplex status.
> 3. In TCP_RR and UDP_RR tests, the performance of the cdc_ncm driver
>    is significantly lower than that of the vendor's driver:
> Average of three netperf runs: `netperf -t {TCP/UDP_RR} -H serverIP -l 120`
> - cdc_ncm.ko: TCP_RR: 740, UDP_RR: 750
> - ax88179_178a.ko: TCP_RR: 8900, UDP_RR: 9200
> 
> Issues related to the vendor's driver ax88179_178a.ko will be addressed
> in the next patch.

It looks like there was a lot of discussion somewhere else, because
this patchset jumps from v1 to v4. Please don't change the email
distribution like this.

Also, please start a new thread for each version of the patchset.

      Andrew

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-30  8:57             ` Oliver Neukum
@ 2025-10-09  7:34               ` yicongsrfy
  2025-10-09  8:46                 ` Oliver Neukum
  2025-10-09 11:56                 ` Andrew Lunn
  2025-10-13  5:59               ` Michal Pecio
  1 sibling, 2 replies; 35+ messages in thread
From: yicongsrfy @ 2025-10-09  7:34 UTC (permalink / raw)
  To: oneukum
  Cc: andrew+netdev, davem, edumazet, kuba, linux-usb, marcan, netdev,
	pabeni, yicong

Hi, Oliver:
Thank you for your reply!

The issues you mentioned above, I will fix them one by one in new patch
versions. However, I'm a bit confused about the following comment:

> > +
> > +static void __exit ax88179_driver_exit(void)
> > +{
> > +	usb_deregister(&ax88179_178a_driver);
>
> The window for the race
>
> > +	usb_deregister_device_driver(&ax88179_cfgselector_driver);
>
> Wrong order. I you remove ax88179_178a_driver before you remove
> ax88179_cfgselector_driver, you'll leave a window during which
> devices would be switched to a mode no driver exists for.

In my init function, I first call usb_register_device_driver and then call
usb_register; in exit, I reverse the order by calling usb_deregister first,
then usb_deregister_device_driver. Why is this sequence considered incorrect?


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-10-09  7:34               ` yicongsrfy
@ 2025-10-09  8:46                 ` Oliver Neukum
  2025-10-09 11:56                 ` Andrew Lunn
  1 sibling, 0 replies; 35+ messages in thread
From: Oliver Neukum @ 2025-10-09  8:46 UTC (permalink / raw)
  To: yicongsrfy, oneukum
  Cc: andrew+netdev, davem, edumazet, kuba, linux-usb, marcan, netdev,
	pabeni, yicong

Hi,

On 09.10.25 09:34, yicongsrfy@163.com wrote:

>>> +static void __exit ax88179_driver_exit(void)
>>> +{
>>> +	usb_deregister(&ax88179_178a_driver);
>>
>> The window for the race
>>
>>> +	usb_deregister_device_driver(&ax88179_cfgselector_driver);
>>
>> Wrong order. I you remove ax88179_178a_driver before you remove
>> ax88179_cfgselector_driver, you'll leave a window during which
>> devices would be switched to a mode no driver exists for.
> 
> In my init function, I first call usb_register_device_driver and then call
> usb_register; in exit, I reverse the order by calling usb_deregister first,
> then usb_deregister_device_driver. Why is this sequence considered incorrect?

To explain this I need to make a chart:

CPU A								CPU B

usb_deregister(&ax88179_178a_driver);

								New device registered
								ax88179_cfgselector_driver:
									Device switches to proprietary mode

usb_deregister_device_driver(&ax88179_cfgselector_driver);
[This comes too late. No consequences for current events]
								No driver. No probe().
								Very sad device. Disappointed user.

I hope you excuse my attempt at humor. Anyway this order is incorrect, as I hope
you see from the chart. Now you may say that the class mode would not work
anyway, but that is an iffy argument. It is better to have the order that is
right.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-10-09  7:34               ` yicongsrfy
  2025-10-09  8:46                 ` Oliver Neukum
@ 2025-10-09 11:56                 ` Andrew Lunn
  1 sibling, 0 replies; 35+ messages in thread
From: Andrew Lunn @ 2025-10-09 11:56 UTC (permalink / raw)
  To: yicongsrfy
  Cc: oneukum, andrew+netdev, davem, edumazet, kuba, linux-usb, marcan,
	netdev, pabeni, yicong

On Thu, Oct 09, 2025 at 03:34:50PM +0800, yicongsrfy@163.com wrote:
> Hi, Oliver:
> Thank you for your reply!
> 
> The issues you mentioned above, I will fix them one by one in new patch
> versions. However, I'm a bit confused about the following comment:
> 
> > > +
> > > +static void __exit ax88179_driver_exit(void)
> > > +{
> > > +	usb_deregister(&ax88179_178a_driver);
> >
> > The window for the race
> >
> > > +	usb_deregister_device_driver(&ax88179_cfgselector_driver);
> >
> > Wrong order. I you remove ax88179_178a_driver before you remove
> > ax88179_cfgselector_driver, you'll leave a window during which
> > devices would be switched to a mode no driver exists for.
> 
> In my init function, I first call usb_register_device_driver and then call
> usb_register; in exit, I reverse the order by calling usb_deregister first,
> then usb_deregister_device_driver. Why is this sequence considered incorrect?

This is not about the order you do things in this patch. It is about
the order of the patches.

It is assumed that this hardware somewhat works with the old
driver. But without this patch the hardware does not work?

Anybody doing a git bisect could land on the first patch, and have
broken networking. So you need the patches in the opposite order. Make
sure the driver will work before swapping to it.

	Andrew

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-09-30  8:57             ` Oliver Neukum
  2025-10-09  7:34               ` yicongsrfy
@ 2025-10-13  5:59               ` Michal Pecio
  2025-10-13  8:46                 ` Oliver Neukum
  1 sibling, 1 reply; 35+ messages in thread
From: Michal Pecio @ 2025-10-13  5:59 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: yicongsrfy, andrew+netdev, davem, edumazet, kuba, linux-usb,
	marcan, netdev, pabeni, yicong

On Tue, 30 Sep 2025 10:57:05 +0200, Oliver Neukum wrote:
> > +static int __init ax88179_driver_init(void)
> > +{
> > +	int ret;
> > +
> > +	ret = usb_register_device_driver(&ax88179_cfgselector_driver, THIS_MODULE);
> > +	if (ret)
> > +		return ret;
> > +	return usb_register(&ax88179_178a_driver);  
> 
> Missing error handling. If you cannot register ax88179_178a_driver
> you definitely do not want to keep ax88179_cfgselector_driver
> 
> > +}
> > +
> > +static void __exit ax88179_driver_exit(void)
> > +{
> > +	usb_deregister(&ax88179_178a_driver);  
> 
> The window for the race
> 
> > +	usb_deregister_device_driver(&ax88179_cfgselector_driver);  
> 
> Wrong order. I you remove ax88179_178a_driver before you remove
> ax88179_cfgselector_driver, you'll leave a window during which
> devices would be switched to a mode no driver exists for.

Hmm, what about registration?

I added msleep(1000) and simulated usb_register() error, then
cfgselector binds to the device and switches configuration before
the interface driver is available. But the module fails to load
(I fixed this) and device is left with no driver whatsoever.

Moreover, according to c67cc4315a8e, config switch is irreversible
since the device reconnects with only the vendor config available.
I can't test it because my device doesn't have a CDC config at all.

There is a gotcha. I tried to test in a realistic scenario: device
hotplug, module not loaded yet. I found that udev apparently retries
loading the module, so this state would be fixed unless the module
init error is persistent. Still, better not to rely on this?

Would it make sense to swap registration order?

Regards,
Michal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection
  2025-10-13  5:59               ` Michal Pecio
@ 2025-10-13  8:46                 ` Oliver Neukum
  0 siblings, 0 replies; 35+ messages in thread
From: Oliver Neukum @ 2025-10-13  8:46 UTC (permalink / raw)
  To: Michal Pecio
  Cc: yicongsrfy, andrew+netdev, davem, edumazet, kuba, linux-usb,
	marcan, netdev, pabeni, yicong

On 13.10.25 07:59, Michal Pecio wrote:

> 
> Would it make sense to swap registration order?

I would say so. As a rule we should probably
only switch devices to modes we are positive
we have a driver for.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2025-10-13  8:46 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-28  1:46 [PATCH 1/2] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
2025-09-28  1:46 ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy
2025-09-29  4:23   ` Jakub Kicinski
2025-09-29  5:31     ` [PATCH v2 0/3] ax88179 driver optimization yicongsrfy
2025-09-29  5:31       ` [PATCH v2 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
2025-09-29  7:02         ` Michal Pecio
2025-09-29  7:25           ` yicongsrfy
2025-09-29  5:31       ` [PATCH v2 2/3] net: usb: support quirks in usbnet yicongsrfy
2025-09-29  7:11         ` Michal Pecio
2025-09-29  7:29           ` yicongsrfy
2025-09-29  5:31       ` [PATCH v2 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
2025-09-29  5:42         ` yicongsrfy
2025-09-29  7:53           ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
2025-09-29  7:54             ` [PATCH v3 2/3] net: usb: support quirks in usbnet yicongsrfy
2025-09-29  7:54             ` [PATCH v3 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
2025-09-29 11:20               ` Oliver Neukum
2025-09-29 16:11               ` Jakub Kicinski
2025-09-29 11:15             ` [PATCH v3 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" Oliver Neukum
2025-09-29  8:45   ` [PATCH 2/2] net: usb: support quirks in usbnet Oliver Neukum
2025-09-29  9:29     ` yicongsrfy
2025-09-29 10:21       ` Oliver Neukum
2025-09-30  8:07         ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" yicongsrfy
2025-09-30  8:07           ` [PATCH v4 2/3] net: usb: support quirks in cdc_ncm yicongsrfy
2025-09-30  8:37             ` Greg KH
2025-09-30  8:38             ` Greg KH
2025-09-30  8:07           ` [PATCH v4 3/3] net: usb: ax88179_178a: add USB device driver for config selection yicongsrfy
2025-09-30  8:38             ` Greg KH
2025-09-30  8:57             ` Oliver Neukum
2025-10-09  7:34               ` yicongsrfy
2025-10-09  8:46                 ` Oliver Neukum
2025-10-09 11:56                 ` Andrew Lunn
2025-10-13  5:59               ` Michal Pecio
2025-10-13  8:46                 ` Oliver Neukum
2025-10-06 16:33           ` [PATCH v4 1/3] Revert "net: usb: ax88179_178a: Bind only to vendor-specific interface" Andrew Lunn
2025-09-30  8:14         ` [PATCH 2/2] net: usb: support quirks in usbnet yicongsrfy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).