net/cxgbe: add option to keep outer VLAN tag in QinQ

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

Signed-off-by: Shagun Agrawal <shaguna@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
This commit is contained in:
Shagun Agrawal 2018-04-04 09:23:36 +05:30 committed by Ferruh Yigit
parent a9e3e99916
commit cda260a4ac
4 changed files with 154 additions and 1 deletions

View File

@ -127,6 +127,22 @@ enabling debugging options may affect system performance.
Toggle behaviour to prefer Throughput or Latency.
Runtime Options
~~~~~~~~~~~~~~~
The following ``devargs`` options can be enabled at runtime. They must
be passed as part of EAL arguments. For example,
.. code-block:: console
testpmd -w 02:00.4,keep_ovlan=1 -- -i
- ``keep_ovlan`` (default **0**)
Toggle behaviour to keep/strip outer VLAN in Q-in-Q packets. If
enabled, the outer VLAN tag is preserved in Q-in-Q packets. Otherwise,
the outer VLAN tag is stripped in Q-in-Q packets.
.. _driver-compilation:
Driver compilation and testing

View File

@ -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

View File

@ -32,12 +32,15 @@
#include <rte_malloc.h>
#include <rte_random.h>
#include <rte_dev.h>
#include <rte_kvargs.h>
#include "common.h"
#include "t4_regs.h"
#include "t4_msg.h"
#include "cxgbe.h"
#define CXGBE_DEVARG_KEEP_OVLAN "keep_ovlan"
/*
* Response queue handler for the FW event queue.
*/
@ -392,6 +395,84 @@ void print_port_info(struct adapter *adap)
}
}
static int
check_devargs_handler(__rte_unused const char *key, const char *value,
__rte_unused void *opaque)
{
if (strcmp(value, "1"))
return -1;
return 0;
}
static int cxgbe_get_devargs(struct rte_devargs *devargs, const char *key)
{
struct rte_kvargs *kvlist;
if (!devargs)
return 0;
kvlist = rte_kvargs_parse(devargs->args, NULL);
if (!kvlist)
return 0;
if (!rte_kvargs_count(kvlist, key)) {
rte_kvargs_free(kvlist);
return 0;
}
if (rte_kvargs_process(kvlist, key,
check_devargs_handler, NULL) < 0) {
rte_kvargs_free(kvlist);
return 0;
}
rte_kvargs_free(kvlist);
return 1;
}
static void configure_vlan_types(struct adapter *adapter)
{
struct rte_pci_device *pdev = adapter->pdev;
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);
}
if (cxgbe_get_devargs(pdev->device.devargs, CXGBE_DEVARG_KEEP_OVLAN))
t4_tp_wr_bits_indirect(adapter, A_TP_INGRESS_CONFIG,
V_RM_OVLAN(1), V_RM_OVLAN(0));
}
static void configure_pcie_ext_tag(struct adapter *adapter)
{
u16 v;
@ -808,6 +889,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;

View File

@ -1597,7 +1597,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);
}