[v4,18/23] common/cnxk: support port representor and represented port

Message ID 20240227191550.137687-19-hkalra@marvell.com (mailing list archive)
State Changes Requested, archived
Delegated to: Jerin Jacob
Headers
Series net/cnxk: support for port representors |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Harman Kalra Feb. 27, 2024, 7:15 p.m. UTC
  From: Kiran Kumar K <kirankumark@marvell.com>

Implementing the common infrastructural changes for supporting port
representors and represented ports used as action and pattern in net
layer.

Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 drivers/common/cnxk/roc_npc.c       | 84 +++++++++++++++++++++++------
 drivers/common/cnxk/roc_npc.h       | 19 ++++++-
 drivers/common/cnxk/roc_npc_mcam.c  | 65 +++++++++++-----------
 drivers/common/cnxk/roc_npc_parse.c | 28 +++++++++-
 drivers/common/cnxk/roc_npc_priv.h  |  2 +
 drivers/net/cnxk/cnxk_flow.c        |  2 +-
 6 files changed, 150 insertions(+), 50 deletions(-)
  

Patch

diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index 67a660a2bc..d6ad3756bb 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -570,6 +570,8 @@  npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 	flow->ctr_id = NPC_COUNTER_NONE;
 	flow->mtr_id = ROC_NIX_MTR_ID_INVALID;
 	pf_func = npc->pf_func;
