net: xgmac: Augment mdio read/write with cl-45 format support
authorNikunj Kela <nikunj.kela@sima.ai>
Fri, 29 Aug 2025 04:12:32 +0000 (21:12 -0700)
committerTien Fong Chee <tien.fong.chee@intel.com>
Mon, 1 Dec 2025 05:54:04 +0000 (13:54 +0800)
Currently, clause-22 format is supported. This change adds
support for clause-45 format.

Signed-off-by: Nikunj Kela <nikunj.kela@sima.ai>
Reviewed-by: Boon Khai Ng <boon.khai.ng@altera.com>
Tested-by: Boon Khai Ng <boon.khai.ng@altera.com>
Reviewed-by: Boon Khai Ng <boon.khai.ng@altera.com>
Tested-by: Boon Khai Ng <boon.khai.ng@altera.com>
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
drivers/net/dwc_eth_xgmac.c
drivers/net/dwc_eth_xgmac.h

index d29d871..458b87a 100644 (file)
@@ -140,9 +140,34 @@ static int xgmac_mdio_wait_idle(struct xgmac_priv *xgmac)
                                 XGMAC_TIMEOUT_100MS, true);
 }
 
+static u32 xgmac_set_clause(struct xgmac_priv *xgmac, int mdio_addr, int mdio_devad,
+                           int mdio_reg, bool is_c45)
+{
+       u32 hw_addr;
+       u32 val;
+
+       if (is_c45) {
+               val = readl(&xgmac->mac_regs->mdio_clause_22_port);
+               val &= ~BIT(mdio_addr);
+               writel(val, &xgmac->mac_regs->mdio_clause_22_port);
+               hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
+                          (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C45P_MASK);
+               hw_addr |= mdio_devad << XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+       } else {
+               /* Set clause 22 format */
+               val = BIT(mdio_addr);
+               writel(val, &xgmac->mac_regs->mdio_clause_22_port);
+               hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
+                          (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
+       }
+
+       return hw_addr;
+}
+
 static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                           int mdio_reg)
 {
+       bool is_c45 = (mdio_devad != MDIO_DEVAD_NONE);
        struct xgmac_priv *xgmac = bus->priv;
        u32 val;
        u32 hw_addr;
@@ -159,19 +184,16 @@ static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                return ret;
        }
 
-       /* Set clause 22 format */
-       val = BIT(mdio_addr);
-       writel(val, &xgmac->mac_regs->mdio_clause_22_port);
-
-       hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
-                  (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
+       hw_addr = xgmac_set_clause(xgmac, mdio_addr, mdio_devad, mdio_reg, is_c45);
 
        val = xgmac->config->config_mac_mdio <<
              XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT;
 
-       val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
-              XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ |
-              XGMAC_MAC_MDIO_ADDRESS_SBUSY;
+       if (!is_c45)
+               val |= XGMAC_MAC_MDIO_ADDRESS_SADDR;
+
+       val |= XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ |
+               XGMAC_MAC_MDIO_ADDRESS_SBUSY;
 
        ret = xgmac_mdio_wait_idle(xgmac);
        if (ret) {
@@ -203,6 +225,7 @@ static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
 static int xgmac_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                            int mdio_reg, u16 mdio_val)
 {
+       bool is_c45 = (mdio_devad != MDIO_DEVAD_NONE);
        struct xgmac_priv *xgmac = bus->priv;
        u32 val;
        u32 hw_addr;
@@ -219,21 +242,18 @@ static int xgmac_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                return ret;
        }
 
-       /* Set clause 22 format */
-       val = BIT(mdio_addr);
-       writel(val, &xgmac->mac_regs->mdio_clause_22_port);
-
-       hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
-                  (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
-
-       hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) <<
-                   XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+       hw_addr = xgmac_set_clause(xgmac, mdio_addr, mdio_devad, mdio_reg, is_c45);
 
        val = (xgmac->config->config_mac_mdio <<
               XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT);
 
-       val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
-               mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE |
+       if (!is_c45) {
+               hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) <<
+                           XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+               val |= XGMAC_MAC_MDIO_ADDRESS_SADDR;
+       }
+
+       val |= mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE |
                XGMAC_MAC_MDIO_ADDRESS_SBUSY;
 
        ret = xgmac_mdio_wait_idle(xgmac);
index 259f815..90c2e22 100644 (file)
@@ -109,6 +109,7 @@ struct xgmac_mac_regs {
 #define XGMAC_MAC_MDIO_ADDRESS_SBUSY           BIT(22)
 #define XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK      GENMASK(4, 0)
 #define XGMAC_MAC_MDIO_DATA_GD_MASK            GENMASK(15, 0)
+#define XGMAC_MAC_MDIO_REG_ADDR_C45P_MASK      GENMASK(15, 0)
 
 /* MTL Registers */