diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2006-01-12 19:50:23 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-17 07:40:10 -0500 |
commit | 9a3056da0d7fde1e19e806824c41857b239954ed (patch) | |
tree | a416cf97788135fa3635a78c9c55f0624a10f837 /drivers/net | |
parent | 4ee9c02007249cf9c66e368b5d433c6956e05586 (diff) |
[PATCH] e1000: Fix TSO
Fixed the TSO workaround for 82571/2 controllers.
Fixed TSO issue where a non-tso packet in a linear SKB which followed a TSO packet would get written back prematurely.
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>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4b44bcd0f958..4945a41e3aea 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2688,11 +2688,23 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2688 | * overrun the FIFO, adjust the max buffer len if mss | 2688 | * overrun the FIFO, adjust the max buffer len if mss |
2689 | * drops. */ | 2689 | * drops. */ |
2690 | if(mss) { | 2690 | if(mss) { |
2691 | uint8_t hdr_len; | ||
2691 | max_per_txd = min(mss << 2, max_per_txd); | 2692 | max_per_txd = min(mss << 2, max_per_txd); |
2692 | max_txd_pwr = fls(max_per_txd) - 1; | 2693 | max_txd_pwr = fls(max_per_txd) - 1; |
2694 | |||
2695 | /* TSO Workaround for 82571/2 Controllers -- if skb->data | ||
2696 | * points to just header, pull a few bytes of payload from | ||
2697 | * frags into skb->data */ | ||
2698 | hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); | ||
2699 | if (skb->data_len && (hdr_len == (skb->len - skb->data_len)) && | ||
2700 | (adapter->hw.mac_type == e1000_82571 || | ||
2701 | adapter->hw.mac_type == e1000_82572)) { | ||
2702 | len = skb->len - skb->data_len; | ||
2703 | } | ||
2693 | } | 2704 | } |
2694 | 2705 | ||
2695 | if((mss) || (skb->ip_summed == CHECKSUM_HW)) | 2706 | if((mss) || (skb->ip_summed == CHECKSUM_HW)) |
2707 | /* reserve a descriptor for the offload context */ | ||
2696 | count++; | 2708 | count++; |
2697 | count++; | 2709 | count++; |
2698 | #else | 2710 | #else |
@@ -2726,26 +2738,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2726 | if(adapter->pcix_82544) | 2738 | if(adapter->pcix_82544) |
2727 | count += nr_frags; | 2739 | count += nr_frags; |
2728 | 2740 | ||
2729 | #ifdef NETIF_F_TSO | 2741 | unsigned int pull_size; |
2730 | /* TSO Workaround for 82571/2 Controllers -- if skb->data | 2742 | pull_size = min((unsigned int)4, skb->data_len); |
2731 | * points to just header, pull a few bytes of payload from | 2743 | if (!__pskb_pull_tail(skb, pull_size)) { |
2732 | * frags into skb->data */ | 2744 | printk(KERN_ERR "__pskb_pull_tail failed.\n"); |
2733 | if (skb_shinfo(skb)->tso_size) { | 2745 | dev_kfree_skb_any(skb); |
2734 | uint8_t hdr_len; | 2746 | return -EFAULT; |
2735 | hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); | ||
2736 | if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) && | ||
2737 | (adapter->hw.mac_type == e1000_82571 || | ||
2738 | adapter->hw.mac_type == e1000_82572)) { | ||
2739 | unsigned int pull_size; | ||
2740 | pull_size = min((unsigned int)4, skb->data_len); | ||
2741 | if (!__pskb_pull_tail(skb, pull_size)) { | ||
2742 | printk(KERN_ERR "__pskb_pull_tail failed.\n"); | ||
2743 | dev_kfree_skb_any(skb); | ||
2744 | return -EFAULT; | ||
2745 | } | ||
2746 | } | 2747 | } |
2747 | } | ||
2748 | #endif | ||
2749 | 2748 | ||
2750 | if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) ) | 2749 | if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) ) |
2751 | e1000_transfer_dhcp_info(adapter, skb); | 2750 | e1000_transfer_dhcp_info(adapter, skb); |