DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 1/4] drivers: add support for switch header type pre L2
@ 2022-01-03  5:57 psatheesh
  2022-01-03  5:57 ` [dpdk-dev] [PATCH 2/4] common/cnxk: support custom pre L2 header parsing as raw psatheesh
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  5:57 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, sa_ip-toolkits-Jenkins, Satheesh Paul

From: Kiran Kumar K <kirankumark@marvell.com>

Adding changes to configure switch header type pre L2 for cnxk.
Along with switch header type user needs to provide the
offset with in the custom header that holds the size of the
custom header and mask for the size with in the size offset.

ci: skip_roc_check skip_checkformat

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Change-Id: I1f114570c6ba451a8d57c27715cb4c5b65d5b2cb
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/64820
Tested-by: sa_ip-toolkits-Jenkins <sa_ip-toolkits-jenkins@marvell.com>
Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/67029
---
 doc/guides/nics/cnxk.rst               | 25 +++++++++++++++-
 drivers/common/cnxk/hw/npc.h           | 11 ++++---
 drivers/common/cnxk/roc_mbox.h         |  1 +
 drivers/common/cnxk/roc_nix.h          |  5 +++-
 drivers/common/cnxk/roc_nix_ops.c      | 12 +++++++-
 drivers/common/cnxk/roc_npc.h          |  8 +++++
 drivers/net/cnxk/cnxk_ethdev.c         |  7 +++--
 drivers/net/cnxk/cnxk_ethdev_devargs.c | 41 ++++++++++++++++++++++++++
 8 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index 2927c6cb7e..7c82cb55e1 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -167,7 +167,30 @@ Runtime Config Options
 
    With the above configuration, higig2 will be enabled on that port and the
    traffic on this port should be higig2 traffic only. Supported switch header
-   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2" and "vlan_exdsa".
+   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and "pre_l2".
+
+- ``Flow pre l2 info`` (default ``0x0/0x0/0x0``)
+
+   In case of custom pre l2 headers, an offset, mask with in the offset and shift direction
+   has to be provided within the custom header that holds the size of the custom header.
+   This is valid only with switch header pre l2. Maximum supported offset range is 0 to 255
+   and mask range is 1 to 255 and shift direction, 0: left shift, 1: right shift.
+   Info format will be "offset/mask/shift direction". All parameters has to be in hexadecimal
+   format and mask should be contiguous. Info can be configured using
+   ``flow_pre_l2_info`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,switch_header="pre_l2",flow_pre_l2_info=0x2/0x7e/0x1
+
+   With the above configuration, custom pre l2 header will be enabled on that port and size
+   of the header is placed at byte offset 0x2 in the packet with mask 0x7e and right shift will
+   be used to get the size. i.e size will be (pkt[0x2] & 0x7e) >> shift count.
+   Shift count will be calculated based on mask and shift direction. For example if mask is 0x7c
+   and shift direction is 1, i.e right shift, then the shift count will be 2 i.e absolute
+   position of the right most set bit. If the mask is 0x7c and shift direction is 0, i.e left
+   shift, then the shift count will be 1, i.e 8-n, where n is the absolute position of
+   left most set bit.
 
 - ``RSS tag as XOR`` (default ``0``)
 
diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
index 68c5037e1c..6f896de9f0 100644
--- a/drivers/common/cnxk/hw/npc.h
+++ b/drivers/common/cnxk/hw/npc.h
@@ -169,13 +169,12 @@ enum npc_kpu_la_ltype {
 	NPC_LT_LA_8023 = 1,
 	NPC_LT_LA_ETHER,
 	NPC_LT_LA_IH_NIX_ETHER,
-	NPC_LT_LA_IH_8_ETHER,
-	NPC_LT_LA_IH_4_ETHER,
-	NPC_LT_LA_IH_2_ETHER,
-	NPC_LT_LA_HIGIG2_ETHER,
+	NPC_LT_LA_HIGIG2_ETHER = 7,
 	NPC_LT_LA_IH_NIX_HIGIG2_ETHER,
-	NPC_LT_LA_CH_LEN_90B_ETHER,
+	NPC_LT_LA_CUSTOM_L2_90B_ETHER,
 	NPC_LT_LA_CPT_HDR,
+	NPC_LT_LA_CUSTOM_L2_24B_ETHER,
+	NPC_LT_LA_CUSTOM_PRE_L2_ETHER,
 	NPC_LT_LA_CUSTOM0 = 0xE,
 	NPC_LT_LA_CUSTOM1 = 0xF,
 };
@@ -185,7 +184,7 @@ enum npc_kpu_lb_ltype {
 	NPC_LT_LB_CTAG,
 	NPC_LT_LB_STAG_QINQ,
 	NPC_LT_LB_BTAG,
-	NPC_LT_LB_ITAG,
+	NPC_LT_LB_PPPOE,
 	NPC_LT_LB_DSA,
 	NPC_LT_LB_DSA_VLAN,
 	NPC_LT_LB_EDSA,
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index b63fe108c9..4cffe9b182 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -313,6 +313,7 @@ struct npc_set_pkind {
 #define ROC_PRIV_FLAGS_LEN_90B	  BIT_ULL(3)
 #define ROC_PRIV_FLAGS_EXDSA	  BIT_ULL(4)
 #define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
+#define ROC_PRIV_FLAGS_PRE_L2	  BIT_ULL(6)
 #define ROC_PRIV_FLAGS_CUSTOM	  BIT_ULL(63)
 	uint64_t __io mode;
 #define PKIND_TX BIT_ULL(0)
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 69a5e8e7b4..3f195f191a 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -714,7 +714,10 @@ void __roc_api roc_nix_mac_link_info_get_cb_unregister(struct roc_nix *roc_nix);
 
 /* Ops */
 int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix,
-				     uint64_t switch_header_type);
+				     uint64_t switch_header_type,
+				     uint8_t pre_l2_size_offset,
+				     uint8_t pre_l2_size_offset_mask,
+				     uint8_t pre_l2_size_shift_dir);
 int __roc_api roc_nix_lso_fmt_setup(struct roc_nix *roc_nix);
 int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 				  uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
index 04a78cf4ca..8d3cddf2a6 100644
--- a/drivers/common/cnxk/roc_nix_ops.c
+++ b/drivers/common/cnxk/roc_nix_ops.c
@@ -364,7 +364,10 @@ roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 }
 
 int
-roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
+roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
+		       uint8_t pre_l2_size_offset,
+		       uint8_t pre_l2_size_offset_mask,
+		       uint8_t pre_l2_size_shift_dir)
 {
 	struct mbox *mbox = get_mbox(roc_nix);
 	struct npc_set_pkind *req;
@@ -380,6 +383,7 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 	    switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
 	    switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
 	    switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
+	    switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
 	    switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
 		plt_err("switch header type is not supported");
 		return NIX_ERR_PARAM;
@@ -411,6 +415,12 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 	} else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
 		req->mode = ROC_PRIV_FLAGS_CUSTOM;
 		req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
+	} else if (switch_header_type == ROC_PRIV_FLAGS_PRE_L2) {
+		req->mode = ROC_PRIV_FLAGS_CUSTOM;
+		req->pkind = NPC_RX_CUSTOM_PRE_L2_PKIND;
+		req->var_len_off = pre_l2_size_offset;
+		req->var_len_off_mask = pre_l2_size_offset_mask;
+		req->shift_dir = pre_l2_size_shift_dir;
 	}
 
 	req->dir = PKIND_RX;
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 8c24126ae8..8b57678863 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -187,6 +187,14 @@ enum flow_vtag_cfg_dir { VTAG_TX, VTAG_RX };
 struct roc_npc {
 	struct roc_nix *roc_nix;
 	uint8_t switch_header_type;
+	uint8_t pre_l2_size_offset;	 /**< Offset with in header that holds
+					   * size of custom header
+					   */
+	uint8_t pre_l2_size_offset_mask; /**< Offset mask with in header
+					   * that holds size of custom header
+					   */
+	uint8_t pre_l2_size_shift_dir;	 /**< Shift direction to calculate size
+					   */
 	uint16_t flow_prealloc_size;
 	uint16_t flow_max_priority;
 	uint16_t channel;
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 74f625553d..cacc117e50 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1164,7 +1164,10 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
 		goto free_nix_lf;
 	}
 
-	rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type);
+	rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
+				    dev->npc.pre_l2_size_offset,
+				    dev->npc.pre_l2_size_offset_mask,
+				    dev->npc.pre_l2_size_shift_dir);
 	if (rc) {
 		plt_err("Failed to enable switch type nix_lf rc=%d", rc);
 		goto free_nix_lf;
@@ -1405,7 +1408,7 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev)
 	void *rxq;
 
 	/* Disable switch hdr pkind */
-	roc_nix_switch_hdr_set(&dev->nix, 0);
+	roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
 
 	/* Stop link change events */
 	if (!roc_nix_is_vf_or_sdp(&dev->nix))
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index ad7babdf52..157b27d9cb 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -13,6 +13,12 @@ struct sdp_channel {
 	uint16_t mask;
 };
 
+struct flow_pre_l2_size_info {
+	uint8_t pre_l2_size_off;
+	uint8_t pre_l2_size_off_mask;
+	uint8_t pre_l2_size_shift_dir;
+};
+
 static int
 parse_outb_nb_desc(const char *key, const char *value, void *extra_args)
 {
@@ -124,6 +130,29 @@ parse_reta_size(const char *key, const char *value, void *extra_args)
 	return 0;
 }
 
+static int
+parse_pre_l2_hdr_info(const char *key, const char *value, void *extra_args)
+{
+	struct flow_pre_l2_size_info *info =
+		(struct flow_pre_l2_size_info *)extra_args;
+	char *tok1 = NULL, *tok2 = NULL;
+	uint16_t off, off_mask, dir;
+
+	RTE_SET_USED(key);
+	off = strtol(value, &tok1, 16);
+	tok1++;
+	off_mask = strtol(tok1, &tok2, 16);
+	tok2++;
+	dir = strtol(tok2, 0, 16);
+	if (off >= 256 || off_mask < 1 || off_mask >= 256 || dir > 1)
+		return -EINVAL;
+	info->pre_l2_size_off = off;
+	info->pre_l2_size_off_mask = off_mask;
+	info->pre_l2_size_shift_dir = dir;
+
+	return 0;
+}
+
 static int
 parse_flag(const char *key, const char *value, void *extra_args)
 {
@@ -167,6 +196,9 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
 	if (strcmp(value, "vlan_exdsa") == 0)
 		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_VLAN_EXDSA;
 
+	if (strcmp(value, "pre_l2") == 0)
+		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2;
+
 	return 0;
 }
 
@@ -205,12 +237,14 @@ parse_sdp_channel_mask(const char *key, const char *value, void *extra_args)
 #define CNXK_FORCE_INB_INL_DEV	"force_inb_inl_dev"
 #define CNXK_OUTB_NB_CRYPTO_QS	"outb_nb_crypto_qs"
 #define CNXK_SDP_CHANNEL_MASK	"sdp_channel_mask"
+#define CNXK_FLOW_PRE_L2_INFO	"flow_pre_l2_info"
 
 int
 cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 {
 	uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64;
 	uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB;
+	struct flow_pre_l2_size_info pre_l2_info;
 	uint16_t ipsec_in_max_spi = BIT(8) - 1;
 	uint16_t ipsec_out_max_sa = BIT(12);
 	uint16_t flow_prealloc_size = 1;
@@ -226,6 +260,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	struct rte_kvargs *kvlist;
 
 	memset(&sdp_chan, 0, sizeof(sdp_chan));
+	memset(&pre_l2_info, 0, sizeof(struct flow_pre_l2_size_info));
 
 	if (devargs == NULL)
 		goto null_devargs;
@@ -261,6 +296,8 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 			   &force_inb_inl_dev);
 	rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK,
 			   &parse_sdp_channel_mask, &sdp_chan);
+	rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO,
+			   &parse_pre_l2_hdr_info, &pre_l2_info);
 	rte_kvargs_free(kvlist);
 
 null_devargs:
@@ -282,6 +319,9 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	dev->npc.sdp_channel = sdp_chan.channel;
 	dev->npc.sdp_channel_mask = sdp_chan.mask;
 	dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set;
+	dev->npc.pre_l2_size_offset = pre_l2_info.pre_l2_size_off;
+	dev->npc.pre_l2_size_offset_mask = pre_l2_info.pre_l2_size_off_mask;
+	dev->npc.pre_l2_size_shift_dir = pre_l2_info.pre_l2_size_shift_dir;
 	return 0;
 exit:
 	return -EINVAL;
@@ -297,6 +337,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
 			      CNXK_RSS_TAG_AS_XOR "=1"
 			      CNXK_IPSEC_IN_MAX_SPI "=<1-65535>"
 			      CNXK_OUTB_NB_DESC "=<1-65535>"
