[PATCH net-next v2 03/12] ax88179_178a: Add MMD accessor function for AX88179A

From: Birger Koblitz

Date: Wed Jul 08 2026 - 14:42:08 EST


The AX88179A uses a much simpler Clause-45 MMD access interface,
make use of this interface and abstract MMD read/write operations
for the AX88179 and AX88179A architecture by introducing
ax_read_mmd() and ax_write_mmd(), which in turn call the chips'
respective implementation.

Signed-off-by: Birger Koblitz <mail@xxxxxxxxxxxxxxxxx>
---
drivers/net/usb/ax88179_178a.c | 66 ++++++++++++++++++++++++------------------
1 file changed, 38 insertions(+), 28 deletions(-)

diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 3aad69b5d4f8ad43527fa7cf51304af9a926ea78..c483b7b636e37d45455d46e1b0354fd63e0ef100 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -37,6 +37,7 @@
#define AX_FW_MODE 0x08
#define AX88179A_FLASH_READ 0x21
#define AX88179A_FLASH_WRITE 0x24
+#define AX88179A_PHY_CLAUSE45 0x27
#define AX88179A_ACCESS_BL 0x2A
#define AX88179A_PHY_POWER 0x31
#define AX88179A_AUTODETACH 0xC0
@@ -575,6 +576,32 @@ ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad,
return 0;
}

+static int ax_read_mmd(struct usbnet *dev, u16 dev_addr, u16 reg)
+{
+ struct ax88179_data *priv = dev->driver_priv;
+ u16 res;
+ int ret;
+
+ if (priv->chip_version >= AX_VERSION_AX88179A) {
+ ret = ax88179_read_cmd(dev, AX88179A_PHY_CLAUSE45, dev_addr, reg, 2, &res);
+ if (ret < 0)
+ return ret;
+ return res;
+ }
+
+ return ax88179_phy_read_mmd_indirect(dev, reg, dev_addr);
+}
+
+static int ax_write_mmd(struct usbnet *dev, u16 dev_addr, u16 reg, u16 data)
+{
+ struct ax88179_data *priv = dev->driver_priv;
+
+ if (priv->chip_version >= AX_VERSION_AX88179A)
+ return ax88179_write_cmd(dev, AX88179A_PHY_CLAUSE45, dev_addr, reg, 2, &data);
+
+ return ax88179_phy_write_mmd_indirect(dev, reg, dev_addr, data);
+}
+
static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
@@ -892,22 +919,19 @@ ax88179_ethtool_get_eee(struct usbnet *dev, struct ethtool_keee *data)
int val;

/* Get Supported EEE */
- val = ax88179_phy_read_mmd_indirect(dev, MDIO_PCS_EEE_ABLE,
- MDIO_MMD_PCS);
+ val = ax_read_mmd(dev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
if (val < 0)
return val;
mii_eee_cap1_mod_linkmode_t(data->supported, val);

/* Get advertisement EEE */
- val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_ADV,
- MDIO_MMD_AN);
+ val = ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
if (val < 0)
return val;
mii_eee_cap1_mod_linkmode_t(data->advertised, val);

/* Get LP advertisement EEE */
- val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_LPABLE,
- MDIO_MMD_AN);
+ val = ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
if (val < 0)
return val;
mii_eee_cap1_mod_linkmode_t(data->lp_advertised, val);
@@ -920,8 +944,7 @@ ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_keee *data)
{
u16 tmp16 = linkmode_to_mii_eee_cap1_t(data->advertised);

- return ax88179_phy_write_mmd_indirect(dev, MDIO_AN_EEE_ADV,
- MDIO_MMD_AN, tmp16);
+ return ax_write_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tmp16);
}

static int ax88179_chk_eee(struct usbnet *dev)
@@ -935,32 +958,19 @@ static int ax88179_chk_eee(struct usbnet *dev)
int eee_lp, eee_cap, eee_adv;
u32 lp, cap, adv, supported = 0;

- eee_cap = ax88179_phy_read_mmd_indirect(dev,
- MDIO_PCS_EEE_ABLE,
- MDIO_MMD_PCS);
- if (eee_cap < 0) {
- priv->eee_active = 0;
+ eee_cap = ax_read_mmd(dev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
+ if (eee_cap < 0)
return false;
- }

cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
- if (!cap) {
- priv->eee_active = 0;
- return false;
- }
-
- eee_lp = ax88179_phy_read_mmd_indirect(dev,
- MDIO_AN_EEE_LPABLE,
- MDIO_MMD_AN);
- if (eee_lp < 0) {
- priv->eee_active = 0;
+ if (!cap)
return false;
- }

- eee_adv = ax88179_phy_read_mmd_indirect(dev,
- MDIO_AN_EEE_ADV,
- MDIO_MMD_AN);
+ eee_lp = ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
+ if (eee_lp < 0)
+ return true;

+ eee_adv = ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
if (eee_adv < 0) {
priv->eee_active = 0;
return false;

--
2.47.3