aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/e1000/e1000_main.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 2ab44db29fa..3bafaede791 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2873,32 +2873,49 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info;
unsigned int i;
u8 css;
+ u32 cmd_len = E1000_TXD_CMD_DEXT;
- if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
- css = skb_transport_offset(skb);
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return false;
- i = tx_ring->next_to_use;
- buffer_info = &tx_ring->buffer_info[i];
- context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+ cmd_len |= E1000_TXD_CMD_TCP;
+ break;
+ case __constant_htons(ETH_P_IPV6):
+ /* XXX not handling all IPV6 headers */
+ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+ cmd_len |= E1000_TXD_CMD_TCP;
+ break;
+ default:
+ if (unlikely(net_ratelimit()))
+ DPRINTK(DRV, WARNING,
+ "checksum_partial proto=%x!\n", skb->protocol);
+ break;
+ }
- context_desc->lower_setup.ip_config = 0;
- context_desc->upper_setup.tcp_fields.tucss = css;
- context_desc->upper_setup.tcp_fields.tucso =
- css + skb->csum_offset;
- context_desc->upper_setup.tcp_fields.tucse = 0;
- context_desc->tcp_seg_setup.data = 0;
- context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
+ css = skb_transport_offset(skb);
- buffer_info->time_stamp = jiffies;
- buffer_info->next_to_watch = i;
+ i = tx_ring->next_to_use;
+ buffer_info = &tx_ring->buffer_info[i];
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
- if (unlikely(++i == tx_ring->count)) i = 0;
- tx_ring->next_to_use = i;
+ context_desc->lower_setup.ip_config = 0;
+ context_desc->upper_setup.tcp_fields.tucss = css;
+ context_desc->upper_setup.tcp_fields.tucso =
+ css + skb->csum_offset;
+ context_desc->upper_setup.tcp_fields.tucse = 0;
+ context_desc->tcp_seg_setup.data = 0;
+ context_desc->cmd_and_length = cpu_to_le32(cmd_len);
- return true;
- }
+ buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
- return false;
+ if (unlikely(++i == tx_ring->count)) i = 0;
+ tx_ring->next_to_use = i;
+
+ return true;
}
#define E1000_MAX_TXD_PWR 12