+	if (flow->has_rep)
+		pf_func = flow->rep_pf_func;
 
 	for (; actions->type != ROC_NPC_ACTION_TYPE_END; actions++) {
 		switch (actions->type) {
@@ -788,9 +790,12 @@  npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 
 		if (req_act & ROC_NPC_ACTION_TYPE_DROP) {
 			flow->npc_action = NIX_TX_ACTIONOP_DROP;
-		} else if ((req_act & ROC_NPC_ACTION_TYPE_COUNT) ||
-			   vlan_insert_action) {
+		} else if ((req_act & ROC_NPC_ACTION_TYPE_COUNT) || vlan_insert_action) {
 			flow->npc_action = NIX_TX_ACTIONOP_UCAST_DEFAULT;
+			if (flow->rep_act_rep) {
+				flow->npc_action = NIX_TX_ACTIONOP_UCAST_CHAN;
+				flow->npc_action |= (uint64_t)0x3f << 12;
+			}
 		} else {
 			plt_err("Unsupported action for egress");
 			errcode = NPC_ERR_ACTION_NOTSUP;
@@ -802,7 +807,9 @@  npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 			flow->mcast_channels[1] = npc->channel;
 		}
 
-		goto set_pf_func;
+		/* PF func who is sending the packet */
+		flow->tx_pf_func = pf_func;
+		goto done;
 	} else {
 		if (vlan_insert_action) {
 			errcode = NPC_ERR_ACTION_NOTSUP;
@@ -881,10 +888,10 @@  npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 	if (mark)
 		flow->npc_action |= (uint64_t)mark << 40;
 
-set_pf_func:
 	/* Ideally AF must ensure that correct pf_func is set */
 	flow->npc_action |= (uint64_t)pf_func << 4;
 
+done:
 	return 0;
 
 err_exit:
@@ -898,10 +905,14 @@  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_mark_item, npc_parse_pre_l2, npc_parse_cpt_hdr,
-		npc_parse_higig2_hdr, npc_parse_tx_queue,  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_port_representor_id,
+		npc_parse_mark_item,  npc_parse_pre_l2,
+		npc_parse_cpt_hdr,    npc_parse_higig2_hdr,
+		npc_parse_tx_queue,   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;
@@ -1140,15 +1151,20 @@  npc_rss_action_program(struct roc_npc *roc_npc,
 		       struct roc_npc_flow *flow)
 {
 	const struct roc_npc_action_rss *rss;
+	struct roc_npc *npc = roc_npc;
 	uint32_t rss_grp;
 	uint8_t alg_idx;
 	int rc;
 
+	if (flow->has_rep) {
+		npc = roc_npc->rep_npc;
+		npc->flowkey_cfg_state = roc_npc->flowkey_cfg_state;
+	}
+
 	for (; actions->type != ROC_NPC_ACTION_TYPE_END; actions++) {
 		if (actions->type == ROC_NPC_ACTION_TYPE_RSS) {
 			rss = (const struct roc_npc_action_rss *)actions->conf;
-			rc = npc_rss_action_configure(roc_npc, rss, &alg_idx,
-						      &rss_grp, flow->mcam_id);
+			rc = npc_rss_action_configure(npc, rss, &alg_idx, &rss_grp, flow->mcam_id);
 			if (rc)
 				return rc;
 
@@ -1171,7 +1187,7 @@  npc_vtag_cfg_delete(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
 	struct roc_nix *roc_nix = roc_npc->roc_nix;
 	struct nix_vtag_config *vtag_cfg;
 	struct nix_vtag_config_rsp *rsp;
-	struct mbox *mbox;
+	struct mbox *mbox, *ombox;
 	struct nix *nix;
 	int rc = 0;
 
@@ -1181,7 +1197,10 @@  npc_vtag_cfg_delete(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
 	} tx_vtag_action;
 
 	nix = roc_nix_to_nix_priv(roc_nix);
-	mbox = mbox_get((&nix->dev)->mbox);
+	ombox = (&nix->dev)->mbox;
+	if (flow->has_rep)
+		ombox = flow->rep_mbox;
+	mbox = mbox_get(ombox);
 
 	tx_vtag_action.reg = flow->vtag_action;
 	vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox);
@@ -1400,6 +1419,7 @@  npc_vtag_strip_action_configure(struct mbox *mbox,
 
 	rx_vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 15);
 	rx_vtag_action |= ((uint64_t)NPC_LID_LB << 8);
+	rx_vtag_action |= ((uint64_t)NIX_RX_VTAG_TYPE6 << 12);
 	rx_vtag_action |= NIX_RX_VTAGACTION_VTAG0_RELPTR;
 
 	if (*strip_cnt == 2) {
@@ -1432,6 +1452,8 @@  npc_vtag_action_program(struct roc_npc *roc_npc,
 
 	nix = roc_nix_to_nix_priv(roc_nix);
 	mbox = (&nix->dev)->mbox;
+	if (flow->has_rep)
+		mbox = flow->rep_mbox;
 
 	memset(vlan_info, 0, sizeof(vlan_info));
 
@@ -1448,6 +1470,7 @@  npc_vtag_action_program(struct roc_npc *roc_npc,
 			if (rc)
 				return rc;
 
+			plt_npc_dbg("VLAN strip action, strip_cnt %d", strip_cnt);
 			if (strip_cnt == 2)
 				actions++;
 
@@ -1587,6 +1610,25 @@  roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 	memset(flow, 0, sizeof(*flow));
 	memset(&parse_state, 0, sizeof(parse_state));
 
+	flow->port_id = -1;
+	if (roc_npc->rep_npc) {
+		flow->rep_channel =
+			(roc_npc->rep_rx_channel == 0) ?
+				roc_nix_to_nix_priv(roc_npc->rep_npc->roc_nix)->rx_chan_base :
+				roc_npc->rep_rx_channel;
+		flow->rep_pf_func = roc_npc->rep_pf_func;
+		flow->rep_act_pf_func = roc_npc->rep_act_pf_func;
+		flow->rep_act_rep = roc_npc->rep_act_rep;
+		flow->rep_mbox = roc_npc_to_npc_priv(roc_npc->rep_npc)->mbox;
+		flow->has_rep = true;
+		flow->is_rep_vf = !roc_nix_is_pf(roc_npc->rep_npc->roc_nix);
+		flow->port_id = roc_npc->rep_port_id;
+		flow->rep_npc = roc_npc_to_npc_priv(roc_npc->rep_npc);
+		roc_npc->rep_act_rep = false;
+		roc_npc->rep_act_pf_func = 0;
+		roc_npc->rep_rx_channel = 0;
+	}
+
 	parse_state.dst_pf_func = dst_pf_func;
 
 	rc = npc_parse_rule(roc_npc, attr, pattern, actions, flow, &parse_state);
@@ -1629,6 +1671,7 @@  roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 		*errcode = rc;
 		goto set_rss_failed;
 	}
+	roc_npc->rep_npc = NULL;
 
 	if (flow->has_age_action)
 		npc_age_flow_list_entry_add(roc_npc, flow);
@@ -1641,6 +1684,7 @@  roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 	TAILQ_FOREACH(flow_iter, list, next) {
 		if (flow_iter->mcam_id > flow->mcam_id) {
 			TAILQ_INSERT_BEFORE(flow_iter, flow, next);
+			roc_npc->rep_npc = NULL;
 			return flow;
 		}
 	}
@@ -1649,6 +1693,7 @@  roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 	return flow;
 
 set_rss_failed:
+	roc_npc->rep_npc = NULL;
 	if (flow->use_pre_alloc == 0) {
 		rc = roc_npc_mcam_free_entry(roc_npc, flow->mcam_id);
 		if (rc != 0) {
@@ -1660,6 +1705,7 @@  roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 		npc_inline_dev_ipsec_action_free(npc, flow);
 	}
 err_exit:
+	roc_npc->rep_npc = NULL;
 	plt_free(flow);
 	return NULL;
 }
@@ -1667,15 +1713,19 @@  roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
 int
 npc_rss_group_free(struct npc *npc, struct roc_npc_flow *flow)
 {
+	struct npc *lnpc = npc;
 	uint32_t rss_grp;
 
+	if (flow->has_rep)
+		lnpc = flow->rep_npc;
+
 	if ((flow->npc_action & 0xF) == NIX_RX_ACTIONOP_RSS) {
 		rss_grp = (flow->npc_action >> NPC_RSS_ACT_GRP_OFFSET) &
 			  NPC_RSS_ACT_GRP_MASK;
 		if (rss_grp == 0 || rss_grp >= npc->rss_grps)
 			return -EINVAL;
 
-		plt_bitmap_clear(npc->rss_grp_entries, rss_grp);
+		plt_bitmap_clear(lnpc->rss_grp_entries, rss_grp);
 	}
 
 	return 0;
@@ -1770,7 +1820,7 @@  roc_npc_flow_destroy(struct roc_npc *roc_npc, struct roc_npc_flow *flow)
 }
 
 void
-roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc)
+roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc, int rep_port_id)
 {
 	struct npc *npc = roc_npc_to_npc_priv(roc_npc);
 	struct roc_npc_flow *flow_iter;
@@ -1784,12 +1834,14 @@  roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc)
 
 		/* List in ascending order of mcam entries */
 		TAILQ_FOREACH(flow_iter, list, next) {
-			roc_npc_flow_mcam_dump(file, roc_npc, flow_iter);
+			if (rep_port_id == -1 || rep_port_id == flow_iter->port_id)
+				roc_npc_flow_mcam_dump(file, roc_npc, flow_iter);
 		}
 	}
 
 	TAILQ_FOREACH(flow_iter, &npc->ipsec_list, next) {
-		roc_npc_flow_mcam_dump(file, roc_npc, flow_iter);
+		if (rep_port_id == -1 || rep_port_id == flow_iter->port_id)
+			roc_npc_flow_mcam_dump(file, roc_npc, flow_iter);
 	}
 }
 
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 349c7f9d22..72aada84a1 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -42,6 +42,7 @@  enum roc_npc_item_type {
 	ROC_NPC_ITEM_TYPE_MARK,
 	ROC_NPC_ITEM_TYPE_TX_QUEUE,
 	ROC_NPC_ITEM_TYPE_IPV6_ROUTING_EXT,
+	ROC_NPC_ITEM_TYPE_REPRESENTED_PORT,
 	ROC_NPC_ITEM_TYPE_END,
 };
 
@@ -324,6 +325,7 @@  struct roc_npc_flow {
 	struct roc_npc_flow_dump_data dump_data[ROC_NPC_MAX_FLOW_PATTERNS];
 	uint16_t num_patterns;
 	struct roc_npc_spi_to_sa_action_info spi_to_sa_info;
+	uint16_t tx_pf_func;
 	bool is_validate;
 	uint16_t match_id;
 	uint8_t is_inline_dev;
@@ -332,6 +334,15 @@  struct roc_npc_flow {
 	void *age_context;
 	uint32_t timeout;
 	bool has_age_action;
+	uint16_t rep_pf_func;
+	uint16_t rep_act_pf_func;
+	bool rep_act_rep;
+	uint16_t rep_channel;
+	struct mbox *rep_mbox;
+	bool has_rep;
+	bool is_rep_vf;
+	struct npc *rep_npc;
+	int port_id;
 	bool is_sampling_rule;
 	uint32_t recv_queue;
 	uint32_t mcast_grp_index;
@@ -407,6 +418,12 @@  struct roc_npc {
 	uint16_t sdp_channel;
 	uint16_t sdp_channel_mask;
 	struct roc_npc_flow_age flow_age;
+	struct roc_npc *rep_npc;
+	uint16_t rep_pf_func;
+	uint16_t rep_rx_channel;
+	uint16_t rep_act_pf_func;
+	bool rep_act_rep;
+	int rep_port_id;
 
 #define ROC_NPC_MEM_SZ (6 * 1024)
 	uint8_t reserved[ROC_NPC_MEM_SZ];
@@ -448,7 +465,7 @@  int __roc_api roc_npc_get_free_mcam_entry(struct roc_npc *roc_npc, struct roc_np
 int __roc_api roc_npc_inl_mcam_read_counter(uint32_t ctr_id, uint64_t *count);
 int __roc_api roc_npc_inl_mcam_clear_counter(uint32_t ctr_id);
 int __roc_api roc_npc_mcam_free_all_resources(struct roc_npc *roc_npc);
-void __roc_api roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc);
+void __roc_api roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc, int rep_port_id);
 void __roc_api roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc,
 				      struct roc_npc_flow *mcam);
 int __roc_api roc_npc_mark_actions_get(struct roc_npc *roc_npc);
diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c
index 2de988a44b..cdb9db1383 100644
--- a/drivers/common/cnxk/roc_npc_mcam.c
+++ b/drivers/common/cnxk/roc_npc_mcam.c
@@ -143,8 +143,8 @@  npc_lid_lt_in_kex(struct npc *npc, uint8_t lid, uint8_t lt)
 }
 
 static void
-npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid,
-			 uint8_t lt, uint8_t ld)
+npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid, uint8_t lt,
+			 uint8_t ld)
 {
 	struct npc_xtract_info *x_info, *infoflag;
 	int hdr_off, keylen;
@@ -197,8 +197,7 @@  npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid,
  * @param len length of the match
  */
 static bool
-npc_is_kex_enabled(struct npc *npc, uint8_t lid, uint8_t lt, int offset,
-		   int len)
+npc_is_kex_enabled(struct npc *npc, uint8_t lid, uint8_t lt, int offset, int len)
 {
 	struct plt_bitmap *bmap;
 	uint32_t bmap_sz;
@@ -349,8 +348,8 @@  npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int re
 }
 
 int
-npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam,
-		     struct roc_npc_flow *ref_mcam, int prio, int *resp_count)
+npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_flow *ref_mcam,
+		     int prio, int *resp_count)
 {
 	struct npc_mcam_alloc_entry_req *req;
 	struct npc_mcam_alloc_entry_rsp *rsp;
@@ -450,22 +449,17 @@  npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam)
 static void
 npc_mcam_process_mkex_cfg(struct npc *npc, struct npc_get_kex_cfg_rsp *kex_rsp)
 {
-	volatile uint64_t(
-		*q)[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];
+	volatile uint64_t(*q)[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];
 	struct npc_xtract_info *x_info = NULL;
 	int lid, lt, ld, fl, ix;
 	npc_dxcfg_t *p;
 	uint64_t keyw;
 	uint64_t val;
 
-	npc->keyx_supp_nmask[NPC_MCAM_RX] =
-		kex_rsp->rx_keyx_cfg & 0x7fffffffULL;
-	npc->keyx_supp_nmask[NPC_MCAM_TX] =
-		kex_rsp->tx_keyx_cfg & 0x7fffffffULL;
-	npc->keyx_len[NPC_MCAM_RX] =
-		npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);
-	npc->keyx_len[NPC_MCAM_TX] =
-		npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);
+	npc->keyx_supp_nmask[NPC_MCAM_RX] = kex_rsp->rx_keyx_cfg & 0x7fffffffULL;
+	npc->keyx_supp_nmask[NPC_MCAM_TX] = kex_rsp->tx_keyx_cfg & 0x7fffffffULL;
+	npc->keyx_len[NPC_MCAM_RX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);
+	npc->keyx_len[NPC_MCAM_TX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);
 
 	keyw = (kex_rsp->rx_keyx_cfg >> 32) & 0x7ULL;
 	npc->keyw[NPC_MCAM_RX] = keyw;
