net: sxgbe: Separate C22 and C45 transactions
authorAndrew Lunn <andrew@lunn.ch>
Mon, 16 Jan 2023 23:52:17 +0000 (00:52 +0100)
committerJakub Kicinski <kuba@kernel.org>
Wed, 18 Jan 2023 03:34:08 +0000 (19:34 -0800)
The sxgdb MDIO bus driver can perform both C22 and C45 transfers.
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/samsung/sxgbe/sxgbe_mdio.c

index fceb6d63723521083f77cff79d0799ef76dbd2e5..0227223c06fa79cbd4d7b4a7b331264ba8d79b84 100644 (file)
@@ -50,12 +50,12 @@ static void sxgbe_mdio_ctrl_data(struct sxgbe_priv_data *sp, u32 cmd,
 }
 
 static void sxgbe_mdio_c45(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
-                          int phyreg, u16 phydata)
+                          int devad, int phyreg, u16 phydata)
 {
        u32 reg;
 
        /* set mdio address register */
-       reg = ((phyreg >> 16) & 0x1f) << 21;
+       reg = (devad & 0x1f) << 21;
        reg |= (phyaddr << 16) | (phyreg & 0xffff);
        writel(reg, sp->ioaddr + sp->hw->mii.addr);
 
@@ -76,8 +76,8 @@ static void sxgbe_mdio_c22(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
        sxgbe_mdio_ctrl_data(sp, cmd, phydata);
 }
 
-static int sxgbe_mdio_access(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
-                            int phyreg, u16 phydata)
+static int sxgbe_mdio_access_c22(struct sxgbe_priv_data *sp, u32 cmd,
+                                int phyaddr, int phyreg, u16 phydata)
 {
        const struct mii_regs *mii = &sp->hw->mii;
        int rc;
@@ -86,33 +86,46 @@ static int sxgbe_mdio_access(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
        if (rc < 0)
                return rc;
 
-       if (phyreg & MII_ADDR_C45) {
-               sxgbe_mdio_c45(sp, cmd, phyaddr, phyreg, phydata);
-       } else {
-                /* Ports 0-3 only support C22. */
-               if (phyaddr >= 4)
-                       return -ENODEV;
+       /* Ports 0-3 only support C22. */
+       if (phyaddr >= 4)
+               return -ENODEV;
 
-               sxgbe_mdio_c22(sp, cmd, phyaddr, phyreg, phydata);
-       }
+       sxgbe_mdio_c22(sp, cmd, phyaddr, phyreg, phydata);
+
+       return sxgbe_mdio_busy_wait(sp->ioaddr, mii->data);
+}
+
+static int sxgbe_mdio_access_c45(struct sxgbe_priv_data *sp, u32 cmd,
+                                int phyaddr, int devad, int phyreg,
+                                u16 phydata)
+{
+       const struct mii_regs *mii = &sp->hw->mii;
+       int rc;
+
+       rc = sxgbe_mdio_busy_wait(sp->ioaddr, mii->data);
+       if (rc < 0)
+               return rc;
+
+       sxgbe_mdio_c45(sp, cmd, phyaddr, devad, phyreg, phydata);
 
        return sxgbe_mdio_busy_wait(sp->ioaddr, mii->data);
 }
 
 /**
- * sxgbe_mdio_read
+ * sxgbe_mdio_read_c22
  * @bus: points to the mii_bus structure
  * @phyaddr: address of phy port
  * @phyreg: address of register with in phy register
- * Description: this function used for C45 and C22 MDIO Read
+ * Description: this function used for C22 MDIO Read
  */
-static int sxgbe_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+static int sxgbe_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg)
 {
        struct net_device *ndev = bus->priv;
        struct sxgbe_priv_data *priv = netdev_priv(ndev);
        int rc;
 
-       rc = sxgbe_mdio_access(priv, SXGBE_SMA_READ_CMD, phyaddr, phyreg, 0);
+       rc = sxgbe_mdio_access_c22(priv, SXGBE_SMA_READ_CMD, phyaddr,
+                                  phyreg, 0);
        if (rc < 0)
                return rc;
 
@@ -120,21 +133,63 @@ static int sxgbe_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
 }
 
 /**
- * sxgbe_mdio_write
+ * sxgbe_mdio_read_c45
+ * @bus: points to the mii_bus structure
+ * @phyaddr: address of phy port
+ * @devad: device (MMD) address
+ * @phyreg: address of register with in phy register
+ * Description: this function used for C45 MDIO Read
+ */
+static int sxgbe_mdio_read_c45(struct mii_bus *bus, int phyaddr, int devad,
+                              int phyreg)
+{
+       struct net_device *ndev = bus->priv;
+       struct sxgbe_priv_data *priv = netdev_priv(ndev);
+       int rc;
+
+       rc = sxgbe_mdio_access_c45(priv, SXGBE_SMA_READ_CMD, phyaddr,
+                                  devad, phyreg, 0);
+       if (rc < 0)
+               return rc;
+
+       return readl(priv->ioaddr + priv->hw->mii.data) & 0xffff;
+}
+
+/**
+ * sxgbe_mdio_write_c22
+ * @bus: points to the mii_bus structure
+ * @phyaddr: address of phy port
+ * @phyreg: address of phy registers
+ * @phydata: data to be written into phy register
+ * Description: this function is used for C22 MDIO write
+ */
+static int sxgbe_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg,
+                               u16 phydata)
+{
+       struct net_device *ndev = bus->priv;
+       struct sxgbe_priv_data *priv = netdev_priv(ndev);
+
+       return sxgbe_mdio_access_c22(priv, SXGBE_SMA_WRITE_CMD, phyaddr, phyreg,
+                                    phydata);
+}
+
+/**
+ * sxgbe_mdio_write_c45
  * @bus: points to the mii_bus structure
  * @phyaddr: address of phy port
  * @phyreg: address of phy registers
+ * @devad: device (MMD) address
  * @phydata: data to be written into phy register
- * Description: this function is used for C45 and C22 MDIO write
+ * Description: this function is used for C45 MDIO write
  */
-static int sxgbe_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
-                            u16 phydata)
+static int sxgbe_mdio_write_c45(struct mii_bus *bus, int phyaddr, int devad,
+                               int phyreg, u16 phydata)
 {
        struct net_device *ndev = bus->priv;
        struct sxgbe_priv_data *priv = netdev_priv(ndev);
 
-       return sxgbe_mdio_access(priv, SXGBE_SMA_WRITE_CMD, phyaddr, phyreg,
-                                phydata);
+       return sxgbe_mdio_access_c45(priv, SXGBE_SMA_WRITE_CMD, phyaddr,
+                                    devad, phyreg, phydata);
 }
 
 int sxgbe_mdio_register(struct net_device *ndev)
@@ -161,8 +216,10 @@ int sxgbe_mdio_register(struct net_device *ndev)
 
        /* assign mii bus fields */
        mdio_bus->name = "sxgbe";
-       mdio_bus->read = &sxgbe_mdio_read;
-       mdio_bus->write = &sxgbe_mdio_write;
+       mdio_bus->read = sxgbe_mdio_read_c22;
+       mdio_bus->write = sxgbe_mdio_write_c22;
+       mdio_bus->read_c45 = sxgbe_mdio_read_c45;
+       mdio_bus->write_c45 = sxgbe_mdio_write_c45;
        snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x",
                 mdio_bus->name, priv->plat->bus_id);
        mdio_bus->priv = ndev;