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 5a1a677..d8989f9 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 2be50a8..e2ddb30 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;
 }