From: <psatheesh@marvell.com>
To: Nithin Dabilpuram <ndabilpuram@marvell.com>,
Kiran Kumar K <kirankumark@marvell.com>,
Sunil Kumar Kori <skori@marvell.com>,
Satha Rao <skoteshwar@marvell.com>
Cc: <dev@dpdk.org>, Satheesh Paul <psatheesh@marvell.com>
Subject: [dpdk-dev] [PATCH v2 3/4] common/cnxk: support matching VLAN existence in RTE Flow
Date: Mon, 3 Jan 2022 11:49:08 +0530 [thread overview]
Message-ID: <20220103061909.83319-3-psatheesh@marvell.com> (raw)
In-Reply-To: <20220103061909.83319-1-psatheesh@marvell.com>
From: Satheesh Paul <psatheesh@marvell.com>
Support matching existence of VLAN after
RTE_FLOW_ITEM_TYPE_ETH and RTE_FLOW_ITEM_TYPE_VLAN items.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
---
drivers/common/cnxk/roc_npc.h | 56 ++++++++++++++++++++++++++++-
drivers/common/cnxk/roc_npc_mcam.c | 37 ++++++++++++++++---
drivers/common/cnxk/roc_npc_parse.c | 56 +++++++++++++++++++++++++----
drivers/common/cnxk/roc_npc_priv.h | 7 ++++
drivers/common/cnxk/roc_platform.h | 6 +++-
5 files changed, 150 insertions(+), 12 deletions(-)
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 8b57678863..6ab185e188 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -58,6 +58,60 @@ struct roc_npc_flow_item_raw {
const uint8_t *pattern; /**< Byte string to look for. */
};
+struct roc_ether_addr {
+ uint8_t addr_bytes[PLT_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+} plt_aligned(2);
+
+struct roc_ether_hdr {
+ struct roc_ether_addr d_addr; /**< Destination address. */
+ PLT_STD_C11
+ union {
+ struct roc_ether_addr s_addr; /**< Source address. */
+ struct {
+ struct roc_ether_addr S_addr;
+ } S_un; /**< Do not use directly; use s_addr instead.*/
+ };
+ uint16_t ether_type; /**< Frame type. */
+} plt_aligned(2);
+
+PLT_STD_C11
+struct roc_npc_flow_item_eth {
+ union {
+ struct {
+ /*
+ * These fields are retained
+ * for compatibility.
+ * Please switch to the new header field below.
+ */
+ struct roc_ether_addr dst; /**< Destination MAC. */
+ struct roc_ether_addr src; /**< Source MAC. */
+ uint16_t type; /**< EtherType or TPID. */
+ };
+ struct roc_ether_hdr hdr;
+ };
+ uint32_t has_vlan : 1; /**< Packet header contains at least one VLAN. */
+ uint32_t reserved : 31; /**< Reserved, must be zero. */
+};
+
+struct roc_vlan_hdr {
+ uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
+ uint16_t eth_proto; /**< Ethernet type of encapsulated frame. */
+} __plt_packed;
+
+PLT_STD_C11
+struct roc_npc_flow_item_vlan {
+ union {
+ struct {
+ uint16_t tci; /**< Tag control information. */
+ uint16_t inner_type; /**< Inner EtherType or TPID. */
+ };
+ struct roc_vlan_hdr hdr;
+ };
+ uint32_t has_more_vlan : 1;
+ /**< Packet header contains at least one more VLAN, after this VLAN. */
+ uint32_t reserved : 31; /**< Reserved, must be zero. */
+};
+
#define ROC_NPC_MAX_ACTION_COUNT 19
enum roc_npc_action_type {
@@ -97,7 +151,7 @@ struct roc_npc_action_vf {
};
struct roc_npc_action_port_id {
- uint32_t original : 1; /**< Use original DPDK port ID if possible. */
+ uint32_t original : 1; /**< Use original port ID if possible. */
uint32_t reserved : 31; /**< Reserved, must be zero. */
uint32_t id; /**< port ID. */
};
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index 80851d6f9f..2349317c5c 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -613,6 +613,28 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow,
return 0;
}
+static void
+npc_set_vlan_ltype(struct npc_parse_state *pst)
+{
+ uint64_t val, mask;
+ uint8_t lb_offset;
+
+ lb_offset =
+ __builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ ((1ULL << NPC_LTYPE_LB_OFFSET) - 1));
+ lb_offset *= 4;
+
+ mask = ~((0xfULL << lb_offset));
+ pst->flow->mcam_data[0] &= mask;
+ pst->flow->mcam_mask[0] &= mask;
+ /* NPC_LT_LB_CTAG: 0b0010, NPC_LT_LB_STAG_QINQ: 0b0011
+ * Set LB layertype/mask as 0b0010/0b1110 to match both.
+ */
+ val = ((uint64_t)(NPC_LT_LB_CTAG & NPC_LT_LB_STAG_QINQ)) << lb_offset;
+ pst->flow->mcam_data[0] |= val;
+ pst->flow->mcam_mask[0] |= (0xeULL << lb_offset);
+}
+
int
npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
{
@@ -651,12 +673,16 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
if (layer_info) {
for (idx = 0; idx <= 2; idx++) {
if (layer_info & (1 << idx)) {
- if (idx == 2)
+ if (idx == 2) {
data = lt;
- else if (idx == 1)
+ mask = 0xf;
+ } else if (idx == 1) {
data = ((flags >> 4) & 0xf);
- else
+ mask = ((flags >> 4) & 0xf);
+ } else {
data = (flags & 0xf);
+ mask = (flags & 0xf);
+ }
if (data_off >= 64) {
data_off = 0;
@@ -664,7 +690,7 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
}
key_data[index] |=
((uint64_t)data << data_off);
- mask = 0xf;
+
if (lt == 0)
mask = 0;
key_mask[index] |=
@@ -680,6 +706,9 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
memcpy(pst->flow->mcam_data, key_data, key_len);
memcpy(pst->flow->mcam_mask, key_mask, key_len);
+ if (pst->set_vlan_ltype_mask)
+ npc_set_vlan_ltype(pst);
+
if (pst->is_vf) {
(void)mbox_alloc_msg_npc_read_base_steer_rule(npc->mbox);
rc = mbox_process_msg(npc->mbox, (void *)&base_rule_rsp);
diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c
index c9ab9aef28..75724661da 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -167,6 +167,7 @@ npc_parse_higig2_hdr(struct npc_parse_state *pst)
int
npc_parse_la(struct npc_parse_state *pst)
{
+ const struct roc_npc_flow_item_eth *eth_item;
uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
struct npc_parse_item_info info;
int lid, lt;
@@ -176,6 +177,8 @@ npc_parse_la(struct npc_parse_state *pst)
if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH)
return 0;
+ eth_item = pst->pattern->spec;
+
lid = NPC_LID_LA;
lt = NPC_LT_LA_ETHER;
info.hw_hdr_len = 0;
@@ -196,7 +199,7 @@ npc_parse_la(struct npc_parse_state *pst)
/* Prepare for parsing the item */
info.hw_mask = &hw_mask;
- info.len = pst->pattern->size;
+ info.len = sizeof(eth_item->hdr);
npc_get_hw_supp_mask(pst, &info, lid, lt);
info.spec = NULL;
info.mask = NULL;
@@ -206,13 +209,22 @@ npc_parse_la(struct npc_parse_state *pst)
if (rc)
return rc;
- /* Update pst if not validate only? clash check? */
- return npc_update_parse_state(pst, &info, lid, lt, 0);
+ rc = npc_update_parse_state(pst, &info, lid, lt, 0);
+ if (rc)
+ return rc;
+
+ if (eth_item && eth_item->has_vlan)
+ pst->set_vlan_ltype_mask = true;
+
+ return 0;
}
+#define NPC_MAX_SUPPORTED_VLANS 3
+
int
npc_parse_lb(struct npc_parse_state *pst)
{
+ const struct roc_npc_flow_item_vlan *vlan_item[NPC_MAX_SUPPORTED_VLANS];
const struct roc_npc_item_info *pattern = pst->pattern;
const struct roc_npc_item_info *last_pattern;
const struct roc_npc_flow_item_raw *raw_spec;
@@ -240,10 +252,14 @@ npc_parse_lb(struct npc_parse_state *pst)
* supported on first tag only.
*/
info.hw_mask = NULL;
- info.len = pst->pattern->size;
+ info.len = sizeof(vlan_item[0]->hdr);
pattern = pst->pattern;
while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
+ if (nr_vlans > NPC_MAX_SUPPORTED_VLANS - 1)
+ return NPC_ERR_PATTERN_NOTSUP;
+
+ vlan_item[nr_vlans] = pattern->spec;
nr_vlans++;
/* Basic validation of Second/Third vlan item */
@@ -260,12 +276,35 @@ npc_parse_lb(struct npc_parse_state *pst)
switch (nr_vlans) {
case 1:
lt = NPC_LT_LB_CTAG;
+ if (vlan_item[0] && vlan_item[0]->has_more_vlan)
+ lt = NPC_LT_LB_STAG_QINQ;
break;
case 2:
+ if (vlan_item[1] && vlan_item[1]->has_more_vlan) {
+ if (!(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+ 0x3ULL << NPC_LFLAG_LB_OFFSET))
+ return NPC_ERR_PATTERN_NOTSUP;
+
+ /* This lflag value will match either one of
+ * NPC_F_LB_L_WITH_STAG_STAG,
+ * NPC_F_LB_L_WITH_QINQ_CTAG,
+ * NPC_F_LB_L_WITH_QINQ_QINQ and
+ * NPC_F_LB_L_WITH_ITAG (0b0100 to 0b0111). For
+ * NPC_F_LB_L_WITH_ITAG, ltype is NPC_LT_LB_ETAG
+ * hence will not match.
+ */
+
+ lflags = NPC_F_LB_L_WITH_QINQ_CTAG &
+ NPC_F_LB_L_WITH_QINQ_QINQ &
+ NPC_F_LB_L_WITH_STAG_STAG;
+ } else {
+ lflags = NPC_F_LB_L_WITH_CTAG;
+ }
lt = NPC_LT_LB_STAG_QINQ;
- lflags = NPC_F_STAG_CTAG;
break;
case 3:
+ if (vlan_item[2] && vlan_item[2]->has_more_vlan)
+ return NPC_ERR_PATTERN_NOTSUP;
lt = NPC_LT_LB_STAG_QINQ;
lflags = NPC_F_STAG_STAG_CTAG;
break;
@@ -294,10 +333,15 @@ npc_parse_lb(struct npc_parse_state *pst)
}
info.len = pattern->size;
} else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_QINQ) {
+ vlan_item[0] = pst->pattern->spec;
info.hw_mask = NULL;
- info.len = pst->pattern->size;
+ info.len = sizeof(vlan_item[0]->hdr);
lt = NPC_LT_LB_STAG_QINQ;
lflags = NPC_F_STAG_CTAG;
+ if (vlan_item[0] && vlan_item[0]->has_more_vlan) {
+ lflags = NPC_F_LB_L_WITH_QINQ_CTAG &
+ NPC_F_LB_L_WITH_QINQ_QINQ;
+ }
} else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_RAW) {
raw_spec = pst->pattern->spec;
if (raw_spec->relative)
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index 1a40192599..ef7985f4cf 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -67,6 +67,11 @@
#define NPC_ACTION_MAX_VLAN_PARAMS 3
#define NPC_ACTION_MAX_VLANS_STRIPPED 2
+#define NPC_LTYPE_OFFSET_START 7
+/* LB OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags) */
+#define NPC_LTYPE_LB_OFFSET (NPC_LTYPE_OFFSET_START + 5)
+#define NPC_LFLAG_LB_OFFSET (NPC_LTYPE_OFFSET_START + 3)
+
struct npc_action_vtag_info {
uint16_t vlan_id;
uint16_t vlan_ethtype;
@@ -176,6 +181,8 @@ struct npc_parse_state {
uint8_t *mcam_data; /* point to flow->mcam_data + key_len */
uint8_t *mcam_mask; /* point to flow->mcam_mask + key_len */
bool is_vf;
+ /* adjust ltype in MCAM to match at least one vlan */
+ bool set_vlan_ltype_mask;
};
enum npc_kpu_parser_flag {
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 61d4781209..28e67c91a1 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -11,6 +11,7 @@
#include <rte_byteorder.h>
#include <rte_common.h>
#include <rte_cycles.h>
+#include <rte_ether.h>
#include <rte_interrupts.h>
#include <rte_io.h>
#include <rte_log.h>
@@ -53,7 +54,9 @@
#define BITMASK_ULL GENMASK_ULL
#define PLT_ALIGN_CEIL RTE_ALIGN_CEIL
#define PLT_INIT RTE_INIT
-
+#ifndef PLT_ETHER_ADDR_LEN
+#define PLT_ETHER_ADDR_LEN RTE_ETHER_ADDR_LEN
+#endif
/** Divide ceil */
#define PLT_DIV_CEIL(x, y) \
({ \
@@ -82,6 +85,7 @@
#define plt_cpu_to_be_64 rte_cpu_to_be_64
#define plt_be_to_cpu_64 rte_be_to_cpu_64
+#define plt_aligned __rte_aligned
#define plt_align32pow2 rte_align32pow2
#define plt_align32prevpow2 rte_align32prevpow2
--
2.25.4
next prev parent reply other threads:[~2022-01-03 6:19 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-03 5:57 [dpdk-dev] [PATCH 1/4] drivers: add support for switch header type pre L2 psatheesh
2022-01-03 5:57 ` [dpdk-dev] [PATCH 2/4] common/cnxk: support custom pre L2 header parsing as raw psatheesh
2022-01-03 5:57 ` [dpdk-dev] [PATCH 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
2022-01-03 5:57 ` [dpdk-dev] [PATCH 4/4] common/cnxk: support extensions attributes in IPv6 item psatheesh
2022-01-03 6:19 ` [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2 psatheesh
2022-01-03 6:19 ` [dpdk-dev] [PATCH v2 2/4] common/cnxk: support custom pre L2 header parsing as raw psatheesh
2022-01-03 6:19 ` psatheesh [this message]
2022-01-03 6:19 ` [dpdk-dev] [PATCH v2 4/4] common/cnxk: support extensions attributes in IPv6 item psatheesh
2022-01-20 6:54 ` [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2 Jerin Jacob
2022-01-21 6:26 ` [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2 psatheesh
2022-01-21 6:26 ` [dpdk-dev v3] [PATCH 2/4] common/cnxk: support custom pre L2 header parsing as raw psatheesh
2022-01-21 6:26 ` [dpdk-dev v3] [PATCH 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
2022-01-21 6:26 ` [dpdk-dev v3] [PATCH 4/4] common/cnxk: support extensions attributes in IPv6 item psatheesh
2022-01-22 14:08 ` [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2 Jerin Jacob
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220103061909.83319-3-psatheesh@marvell.com \
--to=psatheesh@marvell.com \
--cc=dev@dpdk.org \
--cc=kirankumark@marvell.com \
--cc=ndabilpuram@marvell.com \
--cc=skori@marvell.com \
--cc=skoteshwar@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).