From: Kumar Sanghvi <kuma...@chelsio.com>

Add compile time option to keep outer VLAN tag in Q-in-Q packets.

Signed-off-by: Kumar Sanghvi <kuma...@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkire...@chelsio.com>
---
 config/common_base               |  1 +
 doc/guides/nics/cxgbe.rst        |  4 +++
 drivers/net/cxgbe/base/t4_regs.h | 54 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/cxgbe_main.c   | 43 ++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/sge.c          |  3 ++-
 5 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/config/common_base b/config/common_base
index ad03cf433..325e9847c 100644
--- a/config/common_base
+++ b/config/common_base
@@ -167,6 +167,7 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
 CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
 CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
 CONFIG_RTE_LIBRTE_CXGBE_TPUT=y
+CONFIG_RTE_LIBRTE_CXGBE_KEEP_OVLAN=n
 
 # NXP DPAA Bus
 CONFIG_RTE_LIBRTE_DPAA_BUS=n
diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst
index f2e209901..a84547f6f 100644
--- a/doc/guides/nics/cxgbe.rst
+++ b/doc/guides/nics/cxgbe.rst
@@ -110,6 +110,10 @@ enabling debugging options may affect system performance.
 
   Toggle behaviour to prefer Throughput or Latency.
 
+- ``CONFIG_RTE_LIBRTE_CXGBE_KEEP_OVLAN`` (default **n**)
+
+  Toggle behaviour to keep/remove Outer VLAN in Q-in-Q.
+
 .. _driver-compilation:
 
 Driver compilation and testing
diff --git a/drivers/net/cxgbe/base/t4_regs.h b/drivers/net/cxgbe/base/t4_regs.h
index 28ff21927..c0d6ddcac 100644
--- a/drivers/net/cxgbe/base/t4_regs.h
+++ b/drivers/net/cxgbe/base/t4_regs.h
@@ -571,6 +571,9 @@
 #define V_CSUM_HAS_PSEUDO_HDR(x) ((x) << S_CSUM_HAS_PSEUDO_HDR)
 #define F_CSUM_HAS_PSEUDO_HDR    V_CSUM_HAS_PSEUDO_HDR(1U)
 
+#define S_RM_OVLAN     9
+#define V_RM_OVLAN(x)  ((x) << S_RM_OVLAN)
+
 /* registers for module MPS */
 #define MPS_BASE_ADDR 0x9000
 #define T4VF_MPS_BASE_ADDR 0x0100
@@ -789,6 +792,57 @@
 #define A_MPS_VF_STAT_RX_VF_UCAST_FRAMES_L 0xf0
 #define A_MPS_VF_STAT_RX_VF_ERR_FRAMES_L 0xf8
 
+#define A_MPS_PORT0_RX_IVLAN   0x3011c
+
+#define S_IVLAN_ETYPE          0
+#define M_IVLAN_ETYPE          0xffffU
+#define V_IVLAN_ETYPE(x)       ((x) << S_IVLAN_ETYPE)
+
+#define MPS_PORT_RX_IVLAN_STRIDE       0x4000
+#define MPS_PORT_RX_IVLAN(idx)         \
+       (A_MPS_PORT0_RX_IVLAN + (idx) * MPS_PORT_RX_IVLAN_STRIDE)
+
+#define A_MPS_PORT0_RX_OVLAN0  0x30120
+
+#define S_OVLAN_MASK   16
+#define M_OVLAN_MASK   0xffffU
+#define V_OVLAN_MASK(x)        ((x) << S_OVLAN_MASK)
+
+#define S_OVLAN_ETYPE          0
+#define M_OVLAN_ETYPE          0xffffU
+#define V_OVLAN_ETYPE(x)       ((x) << S_OVLAN_ETYPE)
+
+#define MPS_PORT_RX_OVLAN_STRIDE       0x4000
+#define MPS_PORT_RX_OVLAN_BASE(idx)    \
+(A_MPS_PORT0_RX_OVLAN0 + (idx) * MPS_PORT_RX_OVLAN_STRIDE)
+#define MPS_PORT_RX_OVLAN_REG(idx, reg)        (MPS_PORT_RX_OVLAN_BASE(idx) + 
(reg))
+
+#define A_RX_OVLAN0    0x0
+#define A_RX_OVLAN1    0x4
+#define A_RX_OVLAN2    0x8
+
+#define A_MPS_PORT0_RX_CTL     0x30100
+
+#define S_OVLAN_EN0    0
+#define V_OVLAN_EN0(x) ((x) << S_OVLAN_EN0)
+#define F_OVLAN_EN0    V_OVLAN_EN0(1)
+
+#define S_OVLAN_EN1    1
+#define V_OVLAN_EN1(x) ((x) << S_OVLAN_EN1)
+#define F_OVLAN_EN1    V_OVLAN_EN1(1)
+
+#define S_OVLAN_EN2    2
+#define V_OVLAN_EN2(x) ((x) << S_OVLAN_EN2)
+#define F_OVLAN_EN2    V_OVLAN_EN2(1)
+
+#define S_IVLAN_EN     4
+#define V_IVLAN_EN(x)  ((x) << S_IVLAN_EN)
+#define F_IVLAN_EN     V_IVLAN_EN(1)
+
+#define MPS_PORT_RX_CTL_STRIDE 0x4000
+#define MPS_PORT_RX_CTL(idx)   \
+       (A_MPS_PORT0_RX_CTL + (idx) * MPS_PORT_RX_CTL_STRIDE)
+
 /* registers for module ULP_RX */
 #define ULP_RX_BASE_ADDR 0x19150
 
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 01a80ace8..7cbdb2aa0 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -392,6 +392,48 @@ void print_port_info(struct adapter *adap)
        }
 }
 
