i40e/i40evf: Set Ethernet protocol correctly when Tx VLAN offloads are disabled
authorGreg Rose <gregory.v.rose@intel.com>
Tue, 31 Mar 2015 07:45:03 +0000 (00:45 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 3 Apr 2015 10:54:30 +0000 (03:54 -0700)
If transmit VLAN HW offloads are disabled then the network stack sends up
an skb with the protocol set to 8021q. In that case to get the correct
checksum offloads we have to reset the skb protocol to the encapsulated
ethertype.

Change-ID: I903d78533de09b1c5d3ec695ee1990dd0fa5dd0d
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Jim Young <james.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c

index 5a1a67733b880232e71589f3f564b4fd8aa17654..d8989f9d1798cfa7279c3216a08a4cdbfafd03d9 100644 (file)
@@ -2057,6 +2057,19 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
        __be16 protocol = skb->protocol;
        u32  tx_flags = 0;
 
+       if (protocol == htons(ETH_P_8021Q) &&
+           !(tx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) {
+               /* When HW VLAN acceleration is turned off by the user the
+                * stack sets the protocol to 8021q so that the driver
+                * can take any steps required to support the SW only
+                * VLAN handling.  In our case the driver doesn't need
+                * to take any further steps so just set the protocol
+                * to the encapsulated ethertype.
+                */
+               skb->protocol = vlan_get_protocol(skb);
+               goto out;
+       }
+
        /* if we have a HW VLAN tag being added, default to the HW one */
        if (skb_vlan_tag_present(skb)) {
                tx_flags |= skb_vlan_tag_get(skb) << I40E_TX_FLAGS_VLAN_SHIFT;
index 2be50a8d36711f27c562ab3cf538b8937b07d4a8..e2ddb30e96f594a210470b56621cf2ac3f19a0d0 100644 (file)
@@ -1370,6 +1370,19 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
        __be16 protocol = skb->protocol;
        u32  tx_flags = 0;
 
+       if (protocol == htons(ETH_P_8021Q) &&
+           !(tx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) {
+               /* When HW VLAN acceleration is turned off by the user the
+                * stack sets the protocol to 8021q so that the driver
+                * can take any steps required to support the SW only
+                * VLAN handling.  In our case the driver doesn't need
+                * to take any further steps so just set the protocol
+                * to the encapsulated ethertype.
+                */
+               skb->protocol = vlan_get_protocol(skb);
+               goto out;
+       }
+
        /* if we have a HW VLAN tag being added, default to the HW one */
        if (skb_vlan_tag_present(skb)) {
                tx_flags |= skb_vlan_tag_get(skb) << I40E_TX_FLAGS_VLAN_SHIFT;
@@ -1386,6 +1399,7 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
                tx_flags |= I40E_TX_FLAGS_SW_VLAN;
        }
 
+out:
        *flags = tx_flags;
        return 0;
 }