net: lan743x: Add support for Clause-45 MDIO PHY management
authorRaju Lakkaraju <Raju.Lakkaraju@microchip.com>
Sat, 12 Feb 2022 15:53:15 +0000 (21:23 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sun, 13 Feb 2022 12:07:26 +0000 (12:07 +0000)
Add support for Clause-45 MDIO PHY management

Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/microchip/lan743x_main.h

index 8b0890aa66fa5d8a4a6438720c6ce4007c5bfbcf..5282d25a6f9b8e6c407bb167795153d8fc188e66 100644 (file)
 #include "lan743x_main.h"
 #include "lan743x_ethtool.h"
 
+#define MMD_ACCESS_ADDRESS     0
+#define MMD_ACCESS_WRITE       1
+#define MMD_ACCESS_READ                2
+#define MMD_ACCESS_READ_INC    3
+
 static void pci11x1x_strap_get_status(struct lan743x_adapter *adapter)
 {
        u32 chip_rev;
@@ -814,6 +819,96 @@ static int lan743x_mdiobus_write(struct mii_bus *bus,
        return ret;
 }
 
+static u32 lan743x_mac_mmd_access(int id, int index, int op)
+{
+       u16 dev_addr;
+       u32 ret;
+
+       dev_addr = (index >> 16) & 0x1f;
+       ret = (id << MAC_MII_ACC_PHY_ADDR_SHIFT_) &
+               MAC_MII_ACC_PHY_ADDR_MASK_;
+       ret |= (dev_addr << MAC_MII_ACC_MIIMMD_SHIFT_) &
+               MAC_MII_ACC_MIIMMD_MASK_;
+       if (op == MMD_ACCESS_WRITE)
+               ret |= MAC_MII_ACC_MIICMD_WRITE_;
+       else if (op == MMD_ACCESS_READ)
+               ret |= MAC_MII_ACC_MIICMD_READ_;
+       else if (op == MMD_ACCESS_READ_INC)
+               ret |= MAC_MII_ACC_MIICMD_READ_INC_;
+       else
+               ret |= MAC_MII_ACC_MIICMD_ADDR_;
+       ret |= (MAC_MII_ACC_MII_BUSY_ | MAC_MII_ACC_MIICL45_);
+
+       return ret;
+}
+
+static int lan743x_mdiobus_c45_read(struct mii_bus *bus, int phy_id, int index)
+{
+       struct lan743x_adapter *adapter = bus->priv;
+       u32 mmd_access;
+       int ret;
+
+       /* comfirm MII not busy */
+       ret = lan743x_mac_mii_wait_till_not_busy(adapter);
+       if (ret < 0)
+               return ret;
+       if (index & MII_ADDR_C45) {
+               /* Load Register Address */
+               lan743x_csr_write(adapter, MAC_MII_DATA, (u32)(index & 0xffff));
+               mmd_access = lan743x_mac_mmd_access(phy_id, index,
+                                                   MMD_ACCESS_ADDRESS);
+               lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
+               ret = lan743x_mac_mii_wait_till_not_busy(adapter);
+               if (ret < 0)
+                       return ret;
+               /* Read Data */
+               mmd_access = lan743x_mac_mmd_access(phy_id, index,
+                                                   MMD_ACCESS_READ);
+               lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
+               ret = lan743x_mac_mii_wait_till_not_busy(adapter);
+               if (ret < 0)
+                       return ret;
+               ret = lan743x_csr_read(adapter, MAC_MII_DATA);
+               return (int)(ret & 0xFFFF);
+       }
+
+       ret = lan743x_mdiobus_read(bus, phy_id, index);
+       return ret;
+}
+
+static int lan743x_mdiobus_c45_write(struct mii_bus *bus,
+                                    int phy_id, int index, u16 regval)
+{
+       struct lan743x_adapter *adapter = bus->priv;
+       u32 mmd_access;
+       int ret;
+
+       /* confirm MII not busy */
+       ret = lan743x_mac_mii_wait_till_not_busy(adapter);
+       if (ret < 0)
+               return ret;
+       if (index & MII_ADDR_C45) {
+               /* Load Register Address */
+               lan743x_csr_write(adapter, MAC_MII_DATA, (u32)(index & 0xffff));
+               mmd_access = lan743x_mac_mmd_access(phy_id, index,
+                                                   MMD_ACCESS_ADDRESS);
+               lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
+               ret = lan743x_mac_mii_wait_till_not_busy(adapter);
+               if (ret < 0)
+                       return ret;
+               /* Write Data */
+               lan743x_csr_write(adapter, MAC_MII_DATA, (u32)regval);
+               mmd_access = lan743x_mac_mmd_access(phy_id, index,
+                                                   MMD_ACCESS_WRITE);
+               lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
+               ret = lan743x_mac_mii_wait_till_not_busy(adapter);
+       } else {
+               ret = lan743x_mdiobus_write(bus, phy_id, index, regval);
+       }
+
+       return ret;
+}
+
 static void lan743x_mac_set_address(struct lan743x_adapter *adapter,
                                    u8 *addr)
 {
@@ -2847,11 +2942,19 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter)
                        netif_dbg(adapter, drv, adapter->netdev,
                                          "(R)GMII operation\n");
                }
+
+               adapter->mdiobus->probe_capabilities = MDIOBUS_C22_C45;
+               adapter->mdiobus->read = lan743x_mdiobus_c45_read;
+               adapter->mdiobus->write = lan743x_mdiobus_c45_write;
+               adapter->mdiobus->name = "lan743x-mdiobus-c45";
+               netif_dbg(adapter, drv, adapter->netdev, "lan743x-mdiobus-c45\n");
+       } else {
+               adapter->mdiobus->read = lan743x_mdiobus_read;
+               adapter->mdiobus->write = lan743x_mdiobus_write;
+               adapter->mdiobus->name = "lan743x-mdiobus";
+               netif_dbg(adapter, drv, adapter->netdev, "lan743x-mdiobus\n");
        }
 
