diff options
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 88a82ba88f57..2baccf864328 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -183,6 +183,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | } | 184 | } |
185 | 185 | ||
186 | while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) | ||
187 | msleep(1); | ||
188 | |||
186 | if (ecmd->autoneg == AUTONEG_ENABLE) { | 189 | if (ecmd->autoneg == AUTONEG_ENABLE) { |
187 | hw->autoneg = 1; | 190 | hw->autoneg = 1; |
188 | if (hw->media_type == e1000_media_type_fiber) | 191 | if (hw->media_type == e1000_media_type_fiber) |
@@ -199,16 +202,20 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
199 | ADVERTISED_TP; | 202 | ADVERTISED_TP; |
200 | ecmd->advertising = hw->autoneg_advertised; | 203 | ecmd->advertising = hw->autoneg_advertised; |
201 | } else | 204 | } else |
202 | if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) | 205 | if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { |
206 | clear_bit(__E1000_RESETTING, &adapter->flags); | ||
203 | return -EINVAL; | 207 | return -EINVAL; |
208 | } | ||
204 | 209 | ||
205 | /* reset the link */ | 210 | /* reset the link */ |
206 | 211 | ||
207 | if (netif_running(adapter->netdev)) | 212 | if (netif_running(adapter->netdev)) { |
208 | e1000_reinit_locked(adapter); | 213 | e1000_down(adapter); |
209 | else | 214 | e1000_up(adapter); |
215 | } else | ||
210 | e1000_reset(adapter); | 216 | e1000_reset(adapter); |
211 | 217 | ||
218 | clear_bit(__E1000_RESETTING, &adapter->flags); | ||
212 | return 0; | 219 | return 0; |
213 | } | 220 | } |
214 | 221 | ||
@@ -238,9 +245,13 @@ e1000_set_pauseparam(struct net_device *netdev, | |||
238 | { | 245 | { |
239 | struct e1000_adapter *adapter = netdev_priv(netdev); | 246 | struct e1000_adapter *adapter = netdev_priv(netdev); |
240 | struct e1000_hw *hw = &adapter->hw; | 247 | struct e1000_hw *hw = &adapter->hw; |
248 | int retval = 0; | ||
241 | 249 | ||
242 | adapter->fc_autoneg = pause->autoneg; | 250 | adapter->fc_autoneg = pause->autoneg; |
243 | 251 | ||
252 | while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) | ||
253 | msleep(1); | ||
254 | |||
244 | if (pause->rx_pause && pause->tx_pause) | 255 | if (pause->rx_pause && pause->tx_pause) |
245 | hw->fc = e1000_fc_full; | 256 | hw->fc = e1000_fc_full; |
246 | else if (pause->rx_pause && !pause->tx_pause) | 257 | else if (pause->rx_pause && !pause->tx_pause) |
@@ -253,15 +264,17 @@ e1000_set_pauseparam(struct net_device *netdev, | |||
253 | hw->original_fc = hw->fc; | 264 | hw->original_fc = hw->fc; |
254 | 265 | ||
255 | if (adapter->fc_autoneg == AUTONEG_ENABLE) { | 266 | if (adapter->fc_autoneg == AUTONEG_ENABLE) { |
256 | if (netif_running(adapter->netdev)) | 267 | if (netif_running(adapter->netdev)) { |
257 | e1000_reinit_locked(adapter); | 268 | e1000_down(adapter); |
258 | else | 269 | e1000_up(adapter); |
270 | } else | ||
259 | e1000_reset(adapter); | 271 | e1000_reset(adapter); |
260 | } else | 272 | } else |
261 | return ((hw->media_type == e1000_media_type_fiber) ? | 273 | retval = ((hw->media_type == e1000_media_type_fiber) ? |
262 | e1000_setup_link(hw) : e1000_force_mac_fc(hw)); | 274 | e1000_setup_link(hw) : e1000_force_mac_fc(hw)); |
263 | 275 | ||
264 | return 0; | 276 | clear_bit(__E1000_RESETTING, &adapter->flags); |
277 | return retval; | ||
265 | } | 278 | } |
266 | 279 | ||
267 | static uint32_t | 280 | static uint32_t |
@@ -1590,6 +1603,8 @@ e1000_diag_test_count(struct net_device *netdev) | |||
1590 | return E1000_TEST_LEN; | 1603 | return E1000_TEST_LEN; |
1591 | } | 1604 | } |
1592 | 1605 | ||
1606 | extern void e1000_power_up_phy(struct e1000_adapter *); | ||
1607 | |||
1593 | static void | 1608 | static void |
1594 | e1000_diag_test(struct net_device *netdev, | 1609 | e1000_diag_test(struct net_device *netdev, |
1595 | struct ethtool_test *eth_test, uint64_t *data) | 1610 | struct ethtool_test *eth_test, uint64_t *data) |
@@ -1606,6 +1621,8 @@ e1000_diag_test(struct net_device *netdev, | |||
1606 | uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex; | 1621 | uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex; |
1607 | uint8_t autoneg = adapter->hw.autoneg; | 1622 | uint8_t autoneg = adapter->hw.autoneg; |
1608 | 1623 | ||
1624 | DPRINTK(HW, INFO, "offline testing starting\n"); | ||
1625 | |||
1609 | /* Link test performed before hardware reset so autoneg doesn't | 1626 | /* Link test performed before hardware reset so autoneg doesn't |
1610 | * interfere with test result */ | 1627 | * interfere with test result */ |
1611 | if (e1000_link_test(adapter, &data[4])) | 1628 | if (e1000_link_test(adapter, &data[4])) |
@@ -1629,6 +1646,8 @@ e1000_diag_test(struct net_device *netdev, | |||
1629 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1646 | eth_test->flags |= ETH_TEST_FL_FAILED; |
1630 | 1647 | ||
1631 | e1000_reset(adapter); | 1648 | e1000_reset(adapter); |
1649 | /* make sure the phy is powered up */ | ||
1650 | e1000_power_up_phy(adapter); | ||
1632 | if (e1000_loopback_test(adapter, &data[3])) | 1651 | if (e1000_loopback_test(adapter, &data[3])) |
1633 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1652 | eth_test->flags |= ETH_TEST_FL_FAILED; |
1634 | 1653 | ||
@@ -1642,6 +1661,7 @@ e1000_diag_test(struct net_device *netdev, | |||
1642 | if (if_running) | 1661 | if (if_running) |
1643 | dev_open(netdev); | 1662 | dev_open(netdev); |
1644 | } else { | 1663 | } else { |
1664 | DPRINTK(HW, INFO, "online testing starting\n"); | ||
1645 | /* Online tests */ | 1665 | /* Online tests */ |
1646 | if (e1000_link_test(adapter, &data[4])) | 1666 | if (e1000_link_test(adapter, &data[4])) |
1647 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1667 | eth_test->flags |= ETH_TEST_FL_FAILED; |