net/i40e: fix single VLAN tag to be outer VLAN tag
authorBeilei Xing <beilei.xing@intel.com>
Wed, 22 Jun 2016 02:53:51 +0000 (10:53 +0800)
committerBruce Richardson <bruce.richardson@intel.com>
Fri, 24 Jun 2016 16:28:09 +0000 (18:28 +0200)
In current i40e codebase, if single VLAN header is added in a packet,
it's treated as inner VLAN. Generally, a single VLAN header is
treated as the outer VLAN header, so update the driver behaviour
appropriately.

Fixes: 19b16e2f6442 ("ethdev: add vlan type when setting ether type")

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
doc/guides/rel_notes/release_16_07.rst
drivers/net/i40e/i40e_ethdev.c
lib/librte_ether/rte_ethdev.h

index 5f6366c..b198890 100644 (file)
@@ -178,6 +178,13 @@ Drivers
   info to descriptor.
   Now this issue is fixed by disabling vlan stripping from inner header.
 
+* **i40e: Fixed the type issue of a single VLAN type.**
+
+  Currently, if a single VLAN header is added in a packet, it's treated
+  as inner VLAN. But generally, a single VLAN header is treated as the
+  outer VLAN header.
+  This issue is fixed by changing corresponding register for single VLAN.
+
 
 Libraries
 ~~~~~~~~~
index c1fb89a..ccab70e 100644 (file)
@@ -927,12 +927,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                             "VLAN ether type");
                goto err_setup_pf_switch;
        }
-       ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, ETHER_TYPE_VLAN);
-       if (ret != I40E_SUCCESS) {
-               PMD_INIT_LOG(ERR, "Failed to set the default outer "
-                            "VLAN ether type");
-               goto err_setup_pf_switch;
-       }
 
        /* PF setup, which includes VSI setup */
        ret = i40e_pf_setup(pf);
@@ -2493,13 +2487,24 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
        uint64_t reg_r = 0, reg_w = 0;
        uint16_t reg_id = 0;
        int ret = 0;
+       int qinq = dev->data->dev_conf.rxmode.hw_vlan_extend;
 
        switch (vlan_type) {
        case ETH_VLAN_TYPE_OUTER:
-               reg_id = 2;
+               if (qinq)
+                       reg_id = 2;
+               else
+                       reg_id = 3;
                break;
        case ETH_VLAN_TYPE_INNER:
-               reg_id = 3;
+               if (qinq)
+                       reg_id = 3;
+               else {
+                       ret = -EINVAL;
+                       PMD_DRV_LOG(ERR,
+                               "Unsupported vlan type in single vlan.\n");
+                       return ret;
+               }
                break;
        default:
                ret = -EINVAL;
@@ -2561,8 +2566,14 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        }
 
        if (mask & ETH_VLAN_EXTEND_MASK) {
-               if (dev->data->dev_conf.rxmode.hw_vlan_extend)
+               if (dev->data->dev_conf.rxmode.hw_vlan_extend) {
                        i40e_vsi_config_double_vlan(vsi, TRUE);
+                       /* Set global registers with default ether type value */
+                       i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
+                                          ETHER_TYPE_VLAN);
+                       i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER,
+                                          ETHER_TYPE_VLAN);
+               }
                else
                        i40e_vsi_config_double_vlan(vsi, FALSE);
        }
index e01e47c..05d7939 100644 (file)
@@ -363,8 +363,8 @@ struct rte_eth_rxmode {
  */
 enum rte_vlan_type {
        ETH_VLAN_TYPE_UNKNOWN = 0,
-       ETH_VLAN_TYPE_INNER, /**< Single VLAN, or inner VLAN. */
-       ETH_VLAN_TYPE_OUTER, /**< Outer VLAN. */
+       ETH_VLAN_TYPE_INNER, /**< Inner VLAN. */
+       ETH_VLAN_TYPE_OUTER, /**< Single VLAN, or outer VLAN. */
        ETH_VLAN_TYPE_MAX,
 };