From: Alexander Duyck Date: Fri, 26 Aug 2011 07:44:53 +0000 (+0000) Subject: igb: Cleanup protocol handling in transmit path X-Git-Tag: v2.6.39-400.9.0~423^2~19^2~11^2~279 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a4bc16752d4d8e840cdf2ecf5d6e9356b6f43493;p=users%2Fjedix%2Flinux-maple.git igb: Cleanup protocol handling in transmit path This change is meant to cleanup the protocol handling in the transmit path so that it correctly offloads software VLAN tagged frames. (cherry picked from commit 31f6adbb352ae118550ab51f2a5ed1023ec7eb03) Signed-off-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Joe Jin --- diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index e581added4a7..156745a9b9ed 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3988,8 +3988,8 @@ void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens, context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); } -static inline int igb_tso(struct igb_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, u8 *hdr_len) +static inline int igb_tso(struct igb_ring *tx_ring, struct sk_buff *skb, + u32 tx_flags, __be16 protocol, u8 *hdr_len) { int err; u32 vlan_macip_lens, type_tucmd; @@ -4007,7 +4007,7 @@ static inline int igb_tso(struct igb_ring *tx_ring, /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP; - if (skb->protocol == htons(ETH_P_IP)) { + if (protocol == __constant_htons(ETH_P_IP)) { struct iphdr *iph = ip_hdr(skb); iph->tot_len = 0; iph->check = 0; @@ -4040,8 +4040,8 @@ static inline int igb_tso(struct igb_ring *tx_ring, return 1; } -static inline bool igb_tx_csum(struct igb_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags) +static inline bool igb_tx_csum(struct igb_ring *tx_ring, struct sk_buff *skb, + u32 tx_flags, __be16 protocol) { u32 vlan_macip_lens = 0; u32 mss_l4len_idx = 0; @@ -4052,7 +4052,7 @@ static inline bool igb_tx_csum(struct igb_ring *tx_ring, return false; } else { u8 l4_hdr = 0; - switch (skb->protocol) { + switch (protocol) { case __constant_htons(ETH_P_IP): vlan_macip_lens |= skb_network_header_len(skb); type_tucmd |= E1000_ADVTXD_TUCMD_IPV4; @@ -4066,7 +4066,7 @@ static inline bool igb_tx_csum(struct igb_ring *tx_ring, if (unlikely(net_ratelimit())) { dev_warn(tx_ring->dev, "partial checksum but proto=%x!\n", - skb->protocol); + protocol); } break; } @@ -4306,6 +4306,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, struct igb_tx_buffer *first; int tso, count; u32 tx_flags = 0; + __be16 protocol = vlan_get_protocol(skb); u8 hdr_len = 0; /* need: 1 descriptor per page, @@ -4331,16 +4332,14 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, /* record the location of the first descriptor for this packet */ first = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; - tso = igb_tso(tx_ring, skb, tx_flags, &hdr_len); - + tso = igb_tso(tx_ring, skb, tx_flags, protocol, &hdr_len); if (tso < 0) { goto out_drop; } else if (tso) { tx_flags |= IGB_TX_FLAGS_TSO | IGB_TX_FLAGS_CSUM; - if (skb->protocol == htons(ETH_P_IP)) + if (protocol == htons(ETH_P_IP)) tx_flags |= IGB_TX_FLAGS_IPV4; - - } else if (igb_tx_csum(tx_ring, skb, tx_flags) && + } else if (igb_tx_csum(tx_ring, skb, tx_flags, protocol) && (skb->ip_summed == CHECKSUM_PARTIAL)) { tx_flags |= IGB_TX_FLAGS_CSUM; }