+			      CNXK_FLOW_PRE_L2_INFO "=<0-255>/<1-255>/<0-1>"
 			      CNXK_OUTB_NB_CRYPTO_QS "=<1-64>"
 			      CNXK_FORCE_INB_INL_DEV "=1"
 			      CNXK_SDP_CHANNEL_MASK "=<1-4095>/<1-4095>");
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 2/4] common/cnxk: support custom pre L2 header parsing as raw
  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 ` psatheesh
  2022-01-03  5:57 ` [dpdk-dev] [PATCH 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  5:57 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, sa_ip-toolkits-Jenkins, Satheesh Paul, Jerin Jacob Kollanukkaran

From: Kiran Kumar K <kirankumark@marvell.com>

Add roc API for parsing custom pre L2 headers as raw data.
Only relative offset is supported and search and limit is
not supported with this raw item type.

ci: skip_klocwork

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Change-Id: I2840244715e2c849e8b96145dc1b642dd8e3583b
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/65070
Tested-by: sa_ip-toolkits-Jenkins <sa_ip-toolkits-jenkins@marvell.com>
Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/67030
Tested-by: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
---
 drivers/common/cnxk/roc_npc.c           |   8 +-
 drivers/common/cnxk/roc_npc_mcam_dump.c |   2 +
 drivers/common/cnxk/roc_npc_parse.c     | 103 +++++++++++++++++-------
 drivers/common/cnxk/roc_npc_priv.h      |   1 +
 4 files changed, 81 insertions(+), 33 deletions(-)

diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index d18dfd4259..e3961bfbc6 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -566,10 +566,10 @@ npc_parse_pattern(struct npc *npc, const struct roc_npc_item_info pattern[],
 		  struct roc_npc_flow *flow, struct npc_parse_state *pst)
 {
 	npc_parse_stage_func_t parse_stage_funcs[] = {
-		npc_parse_meta_items, npc_parse_cpt_hdr, npc_parse_higig2_hdr,
-		npc_parse_la,	      npc_parse_lb,	 npc_parse_lc,
-		npc_parse_ld,	      npc_parse_le,	 npc_parse_lf,
-		npc_parse_lg,	      npc_parse_lh,
+		npc_parse_meta_items, npc_parse_pre_l2, npc_parse_cpt_hdr,
+		npc_parse_higig2_hdr, npc_parse_la,	npc_parse_lb,
+		npc_parse_lc,	      npc_parse_ld,	npc_parse_le,
+		npc_parse_lf,	      npc_parse_lg,	npc_parse_lh,
 	};
 	uint8_t layer = 0;
 	int key_offset;
diff --git a/drivers/common/cnxk/roc_npc_mcam_dump.c b/drivers/common/cnxk/roc_npc_mcam_dump.c
index 278056591e..679e3d7657 100644
--- a/drivers/common/cnxk/roc_npc_mcam_dump.c
+++ b/drivers/common/cnxk/roc_npc_mcam_dump.c
@@ -69,6 +69,8 @@ static const char *const ltype_str[NPC_MAX_LID][NPC_MAX_LT] = {
 	[NPC_LID_LA][NPC_LT_LA_IH_NIX_ETHER] = "LA_IH_NIX_ETHER",
 	[NPC_LID_LA][NPC_LT_LA_HIGIG2_ETHER] = "LA_HIGIG2_ETHER",
 	[NPC_LID_LA][NPC_LT_LA_IH_NIX_HIGIG2_ETHER] = "LA_IH_NIX_HIGIG2_ETHER",
+	[NPC_LID_LA][NPC_LT_LA_CUSTOM_PRE_L2_ETHER] =
+		"NPC_LT_LA_CUSTOM_PRE_L2_ETHER",
 	[NPC_LID_LB][0] = "NONE",
 	[NPC_LID_LB][NPC_LT_LB_CTAG] = "LB_CTAG",
 	[NPC_LID_LB][NPC_LT_LB_STAG_QINQ] = "LB_STAG_QINQ",
diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c
index 8125035dd8..c9ab9aef28 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -21,6 +21,80 @@ npc_parse_meta_items(struct npc_parse_state *pst)
 	return 0;
 }
 
+static int
+npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
+			  const struct roc_npc_flow_item_raw *raw_mask,
+			  struct npc_parse_item_info *info, uint8_t *spec_buf,
+			  uint8_t *mask_buf)
+{
+
+	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+	memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+
+	memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
+	       raw_spec->length);
+
+	if (raw_mask && raw_mask->pattern) {
+		memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
+		       raw_spec->length);
+	} else {
+		memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
+	}
+
+	info->len = NPC_MAX_RAW_ITEM_LEN;
+	info->spec = spec_buf;
+	info->mask = mask_buf;
+	return 0;
+}
+
+int
+npc_parse_pre_l2(struct npc_parse_state *pst)
+{
+	uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
+	uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN] = {0};
+	const struct roc_npc_flow_item_raw *raw_spec;
+	struct npc_parse_item_info info;
+	int lid, lt, len;
+	int rc;
+
+	if (pst->npc->switch_header_type != ROC_PRIV_FLAGS_PRE_L2)
+		return 0;
+
+	/* Identify the pattern type into lid, lt */
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_RAW)
+		return 0;
+
+	lid = NPC_LID_LA;
+	lt = NPC_LT_LA_CUSTOM_PRE_L2_ETHER;
+	info.hw_hdr_len = 0;
+
+	raw_spec = pst->pattern->spec;
+	len = raw_spec->length + raw_spec->offset;
+	if (len > NPC_MAX_RAW_ITEM_LEN)
+		return -EINVAL;
+
+	if (raw_spec->relative == 0 || raw_spec->search || raw_spec->limit ||
+	    raw_spec->offset < 0)
+		return -EINVAL;
+
+	npc_flow_raw_item_prepare(
+		(const struct roc_npc_flow_item_raw *)pst->pattern->spec,
+		(const struct roc_npc_flow_item_raw *)pst->pattern->mask, &info,
+		raw_spec_buf, raw_mask_buf);
+
+	info.hw_mask = &hw_mask;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+
+	/* Basic validation of item parameters */
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc)
+		return rc;
+
+	/* Update pst if not validate only? clash check? */
+	return npc_update_parse_state(pst, &info, lid, lt, 0);
+}
+
 int
 npc_parse_cpt_hdr(struct npc_parse_state *pst)
 {
@@ -136,35 +210,6 @@ npc_parse_la(struct npc_parse_state *pst)
 	return npc_update_parse_state(pst, &info, lid, lt, 0);
 }
 
-static int
-npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
-			  const struct roc_npc_flow_item_raw *raw_mask,
-			  struct npc_parse_item_info *info, uint8_t *spec_buf,
-			  uint8_t *mask_buf)
-{
-	uint32_t custom_hdr_size = 0;
-
-	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
-	memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
-	custom_hdr_size = raw_spec->offset + raw_spec->length;
-
-	memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
-	       raw_spec->length);
-
-	if (raw_mask->pattern) {
-		memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
-		       raw_spec->length);
-	} else {
-		memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
-	}
-
-	info->len = custom_hdr_size;
-	info->spec = spec_buf;
-	info->mask = mask_buf;
-
-	return 0;
-}
-
 int
 npc_parse_lb(struct npc_parse_state *pst)
 {
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index 86c10ea082..1a40192599 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -408,6 +408,7 @@ void npc_get_hw_supp_mask(struct npc_parse_state *pst,
 int npc_parse_item_basic(const struct roc_npc_item_info *item,
 			 struct npc_parse_item_info *info);
 int npc_parse_meta_items(struct npc_parse_state *pst);
+int npc_parse_pre_l2(struct npc_parse_state *pst);
 int npc_parse_higig2_hdr(struct npc_parse_state *pst);
 int npc_parse_cpt_hdr(struct npc_parse_state *pst);
 int npc_parse_la(struct npc_parse_state *pst);
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 3/4] common/cnxk: support matching VLAN existence in RTE Flow
  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 ` psatheesh
  2022-01-03  5:57 ` [dpdk-dev] [PATCH 4/4] common/cnxk: support extensions attributes in IPv6 item psatheesh
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  5:57 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul, sa_ip-toolkits-Jenkins

From: Satheesh Paul <psatheesh@marvell.com>

Support matching existence of VLAN after
RTE_FLOW_ITEM_TYPE_ETH and RTE_FLOW_ITEM_TYPE_VLAN items.

ci: skip_checkformat

Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Change-Id: Ieebeaee5f13e58e7db20a171ea878bb33ddd57bb
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/67088
Tested-by: sa_ip-toolkits-Jenkins <sa_ip-toolkits-jenkins@marvell.com>
Reviewed-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
---
 drivers/common/cnxk/roc_npc.h       | 58 ++++++++++++++++++++++++++++-
 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, 151 insertions(+), 13 deletions(-)

diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 8b57678863..634c67e6f6 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. */
 };
