7979#define T1_EQ_WT_FD_LCK_FRZ_CFG 0x6D
8080#define T1_PST_EQ_LCK_STG1_FRZ_CFG 0x6E
8181
82+ #define T1_MODE_STAT_REG 0x11
83+ #define T1_LINK_UP_MSK BIT(0)
84+
8285#define DRIVER_AUTHOR "Nisar Sayed <
[email protected] >"
8386#define DRIVER_DESC "Microchip LAN87XX/LAN937x T1 PHY driver"
8487
@@ -671,6 +674,89 @@ static int lan87xx_cable_test_get_status(struct phy_device *phydev,
671674 return 0 ;
672675}
673676
677+ static int lan87xx_read_master_slave (struct phy_device * phydev )
678+ {
679+ int rc = 0 ;
680+
681+ phydev -> master_slave_get = MASTER_SLAVE_CFG_UNKNOWN ;
682+ phydev -> master_slave_state = MASTER_SLAVE_STATE_UNKNOWN ;
683+
684+ rc = phy_read (phydev , MII_CTRL1000 );
685+ if (rc < 0 )
686+ return rc ;
687+
688+ if (rc & CTL1000_AS_MASTER )
689+ phydev -> master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE ;
690+ else
691+ phydev -> master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE ;
692+
693+ rc = phy_read (phydev , MII_STAT1000 );
694+ if (rc < 0 )
695+ return rc ;
696+
697+ if (rc & LPA_1000MSRES )
698+ phydev -> master_slave_state = MASTER_SLAVE_STATE_MASTER ;
699+ else
700+ phydev -> master_slave_state = MASTER_SLAVE_STATE_SLAVE ;
701+
702+ return rc ;
703+ }
704+
705+ static int lan87xx_read_status (struct phy_device * phydev )
706+ {
707+ int rc = 0 ;
708+
709+ rc = phy_read (phydev , T1_MODE_STAT_REG );
710+ if (rc < 0 )
711+ return rc ;
712+
713+ if (rc & T1_LINK_UP_MSK )
714+ phydev -> link = 1 ;
715+ else
716+ phydev -> link = 0 ;
717+
718+ phydev -> speed = SPEED_UNKNOWN ;
719+ phydev -> duplex = DUPLEX_UNKNOWN ;
720+ phydev -> pause = 0 ;
721+ phydev -> asym_pause = 0 ;
722+
723+ rc = lan87xx_read_master_slave (phydev );
724+ if (rc < 0 )
725+ return rc ;
726+
727+ rc = genphy_read_status_fixed (phydev );
728+ if (rc < 0 )
729+ return rc ;
730+
731+ return rc ;
732+ }
733+
734+ static int lan87xx_config_aneg (struct phy_device * phydev )
735+ {
736+ u16 ctl = 0 ;
737+ int rc ;
738+
739+ switch (phydev -> master_slave_set ) {
740+ case MASTER_SLAVE_CFG_MASTER_FORCE :
741+ ctl |= CTL1000_AS_MASTER ;
742+ break ;
743+ case MASTER_SLAVE_CFG_SLAVE_FORCE :
744+ break ;
745+ case MASTER_SLAVE_CFG_UNKNOWN :
746+ case MASTER_SLAVE_CFG_UNSUPPORTED :
747+ return 0 ;
748+ default :
749+ phydev_warn (phydev , "Unsupported Master/Slave mode\n" );
750+ return - EOPNOTSUPP ;
751+ }
752+
753+ rc = phy_modify_changed (phydev , MII_CTRL1000 , CTL1000_AS_MASTER , ctl );
754+ if (rc == 1 )
755+ rc = genphy_soft_reset (phydev );
756+
757+ return rc ;
758+ }
759+
674760static struct phy_driver microchip_t1_phy_driver [] = {
675761 {
676762 PHY_ID_MATCH_MODEL (PHY_ID_LAN87XX ),
@@ -682,6 +768,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
682768 .handle_interrupt = lan87xx_handle_interrupt ,
683769 .suspend = genphy_suspend ,
684770 .resume = genphy_resume ,
771+ .config_aneg = lan87xx_config_aneg ,
772+ .read_status = lan87xx_read_status ,
685773 .cable_test_start = lan87xx_cable_test_start ,
686774 .cable_test_get_status = lan87xx_cable_test_get_status ,
687775 },
@@ -692,6 +780,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
692780 .config_init = lan87xx_config_init ,
693781 .suspend = genphy_suspend ,
694782 .resume = genphy_resume ,
783+ .config_aneg = lan87xx_config_aneg ,
784+ .read_status = lan87xx_read_status ,
695785 .cable_test_start = lan87xx_cable_test_start ,
696786 .cable_test_get_status = lan87xx_cable_test_get_status ,
697787 }
0 commit comments