All of lore.kernel.org
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 00/10] bnxt patches
@ 2020-07-13  6:15 Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
                   ` (11 more replies)
  0 siblings, 12 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>

Minor enhancements to the TF-ULP/Core layers

Farah Smith (1):
  net/bnxt: add changes to support 2 table scopes

Jay Ding (2):
  net/bnxt: implement TF Identifier search
  net/bnxt: check index range in bulk get

Kishore Padmanabha (6):
  net/bnxt: add support to extract data from the ulp blob
  net/bnxt: ignore ipv4 tos mask
  net/bnxt: add support for identifier search and ref count
  net/bnxt: consider vlan fields for the template match criteria
  net/bnxt: increase the number of egress flow entries
  net/bnxt: add support for decrement ttl action

Peter Spreadborough (1):
  net/bnxt: add option to delay EEM sysmem mapping

 drivers/net/bnxt/meson.build                    |   3 +-
 drivers/net/bnxt/tf_core/Makefile               |   1 +
 drivers/net/bnxt/tf_core/tf_core.c              |  78 +++++++-
 drivers/net/bnxt/tf_core/tf_core.h              |  78 +++++++-
 drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
 drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
 drivers/net/bnxt/tf_core/tf_em.h                |  11 ++
 drivers/net/bnxt/tf_core/tf_em_common.c         | 145 ++++++++++++++-
 drivers/net/bnxt/tf_core/tf_em_common.h         |  27 ++-
 drivers/net/bnxt/tf_core/tf_em_host.c           |  23 +--
 drivers/net/bnxt/tf_core/tf_em_internal.c       |   2 +-
 drivers/net/bnxt/tf_core/tf_em_system.c         |  25 +--
 drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
 drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
 drivers/net/bnxt/tf_core/tf_msg.c               |   3 +-
 drivers/net/bnxt/tf_core/tf_rm.c                |  43 +++++
 drivers/net/bnxt/tf_core/tf_rm.h                |  45 +++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tbl.c               |  40 ++---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c              |   2 +-
 drivers/net/bnxt/tf_ulp/ulp_mapper.c            | 117 +++++++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c        |  74 +++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h        |   5 +
 drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c   |   4 +-
 drivers/net/bnxt/tf_ulp/ulp_utils.c             |  76 ++++++++
 drivers/net/bnxt/tf_ulp/ulp_utils.h             |  17 ++
 27 files changed, 1367 insertions(+), 88 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h

-- 
2.7.4


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

* [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Peter Spreadborough <peter.spreadborough@broadcom.com>

- The mapping of kernel pages for EEM sysmem operation takes
  a significant amount of time. This change give the build option
  to delay the sysmem mapping until the first write to EEM

Signed-off-by: Peter Spreadborough <peter.spreadborough@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.c        | 17 +++++++++++--
 drivers/net/bnxt/tf_core/tf_em.h          | 11 +++++++++
 drivers/net/bnxt/tf_core/tf_em_common.c   | 41 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_em_internal.c |  2 +-
 drivers/net/bnxt/tf_core/tf_em_system.c   |  6 +++--
 5 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 00b2775..a404cb8 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -49,9 +49,22 @@ tf_open_session(struct tf *tfp,
 		    &slot,
 		    &device);
 	if (rc != 4) {
-		TFP_DRV_LOG(ERR,
+		/* PCI Domain not provided (optional in DPDK), thus we
+		 * force domain to 0 and recheck.
+		 */
+		domain = 0;
+
+		/* Check parsing of bus/slot/device */
+		rc = sscanf(parms->ctrl_chan_name,
+			    "%x:%x.%d",
+			    &bus,
+			    &slot,
+			    &device);
+		if (rc != 3) {
+			TFP_DRV_LOG(ERR,
 			    "Failed to scan device ctrl_chan_name\n");
-		return -EINVAL;
+			return -EINVAL;
+		}
 	}
 
 	parms->session_id.internal.domain = domain;
diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h
index 0890261..ae2e64d 100644
--- a/drivers/net/bnxt/tf_core/tf_em.h
+++ b/drivers/net/bnxt/tf_core/tf_em.h
@@ -9,6 +9,16 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
+#ifdef TF_USE_SYSTEM_MEM
+/**
+ * Select EEM sysmem mmap export to be done at init
+ * or on the first write to EEM.
+ */
+#define TF_EM_SYSMEM_DELAY_EXPORT 1
+#else
+#define TF_EM_SYSMEM_DELAY_EXPORT 0
+#endif
+
 #define SUPPORT_CFA_HW_P4 1
 #define SUPPORT_CFA_HW_P58 0
 #define SUPPORT_CFA_HW_P59 0
@@ -482,4 +492,5 @@ int
 tf_em_ext_system_bind(struct tf *tfp,
 		      struct tf_em_cfg_parms *parms);
 
+int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb);
 #endif /* _TF_EM_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 8b02b8b..65b9abf 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -700,6 +700,26 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
 	uint64_t big_hash;
 	int rc;
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 1)
+	if (!tbl_scope_cb->valid) {
+		rc = offload_system_mmap(tbl_scope_cb);
+
+		if (rc) {
+			struct tf_rm_free_parms fparms = { 0 };
+
+			TFP_DRV_LOG(ERR,
+				    "System alloc mmap failed\n");
+			/* Free Table control block */
+			fparms.rm_db = eem_db[TF_DIR_RX];
+			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+			fparms.index = parms->tbl_scope_id;
+			tf_rm_free(&fparms);
+			return -EINVAL;
+		}
+
+		tbl_scope_cb->valid = true;
+	}
+#endif
 	/* Get mask to use on hash */
 	mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
 
@@ -1017,6 +1037,27 @@ int tf_tbl_ext_common_set(struct tf *tfp,
 		return -EINVAL;
 	}
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 1)
+	if (!tbl_scope_cb->valid) {
+		rc = offload_system_mmap(tbl_scope_cb);
+
+		if (rc) {
+			struct tf_rm_free_parms fparms = { 0 };
+
+			TFP_DRV_LOG(ERR,
+				    "System alloc mmap failed\n");
+			/* Free Table control block */
+			fparms.rm_db = eem_db[TF_DIR_RX];
+			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+			fparms.index = parms->tbl_scope_id;
+			tf_rm_free(&fparms);
+			return -EINVAL;
+		}
+
+		tbl_scope_cb->valid = true;
+	}
+#endif
+
 	op.opcode = HCAPI_CFA_HWOPS_PUT;
 	key_tbl.base0 =
 		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_RECORD_TABLE];
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
index 3129fbe..462d0fa 100644
--- a/drivers/net/bnxt/tf_core/tf_em_internal.c
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -179,7 +179,7 @@ tf_em_insert_int_entry(struct tf *tfp,
 		return -1;
 
 	PMD_DRV_LOG
-		  (ERR,
+		  (DEBUG,
 		   "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
 		   tf_dir_2_str(parms->dir),
 		   index,
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
index 339392c..1c3c702 100644
--- a/drivers/net/bnxt/tf_core/tf_em_system.c
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -272,8 +272,7 @@ tf_prepare_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)
 	return 0;
 }
 
-static int
-offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
+int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
 {
 	int rc;
 	int dmabuf_fd;
@@ -455,6 +454,7 @@ tf_em_ext_alloc(struct tf *tfp,
 		}
 	}
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 0)
 	rc = offload_system_mmap(tbl_scope_cb);
 
 	if (rc) {
@@ -462,6 +462,7 @@ tf_em_ext_alloc(struct tf *tfp,
 			    "System alloc mmap failed\n");
 		goto cleanup_full;
 	}
+#endif
 
 	return rc;
 
@@ -527,6 +528,7 @@ tf_em_ext_free(struct tf *tfp,
 	}
 
 	tf_dmabuf_free(tfp, tbl_scope_cb);
+	tbl_scope_cb->valid = false;
 
 	return rc;
 }
-- 
2.7.4


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

* [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Jay Ding <jay.ding@broadcom.com>

Implement shadow copy DB to hold reference count for
each ID in each identifier type. Implement identifier
search functionality.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/meson.build                    |   3 +-
 drivers/net/bnxt/tf_core/Makefile               |   1 +
 drivers/net/bnxt/tf_core/tf_core.c              |  61 +++++++
 drivers/net/bnxt/tf_core/tf_core.h              |  70 +++++++-
 drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
 drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
 drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
 drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
 drivers/net/bnxt/tf_core/tf_rm.c                |   2 +
 drivers/net/bnxt/tf_core/tf_rm.h                |   8 +
 drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
 12 files changed, 777 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h

diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index 0b93c31..8529b33 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -46,7 +46,7 @@ sources = files('bnxt_cpr.c',
 	'tf_core/ll.c',
 	'tf_core/tf_global_cfg.c',
 	'tf_core/tf_em_host.c',
-	'tf_ulp/ulp_fc_mgr.c',
+	'tf_core/tf_shadow_identifier.c',
 
 	'hcapi/hcapi_cfa_p4.c',
 
@@ -63,6 +63,7 @@ sources = files('bnxt_cpr.c',
 	'tf_ulp/bnxt_ulp_flow.c',
 	'tf_ulp/ulp_port_db.c',
 	'tf_ulp/ulp_def_rules.c',
+	'tf_ulp/ulp_fc_mgr.c',
 
 	'rte_pmd_bnxt.c')
 
diff --git a/drivers/net/bnxt/tf_core/Makefile b/drivers/net/bnxt/tf_core/Makefile
index 8064714..9c2735d 100644
--- a/drivers/net/bnxt/tf_core/Makefile
+++ b/drivers/net/bnxt/tf_core/Makefile
@@ -31,3 +31,4 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tcam.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_util.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_if_tbl.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_global_cfg.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_shadow_identifier.c
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index a404cb8..97e7952 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -534,6 +534,7 @@ tf_free_identifier(struct tf *tfp,
 	fparms.dir = parms->dir;
 	fparms.type = parms->ident_type;
 	fparms.id = parms->id;
+	fparms.ref_cnt = &parms->ref_cnt;
 	rc = dev->ops->tf_dev_free_ident(tfp, &fparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -547,6 +548,66 @@ tf_free_identifier(struct tf *tfp,
 }
 
 int
+tf_search_identifier(struct tf *tfp,
+		     struct tf_search_identifier_parms *parms)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_ident_search_parms sparms;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Can't do static initialization due to UT enum check */
+	memset(&sparms, 0, sizeof(struct tf_ident_search_parms));
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_search_ident == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	sparms.dir = parms->dir;
+	sparms.type = parms->ident_type;
+	sparms.search_id = parms->search_id;
+	sparms.hit = &parms->hit;
+	sparms.ref_cnt = &parms->ref_cnt;
+	rc = dev->ops->tf_dev_search_ident(tfp, &sparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Identifier search failed, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	return 0;
+}
+
+int
 tf_alloc_tcam_entry(struct tf *tfp,
 		    struct tf_alloc_tcam_entry_parms *parms)
 {
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 9e80426..9a5e816 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -695,9 +695,9 @@ struct tf_alloc_identifier_parms {
 	 */
 	enum tf_identifier_type ident_type;
 	/**
-	 * [out] Identifier allocated
+	 * [out] Allocated identifier
 	 */
-	uint16_t id;
+	uint32_t id;
 };
 
 /**
@@ -715,7 +715,38 @@ struct tf_free_identifier_parms {
 	/**
 	 * [in] ID to free
 	 */
-	uint16_t id;
+	uint32_t id;
+	/**
+	 * (experimental)
+	 * [out] Current refcnt after free
+	 */
+	uint32_t ref_cnt;
+};
+
+/**
+ * tf_search_identifier parameter definition (experimental)
+ */
+struct tf_search_identifier_parms {
+	/**
+	 * [in]	 receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type ident_type;
+	/**
+	 * [in] Identifier data to search for
+	 */
+	uint32_t search_id;
+	/**
+	 * [out] Set if matching identifier found
+	 */
+	bool hit;
+	/**
+	 * [out] Current ref count after allocation
+	 */
+	uint32_t ref_cnt;
 };
 
 /**
@@ -724,6 +755,9 @@ struct tf_free_identifier_parms {
  * TruFlow core will allocate a free id from the per identifier resource type
  * pool reserved for the session during tf_open().  No firmware is involved.
  *
+ * If shadow copy is enabled, the internal ref_cnt is set to 1 in the
+ * shadow table for a newly allocated resource.
+ *
  * Returns success or failure code.
  */
 int tf_alloc_identifier(struct tf *tfp,
@@ -736,12 +770,42 @@ int tf_alloc_identifier(struct tf *tfp,
  * reserved for the session.  No firmware is involved.  During tf_close, the
  * complete pool is returned to the firmware.
  *
+ * additional operation (experimental)
+ * Decrement reference count.  Only release resource once refcnt goes to 0 if
+ * shadow copy is enabled.
+ *
  * Returns success or failure code.
  */
 int tf_free_identifier(struct tf *tfp,
 		       struct tf_free_identifier_parms *parms);
 
 /**
+ * Search identifier resource (experimental)
+ *
+ * If the shadow copy is enabled search_id is used to search for a matching
+ * entry in the shadow table.  The shadow table consists of an array of
+ * reference counts indexed by identifier.  If a matching entry is found hit is
+ * set to TRUE, refcnt is increased by 1 and returned.  Otherwise, hit is
+ * set to false and refcnt is set to 0.
+ *
+ * TODO: we may need a per table internal shadow copy enable flag to stage
+ * the shadow table implementation.  We do not need the shadow table for other
+ * tables at this time so we may only want to enable the identifier shadow.
+ *
+ * TODO: remove this pseudocode below added to show that if search fails
+ * we shouldn't allocate a new entry but return.
+ *
+ * identifier alloc (search_en=1)
+ * if (ident is allocated and ref_cnt >=1)
+ *      return ident - hit is set, incr refcnt
+ * else (not found)
+ *      return
+ *
+ */
+int tf_search_identifier(struct tf *tfp,
+			 struct tf_search_identifier_parms *parms);
+
+/**
  * @page dram_table DRAM Table Scope Interface
  *
  * @ref tf_alloc_tbl_scope
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 0bc7090..fce7f25 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -199,6 +199,26 @@ struct tf_dev_ops {
 				 struct tf_ident_free_parms *parms);
 
 	/**
+	 * Search of an identifier element.
+	 *
+	 * This API search the specified identifier element from a
+	 * device specific identifier shadow DB. The allocated element
+	 * is returned.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to identifier search parameters
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_search_ident)(struct tf *tfp,
+				   struct tf_ident_search_parms *parms);
+
+	/**
 	 * Allocation of a table type element.
 	 *
 	 * This API allocates the specified table type element from a
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index dfe626c..f38c38e 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -86,6 +86,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = NULL,
 	.tf_dev_free_ident = NULL,
+	.tf_dev_search_ident = NULL,
 	.tf_dev_alloc_ext_tbl = NULL,
 	.tf_dev_alloc_tbl = NULL,
 	.tf_dev_free_ext_tbl = NULL,
@@ -120,6 +121,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = tf_ident_alloc,
 	.tf_dev_free_ident = tf_ident_free,
+	.tf_dev_search_ident = tf_ident_search,
 	.tf_dev_alloc_tbl = tf_tbl_alloc,
 	.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,
 	.tf_dev_free_tbl = tf_tbl_free,
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index 90aeaa4..273d629 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -6,6 +6,7 @@
 #include <rte_common.h>
 
 #include "tf_identifier.h"
+#include "tf_shadow_identifier.h"
 #include "tf_common.h"
 #include "tf_rm.h"
 #include "tf_util.h"
@@ -23,6 +24,16 @@ static void *ident_db[TF_DIR_MAX];
  */
 static uint8_t init;
 
+/**
+ * Identifier shadow DBs.
+ */
+static void *ident_shadow_db[TF_DIR_MAX];
+
+/**
+ * Shadow DB Init flag, set on bind and cleared on unbind
+ */
+static uint8_t shadow_init;
+
 int
 tf_ident_bind(struct tf *tfp,
 	      struct tf_ident_cfg_parms *parms)
@@ -30,6 +41,8 @@ tf_ident_bind(struct tf *tfp,
 	int rc;
 	int i;
 	struct tf_rm_create_db_parms db_cfg = { 0 };
+	struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 };
+	struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -55,6 +68,23 @@ tf_ident_bind(struct tf *tfp,
 
 			return rc;
 		}
+
+		if (parms->shadow_copy) {
+			shadow_cfg.alloc_cnt =
+				parms->resources->ident_cnt[i].cnt;
+			shadow_cdb.num_elements = parms->num_elements;
+			shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i];
+			shadow_cdb.cfg = &shadow_cfg;
+			rc = tf_shadow_ident_create_db(&shadow_cdb);
+			if (rc) {
+				TFP_DRV_LOG(ERR,
+				    "%s: Ident shadow DB creation failed\n",
+				    tf_dir_2_str(i));
+
+				return rc;
+			}
+			shadow_init = 1;
+		}
 	}
 
 	init = 1;
@@ -71,6 +101,7 @@ tf_ident_unbind(struct tf *tfp)
 	int rc = 0;
 	int i;
 	struct tf_rm_free_db_parms fparms = { 0 };
+	struct tf_shadow_ident_free_db_parms sparms = { 0 };
 
 	TF_CHECK_PARMS1(tfp);
 
@@ -89,10 +120,22 @@ tf_ident_unbind(struct tf *tfp)
 			TFP_DRV_LOG(ERR,
 				    "rm free failed on unbind\n");
 		}
+		if (shadow_init) {
+			sparms.tf_shadow_ident_db = ident_shadow_db[i];
+			rc = tf_shadow_ident_free_db(&sparms);
+			if (rc) {
+				/* TODO: If there are failures on unbind we
+				 * really just have to try until all DBs are
+				 * attempted to be cleared.
+				 */
+			}
+			ident_shadow_db[i] = NULL;
+		}
 		ident_db[i] = NULL;
 	}
 
 	init = 0;
+	shadow_init = 0;
 
 	return 0;
 }
@@ -103,7 +146,9 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 {
 	int rc;
 	uint32_t id;
+	uint32_t base_id;
 	struct tf_rm_allocate_parms aparms = { 0 };
+	struct tf_shadow_ident_insert_parms iparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -118,6 +163,7 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 	aparms.rm_db = ident_db[parms->dir];
 	aparms.db_index = parms->type;
 	aparms.index = &id;
+	aparms.base_index = &base_id;
 	rc = tf_rm_allocate(&aparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -127,6 +173,21 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 		return rc;
 	}
 
+	if (shadow_init) {
+		iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+		iparms.type = parms->type;
+		iparms.id = base_id;
+
+		rc = tf_shadow_ident_insert(&iparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Failed insert shadow DB, type:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    parms->type);
+			return rc;
+		}
+	}
+
 	*parms->id = id;
 
 	return 0;
@@ -139,7 +200,9 @@ tf_ident_free(struct tf *tfp __rte_unused,
 	int rc;
 	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_free_parms fparms = { 0 };
+	struct tf_shadow_ident_remove_parms rparms = { 0 };
 	int allocated = 0;
+	uint32_t base_id;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -154,6 +217,7 @@ tf_ident_free(struct tf *tfp __rte_unused,
 	aparms.rm_db = ident_db[parms->dir];
 	aparms.db_index = parms->type;
 	aparms.index = parms->id;
+	aparms.base_index = &base_id;
 	aparms.allocated = &allocated;
 	rc = tf_rm_is_allocated(&aparms);
 	if (rc)
@@ -168,6 +232,27 @@ tf_ident_free(struct tf *tfp __rte_unused,
 		return -EINVAL;
 	}
 
+	if (shadow_init) {
+		rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+		rparms.type = parms->type;
+		rparms.id = base_id;
+		rparms.ref_cnt = parms->ref_cnt;
+
+		rc = tf_shadow_ident_remove(&rparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: ref_cnt was 0 in shadow DB,"
+				    " type:%d, index:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    parms->type,
+				    parms->id);
+			return rc;
+		}
+
+		if (*rparms.ref_cnt > 0)
+			return 0;
+	}
+
 	/* Free requested element */
 	fparms.rm_db = ident_db[parms->dir];
 	fparms.db_index = parms->type;
@@ -184,3 +269,66 @@ tf_ident_free(struct tf *tfp __rte_unused,
 
 	return 0;
 }
+
+int
+tf_ident_search(struct tf *tfp __rte_unused,
+		struct tf_ident_search_parms *parms)
+{
+	int rc;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_shadow_ident_search_parms sparms = { 0 };
+	int allocated = 0;
+	uint32_t base_id;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No Identifier DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	if (!shadow_init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Identifier Shadow copy is not enabled\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Check if element is in use */
+	aparms.rm_db = ident_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = parms->search_id;
+	aparms.base_index = &base_id;
+	aparms.allocated = &allocated;
+	rc = tf_rm_is_allocated(&aparms);
+	if (rc)
+		return rc;
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry not allocated, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->search_id);
+		return -EINVAL;
+	}
+
+	sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+	sparms.type = parms->type;
+	sparms.search_id = base_id;
+	sparms.hit = parms->hit;
+	sparms.ref_cnt = parms->ref_cnt;
+
+	rc = tf_shadow_ident_search(&sparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed search shadow DB, type:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type);
+		return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h
index 6e36c52..6d9fa08 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.h
+++ b/drivers/net/bnxt/tf_core/tf_identifier.h
@@ -66,6 +66,37 @@ struct tf_ident_free_parms {
 	 * [in] ID to free
 	 */
 	uint16_t id;
+	/**
+	 * (experimental)
+	 * [out] Current refcnt after free
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * Identifier search parameter definition
+ */
+struct tf_ident_search_parms {
+	/**
+	 * [in]  receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Identifier data to search for
+	 */
+	uint16_t search_id;
+	/**
+	 * [out] Set if matching identifier found
+	 */
+	bool *hit;
+	/**
+	 * [out] Current ref count after allocation
+	 */
+	uint32_t *ref_cnt;
 };
 
 /**
@@ -144,4 +175,20 @@ int tf_ident_alloc(struct tf *tfp,
 int tf_ident_free(struct tf *tfp,
 		  struct tf_ident_free_parms *parms);
 
+/**
+ * Search a single identifier type.
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_ident_search(struct tf *tfp,
+		    struct tf_ident_search_parms *parms);
+
 #endif /* _TF_IDENTIFIER_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index fdb87ec..78bc231 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -755,6 +755,7 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 	}
 
 	*parms->index = index;
+	*parms->base_index = id;
 
 	return rc;
 }
@@ -841,6 +842,7 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
 	if (rc)
 		return rc;
 
+	*parms->base_index = adj_index;
 	*parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
 				     adj_index);
 
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 775f0aa..971120a 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -204,6 +204,10 @@ struct tf_rm_allocate_parms {
 	 *              available index)
 	 */
 	uint32_t priority;
+	/**
+	 * [in] Pointer to the allocated index before adjusted.
+	 */
+	uint32_t *base_index;
 };
 
 /**
@@ -246,6 +250,10 @@ struct tf_rm_is_allocated_parms {
 	 * [in] Pointer to flag that indicates the state of the query
 	 */
 	int *allocated;
+	/**
+	 * [in] Pointer to the allocated index before adjusted.
+	 */
+	uint32_t *base_index;
 };
 
 /**
diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.c b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c
new file mode 100644
index 0000000..390d22f
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_common.h>
+
+#include "tf_shadow_identifier.h"
+#include "tf_common.h"
+#include "tf_util.h"
+#include "tfp.h"
+
+/**
+ * Shadow identifier DB element
+ */
+struct tf_shadow_ident_element {
+	/**
+	 * Identifier
+	 */
+	uint32_t *id;
+
+	/**
+	 * Reference count, array of number of identifier type entries
+	 */
+	uint32_t *ref_count;
+};
+
+/**
+ * Shadow identifier DB definition
+ */
+struct tf_shadow_ident_db {
+	/**
+	 * Number of elements in the DB
+	 */
+	uint16_t num_entries;
+
+	/**
+	 * The DB consists of an array of elements
+	 */
+	struct tf_shadow_ident_element *db;
+};
+
+int
+tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms)
+{
+	int rc;
+	int i;
+	struct tfp_calloc_parms cparms;
+	struct tf_shadow_ident_db *shadow_db;
+	struct tf_shadow_ident_element *db;
+
+	TF_CHECK_PARMS1(parms);
+
+	/* Build the shadow DB per the request */
+	cparms.nitems = 1;
+	cparms.size = sizeof(struct tf_shadow_ident_db);
+	cparms.alignment = 0;
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	shadow_db = (void *)cparms.mem_va;
+
+	/* Build the DB within shadow DB */
+	cparms.nitems = parms->num_elements;
+	cparms.size = sizeof(struct tf_shadow_ident_element);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	shadow_db->db = (struct tf_shadow_ident_element *)cparms.mem_va;
+	shadow_db->num_entries = parms->num_elements;
+
+	db = shadow_db->db;
+	for (i = 0; i < parms->num_elements; i++) {
+		/* If the element didn't request an allocation no need
+		 * to create a pool nor verify if we got a reservation.
+		 */
+		if (parms->cfg->alloc_cnt[i] == 0)
+			continue;
+
+		/* Create array */
+		cparms.nitems = parms->cfg->alloc_cnt[i];
+		cparms.size = sizeof(uint32_t);
+		rc = tfp_calloc(&cparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Array alloc failed, type:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    i);
+			goto fail;
+		}
+		db[i].ref_count = (uint32_t *)cparms.mem_va;
+	}
+
+	*parms->tf_shadow_ident_db = (void *)shadow_db;
+
+	return 0;
+fail:
+	tfp_free((void *)db->ref_count);
+	tfp_free((void *)db);
+	tfp_free((void *)shadow_db);
+	parms->tf_shadow_ident_db = NULL;
+
+	return -EINVAL;
+}
+
+int
+tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms)
+{
+	int i;
+	struct tf_shadow_ident_db *shadow_db;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	for (i = 0; i < shadow_db->num_entries; i++)
+		tfp_free((void *)shadow_db->db[i].ref_count);
+
+	tfp_free((void *)shadow_db->db);
+	tfp_free((void *)parms->tf_shadow_ident_db);
+
+	return 0;
+}
+
+int
+tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+	uint32_t ref_cnt = 0;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	ref_cnt = shadow_db->db[parms->type].ref_count[parms->search_id];
+	if (ref_cnt > 0) {
+		*parms->hit = 1;
+		*parms->ref_cnt = ++ref_cnt;
+		shadow_db->db[parms->type].ref_count[parms->search_id] =
+								ref_cnt;
+	} else {
+		*parms->hit = 0;
+		*parms->ref_cnt = 0;
+	}
+
+
+	return 0;
+}
+
+#define ID_REF_CNT_MAX 0xffffffff
+int
+tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+
+	/* In case of overflow, ref count keeps the max value */
+	if (shadow_db->db[parms->type].ref_count[parms->id] < ID_REF_CNT_MAX)
+		shadow_db->db[parms->type].ref_count[parms->id]++;
+	else
+		TFP_DRV_LOG(ERR,
+			    "Identifier %d in type %d reaches the max ref_cnt\n",
+			    parms->type,
+			    parms->id);
+
+	parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+
+	return 0;
+}
+
+int
+tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+	uint32_t ref_cnt = 0;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+	if (ref_cnt > 0)
+		shadow_db->db[parms->type].ref_count[parms->id]--;
+	else
+		return -EINVAL;
+
+	*parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.h b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h
new file mode 100644
index 0000000..dd633af
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_SHADOW_IDENTIFIER_H_
+#define _TF_SHADOW_IDENTIFIER_H_
+
+#include "tf_core.h"
+
+struct tf;
+
+/**
+ * The Shadow Identifier module provides shadow DB handling for identifier based
+ * TF types. A shadow DB provides the capability that allows for reuse
+ * of TF resources.
+ *
+ * A Shadow identifier DB is intended to be used by the Identifier Type module
+ * only.
+ */
+
+/**
+ * Shadow DB configuration information for a single identifier type.
+ *
+ * It is used in an array of identifier types. The array must be ordered
+ * by the TF type is represents.
+ */
+struct tf_shadow_ident_cfg_parms {
+	/**
+	 * TF Identifier type
+	 */
+	enum tf_identifier_type type;
+
+	/**
+	 * Number of entries the Shadow DB needs to hold
+	 */
+	int num_entries;
+
+	/**
+	 * Resource allocation count array. This array content
+	 * originates from the tf_session_resources that is passed in
+	 * on session open.
+	 * Array size is num_elements.
+	 */
+	uint16_t *alloc_cnt;
+};
+
+/**
+ * Shadow identifier DB creation parameters
+ */
+struct tf_shadow_ident_create_db_parms {
+	/**
+	 * [in] Receive or transmit direction.
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Configuration information for the shadow db
+	 */
+	struct tf_shadow_ident_cfg_parms *cfg;
+	/**
+	 * [in] Number of elements in the parms structure
+	 */
+	uint16_t num_elements;
+	/**
+	 * [out] Shadow identifier DB handle
+	 */
+	void **tf_shadow_ident_db;
+};
+
+/**
+ * Shadow identifier DB free parameters
+ */
+struct tf_shadow_ident_free_db_parms {
+	/**
+	 * Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+};
+
+/**
+ * Shadow identifier search parameters
+ */
+struct tf_shadow_ident_search_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] id to search
+	 */
+	uint16_t search_id;
+	/**
+	 * [out] Index of the found element returned if hit
+	 */
+	bool *hit;
+	/**
+	 * [out] Reference count incremented if hit
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * Shadow identifier insert parameters
+ */
+struct tf_shadow_ident_insert_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Tbl type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Entry to update
+	 */
+	uint16_t id;
+	/**
+	 * [out] Reference count after insert
+	 */
+	uint32_t ref_cnt;
+};
+
+/**
+ * Shadow identifier remove parameters
+ */
+struct tf_shadow_ident_remove_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Tbl type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Entry to update
+	 */
+	uint16_t id;
+	/**
+	 * [out] Reference count after removal
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * @page shadow_ident Shadow identifier DB
+ *
+ * @ref tf_shadow_ident_create_db
+ *
+ * @ref tf_shadow_ident_free_db
+ *
+ * @reg tf_shadow_ident_search
+ *
+ * @reg tf_shadow_ident_insert
+ *
+ * @reg tf_shadow_ident_remove
+ */
+
+/**
+ * Creates and fills a Shadow identifier DB. The DB is indexed per the
+ * parms structure.
+ *
+ * [in] parms
+ *   Pointer to create db parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms);
+
+/**
+ * Closes the Shadow identifier DB and frees all allocated
+ * resources per the associated database.
+ *
+ * [in] parms
+ *   Pointer to the free DB parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms);
+
+/**
+ * Search Shadow identifier db for matching result
+ *
+ * [in] parms
+ *   Pointer to the search parameters
+ *
+ * Returns
+ *   - (0) if successful, element was found.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms);
+
+/**
+ * Inserts an element into the Shadow identifier DB. Ref_count after insert
+ * will be incremented.
+ *
+ * [in] parms
+ *   Pointer to insert parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms);
+
+/**
+ * Removes an element from the Shadow identifier DB. Will fail if the
+ * elements ref_count is 0. Ref_count after removal will be
+ * decremented.
+ *
+ * [in] parms
+ *   Pointer to remove parameter
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms);
+
+#endif /* _TF_SHADOW_IDENTIFIER_H_ */
-- 
2.7.4


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

* [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Jay Ding <jay.ding@broadcom.com>

In tf_tbl_bulk_get, check if the indexes are in the range
of reserved tbl id instead of checking the allocation of each id.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.h |  8 ++++---
 drivers/net/bnxt/tf_core/tf_msg.c  |  3 ++-
 drivers/net/bnxt/tf_core/tf_rm.c   | 45 ++++++++++++++++++++++++++++++++++++--
 drivers/net/bnxt/tf_core/tf_rm.h   | 37 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tbl.c  | 40 ++++++++++++++-------------------
 5 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 9a5e816..758685e 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -1426,10 +1426,12 @@ struct tf_bulk_get_tbl_entry_parms {
 /**
  * Bulk get index table entry
  *
- * Used to retrieve a previous set index table entry.
+ * Used to retrieve a set of index table entries.
  *
- * Reads and compares with the shadow table copy (if enabled) (only
- * for internal objects).
+ * Entries within the range may not have been allocated using
+ * tf_alloc_tbl_entry() at the time of access. But the range must
+ * be within the bounds determined from tf_open_session() for the
+ * given table type.  Currently, this is only used for collecting statistics.
  *
  * Returns success or failure code. Failure will be returned if the
  * provided data buffer is too small for the data type requested.
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index 1e14d92..53515ad 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -143,7 +143,8 @@ tf_msg_session_open(struct tf *tfp,
 		return rc;
 
 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
-	*fw_session_client_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
+	*fw_session_client_id =
+		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
 
 	return rc;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index 78bc231..9aec954 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -755,7 +755,8 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 	}
 
 	*parms->index = index;
-	*parms->base_index = id;
+	if (parms->base_index)
+		*parms->base_index = id;
 
 	return rc;
 }
@@ -842,7 +843,8 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
 	if (rc)
 		return rc;
 
-	*parms->base_index = adj_index;
+	if (parms->base_index)
+		*parms->base_index = adj_index;
 	*parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
 				     adj_index);
 
@@ -922,3 +924,42 @@ tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
 	return rc;
 
 }
+
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms)
+{
+	struct tf_rm_new_db *rm_db;
+	enum tf_rm_elem_cfg_type cfg_type;
+	uint32_t base_index;
+	uint32_t stride;
+	int rc = 0;
+
+	TF_CHECK_PARMS2(parms, parms->rm_db);
+
+	rm_db = (struct tf_rm_new_db *)parms->rm_db;
+	cfg_type = rm_db->db[parms->db_index].cfg_type;
+
+	/* Bail out if not controlled by RM */
+	if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
+		return -ENOTSUP;
+
+	/* Bail out if the pool is not valid, should never happen */
+	if (rm_db->db[parms->db_index].pool == NULL) {
+		rc = -ENOTSUP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Invalid pool for this type:%d, rc:%s\n",
+			    tf_dir_2_str(rm_db->dir),
+			    parms->db_index,
+			    strerror(-rc));
+		return rc;
+	}
+
+	base_index = rm_db->db[parms->db_index].alloc.entry.start;
+	stride = rm_db->db[parms->db_index].alloc.entry.stride;
+
+	if (parms->starting_index < base_index ||
+	    parms->starting_index + parms->num_entries > base_index + stride)
+		return -EINVAL;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 971120a..97692db 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -315,6 +315,29 @@ struct tf_rm_get_inuse_count_parms {
 };
 
 /**
+ * Check if the indexes are in the range of reserved resource
+ */
+struct tf_rm_check_indexes_in_range_parms {
+	/**
+	 * [in] RM DB Handle
+	 */
+	void *rm_db;
+	/**
+	 * [in] DB Index, indicates which DB entry to perform the
+	 * action on.
+	 */
+	uint16_t db_index;
+	/**
+	 * [in] Starting index
+	 */
+	uint16_t starting_index;
+	/**
+	 * [in] number of entries
+	 */
+	uint16_t num_entries;
+};
+
+/**
  * @page rm Resource Manager
  *
  * @ref tf_rm_create_db
@@ -462,4 +485,18 @@ int tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms);
  */
 int tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms);
 
+/**
+ * Check if the requested indexes are in the range of reserved resource.
+ *
+ * [in] parms
+ *   Pointer to get inuse parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms);
+
+
 #endif /* TF_RM_NEW_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index 2b4a7c5..9ebaa34 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -350,12 +350,9 @@ tf_tbl_bulk_get(struct tf *tfp,
 		struct tf_tbl_get_bulk_parms *parms)
 {
 	int rc;
-	int i;
 	uint16_t hcapi_type;
-	uint32_t idx;
-	int allocated = 0;
-	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_get_hcapi_parms hparms = { 0 };
+	struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -366,26 +363,23 @@ tf_tbl_bulk_get(struct tf *tfp,
 
 		return -EINVAL;
 	}
-	/* Verify that the entries has been previously allocated */
-	aparms.rm_db = tbl_db[parms->dir];
-	aparms.db_index = parms->type;
-	aparms.allocated = &allocated;
-	idx = parms->starting_idx;
-	for (i = 0; i < parms->num_entries; i++) {
-		aparms.index = idx;
-		rc = tf_rm_is_allocated(&aparms);
-		if (rc)
-			return rc;
 
-		if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
-			TFP_DRV_LOG(ERR,
-				    "%s, Invalid or not allocated index, type:%d, idx:%d\n",
-				    tf_dir_2_str(parms->dir),
-				    parms->type,
-				    idx);
-			return -EINVAL;
-		}
-		idx++;
+	/* Verify that the entries are in the range of reserved resources. */
+	cparms.rm_db = tbl_db[parms->dir];
+	cparms.db_index = parms->type;
+	cparms.starting_index = parms->starting_idx;
+	cparms.num_entries = parms->num_entries;
+
+	rc = tf_rm_check_indexes_in_range(&cparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s, Invalid or %d index starting from %d"
+			    " not in range, type:%d",
+			    tf_dir_2_str(parms->dir),
+			    parms->starting_idx,
+			    parms->num_entries,
+			    parms->type);
+		return rc;
 	}
 
 	hparms.rm_db = tbl_db[parms->dir];
-- 
2.7.4


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

* [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (2 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Farah Smith <farah.smith@broadcom.com>

Need to remap the table scope ids allocated from HCAPI RM from high
to low value because for legacy devices a table scope is a set of base
addresses.  The PCIe addresses must map to a PCIe PF which exists in
the hardware.

Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_em_common.c | 106 +++++++++++++++++++++++++++++++-
 drivers/net/bnxt/tf_core/tf_em_common.h |  27 +++++++-
 drivers/net/bnxt/tf_core/tf_em_host.c   |  23 ++-----
 drivers/net/bnxt/tf_core/tf_em_system.c |  19 +-----
 4 files changed, 137 insertions(+), 38 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 65b9abf..10c3f16 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -44,6 +44,28 @@ static enum tf_mem_type mem_type;
 /** Table scope array */
 struct tf_tbl_scope_cb tbl_scopes[TF_NUM_TBL_SCOPE];
 
+/** Table scope reversal table
+ *
+ * Table scope are allocated from 15 to 0 within HCAPI RM.  Because of the
+ * association between PFs and legacy table scopes, reverse table scope ids.
+ * 15 indicates 0, 14 indicates 1, etc... The application will only see the 0
+ * based number.  The firmware will only use the 0 based number.  Only HCAPI RM
+ * and Truflow RM believe the number is 15.  When HCAPI RM support allocation
+ * from low to high is supported, this adjust function can be removed.
+ */
+const uint32_t tbl_scope_reverse[TF_NUM_TBL_SCOPE] = {
+	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+static uint32_t
+tf_tbl_scope_adjust(uint32_t tbl_scope_id)
+{
+	if (tbl_scope_id < TF_NUM_TBL_SCOPE)
+		return tbl_scope_reverse[tbl_scope_id];
+	else
+		return TF_TBL_SCOPE_INVALID;
+};
+
+
 /* API defined in tf_em.h */
 struct tf_tbl_scope_cb *
 tbl_scope_cb_find(uint32_t tbl_scope_id)
@@ -51,11 +73,17 @@ tbl_scope_cb_find(uint32_t tbl_scope_id)
 	int i;
 	struct tf_rm_is_allocated_parms parms;
 	int allocated;
+	uint32_t rm_tbl_scope_id;
+
+	rm_tbl_scope_id = tf_tbl_scope_adjust(tbl_scope_id);
+
+	if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+		return NULL;
 
 	/* Check that id is valid */
 	parms.rm_db = eem_db[TF_DIR_RX];
 	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	parms.index = tbl_scope_id;
+	parms.index = rm_tbl_scope_id;
 	parms.allocated = &allocated;
 
 	i = tf_rm_is_allocated(&parms);
@@ -71,6 +99,61 @@ tbl_scope_cb_find(uint32_t tbl_scope_id)
 	return NULL;
 }
 
+int tf_tbl_scope_alloc(uint32_t *tbl_scope_id)
+{
+	int rc;
+	struct tf_rm_allocate_parms parms = { 0 };
+	uint32_t rm_tbl_scope_id;
+	uint32_t usr_tbl_scope_id = TF_TBL_SCOPE_INVALID;
+
+	/* Get Table Scope control block from the session pool */
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+	parms.index = &rm_tbl_scope_id;
+
+	rc = tf_rm_allocate(&parms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to allocate table scope rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	usr_tbl_scope_id = tf_tbl_scope_adjust(rm_tbl_scope_id);
+
+	if (usr_tbl_scope_id == TF_TBL_SCOPE_INVALID) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid table scope allocated id:%d\n",
+			    (int)rm_tbl_scope_id);
+		return -EINVAL;
+	}
+	*tbl_scope_id = usr_tbl_scope_id;
+	return 0;
+};
+
+int tf_tbl_scope_free(uint32_t tbl_scope_id)
+{
+	struct tf_rm_free_parms parms = { 0 };
+	uint32_t rm_tbl_scope_id;
+	uint32_t rc;
+
+	rm_tbl_scope_id = tf_tbl_scope_adjust(tbl_scope_id);
+
+	if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid table scope allocated id:%d\n",
+			    (int)tbl_scope_id);
+		return -EINVAL;
+	}
+
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+	parms.index = rm_tbl_scope_id;
+
+	rc = tf_rm_free(&parms);
+	return rc;
+};
+
 int
 tf_create_tbl_pool_external(enum tf_dir dir,
 			    struct tf_tbl_scope_cb *tbl_scope_cb,
@@ -706,9 +789,17 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
 
 		if (rc) {
 			struct tf_rm_free_parms fparms = { 0 };
+			uint32_t rm_tbl_scope_id;
 
 			TFP_DRV_LOG(ERR,
 				    "System alloc mmap failed\n");
+
+			rm_tbl_scope_id =
+				tf_tbl_scope_adjust(parms->tbl_scope_id);
+
+			if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+				return -EINVAL;
+
 			/* Free Table control block */
 			fparms.rm_db = eem_db[TF_DIR_RX];
 			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
@@ -1043,13 +1134,24 @@ int tf_tbl_ext_common_set(struct tf *tfp,
 
 		if (rc) {
 			struct tf_rm_free_parms fparms = { 0 };
+			uint32_t rm_tbl_scope_id;
+
+			/* TODO: support allocation of table scope from
+			 * min in HCAPI RM.  For now call adjust function
+			 * on value obtained from RM.
+			 */
+			rm_tbl_scope_id =
+				tf_tbl_scope_adjust(parms->tbl_scope_id);
+
+			if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+				return -EINVAL;
 
 			TFP_DRV_LOG(ERR,
 				    "System alloc mmap failed\n");
 			/* Free Table control block */
 			fparms.rm_db = eem_db[TF_DIR_RX];
 			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-			fparms.index = parms->tbl_scope_id;
+			fparms.index = rm_tbl_scope_id;
 			tf_rm_free(&fparms);
 			return -EINVAL;
 		}
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.h b/drivers/net/bnxt/tf_core/tf_em_common.h
index fa313c4..f71a487 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.h
+++ b/drivers/net/bnxt/tf_core/tf_em_common.h
@@ -9,7 +9,6 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
-
 /**
  * Function to search for table scope control block structure
  * with specified table scope ID.
@@ -24,6 +23,32 @@
 struct tf_tbl_scope_cb *tbl_scope_cb_find(uint32_t tbl_scope_id);
 
 /**
+ * Table Scope Allocate
+ *
+ * Allocate a table scope
+ *
+ * [in/out] pointer to tbl_scope_id
+ *
+ * Returns:
+ *  0 - success
+ *  -EINVAL - error
+ */
+int tf_tbl_scope_alloc(uint32_t *tbl_scope_id);
+
+/**
+ * Table Scope Free
+ *
+ * Free a table scope
+ *
+ * [in] tbl_scope_id to free
+ *
+ * Returns:
+ *  0 - success
+ *  -EINVAL - error
+ */
+int tf_tbl_scope_free(uint32_t tbl_scope_id);
+
+/**
  * Create and initialize a stack to use for action entries
  *
  * [in] dir
diff --git a/drivers/net/bnxt/tf_core/tf_em_host.c b/drivers/net/bnxt/tf_core/tf_em_host.c
index b5db94f..cfcb12f 100644
--- a/drivers/net/bnxt/tf_core/tf_em_host.c
+++ b/drivers/net/bnxt/tf_core/tf_em_host.c
@@ -374,14 +374,8 @@ tf_em_ext_alloc(struct tf *tfp, struct tf_alloc_tbl_scope_parms *parms)
 	struct tf_tbl_scope_cb *tbl_scope_cb;
 	struct hcapi_cfa_em_table *em_tables;
 	struct tf_free_tbl_scope_parms free_parms;
-	struct tf_rm_allocate_parms aparms = { 0 };
-	struct tf_rm_free_parms fparms = { 0 };
-
-	/* Get Table Scope control block from the session pool */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = (uint32_t *)&parms->tbl_scope_id;
-	rc = tf_rm_allocate(&aparms);
+
+	rc = tf_tbl_scope_alloc(&parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to allocate table scope\n");
@@ -478,11 +472,7 @@ tf_em_ext_alloc(struct tf *tfp, struct tf_alloc_tbl_scope_parms *parms)
 	return -EINVAL;
 
 cleanup:
-	/* Free Table control block */
-	fparms.rm_db = eem_db[TF_DIR_RX];
-	fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	fparms.index = parms->tbl_scope_id;
-	tf_rm_free(&fparms);
+	tf_tbl_scope_free(parms->tbl_scope_id);
 	return -EINVAL;
 }
 
@@ -493,7 +483,6 @@ tf_em_ext_free(struct tf *tfp,
 	int rc = 0;
 	enum tf_dir  dir;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_rm_free_parms aparms = { 0 };
 
 	tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);
 
@@ -502,11 +491,7 @@ tf_em_ext_free(struct tf *tfp,
 		return -EINVAL;
 	}
 
-	/* Free Table control block */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = parms->tbl_scope_id;
-	rc = tf_rm_free(&aparms);
+	rc = tf_tbl_scope_free(parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to free table scope\n");
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
index 1c3c702..32ee1ee 100644
--- a/drivers/net/bnxt/tf_core/tf_em_system.c
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -364,9 +364,7 @@ tf_em_ext_alloc(struct tf *tfp,
 	int rc;
 	struct tf_session *tfs;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_rm_allocate_parms aparms = { 0 };
 	struct tf_free_tbl_scope_parms free_parms;
-	struct tf_rm_free_parms fparms = { 0 };
 	int dir;
 	int i;
 	struct hcapi_cfa_em_table *em_tables;
@@ -382,10 +380,7 @@ tf_em_ext_alloc(struct tf *tfp,
 		return rc;
 	}
 
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = (uint32_t *)&parms->tbl_scope_id;
-	rc = tf_rm_allocate(&aparms);
+	rc = tf_tbl_scope_alloc(&parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to allocate table scope\n");
@@ -473,10 +468,7 @@ tf_em_ext_alloc(struct tf *tfp,
 
 cleanup:
 	/* Free Table control block */
-	fparms.rm_db = eem_db[TF_DIR_RX];
-	fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	fparms.index = parms->tbl_scope_id;
-	tf_rm_free(&fparms);
+	tf_tbl_scope_free(parms->tbl_scope_id);
 	return -EINVAL;
 }
 
@@ -488,7 +480,6 @@ tf_em_ext_free(struct tf *tfp,
 	struct tf_session *tfs;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
 	int dir;
-	struct tf_rm_free_parms aparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -503,11 +494,7 @@ tf_em_ext_free(struct tf *tfp,
 
 	tbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];
 
-		/* Free Table control block */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = parms->tbl_scope_id;
-	rc = tf_rm_free(&aparms);
+	rc = tf_tbl_scope_free(parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to free table scope\n");
-- 
2.7.4


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

* [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (3 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 tos mask Somnath Kotur
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Extended the ulp blob to extract data from the blob for a given
offset and length. The support is added only for little endian
format.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_utils.c | 76 +++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_ulp/ulp_utils.h | 17 +++++++++
 2 files changed, 93 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.c b/drivers/net/bnxt/tf_ulp/ulp_utils.c
index 3afaac6..2b556b8 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_utils.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.c
@@ -418,6 +418,82 @@ ulp_blob_pad_push(struct ulp_blob *blob,
 	return datalen;
 }
 
+/* Get data from src and put into dst using little-endian format */
+static void
+ulp_bs_get_lsb(uint8_t *src, uint16_t bitpos, uint8_t bitlen, uint8_t *dst)
+{
+	uint8_t bitoffs = bitpos % ULP_BLOB_BYTE;
+	uint16_t index  = ULP_BITS_2_BYTE_NR(bitpos);
+	uint8_t mask, partial, shift;
+
+	shift = bitoffs;
+	partial = ULP_BLOB_BYTE - bitoffs;
+	if (bitoffs + bitlen <= ULP_BLOB_BYTE) {
+		mask = ((1 << bitlen) - 1) << shift;
+		*dst = (src[index] & mask) >> shift;
+	} else {
+		mask = ((1 << partial) - 1) << shift;
+		*dst = (src[index] & mask) >> shift;
+		index++;
+		partial = bitlen - partial;
+		mask = ((1 << partial) - 1);
+		*dst |= (src[index] & mask) << (ULP_BLOB_BYTE - bitoffs);
+	}
+}
+
+/* Assuming that src is in litte-Endian Format */
+static void
+ulp_bs_pull_lsb(uint8_t *src, uint8_t *dst, uint32_t size,
+		uint32_t offset, uint32_t len)
+{
+	uint32_t idx;
+	uint32_t cnt = ULP_BITS_2_BYTE_NR(len);
+
+	/* iterate bytewise to get data */
+	for (idx = 0; idx < cnt; idx++) {
+		ulp_bs_get_lsb(src, offset, ULP_BLOB_BYTE,
+			       &dst[size - 1 - idx]);
+		offset += ULP_BLOB_BYTE;
+		len -= ULP_BLOB_BYTE;
+	}
+
+	/* Extract the last reminder data that is not 8 byte boundary */
+	if (len)
+		ulp_bs_get_lsb(src, offset, len, &dst[size - 1 - idx]);
+}
+
+/*
+ * Extract data from the binary blob using given offset.
+ *
+ * blob [in] The blob that data is extracted from. The blob must
+ * be initialized prior to pulling data.
+ *
+ * data [in] A pointer to put the data.
+ * data_size [in] size of the data buffer in bytes.
+ *offset [in] - Offset in the blob to extract the data in bits format.
+ * len [in] The number of bits to be pulled from the blob.
+ *
+ * Output: zero on success, -1 on failure
+ */
+int32_t
+ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
+	      uint16_t offset, uint16_t len)
+{
+	/* validate the arguments */
+	if (!blob || (offset + len) > blob->bitlen ||
+	    ULP_BYTE_2_BITS(data_size) < len) {
+		BNXT_TF_DBG(ERR, "invalid argument\n");
+		return -1; /* failure */
+	}
+
+	if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE) {
+		BNXT_TF_DBG(ERR, "Big endian pull not implemented\n");
+		return -1; /* failure */
+	}
+	ulp_bs_pull_lsb(blob->data, data, data_size, offset, len);
+	return 0;
+}
+
 /*
  * Get the data portion of the binary blob.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.h b/drivers/net/bnxt/tf_ulp/ulp_utils.h
index 97c7750..22dfb17 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_utils.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.h
@@ -229,6 +229,23 @@ ulp_blob_data_get(struct ulp_blob *blob,
 		  uint16_t *datalen);
 
 /*
+ * Extract data from the binary blob using given offset.
+ *
+ * blob [in] The blob that data is extracted from. The blob must
+ * be initialized prior to pulling data.
+ *
+ * data [in] A pointer to put the data.
+ * data_size [in] size of the data buffer in bytes.
+ *offset [in] - Offset in the blob to extract the data in bits format.
+ * len [in] The number of bits to be pulled from the blob.
+ *
+ * Output: zero on success, -1 on failure
+ */
+int32_t
+ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
+	      uint16_t offset, uint16_t len);
+
+/*
  * Adds pad to an initialized blob at the current offset
  *
  * blob [in] The blob that data is added to.  The blob must
-- 
2.7.4


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

* [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 tos mask
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (4 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

This is a work around for the OVS setting offload rules that
are passing ipv4 tos mask as wild card and currently we do not
support.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index b943465..c9237b4 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -704,9 +704,19 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.version_ihl,
 				       sizeof(ipv4_mask->hdr.version_ihl));
+#ifdef ULP_DONT_IGNORE_TOS
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.type_of_service,
 				       sizeof(ipv4_mask->hdr.type_of_service));
+#else
+		/*
+		 * The tos field is ignored since OVS is seting it as wild card
+		 * match and it is not supported. This is a work around and
+		 * shall be addressed in the future.
+		 */
+		idx += 1;
+#endif
+
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.total_length,
 				       sizeof(ipv4_mask->hdr.total_length));
-- 
2.7.4


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

* [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (5 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 tos mask Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider vlan fields for the template match criteria Somnath Kotur
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Add support to search for identifiers and increase the reference
count for identifiers that are already allocated.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_mapper.c | 118 ++++++++++++++++++++++++++++++++++-
 1 file changed, 115 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 86858b8..157c451 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -677,6 +677,103 @@ ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms,
 	return rc;
 }
 
+/*
+ * Process the identifier instruction and extract it from result blob.
+ * Increment the identifier reference count and store it in the flow database.
+ */
+static int32_t
+ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,
+			 struct bnxt_ulp_mapper_tbl_info *tbl,
+			 struct bnxt_ulp_mapper_ident_info *ident,
+			 struct ulp_blob *res_blob)
+{
+	struct ulp_flow_db_res_params	fid_parms;
+	uint64_t id = 0;
+	uint32_t idx;
+	struct tf_search_identifier_parms sparms = { 0 };
+	struct tf_free_identifier_parms free_parms = { 0 };
+	struct tf *tfp;
+	int rc;
+
+	/* Get the tfp from ulp context */
+	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
+	if (!tfp) {
+		BNXT_TF_DBG(ERR, "Failed to get tf pointer\n");
+		return -EINVAL;
+	}
+
+	/* Extract the index from the result blob */
+	rc = ulp_blob_pull(res_blob, (uint8_t *)&idx, sizeof(idx),
+			   ident->ident_bit_pos, ident->ident_bit_size);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Failed to extract identifier from blob\n");
+		return -EIO;
+	}
+
+	/* populate the search params and search identifier shadow table */
+	sparms.ident_type = ident->ident_type;
+	sparms.dir = tbl->direction;
+	/* convert the idx into cpu format */
+	sparms.search_id = tfp_be_to_cpu_32(idx);
+
+	/* Search identifier also increase the reference count */
+	rc = tf_search_identifier(tfp, &sparms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
+			    tf_dir_2_str(sparms.dir),
+			    tf_tbl_type_2_str(sparms.ident_type),
+			    sparms.search_id);
+		return rc;
+	}
+	BNXT_TF_INF("Search ident %s:%s:%x.success.\n",
+		    tf_dir_2_str(sparms.dir),
+		    tf_tbl_type_2_str(sparms.ident_type),
+		    sparms.search_id);
+
+	/* Write it to the regfile */
+	id = (uint64_t)tfp_cpu_to_be_64(sparms.search_id);
+	if (!ulp_regfile_write(parms->regfile, ident->regfile_idx, id)) {
+		BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n", idx);
+		rc = -EINVAL;
+		/* Need to free the identifier, so goto error */
+		goto error;
+	}
+
+	/* Link the resource to the flow in the flow db */
+	memset(&fid_parms, 0, sizeof(fid_parms));
+	fid_parms.direction = tbl->direction;
+	fid_parms.resource_func = ident->resource_func;
+	fid_parms.resource_type = ident->ident_type;
+	fid_parms.resource_hndl = sparms.search_id;
+	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
+	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
+				      parms->tbl_idx,
+				      parms->fid,
+				      &fid_parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n",
+			    rc);
+		/* Need to free the identifier, so goto error */
+		goto error;
+	}
+
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
+	ulp_mapper_ident_field_dump("Ident", ident, tbl, sparms.search_id);
+#endif
+	return 0;
+
+error:
+	/* Need to free the identifier */
+	free_parms.dir = tbl->direction;
+	free_parms.ident_type = ident->ident_type;
+	free_parms.id = sparms.search_id;
+	(void)tf_free_identifier(tfp, &free_parms);
+	BNXT_TF_DBG(ERR, "Ident extract failed for %s:%s:%x\n",
+		    ident->description,
+		    tf_dir_2_str(tbl->direction), sparms.search_id);
+	return rc;
+}
+
 static int32_t
 ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms *parms,
 				enum tf_dir dir,
@@ -1204,6 +1301,7 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 	struct tf_free_tcam_entry_parms free_parms	= { 0 };
 	uint32_t hit = 0;
 	uint16_t tmplen = 0;
+	struct ulp_blob res_blob;
 
 	/* Skip this if was handled by the cache. */
 	if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP) {
@@ -1379,9 +1477,23 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 			goto error;
 
 	} else {
-		BNXT_TF_DBG(ERR, "Not supporting search before alloc now\n");
-		rc = -EINVAL;
-		goto error;
+		struct bnxt_ulp_mapper_ident_info *idents;
+		uint32_t num_idents;
+
+		/*
+		 * Extract the listed identifiers from the result field,
+		 * no need to allocate them.
+		 */
+		idents = ulp_mapper_ident_fields_get(tbl, &num_idents);
+		for (i = 0; i < num_idents; i++) {
+			rc = ulp_mapper_ident_extract(parms, tbl,
+						      &idents[i], &res_blob);
+			if (rc) {
+				BNXT_TF_DBG(ERR,
+					    "Error in ident extraction\n");
+				goto error;
+			}
+		}
 	}
 
 	/*
-- 
2.7.4


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

* [dpdk-dev] [PATCH 08/10] net/bnxt: consider vlan fields for the template match criteria
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (6 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

The vlan mask fields were not setting the field bitmap causing
the template match process to ignore vlan fields. This change fixes
this bug.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_mapper.c     |  7 +++----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 34 +++++++++++++++++++++++---------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 157c451..051a095 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -16,6 +16,7 @@
 #include "ulp_mark_mgr.h"
 #include "ulp_flow_db.h"
 #include "ulp_mapper.h"
+#include "tf_util.h"
 
 static struct bnxt_ulp_glb_resource_info *
 ulp_mapper_glb_resource_info_list_get(uint32_t *num_entries)
@@ -719,15 +720,13 @@ ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,
 	/* Search identifier also increase the reference count */
 	rc = tf_search_identifier(tfp, &sparms);
 	if (rc) {
-		BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
+		BNXT_TF_DBG(ERR, "Search ident %s:%x failed.\n",
 			    tf_dir_2_str(sparms.dir),
-			    tf_tbl_type_2_str(sparms.ident_type),
 			    sparms.search_id);
 		return rc;
 	}
-	BNXT_TF_INF("Search ident %s:%s:%x.success.\n",
+	BNXT_TF_DBG(INFO, "Search ident %s:%x.success.\n",
 		    tf_dir_2_str(sparms.dir),
-		    tf_tbl_type_2_str(sparms.ident_type),
 		    sparms.search_id);
 
 	/* Write it to the regfile */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index c9237b4..b63a454 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -12,6 +12,11 @@
 #include "tfp.h"
 #include "ulp_port_db.h"
 
+/* Local defines for the parsing functions */
+#define ULP_VLAN_PRIORITY_SHIFT		13 /* First 3 bits */
+#define ULP_VLAN_PRIORITY_MASK		0x700
+#define ULP_VLAN_TAG_MASK		0xFFF /* Last 12 bits*/
+
 /* Utility function to skip the void items. */
 static inline int32_t
 ulp_rte_item_skip_void(const struct rte_flow_item **item, uint32_t increment)
@@ -545,8 +550,8 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
 	 */
 	if (vlan_spec) {
 		vlan_tag = ntohs(vlan_spec->tci);
-		priority = htons(vlan_tag >> 13);
-		vlan_tag &= 0xfff;
+		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
+		vlan_tag &= ULP_VLAN_TAG_MASK;
 		vlan_tag = htons(vlan_tag);
 
 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
@@ -562,16 +567,27 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
 
 	if (vlan_mask) {
 		vlan_tag = ntohs(vlan_mask->tci);
-		priority = htons(vlan_tag >> 13);
+		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
 		vlan_tag &= 0xfff;
+
+		/*
+		 * the storage for priority and vlan tag is 2 bytes
+		 * The mask of priority which is 3 bits if it is all 1's
+		 * then make the rest bits 13 bits as 1's
+		 * so that it is matched as exact match.
+		 */
+		if (priority == ULP_VLAN_PRIORITY_MASK)
+			priority |= ~ULP_VLAN_PRIORITY_MASK;
+		if (vlan_tag == ULP_VLAN_TAG_MASK)
+			vlan_tag |= ~ULP_VLAN_TAG_MASK;
 		vlan_tag = htons(vlan_tag);
 
-		field = &params->hdr_field[idx];
-		memcpy(field->mask, &priority, field->size);
-		field++;
-		memcpy(field->mask, &vlan_tag, field->size);
-		field++;
-		memcpy(field->mask, &vlan_mask->inner_type, field->size);
+		ulp_rte_prsr_mask_copy(params, &idx, &priority,
+				       sizeof(priority));
+		ulp_rte_prsr_mask_copy(params, &idx, &vlan_tag,
+				       sizeof(vlan_tag));
+		ulp_rte_prsr_mask_copy(params, &idx, &vlan_mask->inner_type,
+				       sizeof(vlan_mask->inner_type));
 	}
 	/* Set the vlan index to new incremented value */
 	params->vlan_idx += BNXT_ULP_PROTO_HDR_S_VLAN_NUM;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (7 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider vlan fields for the template match criteria Somnath Kotur
@ 2020-07-13  6:15 ` Somnath Kotur
  2020-07-13  6:16 ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement ttl action Somnath Kotur
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:15 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Increase the number of egress flow entries.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 397d0a9..6b0a403 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -127,7 +127,7 @@ ulp_ctx_session_open(struct bnxt *bp,
 	resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 8;
 
 	/* EM */
-	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 8;
+	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 2048;
 
 	/* EEM */
 	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement ttl action
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (8 preceding siblings ...)
  2020-07-13  6:15 ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
@ 2020-07-13  6:16 ` Somnath Kotur
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
  11 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  6:16 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Added support for decrement ttl action.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 30 +++++++++++++++++++++++++++
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  5 +++++
 drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c |  4 ++--
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index b63a454..5815024 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -189,6 +189,26 @@ bnxt_ulp_rte_parser_post_process(struct ulp_rte_parser_params *params)
 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_VF_TO_VF, 1);
 
+	/* Update the decrement ttl computational fields */
+	if (ULP_BITMAP_ISSET(params->act_bitmap.bits,
+			     BNXT_ULP_ACTION_BIT_DEC_TTL)) {
+		/*
+		 * Check that vxlan proto is included and vxlan decap
+		 * action is not set then decrement tunnel ttl.
+		 * Similarly add GRE and NVGRE in future.
+		 */
+		if ((ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
+				      BNXT_ULP_HDR_BIT_T_VXLAN) &&
+		    !ULP_BITMAP_ISSET(params->act_bitmap.bits,
+				      BNXT_ULP_ACTION_BIT_VXLAN_DECAP))) {
+			ULP_COMP_FLD_IDX_WR(params,
+					    BNXT_ULP_CF_IDX_ACT_T_DEC_TTL, 1);
+		} else {
+			ULP_COMP_FLD_IDX_WR(params,
+					    BNXT_ULP_CF_IDX_ACT_DEC_TTL, 1);
+		}
+	}
+
 	/* TBD: Handle the flow rejection scenarios */
 	return 0;
 }
@@ -1814,3 +1834,13 @@ ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
 	return BNXT_TF_RC_ERROR;
 }
+
+/* Function to handle the parsing of RTE Flow action dec ttl.*/
+int32_t
+ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *act __rte_unused,
+			    struct ulp_rte_parser_params *params)
+{
+	/* Update the act_bitmap with dec ttl */
+	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_DEC_TTL);
+	return BNXT_TF_RC_SUCCESS;
+}
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e155250..7b6b57e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -216,4 +216,9 @@ int32_t
 ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
 			       struct ulp_rte_parser_params *params);
 
+/* Function to handle the parsing of RTE Flow action dec ttl.*/
+int32_t
+ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *action_item,
+			    struct ulp_rte_parser_params *params);
+
 #endif /* _ULP_RTE_PARSER_H_ */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
index 5847e58..9a27cbf 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
@@ -259,8 +259,8 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 		.proto_act_func          = NULL
 	},
 	[RTE_FLOW_ACTION_TYPE_DEC_TTL] = {
-		.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
-		.proto_act_func          = NULL
+		.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+		.proto_act_func          = ulp_rte_dec_ttl_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_SET_TTL] = {
 		.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
-- 
2.7.4


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

* [dpdk-dev] [PATCH v3 00/10] bnxt patches
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (9 preceding siblings ...)
  2020-07-13  6:16 ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement ttl action Somnath Kotur
@ 2020-07-13  9:42 ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
                     ` (10 more replies)
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
  11 siblings, 11 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Minor enhancments added to the TF-ULP/Core layers

Farah Smith (1):
  net/bnxt: add changes to support 2 table scopes

Jay Ding (2):
  net/bnxt: implement TF Identifier search
  net/bnxt: check index range in bulk get

Kishore Padmanabha (6):
  net/bnxt: add support to extract data from the ulp blob
  net/bnxt: ignore ipv4 TOS mask
  net/bnxt: add support for identifier search and ref count
  net/bnxt: consider VLAN fields for template match criteria
  net/bnxt: increase the number of egress flow entries
  net/bnxt: add support for decrement TTL action

Peter Spreadborough (1):
  net/bnxt: add option to delay EEM sysmem mapping

 drivers/net/bnxt/meson.build                    |   3 +-
 drivers/net/bnxt/tf_core/Makefile               |   1 +
 drivers/net/bnxt/tf_core/tf_core.c              |  78 +++++++-
 drivers/net/bnxt/tf_core/tf_core.h              |  78 +++++++-
 drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
 drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
 drivers/net/bnxt/tf_core/tf_em.h                |  11 ++
 drivers/net/bnxt/tf_core/tf_em_common.c         | 145 ++++++++++++++-
 drivers/net/bnxt/tf_core/tf_em_common.h         |  27 ++-
 drivers/net/bnxt/tf_core/tf_em_host.c           |  23 +--
 drivers/net/bnxt/tf_core/tf_em_internal.c       |   2 +-
 drivers/net/bnxt/tf_core/tf_em_system.c         |  25 +--
 drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
 drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
 drivers/net/bnxt/tf_core/tf_msg.c               |   3 +-
 drivers/net/bnxt/tf_core/tf_rm.c                |  43 +++++
 drivers/net/bnxt/tf_core/tf_rm.h                |  45 +++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tbl.c               |  40 ++---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c              |   2 +-
 drivers/net/bnxt/tf_ulp/ulp_mapper.c            | 117 +++++++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c        |  74 +++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h        |   5 +
 drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c   |   4 +-
 drivers/net/bnxt/tf_ulp/ulp_utils.c             |  76 ++++++++
 drivers/net/bnxt/tf_ulp/ulp_utils.h             |  17 ++
 27 files changed, 1367 insertions(+), 88 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h

-- 
v1->v2: Corrected some typos in patch 5 and 6
v2->v3: Modified case of some words in commit summary as per git-check-log.sh
2.7.4


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

* [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Peter Spreadborough <peter.spreadborough@broadcom.com>

- The mapping of kernel pages for EEM sysmem operation takes
  a significant amount of time. This change give the build option
  to delay the sysmem mapping until the first write to EEM

Signed-off-by: Peter Spreadborough <peter.spreadborough@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.c        | 17 +++++++++++--
 drivers/net/bnxt/tf_core/tf_em.h          | 11 +++++++++
 drivers/net/bnxt/tf_core/tf_em_common.c   | 41 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_em_internal.c |  2 +-
 drivers/net/bnxt/tf_core/tf_em_system.c   |  6 +++--
 5 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 00b2775..a404cb8 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -49,9 +49,22 @@ tf_open_session(struct tf *tfp,
 		    &slot,
 		    &device);
 	if (rc != 4) {
-		TFP_DRV_LOG(ERR,
+		/* PCI Domain not provided (optional in DPDK), thus we
+		 * force domain to 0 and recheck.
+		 */
+		domain = 0;
+
+		/* Check parsing of bus/slot/device */
+		rc = sscanf(parms->ctrl_chan_name,
+			    "%x:%x.%d",
+			    &bus,
+			    &slot,
+			    &device);
+		if (rc != 3) {
+			TFP_DRV_LOG(ERR,
 			    "Failed to scan device ctrl_chan_name\n");
-		return -EINVAL;
+			return -EINVAL;
+		}
 	}
 
 	parms->session_id.internal.domain = domain;
diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h
index 0890261..ae2e64d 100644
--- a/drivers/net/bnxt/tf_core/tf_em.h
+++ b/drivers/net/bnxt/tf_core/tf_em.h
@@ -9,6 +9,16 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
+#ifdef TF_USE_SYSTEM_MEM
+/**
+ * Select EEM sysmem mmap export to be done at init
+ * or on the first write to EEM.
+ */
+#define TF_EM_SYSMEM_DELAY_EXPORT 1
+#else
+#define TF_EM_SYSMEM_DELAY_EXPORT 0
+#endif
+
 #define SUPPORT_CFA_HW_P4 1
 #define SUPPORT_CFA_HW_P58 0
 #define SUPPORT_CFA_HW_P59 0
@@ -482,4 +492,5 @@ int
 tf_em_ext_system_bind(struct tf *tfp,
 		      struct tf_em_cfg_parms *parms);
 
+int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb);
 #endif /* _TF_EM_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 8b02b8b..65b9abf 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -700,6 +700,26 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
 	uint64_t big_hash;
 	int rc;
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 1)
+	if (!tbl_scope_cb->valid) {
+		rc = offload_system_mmap(tbl_scope_cb);
+
+		if (rc) {
+			struct tf_rm_free_parms fparms = { 0 };
+
+			TFP_DRV_LOG(ERR,
+				    "System alloc mmap failed\n");
+			/* Free Table control block */
+			fparms.rm_db = eem_db[TF_DIR_RX];
+			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+			fparms.index = parms->tbl_scope_id;
+			tf_rm_free(&fparms);
+			return -EINVAL;
+		}
+
+		tbl_scope_cb->valid = true;
+	}
+#endif
 	/* Get mask to use on hash */
 	mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
 
@@ -1017,6 +1037,27 @@ int tf_tbl_ext_common_set(struct tf *tfp,
 		return -EINVAL;
 	}
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 1)
+	if (!tbl_scope_cb->valid) {
+		rc = offload_system_mmap(tbl_scope_cb);
+
+		if (rc) {
+			struct tf_rm_free_parms fparms = { 0 };
+
+			TFP_DRV_LOG(ERR,
+				    "System alloc mmap failed\n");
+			/* Free Table control block */
+			fparms.rm_db = eem_db[TF_DIR_RX];
+			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+			fparms.index = parms->tbl_scope_id;
+			tf_rm_free(&fparms);
+			return -EINVAL;
+		}
+
+		tbl_scope_cb->valid = true;
+	}
+#endif
+
 	op.opcode = HCAPI_CFA_HWOPS_PUT;
 	key_tbl.base0 =
 		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_RECORD_TABLE];
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
index 3129fbe..462d0fa 100644
--- a/drivers/net/bnxt/tf_core/tf_em_internal.c
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -179,7 +179,7 @@ tf_em_insert_int_entry(struct tf *tfp,
 		return -1;
 
 	PMD_DRV_LOG
-		  (ERR,
+		  (DEBUG,
 		   "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
 		   tf_dir_2_str(parms->dir),
 		   index,
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
index 339392c..1c3c702 100644
--- a/drivers/net/bnxt/tf_core/tf_em_system.c
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -272,8 +272,7 @@ tf_prepare_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)
 	return 0;
 }
 
-static int
-offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
+int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
 {
 	int rc;
 	int dmabuf_fd;
@@ -455,6 +454,7 @@ tf_em_ext_alloc(struct tf *tfp,
 		}
 	}
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 0)
 	rc = offload_system_mmap(tbl_scope_cb);
 
 	if (rc) {
@@ -462,6 +462,7 @@ tf_em_ext_alloc(struct tf *tfp,
 			    "System alloc mmap failed\n");
 		goto cleanup_full;
 	}
