@@ -794,6 +794,49 @@ static int _bcm_phy_cable_test_get_status(struct phy_device *phydev,
794
794
return ret ;
795
795
}
796
796
797
+ static int bcm_setup_lre_forced (struct phy_device * phydev )
798
+ {
799
+ u16 ctl = 0 ;
800
+
801
+ phydev -> pause = 0 ;
802
+ phydev -> asym_pause = 0 ;
803
+
804
+ if (phydev -> speed == SPEED_100 )
805
+ ctl |= LRECR_SPEED100 ;
806
+
807
+ if (phydev -> duplex != DUPLEX_FULL )
808
+ return - EOPNOTSUPP ;
809
+
810
+ return phy_modify (phydev , MII_BCM54XX_LRECR , LRECR_SPEED100 , ctl );
811
+ }
812
+
813
+ /**
814
+ * bcm_linkmode_adv_to_lre_adv_t - translate linkmode advertisement to LDS
815
+ * @advertising: the linkmode advertisement settings
816
+ * Return: LDS Auto-Negotiation Advertised Ability register value
817
+ *
818
+ * A small helper function that translates linkmode advertisement
819
+ * settings to phy LDS autonegotiation advertisements for the
820
+ * MII_BCM54XX_LREANAA register of Broadcom PHYs capable of LDS
821
+ */
822
+ static u32 bcm_linkmode_adv_to_lre_adv_t (unsigned long * advertising )
823
+ {
824
+ u32 result = 0 ;
825
+
826
+ if (linkmode_test_bit (ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT ,
827
+ advertising ))
828
+ result |= LREANAA_10_1PAIR ;
829
+ if (linkmode_test_bit (ETHTOOL_LINK_MODE_100baseT1_Full_BIT ,
830
+ advertising ))
831
+ result |= LREANAA_100_1PAIR ;
832
+ if (linkmode_test_bit (ETHTOOL_LINK_MODE_Pause_BIT , advertising ))
833
+ result |= LRELPA_PAUSE ;
834
+ if (linkmode_test_bit (ETHTOOL_LINK_MODE_Asym_Pause_BIT , advertising ))
835
+ result |= LRELPA_PAUSE_ASYM ;
836
+
837
+ return result ;
838
+ }
839
+
797
840
int bcm_phy_cable_test_start (struct phy_device * phydev )
798
841
{
799
842
return _bcm_phy_cable_test_start (phydev , false);
@@ -1066,6 +1109,78 @@ int bcm_phy_led_brightness_set(struct phy_device *phydev,
1066
1109
}
1067
1110
EXPORT_SYMBOL_GPL (bcm_phy_led_brightness_set );
1068
1111
1112
+ int bcm_setup_lre_master_slave (struct phy_device * phydev )
1113
+ {
1114
+ u16 ctl = 0 ;
1115
+
1116
+ switch (phydev -> master_slave_set ) {
1117
+ case MASTER_SLAVE_CFG_MASTER_PREFERRED :
1118
+ case MASTER_SLAVE_CFG_MASTER_FORCE :
1119
+ ctl = LRECR_MASTER ;
1120
+ break ;
1121
+ case MASTER_SLAVE_CFG_SLAVE_PREFERRED :
1122
+ case MASTER_SLAVE_CFG_SLAVE_FORCE :
1123
+ break ;
1124
+ case MASTER_SLAVE_CFG_UNKNOWN :
1125
+ case MASTER_SLAVE_CFG_UNSUPPORTED :
1126
+ return 0 ;
1127
+ default :
1128
+ phydev_warn (phydev , "Unsupported Master/Slave mode\n" );
1129
+ return - EOPNOTSUPP ;
1130
+ }
1131
+
1132
+ return phy_modify_changed (phydev , MII_BCM54XX_LRECR , LRECR_MASTER , ctl );
1133
+ }
1134
+ EXPORT_SYMBOL_GPL (bcm_setup_lre_master_slave );
1135
+
1136
+ int bcm_config_lre_aneg (struct phy_device * phydev , bool changed )
1137
+ {
1138
+ int err ;
1139
+
1140
+ if (genphy_config_eee_advert (phydev ))
1141
+ changed = true;
1142
+
1143
+ err = bcm_setup_lre_master_slave (phydev );
1144
+ if (err < 0 )
1145
+ return err ;
1146
+ else if (err )
1147
+ changed = true;
1148
+
1149
+ if (phydev -> autoneg != AUTONEG_ENABLE )
1150
+ return bcm_setup_lre_forced (phydev );
1151
+
1152
+ err = bcm_config_lre_advert (phydev );
1153
+ if (err < 0 )
1154
+ return err ;
1155
+ else if (err )
1156
+ changed = true;
1157
+
1158
+ return genphy_check_and_restart_aneg (phydev , changed );
1159
+ }
1160
+ EXPORT_SYMBOL_GPL (bcm_config_lre_aneg );
1161
+
1162
+ /**
1163
+ * bcm_config_lre_advert - sanitize and advertise Long-Distance Signaling
1164
+ * auto-negotiation parameters
1165
+ * @phydev: target phy_device struct
1166
+ * Return: 0 if the PHY's advertisement hasn't changed, < 0 on error,
1167
+ * > 0 if it has changed
1168
+ *
1169
+ * Writes MII_BCM54XX_LREANAA with the appropriate values. The values are to be
1170
+ * sanitized before, to make sure we only advertise what is supported.
1171
+ * The sanitization is done already in phy_ethtool_ksettings_set()
1172
+ */
1173
+ int bcm_config_lre_advert (struct phy_device * phydev )
1174
+ {
1175
+ u32 adv = bcm_linkmode_adv_to_lre_adv_t (phydev -> advertising );
1176
+
1177
+ /* Setup BroadR-Reach mode advertisement */
1178
+ return phy_modify_changed (phydev , MII_BCM54XX_LREANAA ,
1179
+ LRE_ADVERTISE_ALL | LREANAA_PAUSE |
1180
+ LREANAA_PAUSE_ASYM , adv );
1181
+ }
1182
+ EXPORT_SYMBOL_GPL (bcm_config_lre_advert );
1183
+
1069
1184
MODULE_DESCRIPTION ("Broadcom PHY Library" );
1070
1185
MODULE_LICENSE ("GPL v2" );
1071
1186
MODULE_AUTHOR ("Broadcom Corporation" );
0 commit comments