diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2013-06-29 13:23:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-01 16:18:19 -0400 |
commit | a5b87cc9e0538bf6680d431e0076d778e5bae38e (patch) | |
tree | abda29f1ca08441d2d81cb21bc8fb655064cd8b4 /drivers/net/ethernet/atheros/alx/main.c | |
parent | 4a134c39db2d9d6f31c55e7c3773fc33189c9320 (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.c | 37 |
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 | ||
872 | static const char *alx_speed_desc(u16 speed) | 874 | static 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); |