@@ -794,6 +794,49 @@ static int _bcm_phy_cable_test_get_status(struct phy_device *phydev,
794794 return ret ;
795795}
796796
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+
797840int bcm_phy_cable_test_start (struct phy_device * phydev )
798841{
799842 return _bcm_phy_cable_test_start (phydev , false);
@@ -1066,6 +1109,78 @@ int bcm_phy_led_brightness_set(struct phy_device *phydev,
10661109}
10671110EXPORT_SYMBOL_GPL (bcm_phy_led_brightness_set );
10681111
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+
10691184MODULE_DESCRIPTION ("Broadcom PHY Library" );
10701185MODULE_LICENSE ("GPL v2" );
10711186MODULE_AUTHOR ("Broadcom Corporation" );
0 commit comments