@@ -737,6 +737,18 @@ static void xgbe_an_init(struct xgbe_prv_data *pdata)
737
737
XMDIO_WRITE (pdata , MDIO_MMD_AN , MDIO_AN_ADVERTISE , reg );
738
738
}
739
739
740
+ static const char * xgbe_phy_fc_string (struct xgbe_prv_data * pdata )
741
+ {
742
+ if (pdata -> tx_pause && pdata -> rx_pause )
743
+ return "rx/tx" ;
744
+ else if (pdata -> rx_pause )
745
+ return "rx" ;
746
+ else if (pdata -> tx_pause )
747
+ return "tx" ;
748
+ else
749
+ return "off" ;
750
+ }
751
+
740
752
static const char * xgbe_phy_speed_string (int speed )
741
753
{
742
754
switch (speed ) {
@@ -760,7 +772,7 @@ static void xgbe_phy_print_status(struct xgbe_prv_data *pdata)
760
772
"Link is Up - %s/%s - flow control %s\n" ,
761
773
xgbe_phy_speed_string (pdata -> phy .speed ),
762
774
pdata -> phy .duplex == DUPLEX_FULL ? "Full" : "Half" ,
763
- pdata -> phy . pause ? "rx/tx" : "off" );
775
+ xgbe_phy_fc_string ( pdata ) );
764
776
else
765
777
netdev_info (pdata -> netdev , "Link is Down\n" );
766
778
}
@@ -771,24 +783,18 @@ static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata)
771
783
772
784
if (pdata -> phy .link ) {
773
785
/* Flow control support */
774
- if (pdata -> pause_autoneg ) {
775
- if (pdata -> phy .pause || pdata -> phy .asym_pause ) {
776
- pdata -> tx_pause = 1 ;
777
- pdata -> rx_pause = 1 ;
778
- } else {
779
- pdata -> tx_pause = 0 ;
780
- pdata -> rx_pause = 0 ;
781
- }
782
- }
786
+ pdata -> pause_autoneg = pdata -> phy .pause_autoneg ;
783
787
784
- if (pdata -> tx_pause != pdata -> phy_tx_pause ) {
788
+ if (pdata -> tx_pause != pdata -> phy .tx_pause ) {
789
+ new_state = 1 ;
785
790
pdata -> hw_if .config_tx_flow_control (pdata );
786
- pdata -> phy_tx_pause = pdata -> tx_pause ;
791
+ pdata -> tx_pause = pdata -> phy . tx_pause ;
787
792
}
788
793
789
- if (pdata -> rx_pause != pdata -> phy_rx_pause ) {
794
+ if (pdata -> rx_pause != pdata -> phy .rx_pause ) {
795
+ new_state = 1 ;
790
796
pdata -> hw_if .config_rx_flow_control (pdata );
791
- pdata -> phy_rx_pause = pdata -> rx_pause ;
797
+ pdata -> rx_pause = pdata -> phy . rx_pause ;
792
798
}
793
799
794
800
/* Speed support */
@@ -835,9 +841,6 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
835
841
if (pdata -> phy .duplex != DUPLEX_FULL )
836
842
return - EINVAL ;
837
843
838
- pdata -> phy .pause = 0 ;
839
- pdata -> phy .asym_pause = 0 ;
840
-
841
844
return 0 ;
842
845
}
843
846
@@ -933,8 +936,6 @@ static void xgbe_phy_status_force(struct xgbe_prv_data *pdata)
933
936
}
934
937
}
935
938
pdata -> phy .duplex = DUPLEX_FULL ;
936
- pdata -> phy .pause = 0 ;
937
- pdata -> phy .asym_pause = 0 ;
938
939
}
939
940
940
941
static void xgbe_phy_status_aneg (struct xgbe_prv_data * pdata )
@@ -957,9 +958,21 @@ static void xgbe_phy_status_aneg(struct xgbe_prv_data *pdata)
957
958
if (lp_reg & 0x800 )
958
959
pdata -> phy .lp_advertising |= ADVERTISED_Asym_Pause ;
959
960
960
- ad_reg &= lp_reg ;
961
- pdata -> phy .pause = (ad_reg & 0x400 ) ? 1 : 0 ;
962
- pdata -> phy .asym_pause = (ad_reg & 0x800 ) ? 1 : 0 ;
961
+ if (pdata -> phy .pause_autoneg ) {
962
+ /* Set flow control based on auto-negotiation result */
963
+ pdata -> phy .tx_pause = 0 ;
964
+ pdata -> phy .rx_pause = 0 ;
965
+
966
+ if (ad_reg & lp_reg & 0x400 ) {
967
+ pdata -> phy .tx_pause = 1 ;
968
+ pdata -> phy .rx_pause = 1 ;
969
+ } else if (ad_reg & lp_reg & 0x800 ) {
970
+ if (ad_reg & 0x400 )
971
+ pdata -> phy .rx_pause = 1 ;
972
+ else if (lp_reg & 0x400 )
973
+ pdata -> phy .tx_pause = 1 ;
974
+ }
975
+ }
963
976
964
977
/* Compare Advertisement and Link Partner register 2 */
965
978
ad_reg = XMDIO_READ (pdata , MDIO_MMD_AN , MDIO_AN_ADVERTISE + 1 );
@@ -1223,6 +1236,22 @@ static void xgbe_phy_init(struct xgbe_prv_data *pdata)
1223
1236
1224
1237
pdata -> phy .link = 0 ;
1225
1238
1239
+ pdata -> phy .pause_autoneg = pdata -> pause_autoneg ;
1240
+ pdata -> phy .tx_pause = pdata -> tx_pause ;
1241
+ pdata -> phy .rx_pause = pdata -> rx_pause ;
1242
+
1243
+ /* Fix up Flow Control advertising */
1244
+ pdata -> phy .advertising &= ~ADVERTISED_Pause ;
1245
+ pdata -> phy .advertising &= ~ADVERTISED_Asym_Pause ;
1246
+
1247
+ if (pdata -> rx_pause ) {
1248
+ pdata -> phy .advertising |= ADVERTISED_Pause ;
1249
+ pdata -> phy .advertising |= ADVERTISED_Asym_Pause ;
1250
+ }
1251
+
1252
+ if (pdata -> tx_pause )
1253
+ pdata -> phy .advertising ^= ADVERTISED_Asym_Pause ;
1254
+
1226
1255
if (netif_msg_drv (pdata ))
1227
1256
xgbe_dump_phy_registers (pdata );
1228
1257
}
0 commit comments