aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/ethtool.c
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2007-10-15 17:30:59 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-16 21:10:27 -0400
commit369d742defed73fc6b38bf0929fb198d072102ab (patch)
tree04b5cb53a8379145b3ea7ceca28cf50feaa6e713 /drivers/net/e1000e/ethtool.c
parente265522ca7d7a0cfa24aa2c811d22a1764a90783 (diff)
e1000e: don't poke PHY registers to retreive link status
Apparently poking the link status registers when autonegotiation is running on the PHY might botch the PHY link on 80003es2lan devices. While this is a very rare condition we can completely avoid it alltogether by just using the MAC link bits to provide the proper information to ethtool. Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/e1000e/ethtool.c')
-rw-r--r--drivers/net/e1000e/ethtool.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index ca06c354b53c..0666e62e9ad2 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -110,6 +110,7 @@ static int e1000_get_settings(struct net_device *netdev,
110{ 110{
111 struct e1000_adapter *adapter = netdev_priv(netdev); 111 struct e1000_adapter *adapter = netdev_priv(netdev);
112 struct e1000_hw *hw = &adapter->hw; 112 struct e1000_hw *hw = &adapter->hw;
113 u32 status;
113 114
114 if (hw->media_type == e1000_media_type_copper) { 115 if (hw->media_type == e1000_media_type_copper) {
115 116
@@ -147,16 +148,16 @@ static int e1000_get_settings(struct net_device *netdev,
147 ecmd->transceiver = XCVR_EXTERNAL; 148 ecmd->transceiver = XCVR_EXTERNAL;
148 } 149 }
149 150
150 if (er32(STATUS) & E1000_STATUS_LU) { 151 status = er32(STATUS);
151 152 if (status & E1000_STATUS_LU) {
152 adapter->hw.mac.ops.get_link_up_info(hw, &adapter->link_speed, 153 if (status & E1000_STATUS_SPEED_1000)
153 &adapter->link_duplex); 154 ecmd->speed = 1000;
154 ecmd->speed = adapter->link_speed; 155 else if (status & E1000_STATUS_SPEED_100)
155 156 ecmd->speed = 100;
156 /* unfortunately FULL_DUPLEX != DUPLEX_FULL 157 else
157 * and HALF_DUPLEX != DUPLEX_HALF */ 158 ecmd->speed = 10;
158 159
159 if (adapter->link_duplex == FULL_DUPLEX) 160 if (status & E1000_STATUS_FD)
160 ecmd->duplex = DUPLEX_FULL; 161 ecmd->duplex = DUPLEX_FULL;
161 else 162 else
162 ecmd->duplex = DUPLEX_HALF; 163 ecmd->duplex = DUPLEX_HALF;
@@ -170,6 +171,16 @@ static int e1000_get_settings(struct net_device *netdev,
170 return 0; 171 return 0;
171} 172}
172 173
174static u32 e1000_get_link(struct net_device *netdev)
175{
176 struct e1000_adapter *adapter = netdev_priv(netdev);
177 struct e1000_hw *hw = &adapter->hw;
178 u32 status;
179
180 status = er32(STATUS);
181 return (status & E1000_STATUS_LU);
182}
183
173static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) 184static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
174{ 185{
175 struct e1000_mac_info *mac = &adapter->hw.mac; 186 struct e1000_mac_info *mac = &adapter->hw.mac;
@@ -1751,7 +1762,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
1751 .get_msglevel = e1000_get_msglevel, 1762 .get_msglevel = e1000_get_msglevel,
1752 .set_msglevel = e1000_set_msglevel, 1763 .set_msglevel = e1000_set_msglevel,
1753 .nway_reset = e1000_nway_reset, 1764 .nway_reset = e1000_nway_reset,
1754 .get_link = ethtool_op_get_link, 1765 .get_link = e1000_get_link,
1755 .get_eeprom_len = e1000_get_eeprom_len, 1766 .get_eeprom_len = e1000_get_eeprom_len,
1756 .get_eeprom = e1000_get_eeprom, 1767 .get_eeprom = e1000_get_eeprom,
1757 .set_eeprom = e1000_set_eeprom, 1768 .set_eeprom = e1000_set_eeprom,