@@ -167,7 +221,7 @@ enum roc_npc_rss_hash_function {
 struct roc_npc_action_rss {
 	enum roc_npc_rss_hash_function func;
 	uint32_t level;
-	uint64_t types;	       /**< Specific RSS hash types (see RTE_ETH_RSS_*). */
+	uint64_t types;	       /**< Specific RSS hash types (see ETH_RSS_*). */
 	uint32_t key_len;      /**< Hash key length in bytes. */
 	uint32_t queue_num;    /**< Number of entries in @p queue. */
 	const uint8_t *key;    /**< Hash key. */
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..7eecb365bf 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)			\
 	({					\
@@ -62,6 +65,7 @@
 		(__x + __y - 1) / __y;		\
 	})
 
+#define __plt_aligned	    __rte_aligned
 #define __plt_cache_aligned __rte_cache_aligned
 #define __plt_always_inline __rte_always_inline
 #define __plt_packed	    __rte_packed
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 4/4] common/cnxk: support extensions attributes in IPv6 item
  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 ` psatheesh
  2022-01-03  6:19 ` [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2 psatheesh
  2022-01-21  6:26 ` [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2 psatheesh
  4 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  5:57 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul, sa_ip-toolkits-Jenkins

From: Satheesh Paul <psatheesh@marvell.com>

Support matching existence of specific extension headers
after RTE_FLOW_ITEM_TYPE_IPV6 item.

Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Change-Id: I8c7d58af242d6d991b718787a6c9b8e79c6ff409
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/66900
Tested-by: sa_ip-toolkits-Jenkins <sa_ip-toolkits-jenkins@marvell.com>
Reviewed-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpdk/+/67409
---
 drivers/common/cnxk/hw/npc.h        | 17 ++++++++
 drivers/common/cnxk/roc_npc.h       | 33 +++++++++++++++
 drivers/common/cnxk/roc_npc_mcam.c  | 47 ++++++++++++++++++++-
 drivers/common/cnxk/roc_npc_parse.c | 65 +++++++++++++++++++++++++++--
 drivers/common/cnxk/roc_npc_priv.h  |  6 +++
 5 files changed, 162 insertions(+), 6 deletions(-)

diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
index 6f896de9f0..b8218e25af 100644
--- a/drivers/common/cnxk/hw/npc.h
+++ b/drivers/common/cnxk/hw/npc.h
@@ -320,6 +320,23 @@ enum npc_kpu_lc_uflag {
 	NPC_F_LC_U_IP6_FRAG = 0x40,
 };
 
+enum npc_kpu_lc_lflag {
+	NPC_F_LC_L_IP_IN_IP = 1,
+	NPC_F_LC_L_6TO4,
+	NPC_F_LC_L_MPLS_IN_IP,
+	NPC_F_LC_L_IP6_TUN_IP6,
+	NPC_F_LC_L_IP6_MPLS_IN_IP,
+	NPC_F_LC_L_MPLS_4_LABELS,
+	NPC_F_LC_L_MPLS_3_LABELS,
+	NPC_F_LC_L_MPLS_2_LABELS,
+	NPC_F_LC_L_EXT_HOP,
+	NPC_F_LC_L_EXT_DEST,
+	NPC_F_LC_L_EXT_ROUT,
+	NPC_F_LC_L_EXT_MOBILITY,
+	NPC_F_LC_L_EXT_HOSTID,
+	NPC_F_LC_L_EXT_SHIM6,
+};
+
 /* Structures definitions */
 struct npc_kpu_profile_cam {
 	uint8_t state;
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 634c67e6f6..2098810ee3 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -112,6 +112,39 @@ struct roc_npc_flow_item_vlan {
 	uint32_t reserved : 31; /**< Reserved, must be zero. */
 };
 
+struct roc_ipv6_hdr {
+	uint32_t vtc_flow;    /**< IP version, traffic class & flow label. */
+	uint16_t payload_len; /**< IP payload size, including ext. headers */
+	uint8_t proto;	      /**< Protocol, next header. */
+	uint8_t hop_limits;   /**< Hop limits. */
+	uint8_t src_addr[16]; /**< IP address of source host. */
+	uint8_t dst_addr[16]; /**< IP address of destination host(s). */
+} __plt_packed;
+
+struct roc_npc_flow_item_ipv6 {
+	struct roc_ipv6_hdr hdr; /**< IPv6 header definition. */
+	uint32_t has_hop_ext : 1;
+	/**< Header contains Hop-by-Hop Options extension header. */
+	uint32_t has_route_ext : 1;
+	/**< Header contains Routing extension header. */
+	uint32_t has_frag_ext : 1;
+	/**< Header contains Fragment extension header. */
+	uint32_t has_auth_ext : 1;
+	/**< Header contains Authentication extension header. */
+	uint32_t has_esp_ext : 1;
+	/**< Header contains Encapsulation Security Payload extension header. */
+	uint32_t has_dest_ext : 1;
+	/**< Header contains Destination Options extension header. */
+	uint32_t has_mobil_ext : 1;
+	/**< Header contains Mobility extension header. */
+	uint32_t has_hip_ext : 1;
+	/**< Header contains Host Identity Protocol extension header. */
+	uint32_t has_shim6_ext : 1;
+	/**< Header contains Shim6 Protocol extension header. */
+	uint32_t reserved : 23;
+	/**< Reserved for future extension headers, must be zero. */
+};
+
 #define ROC_NPC_MAX_ACTION_COUNT 19
 
 enum roc_npc_action_type {
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index 2349317c5c..da5815ada0 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -283,8 +283,8 @@ npc_get_kex_capability(struct npc *npc)
 	/* Custom L3 frame: varied offset and lengths */
 	kex_cap.bit.custom_l3 =
 		npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_CUSTOM0, 0, 0);
-	kex_cap.bit.custom_l3 |=
-		npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_CUSTOM1, 0, 0);
+	kex_cap.bit.custom_l3 |= (uint64_t)npc_is_kex_enabled(
+		npc, NPC_LID_LC, NPC_LT_LC_CUSTOM1, 0, 0);
 	/* SCTP sport : offset 0B, len 2B */
 	kex_cap.bit.sctp_sport = npc_is_kex_enabled(
 		npc, NPC_LID_LD, NPC_LT_LD_SCTP, 0 * 8, 2 * 8);
@@ -635,6 +635,46 @@ npc_set_vlan_ltype(struct npc_parse_state *pst)
 	pst->flow->mcam_mask[0] |= (0xeULL << lb_offset);
 }
 
+static void
+npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
+{
+	uint8_t lc_offset, lcflag_offset;
+	uint64_t val, mask;
+
+	lc_offset =
+		__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+				   ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+	lc_offset *= 4;
+
+	mask = ~((0xfULL << lc_offset));
+	pst->flow->mcam_data[0] &= mask;
+	pst->flow->mcam_mask[0] &= mask;
+	/* NPC_LT_LC_IP6: 0b0100, NPC_LT_LC_IP6_EXT: 0b0101
+	 * Set LC layertype/mask as 0b0100/0b1110 to match both.
+	 */
+	val = ((uint64_t)(NPC_LT_LC_IP6 & NPC_LT_LC_IP6_EXT)) << lc_offset;
+	pst->flow->mcam_data[0] |= val;
+	pst->flow->mcam_mask[0] |= (0xeULL << lc_offset);
+
+	/* If LC LFLAG is non-zero, set the LC LFLAG mask to 0xF. In general
+	 * case flag mask is set same as the value in data. For example, to
+	 * match 3 VLANs, flags have to match a range of values. But, for IPv6
+	 * extended attributes matching, we need an exact match. Hence, set the
+	 * mask as 0xF. This is done only if LC LFLAG value is non-zero,
+	 * because for AH and ESP, LC LFLAG is zero and we don't want to match
+	 * zero in LFLAG.
+	 */
+	lcflag_offset =
+		__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+				   ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+	lcflag_offset *= 4;
+
+	mask = (0xfULL << lcflag_offset);
+	val = pst->flow->mcam_data[0] & mask;
+	if (val)
+		pst->flow->mcam_mask[0] |= mask;
+}
+
 int
 npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 {
@@ -709,6 +749,9 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 	if (pst->set_vlan_ltype_mask)
 		npc_set_vlan_ltype(pst);
 
+	if (pst->set_ipv6ext_ltype_mask)
+		npc_set_ipv6ext_ltype_mask(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 75724661da..1f21693369 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -480,16 +480,69 @@ npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
 		pst->tunnel = 1;
 }
 
+static int
+npc_handle_ipv6ext_attr(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+			struct npc_parse_state *pst, uint8_t *flags)
+{
+	int flags_count = 0;
+
+	if (ipv6_spec->has_hop_ext) {
+		*flags = NPC_F_LC_L_EXT_HOP;
+		flags_count++;
+	}
+	if (ipv6_spec->has_route_ext) {
+		*flags = NPC_F_LC_L_EXT_ROUT;
+		flags_count++;
+	}
+	if (ipv6_spec->has_frag_ext) {
+		*flags = NPC_F_LC_U_IP6_FRAG;
+		flags_count++;
+	}
+	if (ipv6_spec->has_dest_ext) {
+		*flags = NPC_F_LC_L_EXT_DEST;
+		flags_count++;
+	}
+	if (ipv6_spec->has_mobil_ext) {
+		*flags = NPC_F_LC_L_EXT_MOBILITY;
+		flags_count++;
+	}
+	if (ipv6_spec->has_hip_ext) {
+		*flags = NPC_F_LC_L_EXT_HOSTID;
+		flags_count++;
+	}
+	if (ipv6_spec->has_shim6_ext) {
+		*flags = NPC_F_LC_L_EXT_SHIM6;
+		flags_count++;
+	}
+	if (ipv6_spec->has_auth_ext) {
+		pst->lt[NPC_LID_LD] = NPC_LT_LD_AH;
+		flags_count++;
+	}
+	if (ipv6_spec->has_esp_ext) {
+		pst->lt[NPC_LID_LE] = NPC_LT_LE_ESP;
+		flags_count++;
+	}
+
+	if (flags_count > 1)
+		return -EINVAL;
+
+	if (flags_count)
+		pst->set_ipv6ext_ltype_mask = true;
+
+	return 0;
+}
+
 int
 npc_parse_lc(struct npc_parse_state *pst)
 {
+	const struct roc_npc_flow_item_ipv6 *ipv6_spec;
 	const struct roc_npc_flow_item_raw *raw_spec;
 	uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
 	uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
 	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
 	struct npc_parse_item_info info;
-	int lid, lt, len = 0;
-	int rc;
+	int rc, lid, lt, len = 0;
+	uint8_t flags = 0;
 
 	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
 		return npc_parse_mpls(pst, NPC_LID_LC);
@@ -506,9 +559,13 @@ npc_parse_lc(struct npc_parse_state *pst)
 		info.len = pst->pattern->size;
 		break;
 	case ROC_NPC_ITEM_TYPE_IPV6:
+		ipv6_spec = pst->pattern->spec;
 		lid = NPC_LID_LC;
 		lt = NPC_LT_LC_IP6;
-		info.len = pst->pattern->size;
+		rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags);
+		if (rc)
+			return rc;
+		info.len = sizeof(ipv6_spec->hdr);
 		break;
 	case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
 		lt = NPC_LT_LC_ARP;
@@ -558,7 +615,7 @@ npc_parse_lc(struct npc_parse_state *pst)
 	if (rc != 0)
 		return rc;
 
-	return npc_update_parse_state(pst, &info, lid, lt, 0);
+	return npc_update_parse_state(pst, &info, lid, lt, flags);
 }
 
 int
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index ef7985f4cf..44d61ba641 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -71,6 +71,11 @@
 /* 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)
+/* LC OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags + 1b ltype) + LC
+ * (2b flags)
+ */
+#define NPC_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 6)
+#define NPC_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 8)
 
 struct npc_action_vtag_info {
 	uint16_t vlan_id;
@@ -183,6 +188,7 @@ struct npc_parse_state {
 	bool is_vf;
 	/* adjust ltype in MCAM to match at least one vlan */
 	bool set_vlan_ltype_mask;
+	bool set_ipv6ext_ltype_mask;
 };
 
 enum npc_kpu_parser_flag {
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2
  2022-01-03  5:57 [dpdk-dev] [PATCH 1/4] drivers: add support for switch header type pre L2 psatheesh
                   ` (2 preceding siblings ...)
  2022-01-03  5:57 ` [dpdk-dev] [PATCH 4/4] common/cnxk: support extensions attributes in IPv6 item psatheesh
@ 2022-01-03  6:19 ` psatheesh
  2022-01-03  6:19   ` [dpdk-dev] [PATCH v2 2/4] common/cnxk: support custom pre L2 header parsing as raw psatheesh
                     ` (3 more replies)
  2022-01-21  6:26 ` [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2 psatheesh
  4 siblings, 4 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  6:19 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

From: Kiran Kumar K <kirankumark@marvell.com>

Adding changes to configure switch header type pre L2 for cnxk.
Along with switch header type user needs to provide the
offset with in the custom header that holds the size of the
custom header and mask for the size with in the size offset.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
---
v2:
* Fixed checkpatch errors in commit messages

 doc/guides/nics/cnxk.rst               | 25 +++++++++++++++-
 drivers/common/cnxk/hw/npc.h           | 11 ++++---
 drivers/common/cnxk/roc_mbox.h         |  1 +
 drivers/common/cnxk/roc_nix.h          |  5 +++-
 drivers/common/cnxk/roc_nix_ops.c      | 12 +++++++-
 drivers/common/cnxk/roc_npc.h          |  8 +++++
 drivers/net/cnxk/cnxk_ethdev.c         |  7 +++--
 drivers/net/cnxk/cnxk_ethdev_devargs.c | 41 ++++++++++++++++++++++++++
 8 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index 2927c6cb7e..7c82cb55e1 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -167,7 +167,30 @@ Runtime Config Options
 
    With the above configuration, higig2 will be enabled on that port and the
    traffic on this port should be higig2 traffic only. Supported switch header
-   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2" and "vlan_exdsa".
+   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and "pre_l2".
+
+- ``Flow pre l2 info`` (default ``0x0/0x0/0x0``)
+
+   In case of custom pre l2 headers, an offset, mask with in the offset and shift direction
+   has to be provided within the custom header that holds the size of the custom header.
+   This is valid only with switch header pre l2. Maximum supported offset range is 0 to 255
+   and mask range is 1 to 255 and shift direction, 0: left shift, 1: right shift.
+   Info format will be "offset/mask/shift direction". All parameters has to be in hexadecimal
+   format and mask should be contiguous. Info can be configured using
+   ``flow_pre_l2_info`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,switch_header="pre_l2",flow_pre_l2_info=0x2/0x7e/0x1
+
+   With the above configuration, custom pre l2 header will be enabled on that port and size
+   of the header is placed at byte offset 0x2 in the packet with mask 0x7e and right shift will
+   be used to get the size. i.e size will be (pkt[0x2] & 0x7e) >> shift count.
+   Shift count will be calculated based on mask and shift direction. For example if mask is 0x7c
+   and shift direction is 1, i.e right shift, then the shift count will be 2 i.e absolute
+   position of the right most set bit. If the mask is 0x7c and shift direction is 0, i.e left
+   shift, then the shift count will be 1, i.e 8-n, where n is the absolute position of
+   left most set bit.
 
 - ``RSS tag as XOR`` (default ``0``)
 
diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
index 68c5037e1c..6f896de9f0 100644
--- a/drivers/common/cnxk/hw/npc.h
+++ b/drivers/common/cnxk/hw/npc.h
@@ -169,13 +169,12 @@ enum npc_kpu_la_ltype {
 	NPC_LT_LA_8023 = 1,
 	NPC_LT_LA_ETHER,
 	NPC_LT_LA_IH_NIX_ETHER,
-	NPC_LT_LA_IH_8_ETHER,
-	NPC_LT_LA_IH_4_ETHER,
-	NPC_LT_LA_IH_2_ETHER,
-	NPC_LT_LA_HIGIG2_ETHER,
+	NPC_LT_LA_HIGIG2_ETHER = 7,
 	NPC_LT_LA_IH_NIX_HIGIG2_ETHER,
-	NPC_LT_LA_CH_LEN_90B_ETHER,
+	NPC_LT_LA_CUSTOM_L2_90B_ETHER,
 	NPC_LT_LA_CPT_HDR,
+	NPC_LT_LA_CUSTOM_L2_24B_ETHER,
+	NPC_LT_LA_CUSTOM_PRE_L2_ETHER,
 	NPC_LT_LA_CUSTOM0 = 0xE,
 	NPC_LT_LA_CUSTOM1 = 0xF,
 };
@@ -185,7 +184,7 @@ enum npc_kpu_lb_ltype {
 	NPC_LT_LB_CTAG,
 	NPC_LT_LB_STAG_QINQ,
 	NPC_LT_LB_BTAG,
-	NPC_LT_LB_ITAG,
+	NPC_LT_LB_PPPOE,
 	NPC_LT_LB_DSA,
 	NPC_LT_LB_DSA_VLAN,
 	NPC_LT_LB_EDSA,
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index b63fe108c9..4cffe9b182 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -313,6 +313,7 @@ struct npc_set_pkind {
 #define ROC_PRIV_FLAGS_LEN_90B	  BIT_ULL(3)
 #define ROC_PRIV_FLAGS_EXDSA	  BIT_ULL(4)
 #define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
+#define ROC_PRIV_FLAGS_PRE_L2	  BIT_ULL(6)
 #define ROC_PRIV_FLAGS_CUSTOM	  BIT_ULL(63)
 	uint64_t __io mode;
 #define PKIND_TX BIT_ULL(0)
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 69a5e8e7b4..3f195f191a 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -714,7 +714,10 @@ void __roc_api roc_nix_mac_link_info_get_cb_unregister(struct roc_nix *roc_nix);
 
 /* Ops */
 int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix,
-				     uint64_t switch_header_type);
+				     uint64_t switch_header_type,
+				     uint8_t pre_l2_size_offset,
+				     uint8_t pre_l2_size_offset_mask,
+				     uint8_t pre_l2_size_shift_dir);
 int __roc_api roc_nix_lso_fmt_setup(struct roc_nix *roc_nix);
 int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 				  uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
index 04a78cf4ca..8d3cddf2a6 100644
--- a/drivers/common/cnxk/roc_nix_ops.c
+++ b/drivers/common/cnxk/roc_nix_ops.c
@@ -364,7 +364,10 @@ roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 }
 
 int
-roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
+roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
+		       uint8_t pre_l2_size_offset,
+		       uint8_t pre_l2_size_offset_mask,
+		       uint8_t pre_l2_size_shift_dir)
 {
 	struct mbox *mbox = get_mbox(roc_nix);
 	struct npc_set_pkind *req;
@@ -380,6 +383,7 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 	    switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
 	    switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
 	    switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
+	    switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
 	    switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
 		plt_err("switch header type is not supported");
 		return NIX_ERR_PARAM;
@@ -411,6 +415,12 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 	} else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
 		req->mode = ROC_PRIV_FLAGS_CUSTOM;
 		req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
+	} else if (switch_header_type == ROC_PRIV_FLAGS_PRE_L2) {
+		req->mode = ROC_PRIV_FLAGS_CUSTOM;
+		req->pkind = NPC_RX_CUSTOM_PRE_L2_PKIND;
+		req->var_len_off = pre_l2_size_offset;
+		req->var_len_off_mask = pre_l2_size_offset_mask;
+		req->shift_dir = pre_l2_size_shift_dir;
 	}
 
 	req->dir = PKIND_RX;
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 8c24126ae8..8b57678863 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -187,6 +187,14 @@ enum flow_vtag_cfg_dir { VTAG_TX, VTAG_RX };
 struct roc_npc {
 	struct roc_nix *roc_nix;
 	uint8_t switch_header_type;
+	uint8_t pre_l2_size_offset;	 /**< Offset with in header that holds
+					   * size of custom header
+					   */
+	uint8_t pre_l2_size_offset_mask; /**< Offset mask with in header
+					   * that holds size of custom header
+					   */
+	uint8_t pre_l2_size_shift_dir;	 /**< Shift direction to calculate size
+					   */
 	uint16_t flow_prealloc_size;
 	uint16_t flow_max_priority;
 	uint16_t channel;
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 74f625553d..cacc117e50 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1164,7 +1164,10 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
 		goto free_nix_lf;
 	}
 
-	rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type);
+	rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
+				    dev->npc.pre_l2_size_offset,
+				    dev->npc.pre_l2_size_offset_mask,
+				    dev->npc.pre_l2_size_shift_dir);
 	if (rc) {
 		plt_err("Failed to enable switch type nix_lf rc=%d", rc);
 		goto free_nix_lf;
@@ -1405,7 +1408,7 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev)
 	void *rxq;
 
 	/* Disable switch hdr pkind */
-	roc_nix_switch_hdr_set(&dev->nix, 0);
+	roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
 
 	/* Stop link change events */
 	if (!roc_nix_is_vf_or_sdp(&dev->nix))
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index ad7babdf52..157b27d9cb 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -13,6 +13,12 @@ struct sdp_channel {
 	uint16_t mask;
 };
 
+struct flow_pre_l2_size_info {
+	uint8_t pre_l2_size_off;
+	uint8_t pre_l2_size_off_mask;
+	uint8_t pre_l2_size_shift_dir;
+};
+
 static int
 parse_outb_nb_desc(const char *key, const char *value, void *extra_args)
 {
@@ -124,6 +130,29 @@ parse_reta_size(const char *key, const char *value, void *extra_args)
 	return 0;
 }
 
+static int
+parse_pre_l2_hdr_info(const char *key, const char *value, void *extra_args)
+{
+	struct flow_pre_l2_size_info *info =
+		(struct flow_pre_l2_size_info *)extra_args;
+	char *tok1 = NULL, *tok2 = NULL;
+	uint16_t off, off_mask, dir;
+
+	RTE_SET_USED(key);
+	off = strtol(value, &tok1, 16);
+	tok1++;
+	off_mask = strtol(tok1, &tok2, 16);
+	tok2++;
+	dir = strtol(tok2, 0, 16);
+	if (off >= 256 || off_mask < 1 || off_mask >= 256 || dir > 1)
+		return -EINVAL;
+	info->pre_l2_size_off = off;
+	info->pre_l2_size_off_mask = off_mask;
+	info->pre_l2_size_shift_dir = dir;
+
+	return 0;
+}
+
 static int
 parse_flag(const char *key, const char *value, void *extra_args)
 {
@@ -167,6 +196,9 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
 	if (strcmp(value, "vlan_exdsa") == 0)
 		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_VLAN_EXDSA;
 
+	if (strcmp(value, "pre_l2") == 0)
+		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2;
+
 	return 0;
 }
 
