Re: [PATCH 2/9] ax88179_178a: Add HW support for AX179A-based chips
From: Paolo Abeni <pabeni@redhat.com>
Date: 2026-07-07 09:11:39
Also in:
linux-usb, lkml
On 7/1/26 7:42 AM, Birger Koblitz wrote:
static int ax88179_reset(struct usbnet *dev)
{
- u8 buf[5];
- u16 *tmp16;
- u8 *tmp;
struct ax88179_data *ax179_data = dev->driver_priv;
struct ethtool_keee eee_data;
+ u16 *tmp16;
+ u8 buf[5];
+ u8 *tmp;
tmp16 = (u16 *)buf;
tmp = (u8 *)buf;
/* Power up ethernet PHY */
- *tmp16 = 0;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+ if (ax179_data->chip_version < AX_VERSION_AX88179A) {
+ *tmp16 = 0;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
- *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
- msleep(500);
+ *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+ msleep(500);
- *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
- msleep(200);
+ *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+ msleep(200);
+ } else {
+ *tmp = AX_PHY_POWER;
+ ax88179_write_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, tmp);
+ msleep(250);
+ }
+
+ if (ax179_data->chip_version == AX_VERSION_AX88279) {
+ *tmp16 = ax88179_mdio_read(dev->net, dev->mii.phy_id, MII_ADVERTISE);
+ *tmp16 &= ~(ADVERTISE_10FULL | ADVERTISE_10HALF);
+ *tmp16 |= ADVERTISE_RESV; /* Advertise 2.5GBit link */
+ ax88179_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, *tmp16);
+ }
/* Ethernet PHY Auto Detach*/
ax88179_auto_detach(dev);
+ if (ax179_data->chip_version >= AX_VERSION_AX88179A) {
+ *tmp = AX_MAC_EFF_EN;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BULK_OUT_CTRL, 1, 1, tmp);
+
+ *tmp16 = 0;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
+
+ *tmp = 0x04;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+ *tmp = 0x10;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1, 1, tmp);
+
+ *tmp = 0;
+ if (dev->net->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+ *tmp |= AX_VLAN_CONTROL_VFE;Does not build successfully: ../drivers/net/usb/ax88179_178a.c: In function ‘ax88179_reset’: ../drivers/net/usb/ax88179_178a.c:2376:33: error: ‘AX_VLAN_CONTROL_VFE’ undeclared (first use in this function) 2376 | *tmp |= AX_VLAN_CONTROL_VFE; Full log here: https://netdev-ctrl.bots.linux.dev/logs/build/1119419/14655119/build_32bit/stderr Side process note: the patch series shoudl include the target tree ('net-next' in this case). /P
quoted hunk ↗ jump to hunk
+ if (dev->net->features & NETIF_F_HW_VLAN_CTAG_RX) + *tmp |= AX_VLAN_CONTROL_VSO; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, tmp); + + *tmp = 0xff; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BM_INT_MASK, 1, 1, tmp); + + *tmp = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BM_RX_DMA_CTL, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BM_TX_DMA_CTL, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_ARC_CTRL, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_SWP_CTRL, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_TX_HDR_CKSUM, 1, 1, tmp); + } + /* Read MAC address from DTB or asix chip */ ax88179_get_mac_addr(dev); memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); /* RX bulk configuration */ - memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); - - dev->rx_urb_size = 1024 * 20; - - *tmp = 0x34; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1, 1, tmp); - - *tmp = 0x52; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + if (ax179_data->chip_version < AX_VERSION_AX88179A) { + memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); + *tmp = 0x34; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + + *tmp = 0x52; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, + 1, 1, tmp); + dev->rx_urb_size = 1024 * 20; + } else { + /* The Bulk-Register configuration for the AX88179A is done in + * ax88179a_link_reset(), once the link is up for a given link and USB-speed. + */ + if (ax179_data->is_ax88772d) + dev->rx_urb_size = 1024 * 24; + else + dev->rx_urb_size = 1024 * 48; + } /* Enable checksum offload */ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); + ax179_data->rx_checksum = 1; *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); /* Configure RX control register => start operation */ - *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | - AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); - - *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | - AX_MONITOR_MODE_RWMP; + ax179_data->rxctl = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_START | + AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; + if (ax179_data->ip_align) + ax179_data->rxctl |= AX_RX_CTL_IPE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &ax179_data->rxctl); + + if (ax179_data->chip_version < AX_VERSION_AX88179A) + *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | AX_MONITOR_MODE_RWMP; + else + *tmp = AX_MONITOR_MODE_RWMP; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); /* Configure default medium type => giga */ *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX | - AX_MEDIUM_GIGAMODE; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, tmp16); + AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX; + if (!ax179_data->is_ax88772d) + *tmp16 |= AX_MEDIUM_GIGAMODE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, tmp16); /* Check if WoL is supported */ ax179_data->wol_supported = 0;@@ -1653,7 +2450,11 @@ static int ax88179_reset(struct usbnet *dev) 1, 1, &tmp) > 0) ax179_data->wol_supported = WAKE_MAGIC | WAKE_PHY; - ax88179_led_setting(dev); + /* For chips starting with AX88179A, LEDS are configured by the adapter + * firmware directly from EEPROM/EFUSE values + */ + if (ax179_data->chip_version < AX_VERSION_AX88179A) + ax88179_led_setting(dev); ax179_data->eee_enabled = 0; ax179_data->eee_active = 0;@@ -1706,6 +2507,24 @@ static int ax88179_stop(struct usbnet *dev) return 0; } +static int ax88179a_stop(struct usbnet *dev) +{ + u16 reg16; + u8 reg8; + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, ®16); + reg16 &= ~AX_MEDIUM_RECEIVE_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, ®16); + + reg16 = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, ®16); + + reg8 = 0; + ax88179_read_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, ®8); + + return 0; +} + static const struct driver_info ax88179_info = { .description = "ASIX AX88179 USB 3.0 Gigabit Ethernet", .bind = ax88179_bind,@@ -1732,6 +2551,45 @@ static const struct driver_info ax88178a_info = { .tx_fixup = ax88179_tx_fixup, }; +static const struct driver_info ax88179a_info = { + .description = "ASIX AX88179A USB 3.2 Gigabit Ethernet", + .bind = ax88179a_bind, + .unbind = ax88179a_unbind, + .status = ax88179_status, + .link_reset = ax88179a_link_reset, + .reset = ax88179_reset, + .stop = ax88179a_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET | FLAG_AVOID_UNLINK_URBS, + .rx_fixup = ax88179a_rx_fixup, + .tx_fixup = ax88179a_tx_fixup, +}; + +static const struct driver_info ax88772d_info = { + .description = "ASIX AX88772D/E USB 2.0 Fast Ethernet", + .bind = ax88179a_bind, + .unbind = ax88179a_unbind, + .status = ax88179_status, + .link_reset = ax88179a_link_reset, + .reset = ax88179_reset, + .stop = ax88179a_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET | FLAG_AVOID_UNLINK_URBS, + .rx_fixup = ax88179a_rx_fixup, + .tx_fixup = ax88179a_tx_fixup, +}; + +static const struct driver_info ax88279_info = { + .description = "ASIX AX88279 USB 3.2 2.5Gigabit Ethernet", + .bind = ax88179a_bind, + .unbind = ax88179a_unbind, + .status = ax88179_status, + .link_reset = ax88179a_link_reset, + .reset = ax88179_reset, + .stop = ax88179a_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET | FLAG_AVOID_UNLINK_URBS, + .rx_fixup = ax88179a_rx_fixup, + .tx_fixup = ax88179a_tx_fixup, +}; + static const struct driver_info cypress_GX3_info = { .description = "Cypress GX3 SuperSpeed to Gigabit Ethernet Controller", .bind = ax88179_bind,@@ -1877,6 +2735,18 @@ static const struct driver_info at_umc2000sp_info = { static const struct usb_device_id products[] = { { + /* ASIX AX88179A/B USB 3.2 Gigabit Ethernet */ + USB_DEVICE_VER(0x0b95, 0x1790, 0x0200, 0x0200), + .driver_info = (unsigned long)&ax88179a_info, +}, { + /* ASIX AX88772D USB 2.0 100Mbit Ethernet */ + USB_DEVICE_VER(0x0b95, 0x1790, 0x0300, 0x0300), + .driver_info = (unsigned long)&ax88772d_info, +}, { + /* ASIX AX88279 USB 3.2 2.5GBit Ethernet */ + USB_DEVICE_VER(0x0b95, 0x1790, 0x0400, 0x0400), + .driver_info = (unsigned long)&ax88279_info, +}, { /* ASIX AX88179 10/100/1000 */ USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0), .driver_info = (unsigned long)&ax88179_info,