aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2006-03-02 21:19:30 -0500
committerroot <root@jk-desktop.jf.intel.com>2006-03-02 21:19:30 -0500
commit7e6c9861bbc2fcd2438da910c006781784968a7c (patch)
tree42737b91df1aec190e0c930cc1e9d426316e8b29
parent8491682986e04fe7b258e5ba1d22f9a0ea2d803e (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>
-rw-r--r--drivers/net/e1000/e1000.h5
-rw-r--r--drivers/net/e1000/e1000_ethtool.c3
-rw-r--r--drivers/net/e1000/e1000_main.c67
-rw-r--r--drivers/net/e1000/e1000_param.c2
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;