@@ -205,12 +237,14 @@ parse_sdp_channel_mask(const char *key, const char *value, void *extra_args)
 #define CNXK_FORCE_INB_INL_DEV	"force_inb_inl_dev"
 #define CNXK_OUTB_NB_CRYPTO_QS	"outb_nb_crypto_qs"
 #define CNXK_SDP_CHANNEL_MASK	"sdp_channel_mask"
+#define CNXK_FLOW_PRE_L2_INFO	"flow_pre_l2_info"
 
 int
 cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 {
 	uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64;
 	uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB;
+	struct flow_pre_l2_size_info pre_l2_info;
 	uint16_t ipsec_in_max_spi = BIT(8) - 1;
 	uint16_t ipsec_out_max_sa = BIT(12);
 	uint16_t flow_prealloc_size = 1;
@@ -226,6 +260,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	struct rte_kvargs *kvlist;
 
 	memset(&sdp_chan, 0, sizeof(sdp_chan));
+	memset(&pre_l2_info, 0, sizeof(struct flow_pre_l2_size_info));
 
 	if (devargs == NULL)
 		goto null_devargs;
@@ -261,6 +296,8 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 			   &force_inb_inl_dev);
 	rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK,
 			   &parse_sdp_channel_mask, &sdp_chan);
+	rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO,
+			   &parse_pre_l2_hdr_info, &pre_l2_info);
 	rte_kvargs_free(kvlist);
 
 null_devargs:
@@ -282,6 +319,9 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	dev->npc.sdp_channel = sdp_chan.channel;
 	dev->npc.sdp_channel_mask = sdp_chan.mask;
 	dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set;
+	dev->npc.pre_l2_size_offset = pre_l2_info.pre_l2_size_off;
+	dev->npc.pre_l2_size_offset_mask = pre_l2_info.pre_l2_size_off_mask;
+	dev->npc.pre_l2_size_shift_dir = pre_l2_info.pre_l2_size_shift_dir;
 	return 0;
 exit:
 	return -EINVAL;
@@ -297,6 +337,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
 			      CNXK_RSS_TAG_AS_XOR "=1"
 			      CNXK_IPSEC_IN_MAX_SPI "=<1-65535>"
 			      CNXK_OUTB_NB_DESC "=<1-65535>"
+			      CNXK_FLOW_PRE_L2_INFO "=<0-255>/<1-255>/<0-1>"
 			      CNXK_OUTB_NB_CRYPTO_QS "=<1-64>"
 			      CNXK_FORCE_INB_INL_DEV "=1"
 			      CNXK_SDP_CHANNEL_MASK "=<1-4095>/<1-4095>");
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 2/4] common/cnxk: support custom pre L2 header parsing as raw
  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   ` psatheesh
  2022-01-03  6:19   ` [dpdk-dev] [PATCH v2 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  6:19 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

From: Kiran Kumar K <kirankumark@marvell.com>

Add roc API for parsing custom pre L2 headers as raw data.
Only relative offset is supported and search and limit is
not supported with this raw item type.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
---
 drivers/common/cnxk/roc_npc.c           |   8 +-
 drivers/common/cnxk/roc_npc_mcam_dump.c |   2 +
 drivers/common/cnxk/roc_npc_parse.c     | 103 +++++++++++++++++-------
 drivers/common/cnxk/roc_npc_priv.h      |   1 +
 4 files changed, 81 insertions(+), 33 deletions(-)

diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index d18dfd4259..e3961bfbc6 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -566,10 +566,10 @@ npc_parse_pattern(struct npc *npc, const struct roc_npc_item_info pattern[],
 		  struct roc_npc_flow *flow, struct npc_parse_state *pst)
 {
 	npc_parse_stage_func_t parse_stage_funcs[] = {
-		npc_parse_meta_items, npc_parse_cpt_hdr, npc_parse_higig2_hdr,
-		npc_parse_la,	      npc_parse_lb,	 npc_parse_lc,
-		npc_parse_ld,	      npc_parse_le,	 npc_parse_lf,
-		npc_parse_lg,	      npc_parse_lh,
+		npc_parse_meta_items, npc_parse_pre_l2, npc_parse_cpt_hdr,
+		npc_parse_higig2_hdr, npc_parse_la,	npc_parse_lb,
+		npc_parse_lc,	      npc_parse_ld,	npc_parse_le,
+		npc_parse_lf,	      npc_parse_lg,	npc_parse_lh,
 	};
 	uint8_t layer = 0;
 	int key_offset;
diff --git a/drivers/common/cnxk/roc_npc_mcam_dump.c b/drivers/common/cnxk/roc_npc_mcam_dump.c
index 278056591e..679e3d7657 100644
--- a/drivers/common/cnxk/roc_npc_mcam_dump.c
+++ b/drivers/common/cnxk/roc_npc_mcam_dump.c
@@ -69,6 +69,8 @@ static const char *const ltype_str[NPC_MAX_LID][NPC_MAX_LT] = {
 	[NPC_LID_LA][NPC_LT_LA_IH_NIX_ETHER] = "LA_IH_NIX_ETHER",
 	[NPC_LID_LA][NPC_LT_LA_HIGIG2_ETHER] = "LA_HIGIG2_ETHER",
 	[NPC_LID_LA][NPC_LT_LA_IH_NIX_HIGIG2_ETHER] = "LA_IH_NIX_HIGIG2_ETHER",
+	[NPC_LID_LA][NPC_LT_LA_CUSTOM_PRE_L2_ETHER] =
+		"NPC_LT_LA_CUSTOM_PRE_L2_ETHER",
 	[NPC_LID_LB][0] = "NONE",
 	[NPC_LID_LB][NPC_LT_LB_CTAG] = "LB_CTAG",
 	[NPC_LID_LB][NPC_LT_LB_STAG_QINQ] = "LB_STAG_QINQ",
diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c
index 8125035dd8..c9ab9aef28 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -21,6 +21,80 @@ npc_parse_meta_items(struct npc_parse_state *pst)
 	return 0;
 }
 
+static int
+npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
+			  const struct roc_npc_flow_item_raw *raw_mask,
+			  struct npc_parse_item_info *info, uint8_t *spec_buf,
+			  uint8_t *mask_buf)
+{
+
+	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+	memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+
+	memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
+	       raw_spec->length);
+
+	if (raw_mask && raw_mask->pattern) {
+		memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
+		       raw_spec->length);
+	} else {
+		memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
+	}
+
+	info->len = NPC_MAX_RAW_ITEM_LEN;
+	info->spec = spec_buf;
+	info->mask = mask_buf;
+	return 0;
+}
+
+int
+npc_parse_pre_l2(struct npc_parse_state *pst)
+{
+	uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
+	uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN] = {0};
+	const struct roc_npc_flow_item_raw *raw_spec;
+	struct npc_parse_item_info info;
+	int lid, lt, len;
+	int rc;
+
+	if (pst->npc->switch_header_type != ROC_PRIV_FLAGS_PRE_L2)
+		return 0;
+
+	/* Identify the pattern type into lid, lt */
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_RAW)
+		return 0;
+
+	lid = NPC_LID_LA;
+	lt = NPC_LT_LA_CUSTOM_PRE_L2_ETHER;
+	info.hw_hdr_len = 0;
+
+	raw_spec = pst->pattern->spec;
+	len = raw_spec->length + raw_spec->offset;
+	if (len > NPC_MAX_RAW_ITEM_LEN)
+		return -EINVAL;
+
+	if (raw_spec->relative == 0 || raw_spec->search || raw_spec->limit ||
+	    raw_spec->offset < 0)
+		return -EINVAL;
+
+	npc_flow_raw_item_prepare(
+		(const struct roc_npc_flow_item_raw *)pst->pattern->spec,
+		(const struct roc_npc_flow_item_raw *)pst->pattern->mask, &info,
+		raw_spec_buf, raw_mask_buf);
+
+	info.hw_mask = &hw_mask;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+
+	/* Basic validation of item parameters */
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc)
+		return rc;
+
+	/* Update pst if not validate only? clash check? */
+	return npc_update_parse_state(pst, &info, lid, lt, 0);
+}
+
 int
 npc_parse_cpt_hdr(struct npc_parse_state *pst)
 {
@@ -136,35 +210,6 @@ npc_parse_la(struct npc_parse_state *pst)
 	return npc_update_parse_state(pst, &info, lid, lt, 0);
 }
 
