net/e1000: configure outer VLAN TPID field
authorBeilei Xing <beilei.xing@intel.com>
Thu, 16 Jun 2016 13:36:28 +0000 (21:36 +0800)
committerBruce Richardson <bruce.richardson@intel.com>
Fri, 24 Jun 2016 16:28:01 +0000 (18:28 +0200)
This patch enables configuring the outer TPID for double VLAN.
Note that all other TPID values, for single VLANs or inner VLAN in the
QinQ case, are read only.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
drivers/net/e1000/igb_ethdev.c

index b98c827..b9b9eaf 100644 (file)
 #define E1000_VTIVAR_MISC_MAILBOX        0
 #define E1000_VTIVAR_MISC_INTR_MASK      0x3
 
+/* External VLAN Enable bit mask */
+#define E1000_CTRL_EXT_EXT_VLAN      (1 << 26)
+
+/* External VLAN Ether Type bit mask and shift */
+#define E1000_VET_VET_EXT            0xFFFF0000
+#define E1000_VET_VET_EXT_SHIFT      16
+
 static int  eth_igb_configure(struct rte_eth_dev *dev);
 static int  eth_igb_start(struct rte_eth_dev *dev);
 static void eth_igb_stop(struct rte_eth_dev *dev);
@@ -2334,21 +2341,25 @@ eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
 {
        struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint32_t reg = ETHER_TYPE_VLAN;
-       int ret = 0;
+       uint32_t reg, qinq;
+
+       qinq = E1000_READ_REG(hw, E1000_CTRL_EXT);
+       qinq &= E1000_CTRL_EXT_EXT_VLAN;
 
-       switch (vlan_type) {
-       case ETH_VLAN_TYPE_INNER:
-               reg |= (tpid << 16);
+       /* only outer TPID of double VLAN can be configured*/
+       if (qinq && vlan_type == ETH_VLAN_TYPE_OUTER) {
+               reg = E1000_READ_REG(hw, E1000_VET);
+               reg = (reg & (~E1000_VET_VET_EXT)) |
+                       ((uint32_t)tpid << E1000_VET_VET_EXT_SHIFT);
                E1000_WRITE_REG(hw, E1000_VET, reg);
-               break;
-       default:
-               ret = -EINVAL;
-               PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
-               break;
+
+               return 0;
        }
 
-       return ret;
+       /* all other TPID values are read-only*/
+       PMD_DRV_LOG(ERR, "Not supported");
+
+       return -ENOTSUP;
 }
 
 static void