@@ -485,8 +479,7 @@  npc_mcam_process_mkex_cfg(struct npc *npc, struct npc_get_kex_cfg_rsp *kex_rsp)
 
 	/* Update LID, LT and LDATA cfg */
 	p = &npc->prx_dxcfg;
-	q = (volatile uint64_t(*)[][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD])(
-		&kex_rsp->intf_lid_lt_ld);
+	q = (volatile uint64_t(*)[][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD])(&kex_rsp->intf_lid_lt_ld);
 	for (ix = 0; ix < NPC_MAX_INTF; ix++) {
 		for (lid = 0; lid < NPC_MAX_LID; lid++) {
 			for (lt = 0; lt < NPC_MAX_LT; lt++) {
@@ -539,8 +532,7 @@  npc_mcam_fetch_kex_cfg(struct npc *npc)
 		goto done;
 	}
 
-	mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name,
-		    MKEX_NAME_LEN);
+	mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name, MKEX_NAME_LEN);
 
 	npc->exact_match_ena = (kex_rsp->rx_keyx_cfg >> 40) & 0xF;
 	npc_mcam_process_mkex_cfg(npc, kex_rsp);
@@ -551,9 +543,8 @@  npc_mcam_fetch_kex_cfg(struct npc *npc)
 }
 
 static void
