diff options
Diffstat (limited to 'drivers/net/e1000e/ethtool.c')
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 144 |
1 files changed, 84 insertions, 60 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 2c521218102b..6355a1b779d3 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2010 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
@@ -118,7 +118,6 @@ static int e1000_get_settings(struct net_device *netdev, | |||
118 | { | 118 | { |
119 | struct e1000_adapter *adapter = netdev_priv(netdev); | 119 | struct e1000_adapter *adapter = netdev_priv(netdev); |
120 | struct e1000_hw *hw = &adapter->hw; | 120 | struct e1000_hw *hw = &adapter->hw; |
121 | u32 status; | ||
122 | 121 | ||
123 | if (hw->phy.media_type == e1000_media_type_copper) { | 122 | if (hw->phy.media_type == e1000_media_type_copper) { |
124 | 123 | ||
@@ -156,22 +155,29 @@ static int e1000_get_settings(struct net_device *netdev, | |||
156 | ecmd->transceiver = XCVR_EXTERNAL; | 155 | ecmd->transceiver = XCVR_EXTERNAL; |
157 | } | 156 | } |
158 | 157 | ||
159 | status = er32(STATUS); | 158 | ecmd->speed = -1; |
160 | if (status & E1000_STATUS_LU) { | 159 | ecmd->duplex = -1; |
161 | if (status & E1000_STATUS_SPEED_1000) | ||
162 | ecmd->speed = 1000; | ||
163 | else if (status & E1000_STATUS_SPEED_100) | ||
164 | ecmd->speed = 100; | ||
165 | else | ||
166 | ecmd->speed = 10; | ||
167 | 160 | ||
168 | if (status & E1000_STATUS_FD) | 161 | if (netif_running(netdev)) { |
169 | ecmd->duplex = DUPLEX_FULL; | 162 | if (netif_carrier_ok(netdev)) { |
170 | else | 163 | ecmd->speed = adapter->link_speed; |
171 | ecmd->duplex = DUPLEX_HALF; | 164 | ecmd->duplex = adapter->link_duplex - 1; |
165 | } | ||
172 | } else { | 166 | } else { |
173 | ecmd->speed = -1; | 167 | u32 status = er32(STATUS); |
174 | ecmd->duplex = -1; | 168 | if (status & E1000_STATUS_LU) { |
169 | if (status & E1000_STATUS_SPEED_1000) | ||
170 | ecmd->speed = 1000; | ||
171 | else if (status & E1000_STATUS_SPEED_100) | ||
172 | ecmd->speed = 100; | ||
173 | else | ||
174 | ecmd->speed = 10; | ||
175 | |||
176 | if (status & E1000_STATUS_FD) | ||
177 | ecmd->duplex = DUPLEX_FULL; | ||
178 | else | ||
179 | ecmd->duplex = DUPLEX_HALF; | ||
180 | } | ||
175 | } | 181 | } |
176 | 182 | ||
177 | ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || | 183 | ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || |
@@ -179,7 +185,7 @@ static int e1000_get_settings(struct net_device *netdev, | |||
179 | 185 | ||
180 | /* MDI-X => 2; MDI =>1; Invalid =>0 */ | 186 | /* MDI-X => 2; MDI =>1; Invalid =>0 */ |
181 | if ((hw->phy.media_type == e1000_media_type_copper) && | 187 | if ((hw->phy.media_type == e1000_media_type_copper) && |
182 | !hw->mac.get_link_status) | 188 | netif_carrier_ok(netdev)) |
183 | ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : | 189 | ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : |
184 | ETH_TP_MDI; | 190 | ETH_TP_MDI; |
185 | else | 191 | else |
@@ -191,19 +197,15 @@ static int e1000_get_settings(struct net_device *netdev, | |||
191 | static u32 e1000_get_link(struct net_device *netdev) | 197 | static u32 e1000_get_link(struct net_device *netdev) |
192 | { | 198 | { |
193 | struct e1000_adapter *adapter = netdev_priv(netdev); | 199 | struct e1000_adapter *adapter = netdev_priv(netdev); |
194 | struct e1000_mac_info *mac = &adapter->hw.mac; | 200 | struct e1000_hw *hw = &adapter->hw; |
195 | 201 | ||
196 | /* | 202 | /* |
197 | * If the link is not reported up to netdev, interrupts are disabled, | 203 | * Avoid touching hardware registers when possible, otherwise |
198 | * and so the physical link state may have changed since we last | 204 | * link negotiation can get messed up when user-level scripts |
199 | * looked. Set get_link_status to make sure that the true link | 205 | * are rapidly polling the driver to see if link is up. |
200 | * state is interrogated, rather than pulling a cached and possibly | ||
201 | * stale link state from the driver. | ||
202 | */ | 206 | */ |
203 | if (!netif_carrier_ok(netdev)) | 207 | return netif_running(netdev) ? netif_carrier_ok(netdev) : |
204 | mac->get_link_status = 1; | 208 | !!(er32(STATUS) & E1000_STATUS_LU); |
205 | |||
206 | return e1000e_has_link(adapter); | ||
207 | } | 209 | } |
208 | 210 | ||
209 | static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) | 211 | static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) |
@@ -880,6 +882,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) | |||
880 | switch (mac->type) { | 882 | switch (mac->type) { |
881 | case e1000_ich10lan: | 883 | case e1000_ich10lan: |
882 | case e1000_pchlan: | 884 | case e1000_pchlan: |
885 | case e1000_pch2lan: | ||
883 | mask |= (1 << 18); | 886 | mask |= (1 << 18); |
884 | break; | 887 | break; |
885 | default: | 888 | default: |
@@ -1263,33 +1266,36 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1263 | 1266 | ||
1264 | hw->mac.autoneg = 0; | 1267 | hw->mac.autoneg = 0; |
1265 | 1268 | ||
1266 | /* Workaround: K1 must be disabled for stable 1Gbps operation */ | 1269 | if (hw->phy.type == e1000_phy_ife) { |
1267 | if (hw->mac.type == e1000_pchlan) | ||
1268 | e1000_configure_k1_ich8lan(hw, false); | ||
1269 | |||
1270 | if (hw->phy.type == e1000_phy_m88) { | ||
1271 | /* Auto-MDI/MDIX Off */ | ||
1272 | e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); | ||
1273 | /* reset to update Auto-MDI/MDIX */ | ||
1274 | e1e_wphy(hw, PHY_CONTROL, 0x9140); | ||
1275 | /* autoneg off */ | ||
1276 | e1e_wphy(hw, PHY_CONTROL, 0x8140); | ||
1277 | } else if (hw->phy.type == e1000_phy_gg82563) | ||
1278 | e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); | ||
1279 | |||
1280 | ctrl_reg = er32(CTRL); | ||
1281 | |||
1282 | switch (hw->phy.type) { | ||
1283 | case e1000_phy_ife: | ||
1284 | /* force 100, set loopback */ | 1270 | /* force 100, set loopback */ |
1285 | e1e_wphy(hw, PHY_CONTROL, 0x6100); | 1271 | e1e_wphy(hw, PHY_CONTROL, 0x6100); |
1286 | 1272 | ||
1287 | /* Now set up the MAC to the same speed/duplex as the PHY. */ | 1273 | /* Now set up the MAC to the same speed/duplex as the PHY. */ |
1274 | ctrl_reg = er32(CTRL); | ||
1288 | ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ | 1275 | ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ |
1289 | ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ | 1276 | ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ |
1290 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ | 1277 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ |
1291 | E1000_CTRL_SPD_100 |/* Force Speed to 100 */ | 1278 | E1000_CTRL_SPD_100 |/* Force Speed to 100 */ |
1292 | E1000_CTRL_FD); /* Force Duplex to FULL */ | 1279 | E1000_CTRL_FD); /* Force Duplex to FULL */ |
1280 | |||
1281 | ew32(CTRL, ctrl_reg); | ||
1282 | udelay(500); | ||
1283 | |||
1284 | return 0; | ||
1285 | } | ||
1286 | |||
1287 | /* Specific PHY configuration for loopback */ | ||
1288 | switch (hw->phy.type) { | ||
1289 | case e1000_phy_m88: | ||
1290 | /* Auto-MDI/MDIX Off */ | ||
1291 | e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); | ||
1292 | /* reset to update Auto-MDI/MDIX */ | ||
1293 | e1e_wphy(hw, PHY_CONTROL, 0x9140); | ||
1294 | /* autoneg off */ | ||
1295 | e1e_wphy(hw, PHY_CONTROL, 0x8140); | ||
1296 | break; | ||
1297 | case e1000_phy_gg82563: | ||
1298 | e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); | ||
1293 | break; | 1299 | break; |
1294 | case e1000_phy_bm: | 1300 | case e1000_phy_bm: |
1295 | /* Set Default MAC Interface speed to 1GB */ | 1301 | /* Set Default MAC Interface speed to 1GB */ |
@@ -1312,23 +1318,41 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1312 | /* Set Early Link Enable */ | 1318 | /* Set Early Link Enable */ |
1313 | e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); | 1319 | e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); |
1314 | e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400); | 1320 | e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400); |
1315 | /* fall through */ | 1321 | break; |
1322 | case e1000_phy_82577: | ||
1323 | case e1000_phy_82578: | ||
1324 | /* Workaround: K1 must be disabled for stable 1Gbps operation */ | ||
1325 | e1000_configure_k1_ich8lan(hw, false); | ||
1326 | break; | ||
1327 | case e1000_phy_82579: | ||
1328 | /* Disable PHY energy detect power down */ | ||
1329 | e1e_rphy(hw, PHY_REG(0, 21), &phy_reg); | ||
1330 | e1e_wphy(hw, PHY_REG(0, 21), phy_reg & ~(1 << 3)); | ||
1331 | /* Disable full chip energy detect */ | ||
1332 | e1e_rphy(hw, PHY_REG(776, 18), &phy_reg); | ||
1333 | e1e_wphy(hw, PHY_REG(776, 18), phy_reg | 1); | ||
1334 | /* Enable loopback on the PHY */ | ||
1335 | #define I82577_PHY_LBK_CTRL 19 | ||
1336 | e1e_wphy(hw, I82577_PHY_LBK_CTRL, 0x8001); | ||
1337 | break; | ||
1316 | default: | 1338 | default: |
1317 | /* force 1000, set loopback */ | 1339 | break; |
1318 | e1e_wphy(hw, PHY_CONTROL, 0x4140); | 1340 | } |
1319 | mdelay(250); | ||
1320 | 1341 | ||
1321 | /* Now set up the MAC to the same speed/duplex as the PHY. */ | 1342 | /* force 1000, set loopback */ |
1322 | ctrl_reg = er32(CTRL); | 1343 | e1e_wphy(hw, PHY_CONTROL, 0x4140); |
1323 | ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ | 1344 | mdelay(250); |
1324 | ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ | ||
1325 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ | ||
1326 | E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ | ||
1327 | E1000_CTRL_FD); /* Force Duplex to FULL */ | ||
1328 | 1345 | ||
1329 | if (adapter->flags & FLAG_IS_ICH) | 1346 | /* Now set up the MAC to the same speed/duplex as the PHY. */ |
1330 | ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ | 1347 | ctrl_reg = er32(CTRL); |
1331 | } | 1348 | ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ |
1349 | ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ | ||
1350 | E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ | ||
1351 | E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ | ||
1352 | E1000_CTRL_FD); /* Force Duplex to FULL */ | ||
1353 | |||
1354 | if (adapter->flags & FLAG_IS_ICH) | ||
1355 | ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ | ||
1332 | 1356 | ||
1333 | if (hw->phy.media_type == e1000_media_type_copper && | 1357 | if (hw->phy.media_type == e1000_media_type_copper && |
1334 | hw->phy.type == e1000_phy_m88) { | 1358 | hw->phy.type == e1000_phy_m88) { |
@@ -1868,6 +1892,7 @@ static int e1000_phys_id(struct net_device *netdev, u32 data) | |||
1868 | 1892 | ||
1869 | if ((hw->phy.type == e1000_phy_ife) || | 1893 | if ((hw->phy.type == e1000_phy_ife) || |
1870 | (hw->mac.type == e1000_pchlan) || | 1894 | (hw->mac.type == e1000_pchlan) || |
1895 | (hw->mac.type == e1000_pch2lan) || | ||
1871 | (hw->mac.type == e1000_82583) || | 1896 | (hw->mac.type == e1000_82583) || |
1872 | (hw->mac.type == e1000_82574)) { | 1897 | (hw->mac.type == e1000_82574)) { |
1873 | INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); | 1898 | INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); |
@@ -2026,7 +2051,6 @@ static const struct ethtool_ops e1000_ethtool_ops = { | |||
2026 | .get_coalesce = e1000_get_coalesce, | 2051 | .get_coalesce = e1000_get_coalesce, |
2027 | .set_coalesce = e1000_set_coalesce, | 2052 | .set_coalesce = e1000_set_coalesce, |
2028 | .get_flags = ethtool_op_get_flags, | 2053 | .get_flags = ethtool_op_get_flags, |
2029 | .set_flags = ethtool_op_set_flags, | ||
2030 | }; | 2054 | }; |
2031 | 2055 | ||
2032 | void e1000e_set_ethtool_ops(struct net_device *netdev) | 2056 | void e1000e_set_ethtool_ops(struct net_device *netdev) |