281281
282282#define MII_VCT_TXPINS 0x1A
283283#define MII_VCT_RXPINS 0x1B
284+ #define MII_VCT_SR 0x1C
284285#define MII_VCT_TXPINS_ENVCT BIT(15)
285286#define MII_VCT_TXRXPINS_VCTTST GENMASK(14, 13)
286287#define MII_VCT_TXRXPINS_VCTTST_SHIFT 13
@@ -2623,6 +2624,92 @@ static int m88e3082_vct_cable_test_get_status(struct phy_device *phydev,
26232624 return 0 ;
26242625}
26252626
2627+ static int m88e1111_vct_cable_test_start (struct phy_device * phydev )
2628+ {
2629+ int ret ;
2630+
2631+ ret = marvell_cable_test_start_common (phydev );
2632+ if (ret )
2633+ return ret ;
2634+
2635+ /* It needs some magic workarounds described in VCT manual for this PHY.
2636+ */
2637+ ret = phy_write (phydev , 29 , 0x0018 );
2638+ if (ret < 0 )
2639+ return ret ;
2640+
2641+ ret = phy_write (phydev , 30 , 0x00c2 );
2642+ if (ret < 0 )
2643+ return ret ;
2644+
2645+ ret = phy_write (phydev , 30 , 0x00ca );
2646+ if (ret < 0 )
2647+ return ret ;
2648+
2649+ ret = phy_write (phydev , 30 , 0x00c2 );
2650+ if (ret < 0 )
2651+ return ret ;
2652+
2653+ ret = phy_write_paged (phydev , MII_MARVELL_COPPER_PAGE , MII_VCT_SR ,
2654+ MII_VCT_TXPINS_ENVCT );
2655+ if (ret < 0 )
2656+ return ret ;
2657+
2658+ ret = phy_write (phydev , 29 , 0x0018 );
2659+ if (ret < 0 )
2660+ return ret ;
2661+
2662+ ret = phy_write (phydev , 30 , 0x0042 );
2663+ if (ret < 0 )
2664+ return ret ;
2665+
2666+ return 0 ;
2667+ }
2668+
2669+ static u32 m88e1111_vct_distrfln_2_cm (u8 distrfln )
2670+ {
2671+ if (distrfln < 36 )
2672+ return 0 ;
2673+
2674+ /* Original function for meters: y = 0.8018x - 28.751 */
2675+ return (8018 * distrfln - 287510 ) / 100 ;
2676+ }
2677+
2678+ static int m88e1111_vct_cable_test_get_status (struct phy_device * phydev ,
2679+ bool * finished )
2680+ {
2681+ u8 vcttst_res , distrfln ;
2682+ int ret , result ;
2683+
2684+ * finished = false;
2685+
2686+ /* Each pair use one page: A-0, B-1, C-2, D-3 */
2687+ for (u8 i = 0 ; i < 4 ; i ++ ) {
2688+ ret = phy_read_paged (phydev , i , MII_VCT_SR );
2689+ if (ret < 0 )
2690+ return ret ;
2691+ else if (i == 0 && ret & MII_VCT_TXPINS_ENVCT )
2692+ return 0 ;
2693+
2694+ distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN ;
2695+ vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST ) >>
2696+ MII_VCT_TXRXPINS_VCTTST_SHIFT ;
2697+
2698+ result = m88e3082_vct_cable_test_report_trans (vcttst_res ,
2699+ distrfln );
2700+ ethnl_cable_test_result (phydev , i , result );
2701+
2702+ if (distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX ) {
2703+ u32 cm = m88e1111_vct_distrfln_2_cm (distrfln );
2704+
2705+ ethnl_cable_test_fault_length (phydev , i , cm );
2706+ }
2707+ }
2708+
2709+ * finished = true;
2710+ return 0 ;
2711+ }
2712+
26262713#ifdef CONFIG_HWMON
26272714struct marvell_hwmon_ops {
26282715 int (* config )(struct phy_device * phydev );
@@ -3534,6 +3621,7 @@ static struct phy_driver marvell_drivers[] = {
35343621 .phy_id_mask = MARVELL_PHY_ID_MASK ,
35353622 .name = "Marvell 88E1111" ,
35363623 /* PHY_GBIT_FEATURES */
3624+ .flags = PHY_POLL_CABLE_TEST ,
35373625 .probe = marvell_probe ,
35383626 .config_init = m88e1111gbe_config_init ,
35393627 .config_aneg = m88e1111_config_aneg ,
@@ -3549,6 +3637,8 @@ static struct phy_driver marvell_drivers[] = {
35493637 .get_stats = marvell_get_stats ,
35503638 .get_tunable = m88e1111_get_tunable ,
35513639 .set_tunable = m88e1111_set_tunable ,
3640+ .cable_test_start = m88e1111_vct_cable_test_start ,
3641+ .cable_test_get_status = m88e1111_vct_cable_test_get_status ,
35523642 },
35533643 {
35543644 .phy_id = MARVELL_PHY_ID_88E1111_FINISAR ,
@@ -3642,6 +3732,7 @@ static struct phy_driver marvell_drivers[] = {
36423732 .phy_id_mask = MARVELL_PHY_ID_MASK ,
36433733 .name = "Marvell 88E1145" ,
36443734 /* PHY_GBIT_FEATURES */
3735+ .flags = PHY_POLL_CABLE_TEST ,
36453736 .probe = marvell_probe ,
36463737 .config_init = m88e1145_config_init ,
36473738 .config_aneg = m88e1101_config_aneg ,
@@ -3656,6 +3747,8 @@ static struct phy_driver marvell_drivers[] = {
36563747 .get_stats = marvell_get_stats ,
36573748 .get_tunable = m88e1111_get_tunable ,
36583749 .set_tunable = m88e1111_set_tunable ,
3750+ .cable_test_start = m88e1111_vct_cable_test_start ,
3751+ .cable_test_get_status = m88e1111_vct_cable_test_get_status ,
36593752 },
36603753 {
36613754 .phy_id = MARVELL_PHY_ID_88E1149R ,
0 commit comments