Currently, clause-22 format is supported. This change adds
support for clause-45 format.

Signed-off-by: Nikunj Kela <nikunj.k...@sima.ai>
Reviewed-by: Boon Khai Ng <boon.khai...@altera.com>
Tested-by: Boon Khai Ng <boon.khai...@altera.com>
---
Changes in v3:
        - replaced tab with space

Changes in v2:
        - Created separate function for configuring clause format

[2]: 
https://patchwork.ozlabs.org/project/uboot/patch/20250828225532.1147284-1-nikunj.k...@sima.ai/
[1]: 
https://patchwork.ozlabs.org/project/uboot/patch/20250510041200.2552981-1-nikunj.k...@sima.ai/
---
 drivers/net/dwc_eth_xgmac.c | 60 ++++++++++++++++++++++++-------------
 drivers/net/dwc_eth_xgmac.h |  1 +
 2 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/drivers/net/dwc_eth_xgmac.c b/drivers/net/dwc_eth_xgmac.c
index d29d871ea8c..458b87af7a2 100644
--- a/drivers/net/dwc_eth_xgmac.c
+++ b/drivers/net/dwc_eth_xgmac.c
@@ -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);
diff --git a/drivers/net/dwc_eth_xgmac.h b/drivers/net/dwc_eth_xgmac.h
index 259f815f3f2..90c2e22997c 100644
--- a/drivers/net/dwc_eth_xgmac.h
+++ b/drivers/net/dwc_eth_xgmac.h
@@ -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 */
 
-- 
2.34.1

Reply via email to