+#endif
 
 	return rc;
 
@@ -527,6 +528,7 @@ tf_em_ext_free(struct tf *tfp,
 	}
 
 	tf_dmabuf_free(tfp, tbl_scope_cb);
+	tbl_scope_cb->valid = false;
 
 	return rc;
 }
-- 
2.7.4


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

* [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Jay Ding <jay.ding@broadcom.com>

Implement shadow copy DB to hold reference count for
each ID in each identifier type. Implement identifier
search functionality.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/meson.build                    |   3 +-
 drivers/net/bnxt/tf_core/Makefile               |   1 +
 drivers/net/bnxt/tf_core/tf_core.c              |  61 +++++++
 drivers/net/bnxt/tf_core/tf_core.h              |  70 +++++++-
 drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
 drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
 drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
 drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
 drivers/net/bnxt/tf_core/tf_rm.c                |   2 +
 drivers/net/bnxt/tf_core/tf_rm.h                |   8 +
 drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
 12 files changed, 777 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h

diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index 0b93c31..8529b33 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -46,7 +46,7 @@ sources = files('bnxt_cpr.c',
 	'tf_core/ll.c',
 	'tf_core/tf_global_cfg.c',
 	'tf_core/tf_em_host.c',
-	'tf_ulp/ulp_fc_mgr.c',
+	'tf_core/tf_shadow_identifier.c',
 
 	'hcapi/hcapi_cfa_p4.c',
 
@@ -63,6 +63,7 @@ sources = files('bnxt_cpr.c',
 	'tf_ulp/bnxt_ulp_flow.c',
 	'tf_ulp/ulp_port_db.c',
 	'tf_ulp/ulp_def_rules.c',
+	'tf_ulp/ulp_fc_mgr.c',
 
 	'rte_pmd_bnxt.c')
 
diff --git a/drivers/net/bnxt/tf_core/Makefile b/drivers/net/bnxt/tf_core/Makefile
index 8064714..9c2735d 100644
--- a/drivers/net/bnxt/tf_core/Makefile
+++ b/drivers/net/bnxt/tf_core/Makefile
@@ -31,3 +31,4 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tcam.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_util.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_if_tbl.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_global_cfg.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_shadow_identifier.c
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index a404cb8..97e7952 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -534,6 +534,7 @@ tf_free_identifier(struct tf *tfp,
 	fparms.dir = parms->dir;
 	fparms.type = parms->ident_type;
 	fparms.id = parms->id;
+	fparms.ref_cnt = &parms->ref_cnt;
 	rc = dev->ops->tf_dev_free_ident(tfp, &fparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -547,6 +548,66 @@ tf_free_identifier(struct tf *tfp,
 }
 
 int
+tf_search_identifier(struct tf *tfp,
+		     struct tf_search_identifier_parms *parms)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_ident_search_parms sparms;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Can't do static initialization due to UT enum check */
+	memset(&sparms, 0, sizeof(struct tf_ident_search_parms));
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_search_ident == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	sparms.dir = parms->dir;
+	sparms.type = parms->ident_type;
+	sparms.search_id = parms->search_id;
+	sparms.hit = &parms->hit;
+	sparms.ref_cnt = &parms->ref_cnt;
+	rc = dev->ops->tf_dev_search_ident(tfp, &sparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Identifier search failed, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	return 0;
+}
+
+int
 tf_alloc_tcam_entry(struct tf *tfp,
 		    struct tf_alloc_tcam_entry_parms *parms)
 {
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 9e80426..9a5e816 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -695,9 +695,9 @@ struct tf_alloc_identifier_parms {
 	 */
 	enum tf_identifier_type ident_type;
 	/**
-	 * [out] Identifier allocated
+	 * [out] Allocated identifier
 	 */
-	uint16_t id;
+	uint32_t id;
 };
 
 /**
@@ -715,7 +715,38 @@ struct tf_free_identifier_parms {
 	/**
 	 * [in] ID to free
 	 */
-	uint16_t id;
+	uint32_t id;
+	/**
+	 * (experimental)
+	 * [out] Current refcnt after free
+	 */
+	uint32_t ref_cnt;
+};
+
+/**
+ * tf_search_identifier parameter definition (experimental)
+ */
+struct tf_search_identifier_parms {
+	/**
+	 * [in]	 receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type ident_type;
+	/**
+	 * [in] Identifier data to search for
+	 */
+	uint32_t search_id;
+	/**
+	 * [out] Set if matching identifier found
+	 */
+	bool hit;
+	/**
+	 * [out] Current ref count after allocation
+	 */
+	uint32_t ref_cnt;
 };
 
 /**
@@ -724,6 +755,9 @@ struct tf_free_identifier_parms {
  * TruFlow core will allocate a free id from the per identifier resource type
  * pool reserved for the session during tf_open().  No firmware is involved.
  *
+ * If shadow copy is enabled, the internal ref_cnt is set to 1 in the
+ * shadow table for a newly allocated resource.
+ *
  * Returns success or failure code.
  */
 int tf_alloc_identifier(struct tf *tfp,
@@ -736,12 +770,42 @@ int tf_alloc_identifier(struct tf *tfp,
  * reserved for the session.  No firmware is involved.  During tf_close, the
  * complete pool is returned to the firmware.
  *
+ * additional operation (experimental)
+ * Decrement reference count.  Only release resource once refcnt goes to 0 if
+ * shadow copy is enabled.
+ *
  * Returns success or failure code.
  */
 int tf_free_identifier(struct tf *tfp,
 		       struct tf_free_identifier_parms *parms);
 
 /**
+ * Search identifier resource (experimental)
+ *
+ * If the shadow copy is enabled search_id is used to search for a matching
+ * entry in the shadow table.  The shadow table consists of an array of
+ * reference counts indexed by identifier.  If a matching entry is found hit is
+ * set to TRUE, refcnt is increased by 1 and returned.  Otherwise, hit is
+ * set to false and refcnt is set to 0.
+ *
+ * TODO: we may need a per table internal shadow copy enable flag to stage
+ * the shadow table implementation.  We do not need the shadow table for other
+ * tables at this time so we may only want to enable the identifier shadow.
+ *
+ * TODO: remove this pseudocode below added to show that if search fails
+ * we shouldn't allocate a new entry but return.
+ *
+ * identifier alloc (search_en=1)
+ * if (ident is allocated and ref_cnt >=1)
+ *      return ident - hit is set, incr refcnt
+ * else (not found)
+ *      return
+ *
+ */
+int tf_search_identifier(struct tf *tfp,
+			 struct tf_search_identifier_parms *parms);
+
+/**
  * @page dram_table DRAM Table Scope Interface
  *
  * @ref tf_alloc_tbl_scope
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 0bc7090..fce7f25 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -199,6 +199,26 @@ struct tf_dev_ops {
 				 struct tf_ident_free_parms *parms);
 
 	/**
+	 * Search of an identifier element.
+	 *
+	 * This API search the specified identifier element from a
+	 * device specific identifier shadow DB. The allocated element
+	 * is returned.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to identifier search parameters
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_search_ident)(struct tf *tfp,
+				   struct tf_ident_search_parms *parms);
+
+	/**
 	 * Allocation of a table type element.
 	 *
 	 * This API allocates the specified table type element from a
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index dfe626c..f38c38e 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -86,6 +86,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = NULL,
 	.tf_dev_free_ident = NULL,
+	.tf_dev_search_ident = NULL,
 	.tf_dev_alloc_ext_tbl = NULL,
 	.tf_dev_alloc_tbl = NULL,
 	.tf_dev_free_ext_tbl = NULL,
@@ -120,6 +121,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = tf_ident_alloc,
 	.tf_dev_free_ident = tf_ident_free,
+	.tf_dev_search_ident = tf_ident_search,
 	.tf_dev_alloc_tbl = tf_tbl_alloc,
 	.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,
 	.tf_dev_free_tbl = tf_tbl_free,
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index 90aeaa4..273d629 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -6,6 +6,7 @@
 #include <rte_common.h>
 
 #include "tf_identifier.h"
+#include "tf_shadow_identifier.h"
 #include "tf_common.h"
 #include "tf_rm.h"
 #include "tf_util.h"
@@ -23,6 +24,16 @@ static void *ident_db[TF_DIR_MAX];
  */
 static uint8_t init;
 
+/**
+ * Identifier shadow DBs.
+ */
+static void *ident_shadow_db[TF_DIR_MAX];
+
+/**
+ * Shadow DB Init flag, set on bind and cleared on unbind
+ */
+static uint8_t shadow_init;
+
 int
 tf_ident_bind(struct tf *tfp,
 	      struct tf_ident_cfg_parms *parms)
@@ -30,6 +41,8 @@ tf_ident_bind(struct tf *tfp,
 	int rc;
 	int i;
 	struct tf_rm_create_db_parms db_cfg = { 0 };
+	struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 };
+	struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -55,6 +68,23 @@ tf_ident_bind(struct tf *tfp,
 
 			return rc;
 		}
+
+		if (parms->shadow_copy) {
+			shadow_cfg.alloc_cnt =
+				parms->resources->ident_cnt[i].cnt;
+			shadow_cdb.num_elements = parms->num_elements;
+			shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i];
+			shadow_cdb.cfg = &shadow_cfg;
+			rc = tf_shadow_ident_create_db(&shadow_cdb);
+			if (rc) {
+				TFP_DRV_LOG(ERR,
+				    "%s: Ident shadow DB creation failed\n",
+				    tf_dir_2_str(i));
+
+				return rc;
+			}
+			shadow_init = 1;
+		}
 	}
 
 	init = 1;
@@ -71,6 +101,7 @@ tf_ident_unbind(struct tf *tfp)
 	int rc = 0;
 	int i;
 	struct tf_rm_free_db_parms fparms = { 0 };
+	struct tf_shadow_ident_free_db_parms sparms = { 0 };
 
 	TF_CHECK_PARMS1(tfp);
 
@@ -89,10 +120,22 @@ tf_ident_unbind(struct tf *tfp)
 			TFP_DRV_LOG(ERR,
 				    "rm free failed on unbind\n");
 		}
+		if (shadow_init) {
+			sparms.tf_shadow_ident_db = ident_shadow_db[i];
+			rc = tf_shadow_ident_free_db(&sparms);
+			if (rc) {
+				/* TODO: If there are failures on unbind we
+				 * really just have to try until all DBs are
+				 * attempted to be cleared.
+				 */
+			}
+			ident_shadow_db[i] = NULL;
+		}
 		ident_db[i] = NULL;
 	}
 
 	init = 0;
+	shadow_init = 0;
 
 	return 0;
 }
@@ -103,7 +146,9 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 {
 	int rc;
 	uint32_t id;
+	uint32_t base_id;
 	struct tf_rm_allocate_parms aparms = { 0 };
+	struct tf_shadow_ident_insert_parms iparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -118,6 +163,7 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 	aparms.rm_db = ident_db[parms->dir];
 	aparms.db_index = parms->type;
 	aparms.index = &id;
+	aparms.base_index = &base_id;
 	rc = tf_rm_allocate(&aparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -127,6 +173,21 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 		return rc;
 	}
 
+	if (shadow_init) {
+		iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+		iparms.type = parms->type;
+		iparms.id = base_id;
+
+		rc = tf_shadow_ident_insert(&iparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Failed insert shadow DB, type:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    parms->type);
+			return rc;
+		}
+	}
+
 	*parms->id = id;
 
 	return 0;
@@ -139,7 +200,9 @@ tf_ident_free(struct tf *tfp __rte_unused,
 	int rc;
 	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_free_parms fparms = { 0 };
+	struct tf_shadow_ident_remove_parms rparms = { 0 };
 	int allocated = 0;
+	uint32_t base_id;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -154,6 +217,7 @@ tf_ident_free(struct tf *tfp __rte_unused,
 	aparms.rm_db = ident_db[parms->dir];
 	aparms.db_index = parms->type;
 	aparms.index = parms->id;
+	aparms.base_index = &base_id;
 	aparms.allocated = &allocated;
 	rc = tf_rm_is_allocated(&aparms);
 	if (rc)
@@ -168,6 +232,27 @@ tf_ident_free(struct tf *tfp __rte_unused,
 		return -EINVAL;
 	}
 
+	if (shadow_init) {
+		rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+		rparms.type = parms->type;
+		rparms.id = base_id;
+		rparms.ref_cnt = parms->ref_cnt;
+
+		rc = tf_shadow_ident_remove(&rparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: ref_cnt was 0 in shadow DB,"
+				    " type:%d, index:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    parms->type,
+				    parms->id);
+			return rc;
+		}
+
+		if (*rparms.ref_cnt > 0)
+			return 0;
+	}
+
 	/* Free requested element */
 	fparms.rm_db = ident_db[parms->dir];
 	fparms.db_index = parms->type;
@@ -184,3 +269,66 @@ tf_ident_free(struct tf *tfp __rte_unused,
 
 	return 0;
 }
+
+int
+tf_ident_search(struct tf *tfp __rte_unused,
+		struct tf_ident_search_parms *parms)
+{
+	int rc;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_shadow_ident_search_parms sparms = { 0 };
+	int allocated = 0;
+	uint32_t base_id;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No Identifier DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	if (!shadow_init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Identifier Shadow copy is not enabled\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Check if element is in use */
+	aparms.rm_db = ident_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = parms->search_id;
+	aparms.base_index = &base_id;
+	aparms.allocated = &allocated;
+	rc = tf_rm_is_allocated(&aparms);
+	if (rc)
+		return rc;
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry not allocated, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->search_id);
+		return -EINVAL;
+	}
+
+	sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+	sparms.type = parms->type;
+	sparms.search_id = base_id;
+	sparms.hit = parms->hit;
+	sparms.ref_cnt = parms->ref_cnt;
+
+	rc = tf_shadow_ident_search(&sparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed search shadow DB, type:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type);
+		return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h
index 6e36c52..6d9fa08 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.h
+++ b/drivers/net/bnxt/tf_core/tf_identifier.h
@@ -66,6 +66,37 @@ struct tf_ident_free_parms {
 	 * [in] ID to free
 	 */
 	uint16_t id;
+	/**
+	 * (experimental)
+	 * [out] Current refcnt after free
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * Identifier search parameter definition
+ */
+struct tf_ident_search_parms {
+	/**
+	 * [in]  receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Identifier data to search for
+	 */
+	uint16_t search_id;
+	/**
+	 * [out] Set if matching identifier found
+	 */
+	bool *hit;
+	/**
+	 * [out] Current ref count after allocation
+	 */
+	uint32_t *ref_cnt;
 };
 
 /**
@@ -144,4 +175,20 @@ int tf_ident_alloc(struct tf *tfp,
 int tf_ident_free(struct tf *tfp,
 		  struct tf_ident_free_parms *parms);
 
+/**
+ * Search a single identifier type.
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_ident_search(struct tf *tfp,
+		    struct tf_ident_search_parms *parms);
+
 #endif /* _TF_IDENTIFIER_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index fdb87ec..78bc231 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -755,6 +755,7 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 	}
 
 	*parms->index = index;
+	*parms->base_index = id;
 
 	return rc;
 }
@@ -841,6 +842,7 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
 	if (rc)
 		return rc;
 
+	*parms->base_index = adj_index;
 	*parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
 				     adj_index);
 
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 775f0aa..971120a 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -204,6 +204,10 @@ struct tf_rm_allocate_parms {
 	 *              available index)
 	 */
 	uint32_t priority;
+	/**
+	 * [in] Pointer to the allocated index before adjusted.
+	 */
+	uint32_t *base_index;
 };
 
 /**
@@ -246,6 +250,10 @@ struct tf_rm_is_allocated_parms {
 	 * [in] Pointer to flag that indicates the state of the query
 	 */
 	int *allocated;
+	/**
+	 * [in] Pointer to the allocated index before adjusted.
+	 */
+	uint32_t *base_index;
 };
 
 /**
diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.c b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c
new file mode 100644
index 0000000..390d22f
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_common.h>
+
+#include "tf_shadow_identifier.h"
+#include "tf_common.h"
+#include "tf_util.h"
+#include "tfp.h"
+
+/**
+ * Shadow identifier DB element
+ */
+struct tf_shadow_ident_element {
+	/**
+	 * Identifier
+	 */
+	uint32_t *id;
+
+	/**
+	 * Reference count, array of number of identifier type entries
+	 */
+	uint32_t *ref_count;
+};
+
+/**
+ * Shadow identifier DB definition
+ */
+struct tf_shadow_ident_db {
+	/**
+	 * Number of elements in the DB
+	 */
+	uint16_t num_entries;
+
+	/**
+	 * The DB consists of an array of elements
+	 */
+	struct tf_shadow_ident_element *db;
+};
+
+int
+tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms)
+{
+	int rc;
+	int i;
+	struct tfp_calloc_parms cparms;
+	struct tf_shadow_ident_db *shadow_db;
+	struct tf_shadow_ident_element *db;
+
+	TF_CHECK_PARMS1(parms);
+
+	/* Build the shadow DB per the request */
+	cparms.nitems = 1;
+	cparms.size = sizeof(struct tf_shadow_ident_db);
+	cparms.alignment = 0;
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	shadow_db = (void *)cparms.mem_va;
+
+	/* Build the DB within shadow DB */
+	cparms.nitems = parms->num_elements;
+	cparms.size = sizeof(struct tf_shadow_ident_element);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	shadow_db->db = (struct tf_shadow_ident_element *)cparms.mem_va;
+	shadow_db->num_entries = parms->num_elements;
+
+	db = shadow_db->db;
+	for (i = 0; i < parms->num_elements; i++) {
+		/* If the element didn't request an allocation no need
+		 * to create a pool nor verify if we got a reservation.
+		 */
+		if (parms->cfg->alloc_cnt[i] == 0)
+			continue;
+
+		/* Create array */
+		cparms.nitems = parms->cfg->alloc_cnt[i];
+		cparms.size = sizeof(uint32_t);
+		rc = tfp_calloc(&cparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Array alloc failed, type:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    i);
+			goto fail;
+		}
+		db[i].ref_count = (uint32_t *)cparms.mem_va;
+	}
+
+	*parms->tf_shadow_ident_db = (void *)shadow_db;
+
+	return 0;
+fail:
+	tfp_free((void *)db->ref_count);
+	tfp_free((void *)db);
+	tfp_free((void *)shadow_db);
+	parms->tf_shadow_ident_db = NULL;
+
+	return -EINVAL;
+}
+
+int
+tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms)
+{
+	int i;
+	struct tf_shadow_ident_db *shadow_db;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	for (i = 0; i < shadow_db->num_entries; i++)
+		tfp_free((void *)shadow_db->db[i].ref_count);
+
+	tfp_free((void *)shadow_db->db);
+	tfp_free((void *)parms->tf_shadow_ident_db);
+
+	return 0;
+}
+
+int
+tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+	uint32_t ref_cnt = 0;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	ref_cnt = shadow_db->db[parms->type].ref_count[parms->search_id];
+	if (ref_cnt > 0) {
+		*parms->hit = 1;
+		*parms->ref_cnt = ++ref_cnt;
+		shadow_db->db[parms->type].ref_count[parms->search_id] =
+								ref_cnt;
+	} else {
+		*parms->hit = 0;
+		*parms->ref_cnt = 0;
+	}
+
+
+	return 0;
+}
+
+#define ID_REF_CNT_MAX 0xffffffff
+int
+tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+
+	/* In case of overflow, ref count keeps the max value */
+	if (shadow_db->db[parms->type].ref_count[parms->id] < ID_REF_CNT_MAX)
+		shadow_db->db[parms->type].ref_count[parms->id]++;
+	else
+		TFP_DRV_LOG(ERR,
+			    "Identifier %d in type %d reaches the max ref_cnt\n",
+			    parms->type,
+			    parms->id);
+
+	parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+
+	return 0;
+}
+
+int
+tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+	uint32_t ref_cnt = 0;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+	if (ref_cnt > 0)
+		shadow_db->db[parms->type].ref_count[parms->id]--;
+	else
+		return -EINVAL;
+
+	*parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.h b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h
new file mode 100644
index 0000000..dd633af
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_SHADOW_IDENTIFIER_H_
+#define _TF_SHADOW_IDENTIFIER_H_
+
+#include "tf_core.h"
+
+struct tf;
+
+/**
+ * The Shadow Identifier module provides shadow DB handling for identifier based
+ * TF types. A shadow DB provides the capability that allows for reuse
+ * of TF resources.
+ *
+ * A Shadow identifier DB is intended to be used by the Identifier Type module
+ * only.
+ */
+
+/**
+ * Shadow DB configuration information for a single identifier type.
+ *
+ * It is used in an array of identifier types. The array must be ordered
+ * by the TF type is represents.
+ */
+struct tf_shadow_ident_cfg_parms {
+	/**
+	 * TF Identifier type
+	 */
+	enum tf_identifier_type type;
+
+	/**
+	 * Number of entries the Shadow DB needs to hold
+	 */
+	int num_entries;
+
+	/**
+	 * Resource allocation count array. This array content
+	 * originates from the tf_session_resources that is passed in
+	 * on session open.
+	 * Array size is num_elements.
+	 */
+	uint16_t *alloc_cnt;
+};
+
+/**
+ * Shadow identifier DB creation parameters
+ */
+struct tf_shadow_ident_create_db_parms {
+	/**
+	 * [in] Receive or transmit direction.
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Configuration information for the shadow db
+	 */
+	struct tf_shadow_ident_cfg_parms *cfg;
+	/**
+	 * [in] Number of elements in the parms structure
+	 */
+	uint16_t num_elements;
+	/**
+	 * [out] Shadow identifier DB handle
+	 */
+	void **tf_shadow_ident_db;
+};
+
+/**
+ * Shadow identifier DB free parameters
+ */
+struct tf_shadow_ident_free_db_parms {
+	/**
+	 * Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+};
+
+/**
+ * Shadow identifier search parameters
+ */
+struct tf_shadow_ident_search_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] id to search
+	 */
+	uint16_t search_id;
+	/**
+	 * [out] Index of the found element returned if hit
+	 */
+	bool *hit;
+	/**
+	 * [out] Reference count incremented if hit
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * Shadow identifier insert parameters
+ */
+struct tf_shadow_ident_insert_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Tbl type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Entry to update
+	 */
+	uint16_t id;
+	/**
+	 * [out] Reference count after insert
+	 */
+	uint32_t ref_cnt;
+};
+
+/**
+ * Shadow identifier remove parameters
+ */
+struct tf_shadow_ident_remove_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Tbl type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Entry to update
+	 */
+	uint16_t id;
+	/**
+	 * [out] Reference count after removal
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * @page shadow_ident Shadow identifier DB
+ *
+ * @ref tf_shadow_ident_create_db
+ *
+ * @ref tf_shadow_ident_free_db
+ *
+ * @reg tf_shadow_ident_search
+ *
+ * @reg tf_shadow_ident_insert
+ *
+ * @reg tf_shadow_ident_remove
+ */
+
+/**
+ * Creates and fills a Shadow identifier DB. The DB is indexed per the
+ * parms structure.
+ *
+ * [in] parms
+ *   Pointer to create db parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms);
+
+/**
+ * Closes the Shadow identifier DB and frees all allocated
+ * resources per the associated database.
+ *
+ * [in] parms
+ *   Pointer to the free DB parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms);
+
+/**
+ * Search Shadow identifier db for matching result
+ *
+ * [in] parms
+ *   Pointer to the search parameters
+ *
+ * Returns
+ *   - (0) if successful, element was found.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms);
+
+/**
+ * Inserts an element into the Shadow identifier DB. Ref_count after insert
+ * will be incremented.
+ *
+ * [in] parms
+ *   Pointer to insert parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms);
+
+/**
+ * Removes an element from the Shadow identifier DB. Will fail if the
+ * elements ref_count is 0. Ref_count after removal will be
+ * decremented.
+ *
+ * [in] parms
+ *   Pointer to remove parameter
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms);
+
+#endif /* _TF_SHADOW_IDENTIFIER_H_ */
-- 
2.7.4


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

