]> git.dujemihanovic.xyz Git - linux.git/commitdiff
amd-xgbe: Separate C22 and C45 transactions
authorAndrew Lunn <andrew@lunn.ch>
Mon, 16 Jan 2023 23:52:23 +0000 (00:52 +0100)
committerJakub Kicinski <kuba@kernel.org>
Wed, 18 Jan 2023 03:34:08 +0000 (19:34 -0800)
The xgbe MDIO bus driver can perform both C22 and C45 transfers, when
using its MDIO bus hardware. The SFP I2C mdio bus driver only supports
C22. Create separate functions for each and register the C45 versions
using the new API calls where appropriate.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index e033d6c819f3d9997bba4f00b8fdeb6bcae8f429..13b30f81c49f03aec5b4307d92cfbe6fbbd0d13b 100644 (file)
@@ -1287,11 +1287,20 @@ static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
        }
 }
 
-static unsigned int xgbe_create_mdio_sca(int port, int reg)
+static unsigned int xgbe_create_mdio_sca_c22(int port, int reg)
 {
-       unsigned int mdio_sca, da;
+       unsigned int mdio_sca;
 
-       da = (reg & MII_ADDR_C45) ? reg >> 16 : 0;
+       mdio_sca = 0;
+       XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
+       XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, PA, port);
+
+       return mdio_sca;
+}
+
+static unsigned int xgbe_create_mdio_sca_c45(int port, unsigned int da, int reg)
+{
+       unsigned int mdio_sca;
 
        mdio_sca = 0;
        XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
@@ -1301,14 +1310,13 @@ static unsigned int xgbe_create_mdio_sca(int port, int reg)
        return mdio_sca;
 }
 
-static int xgbe_write_ext_mii_regs(struct xgbe_prv_data *pdata, int addr,
-                                  int reg, u16 val)
+static int xgbe_write_ext_mii_regs(struct xgbe_prv_data *pdata,
+                                  unsigned int mdio_sca, u16 val)
 {
-       unsigned int mdio_sca, mdio_sccd;
+       unsigned int mdio_sccd;
 
        reinit_completion(&pdata->mdio_complete);
 
-       mdio_sca = xgbe_create_mdio_sca(addr, reg);
        XGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
 
        mdio_sccd = 0;
@@ -1325,14 +1333,33 @@ static int xgbe_write_ext_mii_regs(struct xgbe_prv_data *pdata, int addr,
        return 0;
 }
 
-static int xgbe_read_ext_mii_regs(struct xgbe_prv_data *pdata, int addr,
-                                 int reg)
+static int xgbe_write_ext_mii_regs_c22(struct xgbe_prv_data *pdata, int addr,
+                                      int reg, u16 val)
+{
+       unsigned int mdio_sca;
+
+       mdio_sca = xgbe_create_mdio_sca_c22(addr, reg);
+
+       return xgbe_write_ext_mii_regs(pdata, mdio_sca, val);
+}
+
+static int xgbe_write_ext_mii_regs_c45(struct xgbe_prv_data *pdata, int addr,
+                                      int devad, int reg, u16 val)
+{
+       unsigned int mdio_sca;
+
+       mdio_sca = xgbe_create_mdio_sca_c45(addr, devad, reg);
+
+       return xgbe_write_ext_mii_regs(pdata, mdio_sca, val);
+}
+
+static int xgbe_read_ext_mii_regs(struct xgbe_prv_data *pdata,
+                                 unsigned int mdio_sca)
 {
-       unsigned int mdio_sca, mdio_sccd;
+       unsigned int mdio_sccd;
 
        reinit_completion(&pdata->mdio_complete);
 
-       mdio_sca = xgbe_create_mdio_sca(addr, reg);
        XGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
 
        mdio_sccd = 0;
@@ -1348,6 +1375,26 @@ static int xgbe_read_ext_mii_regs(struct xgbe_prv_data *pdata, int addr,
        return XGMAC_IOREAD_BITS(pdata, MAC_MDIOSCCDR, DATA);
 }
 
+static int xgbe_read_ext_mii_regs_c22(struct xgbe_prv_data *pdata, int addr,
+                                     int reg)
+{
+       unsigned int mdio_sca;
+
+       mdio_sca = xgbe_create_mdio_sca_c22(addr, reg);
+
+       return xgbe_read_ext_mii_regs(pdata, mdio_sca);
+}
+
+static int xgbe_read_ext_mii_regs_c45(struct xgbe_prv_data *pdata, int addr,
+                                     int devad, int reg)
+{
+       unsigned int mdio_sca;
+
+       mdio_sca = xgbe_create_mdio_sca_c45(addr, devad, reg);
+
+       return xgbe_read_ext_mii_regs(pdata, mdio_sca);
+}
+
 static int xgbe_set_ext_mii_mode(struct xgbe_prv_data *pdata, unsigned int port,
                                 enum xgbe_mdio_mode mode)
 {
@@ -3561,8 +3608,10 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
        hw_if->set_speed = xgbe_set_speed;
 
        hw_if->set_ext_mii_mode = xgbe_set_ext_mii_mode;
-       hw_if->read_ext_mii_regs = xgbe_read_ext_mii_regs;
-       hw_if->write_ext_mii_regs = xgbe_write_ext_mii_regs;
+       hw_if->read_ext_mii_regs_c22 = xgbe_read_ext_mii_regs_c22;
+       hw_if->write_ext_mii_regs_c22 = xgbe_write_ext_mii_regs_c22;
+       hw_if->read_ext_mii_regs_c45 = xgbe_read_ext_mii_regs_c45;
+       hw_if->write_ext_mii_regs_c45 = xgbe_write_ext_mii_regs_c45;
 
        hw_if->set_gpio = xgbe_set_gpio;
        hw_if->clr_gpio = xgbe_clr_gpio;
index de7118cb10b8e25ab1f53cfb7e4f88c81b9b03a9..f4683d53e58c0d457fd0595190ce963ae72be14d 100644 (file)
@@ -600,20 +600,27 @@ static int xgbe_phy_get_comm_ownership(struct xgbe_prv_data *pdata)
        return -ETIMEDOUT;
 }
 
-static int xgbe_phy_mdio_mii_write(struct xgbe_prv_data *pdata, int addr,
-                                  int reg, u16 val)
+static int xgbe_phy_mdio_mii_write_c22(struct xgbe_prv_data *pdata, int addr,
+                                      int reg, u16 val)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
 
-       if (reg & MII_ADDR_C45) {
-               if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45)
-                       return -ENOTSUPP;
-       } else {
-               if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22)
-                       return -ENOTSUPP;
-       }
+       if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22)
+               return -EOPNOTSUPP;
+
+       return pdata->hw_if.write_ext_mii_regs_c22(pdata, addr, reg, val);
+}
+
+static int xgbe_phy_mdio_mii_write_c45(struct xgbe_prv_data *pdata, int addr,
+                                      int devad, int reg, u16 val)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
 
