diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2006-03-02 21:21:24 -0500 |
---|---|---|
committer | root <root@jk-desktop.jf.intel.com> | 2006-03-02 21:21:24 -0500 |
commit | 8704163987882f8b989e8143ad1f87c6b7229a13 (patch) | |
tree | 24e16b012722402cedba6f9fbc10dcda4a5eef20 | |
parent | 6418ecc68e1d9416451b6f78ebb2c0b077e0abf2 (diff) |
e1000: Fixed the following issues with ESB2 (requires ESB2 support):
- Add restriction for ESB2 to MTU size <=9216
- Removed FIFO errors which were not being used
- Fixed issues with loopback
- Power management change for saving state and config space
- WA to disable recieves and reset device on link loss. Reset needed to be done outside the interrupt context - modified existing tx_timeout_task
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
-rw-r--r-- | drivers/net/e1000/e1000.h | 4 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 10 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 65 |
3 files changed, 65 insertions, 14 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 3319c19cbee6..d4266f18bbd9 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -252,8 +252,8 @@ struct e1000_adapter { | |||
252 | spinlock_t tx_queue_lock; | 252 | spinlock_t tx_queue_lock; |
253 | #endif | 253 | #endif |
254 | atomic_t irq_sem; | 254 | atomic_t irq_sem; |
255 | struct work_struct tx_timeout_task; | ||
256 | struct work_struct watchdog_task; | 255 | struct work_struct watchdog_task; |
256 | struct work_struct reset_task; | ||
257 | uint8_t fc_autoneg; | 257 | uint8_t fc_autoneg; |
258 | 258 | ||
259 | struct timer_list blink_timer; | 259 | struct timer_list blink_timer; |
@@ -328,7 +328,7 @@ struct e1000_adapter { | |||
328 | struct e1000_rx_ring test_rx_ring; | 328 | struct e1000_rx_ring test_rx_ring; |
329 | 329 | ||
330 | 330 | ||
331 | u32 *config_space; | 331 | uint32_t *config_space; |
332 | int msg_enable; | 332 | int msg_enable; |
333 | #ifdef CONFIG_PCI_MSI | 333 | #ifdef CONFIG_PCI_MSI |
334 | boolean_t have_msi; | 334 | boolean_t have_msi; |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 0d6a16c5f8cd..44d39f1d8298 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -67,7 +67,6 @@ static const struct e1000_stats e1000_gstrings_stats[] = { | |||
67 | { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, | 67 | { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, |
68 | { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, | 68 | { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, |
69 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, | 69 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, |
70 | { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, | ||
71 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, | 70 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, |
72 | { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, | 71 | { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, |
73 | { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, | 72 | { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, |
@@ -1253,6 +1252,10 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1253 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); | 1252 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); |
1254 | /* autoneg off */ | 1253 | /* autoneg off */ |
1255 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); | 1254 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); |
1255 | } else if (adapter->hw.phy_type == e1000_phy_gg82563) { | ||
1256 | e1000_write_phy_reg(&adapter->hw, | ||
1257 | GG82563_PHY_KMRN_MODE_CTRL, | ||
1258 | 0x1CE); | ||
1256 | } | 1259 | } |
1257 | /* force 1000, set loopback */ | 1260 | /* force 1000, set loopback */ |
1258 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140); | 1261 | e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140); |
@@ -1403,6 +1406,11 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter) | |||
1403 | case e1000_82546_rev_3: | 1406 | case e1000_82546_rev_3: |
1404 | default: | 1407 | default: |
1405 | hw->autoneg = TRUE; | 1408 | hw->autoneg = TRUE; |
1409 | if (hw->phy_type == e1000_phy_gg82563) { | ||
1410 | e1000_write_phy_reg(hw, | ||
1411 | GG82563_PHY_KMRN_MODE_CTRL, | ||
1412 | 0x180); | ||
1413 | } | ||
1406 | e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); | 1414 | e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); |
1407 | if (phy_reg & MII_CR_LOOPBACK) { | 1415 | if (phy_reg & MII_CR_LOOPBACK) { |
1408 | phy_reg &= ~MII_CR_LOOPBACK; | 1416 | phy_reg &= ~MII_CR_LOOPBACK; |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 3acbffd5bde3..431b03ee077e 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -245,7 +245,7 @@ void e1000_set_ethtool_ops(struct net_device *netdev); | |||
245 | static void e1000_enter_82542_rst(struct e1000_adapter *adapter); | 245 | static void e1000_enter_82542_rst(struct e1000_adapter *adapter); |
246 | static void e1000_leave_82542_rst(struct e1000_adapter *adapter); | 246 | static void e1000_leave_82542_rst(struct e1000_adapter *adapter); |
247 | static void e1000_tx_timeout(struct net_device *dev); | 247 | static void e1000_tx_timeout(struct net_device *dev); |
248 | static void e1000_tx_timeout_task(struct net_device *dev); | 248 | static void e1000_reset_task(struct net_device *dev); |
249 | static void e1000_smartspeed(struct e1000_adapter *adapter); | 249 | static void e1000_smartspeed(struct e1000_adapter *adapter); |
250 | static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, | 250 | static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, |
251 | struct sk_buff *skb); | 251 | struct sk_buff *skb); |
@@ -611,7 +611,10 @@ e1000_reset(struct e1000_adapter *adapter) | |||
611 | 611 | ||
612 | adapter->hw.fc_high_water = fc_high_water_mark; | 612 | adapter->hw.fc_high_water = fc_high_water_mark; |
613 | adapter->hw.fc_low_water = fc_high_water_mark - 8; | 613 | adapter->hw.fc_low_water = fc_high_water_mark - 8; |
614 | adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; | 614 | if (adapter->hw.mac_type == e1000_80003es2lan) |
615 | adapter->hw.fc_pause_time = 0xFFFF; | ||
616 | else | ||
617 | adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; | ||
615 | adapter->hw.fc_send_xon = 1; | 618 | adapter->hw.fc_send_xon = 1; |
616 | adapter->hw.fc = adapter->hw.original_fc; | 619 | adapter->hw.fc = adapter->hw.original_fc; |
617 | 620 | ||
@@ -828,8 +831,8 @@ e1000_probe(struct pci_dev *pdev, | |||
828 | adapter->phy_info_timer.function = &e1000_update_phy_info; | 831 | adapter->phy_info_timer.function = &e1000_update_phy_info; |
829 | adapter->phy_info_timer.data = (unsigned long) adapter; | 832 | adapter->phy_info_timer.data = (unsigned long) adapter; |
830 | 833 | ||
831 | INIT_WORK(&adapter->tx_timeout_task, | 834 | INIT_WORK(&adapter->reset_task, |
832 | (void (*)(void *))e1000_tx_timeout_task, netdev); | 835 | (void (*)(void *))e1000_reset_task, netdev); |
833 | 836 | ||
834 | /* we're going to reset, so assume we have no link for now */ | 837 | /* we're going to reset, so assume we have no link for now */ |
835 | 838 | ||
@@ -1390,6 +1393,10 @@ e1000_configure_tx(struct e1000_adapter *adapter) | |||
1390 | ipgr1 = DEFAULT_82542_TIPG_IPGR1; | 1393 | ipgr1 = DEFAULT_82542_TIPG_IPGR1; |
1391 | ipgr2 = DEFAULT_82542_TIPG_IPGR2; | 1394 | ipgr2 = DEFAULT_82542_TIPG_IPGR2; |
1392 | break; | 1395 | break; |
1396 | case e1000_80003es2lan: | ||
1397 | ipgr1 = DEFAULT_82543_TIPG_IPGR1; | ||
1398 | ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; | ||
1399 | break; | ||
1393 | default: | 1400 | default: |
1394 | ipgr1 = DEFAULT_82543_TIPG_IPGR1; | 1401 | ipgr1 = DEFAULT_82543_TIPG_IPGR1; |
1395 | ipgr2 = DEFAULT_82543_TIPG_IPGR2; | 1402 | ipgr2 = DEFAULT_82543_TIPG_IPGR2; |
@@ -1429,6 +1436,15 @@ e1000_configure_tx(struct e1000_adapter *adapter) | |||
1429 | else | 1436 | else |
1430 | tarc |= (1 << 28); | 1437 | tarc |= (1 << 28); |
1431 | E1000_WRITE_REG(hw, TARC1, tarc); | 1438 | E1000_WRITE_REG(hw, TARC1, tarc); |
1439 | } else if (hw->mac_type == e1000_80003es2lan) { | ||
1440 | tarc = E1000_READ_REG(hw, TARC0); | ||
1441 | tarc |= 1; | ||
1442 | if (hw->media_type == e1000_media_type_internal_serdes) | ||
1443 | tarc |= (1 << 20); | ||
1444 | E1000_WRITE_REG(hw, TARC0, tarc); | ||
1445 | tarc = E1000_READ_REG(hw, TARC1); | ||
1446 | tarc |= 1; | ||
1447 | E1000_WRITE_REG(hw, TARC1, tarc); | ||
1432 | } | 1448 | } |
1433 | 1449 | ||
1434 | e1000_config_collision_dist(hw); | 1450 | e1000_config_collision_dist(hw); |
@@ -2349,6 +2365,16 @@ e1000_watchdog_task(struct e1000_adapter *adapter) | |||
2349 | netif_carrier_off(netdev); | 2365 | netif_carrier_off(netdev); |
2350 | netif_stop_queue(netdev); | 2366 | netif_stop_queue(netdev); |
2351 | mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); | 2367 | mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); |
2368 | |||
2369 | /* 80003ES2LAN workaround-- | ||
2370 | * For packet buffer work-around on link down event; | ||
2371 | * disable receives in the ISR and | ||
2372 | * reset device here in the watchdog | ||
2373 | */ | ||
2374 | if (adapter->hw.mac_type == e1000_80003es2lan) { | ||
2375 | /* reset device */ | ||
2376 | schedule_work(&adapter->reset_task); | ||
2377 | } | ||
2352 | } | 2378 | } |
2353 | 2379 | ||
2354 | e1000_smartspeed(adapter); | 2380 | e1000_smartspeed(adapter); |
@@ -2374,7 +2400,8 @@ e1000_watchdog_task(struct e1000_adapter *adapter) | |||
2374 | * but we've got queued Tx work that's never going | 2400 | * but we've got queued Tx work that's never going |
2375 | * to get done, so reset controller to flush Tx. | 2401 | * to get done, so reset controller to flush Tx. |
2376 | * (Do the reset outside of interrupt context). */ | 2402 | * (Do the reset outside of interrupt context). */ |
2377 | schedule_work(&adapter->tx_timeout_task); | 2403 | adapter->tx_timeout_count++; |
2404 | schedule_work(&adapter->reset_task); | ||
2378 | } | 2405 | } |
2379 | } | 2406 | } |
2380 | 2407 | ||
@@ -2940,15 +2967,15 @@ e1000_tx_timeout(struct net_device *netdev) | |||
2940 | struct e1000_adapter *adapter = netdev_priv(netdev); | 2967 | struct e1000_adapter *adapter = netdev_priv(netdev); |
2941 | 2968 | ||
2942 | /* Do the reset outside of interrupt context */ | 2969 | /* Do the reset outside of interrupt context */ |
2943 | schedule_work(&adapter->tx_timeout_task); | 2970 | adapter->tx_timeout_count++; |
2971 | schedule_work(&adapter->reset_task); | ||
2944 | } | 2972 | } |
2945 | 2973 | ||
2946 | static void | 2974 | static void |
2947 | e1000_tx_timeout_task(struct net_device *netdev) | 2975 | e1000_reset_task(struct net_device *netdev) |
2948 | { | 2976 | { |
2949 | struct e1000_adapter *adapter = netdev_priv(netdev); | 2977 | struct e1000_adapter *adapter = netdev_priv(netdev); |
2950 | 2978 | ||
2951 | adapter->tx_timeout_count++; | ||
2952 | e1000_down(adapter); | 2979 | e1000_down(adapter); |
2953 | e1000_up(adapter); | 2980 | e1000_up(adapter); |
2954 | } | 2981 | } |
@@ -3016,6 +3043,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3016 | /* fall through to get support */ | 3043 | /* fall through to get support */ |
3017 | case e1000_82571: | 3044 | case e1000_82571: |
3018 | case e1000_82572: | 3045 | case e1000_82572: |
3046 | case e1000_80003es2lan: | ||
3019 | #define MAX_STD_JUMBO_FRAME_SIZE 9234 | 3047 | #define MAX_STD_JUMBO_FRAME_SIZE 9234 |
3020 | if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { | 3048 | if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { |
3021 | DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n"); | 3049 | DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n"); |
@@ -3169,11 +3197,15 @@ e1000_update_stats(struct e1000_adapter *adapter) | |||
3169 | 3197 | ||
3170 | /* Rx Errors */ | 3198 | /* Rx Errors */ |
3171 | 3199 | ||
3200 | /* RLEC on some newer hardware can be incorrect so build | ||
3201 | * our own version based on RUC and ROC */ | ||
3172 | adapter->net_stats.rx_errors = adapter->stats.rxerrc + | 3202 | adapter->net_stats.rx_errors = adapter->stats.rxerrc + |
3173 | adapter->stats.crcerrs + adapter->stats.algnerrc + | 3203 | adapter->stats.crcerrs + adapter->stats.algnerrc + |
3174 | adapter->stats.rlec + adapter->stats.cexterr; | 3204 | adapter->stats.ruc + adapter->stats.roc + |
3205 | adapter->stats.cexterr; | ||
3175 | adapter->net_stats.rx_dropped = 0; | 3206 | adapter->net_stats.rx_dropped = 0; |
3176 | adapter->net_stats.rx_length_errors = adapter->stats.rlec; | 3207 | adapter->net_stats.rx_length_errors = adapter->stats.ruc + |
3208 | adapter->stats.roc; | ||
3177 | adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; | 3209 | adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; |
3178 | adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc; | 3210 | adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc; |
3179 | adapter->net_stats.rx_missed_errors = adapter->stats.mpc; | 3211 | adapter->net_stats.rx_missed_errors = adapter->stats.mpc; |
@@ -3219,7 +3251,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) | |||
3219 | struct net_device *netdev = data; | 3251 | struct net_device *netdev = data; |
3220 | struct e1000_adapter *adapter = netdev_priv(netdev); | 3252 | struct e1000_adapter *adapter = netdev_priv(netdev); |
3221 | struct e1000_hw *hw = &adapter->hw; | 3253 | struct e1000_hw *hw = &adapter->hw; |
3222 | uint32_t icr = E1000_READ_REG(hw, ICR); | 3254 | uint32_t rctl, icr = E1000_READ_REG(hw, ICR); |
3223 | #ifndef CONFIG_E1000_NAPI | 3255 | #ifndef CONFIG_E1000_NAPI |
3224 | int i; | 3256 | int i; |
3225 | #else | 3257 | #else |
@@ -3241,6 +3273,17 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) | |||
3241 | 3273 | ||
3242 | if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { | 3274 | if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { |
3243 | hw->get_link_status = 1; | 3275 | hw->get_link_status = 1; |
3276 | /* 80003ES2LAN workaround-- | ||
3277 | * For packet buffer work-around on link down event; | ||
3278 | * disable receives here in the ISR and | ||
3279 | * reset adapter in watchdog | ||
3280 | */ | ||
3281 | if (netif_carrier_ok(netdev) && | ||
3282 | (adapter->hw.mac_type == e1000_80003es2lan)) { | ||
3283 | /* disable receives */ | ||
3284 | rctl = E1000_READ_REG(hw, RCTL); | ||
3285 | E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); | ||
3286 | } | ||
3244 | mod_timer(&adapter->watchdog_timer, jiffies); | 3287 | mod_timer(&adapter->watchdog_timer, jiffies); |
3245 | } | 3288 | } |
3246 | 3289 | ||