* [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Jay Ding <jay.ding@broadcom.com>

In tf_tbl_bulk_get, check if the indexes are in the range
of reserved tbl id instead of checking the allocation of each id.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.h |  8 ++++---
 drivers/net/bnxt/tf_core/tf_msg.c  |  3 ++-
 drivers/net/bnxt/tf_core/tf_rm.c   | 45 ++++++++++++++++++++++++++++++++++++--
 drivers/net/bnxt/tf_core/tf_rm.h   | 37 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tbl.c  | 40 ++++++++++++++-------------------
 5 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 9a5e816..758685e 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -1426,10 +1426,12 @@ struct tf_bulk_get_tbl_entry_parms {
 /**
  * Bulk get index table entry
  *
- * Used to retrieve a previous set index table entry.
+ * Used to retrieve a set of index table entries.
  *
- * Reads and compares with the shadow table copy (if enabled) (only
- * for internal objects).
+ * Entries within the range may not have been allocated using
+ * tf_alloc_tbl_entry() at the time of access. But the range must
+ * be within the bounds determined from tf_open_session() for the
+ * given table type.  Currently, this is only used for collecting statistics.
  *
  * Returns success or failure code. Failure will be returned if the
  * provided data buffer is too small for the data type requested.
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index 1e14d92..53515ad 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -143,7 +143,8 @@ tf_msg_session_open(struct tf *tfp,
 		return rc;
 
 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
-	*fw_session_client_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
+	*fw_session_client_id =
+		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
 
 	return rc;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index 78bc231..9aec954 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -755,7 +755,8 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 	}
 
 	*parms->index = index;
-	*parms->base_index = id;
+	if (parms->base_index)
+		*parms->base_index = id;
 
 	return rc;
 }
@@ -842,7 +843,8 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
 	if (rc)
 		return rc;
 
-	*parms->base_index = adj_index;
+	if (parms->base_index)
+		*parms->base_index = adj_index;
 	*parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
 				     adj_index);
 
@@ -922,3 +924,42 @@ tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
 	return rc;
 
 }
+
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms)
+{
+	struct tf_rm_new_db *rm_db;
+	enum tf_rm_elem_cfg_type cfg_type;
+	uint32_t base_index;
+	uint32_t stride;
+	int rc = 0;
+
+	TF_CHECK_PARMS2(parms, parms->rm_db);
+
+	rm_db = (struct tf_rm_new_db *)parms->rm_db;
+	cfg_type = rm_db->db[parms->db_index].cfg_type;
+
+	/* Bail out if not controlled by RM */
+	if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
+		return -ENOTSUP;
+
+	/* Bail out if the pool is not valid, should never happen */
+	if (rm_db->db[parms->db_index].pool == NULL) {
+		rc = -ENOTSUP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Invalid pool for this type:%d, rc:%s\n",
+			    tf_dir_2_str(rm_db->dir),
+			    parms->db_index,
+			    strerror(-rc));
+		return rc;
+	}
+
+	base_index = rm_db->db[parms->db_index].alloc.entry.start;
+	stride = rm_db->db[parms->db_index].alloc.entry.stride;
+
+	if (parms->starting_index < base_index ||
+	    parms->starting_index + parms->num_entries > base_index + stride)
+		return -EINVAL;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 971120a..97692db 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -315,6 +315,29 @@ struct tf_rm_get_inuse_count_parms {
 };
 
 /**
+ * Check if the indexes are in the range of reserved resource
+ */
+struct tf_rm_check_indexes_in_range_parms {
+	/**
+	 * [in] RM DB Handle
+	 */
+	void *rm_db;
+	/**
+	 * [in] DB Index, indicates which DB entry to perform the
+	 * action on.
+	 */
+	uint16_t db_index;
+	/**
+	 * [in] Starting index
+	 */
+	uint16_t starting_index;
+	/**
+	 * [in] number of entries
+	 */
+	uint16_t num_entries;
+};
+
+/**
  * @page rm Resource Manager
  *
  * @ref tf_rm_create_db
@@ -462,4 +485,18 @@ int tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms);
  */
 int tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms);
 
