diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index 65a8f7e..defa703 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -41,6 +41,7 @@ sources = files('roc_dev.c',
 		'roc_npa_debug.c',
 		'roc_npa_irq.c',
 		'roc_npc_mcam.c',
+		'roc_npc_parse.c',
 		'roc_npc_utils.c',
 		'roc_platform.c',
 		'roc_utils.c')
diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c
new file mode 100644
index 0000000..d07f91d
--- /dev/null
+++ b/drivers/common/cnxk/roc_npc_parse.c
@@ -0,0 +1,703 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+#include "roc_api.h"
+#include "roc_priv.h"
+
+const struct roc_npc_item_info *
+npc_parse_skip_void_and_any_items(const struct roc_npc_item_info *pattern)
+{
+	while ((pattern->type == ROC_NPC_ITEM_TYPE_VOID) ||
+	       (pattern->type == ROC_NPC_ITEM_TYPE_ANY))
+		pattern++;
+
+	return pattern;
+}
+
+int
+npc_parse_meta_items(struct npc_parse_state *pst)
+{
+	PLT_SET_USED(pst);
+	return 0;
+}
+
+int
+npc_parse_cpt_hdr(struct npc_parse_state *pst)
+{
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt;
+	int rc;
+
+	/* Identify the pattern type into lid, lt */
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_CPT_HDR)
+		return 0;
+
+	lid = NPC_LID_LA;
+	lt = NPC_LT_LA_CPT_HDR;
+	info.hw_hdr_len = 0;
+
+	/* Prepare for parsing the item */
+	info.hw_mask = &hw_mask;
+	info.len = pst->pattern->size;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	info.spec = NULL;
+	info.mask = NULL;
+
+	/* 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_higig2_hdr(struct npc_parse_state *pst)
+{
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt;
+	int rc;
+
+	/* Identify the pattern type into lid, lt */
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_HIGIG2)
+		return 0;
+
+	lid = NPC_LID_LA;
+	lt = NPC_LT_LA_HIGIG2_ETHER;
+	info.hw_hdr_len = 0;
+
+	if (pst->flow->nix_intf == NIX_INTF_TX) {
+		lt = NPC_LT_LA_IH_NIX_HIGIG2_ETHER;
+		info.hw_hdr_len = NPC_IH_LENGTH;
+	}
+
+	/* Prepare for parsing the item */
+	info.hw_mask = &hw_mask;
+	info.len = pst->pattern->size;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	info.spec = NULL;
+	info.mask = NULL;
+
+	/* 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_la(struct npc_parse_state *pst)
+{
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt;
+	int rc;
+
+	/* Identify the pattern type into lid, lt */
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH)
+		return 0;
+
+	lid = NPC_LID_LA;
+	lt = NPC_LT_LA_ETHER;
+	info.hw_hdr_len = 0;
+
+	if (pst->flow->nix_intf == NIX_INTF_TX) {
+		lt = NPC_LT_LA_IH_NIX_ETHER;
+		info.hw_hdr_len = NPC_IH_LENGTH;
+		if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
+			lt = NPC_LT_LA_IH_NIX_HIGIG2_ETHER;
+			info.hw_hdr_len += NPC_HIGIG2_LENGTH;
+		}
+	} else {
+		if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
+			lt = NPC_LT_LA_HIGIG2_ETHER;
+			info.hw_hdr_len = NPC_HIGIG2_LENGTH;
+		}
+	}
+
+	/* Prepare for parsing the item */
+	info.hw_mask = &hw_mask;
+	info.len = pst->pattern->size;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	info.spec = NULL;
+	info.mask = NULL;
+
+	/* 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_lb(struct npc_parse_state *pst)
+{
+	const struct roc_npc_item_info *pattern = pst->pattern;
+	const struct roc_npc_item_info *last_pattern;
+	char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt, lflags;
+	int nr_vlans = 0;
+	int rc;
+
+	info.spec = NULL;
+	info.mask = NULL;
+	info.def_mask = NULL;
+	info.hw_hdr_len = NPC_TPID_LENGTH;
+
+	lid = NPC_LID_LB;
+	lflags = 0;
+	last_pattern = pattern;
+
+	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
+		/* RTE vlan is either 802.1q or 802.1ad,
+		 * this maps to either CTAG/STAG. We need to decide
+		 * based on number of VLANS present. Matching is
+		 * supported on first tag only.
+		 */
+		info.hw_mask = NULL;
+		info.len = pst->pattern->size;
+
+		pattern = pst->pattern;
+		while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
+			nr_vlans++;
+
+			/* Basic validation of Second/Third vlan item */
+			if (nr_vlans > 1) {
+				rc = npc_parse_item_basic(pattern, &info);
+				if (rc != 0)
+					return rc;
+			}
+			last_pattern = pattern;
+			pattern++;
+			pattern = npc_parse_skip_void_and_any_items(pattern);
+		}
+
+		switch (nr_vlans) {
+		case 1:
+			lt = NPC_LT_LB_CTAG;
+			break;
+		case 2:
+			lt = NPC_LT_LB_STAG_QINQ;
+			lflags = NPC_F_STAG_CTAG;
+			break;
+		case 3:
+			lt = NPC_LT_LB_STAG_QINQ;
+			lflags = NPC_F_STAG_STAG_CTAG;
+			break;
+		default:
+			return NPC_ERR_PATTERN_NOTSUP;
+		}
+	} else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_E_TAG) {
+		/* we can support ETAG and match a subsequent CTAG
+		 * without any matching support.
+		 */
+		lt = NPC_LT_LB_ETAG;
+		lflags = 0;
+
+		last_pattern = pst->pattern;
+		pattern = npc_parse_skip_void_and_any_items(pst->pattern + 1);
+		if (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
+			/* set supported mask to NULL for vlan tag */
+			info.hw_mask = NULL;
+			info.len = pattern->size;
+			rc = npc_parse_item_basic(pattern, &info);
+			if (rc != 0)
+				return rc;
+
+			lflags = NPC_F_ETAG_CTAG;
+			last_pattern = pattern;
+		}
+		info.len = pattern->size;
+	} else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_QINQ) {
+		info.hw_mask = NULL;
+		info.len = pst->pattern->size;
+		lt = NPC_LT_LB_STAG_QINQ;
+		lflags = NPC_F_STAG_CTAG;
+	} else {
+		return 0;
+	}
+
+	info.hw_mask = &hw_mask;
+	info.spec = NULL;
+	info.mask = NULL;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	/* Point pattern to last item consumed */
+	pst->pattern = last_pattern;
+	return npc_update_parse_state(pst, &info, lid, lt, lflags);
+}
+
+static int
+npc_parse_mpls_label_stack(struct npc_parse_state *pst, int *flag)
+{
+	uint8_t flag_list[] = {0, NPC_F_MPLS_2_LABELS, NPC_F_MPLS_3_LABELS,
+			       NPC_F_MPLS_4_LABELS};
+	const struct roc_npc_item_info *pattern = pst->pattern;
+	struct npc_parse_item_info info;
+	int nr_labels = 0;
+	int rc;
+
+	/*
+	 * pst->pattern points to first MPLS label. We only check
+	 * that subsequent labels do not have anything to match.
+	 */
+	info.hw_mask = NULL;
+	info.len = pattern->size;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_hdr_len = 0;
+	info.def_mask = NULL;
+
+	while (pattern->type == ROC_NPC_ITEM_TYPE_MPLS) {
+		nr_labels++;
+
+		/* Basic validation of Second/Third/Fourth mpls item */
+		if (nr_labels > 1) {
+			rc = npc_parse_item_basic(pattern, &info);
+			if (rc != 0)
+				return rc;
+		}
+		pst->last_pattern = pattern;
+		pattern++;
+		pattern = npc_parse_skip_void_and_any_items(pattern);
+	}
+
+	if (nr_labels < 1 || nr_labels > 4)
+		return NPC_ERR_PATTERN_NOTSUP;
+
+	*flag = flag_list[nr_labels - 1];
+	return 0;
+}
+
+static int
+npc_parse_mpls(struct npc_parse_state *pst, int lid)
+{
+	/* Find number of MPLS labels */
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lt, lflags;
+	int rc;
+
+	lflags = 0;
+
+	if (lid == NPC_LID_LC)
+		lt = NPC_LT_LC_MPLS;
+	else if (lid == NPC_LID_LD)
+		lt = NPC_LT_LD_TU_MPLS_IN_IP;
+	else
+		lt = NPC_LT_LE_TU_MPLS_IN_UDP;
+
+	/* Prepare for parsing the first item */
+	info.hw_mask = &hw_mask;
+	info.len = pst->pattern->size;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_hdr_len = 0;
+
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	/*
+	 * Parse for more labels.
+	 * This sets lflags and pst->last_pattern correctly.
+	 */
+	rc = npc_parse_mpls_label_stack(pst, &lflags);
+	if (rc != 0)
+		return rc;
+
+	pst->tunnel = 1;
+	pst->pattern = pst->last_pattern;
+
+	return npc_update_parse_state(pst, &info, lid, lt, lflags);
+}
+
+static inline void
+npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
+{
+	const struct roc_npc_item_info *pattern = pst->pattern + 1;
+
+	pattern = npc_parse_skip_void_and_any_items(pattern);
+	if (pattern->type == ROC_NPC_ITEM_TYPE_MPLS ||
+	    pattern->type == ROC_NPC_ITEM_TYPE_IPV4 ||
+	    pattern->type == ROC_NPC_ITEM_TYPE_IPV6)
+		pst->tunnel = 1;
+}
+
+int
+npc_parse_lc(struct npc_parse_state *pst)
+{
+	uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt;
+	int rc;
+
+	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
+		return npc_parse_mpls(pst, NPC_LID_LC);
+
+	info.hw_mask = &hw_mask;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_hdr_len = 0;
+	lid = NPC_LID_LC;
+
+	switch (pst->pattern->type) {
+	case ROC_NPC_ITEM_TYPE_IPV4:
+		lt = NPC_LT_LC_IP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_IPV6:
+		lid = NPC_LID_LC;
+		lt = NPC_LT_LC_IP6;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
+		lt = NPC_LT_LC_ARP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_IPV6_EXT:
+		lid = NPC_LID_LC;
+		lt = NPC_LT_LC_IP6_EXT;
+		info.len = pst->pattern->size;
+		info.hw_hdr_len = 40;
+		break;
+	case ROC_NPC_ITEM_TYPE_L3_CUSTOM:
+		lt = NPC_LT_LC_CUSTOM0;
+		info.len = pst->pattern->size;
+		break;
+	default:
+		/* No match at this layer */
+		return 0;
+	}
+
+	/* Identify if IP tunnels MPLS or IPv4/v6 */
+	npc_check_lc_ip_tunnel(pst);
+
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	return npc_update_parse_state(pst, &info, lid, lt, 0);
+}
+
+int
+npc_parse_ld(struct npc_parse_state *pst)
+{
+	char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt, lflags;
+	int rc;
+
+	if (pst->tunnel) {
+		/* We have already parsed MPLS or IPv4/v6 followed
+		 * by MPLS or IPv4/v6. Subsequent TCP/UDP etc
+		 * would be parsed as tunneled versions. Skip
+		 * this layer, except for tunneled MPLS. If LC is
+		 * MPLS, we have anyway skipped all stacked MPLS
+		 * labels.
+		 */
+		if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
+			return npc_parse_mpls(pst, NPC_LID_LD);
+		return 0;
+	}
+	info.hw_mask = &hw_mask;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.def_mask = NULL;
+	info.len = 0;
+	info.hw_hdr_len = 0;
+
+	lid = NPC_LID_LD;
+	lflags = 0;
+
+	switch (pst->pattern->type) {
+	case ROC_NPC_ITEM_TYPE_ICMP:
+		if (pst->lt[NPC_LID_LC] == NPC_LT_LC_IP6)
+			lt = NPC_LT_LD_ICMP6;
+		else
+			lt = NPC_LT_LD_ICMP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_UDP:
+		lt = NPC_LT_LD_UDP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_IGMP:
+		lt = NPC_LT_LD_IGMP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_TCP:
+		lt = NPC_LT_LD_TCP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_SCTP:
+		lt = NPC_LT_LD_SCTP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_GRE:
+		lt = NPC_LT_LD_GRE;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_GRE_KEY:
+		lt = NPC_LT_LD_GRE;
+		info.len = pst->pattern->size;
+		info.hw_hdr_len = 4;
+		break;
+	case ROC_NPC_ITEM_TYPE_NVGRE:
+		lt = NPC_LT_LD_NVGRE;
+		lflags = NPC_F_GRE_NVGRE;
+		info.len = pst->pattern->size;
+		/* Further IP/Ethernet are parsed as tunneled */
+		pst->tunnel = 1;
+		break;
+	default:
+		return 0;
+	}
+
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	return npc_update_parse_state(pst, &info, lid, lt, lflags);
+}
+
+int
+npc_parse_le(struct npc_parse_state *pst)
+{
+	const struct roc_npc_item_info *pattern = pst->pattern;
+	char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt, lflags;
+	int rc;
+
+	if (pst->tunnel)
+		return 0;
+
+	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
+		return npc_parse_mpls(pst, NPC_LID_LE);
+
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_mask = NULL;
+	info.def_mask = NULL;
+	info.len = 0;
+	info.hw_hdr_len = 0;
+	lid = NPC_LID_LE;
+	lflags = 0;
+
+	/* Ensure we are not matching anything in UDP */
+	rc = npc_parse_item_basic(pattern, &info);
+	if (rc)
+		return rc;
+
+	info.hw_mask = &hw_mask;
+	pattern = npc_parse_skip_void_and_any_items(pattern);
+	switch (pattern->type) {
+	case ROC_NPC_ITEM_TYPE_VXLAN:
+		lflags = NPC_F_UDP_VXLAN;
+		info.len = pattern->size;
+		lt = NPC_LT_LE_VXLAN;
+		break;
+	case ROC_NPC_ITEM_TYPE_GTPC:
+		lflags = NPC_F_UDP_GTP_GTPC;
+		info.len = pattern->size;
+		lt = NPC_LT_LE_GTPC;
+		break;
+	case ROC_NPC_ITEM_TYPE_GTPU:
+		lflags = NPC_F_UDP_GTP_GTPU_G_PDU;
+		info.len = pattern->size;
+		lt = NPC_LT_LE_GTPU;
+		break;
+	case ROC_NPC_ITEM_TYPE_GENEVE:
+		lflags = NPC_F_UDP_GENEVE;
+		info.len = pattern->size;
+		lt = NPC_LT_LE_GENEVE;
+		break;
+	case ROC_NPC_ITEM_TYPE_VXLAN_GPE:
+		lflags = NPC_F_UDP_VXLANGPE;
+		info.len = pattern->size;
+		lt = NPC_LT_LE_VXLANGPE;
+		break;
+	case ROC_NPC_ITEM_TYPE_ESP:
+		lt = NPC_LT_LE_ESP;
+		info.len = pst->pattern->size;
+		break;
+	default:
+		return 0;
+	}
+
+	pst->tunnel = 1;
+
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	rc = npc_parse_item_basic(pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	return npc_update_parse_state(pst, &info, lid, lt, lflags);
+}
+
+int
+npc_parse_lf(struct npc_parse_state *pst)
+{
+	const struct roc_npc_item_info *pattern, *last_pattern;
+	char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt, lflags;
+	int nr_vlans = 0;
+	int rc;
+
+	/* We hit this layer if there is a tunneling protocol */
+	if (!pst->tunnel)
+		return 0;
+
+	if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH)
+		return 0;
+
+	lid = NPC_LID_LF;
+	lt = NPC_LT_LF_TU_ETHER;
+	lflags = 0;
+
+	/* No match support for vlan tags */
+	info.hw_mask = NULL;
+	info.len = pst->pattern->size;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_hdr_len = 0;
+
+	/* Look ahead and find out any VLAN tags. These can be
+	 * detected but no data matching is available.
+	 */
+	last_pattern = pst->pattern;
+	pattern = pst->pattern + 1;
+	pattern = npc_parse_skip_void_and_any_items(pattern);
+	while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
+		nr_vlans++;
+		last_pattern = pattern;
+		pattern++;
+		pattern = npc_parse_skip_void_and_any_items(pattern);
+	}
+	switch (nr_vlans) {
+	case 0:
+		break;
+	case 1:
+		lflags = NPC_F_TU_ETHER_CTAG;
+		break;
+	case 2:
+		lflags = NPC_F_TU_ETHER_STAG_CTAG;
+		break;
+	default:
+		return NPC_ERR_PATTERN_NOTSUP;
+	}
+
+	info.hw_mask = &hw_mask;
+	info.len = pst->pattern->size;
+	info.hw_hdr_len = 0;
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	info.spec = NULL;
+	info.mask = NULL;
+
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	pst->pattern = last_pattern;
+
+	return npc_update_parse_state(pst, &info, lid, lt, lflags);
+}
+
+int
+npc_parse_lg(struct npc_parse_state *pst)
+{
+	char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt;
+	int rc;
+
+	if (!pst->tunnel)
+		return 0;
+
+	info.hw_mask = &hw_mask;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_hdr_len = 0;
+	lid = NPC_LID_LG;
+
+	if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV4) {
+		lt = NPC_LT_LG_TU_IP;
+		info.len = pst->pattern->size;
+	} else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV6) {
+		lt = NPC_LT_LG_TU_IP6;
+		info.len = pst->pattern->size;
+	} else {
+		/* There is no tunneled IP header */
+		return 0;
+	}
+
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	return npc_update_parse_state(pst, &info, lid, lt, 0);
+}
+
+int
+npc_parse_lh(struct npc_parse_state *pst)
+{
+	char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
+	struct npc_parse_item_info info;
+	int lid, lt;
+	int rc;
+
+	if (!pst->tunnel)
+		return 0;
+
+	info.hw_mask = &hw_mask;
+	info.spec = NULL;
+	info.mask = NULL;
+	info.hw_hdr_len = 0;
+	lid = NPC_LID_LH;
+
+	switch (pst->pattern->type) {
+	case ROC_NPC_ITEM_TYPE_UDP:
+		lt = NPC_LT_LH_TU_UDP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_TCP:
+		lt = NPC_LT_LH_TU_TCP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_SCTP:
+		lt = NPC_LT_LH_TU_SCTP;
+		info.len = pst->pattern->size;
+		break;
+	case ROC_NPC_ITEM_TYPE_ESP:
+		lt = NPC_LT_LH_TU_ESP;
+		info.len = pst->pattern->size;
+		break;
+	default:
+		return 0;
+	}
+
+	npc_get_hw_supp_mask(pst, &info, lid, lt);
+	rc = npc_parse_item_basic(pst->pattern, &info);
+	if (rc != 0)
+		return rc;
+
+	return npc_update_parse_state(pst, &info, lid, lt, 0);
+}
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index 13768f9..dcf26c0 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -402,11 +402,24 @@ void npc_get_hw_supp_mask(struct npc_parse_state *pst,
 			  struct npc_parse_item_info *info, int lid, int lt);
 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_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);
+int npc_parse_lb(struct npc_parse_state *pst);
+int npc_parse_lc(struct npc_parse_state *pst);
+int npc_parse_ld(struct npc_parse_state *pst);
+int npc_parse_le(struct npc_parse_state *pst);
+int npc_parse_lf(struct npc_parse_state *pst);
+int npc_parse_lg(struct npc_parse_state *pst);
+int npc_parse_lh(struct npc_parse_state *pst);
 int npc_mcam_fetch_kex_cfg(struct npc *npc);
 int npc_check_preallocated_entry_cache(struct mbox *mbox,
 				       struct roc_npc_flow *flow,
 				       struct npc *npc);
 int npc_flow_free_all_resources(struct npc *npc);
+const struct roc_npc_item_info *
+npc_parse_skip_void_and_any_items(const struct roc_npc_item_info *pattern);
 int npc_program_mcam(struct npc *npc, struct npc_parse_state *pst,
 		     bool mcam_alloc);
 uint64_t npc_get_kex_capability(struct npc *npc);
