diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2005-12-13 00:06:22 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-12-13 00:06:22 -0500 |
commit | fd803241744ad6e4262b6588c6af89e8fb794098 (patch) | |
tree | d8c4261a4799a2c9ee980cdd6a0c3c5ac61cafed /drivers/net/e1000 | |
parent | ff7eba15ae65e4299fd9e0fbf067477ce6b43d91 (diff) |
e1000: Fixes for 8357x
- TSO workaround
- Fixes eeprom version reporting
- Fix loopback test
- Fix for WOL
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r-- | drivers/net/e1000/e1000.h | 4 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 95 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_hw.c | 67 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 64 |
5 files changed, 150 insertions, 84 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 3f653a93e1bc..e02e9ba2e18b 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -188,11 +188,13 @@ struct e1000_tx_ring { | |||
188 | /* array of buffer information structs */ | 188 | /* array of buffer information structs */ |
189 | struct e1000_buffer *buffer_info; | 189 | struct e1000_buffer *buffer_info; |
190 | 190 | ||
191 | struct e1000_buffer previous_buffer_info; | ||
192 | spinlock_t tx_lock; | 191 | spinlock_t tx_lock; |
193 | uint16_t tdh; | 192 | uint16_t tdh; |
194 | uint16_t tdt; | 193 | uint16_t tdt; |
195 | uint64_t pkt; | 194 | uint64_t pkt; |
195 | |||
196 | boolean_t last_tx_tso; | ||
197 | |||
196 | }; | 198 | }; |
197 | 199 | ||
198 | struct e1000_rx_ring { | 200 | struct e1000_rx_ring { |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 8646914964e7..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; |
@@ -1309,21 +1328,32 @@ static int | |||
1309 | e1000_setup_loopback_test(struct e1000_adapter *adapter) | 1328 | e1000_setup_loopback_test(struct e1000_adapter *adapter) |
1310 | { | 1329 | { |
1311 | uint32_t rctl; | 1330 | uint32_t rctl; |
1331 | struct e1000_hw *hw = &adapter->hw; | ||
1312 | 1332 | ||
1313 | if(adapter->hw.media_type == e1000_media_type_fiber || | 1333 | if (hw->media_type == e1000_media_type_fiber || |
1314 | adapter->hw.media_type == e1000_media_type_internal_serdes) { | 1334 | hw->media_type == e1000_media_type_internal_serdes) { |
1315 | if(adapter->hw.mac_type == e1000_82545 || | 1335 | switch (hw->mac_type) { |
1316 | adapter->hw.mac_type == e1000_82546 || | 1336 | case e1000_82545: |
1317 | adapter->hw.mac_type == e1000_82545_rev_3 || | 1337 | case e1000_82546: |
1318 | adapter->hw.mac_type == e1000_82546_rev_3) | 1338 | case e1000_82545_rev_3: |
1339 | case e1000_82546_rev_3: | ||
1319 | return e1000_set_phy_loopback(adapter); | 1340 | return e1000_set_phy_loopback(adapter); |
1320 | else { | 1341 | break; |
1321 | 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); | ||
1322 | rctl |= E1000_RCTL_LBM_TCVR; | 1352 | rctl |= E1000_RCTL_LBM_TCVR; |
1323 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); | 1353 | E1000_WRITE_REG(hw, RCTL, rctl); |
1324 | return 0; | 1354 | return 0; |
1325 | } | 1355 | } |
1326 | } else if(adapter->hw.media_type == e1000_media_type_copper) | 1356 | } else if (hw->media_type == e1000_media_type_copper) |
1327 | return e1000_set_phy_loopback(adapter); | 1357 | return e1000_set_phy_loopback(adapter); |
1328 | 1358 | ||
1329 | return 7; | 1359 | return 7; |
@@ -1334,25 +1364,36 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter) | |||
1334 | { | 1364 | { |
1335 | uint32_t rctl; | 1365 | uint32_t rctl; |
1336 | uint16_t phy_reg; | 1366 | uint16_t phy_reg; |
1367 | struct e1000_hw *hw = &adapter->hw; | ||
1337 | 1368 | ||
1338 | rctl = E1000_READ_REG(&adapter->hw, RCTL); | 1369 | rctl = E1000_READ_REG(&adapter->hw, RCTL); |
1339 | rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); | 1370 | rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); |
1340 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); | 1371 | E1000_WRITE_REG(&adapter->hw, RCTL, rctl); |
1341 | 1372 | ||
1342 | if(adapter->hw.media_type == e1000_media_type_copper || | 1373 | switch (hw->mac_type) { |
1343 | ((adapter->hw.media_type == e1000_media_type_fiber || | 1374 | case e1000_82571: |
1344 | adapter->hw.media_type == e1000_media_type_internal_serdes) && | 1375 | case e1000_82572: |
1345 | (adapter->hw.mac_type == e1000_82545 || | 1376 | if (hw->media_type == e1000_media_type_fiber || |
1346 | adapter->hw.mac_type == e1000_82546 || | 1377 | hw->media_type == e1000_media_type_internal_serdes){ |
1347 | adapter->hw.mac_type == e1000_82545_rev_3 || | 1378 | #define E1000_SERDES_LB_OFF 0x400 |
1348 | adapter->hw.mac_type == e1000_82546_rev_3))) { | 1379 | E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF); |
1349 | adapter->hw.autoneg = TRUE; | 1380 | msec_delay(10); |
1350 | e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); | 1381 | break; |
1351 | 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) { | ||
1352 | phy_reg &= ~MII_CR_LOOPBACK; | 1392 | phy_reg &= ~MII_CR_LOOPBACK; |
1353 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); | 1393 | e1000_write_phy_reg(hw, PHY_CTRL, phy_reg); |
1354 | e1000_phy_reset(&adapter->hw); | 1394 | e1000_phy_reset(hw); |
1355 | } | 1395 | } |
1396 | break; | ||
1356 | } | 1397 | } |
1357 | } | 1398 | } |
1358 | 1399 | ||
@@ -1681,6 +1722,14 @@ e1000_phys_id(struct net_device *netdev, uint32_t data) | |||
1681 | msleep_interruptible(data * 1000); | 1722 | msleep_interruptible(data * 1000); |
1682 | del_timer_sync(&adapter->blink_timer); | 1723 | del_timer_sync(&adapter->blink_timer); |
1683 | } | 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 | } | ||
1684 | else { | 1733 | else { |
1685 | E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | | 1734 | E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | |
1686 | E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | | 1735 | E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | |
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index a267c5235fc0..136fc031e4ad 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c | |||
@@ -563,11 +563,13 @@ e1000_reset_hw(struct e1000_hw *hw) | |||
563 | msec_delay(20); | 563 | msec_delay(20); |
564 | break; | 564 | break; |
565 | case e1000_82573: | 565 | case e1000_82573: |
566 | udelay(10); | 566 | if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) { |
567 | ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); | 567 | udelay(10); |
568 | ctrl_ext |= E1000_CTRL_EXT_EE_RST; | 568 | ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); |
569 | E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); | 569 | ctrl_ext |= E1000_CTRL_EXT_EE_RST; |
570 | E1000_WRITE_FLUSH(hw); | 570 | E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); |
571 | E1000_WRITE_FLUSH(hw); | ||
572 | } | ||
571 | /* fall through */ | 573 | /* fall through */ |
572 | case e1000_82571: | 574 | case e1000_82571: |
573 | case e1000_82572: | 575 | case e1000_82572: |
@@ -844,19 +846,27 @@ e1000_setup_link(struct e1000_hw *hw) | |||
844 | * control setting, then the variable hw->fc will | 846 | * control setting, then the variable hw->fc will |
845 | * be initialized based on a value in the EEPROM. | 847 | * be initialized based on a value in the EEPROM. |
846 | */ | 848 | */ |
847 | if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) { | 849 | if (hw->fc == e1000_fc_default) { |
848 | DEBUGOUT("EEPROM Read Error\n"); | 850 | switch (hw->mac_type) { |
849 | return -E1000_ERR_EEPROM; | 851 | case e1000_82573: |
850 | } | ||
851 | |||
852 | if(hw->fc == e1000_fc_default) { | ||
853 | if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) | ||
854 | hw->fc = e1000_fc_none; | ||
855 | else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == | ||
856 | EEPROM_WORD0F_ASM_DIR) | ||
857 | hw->fc = e1000_fc_tx_pause; | ||
858 | else | ||
859 | hw->fc = e1000_fc_full; | 852 | hw->fc = e1000_fc_full; |
853 | break; | ||
854 | default: | ||
855 | ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, | ||
856 | 1, &eeprom_data); | ||
857 | if (ret_val) { | ||
858 | DEBUGOUT("EEPROM Read Error\n"); | ||
859 | return -E1000_ERR_EEPROM; | ||
860 | } | ||
861 | if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) | ||
862 | hw->fc = e1000_fc_none; | ||
863 | else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == | ||
864 | EEPROM_WORD0F_ASM_DIR) | ||
865 | hw->fc = e1000_fc_tx_pause; | ||
866 | else | ||
867 | hw->fc = e1000_fc_full; | ||
868 | break; | ||
869 | } | ||
860 | } | 870 | } |
861 | 871 | ||
862 | /* We want to save off the original Flow Control configuration just | 872 | /* We want to save off the original Flow Control configuration just |
@@ -2962,13 +2972,22 @@ e1000_phy_hw_reset(struct e1000_hw *hw) | |||
2962 | if(hw->mac_type > e1000_82543) { | 2972 | if(hw->mac_type > e1000_82543) { |
2963 | /* Read the device control register and assert the E1000_CTRL_PHY_RST | 2973 | /* Read the device control register and assert the E1000_CTRL_PHY_RST |
2964 | * bit. Then, take it out of reset. | 2974 | * bit. Then, take it out of reset. |
2975 | * For pre-e1000_82571 hardware, we delay for 10ms between the assert | ||
2976 | * and deassert. For e1000_82571 hardware and later, we instead delay | ||
2977 | * for 10ms after the deassertion. | ||
2965 | */ | 2978 | */ |
2966 | ctrl = E1000_READ_REG(hw, CTRL); | 2979 | ctrl = E1000_READ_REG(hw, CTRL); |
2967 | E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); | 2980 | E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); |
2968 | E1000_WRITE_FLUSH(hw); | 2981 | E1000_WRITE_FLUSH(hw); |
2969 | msec_delay(10); | 2982 | |
2983 | if (hw->mac_type < e1000_82571) | ||
2984 | msec_delay(10); | ||
2985 | |||
2970 | E1000_WRITE_REG(hw, CTRL, ctrl); | 2986 | E1000_WRITE_REG(hw, CTRL, ctrl); |
2971 | E1000_WRITE_FLUSH(hw); | 2987 | E1000_WRITE_FLUSH(hw); |
2988 | |||
2989 | if (hw->mac_type >= e1000_82571) | ||
2990 | msec_delay(10); | ||
2972 | } else { | 2991 | } else { |
2973 | /* Read the Extended Device Control Register, assert the PHY_RESET_DIR | 2992 | /* Read the Extended Device Control Register, assert the PHY_RESET_DIR |
2974 | * bit to put the PHY into reset. Then, take it out of reset. | 2993 | * bit to put the PHY into reset. Then, take it out of reset. |
@@ -5278,11 +5297,15 @@ e1000_get_bus_info(struct e1000_hw *hw) | |||
5278 | hw->bus_speed = e1000_bus_speed_unknown; | 5297 | hw->bus_speed = e1000_bus_speed_unknown; |
5279 | hw->bus_width = e1000_bus_width_unknown; | 5298 | hw->bus_width = e1000_bus_width_unknown; |
5280 | break; | 5299 | break; |
5281 | case e1000_82571: | ||
5282 | case e1000_82572: | 5300 | case e1000_82572: |
5283 | case e1000_82573: | 5301 | case e1000_82573: |
5284 | hw->bus_type = e1000_bus_type_pci_express; | 5302 | hw->bus_type = e1000_bus_type_pci_express; |
5285 | hw->bus_speed = e1000_bus_speed_2500; | 5303 | hw->bus_speed = e1000_bus_speed_2500; |
5304 | hw->bus_width = e1000_bus_width_pciex_1; | ||
5305 | break; | ||
5306 | case e1000_82571: | ||
5307 | hw->bus_type = e1000_bus_type_pci_express; | ||
5308 | hw->bus_speed = e1000_bus_speed_2500; | ||
5286 | hw->bus_width = e1000_bus_width_pciex_4; | 5309 | hw->bus_width = e1000_bus_width_pciex_4; |
5287 | break; | 5310 | break; |
5288 | default: | 5311 | default: |
@@ -6650,6 +6673,12 @@ e1000_get_auto_rd_done(struct e1000_hw *hw) | |||
6650 | break; | 6673 | break; |
6651 | } | 6674 | } |
6652 | 6675 | ||
6676 | /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high. | ||
6677 | * Need to wait for PHY configuration completion before accessing NVM | ||
6678 | * and PHY. */ | ||
6679 | if (hw->mac_type == e1000_82573) | ||
6680 | msec_delay(25); | ||
6681 | |||
6653 | return E1000_SUCCESS; | 6682 | return E1000_SUCCESS; |
6654 | } | 6683 | } |
6655 | 6684 | ||
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 76ce12809a11..7caa35748cea 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
@@ -123,6 +123,7 @@ typedef enum { | |||
123 | e1000_bus_width_32, | 123 | e1000_bus_width_32, |
124 | e1000_bus_width_64, | 124 | e1000_bus_width_64, |
125 | e1000_bus_width_pciex_1, | 125 | e1000_bus_width_pciex_1, |
126 | e1000_bus_width_pciex_2, | ||
126 | e1000_bus_width_pciex_4, | 127 | e1000_bus_width_pciex_4, |
127 | e1000_bus_width_reserved | 128 | e1000_bus_width_reserved |
128 | } e1000_bus_width; | 129 | } e1000_bus_width; |
@@ -149,6 +150,7 @@ typedef enum { | |||
149 | e1000_igp_cable_length_90 = 90, | 150 | e1000_igp_cable_length_90 = 90, |
150 | e1000_igp_cable_length_100 = 100, | 151 | e1000_igp_cable_length_100 = 100, |
151 | e1000_igp_cable_length_110 = 110, | 152 | e1000_igp_cable_length_110 = 110, |
153 | e1000_igp_cable_length_115 = 115, | ||
152 | e1000_igp_cable_length_120 = 120, | 154 | e1000_igp_cable_length_120 = 120, |
153 | e1000_igp_cable_length_130 = 130, | 155 | e1000_igp_cable_length_130 = 130, |
154 | e1000_igp_cable_length_140 = 140, | 156 | e1000_igp_cable_length_140 = 140, |
@@ -1457,6 +1459,7 @@ struct e1000_hw { | |||
1457 | #define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ | 1459 | #define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ |
1458 | #define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ | 1460 | #define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ |
1459 | #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ | 1461 | #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ |
1462 | #define E1000_EECD_SECVAL_SHIFT 22 | ||
1460 | #define E1000_STM_OPCODE 0xDB00 | 1463 | #define E1000_STM_OPCODE 0xDB00 |
1461 | #define E1000_HICR_FW_RESET 0xC0 | 1464 | #define E1000_HICR_FW_RESET 0xC0 |
1462 | 1465 | ||
@@ -1951,7 +1954,6 @@ struct e1000_host_command_info { | |||
1951 | 1954 | ||
1952 | #define E1000_MDALIGN 4096 | 1955 | #define E1000_MDALIGN 4096 |
1953 | 1956 | ||
1954 | #define E1000_GCR_BEM32 0x00400000 | ||
1955 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 | 1957 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 |
1956 | /* Function Active and Power State to MNG */ | 1958 | /* Function Active and Power State to MNG */ |
1957 | #define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 | 1959 | #define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index e0ae248b4313..438a931fd55d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -711,6 +711,7 @@ e1000_probe(struct pci_dev *pdev, | |||
711 | break; | 711 | break; |
712 | case e1000_82546: | 712 | case e1000_82546: |
713 | case e1000_82546_rev_3: | 713 | case e1000_82546_rev_3: |
714 | case e1000_82571: | ||
714 | if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) | 715 | if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) |
715 | && (adapter->hw.media_type == e1000_media_type_copper)) { | 716 | && (adapter->hw.media_type == e1000_media_type_copper)) { |
716 | e1000_read_eeprom(&adapter->hw, | 717 | e1000_read_eeprom(&adapter->hw, |
@@ -1158,7 +1159,6 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter, | |||
1158 | return -ENOMEM; | 1159 | return -ENOMEM; |
1159 | } | 1160 | } |
1160 | memset(txdr->buffer_info, 0, size); | 1161 | memset(txdr->buffer_info, 0, size); |
1161 | memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer)); | ||
1162 | 1162 | ||
1163 | /* round up to nearest 4K */ | 1163 | /* round up to nearest 4K */ |
1164 | 1164 | ||
@@ -1813,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter, | |||
1813 | 1813 | ||
1814 | /* Free all the Tx ring sk_buffs */ | 1814 | /* Free all the Tx ring sk_buffs */ |
1815 | 1815 | ||
1816 | if (likely(tx_ring->previous_buffer_info.skb != NULL)) { | ||
1817 | e1000_unmap_and_free_tx_resource(adapter, | ||
1818 | &tx_ring->previous_buffer_info); | ||
1819 | } | ||
1820 | |||
1821 | for(i = 0; i < tx_ring->count; i++) { | 1816 | for(i = 0; i < tx_ring->count; i++) { |
1822 | buffer_info = &tx_ring->buffer_info[i]; | 1817 | buffer_info = &tx_ring->buffer_info[i]; |
1823 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); | 1818 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); |
@@ -1832,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter, | |||
1832 | 1827 | ||
1833 | tx_ring->next_to_use = 0; | 1828 | tx_ring->next_to_use = 0; |
1834 | tx_ring->next_to_clean = 0; | 1829 | tx_ring->next_to_clean = 0; |
1830 | tx_ring->last_tx_tso = 0; | ||
1835 | 1831 | ||
1836 | writel(0, adapter->hw.hw_addr + tx_ring->tdh); | 1832 | writel(0, adapter->hw.hw_addr + tx_ring->tdh); |
1837 | writel(0, adapter->hw.hw_addr + tx_ring->tdt); | 1833 | writel(0, adapter->hw.hw_addr + tx_ring->tdt); |
@@ -2437,6 +2433,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, | |||
2437 | buffer_info = &tx_ring->buffer_info[i]; | 2433 | buffer_info = &tx_ring->buffer_info[i]; |
2438 | size = min(len, max_per_txd); | 2434 | size = min(len, max_per_txd); |
2439 | #ifdef NETIF_F_TSO | 2435 | #ifdef NETIF_F_TSO |
2436 | /* Workaround for Controller erratum -- | ||
2437 | * descriptor for non-tso packet in a linear SKB that follows a | ||
2438 | * tso gets written back prematurely before the data is fully | ||
2439 | * DMAd to the controller */ | ||
2440 | if (!skb->data_len && tx_ring->last_tx_tso && | ||
2441 | !skb_shinfo(skb)->tso_size) { | ||
2442 | tx_ring->last_tx_tso = 0; | ||
2443 | size -= 4; | ||
2444 | } | ||
2445 | |||
2440 | /* Workaround for premature desc write-backs | 2446 | /* Workaround for premature desc write-backs |
2441 | * in TSO mode. Append 4-byte sentinel desc */ | 2447 | * in TSO mode. Append 4-byte sentinel desc */ |
2442 | if(unlikely(mss && !nr_frags && size == len && size > 8)) | 2448 | if(unlikely(mss && !nr_frags && size == len && size > 8)) |
@@ -2693,6 +2699,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2693 | if(skb->ip_summed == CHECKSUM_HW) | 2699 | if(skb->ip_summed == CHECKSUM_HW) |
2694 | count++; | 2700 | count++; |
2695 | #endif | 2701 | #endif |
2702 | |||
2703 | #ifdef NETIF_F_TSO | ||
2704 | /* Controller Erratum workaround */ | ||
2705 | if (!skb->data_len && tx_ring->last_tx_tso && | ||
2706 | !skb_shinfo(skb)->tso_size) | ||
2707 | count++; | ||
2708 | #endif | ||
2709 | |||
2696 | count += TXD_USE_COUNT(len, max_txd_pwr); | 2710 | count += TXD_USE_COUNT(len, max_txd_pwr); |
2697 | 2711 | ||
2698 | if(adapter->pcix_82544) | 2712 | if(adapter->pcix_82544) |
@@ -2774,9 +2788,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2774 | return NETDEV_TX_OK; | 2788 | return NETDEV_TX_OK; |
2775 | } | 2789 | } |
2776 | 2790 | ||
2777 | if (likely(tso)) | 2791 | if (likely(tso)) { |
2792 | tx_ring->last_tx_tso = 1; | ||
2778 | tx_flags |= E1000_TX_FLAGS_TSO; | 2793 | tx_flags |= E1000_TX_FLAGS_TSO; |
2779 | else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) | 2794 | } else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) |
2780 | tx_flags |= E1000_TX_FLAGS_CSUM; | 2795 | tx_flags |= E1000_TX_FLAGS_CSUM; |
2781 | 2796 | ||
2782 | /* Old method was to assume IPv4 packet by default if TSO was enabled. | 2797 | /* Old method was to assume IPv4 packet by default if TSO was enabled. |
@@ -3227,37 +3242,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3227 | eop_desc = E1000_TX_DESC(*tx_ring, eop); | 3242 | eop_desc = E1000_TX_DESC(*tx_ring, eop); |
3228 | 3243 | ||
3229 | while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { | 3244 | while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { |
3230 | /* Premature writeback of Tx descriptors clear (free buffers | ||
3231 | * and unmap pci_mapping) previous_buffer_info */ | ||
3232 | if (likely(tx_ring->previous_buffer_info.skb != NULL)) { | ||
3233 | e1000_unmap_and_free_tx_resource(adapter, | ||
3234 | &tx_ring->previous_buffer_info); | ||
3235 | } | ||
3236 | |||
3237 | for(cleaned = FALSE; !cleaned; ) { | 3245 | for(cleaned = FALSE; !cleaned; ) { |
3238 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 3246 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
3239 | buffer_info = &tx_ring->buffer_info[i]; | 3247 | buffer_info = &tx_ring->buffer_info[i]; |
3240 | cleaned = (i == eop); | 3248 | cleaned = (i == eop); |
3241 | 3249 | ||
3242 | #ifdef NETIF_F_TSO | 3250 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); |
3243 | if (!(netdev->features & NETIF_F_TSO)) { | ||
3244 | #endif | ||
3245 | e1000_unmap_and_free_tx_resource(adapter, | ||
3246 | buffer_info); | ||
3247 | #ifdef NETIF_F_TSO | ||
3248 | } else { | ||
3249 | if (cleaned) { | ||
3250 | memcpy(&tx_ring->previous_buffer_info, | ||
3251 | buffer_info, | ||
3252 | sizeof(struct e1000_buffer)); | ||
3253 | memset(buffer_info, 0, | ||
3254 | sizeof(struct e1000_buffer)); | ||
3255 | } else { | ||
3256 | e1000_unmap_and_free_tx_resource( | ||
3257 | adapter, buffer_info); | ||
3258 | } | ||
3259 | } | ||
3260 | #endif | ||
3261 | 3251 | ||
3262 | tx_desc->buffer_addr = 0; | 3252 | tx_desc->buffer_addr = 0; |
3263 | tx_desc->lower.data = 0; | 3253 | tx_desc->lower.data = 0; |
@@ -3318,12 +3308,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3318 | netif_stop_queue(netdev); | 3308 | netif_stop_queue(netdev); |
3319 | } | 3309 | } |
3320 | } | 3310 | } |
3321 | #ifdef NETIF_F_TSO | ||
3322 | if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && | ||
3323 | time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ))) | ||
3324 | e1000_unmap_and_free_tx_resource( | ||
3325 | adapter, &tx_ring->previous_buffer_info); | ||
3326 | #endif | ||
3327 | return cleaned; | 3311 | return cleaned; |
3328 | } | 3312 | } |
3329 | 3313 | ||