diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 104 |
1 files changed, 50 insertions, 54 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index a5716760c0e2..25b0ef8dc86a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -3725,68 +3725,64 @@ static int e1000_tso(struct e1000_adapter *adapter, | |||
3725 | u8 ipcss, ipcso, tucss, tucso, hdr_len; | 3725 | u8 ipcss, ipcso, tucss, tucso, hdr_len; |
3726 | int err; | 3726 | int err; |
3727 | 3727 | ||
3728 | if (skb_is_gso(skb)) { | 3728 | if (!skb_is_gso(skb)) |
3729 | if (skb_header_cloned(skb)) { | 3729 | return 0; |
3730 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | ||
3731 | if (err) | ||
3732 | return err; | ||
3733 | } | ||
3734 | 3730 | ||
3735 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | 3731 | if (skb_header_cloned(skb)) { |
3736 | mss = skb_shinfo(skb)->gso_size; | 3732 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); |
3737 | if (skb->protocol == htons(ETH_P_IP)) { | 3733 | if (err) |
3738 | struct iphdr *iph = ip_hdr(skb); | 3734 | return err; |
3739 | iph->tot_len = 0; | 3735 | } |
3740 | iph->check = 0; | ||
3741 | tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, | ||
3742 | iph->daddr, 0, | ||
3743 | IPPROTO_TCP, | ||
3744 | 0); | ||
3745 | cmd_length = E1000_TXD_CMD_IP; | ||
3746 | ipcse = skb_transport_offset(skb) - 1; | ||
3747 | } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { | ||
3748 | ipv6_hdr(skb)->payload_len = 0; | ||
3749 | tcp_hdr(skb)->check = | ||
3750 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | ||
3751 | &ipv6_hdr(skb)->daddr, | ||
3752 | 0, IPPROTO_TCP, 0); | ||
3753 | ipcse = 0; | ||
3754 | } | ||
3755 | ipcss = skb_network_offset(skb); | ||
3756 | ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data; | ||
3757 | tucss = skb_transport_offset(skb); | ||
3758 | tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; | ||
3759 | tucse = 0; | ||
3760 | 3736 | ||
3761 | cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | | 3737 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
3762 | E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); | 3738 | mss = skb_shinfo(skb)->gso_size; |
3739 | if (skb->protocol == htons(ETH_P_IP)) { | ||
3740 | struct iphdr *iph = ip_hdr(skb); | ||
3741 | iph->tot_len = 0; | ||
3742 | iph->check = 0; | ||
3743 | tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
3744 | 0, IPPROTO_TCP, 0); | ||
3745 | cmd_length = E1000_TXD_CMD_IP; | ||
3746 | ipcse = skb_transport_offset(skb) - 1; | ||
3747 | } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { | ||
3748 | ipv6_hdr(skb)->payload_len = 0; | ||
3749 | tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | ||
3750 | &ipv6_hdr(skb)->daddr, | ||
3751 | 0, IPPROTO_TCP, 0); | ||
3752 | ipcse = 0; | ||
3753 | } | ||
3754 | ipcss = skb_network_offset(skb); | ||
3755 | ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data; | ||
3756 | tucss = skb_transport_offset(skb); | ||
3757 | tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; | ||
3758 | tucse = 0; | ||
3763 | 3759 | ||
3764 | i = tx_ring->next_to_use; | 3760 | cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | |
3765 | context_desc = E1000_CONTEXT_DESC(*tx_ring, i); | 3761 | E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); |
3766 | buffer_info = &tx_ring->buffer_info[i]; | ||
3767 | 3762 | ||
3768 | context_desc->lower_setup.ip_fields.ipcss = ipcss; | 3763 | i = tx_ring->next_to_use; |
3769 | context_desc->lower_setup.ip_fields.ipcso = ipcso; | 3764 | context_desc = E1000_CONTEXT_DESC(*tx_ring, i); |
3770 | context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse); | 3765 | buffer_info = &tx_ring->buffer_info[i]; |
3771 | context_desc->upper_setup.tcp_fields.tucss = tucss; | ||
3772 | context_desc->upper_setup.tcp_fields.tucso = tucso; | ||
3773 | context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse); | ||
3774 | context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss); | ||
3775 | context_desc->tcp_seg_setup.fields.hdr_len = hdr_len; | ||
3776 | context_desc->cmd_and_length = cpu_to_le32(cmd_length); | ||
3777 | 3766 | ||
3778 | buffer_info->time_stamp = jiffies; | 3767 | context_desc->lower_setup.ip_fields.ipcss = ipcss; |
3779 | buffer_info->next_to_watch = i; | 3768 | context_desc->lower_setup.ip_fields.ipcso = ipcso; |
3769 | context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse); | ||
3770 | context_desc->upper_setup.tcp_fields.tucss = tucss; | ||
3771 | context_desc->upper_setup.tcp_fields.tucso = tucso; | ||
3772 | context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse); | ||
3773 | context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss); | ||
3774 | context_desc->tcp_seg_setup.fields.hdr_len = hdr_len; | ||
3775 | context_desc->cmd_and_length = cpu_to_le32(cmd_length); | ||
3780 | 3776 | ||
3781 | i++; | 3777 | buffer_info->time_stamp = jiffies; |
3782 | if (i == tx_ring->count) | 3778 | buffer_info->next_to_watch = i; |
3783 | i = 0; | ||
3784 | tx_ring->next_to_use = i; | ||
3785 | 3779 | ||
3786 | return 1; | 3780 | i++; |
3787 | } | 3781 | if (i == tx_ring->count) |
3782 | i = 0; | ||
3783 | tx_ring->next_to_use = i; | ||
3788 | 3784 | ||
3789 | return 0; | 3785 | return 1; |
3790 | } | 3786 | } |
3791 | 3787 | ||
3792 | static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) | 3788 | static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) |