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.
 
   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
 ~~~~~~~~~
 
 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;
        }
                             "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);
 
        /* 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;
        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:
 
        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:
                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;
                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 (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);
                        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);
        }
                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,
  */
 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,
 };
 
        ETH_VLAN_TYPE_MAX,
 };