From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 67ADD42A65;
	Thu,  4 May 2023 19:37:53 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id C7D1F42DA4;
	Thu,  4 May 2023 19:36:42 +0200 (CEST)
Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com
 [209.85.210.175])
 by mails.dpdk.org (Postfix) with ESMTP id 3199242D75
 for <dev@dpdk.org>; Thu,  4 May 2023 19:36:39 +0200 (CEST)
Received: by mail-pf1-f175.google.com with SMTP id
 d2e1a72fcca58-63b62d2f729so688112b3a.1
 for <dev@dpdk.org>; Thu, 04 May 2023 10:36:39 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=broadcom.com; s=google; t=1683221798; x=1685813798;
 h=mime-version:references:in-reply-to:message-id:date:subject:cc:to
 :from:from:to:cc:subject:date:message-id:reply-to;
 bh=Ko8Fa3WFKcxunOiwqM93DXGMO8KUxhUyfOgfDBLMnYA=;
 b=HfIvZ3+lx6y1ygA/4IImz0+F/Y5QcBSXg7gmH+4Nqbd3BnoQu9lE9U2hjwPLD8EQ9i
 e700rqJB2xBmBdRuHDZRHmPT3oun4n4CItaH8CkHGyGj8HC072KSA0VqZWLEWCFrBQS+
 xK+D2b2zHDHWXNcIPuQpeIpvJEqUR427m98/A=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20221208; t=1683221798; x=1685813798;
 h=mime-version:references:in-reply-to:message-id:date:subject:cc:to
 :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=Ko8Fa3WFKcxunOiwqM93DXGMO8KUxhUyfOgfDBLMnYA=;
 b=VwBQvOrIgwVZStHqkTfQhWO8iKr4D1HJJqmT5CGOPvclbq8tJHrkrzPCY0LxTdEeZR
 rDeNXUAY/P3rQa9IiCu6tHQRrgfN+s+Q9hv6QfFiQc8pjd/gGq2NK6/JnMUGHy4nKwJO
 2ZruvXrKAMb0qj5LKD/1m/VEPyEwObUj31z26ZmShEHgH5rg2tZ0R7E0nXGu4RZkK0Ls
 Nc69/sjPlnXLyU6k//nzKrH3CJz2fTGQi/f2jT5elDitL5svs9YNlE8OqaBjSJALC77c
 zR+t3S0hxfq3BB2H8/yTjR3gfQ3aRXytPP4zHzqgW0Lg5+xaG2mYZvtEazOA/PC7xig9
 QxMQ==
X-Gm-Message-State: AC+VfDz0guhAqMCZmeja31lkn9EhVXRyEclmHAofvhSe56Lai6jGuw4l
 y8omvj6xdIk5f9Fyi1rYqoIo8mNxncIqNq5g3IMJsps34+bEWGNW0dYSxKbOXmXeRYcIY8G3Dok
 FOaGSsdO7Wgc9dHNsXOHTrzY/DC2zBf6/Ut28JlYvRvmdhGQwB+Bwzb8DVuhVfLKHK0Oo
X-Google-Smtp-Source: ACHHUZ6XbpwywujUG6luCxW/x5L2y8zUWizMcwYoE/vVbdQMMgQGcZgKqYuUsAcbv+0vqlgpCAnCNA==
X-Received: by 2002:aa7:88d1:0:b0:641:699:f353 with SMTP id
 k17-20020aa788d1000000b006410699f353mr3870801pff.22.1683221797826; 
 Thu, 04 May 2023 10:36:37 -0700 (PDT)
Received: from localhost.localdomain ([192.19.223.252])
 by smtp.gmail.com with ESMTPSA id
 v11-20020aa7850b000000b0062bc045bf4fsm26305230pfn.19.2023.05.04.10.36.36
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 04 May 2023 10:36:37 -0700 (PDT)
From: Ajit Khaparde <ajit.khaparde@broadcom.com>
To: dev@dpdk.org
Cc: Randy Schacher <stuart.schacher@broadcom.com>,
 Shahaji Bhosle <sbhosle@broadcom.com>,
 Manish Kurup <manish.kurup@broadcom.com>