-static int
-npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
-			  const struct roc_npc_flow_item_raw *raw_mask,
-			  struct npc_parse_item_info *info, uint8_t *spec_buf,
-			  uint8_t *mask_buf)
-{
-	uint32_t custom_hdr_size = 0;
-
-	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
-	memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
-	custom_hdr_size = raw_spec->offset + raw_spec->length;
-
-	memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
-	       raw_spec->length);
-
-	if (raw_mask->pattern) {
-		memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
-		       raw_spec->length);
-	} else {
-		memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
-	}
-
-	info->len = custom_hdr_size;
-	info->spec = spec_buf;
-	info->mask = mask_buf;
-
-	return 0;
-}
-
 int
 npc_parse_lb(struct npc_parse_state *pst)
 {
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index 86c10ea082..1a40192599 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -408,6 +408,7 @@ void npc_get_hw_supp_mask(struct npc_parse_state *pst,
 int npc_parse_item_basic(const struct roc_npc_item_info *item,
 			 struct npc_parse_item_info *info);
 int npc_parse_meta_items(struct npc_parse_state *pst);
+int npc_parse_pre_l2(struct npc_parse_state *pst);
 int npc_parse_higig2_hdr(struct npc_parse_state *pst);
 int npc_parse_cpt_hdr(struct npc_parse_state *pst);
 int npc_parse_la(struct npc_parse_state *pst);
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 3/4] common/cnxk: support matching VLAN existence in RTE Flow
  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
  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
  3 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  6:19 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

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


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 4/4] common/cnxk: support extensions attributes in IPv6 item
  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   ` [dpdk-dev] [PATCH v2 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
@ 2022-01-03  6:19   ` psatheesh
  2022-01-20  6:54   ` [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2 Jerin Jacob
  3 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-03  6:19 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

From: Satheesh Paul <psatheesh@marvell.com>

Support matching existence of specific extension headers
after RTE_FLOW_ITEM_TYPE_IPV6 item.

Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
---
 drivers/common/cnxk/hw/npc.h        | 17 ++++++++
 drivers/common/cnxk/roc_npc.h       | 33 +++++++++++++++
 drivers/common/cnxk/roc_npc_mcam.c  | 43 +++++++++++++++++++
 drivers/common/cnxk/roc_npc_parse.c | 65 +++++++++++++++++++++++++++--
 drivers/common/cnxk/roc_npc_priv.h  |  6 +++
 5 files changed, 160 insertions(+), 4 deletions(-)

diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
index 6f896de9f0..b8218e25af 100644
--- a/drivers/common/cnxk/hw/npc.h
+++ b/drivers/common/cnxk/hw/npc.h
@@ -320,6 +320,23 @@ enum npc_kpu_lc_uflag {
 	NPC_F_LC_U_IP6_FRAG = 0x40,
 };
 
+enum npc_kpu_lc_lflag {
+	NPC_F_LC_L_IP_IN_IP = 1,
+	NPC_F_LC_L_6TO4,
+	NPC_F_LC_L_MPLS_IN_IP,
+	NPC_F_LC_L_IP6_TUN_IP6,
+	NPC_F_LC_L_IP6_MPLS_IN_IP,
+	NPC_F_LC_L_MPLS_4_LABELS,
+	NPC_F_LC_L_MPLS_3_LABELS,
+	NPC_F_LC_L_MPLS_2_LABELS,
+	NPC_F_LC_L_EXT_HOP,
+	NPC_F_LC_L_EXT_DEST,
+	NPC_F_LC_L_EXT_ROUT,
+	NPC_F_LC_L_EXT_MOBILITY,
+	NPC_F_LC_L_EXT_HOSTID,
+	NPC_F_LC_L_EXT_SHIM6,
+};
+
 /* Structures definitions */
 struct npc_kpu_profile_cam {
 	uint8_t state;
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 6ab185e188..b836e264c6 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -112,6 +112,39 @@ struct roc_npc_flow_item_vlan {
 	uint32_t reserved : 31; /**< Reserved, must be zero. */
 };
 
+struct roc_ipv6_hdr {
+	uint32_t vtc_flow;    /**< IP version, traffic class & flow label. */
+	uint16_t payload_len; /**< IP payload size, including ext. headers */
+	uint8_t proto;	      /**< Protocol, next header. */
+	uint8_t hop_limits;   /**< Hop limits. */
+	uint8_t src_addr[16]; /**< IP address of source host. */
+	uint8_t dst_addr[16]; /**< IP address of destination host(s). */
+} __plt_packed;
+
+struct roc_npc_flow_item_ipv6 {
+	struct roc_ipv6_hdr hdr; /**< IPv6 header definition. */
+	uint32_t has_hop_ext : 1;
+	/**< Header contains Hop-by-Hop Options extension header. */
+	uint32_t has_route_ext : 1;
+	/**< Header contains Routing extension header. */
+	uint32_t has_frag_ext : 1;
+	/**< Header contains Fragment extension header. */
+	uint32_t has_auth_ext : 1;
+	/**< Header contains Authentication extension header. */
+	uint32_t has_esp_ext : 1;
+	/**< Header contains Encapsulation Security Payload extension header. */
+	uint32_t has_dest_ext : 1;
+	/**< Header contains Destination Options extension header. */
+	uint32_t has_mobil_ext : 1;
+	/**< Header contains Mobility extension header. */
+	uint32_t has_hip_ext : 1;
+	/**< Header contains Host Identity Protocol extension header. */
+	uint32_t has_shim6_ext : 1;
+	/**< Header contains Shim6 Protocol extension header. */
+	uint32_t reserved : 23;
+	/**< Reserved for future extension headers, must be zero. */
+};
+
 #define ROC_NPC_MAX_ACTION_COUNT 19
 
 enum roc_npc_action_type {
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index 2349317c5c..2063b5c59a 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -635,6 +635,46 @@ npc_set_vlan_ltype(struct npc_parse_state *pst)
 	pst->flow->mcam_mask[0] |= (0xeULL << lb_offset);
 }
 
+static void
+npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
+{
+	uint8_t lc_offset, lcflag_offset;
+	uint64_t val, mask;
+
+	lc_offset =
+		__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+				   ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+	lc_offset *= 4;
+
+	mask = ~((0xfULL << lc_offset));
+	pst->flow->mcam_data[0] &= mask;
+	pst->flow->mcam_mask[0] &= mask;
+	/* NPC_LT_LC_IP6: 0b0100, NPC_LT_LC_IP6_EXT: 0b0101
+	 * Set LC layertype/mask as 0b0100/0b1110 to match both.
+	 */
+	val = ((uint64_t)(NPC_LT_LC_IP6 & NPC_LT_LC_IP6_EXT)) << lc_offset;
+	pst->flow->mcam_data[0] |= val;
+	pst->flow->mcam_mask[0] |= (0xeULL << lc_offset);
+
+	/* If LC LFLAG is non-zero, set the LC LFLAG mask to 0xF. In general
+	 * case flag mask is set same as the value in data. For example, to
+	 * match 3 VLANs, flags have to match a range of values. But, for IPv6
+	 * extended attributes matching, we need an exact match. Hence, set the
+	 * mask as 0xF. This is done only if LC LFLAG value is non-zero,
+	 * because for AH and ESP, LC LFLAG is zero and we don't want to match
+	 * zero in LFLAG.
+	 */
+	lcflag_offset =
+		__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+				   ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+	lcflag_offset *= 4;
+
+	mask = (0xfULL << lcflag_offset);
+	val = pst->flow->mcam_data[0] & mask;
+	if (val)
+		pst->flow->mcam_mask[0] |= mask;
+}
+
 int
 npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 {
@@ -709,6 +749,9 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 	if (pst->set_vlan_ltype_mask)
 		npc_set_vlan_ltype(pst);
 
+	if (pst->set_ipv6ext_ltype_mask)
+		npc_set_ipv6ext_ltype_mask(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 75724661da..1f21693369 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -480,16 +480,69 @@ npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
 		pst->tunnel = 1;
 }
 
+static int
+npc_handle_ipv6ext_attr(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+			struct npc_parse_state *pst, uint8_t *flags)
+{
+	int flags_count = 0;
+
+	if (ipv6_spec->has_hop_ext) {
+		*flags = NPC_F_LC_L_EXT_HOP;
+		flags_count++;
+	}
+	if (ipv6_spec->has_route_ext) {
+		*flags = NPC_F_LC_L_EXT_ROUT;
+		flags_count++;
+	}
+	if (ipv6_spec->has_frag_ext) {
+		*flags = NPC_F_LC_U_IP6_FRAG;
+		flags_count++;
+	}
+	if (ipv6_spec->has_dest_ext) {
+		*flags = NPC_F_LC_L_EXT_DEST;
+		flags_count++;
+	}
+	if (ipv6_spec->has_mobil_ext) {
+		*flags = NPC_F_LC_L_EXT_MOBILITY;
+		flags_count++;
+	}
+	if (ipv6_spec->has_hip_ext) {
+		*flags = NPC_F_LC_L_EXT_HOSTID;
+		flags_count++;
+	}
+	if (ipv6_spec->has_shim6_ext) {
+		*flags = NPC_F_LC_L_EXT_SHIM6;
+		flags_count++;
+	}
+	if (ipv6_spec->has_auth_ext) {
+		pst->lt[NPC_LID_LD] = NPC_LT_LD_AH;
+		flags_count++;
+	}
+	if (ipv6_spec->has_esp_ext) {
+		pst->lt[NPC_LID_LE] = NPC_LT_LE_ESP;
+		flags_count++;
+	}
+
+	if (flags_count > 1)
+		return -EINVAL;
+
+	if (flags_count)
+		pst->set_ipv6ext_ltype_mask = true;
+
+	return 0;
+}
+
 int
 npc_parse_lc(struct npc_parse_state *pst)
 {
+	const struct roc_npc_flow_item_ipv6 *ipv6_spec;
 	const struct roc_npc_flow_item_raw *raw_spec;
 	uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
 	uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
 	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
 	struct npc_parse_item_info info;
-	int lid, lt, len = 0;
-	int rc;
+	int rc, lid, lt, len = 0;
+	uint8_t flags = 0;
 
 	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
 		return npc_parse_mpls(pst, NPC_LID_LC);
@@ -506,9 +559,13 @@ npc_parse_lc(struct npc_parse_state *pst)
 		info.len = pst->pattern->size;
 		break;
 	case ROC_NPC_ITEM_TYPE_IPV6:
+		ipv6_spec = pst->pattern->spec;
 		lid = NPC_LID_LC;
 		lt = NPC_LT_LC_IP6;
-		info.len = pst->pattern->size;
+		rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags);
+		if (rc)
+			return rc;
+		info.len = sizeof(ipv6_spec->hdr);
 		break;
 	case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
 		lt = NPC_LT_LC_ARP;
@@ -558,7 +615,7 @@ npc_parse_lc(struct npc_parse_state *pst)
 	if (rc != 0)
 		return rc;
 
-	return npc_update_parse_state(pst, &info, lid, lt, 0);
+	return npc_update_parse_state(pst, &info, lid, lt, flags);
 }
 
 int
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index ef7985f4cf..44d61ba641 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -71,6 +71,11 @@
 /* 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)
+/* LC OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags + 1b ltype) + LC
+ * (2b flags)
+ */
+#define NPC_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 6)
+#define NPC_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 8)
 
 struct npc_action_vtag_info {
 	uint16_t vlan_id;
@@ -183,6 +188,7 @@ struct npc_parse_state {
 	bool is_vf;
 	/* adjust ltype in MCAM to match at least one vlan */
 	bool set_vlan_ltype_mask;
+	bool set_ipv6ext_ltype_mask;
 };
 
 enum npc_kpu_parser_flag {
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2
  2022-01-03  6:19 ` [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2 psatheesh
                     ` (2 preceding siblings ...)
  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   ` Jerin Jacob
  3 siblings, 0 replies; 14+ messages in thread
From: Jerin Jacob @ 2022-01-20  6:54 UTC (permalink / raw)
  To: Satheesh Paul
  Cc: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao, dpdk-dev

On Mon, Jan 3, 2022 at 11:49 AM <psatheesh@marvell.com> wrote:
>
> From: Kiran Kumar K <kirankumark@marvell.com>
>
> Adding changes to configure switch header type pre L2 for cnxk.
> Along with switch header type user needs to provide the
> offset with in the custom header that holds the size of the
> custom header and mask for the size with in the size offset.

1) with in -> within
2) Describe what is pre L2 in the commit message.
3) Change the subject to net/cnxk: support  pre L2 switch header type
Also remove "add" in other patches in the series.

4) Please rebase to fix the following

[for-next-net]dell[dpdk-next-net-mrvl] $ git pw series apply 21048
Failed to apply patch:
Applying: drivers: add support for switch header type pre L2
Applying: common/cnxk: support custom pre L2 header parsing as raw
Applying: common/cnxk: support matching VLAN existence in RTE Flow
error: sha1 information is lacking or useless
(drivers/common/cnxk/roc_npc_priv.h).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0003 common/cnxk: support matching VLAN existence in RTE Flow
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

>
> Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
> Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
> ---
> v2:
> * Fixed checkpatch errors in commit messages
>
>  doc/guides/nics/cnxk.rst               | 25 +++++++++++++++-
>  drivers/common/cnxk/hw/npc.h           | 11 ++++---
>  drivers/common/cnxk/roc_mbox.h         |  1 +
>  drivers/common/cnxk/roc_nix.h          |  5 +++-
>  drivers/common/cnxk/roc_nix_ops.c      | 12 +++++++-
>  drivers/common/cnxk/roc_npc.h          |  8 +++++
>  drivers/net/cnxk/cnxk_ethdev.c         |  7 +++--
>  drivers/net/cnxk/cnxk_ethdev_devargs.c | 41 ++++++++++++++++++++++++++
>  8 files changed, 99 insertions(+), 11 deletions(-)
>
> diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
> index 2927c6cb7e..7c82cb55e1 100644
> --- a/doc/guides/nics/cnxk.rst
> +++ b/doc/guides/nics/cnxk.rst
> @@ -167,7 +167,30 @@ Runtime Config Options
>
>     With the above configuration, higig2 will be enabled on that port and the
>     traffic on this port should be higig2 traffic only. Supported switch header
> -   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2" and "vlan_exdsa".
> +   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and "pre_l2".
> +
> +- ``Flow pre l2 info`` (default ``0x0/0x0/0x0``)
> +
> +   In case of custom pre l2 headers, an offset, mask with in the offset and shift direction

Please explain a bit on what is pre l2 header.

> +   has to be provided within the custom header that holds the size of the custom header.
> +   This is valid only with switch header pre l2. Maximum supported offset range is 0 to 255

pre l2 -> ``pre_l2``

> +   and mask range is 1 to 255 and shift direction, 0: left shift, 1: right shift.
> +   Info format will be "offset/mask/shift direction". All parameters has to be in hexadecimal
> +   format and mask should be contiguous. Info can be configured using
> +   ``flow_pre_l2_info`` ``devargs`` parameter.
> +
> +   For example::
> +
> +      -a 0002:02:00.0,switch_header="pre_l2",flow_pre_l2_info=0x2/0x7e/0x1
> +
> +   With the above configuration, custom pre l2 header will be enabled on that port and size
> +   of the header is placed at byte offset 0x2 in the packet with mask 0x7e and right shift will
> +   be used to get the size. i.e size will be (pkt[0x2] & 0x7e) >> shift count.
> +   Shift count will be calculated based on mask and shift direction. For example if mask is 0x7c

For example -> For example,

> +   and shift direction is 1, i.e right shift, then the shift count will be 2 i.e absolute
> +   position of the right most set bit. If the mask is 0x7c and shift direction is 0, i.e left
> +   shift, then the shift count will be 1, i.e 8-n, where n is the absolute position of
> +   left most set bit.
>
>  - ``RSS tag as XOR`` (default ``0``)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2
  2022-01-03  5:57 [dpdk-dev] [PATCH 1/4] drivers: add support for switch header type pre L2 psatheesh
                   ` (3 preceding siblings ...)
  2022-01-03  6:19 ` [dpdk-dev] [PATCH v2 1/4] drivers: add support for switch header type pre L2 psatheesh
