diff options
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 70 |
1 files changed, 46 insertions, 24 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ffdf76b725bc..ceb9cd059b90 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -1326,22 +1326,33 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter) | |||
1326 | static int | 1326 | static int |
1327 | e1000_setup_loopback_test(struct e1000_adapter *adapter) | 1327 | e1000_setup_loopback_test(struct e1000_adapter *adapter) |
1328 | { | 1328 | { |
1329 | struct e1000_hw *hw = &adapter->hw; | ||
1329 | uint32_t rctl; | 1330 | uint32_t rctl; |
1330 | 1331 | ||
1331 | if(adapter->hw.media_type == e1000_media_type_fiber || | 1332 | if (hw->media_type == e1000_media_type_fiber || |
1332 | adapter->hw.media_type == e1000_media_type_internal_serdes) { | 1333 | hw->media_type == e1000_media_type_internal_serdes) { |
1333 | if(adapter->hw.mac_type == e1000_82545 || | 1334 | switch (hw->mac_type) { |
1334 | adapter->hw.mac_type == e1000_82546 || | 1335 | case e1000_82545: |
1335 | adapter->hw.mac_type == e1000_82545_rev_3 || | 1336 | case e1000_82546: |
1336 | adapter->hw.mac_type == e1000_82546_rev_3) | 1337 | case e1000_82545_rev_3: |
1338 | case e1000_82546_rev_3: | ||
1337 | return e1000_set_phy_loopback(adapter); | 1339 | return e1000_set_phy_loopback(adapter); |
1338 | else { | 1340 | break; |
1339 | rctl = E1000_READ_REG(&adapter->hw, RCTL); | 1341 | case e1000_82571: |
1342 | case e1000_82572: | ||
1343 | #define E1000_SERDES_LB_ON 0x410 | ||
1344 | e1000_set_phy_loopback(adapter); | ||
1345 | E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON); | ||
1346 | msec_delay(10); | ||
1347 | return 0; | ||
1348 | break; | ||
1349 | default: | ||
1350 | rctl = E1000_READ_REG(hw, RCTL); | ||
1340 | rctl |= E1000_RCTL_LBM_TCVR; | 1351 | rctl |= E1000_RCTL_LBM_TCVR; |
1341 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); | 1352 | E1000_WRITE_REG(hw, RCTL, rctl); |
1342 | return 0; | 1353 | return 0; |
1343 | } | 1354 | } |
1344 | } else if(adapter->hw.media_type == e1000_media_type_copper) | 1355 | } else if (hw->media_type == e1000_media_type_copper) |
1345 | return e1000_set_phy_loopback(adapter); | 1356 | return e1000_set_phy_loopback(adapter); |
1346 | 1357 | ||
1347 | return 7; | 1358 | return 7; |
@@ -1350,27 +1361,38 @@ e1000_setup_loopback_test(struct e1000_adapter *adapter) | |||
1350 | static void | 1361 | static void |
1351 | e1000_loopback_cleanup(struct e1000_adapter *adapter) | 1362 | e1000_loopback_cleanup(struct e1000_adapter *adapter) |
1352 | { | 1363 | { |
1364 | struct e1000_hw *hw = &adapter->hw; | ||
1353 | uint32_t rctl; | 1365 | uint32_t rctl; |
1354 | uint16_t phy_reg; | 1366 | uint16_t phy_reg; |
1355 | 1367 | ||
1356 | rctl = E1000_READ_REG(&adapter->hw, RCTL); | 1368 | rctl = E1000_READ_REG(hw, RCTL); |
1357 | rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); | 1369 | rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); |
1358 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); | 1370 | E1000_WRITE_REG(hw, RCTL, rctl); |
1359 | 1371 | ||
1360 | if(adapter->hw.media_type == e1000_media_type_copper || | 1372 | switch (hw->mac_type) { |
1361 | ((adapter->hw.media_type == e1000_media_type_fiber || | 1373 | case e1000_82571: |
1362 | adapter->hw.media_type == e1000_media_type_internal_serdes) && | 1374 | case e1000_82572: |
1363 | (adapter->hw.mac_type == e1000_82545 || | 1375 | if (hw->media_type == e1000_media_type_fiber || |
1364 | adapter->hw.mac_type == e1000_82546 || | 1376 | hw->media_type == e1000_media_type_internal_serdes) { |
1365 | adapter->hw.mac_type == e1000_82545_rev_3 || | 1377 | #define E1000_SERDES_LB_OFF 0x400 |
1366 | adapter->hw.mac_type == e1000_82546_rev_3))) { | 1378 | E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF); |
1367 | adapter->hw.autoneg = TRUE; | 1379 | msec_delay(10); |
1368 | e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); | 1380 | break; |
1369 | if(phy_reg & MII_CR_LOOPBACK) { | 1381 | } |
1382 | /* Fall Through */ | ||
1383 | case e1000_82545: | ||
1384 | case e1000_82546: | ||
1385 | case e1000_82545_rev_3: | ||
1386 | case e1000_82546_rev_3: | ||
1387 | default: | ||
1388 | hw->autoneg = TRUE; | ||
1389 | e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); | ||
1390 | if (phy_reg & MII_CR_LOOPBACK) { | ||
1370 | phy_reg &= ~MII_CR_LOOPBACK; | 1391 | phy_reg &= ~MII_CR_LOOPBACK; |
1371 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); | 1392 | e1000_write_phy_reg(hw, PHY_CTRL, phy_reg); |
1372 | e1000_phy_reset(&adapter->hw); | 1393 | e1000_phy_reset(hw); |
1373 | } | 1394 | } |
1395 | break; | ||
1374 | } | 1396 | } |
1375 | } | 1397 | } |
1376 | 1398 | ||