-npc_mcam_set_channel(struct roc_npc_flow *flow,
-		     struct npc_mcam_write_entry_req *req, uint16_t channel,
-		     uint16_t chan_mask, bool is_second_pass)
+npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req *req,
+		     uint16_t channel, uint16_t chan_mask, bool is_second_pass)
 {
 	uint16_t chan = 0, mask = 0;
 
@@ -681,7 +672,10 @@  npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
 	}
 
 	if (flow->nix_intf == NIX_INTF_TX) {
-		uint16_t pf_func = (flow->npc_action >> 4) & 0xffff;
+		uint16_t pf_func = flow->tx_pf_func;
+
+		if (flow->has_rep)
+			pf_func = flow->rep_pf_func;
 
 		pf_func = plt_cpu_to_be_16(pf_func);
 
@@ -759,6 +753,15 @@  npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_
 
 			npc_mcam_set_channel(flow, req, inl_dev->channel, inl_dev->chan_mask,
 					     false);
+		} else if (flow->has_rep) {
+			pf_func = (flow->rep_act_pf_func == 0) ? flow->rep_pf_func :
+								 flow->rep_act_pf_func;
+			req->entry_data.action &= ~(GENMASK(19, 4));
+			req->entry_data.action |= (uint64_t)pf_func << 4;
+			flow->npc_action &= ~(GENMASK(19, 4));
+			flow->npc_action |= (uint64_t)pf_func << 4;
+			npc_mcam_set_channel(flow, req, flow->rep_channel, (BIT_ULL(12) - 1),
+					     false);
 		} else if (npc->is_sdp_link) {
 			npc_mcam_set_channel(flow, req, npc->sdp_channel, npc->sdp_channel_mask,
 					     pst->is_second_pass_rule);
@@ -932,13 +935,11 @@  npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 						data_off = 0;
 						index++;
 					}