@ 2022-01-21  6:26 ` psatheesh
  2022-01-21  6:26   ` [dpdk-dev v3] [PATCH 2/4] common/cnxk: support custom pre L2 header parsing as raw psatheesh
                     ` (3 more replies)
  4 siblings, 4 replies; 14+ messages in thread
From: psatheesh @ 2022-01-21  6:26 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

From: Kiran Kumar K <kirankumark@marvell.com>

Adding changes to configure switch header type pre_L2 for cnxk.
pre_L2 headers are custom headers placed before the ethernet
header. Along with switch header type, user needs to provide the
offset within the custom header that holds the size of the
custom header and mask for the size within the size offset.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
---
v3:
* Fixed commit message grammar, added description of pre_L2
* Fixed grammar issues in documentation for pre_L2 support

v2:
* Fixed checkpatch errors in commit messages

 doc/guides/nics/cnxk.rst               | 29 +++++++++++++++++-
 drivers/common/cnxk/hw/npc.h           | 11 ++++---
 drivers/common/cnxk/roc_mbox.h         |  1 +
 drivers/common/cnxk/roc_nix.h          |  5 +++-
 drivers/common/cnxk/roc_nix_ops.c      | 12 +++++++-
 drivers/common/cnxk/roc_npc.h          |  8 +++++
 drivers/net/cnxk/cnxk_ethdev.c         |  7 +++--
 drivers/net/cnxk/cnxk_ethdev_devargs.c | 41 ++++++++++++++++++++++++++
 8 files changed, 103 insertions(+), 11 deletions(-)

diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index bab009baf0..6fab707c27 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -167,7 +167,34 @@ Runtime Config Options
 
    With the above configuration, higig2 will be enabled on that port and the
    traffic on this port should be higig2 traffic only. Supported switch header
-   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2" and "vlan_exdsa".
+   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and
+   "pre_l2".
+
+- ``Flow pre_l2 info`` (default ``0x0/0x0/0x0``)
+
+   pre_L2 headers are custom headers placed before the ethernet header. For
+   parsing custom pre_l2 headers, an offset, mask within the offset and shift
+   direction has to be provided within the custom header that holds the size of
+   the custom header. This is valid only with switch header pre_l2. Maximum
+   supported offset range is 0 to 255 and mask range is 1 to 255 and
+   shift direction, 0: left shift, 1: right shift.
+   Info format will be "offset/mask/shift direction". All parameters has to be
+   in hexadecimal format and mask should be contiguous. Info can be configured
+   using ``flow_pre_l2_info`` ``devargs`` parameter.
+
+   For example::
+
+      -a 0002:02:00.0,switch_header="pre_l2",flow_pre_l2_info=0x2/0x7e/0x1
+
+   With the above configuration, custom pre_l2 header will be enabled on that
+   port and size of the header is placed at byte offset 0x2 in the packet with
+   mask 0x7e and right shift will be used to get the size. That is, size will be
+   (pkt[0x2] & 0x7e) >> shift count. Shift count will be calculated based on
+   mask and shift direction. For example, if mask is 0x7c and shift direction is
+   1 (i.e., right shift) then the shift count will be 2, that is, absolute
+   position of the rightmost set bit. If the mask is 0x7c and shift direction
+   is 0 (i.e., left shift) then the shift count will be 1, that is, (8 - n),
+   where n is the absolute position of leftmost set bit.
 
 - ``RSS tag as XOR`` (default ``0``)
 
diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
index 68c5037e1c..6f896de9f0 100644
--- a/drivers/common/cnxk/hw/npc.h
+++ b/drivers/common/cnxk/hw/npc.h
@@ -169,13 +169,12 @@ enum npc_kpu_la_ltype {
 	NPC_LT_LA_8023 = 1,
 	NPC_LT_LA_ETHER,
 	NPC_LT_LA_IH_NIX_ETHER,
-	NPC_LT_LA_IH_8_ETHER,
-	NPC_LT_LA_IH_4_ETHER,
-	NPC_LT_LA_IH_2_ETHER,
-	NPC_LT_LA_HIGIG2_ETHER,
+	NPC_LT_LA_HIGIG2_ETHER = 7,
 	NPC_LT_LA_IH_NIX_HIGIG2_ETHER,
-	NPC_LT_LA_CH_LEN_90B_ETHER,
+	NPC_LT_LA_CUSTOM_L2_90B_ETHER,
 	NPC_LT_LA_CPT_HDR,
+	NPC_LT_LA_CUSTOM_L2_24B_ETHER,
+	NPC_LT_LA_CUSTOM_PRE_L2_ETHER,
 	NPC_LT_LA_CUSTOM0 = 0xE,
 	NPC_LT_LA_CUSTOM1 = 0xF,
 };
@@ -185,7 +184,7 @@ enum npc_kpu_lb_ltype {
 	NPC_LT_LB_CTAG,
 	NPC_LT_LB_STAG_QINQ,
 	NPC_LT_LB_BTAG,
-	NPC_LT_LB_ITAG,
+	NPC_LT_LB_PPPOE,
 	NPC_LT_LB_DSA,
 	NPC_LT_LB_DSA_VLAN,
 	NPC_LT_LB_EDSA,
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index e97d93e261..8967858914 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -323,6 +323,7 @@ struct npc_set_pkind {
 #define ROC_PRIV_FLAGS_LEN_90B	  BIT_ULL(3)
 #define ROC_PRIV_FLAGS_EXDSA	  BIT_ULL(4)
 #define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
+#define ROC_PRIV_FLAGS_PRE_L2	  BIT_ULL(6)
 #define ROC_PRIV_FLAGS_CUSTOM	  BIT_ULL(63)
 	uint64_t __io mode;
 #define PKIND_TX BIT_ULL(0)
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index d79abfef9f..755212c8f9 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -714,7 +714,10 @@ void __roc_api roc_nix_mac_link_info_get_cb_unregister(struct roc_nix *roc_nix);
 
 /* Ops */
 int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix,
-				     uint64_t switch_header_type);
+				     uint64_t switch_header_type,
+				     uint8_t pre_l2_size_offset,
+				     uint8_t pre_l2_size_offset_mask,
+				     uint8_t pre_l2_size_shift_dir);
 int __roc_api roc_nix_lso_fmt_setup(struct roc_nix *roc_nix);
 int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 				  uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
index 04a78cf4ca..8d3cddf2a6 100644
--- a/drivers/common/cnxk/roc_nix_ops.c
+++ b/drivers/common/cnxk/roc_nix_ops.c
@@ -364,7 +364,10 @@ roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
 }
 
 int
-roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
+roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
+		       uint8_t pre_l2_size_offset,
+		       uint8_t pre_l2_size_offset_mask,
+		       uint8_t pre_l2_size_shift_dir)
 {
 	struct mbox *mbox = get_mbox(roc_nix);
 	struct npc_set_pkind *req;
@@ -380,6 +383,7 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 	    switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
 	    switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
 	    switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
+	    switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
 	    switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
 		plt_err("switch header type is not supported");
 		return NIX_ERR_PARAM;
@@ -411,6 +415,12 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
 	} else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
 		req->mode = ROC_PRIV_FLAGS_CUSTOM;
 		req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
+	} else if (switch_header_type == ROC_PRIV_FLAGS_PRE_L2) {
+		req->mode = ROC_PRIV_FLAGS_CUSTOM;
+		req->pkind = NPC_RX_CUSTOM_PRE_L2_PKIND;
+		req->var_len_off = pre_l2_size_offset;
+		req->var_len_off_mask = pre_l2_size_offset_mask;
+		req->shift_dir = pre_l2_size_shift_dir;
 	}
 
 	req->dir = PKIND_RX;
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 8c24126ae8..8b57678863 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -187,6 +187,14 @@ enum flow_vtag_cfg_dir { VTAG_TX, VTAG_RX };
 struct roc_npc {
 	struct roc_nix *roc_nix;
 	uint8_t switch_header_type;
+	uint8_t pre_l2_size_offset;	 /**< Offset with in header that holds
+					   * size of custom header
+					   */
+	uint8_t pre_l2_size_offset_mask; /**< Offset mask with in header
+					   * that holds size of custom header
+					   */
+	uint8_t pre_l2_size_shift_dir;	 /**< Shift direction to calculate size
+					   */
 	uint16_t flow_prealloc_size;
 	uint16_t flow_max_priority;
 	uint16_t channel;
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 2ec5097555..53dfb5eae8 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1164,7 +1164,10 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
 		goto free_nix_lf;
 	}
 
-	rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type);
+	rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
+				    dev->npc.pre_l2_size_offset,
+				    dev->npc.pre_l2_size_offset_mask,
+				    dev->npc.pre_l2_size_shift_dir);
 	if (rc) {
 		plt_err("Failed to enable switch type nix_lf rc=%d", rc);
 		goto free_nix_lf;
@@ -1405,7 +1408,7 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev)
 	void *rxq;
 
 	/* Disable switch hdr pkind */
-	roc_nix_switch_hdr_set(&dev->nix, 0);
+	roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
 
 	/* Stop link change events */
 	if (!roc_nix_is_vf_or_sdp(&dev->nix))
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index ad7babdf52..157b27d9cb 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -13,6 +13,12 @@ struct sdp_channel {
 	uint16_t mask;
 };
 
+struct flow_pre_l2_size_info {
+	uint8_t pre_l2_size_off;
+	uint8_t pre_l2_size_off_mask;
+	uint8_t pre_l2_size_shift_dir;
+};
+
 static int
 parse_outb_nb_desc(const char *key, const char *value, void *extra_args)
 {
@@ -124,6 +130,29 @@ parse_reta_size(const char *key, const char *value, void *extra_args)
 	return 0;
 }
 
+static int
+parse_pre_l2_hdr_info(const char *key, const char *value, void *extra_args)
+{
+	struct flow_pre_l2_size_info *info =
+		(struct flow_pre_l2_size_info *)extra_args;
+	char *tok1 = NULL, *tok2 = NULL;
+	uint16_t off, off_mask, dir;
+
+	RTE_SET_USED(key);
+	off = strtol(value, &tok1, 16);
+	tok1++;
+	off_mask = strtol(tok1, &tok2, 16);
+	tok2++;
+	dir = strtol(tok2, 0, 16);
+	if (off >= 256 || off_mask < 1 || off_mask >= 256 || dir > 1)
+		return -EINVAL;
+	info->pre_l2_size_off = off;
+	info->pre_l2_size_off_mask = off_mask;
+	info->pre_l2_size_shift_dir = dir;
+
+	return 0;
+}
+
 static int
 parse_flag(const char *key, const char *value, void *extra_args)
 {
@@ -167,6 +196,9 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
 	if (strcmp(value, "vlan_exdsa") == 0)
 		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_VLAN_EXDSA;
 
+	if (strcmp(value, "pre_l2") == 0)
+		*(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2;
+
 	return 0;
 }
 
@@ -205,12 +237,14 @@ parse_sdp_channel_mask(const char *key, const char *value, void *extra_args)
 #define CNXK_FORCE_INB_INL_DEV	"force_inb_inl_dev"
 #define CNXK_OUTB_NB_CRYPTO_QS	"outb_nb_crypto_qs"
 #define CNXK_SDP_CHANNEL_MASK	"sdp_channel_mask"
+#define CNXK_FLOW_PRE_L2_INFO	"flow_pre_l2_info"
 
 int
 cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 {
 	uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64;
 	uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB;
+	struct flow_pre_l2_size_info pre_l2_info;
 	uint16_t ipsec_in_max_spi = BIT(8) - 1;
 	uint16_t ipsec_out_max_sa = BIT(12);
 	uint16_t flow_prealloc_size = 1;
@@ -226,6 +260,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	struct rte_kvargs *kvlist;
 
 	memset(&sdp_chan, 0, sizeof(sdp_chan));
+	memset(&pre_l2_info, 0, sizeof(struct flow_pre_l2_size_info));
 
 	if (devargs == NULL)
 		goto null_devargs;
@@ -261,6 +296,8 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 			   &force_inb_inl_dev);
 	rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK,
 			   &parse_sdp_channel_mask, &sdp_chan);
+	rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO,
+			   &parse_pre_l2_hdr_info, &pre_l2_info);
 	rte_kvargs_free(kvlist);
 
 null_devargs:
@@ -282,6 +319,9 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
 	dev->npc.sdp_channel = sdp_chan.channel;
 	dev->npc.sdp_channel_mask = sdp_chan.mask;
 	dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set;
+	dev->npc.pre_l2_size_offset = pre_l2_info.pre_l2_size_off;
+	dev->npc.pre_l2_size_offset_mask = pre_l2_info.pre_l2_size_off_mask;
+	dev->npc.pre_l2_size_shift_dir = pre_l2_info.pre_l2_size_shift_dir;
 	return 0;
 exit:
 	return -EINVAL;
@@ -297,6 +337,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
 			      CNXK_RSS_TAG_AS_XOR "=1"
 			      CNXK_IPSEC_IN_MAX_SPI "=<1-65535>"
 			      CNXK_OUTB_NB_DESC "=<1-65535>"
+			      CNXK_FLOW_PRE_L2_INFO "=<0-255>/<1-255>/<0-1>"
 			      CNXK_OUTB_NB_CRYPTO_QS "=<1-64>"
 			      CNXK_FORCE_INB_INL_DEV "=1"
 			      CNXK_SDP_CHANNEL_MASK "=<1-4095>/<1-4095>");
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev v3] [PATCH 2/4] common/cnxk: support custom pre L2 header parsing as raw
  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   ` psatheesh
  2022-01-21  6:26   ` [dpdk-dev v3] [PATCH 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-21  6:26 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

From: Kiran Kumar K <kirankumark@marvell.com>

Add roc API for parsing custom pre L2 headers as raw data.
Only relative offset is supported and search and limit is
not supported with this raw item type.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
---
 drivers/common/cnxk/roc_npc.c           |   8 +-
 drivers/common/cnxk/roc_npc_mcam_dump.c |   2 +
 drivers/common/cnxk/roc_npc_parse.c     | 103 +++++++++++++++++-------
 drivers/common/cnxk/roc_npc_priv.h      |   1 +
 4 files changed, 81 insertions(+), 33 deletions(-)

diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index d18dfd4259..e3961bfbc6 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -566,10 +566,10 @@ npc_parse_pattern(struct npc *npc, const struct roc_npc_item_info pattern[],
 		  struct roc_npc_flow *flow, struct npc_parse_state *pst)
 {
 	npc_parse_stage_func_t parse_stage_funcs[] = {
-		npc_parse_meta_items, npc_parse_cpt_hdr, npc_parse_higig2_hdr,
-		npc_parse_la,	      npc_parse_lb,	 npc_parse_lc,
-		npc_parse_ld,	      npc_parse_le,	 npc_parse_lf,
-		npc_parse_lg,	      npc_parse_lh,
+		npc_parse_meta_items, npc_parse_pre_l2, npc_parse_cpt_hdr,
+		npc_parse_higig2_hdr, npc_parse_la,	npc_parse_lb,
+		npc_parse_lc,	      npc_parse_ld,	npc_parse_le,
+		npc_parse_lf,	      npc_parse_lg,	npc_parse_lh,
 	};
 	uint8_t layer = 0;
 	int key_offset;
diff --git a/drivers/common/cnxk/roc_npc_mcam_dump.c b/drivers/common/cnxk/roc_npc_mcam_dump.c
index 278056591e..679e3d7657 100644
--- a/drivers/common/cnxk/roc_npc_mcam_dump.c
+++ b/drivers/common/cnxk/roc_npc_mcam_dump.c
@@ -69,6 +69,8 @@ static const char *const ltype_str[NPC_MAX_LID][NPC_MAX_LT] = {
 	[NPC_LID_LA][NPC_LT_LA_IH_NIX_ETHER] = "LA_IH_NIX_ETHER",
 	[NPC_LID_LA][NPC_LT_LA_HIGIG2_ETHER] = "LA_HIGIG2_ETHER",
 	[NPC_LID_LA][NPC_LT_LA_IH_NIX_HIGIG2_ETHER] = "LA_IH_NIX_HIGIG2_ETHER",
+	[NPC_LID_LA][NPC_LT_LA_CUSTOM_PRE_L2_ETHER] =
+		"NPC_LT_LA_CUSTOM_PRE_L2_ETHER",
 	[NPC_LID_LB][0] = "NONE",
 	[NPC_LID_LB][NPC_LT_LB_CTAG] = "LB_CTAG",
 	[NPC_LID_LB][NPC_LT_LB_STAG_QINQ] = "LB_STAG_QINQ",
diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c
index 8125035dd8..c9ab9aef28 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -21,6 +21,80 @@ npc_parse_meta_items(struct npc_parse_state *pst)
 	return 0;
 }
 
+static int
+npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
+			  const struct roc_npc_flow_item_raw *raw_mask,
+			  struct npc_parse_item_info *info, uint8_t *spec_buf,
+			  uint8_t *mask_buf)
+{
+
+	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+	memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+
+	memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
+	       raw_spec->length);
+
+	if (raw_mask && raw_mask->pattern) {
+		memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
+		       raw_spec->length);
+	} else {
+		memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
+	}
+
+	info->len = NPC_MAX_RAW_ITEM_LEN;
+	info->spec = spec_buf;
+	info->mask = mask_buf;
+	return 0;
+}
+
+int
+npc_parse_pre_l2(struct npc_parse_state *pst)
+{
+	uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
+	uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN] = {0};
+	const struct roc_npc_flow_item_raw *raw_spec;
+	struct npc_parse_item_info info;
+	int lid, lt, len;
+	int rc;
+
+	if (pst->npc->switch_header_type != ROC_PRIV_FLAGS_PRE_L2)
+		return 0;
+
+	/* Identify the pattern type into lid, lt */
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_RAW)
+		return 0;
+
+	lid = NPC_LID_LA;
+	lt = NPC_LT_LA_CUSTOM_PRE_L2_ETHER;
+	info.hw_hdr_len = 0;
+
+	raw_spec = pst->pattern->spec;
+	len = raw_spec->length + raw_spec->offset;
+	if (len > NPC_MAX_RAW_ITEM_LEN)
+		return -EINVAL;
+
+	if (raw_spec->relative == 0 || raw_spec->search || raw_spec->limit ||
+	    raw_spec->offset < 0)
+		return -EINVAL;
+
+	npc_flow_raw_item_prepare(
+		(const struct roc_npc_flow_item_raw *)pst->pattern->spec,
+		(const struct roc_npc_flow_item_raw *)pst->pattern->mask, &info,
+		raw_spec_buf, raw_mask_buf);
+
+	info.hw_mask = &hw_mask;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+
+	/* Basic validation of item parameters */
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc)
+		return rc;
+
+	/* Update pst if not validate only? clash check? */
+	return npc_update_parse_state(pst, &info, lid, lt, 0);
+}
+
 int
 npc_parse_cpt_hdr(struct npc_parse_state *pst)
 {
@@ -136,35 +210,6 @@ npc_parse_la(struct npc_parse_state *pst)
 	return npc_update_parse_state(pst, &info, lid, lt, 0);
 }
 
-static int
-npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
-			  const struct roc_npc_flow_item_raw *raw_mask,
-			  struct npc_parse_item_info *info, uint8_t *spec_buf,
-			  uint8_t *mask_buf)
-{
-	uint32_t custom_hdr_size = 0;
-
-	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
-	memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
-	custom_hdr_size = raw_spec->offset + raw_spec->length;
-
-	memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
-	       raw_spec->length);
-
-	if (raw_mask->pattern) {
-		memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
-		       raw_spec->length);
-	} else {
-		memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
-	}
-
-	info->len = custom_hdr_size;
-	info->spec = spec_buf;
-	info->mask = mask_buf;
-
-	return 0;
-}
-
 int
 npc_parse_lb(struct npc_parse_state *pst)
 {
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index a503d47de4..59e6c307cd 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -408,6 +408,7 @@ void npc_get_hw_supp_mask(struct npc_parse_state *pst,
 int npc_parse_item_basic(const struct roc_npc_item_info *item,
 			 struct npc_parse_item_info *info);
 int npc_parse_meta_items(struct npc_parse_state *pst);
+int npc_parse_pre_l2(struct npc_parse_state *pst);
 int npc_parse_higig2_hdr(struct npc_parse_state *pst);
 int npc_parse_cpt_hdr(struct npc_parse_state *pst);
 int npc_parse_la(struct npc_parse_state *pst);
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev v3] [PATCH 3/4] common/cnxk: support matching VLAN existence in RTE Flow
  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   ` 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
  3 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-21  6:26 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

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  |  5 +++
 5 files changed, 150 insertions(+), 11 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 7ed1fd3d6b..29bfc072c9 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 59e6c307cd..12320f0ced 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 adcd2faec6..babf56b1d5 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>
