diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 57f2137bbe9d9..c67171975d5c7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -35,6 +35,7 @@ #define DWMAC_CORE_5_10 0x51 #define DWMAC_CORE_5_20 0x52 #define DWXGMAC_CORE_2_10 0x21 +#define DWXGMAC_CORE_2_20 0x22 #define DWXLGMAC_CORE_2_00 0x20 /* Device ID */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 3db1cb0fd160c..dd9e2fec53281 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -62,11 +62,16 @@ static void stmmac_xgmac2_c45_format(struct stmmac_priv *priv, int phyaddr, static void stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr, int phyreg, u32 *hw_addr) { - u32 tmp; + u32 tmp = 0; + if (priv->synopsys_id < DWXGMAC_CORE_2_20) { + /* Until ver 2.20 XGMAC does not support C22 addr >= 4. Those + * bits above bit 3 of XGMAC_MDIO_C22P register are reserved. + */ + tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P); + tmp &= ~MII_XGMAC_C22P_MASK; + } /* Set port as Clause 22 */ - tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P); - tmp &= ~MII_XGMAC_C22P_MASK; tmp |= BIT(phyaddr); writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P); @@ -132,8 +137,9 @@ static int stmmac_xgmac2_mdio_read_c22(struct mii_bus *bus, int phyaddr, priv = netdev_priv(ndev); - /* HW does not support C22 addr >= 4 */ - if (phyaddr > MII_XGMAC_MAX_C22ADDR) + /* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ + if (priv->synopsys_id < DWXGMAC_CORE_2_20 && + phyaddr > MII_XGMAC_MAX_C22ADDR) return -ENODEV; stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); @@ -209,8 +215,9 @@ static int stmmac_xgmac2_mdio_write_c22(struct mii_bus *bus, int phyaddr, priv = netdev_priv(ndev); - /* HW does not support C22 addr >= 4 */ - if (phyaddr > MII_XGMAC_MAX_C22ADDR) + /* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ + if (priv->synopsys_id < DWXGMAC_CORE_2_20 && + phyaddr > MII_XGMAC_MAX_C22ADDR) return -ENODEV; stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); @@ -551,13 +558,18 @@ int stmmac_mdio_register(struct net_device *ndev) new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45; new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45; - /* Right now only C22 phys are supported */ - max_addr = MII_XGMAC_MAX_C22ADDR + 1; + if (priv->synopsys_id < DWXGMAC_CORE_2_20) { + /* Right now only C22 phys are supported */ + max_addr = MII_XGMAC_MAX_C22ADDR + 1; - /* Check if DT specified an unsupported phy addr */ - if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR) - dev_err(dev, "Unsupported phy_addr (max=%d)\n", + /* Check if DT specified an unsupported phy addr */ + if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR) + dev_err(dev, "Unsupported phy_addr (max=%d)\n", MII_XGMAC_MAX_C22ADDR); + } else { + /* XGMAC version 2.20 onwards support 32 phy addr */ + max_addr = PHY_MAX_ADDR; + } } else { new_bus->read = &stmmac_mdio_read_c22; new_bus->write = &stmmac_mdio_write_c22;