-					key_data[index] |=
-						((uint64_t)data << data_off);
+					key_data[index] |= ((uint64_t)data << data_off);
 
 					if (lt == 0)
 						mask = 0;
-					key_mask[index] |=
-						((uint64_t)mask << data_off);
+					key_mask[index] |= ((uint64_t)mask << data_off);
 					data_off += 4;
 				}
 			}
@@ -963,8 +964,12 @@  npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
 	    (pst->flow->npc_action & NIX_RX_ACTIONOP_UCAST_IPSEC))
 		skip_base_rule = true;
 
-	if (pst->is_vf && pst->flow->nix_intf == NIX_INTF_RX && !skip_base_rule) {
-		mbox = mbox_get(npc->mbox);
+	if ((pst->is_vf || pst->flow->is_rep_vf) && pst->flow->nix_intf == NIX_INTF_RX &&
+	    !skip_base_rule) {
+		if (pst->flow->has_rep)
+			mbox = mbox_get(pst->flow->rep_mbox);
+		else
+			mbox = mbox_get(npc->mbox);
 		(void)mbox_alloc_msg_npc_read_base_steer_rule(mbox);
 		rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
 		if (rc) {
diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c
index 571d6b8e5d..0aaf86c768 100644
--- a/drivers/common/cnxk/roc_npc_parse.c
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -35,11 +35,35 @@  npc_parse_mark_item(struct npc_parse_state *pst)
 	return 0;
 }
 
+int
+npc_parse_port_representor_id(struct npc_parse_state *pst)
+{
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_REPRESENTED_PORT)
+		return 0;
+
+	pst->pattern++;
+
+	return 0;
+}
+
+int
+npc_parse_represented_port_id(struct npc_parse_state *pst)
+{
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_REPRESENTED_PORT)
+		return 0;
+
+	if (pst->flow->nix_intf != NIX_INTF_RX)
+		return -EINVAL;
+
+	pst->pattern++;
+
+	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)
+			  struct npc_parse_item_info *info, uint8_t *spec_buf, uint8_t *mask_buf)
 {
 
 	memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index 50b62b1244..069c625911 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -457,6 +457,8 @@  int npc_mask_is_supported(const char *mask, const char *hw_mask, int len);
 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_mark_item(struct npc_parse_state *pst);
+int npc_parse_port_representor_id(struct npc_parse_state *pst);
+int npc_parse_represented_port_id(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);
diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c
index 4deccd1a67..b7e6ebc2e1 100644
--- a/drivers/net/cnxk/cnxk_flow.c
+++ b/drivers/net/cnxk/cnxk_flow.c
@@ -594,7 +594,7 @@  cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
 		return -EINVAL;
 	}
 
-	roc_npc_flow_dump(file, npc);
+	roc_npc_flow_dump(file, npc, -1);
 
 	return 0;
 }