@@ -56,6 +57,9 @@
 #define PLT_INIT		 RTE_INIT
 #define PLT_TAILQ_FOREACH_SAFE	 RTE_TAILQ_FOREACH_SAFE
 
+#ifndef PLT_ETHER_ADDR_LEN
+#define PLT_ETHER_ADDR_LEN RTE_ETHER_ADDR_LEN
+#endif
 /** Divide ceil */
 #define PLT_DIV_CEIL(x, y)			\
 	({					\
@@ -84,6 +88,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


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev v3] [PATCH 4/4] common/cnxk: support extensions attributes in IPv6 item
  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   ` psatheesh
  2022-01-22 14:08   ` [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2 Jerin Jacob
  3 siblings, 0 replies; 14+ messages in thread
From: psatheesh @ 2022-01-21  6:26 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev, Satheesh Paul

From: Satheesh Paul <psatheesh@marvell.com>

Support matching existence of specific extension headers
after RTE_FLOW_ITEM_TYPE_IPV6 item.

Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
---
 drivers/common/cnxk/hw/npc.h        | 17 ++++++++
 drivers/common/cnxk/roc_npc.h       | 33 +++++++++++++++
 drivers/common/cnxk/roc_npc_mcam.c  | 43 +++++++++++++++++++
 drivers/common/cnxk/roc_npc_parse.c | 65 +++++++++++++++++++++++++++--
 drivers/common/cnxk/roc_npc_priv.h  |  6 +++
 5 files changed, 160 insertions(+), 4 deletions(-)

diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
index 6f896de9f0..b8218e25af 100644
--- a/drivers/common/cnxk/hw/npc.h
+++ b/drivers/common/cnxk/hw/npc.h
@@ -320,6 +320,23 @@ enum npc_kpu_lc_uflag {
 	NPC_F_LC_U_IP6_FRAG = 0x40,
 };
 
+enum npc_kpu_lc_lflag {
+	NPC_F_LC_L_IP_IN_IP = 1,
+	NPC_F_LC_L_6TO4,
+	NPC_F_LC_L_MPLS_IN_IP,
+	NPC_F_LC_L_IP6_TUN_IP6,
+	NPC_F_LC_L_IP6_MPLS_IN_IP,
+	NPC_F_LC_L_MPLS_4_LABELS,
+	NPC_F_LC_L_MPLS_3_LABELS,
+	NPC_F_LC_L_MPLS_2_LABELS,
+	NPC_F_LC_L_EXT_HOP,
+	NPC_F_LC_L_EXT_DEST,
+	NPC_F_LC_L_EXT_ROUT,
+	NPC_F_LC_L_EXT_MOBILITY,
+	NPC_F_LC_L_EXT_HOSTID,
+	NPC_F_LC_L_EXT_SHIM6,
+};
+
 /* Structures definitions */
 struct npc_kpu_profile_cam {
 	uint8_t state;
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 6ab185e188..b836e264c6 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -112,6 +112,39 @@ struct roc_npc_flow_item_vlan {
 	uint32_t reserved : 31; /**< Reserved, must be zero. */
 };
 
+struct roc_ipv6_hdr {
+	uint32_t vtc_flow;    /**< IP version, traffic class & flow label. */
+	uint16_t payload_len; /**< IP payload size, including ext. headers */
+	uint8_t proto;	      /**< Protocol, next header. */
+	uint8_t hop_limits;   /**< Hop limits. */
+	uint8_t src_addr[16]; /**< IP address of source host. */
+	uint8_t dst_addr[16]; /**< IP address of destination host(s). */
+} __plt_packed;
+
+struct roc_npc_flow_item_ipv6 {
+	struct roc_ipv6_hdr hdr; /**< IPv6 header definition. */
+	uint32_t has_hop_ext : 1;
+	/**< Header contains Hop-by-Hop Options extension header. */
+	uint32_t has_route_ext : 1;
+	/**< Header contains Routing extension header. */
+	uint32_t has_frag_ext : 1;
+	/**< Header contains Fragment extension header. */
+	uint32_t has_auth_ext : 1;
+	/**< Header contains Authentication extension header. */
+	uint32_t has_esp_ext : 1;
+	/**< Header contains Encapsulation Security Payload extension header. */
+	uint32_t has_dest_ext : 1;
+	/**< Header contains Destination Options extension header. */
+	uint32_t has_mobil_ext : 1;
+	/**< Header contains Mobility extension header. */
+	uint32_t has_hip_ext : 1;
+	/**< Header contains Host Identity Protocol extension header. */
+	uint32_t has_shim6_ext : 1;
+	/**< Header contains Shim6 Protocol extension header. */
+	uint32_t reserved : 23;
+	/**< Reserved for future extension headers, must be zero. */
+};
+
 #define ROC_NPC_MAX_ACTION_COUNT 19
 
 enum roc_npc_action_type {
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index 29bfc072c9..b251f643bc 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -635,6 +635,46 @@ npc_set_vlan_ltype(struct npc_parse_state *pst)
 	pst->flow->mcam_mask[0] |= (0xeULL << lb_offset);
 }
 
+static void
+npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
+{
+	uint8_t lc_offset, lcflag_offset;
+	uint64_t val, mask;
+
+	lc_offset =
+		__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+				   ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
+	lc_offset *= 4;
+
+	mask = ~((0xfULL << lc_offset));
+	pst->flow->mcam_data[0] &= mask;
+	pst->flow->mcam_mask[0] &= mask;
+	/* NPC_LT_LC_IP6: 0b0100, NPC_LT_LC_IP6_EXT: 0b0101
+	 * Set LC layertype/mask as 0b0100/0b1110 to match both.
+	 */
+	val = ((uint64_t)(NPC_LT_LC_IP6 & NPC_LT_LC_IP6_EXT)) << lc_offset;
+	pst->flow->mcam_data[0] |= val;
+	pst->flow->mcam_mask[0] |= (0xeULL << lc_offset);
+
+	/* If LC LFLAG is non-zero, set the LC LFLAG mask to 0xF. In general
+	 * case flag mask is set same as the value in data. For example, to
+	 * match 3 VLANs, flags have to match a range of values. But, for IPv6
+	 * extended attributes matching, we need an exact match. Hence, set the
+	 * mask as 0xF. This is done only if LC LFLAG value is non-zero,
+	 * because for AH and ESP, LC LFLAG is zero and we don't want to match
+	 * zero in LFLAG.
+	 */
+	lcflag_offset =
+		__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
+				   ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
+	lcflag_offset *= 4;
+
+	mask = (0xfULL << lcflag_offset);
+	val = pst->flow->mcam_data[0] & mask;
+	if (val)
+		pst->flow->mcam_mask[0] |= mask;
+}
+
 int
 npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 {
@@ -709,6 +749,9 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 	if (pst->set_vlan_ltype_mask)
 		npc_set_vlan_ltype(pst);
 
+	if (pst->set_ipv6ext_ltype_mask)
+		npc_set_ipv6ext_ltype_mask(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 75724661da..1f21693369 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -480,16 +480,69 @@ npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
 		pst->tunnel = 1;
 }
 
+static int
+npc_handle_ipv6ext_attr(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
+			struct npc_parse_state *pst, uint8_t *flags)
+{
+	int flags_count = 0;
+
+	if (ipv6_spec->has_hop_ext) {
+		*flags = NPC_F_LC_L_EXT_HOP;
+		flags_count++;
+	}
+	if (ipv6_spec->has_route_ext) {
+		*flags = NPC_F_LC_L_EXT_ROUT;
+		flags_count++;
+	}
+	if (ipv6_spec->has_frag_ext) {
+		*flags = NPC_F_LC_U_IP6_FRAG;
+		flags_count++;
+	}
+	if (ipv6_spec->has_dest_ext) {
+		*flags = NPC_F_LC_L_EXT_DEST;
+		flags_count++;
+	}
+	if (ipv6_spec->has_mobil_ext) {
+		*flags = NPC_F_LC_L_EXT_MOBILITY;
+		flags_count++;
+	}
+	if (ipv6_spec->has_hip_ext) {
+		*flags = NPC_F_LC_L_EXT_HOSTID;
+		flags_count++;
+	}
+	if (ipv6_spec->has_shim6_ext) {
+		*flags = NPC_F_LC_L_EXT_SHIM6;
+		flags_count++;
+	}
+	if (ipv6_spec->has_auth_ext) {
+		pst->lt[NPC_LID_LD] = NPC_LT_LD_AH;
+		flags_count++;
+	}
+	if (ipv6_spec->has_esp_ext) {
+		pst->lt[NPC_LID_LE] = NPC_LT_LE_ESP;
+		flags_count++;
+	}
+
+	if (flags_count > 1)
+		return -EINVAL;
+
+	if (flags_count)
+		pst->set_ipv6ext_ltype_mask = true;
+
+	return 0;
+}
+
 int
 npc_parse_lc(struct npc_parse_state *pst)
 {
+	const struct roc_npc_flow_item_ipv6 *ipv6_spec;
 	const struct roc_npc_flow_item_raw *raw_spec;
 	uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
 	uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
 	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
 	struct npc_parse_item_info info;
-	int lid, lt, len = 0;
-	int rc;
+	int rc, lid, lt, len = 0;
+	uint8_t flags = 0;
 
 	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
 		return npc_parse_mpls(pst, NPC_LID_LC);
@@ -506,9 +559,13 @@ npc_parse_lc(struct npc_parse_state *pst)
 		info.len = pst->pattern->size;
 		break;
 	case ROC_NPC_ITEM_TYPE_IPV6:
+		ipv6_spec = pst->pattern->spec;
 		lid = NPC_LID_LC;
 		lt = NPC_LT_LC_IP6;
-		info.len = pst->pattern->size;
+		rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags);
+		if (rc)
+			return rc;
+		info.len = sizeof(ipv6_spec->hdr);
 		break;
 	case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
 		lt = NPC_LT_LC_ARP;
@@ -558,7 +615,7 @@ npc_parse_lc(struct npc_parse_state *pst)
 	if (rc != 0)
 		return rc;
 
-	return npc_update_parse_state(pst, &info, lid, lt, 0);
+	return npc_update_parse_state(pst, &info, lid, lt, flags);
 }
 
 int
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index 12320f0ced..afd11add9a 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -71,6 +71,11 @@
 /* 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)
+/* LC OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags + 1b ltype) + LC
+ * (2b flags)
+ */
+#define NPC_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 6)
+#define NPC_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 8)
 
 struct npc_action_vtag_info {
 	uint16_t vlan_id;
@@ -183,6 +188,7 @@ struct npc_parse_state {
 	bool is_vf;
 	/* adjust ltype in MCAM to match at least one vlan */
 	bool set_vlan_ltype_mask;
+	bool set_ipv6ext_ltype_mask;
 };
 
 enum npc_kpu_parser_flag {
-- 
2.25.4


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2
  2022-01-21  6:26 ` [dpdk-dev v3] [PATCH 1/4] drivers: support for switch header type pre_L2 psatheesh
                     ` (2 preceding siblings ...)
  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   ` Jerin Jacob
  3 siblings, 0 replies; 14+ messages in thread
From: Jerin Jacob @ 2022-01-22 14:08 UTC (permalink / raw)
  To: Satheesh Paul, Ferruh Yigit
  Cc: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao, dpdk-dev

On Fri, Jan 21, 2022 at 11:56 AM <psatheesh@marvell.com> wrote:
>
> From: Kiran Kumar K <kirankumark@marvell.com>
>
> Adding changes to configure switch header type pre_L2 for cnxk.
> pre_L2 headers are custom headers placed before the ethernet
> header. Along with switch header type, user needs to provide the
> offset within the custom header that holds the size of the
> custom header and mask for the size within the size offset.
>
> Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
> Reviewed-by: Satheesh Paul <psatheesh@marvell.com>
> ---
> v3:
> * Fixed commit message grammar, added description of pre_L2
> * Fixed grammar issues in documentation for pre_L2 support


Updated the git commit log[1] and documentation to use pre_l2 keyword
everywhere.
Series applied to dpdk-next-net-mrvl/for-next-net. Thanks.


[1]
Author: Satheesh Paul <psatheesh@marvell.com>
Date:   Fri Jan 21 11:56:41 2022 +0530

    common/cnxk: support extensions attributes in IPv6 item

    Support matching existence of specific extension headers
    after RTE_FLOW_ITEM_TYPE_IPV6 item.

    Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
    Reviewed-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>

Author: Satheesh Paul <psatheesh@marvell.com>
Date:   Fri Jan 21 11:56:40 2022 +0530

    common/cnxk: support matching VLAN existence

    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>

Author: Kiran Kumar K <kirankumark@marvell.com>
Date:   Fri Jan 21 11:56:39 2022 +0530

    common/cnxk: support custom pre_l2 header parsing as raw

    Add ROC API for parsing custom pre_l2 headers as raw data.
    Only relative offset is supported and search and limit is
    not supported with this raw item type.

    Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
    Reviewed-by: Satheesh Paul <psatheesh@marvell.com>

Author: Kiran Kumar K <kirankumark@marvell.com>
Date:   Fri Jan 21 11:56:38 2022 +0530

    net/cnxk: support for switch header type pre_l2

    Adding changes to configure switch header type pre_l2 for cnxk.
    pre_l2 headers are custom headers placed before the ethernet
    header. Along with switch header type, user needs to provide the
    offset within the custom header that holds the size of the
    custom header and mask for the size within the size offset.

    Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
    Reviewed-by: Satheesh Paul <psatheesh@marvell.com>

> v2:
> * Fixed checkpatch errors in commit messages
>
>  doc/guides/nics/cnxk.rst               | 29 +++++++++++++++++-
>  drivers/common/cnxk/hw/npc.h           | 11 ++++---
>  drivers/common/cnxk/roc_mbox.h         |  1 +
>  drivers/common/cnxk/roc_nix.h          |  5 +++-
>  drivers/common/cnxk/roc_nix_ops.c      | 12 +++++++-
>  drivers/common/cnxk/roc_npc.h          |  8 +++++
>  drivers/net/cnxk/cnxk_ethdev.c         |  7 +++--
>  drivers/net/cnxk/cnxk_ethdev_devargs.c | 41 ++++++++++++++++++++++++++
>  8 files changed, 103 insertions(+), 11 deletions(-)
>
> diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
> index bab009baf0..6fab707c27 100644
> --- a/doc/guides/nics/cnxk.rst
> +++ b/doc/guides/nics/cnxk.rst
> @@ -167,7 +167,34 @@ Runtime Config Options
>
>     With the above configuration, higig2 will be enabled on that port and the
>     traffic on this port should be higig2 traffic only. Supported switch header
> -   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2" and "vlan_exdsa".
> +   types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and
> +   "pre_l2".
> +
> +- ``Flow pre_l2 info`` (default ``0x0/0x0/0x0``)
> +
> +   pre_L2 headers are custom headers placed before the ethernet header. For
> +   parsing custom pre_l2 headers, an offset, mask within the offset and shift
> +   direction has to be provided within the custom header that holds the size of
> +   the custom header. This is valid only with switch header pre_l2. Maximum
> +   supported offset range is 0 to 255 and mask range is 1 to 255 and
> +   shift direction, 0: left shift, 1: right shift.
> +   Info format will be "offset/mask/shift direction". All parameters has to be
> +   in hexadecimal format and mask should be contiguous. Info can be configured
> +   using ``flow_pre_l2_info`` ``devargs`` parameter.
> +
> +   For example::
> +
> +      -a 0002:02:00.0,switch_header="pre_l2",flow_pre_l2_info=0x2/0x7e/0x1
> +
> +   With the above configuration, custom pre_l2 header will be enabled on that
> +   port and size of the header is placed at byte offset 0x2 in the packet with
> +   mask 0x7e and right shift will be used to get the size. That is, size will be
> +   (pkt[0x2] & 0x7e) >> shift count. Shift count will be calculated based on
> +   mask and shift direction. For example, if mask is 0x7c and shift direction is
> +   1 (i.e., right shift) then the shift count will be 2, that is, absolute
> +   position of the rightmost set bit. If the mask is 0x7c and shift direction
> +   is 0 (i.e., left shift) then the shift count will be 1, that is, (8 - n),
> +   where n is the absolute position of leftmost set bit.
>
>  - ``RSS tag as XOR`` (default ``0``)
>
> diff --git a/drivers/common/cnxk/hw/npc.h b/drivers/common/cnxk/hw/npc.h
> index 68c5037e1c..6f896de9f0 100644
> --- a/drivers/common/cnxk/hw/npc.h
> +++ b/drivers/common/cnxk/hw/npc.h
> @@ -169,13 +169,12 @@ enum npc_kpu_la_ltype {
>         NPC_LT_LA_8023 = 1,
>         NPC_LT_LA_ETHER,
>         NPC_LT_LA_IH_NIX_ETHER,
> -       NPC_LT_LA_IH_8_ETHER,
> -       NPC_LT_LA_IH_4_ETHER,
> -       NPC_LT_LA_IH_2_ETHER,
> -       NPC_LT_LA_HIGIG2_ETHER,
> +       NPC_LT_LA_HIGIG2_ETHER = 7,
>         NPC_LT_LA_IH_NIX_HIGIG2_ETHER,
> -       NPC_LT_LA_CH_LEN_90B_ETHER,
> +       NPC_LT_LA_CUSTOM_L2_90B_ETHER,
>         NPC_LT_LA_CPT_HDR,
> +       NPC_LT_LA_CUSTOM_L2_24B_ETHER,
> +       NPC_LT_LA_CUSTOM_PRE_L2_ETHER,
>         NPC_LT_LA_CUSTOM0 = 0xE,
>         NPC_LT_LA_CUSTOM1 = 0xF,
>  };
> @@ -185,7 +184,7 @@ enum npc_kpu_lb_ltype {
>         NPC_LT_LB_CTAG,
>         NPC_LT_LB_STAG_QINQ,
>         NPC_LT_LB_BTAG,
> -       NPC_LT_LB_ITAG,
> +       NPC_LT_LB_PPPOE,
>         NPC_LT_LB_DSA,
>         NPC_LT_LB_DSA_VLAN,
>         NPC_LT_LB_EDSA,
> diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
> index e97d93e261..8967858914 100644
> --- a/drivers/common/cnxk/roc_mbox.h
> +++ b/drivers/common/cnxk/roc_mbox.h
> @@ -323,6 +323,7 @@ struct npc_set_pkind {
>  #define ROC_PRIV_FLAGS_LEN_90B   BIT_ULL(3)
>  #define ROC_PRIV_FLAGS_EXDSA     BIT_ULL(4)
>  #define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
> +#define ROC_PRIV_FLAGS_PRE_L2    BIT_ULL(6)
>  #define ROC_PRIV_FLAGS_CUSTOM    BIT_ULL(63)
>         uint64_t __io mode;
>  #define PKIND_TX BIT_ULL(0)
> diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
> index d79abfef9f..755212c8f9 100644
> --- a/drivers/common/cnxk/roc_nix.h
> +++ b/drivers/common/cnxk/roc_nix.h
> @@ -714,7 +714,10 @@ void __roc_api roc_nix_mac_link_info_get_cb_unregister(struct roc_nix *roc_nix);
>
>  /* Ops */
>  int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix,
> -                                    uint64_t switch_header_type);
> +                                    uint64_t switch_header_type,
> +                                    uint8_t pre_l2_size_offset,
> +                                    uint8_t pre_l2_size_offset_mask,
> +                                    uint8_t pre_l2_size_shift_dir);
>  int __roc_api roc_nix_lso_fmt_setup(struct roc_nix *roc_nix);
>  int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
>                                   uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
> diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
> index 04a78cf4ca..8d3cddf2a6 100644
> --- a/drivers/common/cnxk/roc_nix_ops.c
> +++ b/drivers/common/cnxk/roc_nix_ops.c
> @@ -364,7 +364,10 @@ roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
>  }
>
>  int
> -roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
> +roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
> +                      uint8_t pre_l2_size_offset,
> +                      uint8_t pre_l2_size_offset_mask,
> +                      uint8_t pre_l2_size_shift_dir)
>  {
>         struct mbox *mbox = get_mbox(roc_nix);
>         struct npc_set_pkind *req;
> @@ -380,6 +383,7 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
>             switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
>             switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
>             switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
> +           switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
>             switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
>                 plt_err("switch header type is not supported");
>                 return NIX_ERR_PARAM;
> @@ -411,6 +415,12 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
>         } else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
>                 req->mode = ROC_PRIV_FLAGS_CUSTOM;
>                 req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
> +       } else if (switch_header_type == ROC_PRIV_FLAGS_PRE_L2) {
> +               req->mode = ROC_PRIV_FLAGS_CUSTOM;
> +               req->pkind = NPC_RX_CUSTOM_PRE_L2_PKIND;
> +               req->var_len_off = pre_l2_size_offset;
> +               req->var_len_off_mask = pre_l2_size_offset_mask;
> +               req->shift_dir = pre_l2_size_shift_dir;
>         }
>
>         req->dir = PKIND_RX;
> diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
> index 8c24126ae8..8b57678863 100644
> --- a/drivers/common/cnxk/roc_npc.h
> +++ b/drivers/common/cnxk/roc_npc.h
> @@ -187,6 +187,14 @@ enum flow_vtag_cfg_dir { VTAG_TX, VTAG_RX };
>  struct roc_npc {
>         struct roc_nix *roc_nix;
>         uint8_t switch_header_type;
> +       uint8_t pre_l2_size_offset;      /**< Offset with in header that holds
> +                                          * size of custom header
> +                                          */
> +       uint8_t pre_l2_size_offset_mask; /**< Offset mask with in header
> +                                          * that holds size of custom header
> +                                          */
> +       uint8_t pre_l2_size_shift_dir;   /**< Shift direction to calculate size
> +                                          */
>         uint16_t flow_prealloc_size;
>         uint16_t flow_max_priority;
>         uint16_t channel;
> diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
> index 2ec5097555..53dfb5eae8 100644
> --- a/drivers/net/cnxk/cnxk_ethdev.c
> +++ b/drivers/net/cnxk/cnxk_ethdev.c
> @@ -1164,7 +1164,10 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
>                 goto free_nix_lf;
>         }
>
> -       rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type);
> +       rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
> +                                   dev->npc.pre_l2_size_offset,
> +                                   dev->npc.pre_l2_size_offset_mask,
> +                                   dev->npc.pre_l2_size_shift_dir);
>         if (rc) {
>                 plt_err("Failed to enable switch type nix_lf rc=%d", rc);
>                 goto free_nix_lf;
> @@ -1405,7 +1408,7 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev)
>         void *rxq;
>
>         /* Disable switch hdr pkind */
> -       roc_nix_switch_hdr_set(&dev->nix, 0);
> +       roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
>
>         /* Stop link change events */
>         if (!roc_nix_is_vf_or_sdp(&dev->nix))
> diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
> index ad7babdf52..157b27d9cb 100644
> --- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
> +++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
> @@ -13,6 +13,12 @@ struct sdp_channel {
>         uint16_t mask;
>  };
>
> +struct flow_pre_l2_size_info {
> +       uint8_t pre_l2_size_off;
> +       uint8_t pre_l2_size_off_mask;
> +       uint8_t pre_l2_size_shift_dir;
> +};
> +
>  static int
>  parse_outb_nb_desc(const char *key, const char *value, void *extra_args)
>  {
> @@ -124,6 +130,29 @@ parse_reta_size(const char *key, const char *value, void *extra_args)
>         return 0;
>  }
>
> +static int
> +parse_pre_l2_hdr_info(const char *key, const char *value, void *extra_args)
> +{
> +       struct flow_pre_l2_size_info *info =
> +               (struct flow_pre_l2_size_info *)extra_args;
> +       char *tok1 = NULL, *tok2 = NULL;
> +       uint16_t off, off_mask, dir;
> +
> +       RTE_SET_USED(key);
> +       off = strtol(value, &tok1, 16);
> +       tok1++;
> +       off_mask = strtol(tok1, &tok2, 16);
> +       tok2++;
> +       dir = strtol(tok2, 0, 16);
> +       if (off >= 256 || off_mask < 1 || off_mask >= 256 || dir > 1)
> +               return -EINVAL;
> +       info->pre_l2_size_off = off;
> +       info->pre_l2_size_off_mask = off_mask;
> +       info->pre_l2_size_shift_dir = dir;
> +
> +       return 0;
> +}
> +
>  static int
>  parse_flag(const char *key, const char *value, void *extra_args)
>  {
> @@ -167,6 +196,9 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
>         if (strcmp(value, "vlan_exdsa") == 0)
>                 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_VLAN_EXDSA;
>
> +       if (strcmp(value, "pre_l2") == 0)
> +               *(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2;
> +
>         return 0;
>  }
>
> @@ -205,12 +237,14 @@ parse_sdp_channel_mask(const char *key, const char *value, void *extra_args)
>  #define CNXK_FORCE_INB_INL_DEV "force_inb_inl_dev"
>  #define CNXK_OUTB_NB_CRYPTO_QS "outb_nb_crypto_qs"
>  #define CNXK_SDP_CHANNEL_MASK  "sdp_channel_mask"
> +#define CNXK_FLOW_PRE_L2_INFO  "flow_pre_l2_info"
>
>  int
>  cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
>  {
>         uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64;
>         uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB;
> +       struct flow_pre_l2_size_info pre_l2_info;
>         uint16_t ipsec_in_max_spi = BIT(8) - 1;
>         uint16_t ipsec_out_max_sa = BIT(12);
>         uint16_t flow_prealloc_size = 1;
> @@ -226,6 +260,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
>         struct rte_kvargs *kvlist;
>
>         memset(&sdp_chan, 0, sizeof(sdp_chan));
> +       memset(&pre_l2_info, 0, sizeof(struct flow_pre_l2_size_info));
>
>         if (devargs == NULL)
>                 goto null_devargs;
> @@ -261,6 +296,8 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
>                            &force_inb_inl_dev);
>         rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK,
>                            &parse_sdp_channel_mask, &sdp_chan);
> +       rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO,
> +                          &parse_pre_l2_hdr_info, &pre_l2_info);
>         rte_kvargs_free(kvlist);
>
>  null_devargs:
> @@ -282,6 +319,9 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
>         dev->npc.sdp_channel = sdp_chan.channel;
>         dev->npc.sdp_channel_mask = sdp_chan.mask;
>         dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set;
> +       dev->npc.pre_l2_size_offset = pre_l2_info.pre_l2_size_off;
> +       dev->npc.pre_l2_size_offset_mask = pre_l2_info.pre_l2_size_off_mask;
> +       dev->npc.pre_l2_size_shift_dir = pre_l2_info.pre_l2_size_shift_dir;
>         return 0;
>  exit:
>         return -EINVAL;
> @@ -297,6 +337,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
>                               CNXK_RSS_TAG_AS_XOR "=1"
>                               CNXK_IPSEC_IN_MAX_SPI "=<1-65535>"
>                               CNXK_OUTB_NB_DESC "=<1-65535>"
> +                             CNXK_FLOW_PRE_L2_INFO "=<0-255>/<1-255>/<0-1>"
>                               CNXK_OUTB_NB_CRYPTO_QS "=<1-64>"
>                               CNXK_FORCE_INB_INL_DEV "=1"
>                               CNXK_SDP_CHANNEL_MASK "=<1-4095>/<1-4095>");
> --
> 2.25.4
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-01-22 14:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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   ` [dpdk-dev] [PATCH v2 3/4] common/cnxk: support matching VLAN existence in RTE Flow psatheesh
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

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).