diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 256969e1300c..38383e4e07a1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | 41 | ||
42 | #include <net/checksum.h> | 42 | #include <net/checksum.h> |
43 | #include <net/ip.h> | ||
43 | 44 | ||
44 | #include <asm/system.h> | 45 | #include <asm/system.h> |
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
@@ -3349,7 +3350,7 @@ static int tg3_rx(struct tg3 *tp, int budget) | |||
3349 | skb_reserve(copy_skb, 2); | 3350 | skb_reserve(copy_skb, 2); |
3350 | skb_put(copy_skb, len); | 3351 | skb_put(copy_skb, len); |
3351 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); | 3352 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); |
3352 | memcpy(copy_skb->data, skb->data, len); | 3353 | skb_copy_from_linear_data(skb, copy_skb->data, len); |
3353 | pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); | 3354 | pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); |
3354 | 3355 | ||
3355 | /* We'll reuse the original ring buffer. */ | 3356 | /* We'll reuse the original ring buffer. */ |
@@ -3908,20 +3909,20 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3908 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) | 3909 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) |
3909 | mss |= (skb_headlen(skb) - ETH_HLEN) << 9; | 3910 | mss |= (skb_headlen(skb) - ETH_HLEN) << 9; |
3910 | else { | 3911 | else { |
3911 | tcp_opt_len = ((skb->h.th->doff - 5) * 4); | 3912 | struct iphdr *iph = ip_hdr(skb); |
3912 | ip_tcp_len = (skb->nh.iph->ihl * 4) + | ||
3913 | sizeof(struct tcphdr); | ||
3914 | 3913 | ||
3915 | skb->nh.iph->check = 0; | 3914 | tcp_opt_len = tcp_optlen(skb); |
3916 | skb->nh.iph->tot_len = htons(mss + ip_tcp_len + | 3915 | ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); |
3917 | tcp_opt_len); | 3916 | |
3917 | iph->check = 0; | ||
3918 | iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); | ||
3918 | mss |= (ip_tcp_len + tcp_opt_len) << 9; | 3919 | mss |= (ip_tcp_len + tcp_opt_len) << 9; |
3919 | } | 3920 | } |
3920 | 3921 | ||
3921 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | | 3922 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | |
3922 | TXD_FLAG_CPU_POST_DMA); | 3923 | TXD_FLAG_CPU_POST_DMA); |
3923 | 3924 | ||
3924 | skb->h.th->check = 0; | 3925 | tcp_hdr(skb)->check = 0; |
3925 | 3926 | ||
3926 | } | 3927 | } |
3927 | else if (skb->ip_summed == CHECKSUM_PARTIAL) | 3928 | else if (skb->ip_summed == CHECKSUM_PARTIAL) |
@@ -4055,6 +4056,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) | |||
4055 | mss = 0; | 4056 | mss = 0; |
4056 | if (skb->len > (tp->dev->mtu + ETH_HLEN) && | 4057 | if (skb->len > (tp->dev->mtu + ETH_HLEN) && |
4057 | (mss = skb_shinfo(skb)->gso_size) != 0) { | 4058 | (mss = skb_shinfo(skb)->gso_size) != 0) { |
4059 | struct iphdr *iph; | ||
4058 | int tcp_opt_len, ip_tcp_len, hdr_len; | 4060 | int tcp_opt_len, ip_tcp_len, hdr_len; |
4059 | 4061 | ||
4060 | if (skb_header_cloned(skb) && | 4062 | if (skb_header_cloned(skb) && |
@@ -4063,8 +4065,8 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) | |||
4063 | goto out_unlock; | 4065 | goto out_unlock; |
4064 | } | 4066 | } |
4065 | 4067 | ||
4066 | tcp_opt_len = ((skb->h.th->doff - 5) * 4); | 4068 | tcp_opt_len = tcp_optlen(skb); |
4067 | ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); | 4069 | ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); |
4068 | 4070 | ||
4069 | hdr_len = ip_tcp_len + tcp_opt_len; | 4071 | hdr_len = ip_tcp_len + tcp_opt_len; |
4070 | if (unlikely((ETH_HLEN + hdr_len) > 80) && | 4072 | if (unlikely((ETH_HLEN + hdr_len) > 80) && |
@@ -4074,34 +4076,31 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) | |||
4074 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | | 4076 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | |
4075 | TXD_FLAG_CPU_POST_DMA); | 4077 | TXD_FLAG_CPU_POST_DMA); |
4076 | 4078 | ||
4077 | skb->nh.iph->check = 0; | 4079 | iph = ip_hdr(skb); |
4078 | skb->nh.iph->tot_len = htons(mss + hdr_len); | 4080 | iph->check = 0; |
4081 | iph->tot_len = htons(mss + hdr_len); | ||
4079 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { | 4082 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { |
4080 | skb->h.th->check = 0; | 4083 | tcp_hdr(skb)->check = 0; |
4081 | base_flags &= ~TXD_FLAG_TCPUDP_CSUM; | 4084 | base_flags &= ~TXD_FLAG_TCPUDP_CSUM; |
4082 | } | 4085 | } else |
4083 | else { | 4086 | tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, |
4084 | skb->h.th->check = | 4087 | iph->daddr, 0, |
4085 | ~csum_tcpudp_magic(skb->nh.iph->saddr, | 4088 | IPPROTO_TCP, |
4086 | skb->nh.iph->daddr, | 4089 | 0); |
4087 | 0, IPPROTO_TCP, 0); | ||
4088 | } | ||
4089 | 4090 | ||
4090 | if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) || | 4091 | if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) || |
4091 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) { | 4092 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) { |
4092 | if (tcp_opt_len || skb->nh.iph->ihl > 5) { | 4093 | if (tcp_opt_len || iph->ihl > 5) { |
4093 | int tsflags; | 4094 | int tsflags; |
4094 | 4095 | ||
4095 | tsflags = ((skb->nh.iph->ihl - 5) + | 4096 | tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2); |
4096 | (tcp_opt_len >> 2)); | ||
4097 | mss |= (tsflags << 11); | 4097 | mss |= (tsflags << 11); |
4098 | } | 4098 | } |
4099 | } else { | 4099 | } else { |
4100 | if (tcp_opt_len || skb->nh.iph->ihl > 5) { | 4100 | if (tcp_opt_len || iph->ihl > 5) { |
4101 | int tsflags; | 4101 | int tsflags; |
4102 | 4102 | ||
4103 | tsflags = ((skb->nh.iph->ihl - 5) + | 4103 | tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2); |
4104 | (tcp_opt_len >> 2)); | ||
4105 | base_flags |= tsflags << 12; | 4104 | base_flags |= tsflags << 12; |
4106 | } | 4105 | } |
4107 | } | 4106 | } |