-       return pdata->hw_if.write_ext_mii_regs(pdata, addr, reg, val);
+       if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45)
+               return -EOPNOTSUPP;
+
+       return pdata->hw_if.write_ext_mii_regs_c45(pdata, addr, devad,
+                                                  reg, val);
 }
 
 static int xgbe_phy_i2c_mii_write(struct xgbe_prv_data *pdata, int reg, u16 val)
@@ -638,7 +645,8 @@ static int xgbe_phy_i2c_mii_write(struct xgbe_prv_data *pdata, int reg, u16 val)
        return ret;
 }
 
-static int xgbe_phy_mii_write(struct mii_bus *mii, int addr, int reg, u16 val)
+static int xgbe_phy_mii_write_c22(struct mii_bus *mii, int addr, int reg,
+                                 u16 val)
 {
        struct xgbe_prv_data *pdata = mii->priv;
        struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -651,29 +659,58 @@ static int xgbe_phy_mii_write(struct mii_bus *mii, int addr, int reg, u16 val)
        if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
                ret = xgbe_phy_i2c_mii_write(pdata, reg, val);
        else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO)
-               ret = xgbe_phy_mdio_mii_write(pdata, addr, reg, val);
+               ret = xgbe_phy_mdio_mii_write_c22(pdata, addr, reg, val);
        else
-               ret = -ENOTSUPP;
+               ret = -EOPNOTSUPP;
 
        xgbe_phy_put_comm_ownership(pdata);
 
        return ret;
 }
 
-static int xgbe_phy_mdio_mii_read(struct xgbe_prv_data *pdata, int addr,
-                                 int reg)
+static int xgbe_phy_mii_write_c45(struct mii_bus *mii, int addr, int devad,
+                                 int reg, u16 val)
 {
+       struct xgbe_prv_data *pdata = mii->priv;
        struct xgbe_phy_data *phy_data = pdata->phy_data;
+       int ret;
 
-       if (reg & MII_ADDR_C45) {
-               if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45)
-                       return -ENOTSUPP;
-       } else {
-               if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22)
-                       return -ENOTSUPP;
-       }
+       ret = xgbe_phy_get_comm_ownership(pdata);
+       if (ret)
+               return ret;
 
