All of lore.kernel.org
 help / color / mirror / Atom feed
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


  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.