Subject: [PATCH v3 10/11] net/bnxt: add support for eCPRI packet parsing
Date: Thu,  4 May 2023 10:36:11 -0700
Message-Id: <20230504173612.17696-11-ajit.khaparde@broadcom.com>
X-Mailer: git-send-email 2.39.2 (Apple Git-143)
In-Reply-To: <20230504173612.17696-1-ajit.khaparde@broadcom.com>
References: <20230504173612.17696-1-ajit.khaparde@broadcom.com>
MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/pkcs7-signature";
 micalg=sha-256; boundary="0000000000005f91a305fae19d42"
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

--0000000000005f91a305fae19d42
Content-Transfer-Encoding: 8bit

From: Randy Schacher <stuart.schacher@broadcom.com>

Add eCPRI parsing and offload support in the TruFlow ULP layer.

Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Shahaji Bhosle <sbhosle@broadcom.com>
Reviewed-by: Manish Kurup <manish.kurup@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 .mailmap                                      |   1 +
 doc/guides/nics/features/bnxt.ini             |   1 +
 drivers/net/bnxt/bnxt.h                       |   4 +
 drivers/net/bnxt/bnxt_ethdev.c                |  35 +++++
 drivers/net/bnxt/bnxt_hwrm.c                  |  17 +++
 drivers/net/bnxt/bnxt_txr.c                   |  10 +-
 drivers/net/bnxt/bnxt_vnic.c                  |   5 +-
 drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c    |   7 +-
 drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h    |   1 +
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c            |  24 ++++
 drivers/net/bnxt/tf_ulp/bnxt_ulp.h            |   9 +-
 drivers/net/bnxt/tf_ulp/ulp_mapper.c          |  18 +++
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |   4 +
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 120 +++++++++++++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |   5 +
 drivers/net/bnxt/tf_ulp/ulp_template_struct.h |   2 +
 16 files changed, 256 insertions(+), 7 deletions(-)

diff --git a/.mailmap b/.mailmap
index aded19d181..cc22746f36 100644
--- a/.mailmap
+++ b/.mailmap
@@ -813,6 +813,7 @@ Malvika Gupta <malvika.gupta@arm.com>
 Mandal Purna Chandra <purna.chandra.mandal@intel.com>
 Mandeep Rohilla <mrohilla@brocade.com>
 Manish Chopra <manishc@marvell.com>
+Manish Kurup <manish.kurup@broadcom.com>
 Manish Tomar <manish.tomar@nxp.com>
 Mao Jiang <maox.jiang@intel.com>
 Mao YingMing <maoyingming@baidu.com>
diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 2809beb629..7b3030a58c 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -57,6 +57,7 @@ Perf doc             = Y
 
 [rte_flow items]
 any                  = Y
+ecpri                = Y
 eth                  = P
 ipv4                 = Y
 ipv6                 = Y
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 08791b8a17..ed21ba7f29 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -844,10 +844,14 @@ struct bnxt {
 	uint8_t			port_cnt;
 	uint8_t			vxlan_port_cnt;
 	uint8_t			geneve_port_cnt;
+	uint8_t			ecpri_port_cnt;
 	uint16_t		vxlan_port;
 	uint16_t		geneve_port;
+	uint16_t		ecpri_port;
 	uint16_t		vxlan_fw_dst_port_id;
 	uint16_t		geneve_fw_dst_port_id;
+	uint16_t		ecpri_fw_dst_port_id;
+	uint16_t		ecpri_upar_in_use;
 	uint32_t		fw_ver;
 	uint32_t		hwrm_spec_code;
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index ea817e1fdd..ee1552452a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -2405,6 +2405,20 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
 		tunnel_type =
 			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
 		break;
+	case RTE_ETH_TUNNEL_TYPE_ECPRI:
+		if (bp->ecpri_port_cnt) {
+			PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->ecpri_port != udp_tunnel->udp_port) {
+				PMD_DRV_LOG(ERR, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->ecpri_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI;
+		break;
 	default:
 		PMD_DRV_LOG(ERR, "Tunnel type is not supported\n");
 		return -ENOTSUP;
@@ -2423,6 +2437,10 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
 	    HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE)
 		bp->geneve_port_cnt++;
 
+	if (tunnel_type ==
+	    HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI)
+		bp->ecpri_port_cnt++;
+
 	return rc;
 }
 
@@ -2474,6 +2492,23 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
 		port = bp->geneve_fw_dst_port_id;
 		break;
+	case RTE_ETH_TUNNEL_TYPE_ECPRI:
+		if (!bp->ecpri_port_cnt) {
+			PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->ecpri_port != udp_tunnel->udp_port) {
+			PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->ecpri_port);
+			return -EINVAL;
+		}
+		if (--bp->ecpri_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_ECPRI;
+		port = bp->ecpri_fw_dst_port_id;
+		break;
 	default:
 		PMD_DRV_LOG(ERR, "Tunnel type is not supported\n");
 		return -ENOTSUP;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index edad84c262..b944547656 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2969,6 +2969,10 @@ bnxt_free_tunnel_ports(struct bnxt *bp)
 	if (bp->geneve_port_cnt)
 		bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id,
 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE);