+static void configure_vlan_types(struct adapter *adapter)
+{
+       int i;
+
+       for_each_port(adapter, i) {
+               /* OVLAN Type 0x88a8 */
+               t4_set_reg_field(adapter, MPS_PORT_RX_OVLAN_REG(i, A_RX_OVLAN0),
+                                V_OVLAN_MASK(M_OVLAN_MASK) |
+                                V_OVLAN_ETYPE(M_OVLAN_ETYPE),
+                                V_OVLAN_MASK(M_OVLAN_MASK) |
+                                V_OVLAN_ETYPE(0x88a8));
+               /* OVLAN Type 0x9100 */
+               t4_set_reg_field(adapter, MPS_PORT_RX_OVLAN_REG(i, A_RX_OVLAN1),
+                                V_OVLAN_MASK(M_OVLAN_MASK) |
+                                V_OVLAN_ETYPE(M_OVLAN_ETYPE),
+                                V_OVLAN_MASK(M_OVLAN_MASK) |
+                                V_OVLAN_ETYPE(0x9100));
+               /* OVLAN Type 0x8100 */
+               t4_set_reg_field(adapter, MPS_PORT_RX_OVLAN_REG(i, A_RX_OVLAN2),
+                                V_OVLAN_MASK(M_OVLAN_MASK) |
+                                V_OVLAN_ETYPE(M_OVLAN_ETYPE),
+                                V_OVLAN_MASK(M_OVLAN_MASK) |
+                                V_OVLAN_ETYPE(0x8100));
+
+               /* IVLAN 0X8100 */
+               t4_set_reg_field(adapter, MPS_PORT_RX_IVLAN(i),
+                                V_IVLAN_ETYPE(M_IVLAN_ETYPE),
+                                V_IVLAN_ETYPE(0x8100));
+
+               t4_set_reg_field(adapter, MPS_PORT_RX_CTL(i),
+                                F_OVLAN_EN0 | F_OVLAN_EN1 |
+                                F_OVLAN_EN2 | F_IVLAN_EN,
+                                F_OVLAN_EN0 | F_OVLAN_EN1 |
+                                F_OVLAN_EN2 | F_IVLAN_EN);
+       }
+
+#ifdef RTE_LIBRTE_CXGBE_KEEP_OVLAN
+       t4_tp_wr_bits_indirect(adapter, A_TP_INGRESS_CONFIG,
+                              V_RM_OVLAN(1), V_RM_OVLAN(0));
+#endif
+}
+
 static void configure_pcie_ext_tag(struct adapter *adapter)
 {
        u16 v;
@@ -808,6 +850,7 @@ static int adap_init0(struct adapter *adap)
        t4_init_sge_params(adap);
        t4_init_tp_params(adap);
        configure_pcie_ext_tag(adap);
+       configure_vlan_types(adap);
 
        adap->params.drv_memwin = MEMWIN_NIC;
        adap->flags |= FW_OK;
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 83e26d0c6..0d866354e 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1596,7 +1596,8 @@ static int process_responses(struct sge_rspq *q, int 
budget,
                                }
 
                                if (cpl->vlan_ex) {
-                                       pkt->ol_flags |= PKT_RX_VLAN;
+                                       pkt->ol_flags |= PKT_RX_VLAN |
+                                                        PKT_RX_VLAN_STRIPPED;
                                        pkt->vlan_tci = ntohs(cpl->vlan);
                                }
 
-- 
2.14.1

Reply via email to