+/**
+ * Check if the requested indexes are in the range of reserved resource.
+ *
+ * [in] parms
+ *   Pointer to get inuse parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms);
+
+
 #endif /* TF_RM_NEW_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index 2b4a7c5..9ebaa34 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -350,12 +350,9 @@ tf_tbl_bulk_get(struct tf *tfp,
 		struct tf_tbl_get_bulk_parms *parms)
 {
 	int rc;
-	int i;
 	uint16_t hcapi_type;
-	uint32_t idx;
-	int allocated = 0;
-	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_get_hcapi_parms hparms = { 0 };
+	struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -366,26 +363,23 @@ tf_tbl_bulk_get(struct tf *tfp,
 
 		return -EINVAL;
 	}
-	/* Verify that the entries has been previously allocated */
-	aparms.rm_db = tbl_db[parms->dir];
-	aparms.db_index = parms->type;
-	aparms.allocated = &allocated;
-	idx = parms->starting_idx;
-	for (i = 0; i < parms->num_entries; i++) {
-		aparms.index = idx;
-		rc = tf_rm_is_allocated(&aparms);
-		if (rc)
-			return rc;
 
-		if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
-			TFP_DRV_LOG(ERR,
-				    "%s, Invalid or not allocated index, type:%d, idx:%d\n",
-				    tf_dir_2_str(parms->dir),
-				    parms->type,
-				    idx);
-			return -EINVAL;
-		}
-		idx++;
+	/* Verify that the entries are in the range of reserved resources. */
+	cparms.rm_db = tbl_db[parms->dir];
+	cparms.db_index = parms->type;
+	cparms.starting_index = parms->starting_idx;
+	cparms.num_entries = parms->num_entries;
+
+	rc = tf_rm_check_indexes_in_range(&cparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s, Invalid or %d index starting from %d"
+			    " not in range, type:%d",
+			    tf_dir_2_str(parms->dir),
+			    parms->starting_idx,
+			    parms->num_entries,
+			    parms->type);
+		return rc;
 	}
 
 	hparms.rm_db = tbl_db[parms->dir];
-- 
2.7.4


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

