diff options
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 111 |
1 files changed, 85 insertions, 26 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 8eae8ba27e84..c88f1a3c1b1d 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -562,10 +562,29 @@ e1000_get_drvinfo(struct net_device *netdev, | |||
562 | struct ethtool_drvinfo *drvinfo) | 562 | struct ethtool_drvinfo *drvinfo) |
563 | { | 563 | { |
564 | struct e1000_adapter *adapter = netdev_priv(netdev); | 564 | struct e1000_adapter *adapter = netdev_priv(netdev); |
565 | char firmware_version[32]; | ||
566 | uint16_t eeprom_data; | ||
565 | 567 | ||
566 | strncpy(drvinfo->driver, e1000_driver_name, 32); | 568 | strncpy(drvinfo->driver, e1000_driver_name, 32); |
567 | strncpy(drvinfo->version, e1000_driver_version, 32); | 569 | strncpy(drvinfo->version, e1000_driver_version, 32); |
568 | strncpy(drvinfo->fw_version, "N/A", 32); | 570 | |
571 | /* EEPROM image version # is reported as firware version # for | ||
572 | * 8257{1|2|3} controllers */ | ||
573 | e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data); | ||
574 | switch (adapter->hw.mac_type) { | ||
575 | case e1000_82571: | ||
576 | case e1000_82572: | ||
577 | case e1000_82573: | ||
578 | sprintf(firmware_version, "%d.%d-%d", | ||
579 | (eeprom_data & 0xF000) >> 12, | ||
580 | (eeprom_data & 0x0FF0) >> 4, | ||
581 | eeprom_data & 0x000F); | ||
582 | break; | ||
583 | default: | ||
584 | sprintf(firmware_version, "n/a"); | ||
585 | } | ||
586 | |||
587 | strncpy(drvinfo->fw_version, firmware_version, 32); | ||
569 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 588 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); |
570 | drvinfo->n_stats = E1000_STATS_LEN; | 589 | drvinfo->n_stats = E1000_STATS_LEN; |
571 | drvinfo->testinfo_len = E1000_TEST_LEN; | 590 | drvinfo->testinfo_len = E1000_TEST_LEN; |
@@ -960,13 +979,21 @@ e1000_free_desc_rings(struct e1000_adapter *adapter) | |||
960 | } | 979 | } |
961 | } | 980 | } |
962 | 981 | ||
963 | if(txdr->desc) | 982 | if(txdr->desc) { |
964 | pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma); | 983 | pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma); |
965 | if(rxdr->desc) | 984 | txdr->desc = NULL; |
985 | } | ||
986 | if(rxdr->desc) { | ||
966 | pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); | 987 | pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); |
988 | rxdr->desc = NULL; | ||
989 | } | ||
967 | 990 | ||
968 | kfree(txdr->buffer_info); | 991 | kfree(txdr->buffer_info); |
992 | txdr->buffer_info = NULL; | ||
993 | |||
969 | kfree(rxdr->buffer_info); | 994 | kfree(rxdr->buffer_info); |
995 | rxdr->buffer_info = NULL; | ||
996 | |||
970 | return; | 997 | return; |
971 | } | 998 | } |
972 | 999 | ||
@@ -1301,21 +1328,32 @@ static int | |||
1301 | e1000_setup_loopback_test(struct e1000_adapter *adapter) | 1328 | e1000_setup_loopback_test(struct e1000_adapter *adapter) |
1302 | { | 1329 | { |
1303 | uint32_t rctl; | 1330 | uint32_t rctl; |
1331 | struct e1000_hw *hw = &adapter->hw; | ||
1304 | 1332 | ||
1305 | if(adapter->hw.media_type == e1000_media_type_fiber || | 1333 | if (hw->media_type == e1000_media_type_fiber || |
1306 | adapter->hw.media_type == e1000_media_type_internal_serdes) { | 1334 | hw->media_type == e1000_media_type_internal_serdes) { |
1307 | if(adapter->hw.mac_type == e1000_82545 || | 1335 | switch (hw->mac_type) { |
1308 | adapter->hw.mac_type == e1000_82546 || | 1336 | case e1000_82545: |
1309 | adapter->hw.mac_type == e1000_82545_rev_3 || | 1337 | case e1000_82546: |
1310 | adapter->hw.mac_type == e1000_82546_rev_3) | 1338 | case e1000_82545_rev_3: |
1339 | case e1000_82546_rev_3: | ||
1311 | return e1000_set_phy_loopback(adapter); | 1340 | return e1000_set_phy_loopback(adapter); |
1312 | else { | 1341 | break; |
1313 | rctl = E1000_READ_REG(&adapter->hw, RCTL); | 1342 | case e1000_82571: |
1343 | case e1000_82572: | ||
1344 | #define E1000_SERDES_LB_ON 0x410 | ||
1345 | e1000_set_phy_loopback(adapter); | ||
1346 | E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON); | ||
1347 | msec_delay(10); | ||
1348 | return 0; | ||
1349 | break; | ||
1350 | default: | ||
1351 | rctl = E1000_READ_REG(hw, RCTL); | ||
1314 | rctl |= E1000_RCTL_LBM_TCVR; | 1352 | rctl |= E1000_RCTL_LBM_TCVR; |
1315 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); | 1353 | E1000_WRITE_REG(hw, RCTL, rctl); |
1316 | return 0; | 1354 | return 0; |
1317 | } | 1355 | } |
1318 | } else if(adapter->hw.media_type == e1000_media_type_copper) | 1356 | } else if (hw->media_type == e1000_media_type_copper) |
1319 | return e1000_set_phy_loopback(adapter); | 1357 | return e1000_set_phy_loopback(adapter); |
1320 | 1358 | ||
1321 | return 7; | 1359 | return 7; |
@@ -1326,25 +1364,36 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter) | |||
1326 | { | 1364 | { |
1327 | uint32_t rctl; | 1365 | uint32_t rctl; |
1328 | uint16_t phy_reg; | 1366 | uint16_t phy_reg; |
1367 | struct e1000_hw *hw = &adapter->hw; | ||
1329 | 1368 | ||
1330 | rctl = E1000_READ_REG(&adapter->hw, RCTL); | 1369 | rctl = E1000_READ_REG(&adapter->hw, RCTL); |
1331 | rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); | 1370 | rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); |
1332 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); | 1371 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); |
1333 | 1372 | ||
1334 | if(adapter->hw.media_type == e1000_media_type_copper || | 1373 | switch (hw->mac_type) { |
1335 | ((adapter->hw.media_type == e1000_media_type_fiber || | 1374 | case e1000_82571: |
1336 | adapter->hw.media_type == e1000_media_type_internal_serdes) && | 1375 | case e1000_82572: |
1337 | (adapter->hw.mac_type == e1000_82545 || | 1376 | if (hw->media_type == e1000_media_type_fiber || |
1338 | adapter->hw.mac_type == e1000_82546 || | 1377 | hw->media_type == e1000_media_type_internal_serdes){ |
1339 | adapter->hw.mac_type == e1000_82545_rev_3 || | 1378 | #define E1000_SERDES_LB_OFF 0x400 |
1340 | adapter->hw.mac_type == e1000_82546_rev_3))) { | 1379 | E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF); |
1341 | adapter->hw.autoneg = TRUE; | 1380 | msec_delay(10); |
1342 | e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); | 1381 | break; |
1343 | if(phy_reg & MII_CR_LOOPBACK) { | 1382 | } |
1383 | /* fall thru for Cu adapters */ | ||
1384 | case e1000_82545: | ||
1385 | case e1000_82546: | ||
1386 | case e1000_82545_rev_3: | ||
1387 | case e1000_82546_rev_3: | ||
1388 | default: | ||
1389 | hw->autoneg = TRUE; | ||
1390 | e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); | ||
1391 | if (phy_reg & MII_CR_LOOPBACK) { | ||
1344 | phy_reg &= ~MII_CR_LOOPBACK; | 1392 | phy_reg &= ~MII_CR_LOOPBACK; |
1345 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); | 1393 | e1000_write_phy_reg(hw, PHY_CTRL, phy_reg); |
1346 | e1000_phy_reset(&adapter->hw); | 1394 | e1000_phy_reset(hw); |
1347 | } | 1395 | } |
1396 | break; | ||
1348 | } | 1397 | } |
1349 | } | 1398 | } |
1350 | 1399 | ||
@@ -1440,9 +1489,11 @@ static int | |||
1440 | e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data) | 1489 | e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data) |
1441 | { | 1490 | { |
1442 | if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback; | 1491 | if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback; |
1443 | if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback; | 1492 | if((*data = e1000_setup_loopback_test(adapter))) |
1493 | goto err_loopback_setup; | ||
1444 | *data = e1000_run_loopback_test(adapter); | 1494 | *data = e1000_run_loopback_test(adapter); |
1445 | e1000_loopback_cleanup(adapter); | 1495 | e1000_loopback_cleanup(adapter); |
1496 | err_loopback_setup: | ||
1446 | e1000_free_desc_rings(adapter); | 1497 | e1000_free_desc_rings(adapter); |
1447 | err_loopback: | 1498 | err_loopback: |
1448 | return *data; | 1499 | return *data; |
@@ -1671,6 +1722,14 @@ e1000_phys_id(struct net_device *netdev, uint32_t data) | |||
1671 | msleep_interruptible(data * 1000); | 1722 | msleep_interruptible(data * 1000); |
1672 | del_timer_sync(&adapter->blink_timer); | 1723 | del_timer_sync(&adapter->blink_timer); |
1673 | } | 1724 | } |
1725 | else if(adapter->hw.mac_type < e1000_82573) { | ||
1726 | E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | | ||
1727 | E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK | | ||
1728 | (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) | | ||
1729 | (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) | | ||
1730 | (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT))); | ||
1731 | msleep_interruptible(data * 1000); | ||
1732 | } | ||
1674 | else { | 1733 | else { |
1675 | E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | | 1734 | E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | |
1676 | E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | | 1735 | E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | |