diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2006-03-02 21:19:30 -0500 |
---|---|---|
committer | root <root@jk-desktop.jf.intel.com> | 2006-03-02 21:19:30 -0500 |
commit | 7e6c9861bbc2fcd2438da910c006781784968a7c (patch) | |
tree | 42737b91df1aec190e0c930cc1e9d426316e8b29 /drivers | |
parent | 8491682986e04fe7b258e5ba1d22f9a0ea2d803e (diff) |
e1000: Fix network problems when forced at 100Mb/s and to fix TSO when forced at 100Mb/s
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e1000/e1000.h | 5 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 67 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_param.c | 2 |
4 files changed, 66 insertions, 11 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index a18782748d5a..3319c19cbee6 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -333,5 +333,10 @@ struct e1000_adapter { | |||
333 | #ifdef CONFIG_PCI_MSI | 333 | #ifdef CONFIG_PCI_MSI |
334 | boolean_t have_msi; | 334 | boolean_t have_msi; |
335 | #endif | 335 | #endif |
336 | /* to not mess up cache alignment, always add to the bottom */ | ||
337 | boolean_t txb2b; | ||
338 | #ifdef NETIF_F_TSO | ||
339 | boolean_t tso_force; | ||
340 | #endif | ||
336 | }; | 341 | }; |
337 | #endif /* _E1000_H_ */ | 342 | #endif /* _E1000_H_ */ |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index f1b9cf4643c9..70238e089f16 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -338,6 +338,9 @@ e1000_set_tso(struct net_device *netdev, uint32_t data) | |||
338 | netdev->features |= NETIF_F_TSO; | 338 | netdev->features |= NETIF_F_TSO; |
339 | else | 339 | else |
340 | netdev->features &= ~NETIF_F_TSO; | 340 | netdev->features &= ~NETIF_F_TSO; |
341 | |||
342 | DPRINTK(PROBE, INFO, "TSO is %s\n", data ? "Enabled" : "Disabled"); | ||
343 | adapter->tso_force = TRUE; | ||
341 | return 0; | 344 | return 0; |
342 | } | 345 | } |
343 | #endif /* NETIF_F_TSO */ | 346 | #endif /* NETIF_F_TSO */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index aad5373a8aeb..6ee8ed5606f1 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -1405,10 +1405,13 @@ e1000_configure_tx(struct e1000_adapter *adapter) | |||
1405 | tctl = E1000_READ_REG(hw, TCTL); | 1405 | tctl = E1000_READ_REG(hw, TCTL); |
1406 | 1406 | ||
1407 | tctl &= ~E1000_TCTL_CT; | 1407 | tctl &= ~E1000_TCTL_CT; |
1408 | tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC | | 1408 | tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | |
1409 | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); | 1409 | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); |
1410 | 1410 | ||
1411 | E1000_WRITE_REG(hw, TCTL, tctl); | 1411 | #ifdef DISABLE_MULR |
1412 | /* disable Multiple Reads for debugging */ | ||
1413 | tctl &= ~E1000_TCTL_MULR; | ||
1414 | #endif | ||
1412 | 1415 | ||
1413 | if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) { | 1416 | if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) { |
1414 | tarc = E1000_READ_REG(hw, TARC0); | 1417 | tarc = E1000_READ_REG(hw, TARC0); |
@@ -1439,6 +1442,9 @@ e1000_configure_tx(struct e1000_adapter *adapter) | |||
1439 | if (hw->mac_type == e1000_82544 && | 1442 | if (hw->mac_type == e1000_82544 && |
1440 | hw->bus_type == e1000_bus_type_pcix) | 1443 | hw->bus_type == e1000_bus_type_pcix) |
1441 | adapter->pcix_82544 = 1; | 1444 | adapter->pcix_82544 = 1; |
1445 | |||
1446 | E1000_WRITE_REG(hw, TCTL, tctl); | ||
1447 | |||
1442 | } | 1448 | } |
1443 | 1449 | ||
1444 | /** | 1450 | /** |
@@ -2243,7 +2249,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) | |||
2243 | { | 2249 | { |
2244 | struct net_device *netdev = adapter->netdev; | 2250 | struct net_device *netdev = adapter->netdev; |
2245 | struct e1000_tx_ring *txdr = adapter->tx_ring; | 2251 | struct e1000_tx_ring *txdr = adapter->tx_ring; |
2246 | uint32_t link; | 2252 | uint32_t link, tctl; |
2247 | 2253 | ||
2248 | e1000_check_for_link(&adapter->hw); | 2254 | e1000_check_for_link(&adapter->hw); |
2249 | if (adapter->hw.mac_type == e1000_82573) { | 2255 | if (adapter->hw.mac_type == e1000_82573) { |
@@ -2269,20 +2275,61 @@ e1000_watchdog_task(struct e1000_adapter *adapter) | |||
2269 | adapter->link_duplex == FULL_DUPLEX ? | 2275 | adapter->link_duplex == FULL_DUPLEX ? |
2270 | "Full Duplex" : "Half Duplex"); | 2276 | "Full Duplex" : "Half Duplex"); |
2271 | 2277 | ||
2272 | /* tweak tx_queue_len according to speed/duplex */ | 2278 | /* tweak tx_queue_len according to speed/duplex |
2279 | * and adjust the timeout factor */ | ||
2273 | netdev->tx_queue_len = adapter->tx_queue_len; | 2280 | netdev->tx_queue_len = adapter->tx_queue_len; |
2274 | adapter->tx_timeout_factor = 1; | 2281 | adapter->tx_timeout_factor = 1; |
2275 | if (adapter->link_duplex == HALF_DUPLEX) { | 2282 | adapter->txb2b = 1; |
2283 | switch (adapter->link_speed) { | ||
2284 | case SPEED_10: | ||
2285 | adapter->txb2b = 0; | ||
2286 | netdev->tx_queue_len = 10; | ||
2287 | adapter->tx_timeout_factor = 8; | ||
2288 | break; | ||
2289 | case SPEED_100: | ||
2290 | adapter->txb2b = 0; | ||
2291 | netdev->tx_queue_len = 100; | ||
2292 | /* maybe add some timeout factor ? */ | ||
2293 | break; | ||
2294 | } | ||
2295 | |||
2296 | if ((adapter->hw.mac_type == e1000_82571 || | ||
2297 | adapter->hw.mac_type == e1000_82572) && | ||
2298 | adapter->txb2b == 0) { | ||
2299 | #define SPEED_MODE_BIT (1 << 21) | ||
2300 | uint32_t tarc0; | ||
2301 | tarc0 = E1000_READ_REG(&adapter->hw, TARC0); | ||
2302 | tarc0 &= ~SPEED_MODE_BIT; | ||
2303 | E1000_WRITE_REG(&adapter->hw, TARC0, tarc0); | ||
2304 | } | ||
2305 | |||
2306 | #ifdef NETIF_F_TSO | ||
2307 | /* disable TSO for pcie and 10/100 speeds, to avoid | ||
2308 | * some hardware issues */ | ||
2309 | if (!adapter->tso_force && | ||
2310 | adapter->hw.bus_type == e1000_bus_type_pci_express){ | ||
2276 | switch (adapter->link_speed) { | 2311 | switch (adapter->link_speed) { |
2277 | case SPEED_10: | 2312 | case SPEED_10: |
2278 | netdev->tx_queue_len = 10; | ||
2279 | adapter->tx_timeout_factor = 8; | ||
2280 | break; | ||
2281 | case SPEED_100: | 2313 | case SPEED_100: |
2282 | netdev->tx_queue_len = 100; | 2314 | DPRINTK(PROBE,INFO, |
2315 | "10/100 speed: disabling TSO\n"); | ||
2316 | netdev->features &= ~NETIF_F_TSO; | ||
2317 | break; | ||
2318 | case SPEED_1000: | ||
2319 | netdev->features |= NETIF_F_TSO; | ||
2320 | break; | ||
2321 | default: | ||
2322 | /* oops */ | ||
2283 | break; | 2323 | break; |
2284 | } | 2324 | } |
2285 | } | 2325 | } |
2326 | #endif | ||
2327 | |||
2328 | /* enable transmits in the hardware, need to do this | ||
2329 | * after setting TARC0 */ | ||
2330 | tctl = E1000_READ_REG(&adapter->hw, TCTL); | ||
2331 | tctl |= E1000_TCTL_EN; | ||
2332 | E1000_WRITE_REG(&adapter->hw, TCTL, tctl); | ||
2286 | 2333 | ||
2287 | netif_carrier_on(netdev); | 2334 | netif_carrier_on(netdev); |
2288 | netif_wake_queue(netdev); | 2335 | netif_wake_queue(netdev); |
@@ -3319,7 +3366,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3319 | adapter->detect_tx_hung = FALSE; | 3366 | adapter->detect_tx_hung = FALSE; |
3320 | if (tx_ring->buffer_info[eop].dma && | 3367 | if (tx_ring->buffer_info[eop].dma && |
3321 | time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + | 3368 | time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + |
3322 | adapter->tx_timeout_factor * HZ) | 3369 | (adapter->tx_timeout_factor * HZ)) |
3323 | && !(E1000_READ_REG(&adapter->hw, STATUS) & | 3370 | && !(E1000_READ_REG(&adapter->hw, STATUS) & |
3324 | E1000_STATUS_TXOFF)) { | 3371 | E1000_STATUS_TXOFF)) { |
3325 | 3372 | ||
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index 3768d83cd577..e0a4d37d1b85 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c | |||
@@ -268,7 +268,7 @@ e1000_validate_option(int *value, struct e1000_option *opt, | |||
268 | BUG(); | 268 | BUG(); |
269 | } | 269 | } |
270 | 270 | ||
271 | DPRINTK(PROBE, INFO, "Invalid %s specified (%i) %s\n", | 271 | DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n", |
272 | opt->name, *value, opt->err); | 272 | opt->name, *value, opt->err); |
273 | *value = opt->def; | 273 | *value = opt->def; |
274 | return -1; | 274 | return -1; |