-       return pdata->hw_if.read_ext_mii_regs(pdata, addr, reg);
+       if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
+               ret = -EOPNOTSUPP;
+       else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO)
+               ret = xgbe_phy_mdio_mii_write_c45(pdata, addr, devad, reg, val);
+       else
+               ret = -EOPNOTSUPP;
+
+       xgbe_phy_put_comm_ownership(pdata);
+
+       return ret;
+}
+
+static int xgbe_phy_mdio_mii_read_c22(struct xgbe_prv_data *pdata, int addr,
+                                     int reg)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22)
+               return -EOPNOTSUPP;
+
+       return pdata->hw_if.read_ext_mii_regs_c22(pdata, addr, reg);
+}
+
+static int xgbe_phy_mdio_mii_read_c45(struct xgbe_prv_data *pdata, int addr,
+                                     int devad, int reg)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45)
+               return -EOPNOTSUPP;
+
+       return pdata->hw_if.read_ext_mii_regs_c45(pdata, addr, devad, reg);
 }
 
 static int xgbe_phy_i2c_mii_read(struct xgbe_prv_data *pdata, int reg)
@@ -698,7 +735,7 @@ static int xgbe_phy_i2c_mii_read(struct xgbe_prv_data *pdata, int reg)
        return ret;
 }
 
-static int xgbe_phy_mii_read(struct mii_bus *mii, int addr, int reg)
+static int xgbe_phy_mii_read_c22(struct mii_bus *mii, int addr, int reg)
 {
        struct xgbe_prv_data *pdata = mii->priv;
        struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -711,7 +748,30 @@ static int xgbe_phy_mii_read(struct mii_bus *mii, int addr, int reg)
        if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
                ret = xgbe_phy_i2c_mii_read(pdata, reg);
        else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO)
-               ret = xgbe_phy_mdio_mii_read(pdata, addr, reg);
+               ret = xgbe_phy_mdio_mii_read_c22(pdata, addr, reg);
+       else
+               ret = -EOPNOTSUPP;
+
+       xgbe_phy_put_comm_ownership(pdata);
+
+       return ret;
+}
+
+static int xgbe_phy_mii_read_c45(struct mii_bus *mii, int addr, int devad,
+                                int reg)
+{
+       struct xgbe_prv_data *pdata = mii->priv;
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+       int ret;
+
+       ret = xgbe_phy_get_comm_ownership(pdata);
+       if (ret)
+               return ret;
+
+       if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
+               ret = -EOPNOTSUPP;
+       else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO)
+               ret = xgbe_phy_mdio_mii_read_c45(pdata, addr, devad, reg);
        else
                ret = -ENOTSUPP;
 
@@ -1929,8 +1989,8 @@ static int xgbe_phy_set_redrv_mode_mdio(struct xgbe_prv_data *pdata,
        redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
        redrv_val = (u16)mode;
 
-       return pdata->hw_if.write_ext_mii_regs(pdata, phy_data->redrv_addr,
-                                              redrv_reg, redrv_val);
+       return pdata->hw_if.write_ext_mii_regs_c22(pdata, phy_data->redrv_addr,
+                                                  redrv_reg, redrv_val);
 }
 
 static int xgbe_phy_set_redrv_mode_i2c(struct xgbe_prv_data *pdata,
@@ -3502,8 +3562,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 
        mii->priv = pdata;
        mii->name = "amd-xgbe-mii";
-       mii->read = xgbe_phy_mii_read;
-       mii->write = xgbe_phy_mii_write;
+       mii->read = xgbe_phy_mii_read_c22;
+       mii->write = xgbe_phy_mii_write_c22;
+       mii->read_c45 = xgbe_phy_mii_read_c45;
+       mii->write_c45 = xgbe_phy_mii_write_c45;
        mii->parent = pdata->dev;
        mii->phy_mask = ~0;
        snprintf(mii->id, sizeof(mii->id), "%s", dev_name(pdata->dev));
index da37476a28486a9cb455d8b8fc229f6ba7147793..a1b8755df84cee1deb1861946b7bbeeff1894e82 100644 (file)
@@ -775,8 +775,11 @@ struct xgbe_hw_if {
 
        int (*set_ext_mii_mode)(struct xgbe_prv_data *, unsigned int,
                                enum xgbe_mdio_mode);
-       int (*read_ext_mii_regs)(struct xgbe_prv_data *, int, int);
-       int (*write_ext_mii_regs)(struct xgbe_prv_data *, int, int, u16);
+       int (*read_ext_mii_regs_c22)(struct xgbe_prv_data *, int, int);
+       int (*write_ext_mii_regs_c22)(struct xgbe_prv_data *, int, int, u16);
+       int (*read_ext_mii_regs_c45)(struct xgbe_prv_data *, int, int, int);
+       int (*write_ext_mii_regs_c45)(struct xgbe_prv_data *, int, int, int,
+                                     u16);
 
        int (*set_gpio)(struct xgbe_prv_data *, unsigned int);
        int (*clr_gpio)(struct xgbe_prv_data *, unsigned int);