aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_main.c
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2006-01-12 19:50:23 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-01-17 07:40:10 -0500
commit9a3056da0d7fde1e19e806824c41857b239954ed (patch)
treea416cf97788135fa3635a78c9c55f0624a10f837 /drivers/net/e1000/e1000_main.c
parent4ee9c02007249cf9c66e368b5d433c6956e05586 (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/e1000/e1000_main.c')
-rw-r--r--drivers/net/e1000/e1000_main.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 4b44bcd0f95..4945a41e3ae 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);