* [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (2 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Farah Smith <farah.smith@broadcom.com>

Need to remap the table scope ids allocated from HCAPI RM from high
to low value because for legacy devices a table scope is a set of base
addresses.  The PCIe addresses must map to a PCIe PF which exists in
the hardware.

Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_em_common.c | 106 +++++++++++++++++++++++++++++++-
 drivers/net/bnxt/tf_core/tf_em_common.h |  27 +++++++-
 drivers/net/bnxt/tf_core/tf_em_host.c   |  23 ++-----
 drivers/net/bnxt/tf_core/tf_em_system.c |  19 +-----
 4 files changed, 137 insertions(+), 38 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 65b9abf..10c3f16 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -44,6 +44,28 @@ static enum tf_mem_type mem_type;
 /** Table scope array */
 struct tf_tbl_scope_cb tbl_scopes[TF_NUM_TBL_SCOPE];
 
+/** Table scope reversal table
+ *
+ * Table scope are allocated from 15 to 0 within HCAPI RM.  Because of the
+ * association between PFs and legacy table scopes, reverse table scope ids.
+ * 15 indicates 0, 14 indicates 1, etc... The application will only see the 0
+ * based number.  The firmware will only use the 0 based number.  Only HCAPI RM
+ * and Truflow RM believe the number is 15.  When HCAPI RM support allocation
+ * from low to high is supported, this adjust function can be removed.
+ */
+const uint32_t tbl_scope_reverse[TF_NUM_TBL_SCOPE] = {
+	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+static uint32_t
+tf_tbl_scope_adjust(uint32_t tbl_scope_id)
+{
+	if (tbl_scope_id < TF_NUM_TBL_SCOPE)
+		return tbl_scope_reverse[tbl_scope_id];
+	else
+		return TF_TBL_SCOPE_INVALID;
+};
+
+
 /* API defined in tf_em.h */
 struct tf_tbl_scope_cb *
 tbl_scope_cb_find(uint32_t tbl_scope_id)
@@ -51,11 +73,17 @@ tbl_scope_cb_find(uint32_t tbl_scope_id)
 	int i;
 	struct tf_rm_is_allocated_parms parms;
 	int allocated;
+	uint32_t rm_tbl_scope_id;
+
+	rm_tbl_scope_id = tf_tbl_scope_adjust(tbl_scope_id);
+
+	if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+		return NULL;
 
 	/* Check that id is valid */
 	parms.rm_db = eem_db[TF_DIR_RX];
 	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	parms.index = tbl_scope_id;
+	parms.index = rm_tbl_scope_id;
 	parms.allocated = &allocated;
 
 	i = tf_rm_is_allocated(&parms);
@@ -71,6 +99,61 @@ tbl_scope_cb_find(uint32_t tbl_scope_id)
 	return NULL;
 }
 
+int tf_tbl_scope_alloc(uint32_t *tbl_scope_id)
+{
+	int rc;
+	struct tf_rm_allocate_parms parms = { 0 };
+	uint32_t rm_tbl_scope_id;
+	uint32_t usr_tbl_scope_id = TF_TBL_SCOPE_INVALID;
+
+	/* Get Table Scope control block from the session pool */
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+	parms.index = &rm_tbl_scope_id;
+
+	rc = tf_rm_allocate(&parms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to allocate table scope rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	usr_tbl_scope_id = tf_tbl_scope_adjust(rm_tbl_scope_id);
+
+	if (usr_tbl_scope_id == TF_TBL_SCOPE_INVALID) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid table scope allocated id:%d\n",
+			    (int)rm_tbl_scope_id);
+		return -EINVAL;
+	}
+	*tbl_scope_id = usr_tbl_scope_id;
+	return 0;
+};
+
+int tf_tbl_scope_free(uint32_t tbl_scope_id)
+{
+	struct tf_rm_free_parms parms = { 0 };
+	uint32_t rm_tbl_scope_id;
+	uint32_t rc;
+
+	rm_tbl_scope_id = tf_tbl_scope_adjust(tbl_scope_id);
+
+	if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid table scope allocated id:%d\n",
+			    (int)tbl_scope_id);
+		return -EINVAL;
+	}
+
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+	parms.index = rm_tbl_scope_id;
+
+	rc = tf_rm_free(&parms);
+	return rc;
+};
+
 int
 tf_create_tbl_pool_external(enum tf_dir dir,
 			    struct tf_tbl_scope_cb *tbl_scope_cb,
@@ -706,9 +789,17 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
 
 		if (rc) {
 			struct tf_rm_free_parms fparms = { 0 };
+			uint32_t rm_tbl_scope_id;
 
 			TFP_DRV_LOG(ERR,
 				    "System alloc mmap failed\n");
+
+			rm_tbl_scope_id =
+				tf_tbl_scope_adjust(parms->tbl_scope_id);
+
+			if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+				return -EINVAL;
+
 			/* Free Table control block */
 			fparms.rm_db = eem_db[TF_DIR_RX];
 			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
@@ -1043,13 +1134,24 @@ int tf_tbl_ext_common_set(struct tf *tfp,
 
 		if (rc) {
 			struct tf_rm_free_parms fparms = { 0 };
+			uint32_t rm_tbl_scope_id;
+
+			/* TODO: support allocation of table scope from
+			 * min in HCAPI RM.  For now call adjust function
+			 * on value obtained from RM.
+			 */
+			rm_tbl_scope_id =
+				tf_tbl_scope_adjust(parms->tbl_scope_id);
+
+			if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+				return -EINVAL;
 
 			TFP_DRV_LOG(ERR,
 				    "System alloc mmap failed\n");
 			/* Free Table control block */
 			fparms.rm_db = eem_db[TF_DIR_RX];
 			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-			fparms.index = parms->tbl_scope_id;
+			fparms.index = rm_tbl_scope_id;
 			tf_rm_free(&fparms);
 			return -EINVAL;
 		}
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.h b/drivers/net/bnxt/tf_core/tf_em_common.h
index fa313c4..f71a487 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.h
+++ b/drivers/net/bnxt/tf_core/tf_em_common.h
@@ -9,7 +9,6 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
-
 /**
  * Function to search for table scope control block structure
  * with specified table scope ID.
@@ -24,6 +23,32 @@
 struct tf_tbl_scope_cb *tbl_scope_cb_find(uint32_t tbl_scope_id);
 
 /**
+ * Table Scope Allocate
+ *
+ * Allocate a table scope
+ *
+ * [in/out] pointer to tbl_scope_id
+ *
+ * Returns:
+ *  0 - success
+ *  -EINVAL - error
+ */
+int tf_tbl_scope_alloc(uint32_t *tbl_scope_id);
+
+/**
+ * Table Scope Free
+ *
+ * Free a table scope
+ *
+ * [in] tbl_scope_id to free
+ *
+ * Returns:
+ *  0 - success
+ *  -EINVAL - error
+ */
+int tf_tbl_scope_free(uint32_t tbl_scope_id);
+
+/**
  * Create and initialize a stack to use for action entries
  *
  * [in] dir
diff --git a/drivers/net/bnxt/tf_core/tf_em_host.c b/drivers/net/bnxt/tf_core/tf_em_host.c
index b5db94f..cfcb12f 100644
--- a/drivers/net/bnxt/tf_core/tf_em_host.c
+++ b/drivers/net/bnxt/tf_core/tf_em_host.c
@@ -374,14 +374,8 @@ tf_em_ext_alloc(struct tf *tfp, struct tf_alloc_tbl_scope_parms *parms)
 	struct tf_tbl_scope_cb *tbl_scope_cb;
 	struct hcapi_cfa_em_table *em_tables;
 	struct tf_free_tbl_scope_parms free_parms;
-	struct tf_rm_allocate_parms aparms = { 0 };
-	struct tf_rm_free_parms fparms = { 0 };
-
-	/* Get Table Scope control block from the session pool */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = (uint32_t *)&parms->tbl_scope_id;
-	rc = tf_rm_allocate(&aparms);
+
+	rc = tf_tbl_scope_alloc(&parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to allocate table scope\n");
@@ -478,11 +472,7 @@ tf_em_ext_alloc(struct tf *tfp, struct tf_alloc_tbl_scope_parms *parms)
 	return -EINVAL;
 
 cleanup:
-	/* Free Table control block */
-	fparms.rm_db = eem_db[TF_DIR_RX];
-	fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	fparms.index = parms->tbl_scope_id;
-	tf_rm_free(&fparms);
+	tf_tbl_scope_free(parms->tbl_scope_id);
 	return -EINVAL;
 }
 
@@ -493,7 +483,6 @@ tf_em_ext_free(struct tf *tfp,
 	int rc = 0;
 	enum tf_dir  dir;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_rm_free_parms aparms = { 0 };
 
 	tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);
 
@@ -502,11 +491,7 @@ tf_em_ext_free(struct tf *tfp,
 		return -EINVAL;
 	}
 
-	/* Free Table control block */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = parms->tbl_scope_id;
-	rc = tf_rm_free(&aparms);
+	rc = tf_tbl_scope_free(parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to free table scope\n");
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
index 1c3c702..32ee1ee 100644
--- a/drivers/net/bnxt/tf_core/tf_em_system.c
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -364,9 +364,7 @@ tf_em_ext_alloc(struct tf *tfp,
 	int rc;
 	struct tf_session *tfs;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_rm_allocate_parms aparms = { 0 };
 	struct tf_free_tbl_scope_parms free_parms;
-	struct tf_rm_free_parms fparms = { 0 };
 	int dir;
 	int i;
 	struct hcapi_cfa_em_table *em_tables;
@@ -382,10 +380,7 @@ tf_em_ext_alloc(struct tf *tfp,
 		return rc;
 	}
 
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = (uint32_t *)&parms->tbl_scope_id;
-	rc = tf_rm_allocate(&aparms);
+	rc = tf_tbl_scope_alloc(&parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to allocate table scope\n");
@@ -473,10 +468,7 @@ tf_em_ext_alloc(struct tf *tfp,
 
 cleanup:
 	/* Free Table control block */
-	fparms.rm_db = eem_db[TF_DIR_RX];
-	fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	fparms.index = parms->tbl_scope_id;
-	tf_rm_free(&fparms);
+	tf_tbl_scope_free(parms->tbl_scope_id);
 	return -EINVAL;
 }
 
@@ -488,7 +480,6 @@ tf_em_ext_free(struct tf *tfp,
 	struct tf_session *tfs;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
 	int dir;
-	struct tf_rm_free_parms aparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -503,11 +494,7 @@ tf_em_ext_free(struct tf *tfp,
 
 	tbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];
 
-		/* Free Table control block */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = parms->tbl_scope_id;
-	rc = tf_rm_free(&aparms);
+	rc = tf_tbl_scope_free(parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to free table scope\n");
-- 
2.7.4


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

* [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (3 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask Somnath Kotur
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Extended the ulp blob to extract data from the blob for a given
offset and length. The support is added only for little endian
format.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_utils.c | 76 +++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_ulp/ulp_utils.h | 17 +++++++++
 2 files changed, 93 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.c b/drivers/net/bnxt/tf_ulp/ulp_utils.c
index 3afaac6..a923da8 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_utils.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.c
@@ -418,6 +418,82 @@ ulp_blob_pad_push(struct ulp_blob *blob,
 	return datalen;
 }
 
+/* Get data from src and put into dst using little-endian format */
+static void
+ulp_bs_get_lsb(uint8_t *src, uint16_t bitpos, uint8_t bitlen, uint8_t *dst)
+{
+	uint8_t bitoffs = bitpos % ULP_BLOB_BYTE;
+	uint16_t index  = ULP_BITS_2_BYTE_NR(bitpos);
+	uint8_t mask, partial, shift;
+
+	shift = bitoffs;
+	partial = ULP_BLOB_BYTE - bitoffs;
+	if (bitoffs + bitlen <= ULP_BLOB_BYTE) {
+		mask = ((1 << bitlen) - 1) << shift;
+		*dst = (src[index] & mask) >> shift;
+	} else {
+		mask = ((1 << partial) - 1) << shift;
+		*dst = (src[index] & mask) >> shift;
+		index++;
+		partial = bitlen - partial;
+		mask = ((1 << partial) - 1);
+		*dst |= (src[index] & mask) << (ULP_BLOB_BYTE - bitoffs);
+	}
+}
+
+/* Assuming that src is in little-Endian Format */
+static void
+ulp_bs_pull_lsb(uint8_t *src, uint8_t *dst, uint32_t size,
+		uint32_t offset, uint32_t len)
+{
+	uint32_t idx;
+	uint32_t cnt = ULP_BITS_2_BYTE_NR(len);
+
+	/* iterate bytewise to get data */
+	for (idx = 0; idx < cnt; idx++) {
+		ulp_bs_get_lsb(src, offset, ULP_BLOB_BYTE,
+			       &dst[size - 1 - idx]);
+		offset += ULP_BLOB_BYTE;
+		len -= ULP_BLOB_BYTE;
+	}
+
+	/* Extract the last reminder data that is not 8 byte boundary */
+	if (len)
+		ulp_bs_get_lsb(src, offset, len, &dst[size - 1 - idx]);
+}
+
+/*
+ * Extract data from the binary blob using given offset.
+ *
+ * blob [in] The blob that data is extracted from. The blob must
+ * be initialized prior to pulling data.
+ *
+ * data [in] A pointer to put the data.
+ * data_size [in] size of the data buffer in bytes.
+ *offset [in] - Offset in the blob to extract the data in bits format.
+ * len [in] The number of bits to be pulled from the blob.
+ *
+ * Output: zero on success, -1 on failure
+ */
+int32_t
+ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
+	      uint16_t offset, uint16_t len)
+{
+	/* validate the arguments */
+	if (!blob || (offset + len) > blob->bitlen ||
+	    ULP_BYTE_2_BITS(data_size) < len) {
+		BNXT_TF_DBG(ERR, "invalid argument\n");
+		return -1; /* failure */
+	}
+
+	if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE) {
+		BNXT_TF_DBG(ERR, "Big endian pull not implemented\n");
+		return -1; /* failure */
+	}
+	ulp_bs_pull_lsb(blob->data, data, data_size, offset, len);
+	return 0;
+}
+
 /*
  * Get the data portion of the binary blob.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.h b/drivers/net/bnxt/tf_ulp/ulp_utils.h
index 97c7750..22dfb17 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_utils.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.h
@@ -229,6 +229,23 @@ ulp_blob_data_get(struct ulp_blob *blob,
 		  uint16_t *datalen);
 
 /*
+ * Extract data from the binary blob using given offset.
+ *
+ * blob [in] The blob that data is extracted from. The blob must
+ * be initialized prior to pulling data.
+ *
+ * data [in] A pointer to put the data.
+ * data_size [in] size of the data buffer in bytes.
+ *offset [in] - Offset in the blob to extract the data in bits format.
+ * len [in] The number of bits to be pulled from the blob.
+ *
+ * Output: zero on success, -1 on failure
+ */
+int32_t
+ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
+	      uint16_t offset, uint16_t len);
+
+/*
  * Adds pad to an initialized blob at the current offset
  *
  * blob [in] The blob that data is added to.  The blob must
-- 
2.7.4


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

* [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (4 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

This is a work around for the OVS setting offload rules that
are passing ipv4 tos mask as wild card and currently we do not
support.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index b943465..63f4c17 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -704,9 +704,19 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.version_ihl,
 				       sizeof(ipv4_mask->hdr.version_ihl));
+#ifdef ULP_DONT_IGNORE_TOS
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.type_of_service,
 				       sizeof(ipv4_mask->hdr.type_of_service));
+#else
+		/*
+		 * The tos field is ignored since OVS is setting it as wild card
+		 * match and it is not supported. This is a work around and
+		 * shall be addressed in the future.
+		 */
+		idx += 1;
+#endif
+
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.total_length,
 				       sizeof(ipv4_mask->hdr.total_length));
-- 
2.7.4


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

* [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (5 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria Somnath Kotur
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Add support to search for identifiers and increase the reference
count for identifiers that are already allocated.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_mapper.c | 118 ++++++++++++++++++++++++++++++++++-
 1 file changed, 115 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 86858b8..157c451 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -677,6 +677,103 @@ ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms,
 	return rc;
 }
 
+/*
+ * Process the identifier instruction and extract it from result blob.
+ * Increment the identifier reference count and store it in the flow database.
+ */
+static int32_t
+ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,
+			 struct bnxt_ulp_mapper_tbl_info *tbl,
+			 struct bnxt_ulp_mapper_ident_info *ident,
+			 struct ulp_blob *res_blob)
+{
+	struct ulp_flow_db_res_params	fid_parms;
+	uint64_t id = 0;
+	uint32_t idx;
+	struct tf_search_identifier_parms sparms = { 0 };
+	struct tf_free_identifier_parms free_parms = { 0 };
+	struct tf *tfp;
+	int rc;
+
+	/* Get the tfp from ulp context */
+	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
+	if (!tfp) {
+		BNXT_TF_DBG(ERR, "Failed to get tf pointer\n");
+		return -EINVAL;
+	}
+
+	/* Extract the index from the result blob */
+	rc = ulp_blob_pull(res_blob, (uint8_t *)&idx, sizeof(idx),
+			   ident->ident_bit_pos, ident->ident_bit_size);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Failed to extract identifier from blob\n");
+		return -EIO;
+	}
+
+	/* populate the search params and search identifier shadow table */
+	sparms.ident_type = ident->ident_type;
+	sparms.dir = tbl->direction;
+	/* convert the idx into cpu format */
+	sparms.search_id = tfp_be_to_cpu_32(idx);
+
+	/* Search identifier also increase the reference count */
+	rc = tf_search_identifier(tfp, &sparms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
+			    tf_dir_2_str(sparms.dir),
+			    tf_tbl_type_2_str(sparms.ident_type),
+			    sparms.search_id);
+		return rc;
+	}
+	BNXT_TF_INF("Search ident %s:%s:%x.success.\n",
+		    tf_dir_2_str(sparms.dir),
+		    tf_tbl_type_2_str(sparms.ident_type),
+		    sparms.search_id);
+
+	/* Write it to the regfile */
+	id = (uint64_t)tfp_cpu_to_be_64(sparms.search_id);
+	if (!ulp_regfile_write(parms->regfile, ident->regfile_idx, id)) {
+		BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n", idx);
+		rc = -EINVAL;
+		/* Need to free the identifier, so goto error */
+		goto error;
+	}
+
+	/* Link the resource to the flow in the flow db */
+	memset(&fid_parms, 0, sizeof(fid_parms));
+	fid_parms.direction = tbl->direction;
+	fid_parms.resource_func = ident->resource_func;
+	fid_parms.resource_type = ident->ident_type;
+	fid_parms.resource_hndl = sparms.search_id;
+	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
+	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
+				      parms->tbl_idx,
+				      parms->fid,
+				      &fid_parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n",
+			    rc);
+		/* Need to free the identifier, so goto error */
+		goto error;
+	}
+
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
+	ulp_mapper_ident_field_dump("Ident", ident, tbl, sparms.search_id);
+#endif
+	return 0;
+
+error:
+	/* Need to free the identifier */
+	free_parms.dir = tbl->direction;
+	free_parms.ident_type = ident->ident_type;
+	free_parms.id = sparms.search_id;
+	(void)tf_free_identifier(tfp, &free_parms);
+	BNXT_TF_DBG(ERR, "Ident extract failed for %s:%s:%x\n",
+		    ident->description,
+		    tf_dir_2_str(tbl->direction), sparms.search_id);
+	return rc;
+}
+
 static int32_t
 ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms *parms,
 				enum tf_dir dir,
@@ -1204,6 +1301,7 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 	struct tf_free_tcam_entry_parms free_parms	= { 0 };
 	uint32_t hit = 0;
 	uint16_t tmplen = 0;
+	struct ulp_blob res_blob;
 
 	/* Skip this if was handled by the cache. */
 	if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP) {
@@ -1379,9 +1477,23 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 			goto error;
 
 	} else {
-		BNXT_TF_DBG(ERR, "Not supporting search before alloc now\n");
-		rc = -EINVAL;
-		goto error;
+		struct bnxt_ulp_mapper_ident_info *idents;
+		uint32_t num_idents;
+
+		/*
+		 * Extract the listed identifiers from the result field,
+		 * no need to allocate them.
+		 */
+		idents = ulp_mapper_ident_fields_get(tbl, &num_idents);
+		for (i = 0; i < num_idents; i++) {
+			rc = ulp_mapper_ident_extract(parms, tbl,
+						      &idents[i], &res_blob);
+			if (rc) {
+				BNXT_TF_DBG(ERR,
+					    "Error in ident extraction\n");
+				goto error;
+			}
+		}
 	}
 
 	/*
-- 
2.7.4


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

* [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (6 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

The vlan mask fields were not setting the field bitmap causing
the template match process to ignore vlan fields. This change fixes
this bug.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_mapper.c     |  7 +++----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 34 +++++++++++++++++++++++---------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 157c451..051a095 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -16,6 +16,7 @@
 #include "ulp_mark_mgr.h"
 #include "ulp_flow_db.h"
 #include "ulp_mapper.h"
+#include "tf_util.h"
 
 static struct bnxt_ulp_glb_resource_info *
 ulp_mapper_glb_resource_info_list_get(uint32_t *num_entries)
@@ -719,15 +720,13 @@ ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,
 	/* Search identifier also increase the reference count */
 	rc = tf_search_identifier(tfp, &sparms);
 	if (rc) {
-		BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
+		BNXT_TF_DBG(ERR, "Search ident %s:%x failed.\n",
 			    tf_dir_2_str(sparms.dir),
-			    tf_tbl_type_2_str(sparms.ident_type),
 			    sparms.search_id);
 		return rc;
 	}
-	BNXT_TF_INF("Search ident %s:%s:%x.success.\n",
+	BNXT_TF_DBG(INFO, "Search ident %s:%x.success.\n",
 		    tf_dir_2_str(sparms.dir),
-		    tf_tbl_type_2_str(sparms.ident_type),
 		    sparms.search_id);
 
 	/* Write it to the regfile */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 63f4c17..68e59c4 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -12,6 +12,11 @@
 #include "tfp.h"
 #include "ulp_port_db.h"
 
+/* Local defines for the parsing functions */
+#define ULP_VLAN_PRIORITY_SHIFT		13 /* First 3 bits */
+#define ULP_VLAN_PRIORITY_MASK		0x700
+#define ULP_VLAN_TAG_MASK		0xFFF /* Last 12 bits*/
+
 /* Utility function to skip the void items. */
 static inline int32_t
 ulp_rte_item_skip_void(const struct rte_flow_item **item, uint32_t increment)
@@ -545,8 +550,8 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
 	 */
 	if (vlan_spec) {
 		vlan_tag = ntohs(vlan_spec->tci);
-		priority = htons(vlan_tag >> 13);
-		vlan_tag &= 0xfff;
+		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
+		vlan_tag &= ULP_VLAN_TAG_MASK;
 		vlan_tag = htons(vlan_tag);
 
 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
@@ -562,16 +567,27 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
 
 	if (vlan_mask) {
 		vlan_tag = ntohs(vlan_mask->tci);
-		priority = htons(vlan_tag >> 13);
+		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
 		vlan_tag &= 0xfff;
+
+		/*
+		 * the storage for priority and vlan tag is 2 bytes
+		 * The mask of priority which is 3 bits if it is all 1's
+		 * then make the rest bits 13 bits as 1's
+		 * so that it is matched as exact match.
+		 */
+		if (priority == ULP_VLAN_PRIORITY_MASK)
+			priority |= ~ULP_VLAN_PRIORITY_MASK;
+		if (vlan_tag == ULP_VLAN_TAG_MASK)
+			vlan_tag |= ~ULP_VLAN_TAG_MASK;
 		vlan_tag = htons(vlan_tag);
 
-		field = &params->hdr_field[idx];
-		memcpy(field->mask, &priority, field->size);
-		field++;
-		memcpy(field->mask, &vlan_tag, field->size);
-		field++;
-		memcpy(field->mask, &vlan_mask->inner_type, field->size);
+		ulp_rte_prsr_mask_copy(params, &idx, &priority,
+				       sizeof(priority));
+		ulp_rte_prsr_mask_copy(params, &idx, &vlan_tag,
+				       sizeof(vlan_tag));
+		ulp_rte_prsr_mask_copy(params, &idx, &vlan_mask->inner_type,
+				       sizeof(vlan_mask->inner_type));
 	}
 	/* Set the vlan index to new incremented value */
 	params->vlan_idx += BNXT_ULP_PROTO_HDR_S_VLAN_NUM;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (7 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action Somnath Kotur
  2020-07-14 22:36   ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Ajit Khaparde
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Increase the number of egress flow entries.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 397d0a9..6b0a403 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -127,7 +127,7 @@ ulp_ctx_session_open(struct bnxt *bp,
 	resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 8;
 
 	/* EM */
-	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 8;
+	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 2048;
 
 	/* EEM */
 	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (8 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
@ 2020-07-13  9:42   ` Somnath Kotur
  2020-07-14 22:36   ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Ajit Khaparde
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-13  9:42 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Added support for decrement TTL action.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 30 +++++++++++++++++++++++++++
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  5 +++++
 drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c |  4 ++--
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 68e59c4..4c1221a 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -189,6 +189,26 @@ bnxt_ulp_rte_parser_post_process(struct ulp_rte_parser_params *params)
 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_VF_TO_VF, 1);
 
+	/* Update the decrement ttl computational fields */
+	if (ULP_BITMAP_ISSET(params->act_bitmap.bits,
+			     BNXT_ULP_ACTION_BIT_DEC_TTL)) {
+		/*
+		 * Check that vxlan proto is included and vxlan decap
+		 * action is not set then decrement tunnel ttl.
+		 * Similarly add GRE and NVGRE in future.
+		 */
+		if ((ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
+				      BNXT_ULP_HDR_BIT_T_VXLAN) &&
+		    !ULP_BITMAP_ISSET(params->act_bitmap.bits,
+				      BNXT_ULP_ACTION_BIT_VXLAN_DECAP))) {
+			ULP_COMP_FLD_IDX_WR(params,
+					    BNXT_ULP_CF_IDX_ACT_T_DEC_TTL, 1);
+		} else {
+			ULP_COMP_FLD_IDX_WR(params,
+					    BNXT_ULP_CF_IDX_ACT_DEC_TTL, 1);
+		}
+	}
+
 	/* TBD: Handle the flow rejection scenarios */
 	return 0;
 }
@@ -1814,3 +1834,13 @@ ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
 	return BNXT_TF_RC_ERROR;
 }
+
+/* Function to handle the parsing of RTE Flow action dec ttl.*/
+int32_t
+ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *act __rte_unused,
+			    struct ulp_rte_parser_params *params)
+{
+	/* Update the act_bitmap with dec ttl */
+	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_DEC_TTL);
+	return BNXT_TF_RC_SUCCESS;
+}
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e155250..7b6b57e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -216,4 +216,9 @@ int32_t
 ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
 			       struct ulp_rte_parser_params *params);
 
+/* Function to handle the parsing of RTE Flow action dec ttl.*/
+int32_t
+ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *action_item,
+			    struct ulp_rte_parser_params *params);
+
 #endif /* _ULP_RTE_PARSER_H_ */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
index 5847e58..9a27cbf 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
@@ -259,8 +259,8 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 		.proto_act_func          = NULL
 	},
 	[RTE_FLOW_ACTION_TYPE_DEC_TTL] = {
-		.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
-		.proto_act_func          = NULL
+		.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+		.proto_act_func          = ulp_rte_dec_ttl_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_SET_TTL] = {
 		.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
-- 
2.7.4


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

* Re: [dpdk-dev] [PATCH v3 00/10] bnxt patches
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
                     ` (9 preceding siblings ...)
  2020-07-13  9:42   ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action Somnath Kotur
@ 2020-07-14 22:36   ` Ajit Khaparde
  2020-07-15 12:50     ` Ferruh Yigit
  10 siblings, 1 reply; 36+ messages in thread
From: Ajit Khaparde @ 2020-07-14 22:36 UTC (permalink / raw)
  To: Somnath Kotur; +Cc: dpdk-dev, Ferruh Yigit

On Mon, Jul 13, 2020 at 2:47 AM Somnath Kotur <somnath.kotur@broadcom.com>
wrote:

> Minor enhancments added to the TF-ULP/Core layers
>
> Farah Smith (1):
>   net/bnxt: add changes to support 2 table scopes
>
> Jay Ding (2):
>   net/bnxt: implement TF Identifier search
>   net/bnxt: check index range in bulk get
>
> Kishore Padmanabha (6):
>   net/bnxt: add support to extract data from the ulp blob
>   net/bnxt: ignore ipv4 TOS mask
>   net/bnxt: add support for identifier search and ref count
>   net/bnxt: consider VLAN fields for template match criteria
>   net/bnxt: increase the number of egress flow entries
>   net/bnxt: add support for decrement TTL action
>
> Peter Spreadborough (1):
>   net/bnxt: add option to delay EEM sysmem mapping
>
>  drivers/net/bnxt/meson.build                    |   3 +-
>  drivers/net/bnxt/tf_core/Makefile               |   1 +
>  drivers/net/bnxt/tf_core/tf_core.c              |  78 +++++++-
>  drivers/net/bnxt/tf_core/tf_core.h              |  78 +++++++-
>  drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
>  drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
>  drivers/net/bnxt/tf_core/tf_em.h                |  11 ++
>  drivers/net/bnxt/tf_core/tf_em_common.c         | 145 ++++++++++++++-
>  drivers/net/bnxt/tf_core/tf_em_common.h         |  27 ++-
>  drivers/net/bnxt/tf_core/tf_em_host.c           |  23 +--
>  drivers/net/bnxt/tf_core/tf_em_internal.c       |   2 +-
>  drivers/net/bnxt/tf_core/tf_em_system.c         |  25 +--
>  drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
>  drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
>  drivers/net/bnxt/tf_core/tf_msg.c               |   3 +-
>  drivers/net/bnxt/tf_core/tf_rm.c                |  43 +++++
>  drivers/net/bnxt/tf_core/tf_rm.h                |  45 +++++
>  drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
>  drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229
> ++++++++++++++++++++++++
>  drivers/net/bnxt/tf_core/tf_tbl.c               |  40 ++---
>  drivers/net/bnxt/tf_ulp/bnxt_ulp.c              |   2 +-
>  drivers/net/bnxt/tf_ulp/ulp_mapper.c            | 117 +++++++++++-
>  drivers/net/bnxt/tf_ulp/ulp_rte_parser.c        |  74 +++++++-
>  drivers/net/bnxt/tf_ulp/ulp_rte_parser.h        |   5 +
>  drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c   |   4 +-
>  drivers/net/bnxt/tf_ulp/ulp_utils.c             |  76 ++++++++
>  drivers/net/bnxt/tf_ulp/ulp_utils.h             |  17 ++
>  27 files changed, 1367 insertions(+), 88 deletions(-)
>  create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
>  create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h
>
> --
> v1->v2: Corrected some typos in patch 5 and 6
> v2->v3: Modified case of some words in commit summary as per
> git-check-log.sh
>
Patchset applied to dpdk-next-net-brcm. Thanks



> 2.7.4
>
>

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

* Re: [dpdk-dev] [PATCH v3 00/10] bnxt patches
  2020-07-14 22:36   ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Ajit Khaparde
@ 2020-07-15 12:50     ` Ferruh Yigit
  0 siblings, 0 replies; 36+ messages in thread
From: Ferruh Yigit @ 2020-07-15 12:50 UTC (permalink / raw)
  To: Ajit Khaparde, Somnath Kotur; +Cc: dpdk-dev

On 7/14/2020 11:36 PM, Ajit Khaparde wrote:
> 
> 
> On Mon, Jul 13, 2020 at 2:47 AM Somnath Kotur <somnath.kotur@broadcom.com
> <mailto:somnath.kotur@broadcom.com>> wrote:
> 
>     Minor enhancments added to the TF-ULP/Core layers
> 
>     Farah Smith (1):
>       net/bnxt: add changes to support 2 table scopes
> 
>     Jay Ding (2):
>       net/bnxt: implement TF Identifier search
>       net/bnxt: check index range in bulk get
> 
>     Kishore Padmanabha (6):
>       net/bnxt: add support to extract data from the ulp blob
>       net/bnxt: ignore ipv4 TOS mask
>       net/bnxt: add support for identifier search and ref count
>       net/bnxt: consider VLAN fields for template match criteria
>       net/bnxt: increase the number of egress flow entries
>       net/bnxt: add support for decrement TTL action
> 
>     Peter Spreadborough (1):
>       net/bnxt: add option to delay EEM sysmem mapping
> 
>      drivers/net/bnxt/meson.build                    |   3 +-
>      drivers/net/bnxt/tf_core/Makefile               |   1 +
>      drivers/net/bnxt/tf_core/tf_core.c              |  78 +++++++-
>      drivers/net/bnxt/tf_core/tf_core.h              |  78 +++++++-
>      drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
>      drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
>      drivers/net/bnxt/tf_core/tf_em.h                |  11 ++
>      drivers/net/bnxt/tf_core/tf_em_common.c         | 145 ++++++++++++++-
>      drivers/net/bnxt/tf_core/tf_em_common.h         |  27 ++-
>      drivers/net/bnxt/tf_core/tf_em_host.c           |  23 +--
>      drivers/net/bnxt/tf_core/tf_em_internal.c       |   2 +-
>      drivers/net/bnxt/tf_core/tf_em_system.c         |  25 +--
>      drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
>      drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
>      drivers/net/bnxt/tf_core/tf_msg.c               |   3 +-
>      drivers/net/bnxt/tf_core/tf_rm.c                |  43 +++++
>      drivers/net/bnxt/tf_core/tf_rm.h                |  45 +++++
>      drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
>      drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
>      drivers/net/bnxt/tf_core/tf_tbl.c               |  40 ++---
>      drivers/net/bnxt/tf_ulp/bnxt_ulp.c              |   2 +-
>      drivers/net/bnxt/tf_ulp/ulp_mapper.c            | 117 +++++++++++-
>      drivers/net/bnxt/tf_ulp/ulp_rte_parser.c        |  74 +++++++-
>      drivers/net/bnxt/tf_ulp/ulp_rte_parser.h        |   5 +
>      drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c   |   4 +-
>      drivers/net/bnxt/tf_ulp/ulp_utils.c             |  76 ++++++++
>      drivers/net/bnxt/tf_ulp/ulp_utils.h             |  17 ++
>      27 files changed, 1367 insertions(+), 88 deletions(-)
>      create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
>      create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h
> 
>     -- 
>     v1->v2: Corrected some typos in patch 5 and 6
>     v2->v3: Modified case of some words in commit summary as per git-check-log.sh
> 
> Patchset applied to dpdk-next-net-brcm. Thanks
> 

Hi Ajit,

The patch "net/bnxt: add support for identifier search and ref count" is causing
build error [1], can you please check it?

[1]
.../drivers/net/bnxt/tf_ulp/ulp_mapper.c: In function ‘ulp_mapper_ident_extract’:
.../drivers/net/bnxt/tf_ulp/ulp_mapper.c:723:8: error: implicit declaration of
function ‘tf_dir_2_str’ [-Werror=implicit-function-declaration]
  723 |        tf_dir_2_str(sparms.dir),
      |        ^~~~~~~~~~~~
.../drivers/net/bnxt/bnxt.h:867:16: note: in definition of macro ‘PMD_DRV_LOG_RAW’
  867 |   __func__, ## args)
      |                ^~~~
.../drivers/net/bnxt/tf_ulp/bnxt_tf_common.h:14:40: note: in expansion of macro
‘PMD_DRV_LOG’
   14 | #define BNXT_TF_DBG(lvl, fmt, args...) PMD_DRV_LOG(lvl, fmt, ## args)
      |                                        ^~~~~~~~~~~
.../drivers/net/bnxt/tf_ulp/ulp_mapper.c:722:3: note: in expansion of macro
‘BNXT_TF_DBG’
  722 |   BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
      |   ^~~~~~~~~~~


      .../drivers/net/bnxt/bnxt.h:866:50: error: format ‘%s’ expects argument of
type ‘char *’, but argument 5 has type ‘int’ [-Werror=format=]
  866 |  rte_log(RTE_LOG_ ## level, bnxt_logtype_driver, "%s(): " fmt, \
      |                                                  ^~~~~~~~
.../drivers/net/bnxt/bnxt.h:870:4: note: in expansion of macro ‘PMD_DRV_LOG_RAW’
  870 |    PMD_DRV_LOG_RAW(level, fmt, ## args)
      |    ^~~~~~~~~~~~~~~
.../drivers/net/bnxt/tf_ulp/bnxt_tf_common.h:14:40: note: in expansion of macro
‘PMD_DRV_LOG’
   14 | #define BNXT_TF_DBG(lvl, fmt, args...) PMD_DRV_LOG(lvl, fmt, ## args)
      |                                        ^~~~~~~~~~~
.../drivers/net/bnxt/tf_ulp/ulp_mapper.c:722:3: note: in expansion of macro
‘BNXT_TF_DBG’
  722 |   BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
      |   ^~~~~~~~~~~
.../drivers/net/bnxt/tf_ulp/ulp_mapper.c:722:35: note: format string is defined here
  722 |   BNXT_TF_DBG(ERR, "Search ident %s:%s:%x failed.\n",
      |                                  ~^
      |                                   |
      |                                   char *
      |                                  %d


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

* [dpdk-dev] [PATCH v4 00/10] bnxt patches
  2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
                   ` (10 preceding siblings ...)
  2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
@ 2020-07-15 13:50 ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
                     ` (10 more replies)
  11 siblings, 11 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Minor enhancments added to the TF-ULP/Core layers

Farah Smith (1):
  net/bnxt: add changes to support 2 table scopes

Jay Ding (2):
  net/bnxt: implement TF Identifier search
  net/bnxt: check index range in bulk get

Kishore Padmanabha (6):
  net/bnxt: add support to extract data from the ulp blob
  net/bnxt: ignore ipv4 TOS mask
  net/bnxt: add support for identifier search and ref count
  net/bnxt: consider VLAN fields for template match criteria
  net/bnxt: increase the number of egress flow entries
  net/bnxt: add support for decrement TTL action

Peter Spreadborough (1):
  net/bnxt: add option to delay EEM sysmem mapping

 drivers/net/bnxt/meson.build                    |   3 +-
 drivers/net/bnxt/tf_core/Makefile               |   1 +
 drivers/net/bnxt/tf_core/tf_core.c              |  78 +++++++-
 drivers/net/bnxt/tf_core/tf_core.h              |  78 +++++++-
 drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
 drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
 drivers/net/bnxt/tf_core/tf_em.h                |  11 ++
 drivers/net/bnxt/tf_core/tf_em_common.c         | 145 ++++++++++++++-
 drivers/net/bnxt/tf_core/tf_em_common.h         |  27 ++-
 drivers/net/bnxt/tf_core/tf_em_host.c           |  23 +--
 drivers/net/bnxt/tf_core/tf_em_internal.c       |   2 +-
 drivers/net/bnxt/tf_core/tf_em_system.c         |  25 +--
 drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
 drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
 drivers/net/bnxt/tf_core/tf_msg.c               |   3 +-
 drivers/net/bnxt/tf_core/tf_rm.c                |  43 +++++
 drivers/net/bnxt/tf_core/tf_rm.h                |  45 +++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tbl.c               |  40 ++---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c              |   2 +-
 drivers/net/bnxt/tf_ulp/ulp_mapper.c            | 117 +++++++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c        |  74 +++++++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h        |   5 +
 drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c   |   4 +-
 drivers/net/bnxt/tf_ulp/ulp_utils.c             |  76 ++++++++
 drivers/net/bnxt/tf_ulp/ulp_utils.h             |  17 ++
 27 files changed, 1367 insertions(+), 88 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h

-- 
v1->v2: Corrected some typos in patch 5 and 6
v2->v3: Modified case of some words in commit summary as per git-check-log.sh
v3->v4: Compilation fix needed in patch 7/10 mistakenly moved to patch 8/10
2.7.4


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

* [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Peter Spreadborough <peter.spreadborough@broadcom.com>

- The mapping of kernel pages for EEM sysmem operation takes
  a significant amount of time. This change give the build option
  to delay the sysmem mapping until the first write to EEM

Signed-off-by: Peter Spreadborough <peter.spreadborough@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.c        | 17 +++++++++++--
 drivers/net/bnxt/tf_core/tf_em.h          | 11 +++++++++
 drivers/net/bnxt/tf_core/tf_em_common.c   | 41 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_em_internal.c |  2 +-
 drivers/net/bnxt/tf_core/tf_em_system.c   |  6 +++--
 5 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 00b2775..a404cb8 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -49,9 +49,22 @@ tf_open_session(struct tf *tfp,
 		    &slot,
 		    &device);
 	if (rc != 4) {
-		TFP_DRV_LOG(ERR,
+		/* PCI Domain not provided (optional in DPDK), thus we
+		 * force domain to 0 and recheck.
+		 */
+		domain = 0;
+
+		/* Check parsing of bus/slot/device */
+		rc = sscanf(parms->ctrl_chan_name,
+			    "%x:%x.%d",
+			    &bus,
+			    &slot,
+			    &device);
+		if (rc != 3) {
+			TFP_DRV_LOG(ERR,
 			    "Failed to scan device ctrl_chan_name\n");
-		return -EINVAL;
+			return -EINVAL;
+		}
 	}
 
 	parms->session_id.internal.domain = domain;
diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h
index 0890261..ae2e64d 100644
--- a/drivers/net/bnxt/tf_core/tf_em.h
+++ b/drivers/net/bnxt/tf_core/tf_em.h
@@ -9,6 +9,16 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
+#ifdef TF_USE_SYSTEM_MEM
+/**
+ * Select EEM sysmem mmap export to be done at init
+ * or on the first write to EEM.
+ */
+#define TF_EM_SYSMEM_DELAY_EXPORT 1
+#else
+#define TF_EM_SYSMEM_DELAY_EXPORT 0
+#endif
+
 #define SUPPORT_CFA_HW_P4 1
 #define SUPPORT_CFA_HW_P58 0
 #define SUPPORT_CFA_HW_P59 0
@@ -482,4 +492,5 @@ int
 tf_em_ext_system_bind(struct tf *tfp,
 		      struct tf_em_cfg_parms *parms);
 
+int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb);
 #endif /* _TF_EM_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 8b02b8b..65b9abf 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -700,6 +700,26 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
 	uint64_t big_hash;
 	int rc;
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 1)
+	if (!tbl_scope_cb->valid) {
+		rc = offload_system_mmap(tbl_scope_cb);
+
+		if (rc) {
+			struct tf_rm_free_parms fparms = { 0 };
+
+			TFP_DRV_LOG(ERR,
+				    "System alloc mmap failed\n");
+			/* Free Table control block */
+			fparms.rm_db = eem_db[TF_DIR_RX];
+			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+			fparms.index = parms->tbl_scope_id;
+			tf_rm_free(&fparms);
+			return -EINVAL;
+		}
+
+		tbl_scope_cb->valid = true;
+	}
+#endif
 	/* Get mask to use on hash */
 	mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
 
@@ -1017,6 +1037,27 @@ int tf_tbl_ext_common_set(struct tf *tfp,
 		return -EINVAL;
 	}
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 1)
+	if (!tbl_scope_cb->valid) {
+		rc = offload_system_mmap(tbl_scope_cb);
+
+		if (rc) {
+			struct tf_rm_free_parms fparms = { 0 };
+
+			TFP_DRV_LOG(ERR,
+				    "System alloc mmap failed\n");
+			/* Free Table control block */
+			fparms.rm_db = eem_db[TF_DIR_RX];
+			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+			fparms.index = parms->tbl_scope_id;
+			tf_rm_free(&fparms);
+			return -EINVAL;
+		}
+
+		tbl_scope_cb->valid = true;
+	}
+#endif
+
 	op.opcode = HCAPI_CFA_HWOPS_PUT;
 	key_tbl.base0 =
 		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_RECORD_TABLE];
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
index 3129fbe..462d0fa 100644
--- a/drivers/net/bnxt/tf_core/tf_em_internal.c
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -179,7 +179,7 @@ tf_em_insert_int_entry(struct tf *tfp,
 		return -1;
 
 	PMD_DRV_LOG
-		  (ERR,
+		  (DEBUG,
 		   "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
 		   tf_dir_2_str(parms->dir),
 		   index,
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
index 339392c..1c3c702 100644
--- a/drivers/net/bnxt/tf_core/tf_em_system.c
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -272,8 +272,7 @@ tf_prepare_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)
 	return 0;
 }
 
-static int
-offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
+int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
 {
 	int rc;
 	int dmabuf_fd;
@@ -455,6 +454,7 @@ tf_em_ext_alloc(struct tf *tfp,
 		}
 	}
 
+#if (TF_EM_SYSMEM_DELAY_EXPORT == 0)
 	rc = offload_system_mmap(tbl_scope_cb);
 
 	if (rc) {
@@ -462,6 +462,7 @@ tf_em_ext_alloc(struct tf *tfp,
 			    "System alloc mmap failed\n");
 		goto cleanup_full;
 	}
+#endif
 
 	return rc;
 
@@ -527,6 +528,7 @@ tf_em_ext_free(struct tf *tfp,
 	}
 
 	tf_dmabuf_free(tfp, tbl_scope_cb);
+	tbl_scope_cb->valid = false;
 
 	return rc;
 }
-- 
2.7.4


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

* [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Jay Ding <jay.ding@broadcom.com>

Implement shadow copy DB to hold reference count for
each ID in each identifier type. Implement identifier
search functionality.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/meson.build                    |   3 +-
 drivers/net/bnxt/tf_core/Makefile               |   1 +
 drivers/net/bnxt/tf_core/tf_core.c              |  61 +++++++
 drivers/net/bnxt/tf_core/tf_core.h              |  70 +++++++-
 drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
 drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
 drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
 drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
 drivers/net/bnxt/tf_core/tf_rm.c                |   2 +
 drivers/net/bnxt/tf_core/tf_rm.h                |   8 +
 drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229 ++++++++++++++++++++++++
 12 files changed, 777 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h

diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index 0b93c31..8529b33 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -46,7 +46,7 @@ sources = files('bnxt_cpr.c',
 	'tf_core/ll.c',
 	'tf_core/tf_global_cfg.c',
 	'tf_core/tf_em_host.c',
-	'tf_ulp/ulp_fc_mgr.c',
+	'tf_core/tf_shadow_identifier.c',
 
 	'hcapi/hcapi_cfa_p4.c',
 
@@ -63,6 +63,7 @@ sources = files('bnxt_cpr.c',
 	'tf_ulp/bnxt_ulp_flow.c',
 	'tf_ulp/ulp_port_db.c',
 	'tf_ulp/ulp_def_rules.c',
+	'tf_ulp/ulp_fc_mgr.c',
 
 	'rte_pmd_bnxt.c')
 
diff --git a/drivers/net/bnxt/tf_core/Makefile b/drivers/net/bnxt/tf_core/Makefile
index 8064714..9c2735d 100644
--- a/drivers/net/bnxt/tf_core/Makefile
+++ b/drivers/net/bnxt/tf_core/Makefile
@@ -31,3 +31,4 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tcam.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_util.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_if_tbl.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_global_cfg.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_shadow_identifier.c
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index a404cb8..97e7952 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -534,6 +534,7 @@ tf_free_identifier(struct tf *tfp,
 	fparms.dir = parms->dir;
 	fparms.type = parms->ident_type;
 	fparms.id = parms->id;
+	fparms.ref_cnt = &parms->ref_cnt;
 	rc = dev->ops->tf_dev_free_ident(tfp, &fparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -547,6 +548,66 @@ tf_free_identifier(struct tf *tfp,
 }
 
 int
+tf_search_identifier(struct tf *tfp,
+		     struct tf_search_identifier_parms *parms)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_ident_search_parms sparms;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Can't do static initialization due to UT enum check */
+	memset(&sparms, 0, sizeof(struct tf_ident_search_parms));
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup device, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_search_ident == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Operation not supported, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	sparms.dir = parms->dir;
+	sparms.type = parms->ident_type;
+	sparms.search_id = parms->search_id;
+	sparms.hit = &parms->hit;
+	sparms.ref_cnt = &parms->ref_cnt;
+	rc = dev->ops->tf_dev_search_ident(tfp, &sparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Identifier search failed, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	return 0;
+}
+
+int
 tf_alloc_tcam_entry(struct tf *tfp,
 		    struct tf_alloc_tcam_entry_parms *parms)
 {
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 9e80426..9a5e816 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -695,9 +695,9 @@ struct tf_alloc_identifier_parms {
 	 */
 	enum tf_identifier_type ident_type;
 	/**
-	 * [out] Identifier allocated
+	 * [out] Allocated identifier
 	 */
-	uint16_t id;
+	uint32_t id;
 };
 
 /**
@@ -715,7 +715,38 @@ struct tf_free_identifier_parms {
 	/**
 	 * [in] ID to free
 	 */
-	uint16_t id;
+	uint32_t id;
+	/**
+	 * (experimental)
+	 * [out] Current refcnt after free
+	 */
+	uint32_t ref_cnt;
+};
+
+/**
+ * tf_search_identifier parameter definition (experimental)
+ */
+struct tf_search_identifier_parms {
+	/**
+	 * [in]	 receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type ident_type;
+	/**
+	 * [in] Identifier data to search for
+	 */
+	uint32_t search_id;
+	/**
+	 * [out] Set if matching identifier found
+	 */
+	bool hit;
+	/**
+	 * [out] Current ref count after allocation
+	 */
+	uint32_t ref_cnt;
 };
 
 /**
@@ -724,6 +755,9 @@ struct tf_free_identifier_parms {
  * TruFlow core will allocate a free id from the per identifier resource type
  * pool reserved for the session during tf_open().  No firmware is involved.
  *
+ * If shadow copy is enabled, the internal ref_cnt is set to 1 in the
+ * shadow table for a newly allocated resource.
+ *
  * Returns success or failure code.
  */
 int tf_alloc_identifier(struct tf *tfp,
@@ -736,12 +770,42 @@ int tf_alloc_identifier(struct tf *tfp,
  * reserved for the session.  No firmware is involved.  During tf_close, the
  * complete pool is returned to the firmware.
  *
+ * additional operation (experimental)
+ * Decrement reference count.  Only release resource once refcnt goes to 0 if
+ * shadow copy is enabled.
+ *
  * Returns success or failure code.
  */
 int tf_free_identifier(struct tf *tfp,
 		       struct tf_free_identifier_parms *parms);
 
 /**
+ * Search identifier resource (experimental)
+ *
+ * If the shadow copy is enabled search_id is used to search for a matching
+ * entry in the shadow table.  The shadow table consists of an array of
+ * reference counts indexed by identifier.  If a matching entry is found hit is
+ * set to TRUE, refcnt is increased by 1 and returned.  Otherwise, hit is
+ * set to false and refcnt is set to 0.
+ *
+ * TODO: we may need a per table internal shadow copy enable flag to stage
+ * the shadow table implementation.  We do not need the shadow table for other
+ * tables at this time so we may only want to enable the identifier shadow.
+ *
+ * TODO: remove this pseudocode below added to show that if search fails
+ * we shouldn't allocate a new entry but return.
+ *
+ * identifier alloc (search_en=1)
+ * if (ident is allocated and ref_cnt >=1)
+ *      return ident - hit is set, incr refcnt
+ * else (not found)
+ *      return
+ *
+ */
+int tf_search_identifier(struct tf *tfp,
+			 struct tf_search_identifier_parms *parms);
+
+/**
  * @page dram_table DRAM Table Scope Interface
  *
  * @ref tf_alloc_tbl_scope
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 0bc7090..fce7f25 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -199,6 +199,26 @@ struct tf_dev_ops {
 				 struct tf_ident_free_parms *parms);
 
 	/**
+	 * Search of an identifier element.
+	 *
+	 * This API search the specified identifier element from a
+	 * device specific identifier shadow DB. The allocated element
+	 * is returned.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to identifier search parameters
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_search_ident)(struct tf *tfp,
+				   struct tf_ident_search_parms *parms);
+
+	/**
 	 * Allocation of a table type element.
 	 *
 	 * This API allocates the specified table type element from a
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index dfe626c..f38c38e 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -86,6 +86,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = NULL,
 	.tf_dev_free_ident = NULL,
+	.tf_dev_search_ident = NULL,
 	.tf_dev_alloc_ext_tbl = NULL,
 	.tf_dev_alloc_tbl = NULL,
 	.tf_dev_free_ext_tbl = NULL,
@@ -120,6 +121,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info,
 	.tf_dev_alloc_ident = tf_ident_alloc,
 	.tf_dev_free_ident = tf_ident_free,
+	.tf_dev_search_ident = tf_ident_search,
 	.tf_dev_alloc_tbl = tf_tbl_alloc,
 	.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,
 	.tf_dev_free_tbl = tf_tbl_free,
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index 90aeaa4..273d629 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -6,6 +6,7 @@
 #include <rte_common.h>
 
 #include "tf_identifier.h"
+#include "tf_shadow_identifier.h"
 #include "tf_common.h"
 #include "tf_rm.h"
 #include "tf_util.h"
@@ -23,6 +24,16 @@ static void *ident_db[TF_DIR_MAX];
  */
 static uint8_t init;
 
+/**
+ * Identifier shadow DBs.
+ */
+static void *ident_shadow_db[TF_DIR_MAX];
+
+/**
+ * Shadow DB Init flag, set on bind and cleared on unbind
+ */
+static uint8_t shadow_init;
+
 int
 tf_ident_bind(struct tf *tfp,
 	      struct tf_ident_cfg_parms *parms)
@@ -30,6 +41,8 @@ tf_ident_bind(struct tf *tfp,
 	int rc;
 	int i;
 	struct tf_rm_create_db_parms db_cfg = { 0 };
+	struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 };
+	struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -55,6 +68,23 @@ tf_ident_bind(struct tf *tfp,
 
 			return rc;
 		}
+
+		if (parms->shadow_copy) {
+			shadow_cfg.alloc_cnt =
+				parms->resources->ident_cnt[i].cnt;
+			shadow_cdb.num_elements = parms->num_elements;
+			shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i];
+			shadow_cdb.cfg = &shadow_cfg;
+			rc = tf_shadow_ident_create_db(&shadow_cdb);
+			if (rc) {
+				TFP_DRV_LOG(ERR,
+				    "%s: Ident shadow DB creation failed\n",
+				    tf_dir_2_str(i));
+
+				return rc;
+			}
+			shadow_init = 1;
+		}
 	}
 
 	init = 1;
@@ -71,6 +101,7 @@ tf_ident_unbind(struct tf *tfp)
 	int rc = 0;
 	int i;
 	struct tf_rm_free_db_parms fparms = { 0 };
+	struct tf_shadow_ident_free_db_parms sparms = { 0 };
 
 	TF_CHECK_PARMS1(tfp);
 
@@ -89,10 +120,22 @@ tf_ident_unbind(struct tf *tfp)
 			TFP_DRV_LOG(ERR,
 				    "rm free failed on unbind\n");
 		}
+		if (shadow_init) {
+			sparms.tf_shadow_ident_db = ident_shadow_db[i];
+			rc = tf_shadow_ident_free_db(&sparms);
+			if (rc) {
+				/* TODO: If there are failures on unbind we
+				 * really just have to try until all DBs are
+				 * attempted to be cleared.
+				 */
+			}
+			ident_shadow_db[i] = NULL;
+		}
 		ident_db[i] = NULL;
 	}
 
 	init = 0;
+	shadow_init = 0;
 
 	return 0;
 }
@@ -103,7 +146,9 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 {
 	int rc;
 	uint32_t id;
+	uint32_t base_id;
 	struct tf_rm_allocate_parms aparms = { 0 };
+	struct tf_shadow_ident_insert_parms iparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -118,6 +163,7 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 	aparms.rm_db = ident_db[parms->dir];
 	aparms.db_index = parms->type;
 	aparms.index = &id;
+	aparms.base_index = &base_id;
 	rc = tf_rm_allocate(&aparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -127,6 +173,21 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 		return rc;
 	}
 
+	if (shadow_init) {
+		iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+		iparms.type = parms->type;
+		iparms.id = base_id;
+
+		rc = tf_shadow_ident_insert(&iparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Failed insert shadow DB, type:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    parms->type);
+			return rc;
+		}
+	}
+
 	*parms->id = id;
 
 	return 0;
@@ -139,7 +200,9 @@ tf_ident_free(struct tf *tfp __rte_unused,
 	int rc;
 	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_free_parms fparms = { 0 };
+	struct tf_shadow_ident_remove_parms rparms = { 0 };
 	int allocated = 0;
+	uint32_t base_id;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -154,6 +217,7 @@ tf_ident_free(struct tf *tfp __rte_unused,
 	aparms.rm_db = ident_db[parms->dir];
 	aparms.db_index = parms->type;
 	aparms.index = parms->id;
+	aparms.base_index = &base_id;
 	aparms.allocated = &allocated;
 	rc = tf_rm_is_allocated(&aparms);
 	if (rc)
@@ -168,6 +232,27 @@ tf_ident_free(struct tf *tfp __rte_unused,
 		return -EINVAL;
 	}
 
+	if (shadow_init) {
+		rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+		rparms.type = parms->type;
+		rparms.id = base_id;
+		rparms.ref_cnt = parms->ref_cnt;
+
+		rc = tf_shadow_ident_remove(&rparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: ref_cnt was 0 in shadow DB,"
+				    " type:%d, index:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    parms->type,
+				    parms->id);
+			return rc;
+		}
+
+		if (*rparms.ref_cnt > 0)
+			return 0;
+	}
+
 	/* Free requested element */
 	fparms.rm_db = ident_db[parms->dir];
 	fparms.db_index = parms->type;
@@ -184,3 +269,66 @@ tf_ident_free(struct tf *tfp __rte_unused,
 
 	return 0;
 }
+
+int
+tf_ident_search(struct tf *tfp __rte_unused,
+		struct tf_ident_search_parms *parms)
+{
+	int rc;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_shadow_ident_search_parms sparms = { 0 };
+	int allocated = 0;
+	uint32_t base_id;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No Identifier DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	if (!shadow_init) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Identifier Shadow copy is not enabled\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
+	/* Check if element is in use */
+	aparms.rm_db = ident_db[parms->dir];
+	aparms.db_index = parms->type;
+	aparms.index = parms->search_id;
+	aparms.base_index = &base_id;
+	aparms.allocated = &allocated;
+	rc = tf_rm_is_allocated(&aparms);
+	if (rc)
+		return rc;
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry not allocated, type:%d, index:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    parms->search_id);
+		return -EINVAL;
+	}
+
+	sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
+	sparms.type = parms->type;
+	sparms.search_id = base_id;
+	sparms.hit = parms->hit;
+	sparms.ref_cnt = parms->ref_cnt;
+
+	rc = tf_shadow_ident_search(&sparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed search shadow DB, type:%d\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type);
+		return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h
index 6e36c52..6d9fa08 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.h
+++ b/drivers/net/bnxt/tf_core/tf_identifier.h
@@ -66,6 +66,37 @@ struct tf_ident_free_parms {
 	 * [in] ID to free
 	 */
 	uint16_t id;
+	/**
+	 * (experimental)
+	 * [out] Current refcnt after free
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * Identifier search parameter definition
+ */
+struct tf_ident_search_parms {
+	/**
+	 * [in]  receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Identifier data to search for
+	 */
+	uint16_t search_id;
+	/**
+	 * [out] Set if matching identifier found
+	 */
+	bool *hit;
+	/**
+	 * [out] Current ref count after allocation
+	 */
+	uint32_t *ref_cnt;
 };
 
 /**
@@ -144,4 +175,20 @@ int tf_ident_alloc(struct tf *tfp,
 int tf_ident_free(struct tf *tfp,
 		  struct tf_ident_free_parms *parms);
 
+/**
+ * Search a single identifier type.
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_ident_search(struct tf *tfp,
+		    struct tf_ident_search_parms *parms);
+
 #endif /* _TF_IDENTIFIER_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index fdb87ec..78bc231 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -755,6 +755,7 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 	}
 
 	*parms->index = index;
+	*parms->base_index = id;
 
 	return rc;
 }
@@ -841,6 +842,7 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
 	if (rc)
 		return rc;
 
+	*parms->base_index = adj_index;
 	*parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
 				     adj_index);
 
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 775f0aa..971120a 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -204,6 +204,10 @@ struct tf_rm_allocate_parms {
 	 *              available index)
 	 */
 	uint32_t priority;
+	/**
+	 * [in] Pointer to the allocated index before adjusted.
+	 */
+	uint32_t *base_index;
 };
 
 /**
@@ -246,6 +250,10 @@ struct tf_rm_is_allocated_parms {
 	 * [in] Pointer to flag that indicates the state of the query
 	 */
 	int *allocated;
+	/**
+	 * [in] Pointer to the allocated index before adjusted.
+	 */
+	uint32_t *base_index;
 };
 
 /**
diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.c b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c
new file mode 100644
index 0000000..390d22f
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_common.h>
+
+#include "tf_shadow_identifier.h"
+#include "tf_common.h"
+#include "tf_util.h"
+#include "tfp.h"
+
+/**
+ * Shadow identifier DB element
+ */
+struct tf_shadow_ident_element {
+	/**
+	 * Identifier
+	 */
+	uint32_t *id;
+
+	/**
+	 * Reference count, array of number of identifier type entries
+	 */
+	uint32_t *ref_count;
+};
+
+/**
+ * Shadow identifier DB definition
+ */
+struct tf_shadow_ident_db {
+	/**
+	 * Number of elements in the DB
+	 */
+	uint16_t num_entries;
+
+	/**
+	 * The DB consists of an array of elements
+	 */
+	struct tf_shadow_ident_element *db;
+};
+
+int
+tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms)
+{
+	int rc;
+	int i;
+	struct tfp_calloc_parms cparms;
+	struct tf_shadow_ident_db *shadow_db;
+	struct tf_shadow_ident_element *db;
+
+	TF_CHECK_PARMS1(parms);
+
+	/* Build the shadow DB per the request */
+	cparms.nitems = 1;
+	cparms.size = sizeof(struct tf_shadow_ident_db);
+	cparms.alignment = 0;
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	shadow_db = (void *)cparms.mem_va;
+
+	/* Build the DB within shadow DB */
+	cparms.nitems = parms->num_elements;
+	cparms.size = sizeof(struct tf_shadow_ident_element);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	shadow_db->db = (struct tf_shadow_ident_element *)cparms.mem_va;
+	shadow_db->num_entries = parms->num_elements;
+
+	db = shadow_db->db;
+	for (i = 0; i < parms->num_elements; i++) {
+		/* If the element didn't request an allocation no need
+		 * to create a pool nor verify if we got a reservation.
+		 */
+		if (parms->cfg->alloc_cnt[i] == 0)
+			continue;
+
+		/* Create array */
+		cparms.nitems = parms->cfg->alloc_cnt[i];
+		cparms.size = sizeof(uint32_t);
+		rc = tfp_calloc(&cparms);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Array alloc failed, type:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    i);
+			goto fail;
+		}
+		db[i].ref_count = (uint32_t *)cparms.mem_va;
+	}
+
+	*parms->tf_shadow_ident_db = (void *)shadow_db;
+
+	return 0;
+fail:
+	tfp_free((void *)db->ref_count);
+	tfp_free((void *)db);
+	tfp_free((void *)shadow_db);
+	parms->tf_shadow_ident_db = NULL;
+
+	return -EINVAL;
+}
+
+int
+tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms)
+{
+	int i;
+	struct tf_shadow_ident_db *shadow_db;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	for (i = 0; i < shadow_db->num_entries; i++)
+		tfp_free((void *)shadow_db->db[i].ref_count);
+
+	tfp_free((void *)shadow_db->db);
+	tfp_free((void *)parms->tf_shadow_ident_db);
+
+	return 0;
+}
+
+int
+tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+	uint32_t ref_cnt = 0;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	ref_cnt = shadow_db->db[parms->type].ref_count[parms->search_id];
+	if (ref_cnt > 0) {
+		*parms->hit = 1;
+		*parms->ref_cnt = ++ref_cnt;
+		shadow_db->db[parms->type].ref_count[parms->search_id] =
+								ref_cnt;
+	} else {
+		*parms->hit = 0;
+		*parms->ref_cnt = 0;
+	}
+
+
+	return 0;
+}
+
+#define ID_REF_CNT_MAX 0xffffffff
+int
+tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+
+	/* In case of overflow, ref count keeps the max value */
+	if (shadow_db->db[parms->type].ref_count[parms->id] < ID_REF_CNT_MAX)
+		shadow_db->db[parms->type].ref_count[parms->id]++;
+	else
+		TFP_DRV_LOG(ERR,
+			    "Identifier %d in type %d reaches the max ref_cnt\n",
+			    parms->type,
+			    parms->id);
+
+	parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+
+	return 0;
+}
+
+int
+tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms)
+{
+	struct tf_shadow_ident_db *shadow_db;
+	uint32_t ref_cnt = 0;
+
+	TF_CHECK_PARMS1(parms);
+
+	shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
+	ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+	if (ref_cnt > 0)
+		shadow_db->db[parms->type].ref_count[parms->id]--;
+	else
+		return -EINVAL;
+
+	*parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_shadow_identifier.h b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h
new file mode 100644
index 0000000..dd633af
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_shadow_identifier.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_SHADOW_IDENTIFIER_H_
+#define _TF_SHADOW_IDENTIFIER_H_
+
+#include "tf_core.h"
+
+struct tf;
+
+/**
+ * The Shadow Identifier module provides shadow DB handling for identifier based
+ * TF types. A shadow DB provides the capability that allows for reuse
+ * of TF resources.
+ *
+ * A Shadow identifier DB is intended to be used by the Identifier Type module
+ * only.
+ */
+
+/**
+ * Shadow DB configuration information for a single identifier type.
+ *
+ * It is used in an array of identifier types. The array must be ordered
+ * by the TF type is represents.
+ */
+struct tf_shadow_ident_cfg_parms {
+	/**
+	 * TF Identifier type
+	 */
+	enum tf_identifier_type type;
+
+	/**
+	 * Number of entries the Shadow DB needs to hold
+	 */
+	int num_entries;
+
+	/**
+	 * Resource allocation count array. This array content
+	 * originates from the tf_session_resources that is passed in
+	 * on session open.
+	 * Array size is num_elements.
+	 */
+	uint16_t *alloc_cnt;
+};
+
+/**
+ * Shadow identifier DB creation parameters
+ */
+struct tf_shadow_ident_create_db_parms {
+	/**
+	 * [in] Receive or transmit direction.
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Configuration information for the shadow db
+	 */
+	struct tf_shadow_ident_cfg_parms *cfg;
+	/**
+	 * [in] Number of elements in the parms structure
+	 */
+	uint16_t num_elements;
+	/**
+	 * [out] Shadow identifier DB handle
+	 */
+	void **tf_shadow_ident_db;
+};
+
+/**
+ * Shadow identifier DB free parameters
+ */
+struct tf_shadow_ident_free_db_parms {
+	/**
+	 * Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+};
+
+/**
+ * Shadow identifier search parameters
+ */
+struct tf_shadow_ident_search_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Identifier type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] id to search
+	 */
+	uint16_t search_id;
+	/**
+	 * [out] Index of the found element returned if hit
+	 */
+	bool *hit;
+	/**
+	 * [out] Reference count incremented if hit
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * Shadow identifier insert parameters
+ */
+struct tf_shadow_ident_insert_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Tbl type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Entry to update
+	 */
+	uint16_t id;
+	/**
+	 * [out] Reference count after insert
+	 */
+	uint32_t ref_cnt;
+};
+
+/**
+ * Shadow identifier remove parameters
+ */
+struct tf_shadow_ident_remove_parms {
+	/**
+	 * [in] Shadow identifier DB handle
+	 */
+	void *tf_shadow_ident_db;
+	/**
+	 * [in] Tbl type
+	 */
+	enum tf_identifier_type type;
+	/**
+	 * [in] Entry to update
+	 */
+	uint16_t id;
+	/**
+	 * [out] Reference count after removal
+	 */
+	uint32_t *ref_cnt;
+};
+
+/**
+ * @page shadow_ident Shadow identifier DB
+ *
+ * @ref tf_shadow_ident_create_db
+ *
+ * @ref tf_shadow_ident_free_db
+ *
+ * @reg tf_shadow_ident_search
+ *
+ * @reg tf_shadow_ident_insert
+ *
+ * @reg tf_shadow_ident_remove
+ */
+
+/**
+ * Creates and fills a Shadow identifier DB. The DB is indexed per the
+ * parms structure.
+ *
+ * [in] parms
+ *   Pointer to create db parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms);
+
+/**
+ * Closes the Shadow identifier DB and frees all allocated
+ * resources per the associated database.
+ *
+ * [in] parms
+ *   Pointer to the free DB parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms);
+
+/**
+ * Search Shadow identifier db for matching result
+ *
+ * [in] parms
+ *   Pointer to the search parameters
+ *
+ * Returns
+ *   - (0) if successful, element was found.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms);
+
+/**
+ * Inserts an element into the Shadow identifier DB. Ref_count after insert
+ * will be incremented.
+ *
+ * [in] parms
+ *   Pointer to insert parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms);
+
+/**
+ * Removes an element from the Shadow identifier DB. Will fail if the
+ * elements ref_count is 0. Ref_count after removal will be
+ * decremented.
+ *
+ * [in] parms
+ *   Pointer to remove parameter
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms);
+
+#endif /* _TF_SHADOW_IDENTIFIER_H_ */
-- 
2.7.4


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

* [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Jay Ding <jay.ding@broadcom.com>

In tf_tbl_bulk_get, check if the indexes are in the range
of reserved tbl id instead of checking the allocation of each id.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_core.h |  8 ++++---
 drivers/net/bnxt/tf_core/tf_msg.c  |  3 ++-
 drivers/net/bnxt/tf_core/tf_rm.c   | 45 ++++++++++++++++++++++++++++++++++++--
 drivers/net/bnxt/tf_core/tf_rm.h   | 37 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tbl.c  | 40 ++++++++++++++-------------------
 5 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 9a5e816..758685e 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -1426,10 +1426,12 @@ struct tf_bulk_get_tbl_entry_parms {
 /**
  * Bulk get index table entry
  *
- * Used to retrieve a previous set index table entry.
+ * Used to retrieve a set of index table entries.
  *
- * Reads and compares with the shadow table copy (if enabled) (only
- * for internal objects).
+ * Entries within the range may not have been allocated using
+ * tf_alloc_tbl_entry() at the time of access. But the range must
+ * be within the bounds determined from tf_open_session() for the
+ * given table type.  Currently, this is only used for collecting statistics.
  *
  * Returns success or failure code. Failure will be returned if the
  * provided data buffer is too small for the data type requested.
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index 1e14d92..53515ad 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -143,7 +143,8 @@ tf_msg_session_open(struct tf *tfp,
 		return rc;
 
 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
-	*fw_session_client_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
+	*fw_session_client_id =
+		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
 
 	return rc;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index 78bc231..9aec954 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -755,7 +755,8 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
 	}
 
 	*parms->index = index;
-	*parms->base_index = id;
+	if (parms->base_index)
+		*parms->base_index = id;
 
 	return rc;
 }
@@ -842,7 +843,8 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
 	if (rc)
 		return rc;
 
-	*parms->base_index = adj_index;
+	if (parms->base_index)
+		*parms->base_index = adj_index;
 	*parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
 				     adj_index);
 
@@ -922,3 +924,42 @@ tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
 	return rc;
 
 }
+
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms)
+{
+	struct tf_rm_new_db *rm_db;
+	enum tf_rm_elem_cfg_type cfg_type;
+	uint32_t base_index;
+	uint32_t stride;
+	int rc = 0;
+
+	TF_CHECK_PARMS2(parms, parms->rm_db);
+
+	rm_db = (struct tf_rm_new_db *)parms->rm_db;
+	cfg_type = rm_db->db[parms->db_index].cfg_type;
+
+	/* Bail out if not controlled by RM */
+	if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
+		return -ENOTSUP;
+
+	/* Bail out if the pool is not valid, should never happen */
+	if (rm_db->db[parms->db_index].pool == NULL) {
+		rc = -ENOTSUP;
+		TFP_DRV_LOG(ERR,
+			    "%s: Invalid pool for this type:%d, rc:%s\n",
+			    tf_dir_2_str(rm_db->dir),
+			    parms->db_index,
+			    strerror(-rc));
+		return rc;
+	}
+
+	base_index = rm_db->db[parms->db_index].alloc.entry.start;
+	stride = rm_db->db[parms->db_index].alloc.entry.stride;
+
+	if (parms->starting_index < base_index ||
+	    parms->starting_index + parms->num_entries > base_index + stride)
+		return -EINVAL;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 971120a..97692db 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -315,6 +315,29 @@ struct tf_rm_get_inuse_count_parms {
 };
 
 /**
+ * Check if the indexes are in the range of reserved resource
+ */
+struct tf_rm_check_indexes_in_range_parms {
+	/**
+	 * [in] RM DB Handle
+	 */
+	void *rm_db;
+	/**
+	 * [in] DB Index, indicates which DB entry to perform the
+	 * action on.
+	 */
+	uint16_t db_index;
+	/**
+	 * [in] Starting index
+	 */
+	uint16_t starting_index;
+	/**
+	 * [in] number of entries
+	 */
+	uint16_t num_entries;
+};
+
+/**
  * @page rm Resource Manager
  *
  * @ref tf_rm_create_db
@@ -462,4 +485,18 @@ int tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms);
  */
 int tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms);
 
+/**
+ * Check if the requested indexes are in the range of reserved resource.
+ *
+ * [in] parms
+ *   Pointer to get inuse parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms);
+
+
 #endif /* TF_RM_NEW_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index 2b4a7c5..9ebaa34 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -350,12 +350,9 @@ tf_tbl_bulk_get(struct tf *tfp,
 		struct tf_tbl_get_bulk_parms *parms)
 {
 	int rc;
-	int i;
 	uint16_t hcapi_type;
-	uint32_t idx;
-	int allocated = 0;
-	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_get_hcapi_parms hparms = { 0 };
+	struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -366,26 +363,23 @@ tf_tbl_bulk_get(struct tf *tfp,
 
 		return -EINVAL;
 	}
-	/* Verify that the entries has been previously allocated */
-	aparms.rm_db = tbl_db[parms->dir];
-	aparms.db_index = parms->type;
-	aparms.allocated = &allocated;
-	idx = parms->starting_idx;
-	for (i = 0; i < parms->num_entries; i++) {
-		aparms.index = idx;
-		rc = tf_rm_is_allocated(&aparms);
-		if (rc)
-			return rc;
 
-		if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
-			TFP_DRV_LOG(ERR,
-				    "%s, Invalid or not allocated index, type:%d, idx:%d\n",
-				    tf_dir_2_str(parms->dir),
-				    parms->type,
-				    idx);
-			return -EINVAL;
-		}
-		idx++;
+	/* Verify that the entries are in the range of reserved resources. */
+	cparms.rm_db = tbl_db[parms->dir];
+	cparms.db_index = parms->type;
+	cparms.starting_index = parms->starting_idx;
+	cparms.num_entries = parms->num_entries;
+
+	rc = tf_rm_check_indexes_in_range(&cparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s, Invalid or %d index starting from %d"
+			    " not in range, type:%d",
+			    tf_dir_2_str(parms->dir),
+			    parms->starting_idx,
+			    parms->num_entries,
+			    parms->type);
+		return rc;
 	}
 
 	hparms.rm_db = tbl_db[parms->dir];
-- 
2.7.4


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

* [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (2 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Farah Smith <farah.smith@broadcom.com>

Need to remap the table scope ids allocated from HCAPI RM from high
to low value because for legacy devices a table scope is a set of base
addresses.  The PCIe addresses must map to a PCIe PF which exists in
the hardware.

Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_core/tf_em_common.c | 106 +++++++++++++++++++++++++++++++-
 drivers/net/bnxt/tf_core/tf_em_common.h |  27 +++++++-
 drivers/net/bnxt/tf_core/tf_em_host.c   |  23 ++-----
 drivers/net/bnxt/tf_core/tf_em_system.c |  19 +-----
 4 files changed, 137 insertions(+), 38 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 65b9abf..10c3f16 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -44,6 +44,28 @@ static enum tf_mem_type mem_type;
 /** Table scope array */
 struct tf_tbl_scope_cb tbl_scopes[TF_NUM_TBL_SCOPE];
 
+/** Table scope reversal table
+ *
+ * Table scope are allocated from 15 to 0 within HCAPI RM.  Because of the
+ * association between PFs and legacy table scopes, reverse table scope ids.
+ * 15 indicates 0, 14 indicates 1, etc... The application will only see the 0
+ * based number.  The firmware will only use the 0 based number.  Only HCAPI RM
+ * and Truflow RM believe the number is 15.  When HCAPI RM support allocation
+ * from low to high is supported, this adjust function can be removed.
+ */
+const uint32_t tbl_scope_reverse[TF_NUM_TBL_SCOPE] = {
+	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+static uint32_t
+tf_tbl_scope_adjust(uint32_t tbl_scope_id)
+{
+	if (tbl_scope_id < TF_NUM_TBL_SCOPE)
+		return tbl_scope_reverse[tbl_scope_id];
+	else
+		return TF_TBL_SCOPE_INVALID;
+};
+
+
 /* API defined in tf_em.h */
 struct tf_tbl_scope_cb *
 tbl_scope_cb_find(uint32_t tbl_scope_id)
@@ -51,11 +73,17 @@ tbl_scope_cb_find(uint32_t tbl_scope_id)
 	int i;
 	struct tf_rm_is_allocated_parms parms;
 	int allocated;
+	uint32_t rm_tbl_scope_id;
+
+	rm_tbl_scope_id = tf_tbl_scope_adjust(tbl_scope_id);
+
+	if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+		return NULL;
 
 	/* Check that id is valid */
 	parms.rm_db = eem_db[TF_DIR_RX];
 	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	parms.index = tbl_scope_id;
+	parms.index = rm_tbl_scope_id;
 	parms.allocated = &allocated;
 
 	i = tf_rm_is_allocated(&parms);
@@ -71,6 +99,61 @@ tbl_scope_cb_find(uint32_t tbl_scope_id)
 	return NULL;
 }
 
+int tf_tbl_scope_alloc(uint32_t *tbl_scope_id)
+{
+	int rc;
+	struct tf_rm_allocate_parms parms = { 0 };
+	uint32_t rm_tbl_scope_id;
+	uint32_t usr_tbl_scope_id = TF_TBL_SCOPE_INVALID;
+
+	/* Get Table Scope control block from the session pool */
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+	parms.index = &rm_tbl_scope_id;
+
+	rc = tf_rm_allocate(&parms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to allocate table scope rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	usr_tbl_scope_id = tf_tbl_scope_adjust(rm_tbl_scope_id);
+
+	if (usr_tbl_scope_id == TF_TBL_SCOPE_INVALID) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid table scope allocated id:%d\n",
+			    (int)rm_tbl_scope_id);
+		return -EINVAL;
+	}
+	*tbl_scope_id = usr_tbl_scope_id;
+	return 0;
+};
+
+int tf_tbl_scope_free(uint32_t tbl_scope_id)
+{
+	struct tf_rm_free_parms parms = { 0 };
+	uint32_t rm_tbl_scope_id;
+	uint32_t rc;
+
+	rm_tbl_scope_id = tf_tbl_scope_adjust(tbl_scope_id);
+
+	if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid table scope allocated id:%d\n",
+			    (int)tbl_scope_id);
+		return -EINVAL;
+	}
+
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
+	parms.index = rm_tbl_scope_id;
+
+	rc = tf_rm_free(&parms);
+	return rc;
+};
+
 int
 tf_create_tbl_pool_external(enum tf_dir dir,
 			    struct tf_tbl_scope_cb *tbl_scope_cb,
@@ -706,9 +789,17 @@ tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
 
 		if (rc) {
 			struct tf_rm_free_parms fparms = { 0 };
+			uint32_t rm_tbl_scope_id;
 
 			TFP_DRV_LOG(ERR,
 				    "System alloc mmap failed\n");
+
+			rm_tbl_scope_id =
+				tf_tbl_scope_adjust(parms->tbl_scope_id);
+
+			if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+				return -EINVAL;
+
 			/* Free Table control block */
 			fparms.rm_db = eem_db[TF_DIR_RX];
 			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
@@ -1043,13 +1134,24 @@ int tf_tbl_ext_common_set(struct tf *tfp,
 
 		if (rc) {
 			struct tf_rm_free_parms fparms = { 0 };
+			uint32_t rm_tbl_scope_id;
+
+			/* TODO: support allocation of table scope from
+			 * min in HCAPI RM.  For now call adjust function
+			 * on value obtained from RM.
+			 */
+			rm_tbl_scope_id =
+				tf_tbl_scope_adjust(parms->tbl_scope_id);
+
+			if (rm_tbl_scope_id == TF_TBL_SCOPE_INVALID)
+				return -EINVAL;
 
 			TFP_DRV_LOG(ERR,
 				    "System alloc mmap failed\n");
 			/* Free Table control block */
 			fparms.rm_db = eem_db[TF_DIR_RX];
 			fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-			fparms.index = parms->tbl_scope_id;
+			fparms.index = rm_tbl_scope_id;
 			tf_rm_free(&fparms);
 			return -EINVAL;
 		}
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.h b/drivers/net/bnxt/tf_core/tf_em_common.h
index fa313c4..f71a487 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.h
+++ b/drivers/net/bnxt/tf_core/tf_em_common.h
@@ -9,7 +9,6 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
-
 /**
  * Function to search for table scope control block structure
  * with specified table scope ID.
@@ -24,6 +23,32 @@
 struct tf_tbl_scope_cb *tbl_scope_cb_find(uint32_t tbl_scope_id);
 
 /**
+ * Table Scope Allocate
+ *
+ * Allocate a table scope
+ *
+ * [in/out] pointer to tbl_scope_id
+ *
+ * Returns:
+ *  0 - success
+ *  -EINVAL - error
+ */
+int tf_tbl_scope_alloc(uint32_t *tbl_scope_id);
+
+/**
+ * Table Scope Free
+ *
+ * Free a table scope
+ *
+ * [in] tbl_scope_id to free
+ *
+ * Returns:
+ *  0 - success
+ *  -EINVAL - error
+ */
+int tf_tbl_scope_free(uint32_t tbl_scope_id);
+
+/**
  * Create and initialize a stack to use for action entries
  *
  * [in] dir
diff --git a/drivers/net/bnxt/tf_core/tf_em_host.c b/drivers/net/bnxt/tf_core/tf_em_host.c
index b5db94f..cfcb12f 100644
--- a/drivers/net/bnxt/tf_core/tf_em_host.c
+++ b/drivers/net/bnxt/tf_core/tf_em_host.c
@@ -374,14 +374,8 @@ tf_em_ext_alloc(struct tf *tfp, struct tf_alloc_tbl_scope_parms *parms)
 	struct tf_tbl_scope_cb *tbl_scope_cb;
 	struct hcapi_cfa_em_table *em_tables;
 	struct tf_free_tbl_scope_parms free_parms;
-	struct tf_rm_allocate_parms aparms = { 0 };
-	struct tf_rm_free_parms fparms = { 0 };
-
-	/* Get Table Scope control block from the session pool */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = (uint32_t *)&parms->tbl_scope_id;
-	rc = tf_rm_allocate(&aparms);
+
+	rc = tf_tbl_scope_alloc(&parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to allocate table scope\n");
@@ -478,11 +472,7 @@ tf_em_ext_alloc(struct tf *tfp, struct tf_alloc_tbl_scope_parms *parms)
 	return -EINVAL;
 
 cleanup:
-	/* Free Table control block */
-	fparms.rm_db = eem_db[TF_DIR_RX];
-	fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	fparms.index = parms->tbl_scope_id;
-	tf_rm_free(&fparms);
+	tf_tbl_scope_free(parms->tbl_scope_id);
 	return -EINVAL;
 }
 
@@ -493,7 +483,6 @@ tf_em_ext_free(struct tf *tfp,
 	int rc = 0;
 	enum tf_dir  dir;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_rm_free_parms aparms = { 0 };
 
 	tbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);
 
@@ -502,11 +491,7 @@ tf_em_ext_free(struct tf *tfp,
 		return -EINVAL;
 	}
 
-	/* Free Table control block */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = parms->tbl_scope_id;
-	rc = tf_rm_free(&aparms);
+	rc = tf_tbl_scope_free(parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to free table scope\n");
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
index 1c3c702..32ee1ee 100644
--- a/drivers/net/bnxt/tf_core/tf_em_system.c
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -364,9 +364,7 @@ tf_em_ext_alloc(struct tf *tfp,
 	int rc;
 	struct tf_session *tfs;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_rm_allocate_parms aparms = { 0 };
 	struct tf_free_tbl_scope_parms free_parms;
-	struct tf_rm_free_parms fparms = { 0 };
 	int dir;
 	int i;
 	struct hcapi_cfa_em_table *em_tables;
@@ -382,10 +380,7 @@ tf_em_ext_alloc(struct tf *tfp,
 		return rc;
 	}
 
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = (uint32_t *)&parms->tbl_scope_id;
-	rc = tf_rm_allocate(&aparms);
+	rc = tf_tbl_scope_alloc(&parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to allocate table scope\n");
@@ -473,10 +468,7 @@ tf_em_ext_alloc(struct tf *tfp,
 
 cleanup:
 	/* Free Table control block */
-	fparms.rm_db = eem_db[TF_DIR_RX];
-	fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	fparms.index = parms->tbl_scope_id;
-	tf_rm_free(&fparms);
+	tf_tbl_scope_free(parms->tbl_scope_id);
 	return -EINVAL;
 }
 
@@ -488,7 +480,6 @@ tf_em_ext_free(struct tf *tfp,
 	struct tf_session *tfs;
 	struct tf_tbl_scope_cb *tbl_scope_cb;
 	int dir;
-	struct tf_rm_free_parms aparms = { 0 };
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -503,11 +494,7 @@ tf_em_ext_free(struct tf *tfp,
 
 	tbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];
 
-		/* Free Table control block */
-	aparms.rm_db = eem_db[TF_DIR_RX];
-	aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
-	aparms.index = parms->tbl_scope_id;
-	rc = tf_rm_free(&aparms);
+	rc = tf_tbl_scope_free(parms->tbl_scope_id);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "Failed to free table scope\n");
-- 
2.7.4


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

* [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (3 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask Somnath Kotur
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Extended the ulp blob to extract data from the blob for a given
offset and length. The support is added only for little endian
format.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_utils.c | 76 +++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/tf_ulp/ulp_utils.h | 17 +++++++++
 2 files changed, 93 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.c b/drivers/net/bnxt/tf_ulp/ulp_utils.c
index 3afaac6..a923da8 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_utils.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.c
@@ -418,6 +418,82 @@ ulp_blob_pad_push(struct ulp_blob *blob,
 	return datalen;
 }
 
+/* Get data from src and put into dst using little-endian format */
+static void
+ulp_bs_get_lsb(uint8_t *src, uint16_t bitpos, uint8_t bitlen, uint8_t *dst)
+{
+	uint8_t bitoffs = bitpos % ULP_BLOB_BYTE;
+	uint16_t index  = ULP_BITS_2_BYTE_NR(bitpos);
+	uint8_t mask, partial, shift;
+
+	shift = bitoffs;
+	partial = ULP_BLOB_BYTE - bitoffs;
+	if (bitoffs + bitlen <= ULP_BLOB_BYTE) {
+		mask = ((1 << bitlen) - 1) << shift;
+		*dst = (src[index] & mask) >> shift;
+	} else {
+		mask = ((1 << partial) - 1) << shift;
+		*dst = (src[index] & mask) >> shift;
+		index++;
+		partial = bitlen - partial;
+		mask = ((1 << partial) - 1);
+		*dst |= (src[index] & mask) << (ULP_BLOB_BYTE - bitoffs);
+	}
+}
+
+/* Assuming that src is in little-Endian Format */
+static void
+ulp_bs_pull_lsb(uint8_t *src, uint8_t *dst, uint32_t size,
+		uint32_t offset, uint32_t len)
+{
+	uint32_t idx;
+	uint32_t cnt = ULP_BITS_2_BYTE_NR(len);
+
+	/* iterate bytewise to get data */
+	for (idx = 0; idx < cnt; idx++) {
+		ulp_bs_get_lsb(src, offset, ULP_BLOB_BYTE,
+			       &dst[size - 1 - idx]);
+		offset += ULP_BLOB_BYTE;
+		len -= ULP_BLOB_BYTE;
+	}
+
+	/* Extract the last reminder data that is not 8 byte boundary */
+	if (len)
+		ulp_bs_get_lsb(src, offset, len, &dst[size - 1 - idx]);
+}
+
+/*
+ * Extract data from the binary blob using given offset.
+ *
+ * blob [in] The blob that data is extracted from. The blob must
+ * be initialized prior to pulling data.
+ *
+ * data [in] A pointer to put the data.
+ * data_size [in] size of the data buffer in bytes.
+ *offset [in] - Offset in the blob to extract the data in bits format.
+ * len [in] The number of bits to be pulled from the blob.
+ *
+ * Output: zero on success, -1 on failure
+ */
+int32_t
+ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
+	      uint16_t offset, uint16_t len)
+{
+	/* validate the arguments */
+	if (!blob || (offset + len) > blob->bitlen ||
+	    ULP_BYTE_2_BITS(data_size) < len) {
+		BNXT_TF_DBG(ERR, "invalid argument\n");
+		return -1; /* failure */
+	}
+
+	if (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE) {
+		BNXT_TF_DBG(ERR, "Big endian pull not implemented\n");
+		return -1; /* failure */
+	}
+	ulp_bs_pull_lsb(blob->data, data, data_size, offset, len);
+	return 0;
+}
+
 /*
  * Get the data portion of the binary blob.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.h b/drivers/net/bnxt/tf_ulp/ulp_utils.h
index 97c7750..22dfb17 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_utils.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.h
@@ -229,6 +229,23 @@ ulp_blob_data_get(struct ulp_blob *blob,
 		  uint16_t *datalen);
 
 /*
+ * Extract data from the binary blob using given offset.
+ *
+ * blob [in] The blob that data is extracted from. The blob must
+ * be initialized prior to pulling data.
+ *
+ * data [in] A pointer to put the data.
+ * data_size [in] size of the data buffer in bytes.
+ *offset [in] - Offset in the blob to extract the data in bits format.
+ * len [in] The number of bits to be pulled from the blob.
+ *
+ * Output: zero on success, -1 on failure
+ */
+int32_t
+ulp_blob_pull(struct ulp_blob *blob, uint8_t *data, uint32_t data_size,
+	      uint16_t offset, uint16_t len);
+
+/*
  * Adds pad to an initialized blob at the current offset
  *
  * blob [in] The blob that data is added to.  The blob must
-- 
2.7.4


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

* [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (4 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

This is a work around for the OVS setting offload rules that
are passing ipv4 tos mask as wild card and currently we do not
support.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index b943465..63f4c17 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -704,9 +704,19 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.version_ihl,
 				       sizeof(ipv4_mask->hdr.version_ihl));
+#ifdef ULP_DONT_IGNORE_TOS
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.type_of_service,
 				       sizeof(ipv4_mask->hdr.type_of_service));
+#else
+		/*
+		 * The tos field is ignored since OVS is setting it as wild card
+		 * match and it is not supported. This is a work around and
+		 * shall be addressed in the future.
+		 */
+		idx += 1;
+#endif
+
 		ulp_rte_prsr_mask_copy(params, &idx,
 				       &ipv4_mask->hdr.total_length,
 				       sizeof(ipv4_mask->hdr.total_length));
-- 
2.7.4


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

* [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (5 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria Somnath Kotur
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Add support to search for identifiers and increase the reference
count for identifiers that are already allocated.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_mapper.c | 117 ++++++++++++++++++++++++++++++++++-
 1 file changed, 114 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 86858b8..051a095 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -16,6 +16,7 @@
 #include "ulp_mark_mgr.h"
 #include "ulp_flow_db.h"
 #include "ulp_mapper.h"
+#include "tf_util.h"
 
 static struct bnxt_ulp_glb_resource_info *
 ulp_mapper_glb_resource_info_list_get(uint32_t *num_entries)
@@ -677,6 +678,101 @@ ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms,
 	return rc;
 }
 
+/*
+ * Process the identifier instruction and extract it from result blob.
+ * Increment the identifier reference count and store it in the flow database.
+ */
+static int32_t
+ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,
+			 struct bnxt_ulp_mapper_tbl_info *tbl,
+			 struct bnxt_ulp_mapper_ident_info *ident,
+			 struct ulp_blob *res_blob)
+{
+	struct ulp_flow_db_res_params	fid_parms;
+	uint64_t id = 0;
+	uint32_t idx;
+	struct tf_search_identifier_parms sparms = { 0 };
+	struct tf_free_identifier_parms free_parms = { 0 };
+	struct tf *tfp;
+	int rc;
+
+	/* Get the tfp from ulp context */
+	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
+	if (!tfp) {
+		BNXT_TF_DBG(ERR, "Failed to get tf pointer\n");
+		return -EINVAL;
+	}
+
+	/* Extract the index from the result blob */
+	rc = ulp_blob_pull(res_blob, (uint8_t *)&idx, sizeof(idx),
+			   ident->ident_bit_pos, ident->ident_bit_size);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Failed to extract identifier from blob\n");
+		return -EIO;
+	}
+
+	/* populate the search params and search identifier shadow table */
+	sparms.ident_type = ident->ident_type;
+	sparms.dir = tbl->direction;
+	/* convert the idx into cpu format */
+	sparms.search_id = tfp_be_to_cpu_32(idx);
+
+	/* Search identifier also increase the reference count */
+	rc = tf_search_identifier(tfp, &sparms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Search ident %s:%x failed.\n",
+			    tf_dir_2_str(sparms.dir),
+			    sparms.search_id);
+		return rc;
+	}
+	BNXT_TF_DBG(INFO, "Search ident %s:%x.success.\n",
+		    tf_dir_2_str(sparms.dir),
+		    sparms.search_id);
+
+	/* Write it to the regfile */
+	id = (uint64_t)tfp_cpu_to_be_64(sparms.search_id);
+	if (!ulp_regfile_write(parms->regfile, ident->regfile_idx, id)) {
+		BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n", idx);
+		rc = -EINVAL;
+		/* Need to free the identifier, so goto error */
+		goto error;
+	}
+
+	/* Link the resource to the flow in the flow db */
+	memset(&fid_parms, 0, sizeof(fid_parms));
+	fid_parms.direction = tbl->direction;
+	fid_parms.resource_func = ident->resource_func;
+	fid_parms.resource_type = ident->ident_type;
+	fid_parms.resource_hndl = sparms.search_id;
+	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
+	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
+				      parms->tbl_idx,
+				      parms->fid,
+				      &fid_parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n",
+			    rc);
+		/* Need to free the identifier, so goto error */
+		goto error;
+	}
+
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
+	ulp_mapper_ident_field_dump("Ident", ident, tbl, sparms.search_id);
+#endif
+	return 0;
+
+error:
+	/* Need to free the identifier */
+	free_parms.dir = tbl->direction;
+	free_parms.ident_type = ident->ident_type;
+	free_parms.id = sparms.search_id;
+	(void)tf_free_identifier(tfp, &free_parms);
+	BNXT_TF_DBG(ERR, "Ident extract failed for %s:%s:%x\n",
+		    ident->description,
+		    tf_dir_2_str(tbl->direction), sparms.search_id);
+	return rc;
+}
+
 static int32_t
 ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms *parms,
 				enum tf_dir dir,
@@ -1204,6 +1300,7 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 	struct tf_free_tcam_entry_parms free_parms	= { 0 };
 	uint32_t hit = 0;
 	uint16_t tmplen = 0;
+	struct ulp_blob res_blob;
 
 	/* Skip this if was handled by the cache. */
 	if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP) {
@@ -1379,9 +1476,23 @@ ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
 			goto error;
 
 	} else {
-		BNXT_TF_DBG(ERR, "Not supporting search before alloc now\n");
-		rc = -EINVAL;
-		goto error;
+		struct bnxt_ulp_mapper_ident_info *idents;
+		uint32_t num_idents;
+
+		/*
+		 * Extract the listed identifiers from the result field,
+		 * no need to allocate them.
+		 */
+		idents = ulp_mapper_ident_fields_get(tbl, &num_idents);
+		for (i = 0; i < num_idents; i++) {
+			rc = ulp_mapper_ident_extract(parms, tbl,
+						      &idents[i], &res_blob);
+			if (rc) {
+				BNXT_TF_DBG(ERR,
+					    "Error in ident extraction\n");
+				goto error;
+			}
+		}
 	}
 
 	/*
-- 
2.7.4


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

* [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (6 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

The vlan mask fields were not setting the field bitmap causing
the template match process to ignore vlan fields. This change fixes
this bug.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 34 +++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 63f4c17..68e59c4 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -12,6 +12,11 @@
 #include "tfp.h"
 #include "ulp_port_db.h"
 
+/* Local defines for the parsing functions */
+#define ULP_VLAN_PRIORITY_SHIFT		13 /* First 3 bits */
+#define ULP_VLAN_PRIORITY_MASK		0x700
+#define ULP_VLAN_TAG_MASK		0xFFF /* Last 12 bits*/
+
 /* Utility function to skip the void items. */
 static inline int32_t
 ulp_rte_item_skip_void(const struct rte_flow_item **item, uint32_t increment)
@@ -545,8 +550,8 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
 	 */
 	if (vlan_spec) {
 		vlan_tag = ntohs(vlan_spec->tci);
-		priority = htons(vlan_tag >> 13);
-		vlan_tag &= 0xfff;
+		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
+		vlan_tag &= ULP_VLAN_TAG_MASK;
 		vlan_tag = htons(vlan_tag);
 
 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
@@ -562,16 +567,27 @@ ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
 
 	if (vlan_mask) {
 		vlan_tag = ntohs(vlan_mask->tci);
-		priority = htons(vlan_tag >> 13);
+		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
 		vlan_tag &= 0xfff;
+
+		/*
+		 * the storage for priority and vlan tag is 2 bytes
+		 * The mask of priority which is 3 bits if it is all 1's
+		 * then make the rest bits 13 bits as 1's
+		 * so that it is matched as exact match.
+		 */
+		if (priority == ULP_VLAN_PRIORITY_MASK)
+			priority |= ~ULP_VLAN_PRIORITY_MASK;
+		if (vlan_tag == ULP_VLAN_TAG_MASK)
+			vlan_tag |= ~ULP_VLAN_TAG_MASK;
 		vlan_tag = htons(vlan_tag);
 
-		field = &params->hdr_field[idx];
-		memcpy(field->mask, &priority, field->size);
-		field++;
-		memcpy(field->mask, &vlan_tag, field->size);
-		field++;
-		memcpy(field->mask, &vlan_mask->inner_type, field->size);
+		ulp_rte_prsr_mask_copy(params, &idx, &priority,
+				       sizeof(priority));
+		ulp_rte_prsr_mask_copy(params, &idx, &vlan_tag,
+				       sizeof(vlan_tag));
+		ulp_rte_prsr_mask_copy(params, &idx, &vlan_mask->inner_type,
+				       sizeof(vlan_mask->inner_type));
 	}
 	/* Set the vlan index to new incremented value */
 	params->vlan_idx += BNXT_ULP_PROTO_HDR_S_VLAN_NUM;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (7 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action Somnath Kotur
  2020-07-16 23:04   ` [dpdk-dev] [PATCH v4 00/10] bnxt patches Ajit Khaparde
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Increase the number of egress flow entries.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 397d0a9..6b0a403 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -127,7 +127,7 @@ ulp_ctx_session_open(struct bnxt *bp,
 	resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 8;
 
 	/* EM */
-	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 8;
+	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 2048;
 
 	/* EEM */
 	resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (8 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
@ 2020-07-15 13:50   ` Somnath Kotur
  2020-07-16 23:04   ` [dpdk-dev] [PATCH v4 00/10] bnxt patches Ajit Khaparde
  10 siblings, 0 replies; 36+ messages in thread
From: Somnath Kotur @ 2020-07-15 13:50 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Kishore Padmanabha <kishore.padmanabha@broadcom.com>

Added support for decrement TTL action.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 30 +++++++++++++++++++++++++++
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  5 +++++
 drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c |  4 ++--
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 68e59c4..4c1221a 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -189,6 +189,26 @@ bnxt_ulp_rte_parser_post_process(struct ulp_rte_parser_params *params)
 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_VF_TO_VF, 1);
 
+	/* Update the decrement ttl computational fields */
+	if (ULP_BITMAP_ISSET(params->act_bitmap.bits,
+			     BNXT_ULP_ACTION_BIT_DEC_TTL)) {
+		/*
+		 * Check that vxlan proto is included and vxlan decap
+		 * action is not set then decrement tunnel ttl.
+		 * Similarly add GRE and NVGRE in future.
+		 */
+		if ((ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
+				      BNXT_ULP_HDR_BIT_T_VXLAN) &&
+		    !ULP_BITMAP_ISSET(params->act_bitmap.bits,
+				      BNXT_ULP_ACTION_BIT_VXLAN_DECAP))) {
+			ULP_COMP_FLD_IDX_WR(params,
+					    BNXT_ULP_CF_IDX_ACT_T_DEC_TTL, 1);
+		} else {
+			ULP_COMP_FLD_IDX_WR(params,
+					    BNXT_ULP_CF_IDX_ACT_DEC_TTL, 1);
+		}
+	}
+
 	/* TBD: Handle the flow rejection scenarios */
 	return 0;
 }
@@ -1814,3 +1834,13 @@ ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
 	return BNXT_TF_RC_ERROR;
 }
+
+/* Function to handle the parsing of RTE Flow action dec ttl.*/
+int32_t
+ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *act __rte_unused,
+			    struct ulp_rte_parser_params *params)
+{
+	/* Update the act_bitmap with dec ttl */
+	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_DEC_TTL);
+	return BNXT_TF_RC_SUCCESS;
+}
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e155250..7b6b57e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -216,4 +216,9 @@ int32_t
 ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
 			       struct ulp_rte_parser_params *params);
 
+/* Function to handle the parsing of RTE Flow action dec ttl.*/
+int32_t
+ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *action_item,
+			    struct ulp_rte_parser_params *params);
+
 #endif /* _ULP_RTE_PARSER_H_ */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
