aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r--drivers/net/e1000/e1000_main.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 9c6c1fbbc41..4a8c069e6c7 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2384,11 +2384,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
2384 eop_desc = E1000_TX_DESC(*tx_ring, eop); 2384 eop_desc = E1000_TX_DESC(*tx_ring, eop);
2385 2385
2386 while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { 2386 while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
2387 /* pre-mature writeback of Tx descriptors */ 2387 /* Premature writeback of Tx descriptors clear (free buffers
2388 /* clear (free buffers and unmap pci_mapping) */ 2388 * and unmap pci_mapping) previous_buffer_info */
2389 /* previous_buffer_info */
2390 if (likely(adapter->previous_buffer_info.skb != NULL)) { 2389 if (likely(adapter->previous_buffer_info.skb != NULL)) {
2391 e1000_unmap_and_free_tx_resource(adapter, 2390 e1000_unmap_and_free_tx_resource(adapter,
2392 &adapter->previous_buffer_info); 2391 &adapter->previous_buffer_info);
2393 } 2392 }
2394 2393
@@ -2397,20 +2396,25 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
2397 buffer_info = &tx_ring->buffer_info[i]; 2396 buffer_info = &tx_ring->buffer_info[i];
2398 cleaned = (i == eop); 2397 cleaned = (i == eop);
2399 2398
2400 /* pre-mature writeback of Tx descriptors */ 2399#ifdef NETIF_F_TSO
2401 /* save the cleaning of the this for the */ 2400 if (!(netdev->features & NETIF_F_TSO)) {
2402 /* next iteration */ 2401#endif
2403 if (cleaned) { 2402 e1000_unmap_and_free_tx_resource(adapter,
2404 memcpy(&adapter->previous_buffer_info, 2403 buffer_info);
2405 buffer_info, 2404#ifdef NETIF_F_TSO
2406 sizeof(struct e1000_buffer));
2407 memset(buffer_info,
2408 0,
2409 sizeof(struct e1000_buffer));
2410 } else { 2405 } else {
2411 e1000_unmap_and_free_tx_resource(adapter, 2406 if (cleaned) {
2412 buffer_info); 2407 memcpy(&adapter->previous_buffer_info,
2408 buffer_info,
2409 sizeof(struct e1000_buffer));
2410 memset(buffer_info, 0,
2411 sizeof(struct e1000_buffer));
2412 } else {
2413 e1000_unmap_and_free_tx_resource(
2414 adapter, buffer_info);
2415 }
2413 } 2416 }
2417#endif
2414 2418
2415 tx_desc->buffer_addr = 0; 2419 tx_desc->buffer_addr = 0;
2416 tx_desc->lower.data = 0; 2420 tx_desc->lower.data = 0;
@@ -2443,7 +2447,14 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
2443 !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) 2447 !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
2444 netif_stop_queue(netdev); 2448 netif_stop_queue(netdev);
2445 } 2449 }
2450#ifdef NETIF_F_TSO
2446 2451
2452 if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
2453 time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ)))
2454 e1000_unmap_and_free_tx_resource(
2455 adapter, &adapter->previous_buffer_info);
2456
2457#endif
2447 return cleaned; 2458 return cleaned;
2448} 2459}
2449 2460