aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros/alx/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2013-06-29 13:23:17 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-01 16:18:19 -0400
commita5b87cc9e0538bf6680d431e0076d778e5bae38e (patch)
treeabda29f1ca08441d2d81cb21bc8fb655064cd8b4 /drivers/net/ethernet/atheros/alx/main.c
parent4a134c39db2d9d6f31c55e7c3773fc33189c9320 (diff)
alx: separate link speed/duplex fields
As suggested by Ben Hutchings, use separate fields to track current link speed and duplex setting. Reported-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros/alx/main.c')
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 418de8b13165..148b4b976474 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -712,6 +712,7 @@ static int alx_init_sw(struct alx_priv *alx)
712 hw->dma_chnl = hw->max_dma_chnl; 712 hw->dma_chnl = hw->max_dma_chnl;
713 hw->ith_tpd = alx->tx_ringsz / 3; 713 hw->ith_tpd = alx->tx_ringsz / 3;
714 hw->link_speed = SPEED_UNKNOWN; 714 hw->link_speed = SPEED_UNKNOWN;
715 hw->duplex = DUPLEX_UNKNOWN;
715 hw->adv_cfg = ADVERTISED_Autoneg | 716 hw->adv_cfg = ADVERTISED_Autoneg |
716 ADVERTISED_10baseT_Half | 717 ADVERTISED_10baseT_Half |
717 ADVERTISED_10baseT_Full | 718 ADVERTISED_10baseT_Full |
@@ -758,6 +759,7 @@ static void alx_halt(struct alx_priv *alx)
758 759
759 alx_netif_stop(alx); 760 alx_netif_stop(alx);
760 hw->link_speed = SPEED_UNKNOWN; 761 hw->link_speed = SPEED_UNKNOWN;
762 hw->duplex = DUPLEX_UNKNOWN;
761 763
762 alx_reset_mac(hw); 764 alx_reset_mac(hw);
763 765
@@ -869,18 +871,18 @@ static void __alx_stop(struct alx_priv *alx)
869 alx_free_rings(alx); 871 alx_free_rings(alx);
870} 872}
871 873
872static const char *alx_speed_desc(u16 speed) 874static const char *alx_speed_desc(struct alx_hw *hw)
873{ 875{
874 switch (speed) { 876 switch (alx_speed_to_ethadv(hw->link_speed, hw->duplex)) {
875 case SPEED_1000 + DUPLEX_FULL: 877 case ADVERTISED_1000baseT_Full:
876 return "1 Gbps Full"; 878 return "1 Gbps Full";
877 case SPEED_100 + DUPLEX_FULL: 879 case ADVERTISED_100baseT_Full:
878 return "100 Mbps Full"; 880 return "100 Mbps Full";
879 case SPEED_100 + DUPLEX_HALF: 881 case ADVERTISED_100baseT_Half:
880 return "100 Mbps Half"; 882 return "100 Mbps Half";
881 case SPEED_10 + DUPLEX_FULL: 883 case ADVERTISED_10baseT_Full:
882 return "10 Mbps Full"; 884 return "10 Mbps Full";
883 case SPEED_10 + DUPLEX_HALF: 885 case ADVERTISED_10baseT_Half:
884 return "10 Mbps Half"; 886 return "10 Mbps Half";
885 default: 887 default:
886 return "Unknown speed"; 888 return "Unknown speed";
@@ -891,7 +893,8 @@ static void alx_check_link(struct alx_priv *alx)
891{ 893{
892 struct alx_hw *hw = &alx->hw; 894 struct alx_hw *hw = &alx->hw;
893 unsigned long flags; 895 unsigned long flags;
894 int speed, old_speed; 896 int old_speed;
897 u8 old_duplex;
895 int err; 898 int err;
896 899
897 /* clear PHY internal interrupt status, otherwise the main 900 /* clear PHY internal interrupt status, otherwise the main
@@ -899,7 +902,9 @@ static void alx_check_link(struct alx_priv *alx)
899 */ 902 */
900 alx_clear_phy_intr(hw); 903 alx_clear_phy_intr(hw);
901 904
902 err = alx_get_phy_link(hw, &speed); 905 old_speed = hw->link_speed;
906 old_duplex = hw->duplex;
907 err = alx_read_phy_link(hw);
903 if (err < 0) 908 if (err < 0)
904 goto reset; 909 goto reset;
905 910
@@ -908,15 +913,12 @@ static void alx_check_link(struct alx_priv *alx)
908 alx_write_mem32(hw, ALX_IMR, alx->int_mask); 913 alx_write_mem32(hw, ALX_IMR, alx->int_mask);
909 spin_unlock_irqrestore(&alx->irq_lock, flags); 914 spin_unlock_irqrestore(&alx->irq_lock, flags);
910 915
911 old_speed = hw->link_speed; 916 if (old_speed == hw->link_speed)
912
913 if (old_speed == speed)
914 return; 917 return;
915 hw->link_speed = speed;
916 918
917 if (speed != SPEED_UNKNOWN) { 919 if (hw->link_speed != SPEED_UNKNOWN) {
918 netif_info(alx, link, alx->dev, 920 netif_info(alx, link, alx->dev,
919 "NIC Up: %s\n", alx_speed_desc(speed)); 921 "NIC Up: %s\n", alx_speed_desc(hw));
920 alx_post_phy_link(hw); 922 alx_post_phy_link(hw);
921 alx_enable_aspm(hw, true, true); 923 alx_enable_aspm(hw, true, true);
922 alx_start_mac(hw); 924 alx_start_mac(hw);
@@ -965,6 +967,7 @@ static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en)
965 struct net_device *netdev = alx->dev; 967 struct net_device *netdev = alx->dev;
966 struct alx_hw *hw = &alx->hw; 968 struct alx_hw *hw = &alx->hw;
967 int err, speed; 969 int err, speed;
970 u8 duplex;
968 971
969 netif_device_detach(netdev); 972 netif_device_detach(netdev);
970 973
@@ -977,13 +980,13 @@ static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en)
977 return err; 980 return err;
978#endif 981#endif
979 982
980 err = alx_select_powersaving_speed(hw, &speed); 983 err = alx_select_powersaving_speed(hw, &speed, &duplex);
981 if (err) 984 if (err)
982 return err; 985 return err;
983 err = alx_clear_phy_intr(hw); 986 err = alx_clear_phy_intr(hw);
984 if (err) 987 if (err)
985 return err; 988 return err;
986 err = alx_pre_suspend(hw, speed); 989 err = alx_pre_suspend(hw, speed, duplex);
987 if (err) 990 if (err)
988 return err; 991 return err;
989 err = alx_config_wol(hw); 992 err = alx_config_wol(hw);