index 5847e58..9a27cbf 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c
@@ -259,8 +259,8 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 		.proto_act_func          = NULL
 	},
 	[RTE_FLOW_ACTION_TYPE_DEC_TTL] = {
-		.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
-		.proto_act_func          = NULL
+		.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+		.proto_act_func          = ulp_rte_dec_ttl_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_SET_TTL] = {
 		.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
-- 
2.7.4


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

* Re: [dpdk-dev] [PATCH v4 00/10] bnxt patches
  2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
                     ` (9 preceding siblings ...)
  2020-07-15 13:50   ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action Somnath Kotur
@ 2020-07-16 23:04   ` Ajit Khaparde
  10 siblings, 0 replies; 36+ messages in thread
From: Ajit Khaparde @ 2020-07-16 23:04 UTC (permalink / raw)
  To: Somnath Kotur; +Cc: dpdk-dev, Ferruh Yigit

On Wed, Jul 15, 2020 at 6:55 AM Somnath Kotur <somnath.kotur@broadcom.com>
wrote:

> Minor enhancments added to the TF-ULP/Core layers
>
> Farah Smith (1):
>   net/bnxt: add changes to support 2 table scopes
>
> Jay Ding (2):
>   net/bnxt: implement TF Identifier search
>   net/bnxt: check index range in bulk get
>
> Kishore Padmanabha (6):
>   net/bnxt: add support to extract data from the ulp blob
>   net/bnxt: ignore ipv4 TOS mask
>   net/bnxt: add support for identifier search and ref count
>   net/bnxt: consider VLAN fields for template match criteria
>   net/bnxt: increase the number of egress flow entries
>   net/bnxt: add support for decrement TTL action
>
> Peter Spreadborough (1):
>   net/bnxt: add option to delay EEM sysmem mapping
>
>  drivers/net/bnxt/meson.build                    |   3 +-
>  drivers/net/bnxt/tf_core/Makefile               |   1 +
>  drivers/net/bnxt/tf_core/tf_core.c              |  78 +++++++-
>  drivers/net/bnxt/tf_core/tf_core.h              |  78 +++++++-
>  drivers/net/bnxt/tf_core/tf_device.h            |  20 +++
>  drivers/net/bnxt/tf_core/tf_device_p4.c         |   2 +
>  drivers/net/bnxt/tf_core/tf_em.h                |  11 ++
>  drivers/net/bnxt/tf_core/tf_em_common.c         | 145 ++++++++++++++-
>  drivers/net/bnxt/tf_core/tf_em_common.h         |  27 ++-
>  drivers/net/bnxt/tf_core/tf_em_host.c           |  23 +--
>  drivers/net/bnxt/tf_core/tf_em_internal.c       |   2 +-
>  drivers/net/bnxt/tf_core/tf_em_system.c         |  25 +--
>  drivers/net/bnxt/tf_core/tf_identifier.c        | 148 +++++++++++++++
>  drivers/net/bnxt/tf_core/tf_identifier.h        |  47 +++++
>  drivers/net/bnxt/tf_core/tf_msg.c               |   3 +-
>  drivers/net/bnxt/tf_core/tf_rm.c                |  43 +++++
>  drivers/net/bnxt/tf_core/tf_rm.h                |  45 +++++
>  drivers/net/bnxt/tf_core/tf_shadow_identifier.c | 190 ++++++++++++++++++++
>  drivers/net/bnxt/tf_core/tf_shadow_identifier.h | 229
> ++++++++++++++++++++++++
>  drivers/net/bnxt/tf_core/tf_tbl.c               |  40 ++---
>  drivers/net/bnxt/tf_ulp/bnxt_ulp.c              |   2 +-
>  drivers/net/bnxt/tf_ulp/ulp_mapper.c            | 117 +++++++++++-
>  drivers/net/bnxt/tf_ulp/ulp_rte_parser.c        |  74 +++++++-
>  drivers/net/bnxt/tf_ulp/ulp_rte_parser.h        |   5 +
>  drivers/net/bnxt/tf_ulp/ulp_template_db_tbl.c   |   4 +-
>  drivers/net/bnxt/tf_ulp/ulp_utils.c             |  76 ++++++++
>  drivers/net/bnxt/tf_ulp/ulp_utils.h             |  17 ++
>  27 files changed, 1367 insertions(+), 88 deletions(-)
>  create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.c
>  create mode 100644 drivers/net/bnxt/tf_core/tf_shadow_identifier.h
>
> --
> v1->v2: Corrected some typos in patch 5 and 6
> v2->v3: Modified case of some words in commit summary as per
> git-check-log.sh
> v3->v4: Compilation fix needed in patch 7/10 mistakenly moved to patch 8/10
>
Applied to dpdk-next-net-brcm. Thanks


> 2.7.4
>
>

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

end of thread, other threads:[~2020-07-16 23:04 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-13  6:15 [dpdk-dev] [PATCH 00/10] bnxt patches Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 tos mask Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider vlan fields for the template match criteria Somnath Kotur
2020-07-13  6:15 ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
2020-07-13  6:16 ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement ttl action Somnath Kotur
2020-07-13  9:42 ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
2020-07-13  9:42   ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action Somnath Kotur
2020-07-14 22:36   ` [dpdk-dev] [PATCH v3 00/10] bnxt patches Ajit Khaparde
2020-07-15 12:50     ` Ferruh Yigit
2020-07-15 13:50 ` [dpdk-dev] [PATCH v4 " Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 01/10] net/bnxt: add option to delay EEM sysmem mapping Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 02/10] net/bnxt: implement TF Identifier search Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 03/10] net/bnxt: check index range in bulk get Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 04/10] net/bnxt: add changes to support 2 table scopes Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 05/10] net/bnxt: add support to extract data from the ulp blob Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 06/10] net/bnxt: ignore ipv4 TOS mask Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 07/10] net/bnxt: add support for identifier search and ref count Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 08/10] net/bnxt: consider VLAN fields for template match criteria Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 09/10] net/bnxt: increase the number of egress flow entries Somnath Kotur
2020-07-15 13:50   ` [dpdk-dev] [PATCH 10/10] net/bnxt: add support for decrement TTL action Somnath Kotur
2020-07-16 23:04   ` [dpdk-dev] [PATCH v4 00/10] bnxt patches Ajit Khaparde

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.