+
+	if (bp->ecpri_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->ecpri_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_ECPRI);
 }
 
 void bnxt_free_all_hwrm_resources(struct bnxt *bp)
@@ -4075,6 +4079,12 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 			rte_le_to_cpu_16(resp->tunnel_dst_port_id);
 		bp->geneve_port = port;
 		break;
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI:
+		bp->ecpri_fw_dst_port_id =
+			rte_le_to_cpu_16(resp->tunnel_dst_port_id);
+		bp->ecpri_port = port;
+		bp->ecpri_upar_in_use = resp->upar_in_use;
+		break;
 	default:
 		break;
 	}
@@ -4142,6 +4152,13 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 		bp->geneve_port_cnt = 0;
 	}
 
+	if (tunnel_type ==
+	    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_ECPRI) {
+		bp->ecpri_port = 0;
+		bp->ecpri_upar_in_use = 0;
+		bp->ecpri_port_cnt = 0;
+	}
+
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 6a11f5c8dc..899986764f 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -150,10 +150,14 @@ bnxt_check_pkt_needs_ts(struct rte_mbuf *m)
 	struct rte_ether_hdr _eth_hdr;
 	uint16_t eth_type, proto;
 	uint32_t off = 0;
-
+	/*
+	 * Check that the received packet is a eCPRI packet
+	 */
 	eth_hdr = rte_pktmbuf_read(m, off, sizeof(_eth_hdr), &_eth_hdr);
 	eth_type = rte_be_to_cpu_16(eth_hdr->ether_type);
 	off += sizeof(*eth_hdr);
