tg3: Fix IPv6 TSO code in tg3_start_xmit_dma_bug()
authorMatt Carlson <mcarlson@broadcom.com>
Sun, 11 Jul 2010 09:31:42 +0000 (09:31 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 12 Jul 2010 00:07:41 +0000 (17:07 -0700)
The tg3_start_xmit_dma_bug() function was missing code to process IPv6
TSO packets.  This patch adds the missing support.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tg3.c

index 57dba794d31eeb589c4377aa13e9e94a65125fe9..efac448ded15d718aeb81bfad5e220a94fdeb6ff 100644 (file)
@@ -5779,7 +5779,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
 
        if ((mss = skb_shinfo(skb)->gso_size) != 0) {
                struct iphdr *iph;
-               u32 tcp_opt_len, ip_tcp_len, hdr_len;
+               u32 tcp_opt_len, hdr_len;
 
                if (skb_header_cloned(skb) &&
                    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5787,10 +5787,21 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                        goto out_unlock;
                }
 
+               iph = ip_hdr(skb);
                tcp_opt_len = tcp_optlen(skb);
-               ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
 
-               hdr_len = ip_tcp_len + tcp_opt_len;
+               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
+                       hdr_len = skb_headlen(skb) - ETH_HLEN;
+               } else {
+                       u32 ip_tcp_len;
+
+                       ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
+                       hdr_len = ip_tcp_len + tcp_opt_len;
+
+                       iph->check = 0;
+                       iph->tot_len = htons(mss + hdr_len);
+               }
+
                if (unlikely((ETH_HLEN + hdr_len) > 80) &&
                             (tp->tg3_flags2 & TG3_FLG2_TSO_BUG))
                        return tg3_tso_bug(tp, skb);
@@ -5798,9 +5809,6 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                base_flags |= (TXD_FLAG_CPU_PRE_DMA |
                               TXD_FLAG_CPU_POST_DMA);
 
-               iph = ip_hdr(skb);
-               iph->check = 0;
-               iph->tot_len = htons(mss + hdr_len);
                if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
                        tcp_hdr(skb)->check = 0;
                        base_flags &= ~TXD_FLAG_TCPUDP_CSUM;