-       adapter->mdiobus->read = lan743x_mdiobus_read;
-       adapter->mdiobus->write = lan743x_mdiobus_write;
-       adapter->mdiobus->name = "lan743x-mdiobus";
        snprintf(adapter->mdiobus->id, MII_BUS_ID_SIZE,
                 "pci-%s", pci_name(adapter->pdev));
 
index 7c387ca2d25c9feb726fb4c5da99322fee5d0082..2c8e76b4e1f79ffdb3aa09fd7aefcbf951a32bef 100644 (file)
 #define MAC_RX_ADDRL                   (0x11C)
 
 #define MAC_MII_ACC                    (0x120)
+#define MAC_MII_ACC_MDC_CYCLE_SHIFT_   (16)
+#define MAC_MII_ACC_MDC_CYCLE_MASK_    (0x00070000)
+#define MAC_MII_ACC_MDC_CYCLE_2_5MHZ_  (0)
+#define MAC_MII_ACC_MDC_CYCLE_5MHZ_    (1)
+#define MAC_MII_ACC_MDC_CYCLE_12_5MHZ_ (2)
+#define MAC_MII_ACC_MDC_CYCLE_25MHZ_   (3)
+#define MAC_MII_ACC_MDC_CYCLE_1_25MHZ_ (4)
 #define MAC_MII_ACC_PHY_ADDR_SHIFT_    (11)
 #define MAC_MII_ACC_PHY_ADDR_MASK_     (0x0000F800)
 #define MAC_MII_ACC_MIIRINDA_SHIFT_    (6)
 #define MAC_MII_ACC_MII_WRITE_         (0x00000002)
 #define MAC_MII_ACC_MII_BUSY_          BIT(0)
 
+#define MAC_MII_ACC_MIIMMD_SHIFT_      (6)
+#define MAC_MII_ACC_MIIMMD_MASK_       (0x000007C0)
+#define MAC_MII_ACC_MIICL45_           BIT(3)
+#define MAC_MII_ACC_MIICMD_MASK_       (0x00000006)
+#define MAC_MII_ACC_MIICMD_ADDR_       (0x00000000)
+#define MAC_MII_ACC_MIICMD_WRITE_      (0x00000002)
+#define MAC_MII_ACC_MIICMD_READ_       (0x00000004)
+#define MAC_MII_ACC_MIICMD_READ_INC_   (0x00000006)
+
 #define MAC_MII_DATA                   (0x124)
 
 #define MAC_EEE_TX_LPI_REQ_DLY_CNT             (0x130)