net: phy: LAN87xx: add ethtool SQI support
authorArun Ramadoss <arun.ramadoss@microchip.com>
Wed, 20 Apr 2022 15:20:15 +0000 (20:50 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 22 Apr 2022 23:30:04 +0000 (16:30 -0700)
This patch add the support for measuring Signal Quality Index for
LAN87xx and LAN937x T1 Phy. It uses the SQI Method 5 for obtaining the
values.

Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/microchip_t1.c

index c2c0e36..796fbcb 100644 (file)
 #define T1_POST_LCK_MUFACT_CFG_REG     0x1C
 #define T1_TX_RX_FIFO_CFG_REG          0x02
 #define T1_TX_LPF_FIR_CFG_REG          0x55
+#define T1_COEF_CLK_PWR_DN_CFG         0x04
+#define T1_COEF_RW_CTL_CFG             0x0D
 #define T1_SQI_CONFIG_REG              0x2E
+#define T1_SQI_CONFIG2_REG             0x4A
+#define T1_DCQ_SQI_REG                 0xC3
+#define T1_DCQ_SQI_MSK                 GENMASK(3, 1)
 #define T1_MDIO_CONTROL2_REG           0x10
 #define T1_INTERRUPT_SOURCE_REG                0x18
 #define T1_INTERRUPT2_SOURCE_REG       0x08
@@ -82,6 +87,9 @@
 #define T1_MODE_STAT_REG               0x11
 #define T1_LINK_UP_MSK                 BIT(0)
 
+/* SQI defines */
+#define LAN87XX_MAX_SQI                        0x07
+
 #define DRIVER_AUTHOR  "Nisar Sayed <nisar.sayed@microchip.com>"
 #define DRIVER_DESC    "Microchip LAN87XX/LAN937x T1 PHY driver"
 
@@ -346,9 +354,20 @@ static int lan87xx_phy_init(struct phy_device *phydev)
                  T1_TX_LPF_FIR_CFG_REG, 0x1011, 0 },
                { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
                  T1_TX_LPF_FIR_CFG_REG, 0x1000, 0 },
+               /* Setup SQI measurement */
+               { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
+                 T1_COEF_CLK_PWR_DN_CFG,       0x16d6, 0 },
                /* SQI enable */
                { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
                  T1_SQI_CONFIG_REG,            0x9572, 0 },
+               /* SQI select mode 5 */
+               { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
+                 T1_SQI_CONFIG2_REG,           0x0001, 0 },
+               /* Throws the first SQI reading */
+               { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
+                 T1_COEF_RW_CTL_CFG,           0x0301, 0 },
+               { PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_DSP,
+                 T1_DCQ_SQI_REG,               0,      0 },
                /* Flag LPS and WUR as idle errors */
                { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI,
                  T1_MDIO_CONTROL2_REG,         0x0014, 0 },
@@ -724,6 +743,31 @@ static int lan87xx_config_aneg(struct phy_device *phydev)
        return phy_modify_changed(phydev, MII_CTRL1000, CTL1000_AS_MASTER, ctl);
 }
 
+static int lan87xx_get_sqi(struct phy_device *phydev)
+{
+       u8 sqi_value = 0;
+       int rc;
+
+       rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
+                        PHYACC_ATTR_BANK_DSP, T1_COEF_RW_CTL_CFG, 0x0301);
+       if (rc < 0)
+               return rc;
+
+       rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
+                        PHYACC_ATTR_BANK_DSP, T1_DCQ_SQI_REG, 0x0);
+       if (rc < 0)
+               return rc;
+
+       sqi_value = FIELD_GET(T1_DCQ_SQI_MSK, rc);
+
+       return sqi_value;
+}
+
+static int lan87xx_get_sqi_max(struct phy_device *phydev)
+{
+       return LAN87XX_MAX_SQI;
+}
+
 static struct phy_driver microchip_t1_phy_driver[] = {
        {
                PHY_ID_MATCH_MODEL(PHY_ID_LAN87XX),
@@ -737,6 +781,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
                .resume         = genphy_resume,
                .config_aneg    = lan87xx_config_aneg,
                .read_status    = lan87xx_read_status,
+               .get_sqi        = lan87xx_get_sqi,
+               .get_sqi_max    = lan87xx_get_sqi_max,
                .cable_test_start = lan87xx_cable_test_start,
                .cable_test_get_status = lan87xx_cable_test_get_status,
        },
@@ -750,6 +796,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
                .resume         = genphy_resume,
                .config_aneg    = lan87xx_config_aneg,
                .read_status    = lan87xx_read_status,
+               .get_sqi        = lan87xx_get_sqi,
+               .get_sqi_max    = lan87xx_get_sqi_max,
                .cable_test_start = lan87xx_cable_test_start,
                .cable_test_get_status = lan87xx_cable_test_get_status,
        }