6868#define T1_POST_LCK_MUFACT_CFG_REG 0x1C
6969#define T1_TX_RX_FIFO_CFG_REG 0x02
7070#define T1_TX_LPF_FIR_CFG_REG 0x55
71+ #define T1_COEF_CLK_PWR_DN_CFG 0x04
72+ #define T1_COEF_RW_CTL_CFG 0x0D
7173#define T1_SQI_CONFIG_REG 0x2E
74+ #define T1_SQI_CONFIG2_REG 0x4A
75+ #define T1_DCQ_SQI_REG 0xC3
76+ #define T1_DCQ_SQI_MSK GENMASK(3, 1)
7277#define T1_MDIO_CONTROL2_REG 0x10
7378#define T1_INTERRUPT_SOURCE_REG 0x18
7479#define T1_INTERRUPT2_SOURCE_REG 0x08
8287#define T1_MODE_STAT_REG 0x11
8388#define T1_LINK_UP_MSK BIT(0)
8489
90+ /* SQI defines */
91+ #define LAN87XX_MAX_SQI 0x07
92+
8593#define DRIVER_AUTHOR "Nisar Sayed <nisar.sayed@microchip.com>"
8694#define DRIVER_DESC "Microchip LAN87XX/LAN937x T1 PHY driver"
8795
@@ -346,9 +354,20 @@ static int lan87xx_phy_init(struct phy_device *phydev)
346354 T1_TX_LPF_FIR_CFG_REG , 0x1011 , 0 },
347355 { PHYACC_ATTR_MODE_WRITE , PHYACC_ATTR_BANK_DSP ,
348356 T1_TX_LPF_FIR_CFG_REG , 0x1000 , 0 },
357+ /* Setup SQI measurement */
358+ { PHYACC_ATTR_MODE_WRITE , PHYACC_ATTR_BANK_DSP ,
359+ T1_COEF_CLK_PWR_DN_CFG , 0x16d6 , 0 },
349360 /* SQI enable */
350361 { PHYACC_ATTR_MODE_WRITE , PHYACC_ATTR_BANK_DSP ,
351362 T1_SQI_CONFIG_REG , 0x9572 , 0 },
363+ /* SQI select mode 5 */
364+ { PHYACC_ATTR_MODE_WRITE , PHYACC_ATTR_BANK_DSP ,
365+ T1_SQI_CONFIG2_REG , 0x0001 , 0 },
366+ /* Throws the first SQI reading */
367+ { PHYACC_ATTR_MODE_WRITE , PHYACC_ATTR_BANK_DSP ,
368+ T1_COEF_RW_CTL_CFG , 0x0301 , 0 },
369+ { PHYACC_ATTR_MODE_READ , PHYACC_ATTR_BANK_DSP ,
370+ T1_DCQ_SQI_REG , 0 , 0 },
352371 /* Flag LPS and WUR as idle errors */
353372 { PHYACC_ATTR_MODE_WRITE , PHYACC_ATTR_BANK_SMI ,
354373 T1_MDIO_CONTROL2_REG , 0x0014 , 0 },
@@ -724,6 +743,31 @@ static int lan87xx_config_aneg(struct phy_device *phydev)
724743 return phy_modify_changed (phydev , MII_CTRL1000 , CTL1000_AS_MASTER , ctl );
725744}
726745
746+ static int lan87xx_get_sqi (struct phy_device * phydev )
747+ {
748+ u8 sqi_value = 0 ;
749+ int rc ;
750+
751+ rc = access_ereg (phydev , PHYACC_ATTR_MODE_WRITE ,
752+ PHYACC_ATTR_BANK_DSP , T1_COEF_RW_CTL_CFG , 0x0301 );
753+ if (rc < 0 )
754+ return rc ;
755+
756+ rc = access_ereg (phydev , PHYACC_ATTR_MODE_READ ,
757+ PHYACC_ATTR_BANK_DSP , T1_DCQ_SQI_REG , 0x0 );
758+ if (rc < 0 )
759+ return rc ;
760+
761+ sqi_value = FIELD_GET (T1_DCQ_SQI_MSK , rc );
762+
763+ return sqi_value ;
764+ }
765+
766+ static int lan87xx_get_sqi_max (struct phy_device * phydev )
767+ {
768+ return LAN87XX_MAX_SQI ;
769+ }
770+
727771static struct phy_driver microchip_t1_phy_driver [] = {
728772 {
729773 PHY_ID_MATCH_MODEL (PHY_ID_LAN87XX ),
@@ -737,6 +781,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
737781 .resume = genphy_resume ,
738782 .config_aneg = lan87xx_config_aneg ,
739783 .read_status = lan87xx_read_status ,
784+ .get_sqi = lan87xx_get_sqi ,
785+ .get_sqi_max = lan87xx_get_sqi_max ,
740786 .cable_test_start = lan87xx_cable_test_start ,
741787 .cable_test_get_status = lan87xx_cable_test_get_status ,
742788 },
@@ -750,6 +796,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
750796 .resume = genphy_resume ,
751797 .config_aneg = lan87xx_config_aneg ,
752798 .read_status = lan87xx_read_status ,
799+ .get_sqi = lan87xx_get_sqi ,
800+ .get_sqi_max = lan87xx_get_sqi_max ,
753801 .cable_test_start = lan87xx_cable_test_start ,
754802 .cable_test_get_status = lan87xx_cable_test_get_status ,
755803 }
0 commit comments