+	if (eth_type == RTE_ETHER_TYPE_ECPRI)
+		return true;
 	/* Check for single tagged and double tagged VLANs */
 	if (eth_type == RTE_ETHER_TYPE_VLAN) {
 		const struct rte_vlan_hdr *vh;
@@ -164,6 +168,8 @@ bnxt_check_pkt_needs_ts(struct rte_mbuf *m)
 			return false;
 		off += sizeof(*vh);
 		proto = rte_be_to_cpu_16(vh->eth_proto);
+		if (proto == RTE_ETHER_TYPE_ECPRI)
+			return true;
 		if (proto == RTE_ETHER_TYPE_VLAN) {
 			const struct rte_vlan_hdr *vh;
 			struct rte_vlan_hdr vh_copy;
@@ -173,6 +179,8 @@ bnxt_check_pkt_needs_ts(struct rte_mbuf *m)
 				return false;
 			off += sizeof(*vh);
 			proto = rte_be_to_cpu_16(vh->eth_proto);
+			if (proto == RTE_ETHER_TYPE_ECPRI)
+				return true;
 		}
 	}
 	return false;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index be9c127b64..2be456956d 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -258,7 +258,8 @@ uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 {
 	uint16_t hwrm_type = 0;
 
-	if (rte_type & RTE_ETH_RSS_IPV4)
+	if ((rte_type & RTE_ETH_RSS_IPV4) ||
+	    (rte_type & RTE_ETH_RSS_ECPRI))
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
 	if (rte_type & RTE_ETH_RSS_NONFRAG_IPV4_TCP)
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
@@ -277,7 +278,7 @@ uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl)
 {
 	uint32_t mode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
-	bool l3 = (hash_f & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6));
+	bool l3 = (hash_f & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_ECPRI));
 	bool l4 = (hash_f & (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
 			     RTE_ETH_RSS_NONFRAG_IPV6_UDP |
 			     RTE_ETH_RSS_NONFRAG_IPV4_TCP |
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c
index 474854d59b..239191e14e 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c
@@ -543,12 +543,15 @@ bnxt_pmd_global_tunnel_set(uint16_t port_id, uint8_t type,
 	case BNXT_GLOBAL_REGISTER_TUNNEL_VXLAN:
 		hwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
 		break;
+	case BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI:
+		hwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI;
+		break;
 	default:
 		BNXT_TF_DBG(ERR, "Tunnel Type (%d) invalid\n", type);
 		return -EINVAL;
 	}
 
-	if (!udp_port) {
+	if (!udp_port && type != BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI) {
 		/* Free based on the handle */
 		if (!handle) {
 			BNXT_TF_DBG(ERR, "Free with invalid handle\n");
@@ -589,7 +592,7 @@ bnxt_pmd_global_tunnel_set(uint16_t port_id, uint8_t type,
 		if (!rc) {
 			ulp_global_tunnel_db[type].ref_cnt++;
 			ulp_global_tunnel_db[type].dport = udp_port;
-			bnxt_pmd_global_reg_data_to_hndl(port_id, 0,
+			bnxt_pmd_global_reg_data_to_hndl(port_id, bp->ecpri_upar_in_use,
 							 type, handle);
 		}
 	}
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h
index b76e4b849d..18feab6cac 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h
+++ b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.h
@@ -19,6 +19,7 @@ struct bnxt_global_tunnel_info {
 enum bnxt_global_register_tunnel_type {
 	BNXT_GLOBAL_REGISTER_TUNNEL_UNUSED = 0,
 	BNXT_GLOBAL_REGISTER_TUNNEL_VXLAN,
+	BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI,
 	BNXT_GLOBAL_REGISTER_TUNNEL_MAX
 };
 
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 500c177039..b696b6dc3e 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -456,6 +456,7 @@ bnxt_ulp_cntxt_app_caps_init(struct bnxt *bp,
 
 		bnxt_ulp_vxlan_ip_port_set(ulp_ctx, info[i].vxlan_ip_port);
 		bnxt_ulp_vxlan_port_set(ulp_ctx, info[i].vxlan_port);
+		bnxt_ulp_ecpri_udp_port_set(ulp_ctx, info[i].ecpri_udp_port);
 
 		/* set the shared session support from firmware */
 		fw = info[i].upgrade_fw_update;
@@ -479,6 +480,29 @@ bnxt_ulp_cntxt_app_caps_init(struct bnxt *bp,
 	return 0;
 }
 
+/* Function to retrieve the vxlan_ip (ecpri) port from the context. */
+int
+bnxt_ulp_ecpri_udp_port_set(struct bnxt_ulp_context *ulp_ctx,
+			   uint32_t ecpri_udp_port)
+{
+	if (!ulp_ctx || !ulp_ctx->cfg_data)
+		return -EINVAL;
+
+	ulp_ctx->cfg_data->ecpri_udp_port = ecpri_udp_port;
+
+	return 0;
+}
+
+/* Function to retrieve the vxlan_ip (ecpri) port from the context. */
+unsigned int
+bnxt_ulp_ecpri_udp_port_get(struct bnxt_ulp_context *ulp_ctx)
+{
+	if (!ulp_ctx || !ulp_ctx->cfg_data)
+		return 0;
+
+	return (unsigned int)ulp_ctx->cfg_data->ecpri_udp_port;
+}
+
 /* Function to set the number for vxlan_ip (custom vxlan) port into the context */
 int
 bnxt_ulp_vxlan_ip_port_set(struct bnxt_ulp_context *ulp_ctx,
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h
index 92db7751fe..258801f633 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h
@@ -113,6 +113,7 @@ struct bnxt_ulp_data {
 	struct bnxt_flow_app_tun_ent	app_tun[BNXT_ULP_MAX_TUN_CACHE_ENTRIES];
 	uint32_t			vxlan_port;
 	uint32_t			vxlan_ip_port;
+	uint32_t			ecpri_udp_port;
 	uint8_t				hu_reg_state;
 	uint8_t				hu_reg_cnt;
 	uint32_t			hu_session_type;
@@ -367,12 +368,19 @@ bnxt_ulp_vxlan_port_set(struct bnxt_ulp_context *ulp_ctx,
 			uint32_t vxlan_port);
 unsigned int
 bnxt_ulp_vxlan_port_get(struct bnxt_ulp_context *ulp_ctx);
+
 int
 bnxt_ulp_vxlan_ip_port_set(struct bnxt_ulp_context *ulp_ctx,
 			   uint32_t vxlan_ip_port);
 unsigned int
 bnxt_ulp_vxlan_ip_port_get(struct bnxt_ulp_context *ulp_ctx);
 
+int
+bnxt_ulp_ecpri_udp_port_set(struct bnxt_ulp_context *ulp_ctx,
+			    uint32_t ecpri_udp_port);
+unsigned int
+bnxt_ulp_ecpri_udp_port_get(struct bnxt_ulp_context *ulp_ctx);
+
 int32_t
 bnxt_flow_meter_init(struct bnxt *bp);
 
@@ -391,5 +399,4 @@ bnxt_ulp_ha_reg_cnt_get(struct bnxt_ulp_context *ulp_ctx);
 
 struct tf*
 bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type);
-
 #endif /* _BNXT_ULP_H_ */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index e5f1d266d7..6d345e12c7 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -3298,6 +3298,11 @@ ulp_mapper_global_res_free(struct bnxt_ulp_context *ulp __rte_unused,
 		rc = bnxt_pmd_global_tunnel_set(port_id, ttype, dport,
 						&handle);
 		break;
+	case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_ECPRI:
+		ttype = BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI;
+		rc = bnxt_pmd_global_tunnel_set(port_id, ttype, dport,
+						&handle);
+		break;
 	default:
 		rc = -EINVAL;
 		BNXT_TF_DBG(ERR, "Invalid ulp global resource type %d\n",
@@ -3362,6 +3367,19 @@ ulp_mapper_global_register_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 			return rc;
 		}
 		break;
+	case BNXT_ULP_RESOURCE_SUB_TYPE_GLOBAL_REGISTER_CUST_ECPRI:
+		tmp_data = ulp_blob_data_get(&data, &data_len);
+		udp_port = *((uint16_t *)tmp_data);
+		udp_port = tfp_be_to_cpu_16(udp_port);
+		ttype = BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI;
+
+		rc = bnxt_pmd_global_tunnel_set(parms->port_id, ttype,
+						udp_port, &handle);
+		if (rc) {
+			BNXT_TF_DBG(ERR, "Unable to set eCPRI UDP port\n");
+			return rc;
+		}
+	break;
 	default:
 		rc = -EINVAL;
 		BNXT_TF_DBG(ERR, "Invalid ulp global resource type %d\n",
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index af02f857d3..51b2e98103 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -408,6 +408,10 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
 	.proto_hdr_func          = NULL
 	},
+	[RTE_FLOW_ITEM_TYPE_ECPRI] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_ecpri_hdr_handler
+	},
 	[RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
 	.proto_hdr_func          = ulp_rte_port_hdr_handler
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index d64c9e4968..0937d0dbe4 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -143,7 +143,7 @@ bnxt_ulp_rte_parser_hdr_parse(const struct rte_flow_item pattern[],
 			hdr_info = &ulp_vendor_hdr_info[item->type -
 				BNXT_RTE_FLOW_ITEM_TYPE_END];
 		} else {
-			if (item->type > RTE_FLOW_ITEM_TYPE_HIGIG2)
+			if (item->type > RTE_FLOW_ITEM_TYPE_ECPRI)
 				goto hdr_parser_error;
 			hdr_info = &ulp_hdr_info[item->type];
 		}
@@ -612,6 +612,10 @@ ulp_rte_l2_proto_type_update(struct ulp_rte_parser_params *param,
 	} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_VLAN)) {
 		has_vlan_mask = 1;
 		has_vlan = 1;
+	} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_ECPRI)) {
+		/* Update the hdr_bitmap with eCPRI */
+		ULP_BITMAP_SET(param->hdr_fp_bit.bits,
+				BNXT_ULP_HDR_BIT_O_ECPRI);
 	} else if (type == tfp_cpu_to_be_16(ULP_RTE_ETHER_TYPE_ROE)) {
 		/* Update the hdr_bitmap with RoE */
 		ULP_BITMAP_SET(param->hdr_fp_bit.bits,
@@ -1660,6 +1664,120 @@ ulp_rte_icmp6_hdr_handler(const struct rte_flow_item *item,
 	return BNXT_TF_RC_SUCCESS;
 }
 
+/* Function to handle the parsing of RTE Flow item ECPRI Header. */
+int32_t
+ulp_rte_ecpri_hdr_handler(const struct rte_flow_item *item,
+			  struct ulp_rte_parser_params *params)
+{
+	const struct rte_flow_item_ecpri *ecpri_spec = item->spec;
+	const struct rte_flow_item_ecpri *ecpri_mask = item->mask;
+	struct rte_flow_item_ecpri l_ecpri_spec, l_ecpri_mask;
+	struct rte_flow_item_ecpri *p_ecpri_spec = &l_ecpri_spec;
+	struct rte_flow_item_ecpri *p_ecpri_mask = &l_ecpri_mask;
+	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
+	uint32_t idx = 0, cnt;
+	uint32_t size;
+
+	if (ulp_rte_prsr_fld_size_validate(params, &idx,
+					   BNXT_ULP_PROTO_HDR_ECPRI_NUM)) {
+		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
+		return BNXT_TF_RC_ERROR;
+	}
+
+	/* Figure out if eCPRI is within L4(UDP), unsupported, for now */
+	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L4_HDR_CNT);
+	if (cnt >= 1) {
+		BNXT_TF_DBG(ERR, "Parse Err: L4 header stack >= 2 not supported\n");
+		return BNXT_TF_RC_ERROR;
+	}
+
+	if (!ecpri_spec || !ecpri_mask)
+		goto parser_set_ecpri_hdr_bit;
+
+	memcpy(p_ecpri_spec, ecpri_spec, sizeof(*ecpri_spec));
+	memcpy(p_ecpri_mask, ecpri_mask, sizeof(*ecpri_mask));
+
+	p_ecpri_spec->hdr.common.u32 = rte_be_to_cpu_32(p_ecpri_spec->hdr.common.u32);
+	p_ecpri_mask->hdr.common.u32 = rte_be_to_cpu_32(p_ecpri_mask->hdr.common.u32);
+
+	/*
+	 * Init eCPRI spec+mask to correct defaults, also clear masks of fields
+	 * we ignore in the TCAM.
+	 */
+
+	l_ecpri_spec.hdr.common.size = 0;
+	l_ecpri_spec.hdr.common.c = 0;
+	l_ecpri_spec.hdr.common.res = 0;
+	l_ecpri_spec.hdr.common.revision = 1;
+	l_ecpri_mask.hdr.common.size = 0;
+	l_ecpri_mask.hdr.common.c = 1;
+	l_ecpri_mask.hdr.common.res = 0;
+	l_ecpri_mask.hdr.common.revision = 0xf;
+
+	switch (p_ecpri_spec->hdr.common.type) {
+	case RTE_ECPRI_MSG_TYPE_IQ_DATA:
+		l_ecpri_mask.hdr.type0.seq_id = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_BIT_SEQ:
+		l_ecpri_mask.hdr.type1.seq_id = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_RTC_CTRL:
+		l_ecpri_mask.hdr.type2.seq_id = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_GEN_DATA:
+		l_ecpri_mask.hdr.type3.seq_id = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_RM_ACC:
+		l_ecpri_mask.hdr.type4.rr = 0;
+		l_ecpri_mask.hdr.type4.rw = 0;
+		l_ecpri_mask.hdr.type4.rma_id = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_DLY_MSR:
+		l_ecpri_spec.hdr.type5.act_type = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_RMT_RST:
+		l_ecpri_spec.hdr.type6.rst_op = 0;
+		break;
+
+	case RTE_ECPRI_MSG_TYPE_EVT_IND:
+		l_ecpri_spec.hdr.type7.evt_type = 0;
+		l_ecpri_spec.hdr.type7.seq = 0;
+		l_ecpri_spec.hdr.type7.number = 0;
+		break;
+
+	default:
+		break;
+	}
+
+	p_ecpri_spec->hdr.common.u32 = rte_cpu_to_be_32(p_ecpri_spec->hdr.common.u32);
+	p_ecpri_mask->hdr.common.u32 = rte_cpu_to_be_32(p_ecpri_mask->hdr.common.u32);
+
+	/* Type */
+	size = sizeof(((struct rte_flow_item_ecpri *)NULL)->hdr.common.u32);
+	ulp_rte_prsr_fld_mask(params, &idx, size,
+			      ulp_deference_struct(p_ecpri_spec, hdr.common.u32),
+			      ulp_deference_struct(p_ecpri_mask, hdr.common.u32),
+			      ULP_PRSR_ACT_DEFAULT);
+
+	/* PC/RTC/MSR_ID */
+	size = sizeof(((struct rte_flow_item_ecpri *)NULL)->hdr.dummy[0]);
+	ulp_rte_prsr_fld_mask(params, &idx, size,
+			      ulp_deference_struct(p_ecpri_spec, hdr.dummy),
+			      ulp_deference_struct(p_ecpri_mask, hdr.dummy),
+			      ULP_PRSR_ACT_DEFAULT);
+
+parser_set_ecpri_hdr_bit:
+	/* Update the hdr_bitmap with eCPRI */
+	ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_ECPRI);
+	return BNXT_TF_RC_SUCCESS;
+}
+
 /* Function to handle the parsing of RTE Flow item void Header */
 int32_t
 ulp_rte_void_hdr_handler(const struct rte_flow_item *item __rte_unused,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index 74c7170a45..9dd7ebcb76 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -149,6 +149,11 @@ int32_t
 ulp_rte_icmp6_hdr_handler(const struct rte_flow_item *item,
 			  struct ulp_rte_parser_params *params);
 
+/* Function to handle the parsing of RTE Flow item ECPRI Header. */
+int32_t
+ulp_rte_ecpri_hdr_handler(const struct rte_flow_item *item,
+			  struct ulp_rte_parser_params *params);
+
 /* Function to handle the parsing of RTE Flow item void Header. */
 int32_t
 ulp_rte_void_hdr_handler(const struct rte_flow_item *item,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
index fb6fb3553b..9e11b3e305 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
@@ -29,6 +29,7 @@
 #define BNXT_ULP_PROTO_HDR_VXLAN_NUM	4
 #define BNXT_ULP_PROTO_HDR_GRE_NUM	2
 #define BNXT_ULP_PROTO_HDR_ICMP_NUM	5
+#define BNXT_ULP_PROTO_HDR_ECPRI_NUM	2
 #define BNXT_ULP_PROTO_HDR_MAX		128
 #define BNXT_ULP_PROTO_HDR_ENCAP_MAX	64
 #define BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX	1
@@ -364,6 +365,7 @@ struct bnxt_ulp_app_capabilities_info {
 	uint8_t				app_id;
 	uint32_t			vxlan_port;
 	uint32_t			vxlan_ip_port;
+	uint32_t			ecpri_udp_port;
 	enum bnxt_ulp_device_id		device_id;
 	uint32_t			upgrade_fw_update;
 	uint8_t				ha_pool_id;
-- 
2.39.2 (Apple Git-143)


--0000000000005f91a305fae19d42
Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature

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
pZEyqKnwS1lKCzjX7mV5W955rFsFxChdAKfw0HilwtqdY24mhy62+GeaEkD0gYIj1tCmw9gnQToc
K+0s7xEunfR9pBrzmOwS3OQbcP0nJ8SmQ8R+reroH6LYuFpaqK1rgQIDAQABo4IB2zCCAdcwDgYD
VR0PAQH/BAQDAgWgMIGjBggrBgEFBQcBAQSBljCBkzBOBggrBgEFBQcwAoZCaHR0cDovL3NlY3Vy
ZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQvZ3NnY2NyM3BlcnNvbmFsc2lnbjJjYTIwMjAuY3J0MEEG
CCsGAQUFBzABhjVodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9nc2djY3IzcGVyc29uYWxzaWdu
MmNhMjAyMDBNBgNVHSAERjBEMEIGCisGAQQBoDIBKAowNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93
d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCQYDVR0TBAIwADBJBgNVHR8EQjBAMD6gPKA6
hjhodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjNwZXJzb25hbHNpZ24yY2EyMDIwLmNy
bDAlBgNVHREEHjAcgRphaml0LmtoYXBhcmRlQGJyb2FkY29tLmNvbTATBgNVHSUEDDAKBggrBgEF
BQcDBDAfBgNVHSMEGDAWgBSWM9HmWBdbNHWKgVZk1b5I3qGPzzAdBgNVHQ4EFgQUbrcTuh0mr2qP
xYdtyDgFeRIiE/gwDQYJKoZIhvcNAQELBQADggEBALrc1TljKrDhXicOaZlzIQyqOEkKAZ324i8X
OwzA0n2EcPGmMZvgARurvanSLD3mLeeuyq1feCcjfGM1CJFh4+EY7EkbFbpVPOIdstSBhbnAJnOl
aC/q0wTndKoC/xXBhXOZB8YL/Zq4ZclQLMUO6xi/fFRyHviI5/IrosdrpniXFJ9ukJoOXtvdrEF+
KlMYg/Deg9xo3wddCqQIsztHSkR4XaANdn+dbLRQpctZ13BY1lim4uz5bYn3M0IxyZWkQ1JuPHCK
aRJv0SfR88PoI4RB7NCEHqFwARTj1KvFPQi8pK/YISFydZYbZrxQdyWDidqm4wSuJfpE6i0cWvCd
u50xggJtMIICaQIBATBrMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNh
MTEwLwYDVQQDEyhHbG9iYWxTaWduIEdDQyBSMyBQZXJzb25hbFNpZ24gMiBDQSAyMDIwAgwM2Vrj
4nZK0WWosNswDQYJYIZIAWUDBAIBBQCggdQwLwYJKoZIhvcNAQkEMSIEIKh/cYHKGyatLUUeybFx
m7kgNudZBNm92duQSZp9OYx+MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkF
MQ8XDTIzMDUwNDE3MzYzOFowaQYJKoZIhvcNAQkPMVwwWjALBglghkgBZQMEASowCwYJYIZIAWUD
BAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzALBgkqhkiG9w0BAQowCwYJKoZIhvcNAQEHMAsG
CWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQARu6Tq0CNp2iaHOEscismunWHfkadHy/snEoST
llSJKJ2/2yReJkxxmBqsbV9ApyP2ikzowArF2whsg8Vava1xeaRnbB0diLPcQPAeRiqIsgtxuKAA
5X8GwEPPFUUcx1N9y8F7VqnQgYI+nJh8tyYjKu56I4Am7lB66yVCpcTkgi0A/2nXKj94nCtpovBP
NcQ5Ft+gIT/0dQov3m0hg2R7yMtbYA5qnrAwoJasYH451l5bTAcZkxAG0iEiGyzpDkdAL7VBCA8l
s3CZm3zijLd2rpEsl2lGYNz2tA4pXdoHEaCmCoWjj+GCXGQjpC7Ylm0GUBBfhqaDh4msM8Ept94w
--0000000000005f91a305fae19d42--