drivers/net/phy/ax88796b.c | 188 ++++++ drivers/net/usb/Kconfig | 10 +- drivers/net/usb/Makefile | 3 +- drivers/net/usb/ax88179_178a.c | 664 ++------------------ drivers/net/usb/ax88179_lib.c | 515 ++++++++++++++++ drivers/net/usb/ax88179_lib.h | 358 +++++++++++ drivers/net/usb/ax88179a_devices.c | 1200 ++++++++++++++++++++++++++++++++++++ 7 files changed, 2314 insertions(+), 624 deletions(-)
This adds support for the current generation of ASIX network adapter chips,
which are based on the AX88179A. This includes the AX88179A/B (1GBit-PHY),
AX88772D/E (100MBit) and AX88279 (2.5GBit).
The AX179A-based chips all provide both a CDC-NCM compatible USB interface,
and a proprietary vendor interface with more features. By default, the
proprietary vendor interface is not active and Linux will load the CDC-NCM
driver to support the devices. If the ax88179_178a module is configured by
the OS to have precedence over CDC-NCM, then this driver will switch the
device to use the vendor interface, and the device will be controlled by
the ax88179_178a driver when the device is probed again after an automatic
reset of the device bringing up the vendor interface.
The following hardware was tested:
Delock 66046 2.5GBit adapter (AX88279, FW: 1.2.0.0)
TP-Link UE306 1GBit adapter (AX88179B, FW: 1.3.0.0)
Renkforce RF-4708614 1GBit adapter (AX88179A, FW: 1.0.4.0)
UGREEN CR110 100MBit adapter (AX88722E, FW: 1.3.0.0)
The driver supports the following features
- EEE
- TCP segmentation offload
- VLAN filtering/tagging offload
(NETIF_F_HW_VLAN_CTAG_FILTER, NETIF_F_HW_VLAN_CTAG_RX/TX)
- RX/TX checksum offload
- FC/Pause configuration
- EEPROM read access
The code is based on the ASIX 4.1.0 out-of-tree driver published under
the GPL,, the aqc111 driver which provides support for the AX88279A,
and some tracing of USB-transfers of the Windows-driver.
Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
Tested-by: Jianhui Xu <neuromoments@gmail.com>
---
Changes in v5:
- Fixed read_status() and config_aneg() in PHY driver
- Introduced netdev2data() as convenience function
- netdev_info instances and debugging relicts removed
- Several instances of badly written/formatted code that was copy and pasted from
the original driver corrected
- select PHYLINK added to Kconfig when phylib dependency added
- PHYLINK selects PHYLIB, so not needed to specify separately
- Link to v4: https://lore.kernel.org/r/20260731-ax88179a-v4-0-2cf1f71b1dd2@birger-koblitz.de
Changes in v4:
- Split driver into library part and part2 for AX88179 and AX88179A-based
controllers
- Driver renamed ax88179
- Improved phylink use: use phylink standard functions for speed and EEE-settings,
correct MAC capabilities, removed ax88179_status() irq-urb callback
- Fixes in PHY driver for AX88179A integrated PHYs
- Link to v3: https://lore.kernel.org/r/20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de
Changes in v3:
- Add PHY drivers for the PHYs of the AX88179A-based controllers
- Use phylink for the AX88179A-based chips
- Link to v2: https://lore.kernel.org/r/20260708-ax88179a-v2-0-0800fedb2e16@birger-koblitz.de
Changes in v2:
- Correctly use net-next prefix
- Fix compilation issue in HW support patch
- Split MMD support patch into patches for EEE/new chip support
- Do not use ADVERTISE_RESV but private flag definition
- Fix pause configuration to keep track of settings when autoneg disabled
- Fix issue with unitialized variable reported by kernel test robot <lkp@intel.com>
- Avoid white-space changes
- Link to v1: https://lore.kernel.org/r/20260701-ax88179a-v1-0-13685df67515@birger-koblitz.de
---
Birger Koblitz (13):
ax88179_178a: Fix endianness of pause watermark register
ax88179_178a: Split driver into library and device specific code
ax88179_178a: Add netdev2data() convenience function
ax88179_178a: Add HW support for AX179A-based chips
ax88179_178a: Add EEE configuration support for AX88179A MACs
ax88179_178a: Add EEE configuration support for AX88179A PHYs
ax88179_178a: Add VLAN offload support for AX88179A
ax88179_178a: Add AX179A/AX279 multicast configuration
ax88179_178a: Add Suspend/resume support for AX88179A/772D/279
ax88179_178a: Add ethtool get_drvinfo
ax88179_178a: Update driver name and information
ax88179_178a: Add support for AX88179A/772D/279 EEPROM access
ax88796b: Add support for AX88772D, AX88179A and AX88279
drivers/net/phy/ax88796b.c | 188 ++++++
drivers/net/usb/Kconfig | 10 +-
drivers/net/usb/Makefile | 3 +-
drivers/net/usb/ax88179_178a.c | 664 ++------------------
drivers/net/usb/ax88179_lib.c | 515 ++++++++++++++++
drivers/net/usb/ax88179_lib.h | 358 +++++++++++
drivers/net/usb/ax88179a_devices.c | 1200 ++++++++++++++++++++++++++++++++++++
7 files changed, 2314 insertions(+), 624 deletions(-)
---
base-commit: 1a9edf8be190decb17227e3cba540513d93ebb85
change-id: 20260630-ax88179a-a1d89fe21730
Best regards,
--
Birger Koblitz <mail@birger-koblitz.de>
Hi Birger, I tested v5 on the same ASIX AX88179B adapter (USB 0b95:1790, bcdDevice 0x0200, firmware 1.3.0.0). The 13 patches applied to net-next commit df13c1df8147675470213ffff29dd5762fa321f5 and built successfully as 7.2.0-rc3-ax88179b-v5. The focused W=1 builds for ax88179.o and ax88796b.o were clean. Unfortunately I reproduced an intermittent cold-activation failure, so I cannot add a Tested-by for v5. In four fresh direct-kernel QEMU starts with complete diagnostic capture, the old lease was released before starting DHCPDISCOVER. Two reported 1000baseT/Full carrier but timed out DHCP, while two succeeded normally. In both failed runs, RX remained at zero while TX increased. Reloading ax88179 and ax88796b recovered DHCP, RX, and bound traffic in both cases. Before this follow-up campaign, in the earlier v5 validation session, I observed a separate 100baseT/Full failure: the adapter negotiated carrier after I changed the advertisement to 100baseT/Full-only, but ARP and bound traffic failed. I then tried to reproduce that result with three new advertise-0x008 transitions. All three negotiated 100baseT/Full and passed bound gateway traffic; two also explicitly passed traffic to the test host. These repetitions included tests both with and without a preceding module reload. I could not reproduce the earlier 100-Mbit failure. That earlier v5 validation session also produced a separate guest ACPI S3 failure: after resume, the adapter returned with 1000baseT/Full carrier, but RX remained frozen and traffic was broken. I then performed three new S3 cycles. All three logged QEMU's same emulated-XHCI resume reinitialization and USB reset, but returned working traffic with increasing RX counters immediately. The final repetition also recreated the earlier speed, EEE, and pause setting sequence and verified working gateway traffic immediately before suspend. I could not reproduce the earlier frozen-RX result. This remains a QEMU emulated-XHCI test, not a physical-XHCI suspend test. While reviewing the speed result, I noticed ax88179a_bulkin_config() selects its table using ax179_data->speed, while ax88179a_mac_link_up() receives the speed argument but I could not find an assignment to that private member. The new passing 100-Mbit tests do not support linking that source observation to the original one-off failure, and the same pattern appears in v4. EEE disable/restore, pause enable/restore, EEPROM read, module reload, and USB detach/reattach otherwise worked. I also tried Wake-on-LAN in QEMU. The driver accepted magic-packet wake, ethtool read back Wake-on: g, and USB wakeup was enabled before the guest entered S3. QEMU was configured with USB remote-wake suppression disabled, but the guest did not resume after directed-broadcast, limited-broadcast, and unicast magic packets. I consider that result inconclusive because I did not independently verify the physical USB remote-wakeup propagation through QEMU. Please let me know if you would like me to test a fix or collect a specific register trace. Thanks, Jianhui
Thanks so much for testing, again, Jianhui!
On 03/08/2026 09:33, Jianhui Xu wrote:
> Hi Birger,
>
> I tested v5 on the same ASIX AX88179B adapter (USB 0b95:1790,
> bcdDevice 0x0200, firmware 1.3.0.0).
>
> The 13 patches applied to net-next commit
> df13c1df8147675470213ffff29dd5762fa321f5 and built successfully as
> 7.2.0-rc3-ax88179b-v5. The focused W=1 builds for ax88179.o and
> ax88796b.o were clean.
>
> Unfortunately I reproduced an intermittent cold-activation failure, so I cannot
> add a Tested-by for v5. In four fresh direct-kernel QEMU starts with complete
> diagnostic capture, the old lease was released before starting DHCPDISCOVER. Two
> reported 1000baseT/Full carrier but timed out DHCP, while two succeeded
> normally. In both failed runs, RX remained at zero while TX increased. Reloading
> ax88179 and ax88796b recovered DHCP, RX, and bound traffic in both cases.
>
> Before this follow-up campaign, in the earlier v5 validation session, I observed
> a separate 100baseT/Full failure: the adapter negotiated carrier after I changed
> the advertisement to 100baseT/Full-only, but ARP and bound traffic failed.
> I then tried to reproduce that result with three new advertise-0x008
> transitions. All three negotiated 100baseT/Full and passed bound gateway
> traffic; two also explicitly passed traffic to the test host. These repetitions
> included tests both with and without a preceding module reload. I could not
> reproduce the earlier 100-Mbit failure.
>
> That earlier v5 validation session also produced a separate guest ACPI S3
> failure: after resume, the adapter returned with 1000baseT/Full carrier, but RX
> remained frozen and traffic was broken. I then performed three new S3 cycles.
> All three logged QEMU's same emulated-XHCI resume reinitialization and USB
> reset, but returned working traffic with increasing RX counters immediately. The
> final repetition also recreated the earlier speed, EEE, and pause setting
> sequence and verified working gateway traffic immediately before suspend.
> I could not reproduce the earlier frozen-RX result. This remains a QEMU
> emulated-XHCI test, not a physical-XHCI suspend test.
>
> While reviewing the speed result, I noticed ax88179a_bulkin_config() selects its
> table using ax179_data->speed, while ax88179a_mac_link_up() receives the speed
> argument but I could not find an assignment to that private member. The new
> passing 100-Mbit tests do not support linking that source observation to the
> original one-off failure, and the same pattern appears in v4.
This issue is not critically problematic, the speed variable only affects the bulk
configuration settins that control how data is assembled in the controller and
assembled to larger USB transfers, including timing and so on. This should only harm
performance, but not the issues with the link after suspend/resume. It was introduced
in v3 or v4 when the speed info no longer came from the USB interrupt URB.
The following should fix this:
diff --git a/drivers/net/usb/ax88179a_devices.c b/drivers/net/usb/ax88179a_devices.c
index 37a55ff5464c..a4d782979c63 100644
--- a/drivers/net/usb/ax88179a_devices.c
+++ b/drivers/net/usb/ax88179a_devices.c
@@ -215,13 +215,13 @@ static void ax88179a_get_drvinfo(struct net_device *net, struct ethtool_drvinfo
priv->fw_version[2], priv->fw_version[3]);
}
-static void ax88179a_bulkin_config(struct usbnet *dev, u8 link_sts)
+static void ax88179a_bulkin_config(struct usbnet *dev, u8 link_sts, u8 speed)
{
struct ax88179_data *ax179_data = dev->driver_priv;
const struct ax_bulkin_settings *bulkin_data;
int index = 0;
- switch (ax179_data->speed) {
+ switch (speed) {
case ETHER_LINK_2500: /* AX88279 only */
index = 0;
break;
@@ -451,6 +451,7 @@ static void ax88179a_mac_link_up(struct phylink_config *config,
struct usbnet *dev = netdev_priv(to_net_dev(config->dev));
struct ax88179_data *ax179_data = dev->driver_priv;
u8 tmp8, link_sts, reg8[3];
+ u8 bulk_config_speed = 0;
u16 tmp16, mode;
/* Stop RX/TX for link configuration */
@@ -503,11 +504,13 @@ static void ax88179a_mac_link_up(struct phylink_config *config,
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_LSO_ENHANCE_CTRL, 1, 1, &tmp8);
mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_FULL_DUPLEX;
+ bulk_config_speed = ETHER_LINK_2500;
break;
case SPEED_1000:
mode |= AX_MEDIUM_GIGAMODE;
+ bulk_config_speed = ETHER_LINK_1000;
fallthrough;
case SPEED_100:
@@ -518,6 +521,8 @@ static void ax88179a_mac_link_up(struct phylink_config *config,
tmp8 = 0x40;
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_DATA_CDC_CNT, 1, 1, &tmp8);
+ if (!bulk_config_speed)
+ bulk_config_speed = ETHER_LINK_100;
break;
case SPEED_10:
@@ -529,12 +534,12 @@ static void ax88179a_mac_link_up(struct phylink_config *config,
tmp8 = 0xFA;
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_DATA_CDC_CNT, 1, 1, &tmp8);
- speed = 10;
+ bulk_config_speed = ETHER_LINK_10;
break;
}
ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS, 1, 1, &link_sts);
- ax88179a_bulkin_config(dev, link_sts);
+ ax88179a_bulkin_config(dev, link_sts, bulk_config_speed);
if (ax179_data->chip_version < AX_VERSION_AX88279) {
tmp8 = 0;
>
> EEE disable/restore, pause enable/restore, EEPROM read, module reload, and USB
> detach/reattach otherwise worked. I also tried Wake-on-LAN in QEMU. The driver
> accepted magic-packet wake, ethtool read back Wake-on: g, and USB wakeup was
> enabled before the guest entered S3. QEMU was configured with USB remote-wake
> suppression disabled, but the guest did not resume after directed-broadcast,
> limited-broadcast, and unicast magic packets. I consider that result
> inconclusive because I did not independently verify the physical USB
> remote-wakeup propagation through QEMU.
>
> Please let me know if you would like me to test a fix or collect a specific
> register trace.
Could you trace the calls to __ax88179_write_cmd (registers, values) around the
suspend/resume events. Since the issue is not deterministic, it is probably sequence/timing-related.
My suspicion is that phylink sends PHY-polls after the controller got the sleep command.
Are there differences in the sequence of calls for the successfull suspend/resume
cycles and the unsuccessful ones?
Thanks!
Birger
Hi Birger, I really appreciate all the work you’ve put into this! I’ll apply the fix and run additional tests this weekend. I’ll report back with the traces and any reproducible differences if I find them. Thanks, Jianhui
Hi Yuan, On 03/08/2026 16:39, Yuan Xu wrote: > Hi Birger, > > I really appreciate all the work you’ve put into this! Thanks so much. And thanks for testing! > > I’ll apply the fix and run additional tests this weekend. I’ll report back > with the traces and any reproducible differences if I find them. I sent out a v5. This should fix the issues you reported. I tested extensively link speeds and resume/suspend using a laptop and a loop-back cable between and AX88279 and an AX88179B using netns. I tested around 20 suspend/resume cycles and found no issues even with different speeds with the fixes in v5. Cheers, Birger
© 2016 - 2026 Red Hat, Inc.