|
@@ -2674,7 +2674,8 @@ set_itr_now:
|
|
#define E1000_TX_FLAGS_VLAN_SHIFT 16
|
|
#define E1000_TX_FLAGS_VLAN_SHIFT 16
|
|
|
|
|
|
static int e1000_tso(struct e1000_adapter *adapter,
|
|
static int e1000_tso(struct e1000_adapter *adapter,
|
|
- struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
|
|
|
|
|
|
+ struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
|
|
|
|
+ __be16 protocol)
|
|
{
|
|
{
|
|
struct e1000_context_desc *context_desc;
|
|
struct e1000_context_desc *context_desc;
|
|
struct e1000_buffer *buffer_info;
|
|
struct e1000_buffer *buffer_info;
|
|
@@ -2692,7 +2693,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
|
|
|
|
|
|
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
|
|
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
|
|
mss = skb_shinfo(skb)->gso_size;
|
|
mss = skb_shinfo(skb)->gso_size;
|
|
- if (skb->protocol == htons(ETH_P_IP)) {
|
|
|
|
|
|
+ if (protocol == htons(ETH_P_IP)) {
|
|
struct iphdr *iph = ip_hdr(skb);
|
|
struct iphdr *iph = ip_hdr(skb);
|
|
iph->tot_len = 0;
|
|
iph->tot_len = 0;
|
|
iph->check = 0;
|
|
iph->check = 0;
|
|
@@ -2702,7 +2703,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
|
|
0);
|
|
0);
|
|
cmd_length = E1000_TXD_CMD_IP;
|
|
cmd_length = E1000_TXD_CMD_IP;
|
|
ipcse = skb_transport_offset(skb) - 1;
|
|
ipcse = skb_transport_offset(skb) - 1;
|
|
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
|
|
|
|
|
|
+ } else if (skb_is_gso_v6(skb)) {
|
|
ipv6_hdr(skb)->payload_len = 0;
|
|
ipv6_hdr(skb)->payload_len = 0;
|
|
tcp_hdr(skb)->check =
|
|
tcp_hdr(skb)->check =
|
|
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
|
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
|
@@ -2745,7 +2746,8 @@ static int e1000_tso(struct e1000_adapter *adapter,
|
|
}
|
|
}
|
|
|
|
|
|
static bool e1000_tx_csum(struct e1000_adapter *adapter,
|
|
static bool e1000_tx_csum(struct e1000_adapter *adapter,
|
|
- struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
|
|
|
|
|
|
+ struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
|
|
|
|
+ __be16 protocol)
|
|
{
|
|
{
|
|
struct e1000_context_desc *context_desc;
|
|
struct e1000_context_desc *context_desc;
|
|
struct e1000_buffer *buffer_info;
|
|
struct e1000_buffer *buffer_info;
|
|
@@ -2756,7 +2758,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
|
|
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
|
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- switch (skb->protocol) {
|
|
|
|
|
|
+ switch (protocol) {
|
|
case cpu_to_be16(ETH_P_IP):
|
|
case cpu_to_be16(ETH_P_IP):
|
|
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
|
|
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
|
|
cmd_len |= E1000_TXD_CMD_TCP;
|
|
cmd_len |= E1000_TXD_CMD_TCP;
|
|
@@ -3097,6 +3099,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
|
int count = 0;
|
|
int count = 0;
|
|
int tso;
|
|
int tso;
|
|
unsigned int f;
|
|
unsigned int f;
|
|
|
|
+ __be16 protocol = vlan_get_protocol(skb);
|
|
|
|
|
|
/* This goes back to the question of how to logically map a Tx queue
|
|
/* This goes back to the question of how to logically map a Tx queue
|
|
* to a flow. Right now, performance is impacted slightly negatively
|
|
* to a flow. Right now, performance is impacted slightly negatively
|
|
@@ -3210,7 +3213,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
|
|
|
|
|
first = tx_ring->next_to_use;
|
|
first = tx_ring->next_to_use;
|
|
|
|
|
|
- tso = e1000_tso(adapter, tx_ring, skb);
|
|
|
|
|
|
+ tso = e1000_tso(adapter, tx_ring, skb, protocol);
|
|
if (tso < 0) {
|
|
if (tso < 0) {
|
|
dev_kfree_skb_any(skb);
|
|
dev_kfree_skb_any(skb);
|
|
return NETDEV_TX_OK;
|
|
return NETDEV_TX_OK;
|
|
@@ -3220,10 +3223,10 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
|
if (likely(hw->mac_type != e1000_82544))
|
|
if (likely(hw->mac_type != e1000_82544))
|
|
tx_ring->last_tx_tso = true;
|
|
tx_ring->last_tx_tso = true;
|
|
tx_flags |= E1000_TX_FLAGS_TSO;
|
|
tx_flags |= E1000_TX_FLAGS_TSO;
|
|
- } else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
|
|
|
|
|
|
+ } else if (likely(e1000_tx_csum(adapter, tx_ring, skb, protocol)))
|
|
tx_flags |= E1000_TX_FLAGS_CSUM;
|
|
tx_flags |= E1000_TX_FLAGS_CSUM;
|
|
|
|
|
|
- if (likely(skb->protocol == htons(ETH_P_IP)))
|
|
|
|
|
|
+ if (protocol == htons(ETH_P_IP))
|
|
tx_flags |= E1000_TX_FLAGS_IPV4;
|
|
tx_flags |= E1000_TX_FLAGS_IPV4;
|
|
|
|
|
|
if (unlikely(skb->no_fcs))
|
|
if (unlikely(skb->no_fcs))
|