diff mbox series

[v3] net/bnxt: shared TCAM region support

Message ID 20210706223950.71669-1-ajit.khaparde@broadcom.com (mailing list archive)
State Accepted, archived
Delegated to: Ajit Khaparde
Headers show
Series [v3] net/bnxt: shared TCAM region support | expand

Checks

Context Check Description
ci/Intel-compilation warning apply issues
ci/iol-testing warning apply patch failure
ci/checkpatch success coding style OK

Commit Message

Ajit Khaparde July 6, 2021, 10:39 p.m. UTC
From: Farah Smith <farah.smith@broadcom.com>

- switch to single slice management on Wh+
- Support of shared session WC_TCAM_HIGH and WC_TCAM_LOW regions
- Enable/disable using TF_TCAM_SHARED flag in tf_core.h
- Fix empty session module DBs in the case that none are
  allocated for a given module type

Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
v1->v2: rebased to latest code base.
v2->v3: addressed review comments.
---
 drivers/net/bnxt/tf_core/meson.build      |  25 +-
 drivers/net/bnxt/tf_core/tf_core.h        |  45 +-
 drivers/net/bnxt/tf_core/tf_device.c      |  72 ++-
 drivers/net/bnxt/tf_core/tf_device.h      |   4 +-
 drivers/net/bnxt/tf_core/tf_device_p4.c   |  17 +-
 drivers/net/bnxt/tf_core/tf_device_p58.c  |  13 +-
 drivers/net/bnxt/tf_core/tf_identifier.c  |   2 +-
 drivers/net/bnxt/tf_core/tf_tbl.c         |   5 +-
 drivers/net/bnxt/tf_core/tf_tcam.c        |   5 +-
 drivers/net/bnxt/tf_core/tf_tcam_shared.c | 743 ++++++++++++++++++++++
 drivers/net/bnxt/tf_core/tf_tcam_shared.h | 127 ++++
 drivers/net/bnxt/tf_core/tf_util.c        |   6 +
 12 files changed, 1013 insertions(+), 51 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_shared.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_shared.h
diff mbox series

Patch

diff --git a/drivers/net/bnxt/tf_core/meson.build b/drivers/net/bnxt/tf_core/meson.build
index 3a91f04bc0..f28e77ec2e 100644
--- a/drivers/net/bnxt/tf_core/meson.build
+++ b/drivers/net/bnxt/tf_core/meson.build
@@ -10,26 +10,27 @@  sources += files(
         'tf_core.c',
         'bitalloc.c',
         'tf_msg.c',
-	'dpool.c',
+        'll.c',
+        'dpool.c',
         'rand.c',
         'stack.c',
-        'tf_em_common.c',
-        'tf_em_internal.c',
         'tf_rm.c',
         'tf_tbl.c',
+        'tf_em_common.c',
+        'tf_em_host.c',
+        'tf_em_internal.c',
+        'tf_em_hash_internal.c',
         'tfp.c',
-        'tf_session.c',
+        'tf_util.c',
         'tf_device.c',
         'tf_device_p4.c',
-        'tf_device_p58.c',
+        'tf_global_cfg.c',
         'tf_identifier.c',
+        'tf_if_tbl.c',
+        'tf_session.c',
         'tf_shadow_tcam.c',
         'tf_tcam.c',
-        'tf_util.c',
-        'tf_if_tbl.c',
-        'll.c',
-        'tf_global_cfg.c',
-        'tf_em_host.c',
-        'tf_em_hash_internal.c',
+        'tf_tcam_shared.c',
         'tf_shadow_identifier.c',
-        'tf_hash.c')
+        'tf_hash.c',
+        'tf_device_p58.c')
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 3d14dc5391..39a498122b 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -21,7 +21,6 @@ 
 
 /********** BEGIN Truflow Core DEFINITIONS **********/
 
-
 #define TF_KILOBYTE  1024
 #define TF_MEGABYTE  (1024 * 1024)
 
@@ -77,7 +76,6 @@  enum tf_ext_mem_chan_type {
 #define TF_ACT_REC_OFFSET_2_PTR(offset) ((offset) >> 4)
 #define TF_ACT_REC_PTR_2_OFFSET(offset) ((offset) << 4)
 
-
 /*
  * Helper Macros
  */
@@ -198,7 +196,6 @@  enum tf_module_type {
 	TF_MODULE_TYPE_MAX
 };
 
-
 /**
  * Identifier resource types
  */
@@ -317,6 +314,41 @@  enum tf_tbl_type {
 	TF_TBL_TYPE_MAX
 };
 
+/** Enable Shared TCAM Management
+ *
+ *  This feature allows for management of high and low pools within
+ *  the WC TCAM.  These pools are only valid when this feature is enabled.
+ *
+ *  For normal OVS-DPDK operation, this feature is not required and can
+ *  be disabled by commenting out TF_TCAM_SHARED in this header file.
+ *
+ *  Operation:
+ *
+ *  When a shared session is created with WC TCAM entries allocated during
+ *  tf_open_session(), the TF_TCAM_TBL_TYPE_WC_TCAM pool entries will be divided
+ *  into 2 equal pools - TF_TCAM_TBL_TYPE_WC_TCAM_HIGH and
+ *  TF_TCAM_TBL_TYPE_WC_TCAM_LOW.
+ *
+ *  The user will allocate and free entries from either of these pools to obtain
+ *  WC_TCAM entry offsets.  For the WC_TCAM_HI/LO management, alloc/free is done
+ *  using the tf_alloc_tcam_entry()/tf_free_tcam_entry() APIs for the shared
+ *  session.
+ *
+ *  The use case for this feature is so that applications can have a shared
+ *  session and use the TF core to allocate/set/free entries within a given
+ *  region of the WC_TCAM within the shared session.  Application A only writes
+ *  to the LOW region for example and Application B only writes to the HIGH
+ *  region during normal operation.  After Application A goes down, Application
+ *  B may decide to overwrite the LOW region with the HIGH region's entries
+ *  and switch to the low region.
+ *
+ *  For other TCAM types in the  shared session, no alloc/free operations are
+ *  permitted. Only set should be used for other TCAM table types after getting
+ *  the range as provided by the tf_get_resource_info() API.
+ *
+ */
+#define TF_TCAM_SHARED 1
+
 /**
  * TCAM table type
  */
@@ -335,6 +367,12 @@  enum tf_tcam_tbl_type {
 	TF_TCAM_TBL_TYPE_CT_RULE_TCAM,
 	/** Virtual Edge Bridge TCAM */
 	TF_TCAM_TBL_TYPE_VEB_TCAM,
+#ifdef TF_TCAM_SHARED
+	/** Wildcard TCAM HI Priority */
+	TF_TCAM_TBL_TYPE_WC_TCAM_HIGH,
+	/** Wildcard TCAM Low Priority */
+	TF_TCAM_TBL_TYPE_WC_TCAM_LOW,
+#endif /* TF_TCAM_SHARED */
 	TF_TCAM_TBL_TYPE_MAX
 };
 
@@ -1044,7 +1082,6 @@  int tf_search_identifier(struct tf *tfp,
  * Current thought is that memory is allocated within core.
  */
 
-
 /**
  * tf_alloc_tbl_scope_parms definition
  */
diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c
index 97ae73fa5a..55cf55886a 100644
--- a/drivers/net/bnxt/tf_core/tf_device.c
+++ b/drivers/net/bnxt/tf_core/tf_device.c
@@ -9,6 +9,9 @@ 
 #include "tfp.h"
 #include "tf_em.h"
 #include "tf_rm.h"
+#ifdef TF_TCAM_SHARED
+#include "tf_tcam_shared.h"
+#endif /* TF_TCAM_SHARED */
 
 struct tf;
 
@@ -92,6 +95,12 @@  tf_dev_bind_p4(struct tf *tfp,
 	struct tf_em_cfg_parms em_cfg;
 	struct tf_if_tbl_cfg_parms if_tbl_cfg;
 	struct tf_global_cfg_cfg_parms global_cfg;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
 
 	/* Initial function initialization */
 	dev_handle->ops = &tf_dev_ops_p4_init;
@@ -142,7 +151,11 @@  tf_dev_bind_p4(struct tf *tfp,
 		tcam_cfg.cfg = tf_tcam_p4;
 		tcam_cfg.shadow_copy = shadow_copy;
 		tcam_cfg.resources = resources;
+#ifdef TF_TCAM_SHARED
+		rc = tf_tcam_shared_bind(tfp, &tcam_cfg);
+#else /* !TF_TCAM_SHARED */
 		rc = tf_tcam_bind(tfp, &tcam_cfg);
+#endif
 		if (rc) {
 			TFP_DRV_LOG(ERR,
 				    "TCAM initialization failure\n");
@@ -203,31 +216,32 @@  tf_dev_bind_p4(struct tf *tfp,
 		return -ENOMEM;
 	}
 
-	/*
-	 * IF_TBL
-	 */
-	if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
-	if_tbl_cfg.cfg = tf_if_tbl_p4;
-	if_tbl_cfg.shadow_copy = shadow_copy;
-	rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "IF Table initialization failure\n");
-		goto fail;
-	}
+	if (!tf_session_is_shared_session(tfs)) {
+		/*
+		 * IF_TBL
+		 */
+		if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
+		if_tbl_cfg.cfg = tf_if_tbl_p4;
+		if_tbl_cfg.shadow_copy = shadow_copy;
+		rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "IF Table initialization failure\n");
+			goto fail;
+		}
 
-	/*
-	 * GLOBAL_CFG
-	 */
-	global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
-	global_cfg.cfg = tf_global_cfg_p4;
-	rc = tf_global_cfg_bind(tfp, &global_cfg);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Global Cfg initialization failure\n");
-		goto fail;
+		/*
+		 * GLOBAL_CFG
+		 */
+		global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
+		global_cfg.cfg = tf_global_cfg_p4;
+		rc = tf_global_cfg_bind(tfp, &global_cfg);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "Global Cfg initialization failure\n");
+			goto fail;
+		}
 	}
-
 	/* Final function initialization */
 	dev_handle->ops = &tf_dev_ops_p4;
 
@@ -265,7 +279,11 @@  tf_dev_unbind_p4(struct tf *tfp)
 	 * In case of residuals TCAMs are cleaned up first as to
 	 * invalidate the pipeline in a clean manner.
 	 */
+#ifdef TF_TCAM_SHARED
+	rc = tf_tcam_shared_unbind(tfp);
+#else /* !TF_TCAM_SHARED */
 	rc = tf_tcam_unbind(tfp);
+#endif /* TF_TCAM_SHARED */
 	if (rc) {
 		TFP_DRV_LOG(INFO,
 			    "Device unbind failed, TCAM\n");
@@ -407,7 +425,11 @@  tf_dev_bind_p58(struct tf *tfp,
 		tcam_cfg.cfg = tf_tcam_p58;
 		tcam_cfg.shadow_copy = shadow_copy;
 		tcam_cfg.resources = resources;
+#ifdef TF_TCAM_SHARED
+		rc = tf_tcam_shared_bind(tfp, &tcam_cfg);
+#else /* !TF_TCAM_SHARED */
 		rc = tf_tcam_bind(tfp, &tcam_cfg);
+#endif
 		if (rc) {
 			TFP_DRV_LOG(ERR,
 				    "TCAM initialization failure\n");
@@ -517,7 +539,11 @@  tf_dev_unbind_p58(struct tf *tfp)
 	 * In case of residuals TCAMs are cleaned up first as to
 	 * invalidate the pipeline in a clean manner.
 	 */
+#ifdef TF_TCAM_SHARED
+	rc = tf_tcam_shared_unbind(tfp);
+#else /* !TF_TCAM_SHARED */
 	rc = tf_tcam_unbind(tfp);
+#endif /* TF_TCAM_SHARED */
 	if (rc) {
 		TFP_DRV_LOG(INFO,
 			    "Device unbind failed, TCAM\n");
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 31806bb289..ea4dcfb8e2 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -10,6 +10,9 @@ 
 #include "tf_identifier.h"
 #include "tf_tbl.h"
 #include "tf_tcam.h"
+#ifdef TF_TCAM_SHARED
+#include "tf_tcam_shared.h"
+#endif
 #include "tf_if_tbl.h"
 #include "tf_global_cfg.h"
 
@@ -136,7 +139,6 @@  struct tf_dev_ops {
 				       uint16_t resource_id,
 				       const char **resource_str);
 
-
 	/**
 	 * Retrieves the WC TCAM slice information that the device
 	 * supports.
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index e74ba6cd8f..0d3c35ae3b 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -10,6 +10,9 @@ 
 #include "tf_identifier.h"
 #include "tf_tbl.h"
 #include "tf_tcam.h"
+#ifdef TF_TCAM_SHARED
+#include "tf_tcam_shared.h"
+#endif /* TF_TCAM_SHARED */
 #include "tf_em.h"
 #include "tf_if_tbl.h"
 #include "tfp.h"
@@ -137,7 +140,8 @@  tf_dev_p4_get_tcam_slice_info(struct tf *tfp __rte_unused,
 			      uint16_t key_sz,
 			      uint16_t *num_slices_per_row)
 {
-#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2
+/* Single slice support */
+#define CFA_P4_WC_TCAM_SLICES_PER_ROW 1
 #define CFA_P4_WC_TCAM_SLICE_SIZE     12
 
 	if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
@@ -263,11 +267,18 @@  const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_get_tbl = tf_tbl_get,
 	.tf_dev_get_bulk_tbl = tf_tbl_bulk_get,
 	.tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info,
+#ifdef TF_TCAM_SHARED
+	.tf_dev_alloc_tcam = tf_tcam_shared_alloc,
+	.tf_dev_free_tcam = tf_tcam_shared_free,
+	.tf_dev_set_tcam = tf_tcam_shared_set,
+	.tf_dev_get_tcam = tf_tcam_shared_get,
+#else /* !TF_TCAM_SHARED */
 	.tf_dev_alloc_tcam = tf_tcam_alloc,
 	.tf_dev_free_tcam = tf_tcam_free,
-	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_set_tcam = tf_tcam_set,
-	.tf_dev_get_tcam = NULL,
+	.tf_dev_get_tcam = tf_tcam_get,
+#endif
+	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info,
 	.tf_dev_insert_int_em_entry = tf_em_insert_int_entry,
 	.tf_dev_delete_int_em_entry = tf_em_delete_int_entry,
diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c
index a5b055bac7..5bf52379a7 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p58.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c
@@ -10,6 +10,9 @@ 
 #include "tf_identifier.h"
 #include "tf_tbl.h"
 #include "tf_tcam.h"
+#ifdef TF_TCAM_SHARED
+#include "tf_tcam_shared.h"
+#endif /* TF_TCAM_SHARED */
 #include "tf_em.h"
 #include "tf_if_tbl.h"
 #include "tfp.h"
@@ -148,7 +151,6 @@  static int tf_dev_p58_word_align(uint16_t size)
 	return ((((size) + 63) >> 6) * 8);
 }
 
-
 #define TF_DEV_P58_BANK_SZ_64B 2048
 /**
  * Get SRAM table information.
@@ -287,11 +289,18 @@  const struct tf_dev_ops tf_dev_ops_p58 = {
 	.tf_dev_get_tbl = tf_tbl_get,
 	.tf_dev_get_bulk_tbl = tf_tbl_bulk_get,
 	.tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info,
+#ifdef TF_TCAM_SHARED
+	.tf_dev_alloc_tcam = tf_tcam_shared_alloc,
+	.tf_dev_free_tcam = tf_tcam_shared_free,
+	.tf_dev_set_tcam = tf_tcam_set,
+	.tf_dev_get_tcam = tf_tcam_get,
+#else /* !TF_TCAM_SHARED */
 	.tf_dev_alloc_tcam = tf_tcam_alloc,
 	.tf_dev_free_tcam = tf_tcam_free,
-	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_set_tcam = tf_tcam_set,
 	.tf_dev_get_tcam = tf_tcam_get,
+#endif
+	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info,
 	.tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry,
 	.tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry,
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index 3cc87de4ef..3575c3e1a0 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -76,7 +76,7 @@  tf_ident_bind(struct tf *tfp,
 			db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
 		if (db_rc[i]) {
 			TFP_DRV_LOG(INFO,
-				    "%s: Identifier DB creation failed\n",
+				    "%s: No Identifier DB required\n",
 				    tf_dir_2_str(i));
 		}
 
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index 192115183b..295204ac87 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -85,7 +85,7 @@  tf_tbl_bind(struct tf *tfp,
 			db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
 		if (db_rc[d]) {
 			TFP_DRV_LOG(ERR,
-				    "%s: Table DB creation failed\n",
+				    "%s: No Table DB creation required\n",
 				    tf_dir_2_str(d));
 
 		}
@@ -656,7 +656,6 @@  tf_tbl_get_resc_info(struct tf *tfp,
 	}
 	tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
 
-
 	/* check if reserved resource for WC is multiple of num_slices */
 	for (d = 0; d < TF_DIR_MAX; d++) {
 		ainfo.rm_db = tbl_db->tbl_db[d];
@@ -693,7 +692,5 @@  tf_tbl_get_resc_info(struct tf *tfp,
 		}
 	}
 
-
-
 	return 0;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index ce959e3923..5c018f7003 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -115,7 +115,7 @@  tf_tcam_bind(struct tf *tfp,
 			db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
 		if (db_rc[d]) {
 			TFP_DRV_LOG(INFO,
-				    "%s: TCAM DB creation failed\n",
+				    "%s: no TCAM DB required\n",
 				    tf_dir_2_str(d));
 		}
 	}
@@ -126,6 +126,9 @@  tf_tcam_bind(struct tf *tfp,
 
 	/* check if reserved resource for WC is multiple of num_slices */
 	for (d = 0; d < TF_DIR_MAX; d++) {
+		if (!tcam_db->tcam_db[d])
+			continue;
+
 		memset(&info, 0, sizeof(info));
 		ainfo.rm_db = tcam_db->tcam_db[d];
 		ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.c b/drivers/net/bnxt/tf_core/tf_tcam_shared.c
new file mode 100644
index 0000000000..18beae78bb
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.c
@@ -0,0 +1,743 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2021 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <rte_common.h>
+
+#include "tf_tcam_shared.h"
+#include "tf_tcam.h"
+#include "tf_common.h"
+#include "tf_util.h"
+#include "tf_rm.h"
+#include "tf_device.h"
+#include "tfp.h"
+#include "tf_session.h"
+#include "tf_msg.h"
+#include "bitalloc.h"
+#include "tf_core.h"
+
+struct tf;
+
+/** Shared WC TCAM pool identifiers
+ */
+enum tf_tcam_shared_wc_pool_id {
+	TF_TCAM_SHARED_WC_POOL_HI  = 0,
+	TF_TCAM_SHARED_WC_POOL_LO  = 1,
+	TF_TCAM_SHARED_WC_POOL_MAX = 2
+};
+
+/** Get string representation of a WC TCAM shared pool id
+ */
+static const char *
+tf_pool_2_str(enum tf_tcam_shared_wc_pool_id id)
+{
+	switch (id) {
+	case TF_TCAM_SHARED_WC_POOL_HI:
+		return "TCAM_SHARED_WC_POOL_HI";
+	case TF_TCAM_SHARED_WC_POOL_LO:
+		return "TCAM_SHARED_WC_POOL_LO";
+	default:
+		return "Invalid TCAM_SHARED_WC_POOL";
+	}
+}
+
+/** The WC TCAM shared pool datastructure
+ */
+struct tf_tcam_shared_wc_pool {
+	/** Start and stride data */
+	struct tf_resource_info info;
+	/** bitalloc pool */
+	struct bitalloc *pool;
+};
+
+/** The WC TCAM shared pool declarations
+ * TODO: add tcam_shared_wc_db
+ */
+struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX];
+
+/** Create a WC TCAM shared pool
+ */
+static int
+tf_tcam_shared_create_wc_pool(int dir,
+			      enum tf_tcam_shared_wc_pool_id id,
+			      int start,
+			      int stride)
+{
+	int rc = 0;
+	bool free = true;
+	struct tfp_calloc_parms cparms;
+	uint32_t pool_size;
+
+	/* Create pool */
+	pool_size = (BITALLOC_SIZEOF(stride) / sizeof(struct bitalloc));
+	cparms.nitems = pool_size;
+	cparms.alignment = 0;
+	cparms.size = sizeof(struct bitalloc);
+	rc = tfp_calloc(&cparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: pool memory alloc failed %s:%s\n",
+			    tf_dir_2_str(dir), tf_pool_2_str(id),
+			    strerror(-rc));
+		return rc;
+	}
+	tcam_shared_wc[dir][id].pool = (struct bitalloc *)cparms.mem_va;
+
+	rc = ba_init(tcam_shared_wc[dir][id].pool,
+		     stride,
+		     free);
+
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: pool bitalloc failed %s\n",
+			    tf_dir_2_str(dir), tf_pool_2_str(id));
+		return rc;
+	}
+
+	tcam_shared_wc[dir][id].info.start = start;
+	tcam_shared_wc[dir][id].info.stride = stride;
+	return rc;
+}
+/** Free a WC TCAM shared pool
+ */
+static void
+tf_tcam_shared_free_wc_pool(int dir,
+			    enum tf_tcam_shared_wc_pool_id id)
+{
+	tcam_shared_wc[dir][id].info.start = 0;
+	tcam_shared_wc[dir][id].info.stride = 0;
+
+	if (tcam_shared_wc[dir][id].pool)
+		tfp_free((void *)tcam_shared_wc[dir][id].pool);
+}
+
+/** Get the number of WC TCAM slices allocated during 1 allocation/free
+ */
+static int
+tf_tcam_shared_get_slices(struct tf *tfp,
+			  struct tf_dev_info *dev,
+			  uint16_t *num_slices)
+{
+	int rc;
+
+	if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "Operation not supported, rc:%s\n", strerror(-rc));
+		return rc;
+	}
+	rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
+						  TF_TCAM_TBL_TYPE_WC_TCAM,
+						  0,
+						  num_slices);
+	return rc;
+}
+
+static bool
+tf_tcam_shared_db_valid(struct tf *tfp,
+			enum tf_dir dir)
+{
+	struct tcam_rm_db *tcam_db;
+	void *tcam_db_ptr = NULL;
+	int rc;
+
+	TF_CHECK_PARMS1(tfp);
+
+	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
+	if (rc)
+		return false;
+
+	tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
+
+	if (tcam_db->tcam_db[dir])
+		return true;
+
+	return false;
+}
+
+static int
+tf_tcam_shared_get_rm_info(struct tf *tfp,
+			   enum tf_dir dir,
+			   uint16_t *hcapi_type,
+			   struct tf_rm_alloc_info *info)
+{
+	int rc;
+	struct tcam_rm_db *tcam_db;
+	void *tcam_db_ptr = NULL;
+	struct tf_rm_get_alloc_info_parms ainfo;
+	struct tf_rm_get_hcapi_parms hparms;
+
+	TF_CHECK_PARMS3(tfp, hcapi_type, info);
+
+	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
+	if (rc) {
+		TFP_DRV_LOG(INFO,
+			    "Tcam_db is not initialized, rc:%s\n",
+			    strerror(-rc));
+		return 0;
+	}
+	tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
+
+	/* Convert TF type to HCAPI RM type */
+	memset(&hparms, 0, sizeof(hparms));
+	hparms.rm_db = tcam_db->tcam_db[dir];
+	hparms.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
+	hparms.hcapi_type = hcapi_type;
+
+	rc = tf_rm_get_hcapi_type(&hparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Get RM hcapi type failed %s\n",
+			    tf_dir_2_str(dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	memset(info, 0, sizeof(struct tf_rm_alloc_info));
+	ainfo.rm_db = tcam_db->tcam_db[dir];
+	ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
+	ainfo.info = info;
+
+	rc = tf_rm_get_info(&ainfo);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM rm info get failed %s\n",
+			    tf_dir_2_str(dir),
+			    strerror(-rc));
+		return rc;
+	}
+	return rc;
+}
+
+/**
+ * tf_tcam_shared_bind
+ */
+int
+tf_tcam_shared_bind(struct tf *tfp,
+		    struct tf_tcam_cfg_parms *parms)
+{
+	int rc, dir;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	struct tf_rm_alloc_info info;
+	uint16_t start, stride;
+	uint16_t num_slices;
+	uint16_t hcapi_type;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Perform normal bind
+	 */
+	rc = tf_tcam_bind(tfp, parms);
+	if (rc)
+		return rc;
+
+	/* After the normal TCAM bind, if this is a shared session
+	 * create all required databases for the WC_HI and WC_LO pools
+	 */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Session access failure: %s\n", strerror(-rc));
+		return rc;
+	}
+	if (tf_session_is_shared_session(tfs)) {
+		/* Retrieve the device information */
+		rc = tf_session_get_device(tfs, &dev);
+		if (rc)
+			return rc;
+
+		rc = tf_tcam_shared_get_slices(tfp,
+					       dev,
+					       &num_slices);
+		if (rc)
+			return rc;
+
+		/* If there are WC TCAM entries, create 2 pools each with 1/2
+		 * the total number of entries
+		 */
+		for (dir = 0; dir < TF_DIR_MAX; dir++) {
+			if (!tf_tcam_shared_db_valid(tfp, dir))
+				continue;
+
+			rc = tf_tcam_shared_get_rm_info(tfp,
+							dir,
+							&hcapi_type,
+							&info);
+			if (rc) {
+				TFP_DRV_LOG(ERR,
+					    "%s: TCAM rm info get failed\n",
+					    tf_dir_2_str(dir));
+				goto done;
+			}
+
+			start = info.entry.start;
+			stride = info.entry.stride / 2;
+
+			tf_tcam_shared_create_wc_pool(dir,
+						TF_TCAM_SHARED_WC_POOL_HI,
+						start,
+						stride);
+
+			start += stride;
+			tf_tcam_shared_create_wc_pool(dir,
+						TF_TCAM_SHARED_WC_POOL_LO,
+						start,
+						stride);
+		}
+	}
+done:
+	return rc;
+}
+/**
+ * tf_tcam_shared_unbind
+ */
+int
+tf_tcam_shared_unbind(struct tf *tfp)
+{
+	int rc, dir;
+	struct tf_session *tfs;
+
+	TF_CHECK_PARMS1(tfp);
+
+	/* Perform normal unbind, this will write all the
+	 * allocated TCAM entries in the shared session.
+	 */
+	rc = tf_tcam_unbind(tfp);
+	if (rc)
+		return rc;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* If we are the shared session
+	 */
+	if (tf_session_is_shared_session(tfs)) {
+		/* If there are WC TCAM entries allocated, free them
+		 */
+		for (dir = 0; dir < TF_DIR_MAX; dir++) {
+			tf_tcam_shared_free_wc_pool(dir,
+						    TF_TCAM_SHARED_WC_POOL_HI);
+			tf_tcam_shared_free_wc_pool(dir,
+						    TF_TCAM_SHARED_WC_POOL_LO);
+		}
+	}
+	return 0;
+}
+/**
+ * tf_tcam_shared_alloc
+ */
+int
+tf_tcam_shared_alloc(struct tf *tfp,
+		     struct tf_tcam_alloc_parms *parms)
+{
+	int rc, i;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int log_idx;
+	struct bitalloc *pool;
+	enum tf_tcam_shared_wc_pool_id id;
+	uint16_t num_slices;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* If we aren't the shared session or the type is
+	 * not one of the special WC TCAM types, call the normal
+	 * allocation.
+	 */
+	if (!tf_session_is_shared_session(tfs) ||
+	    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
+	     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
+		/* Perform normal alloc
+		 */
+		rc = tf_tcam_alloc(tfp, parms);
+		return rc;
+	}
+
+	if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
+		TFP_DRV_LOG(ERR,
+			    "%s: tcam shared pool doesn't exist\n",
+			    tf_dir_2_str(parms->dir));
+		return -ENOMEM;
+	}
+
+	if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
+		id = TF_TCAM_SHARED_WC_POOL_HI;
+	else
+		id = TF_TCAM_SHARED_WC_POOL_LO;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
+	if (rc)
+		return rc;
+
+	pool = tcam_shared_wc[parms->dir][id].pool;
+
+	for (i = 0; i < num_slices; i++) {
+		/*
+		 * priority  0: allocate from top of the tcam i.e. high
+		 * priority !0: allocate index from bottom i.e lowest
+		 */
+		if (parms->priority)
+			log_idx = ba_alloc_reverse(pool);
+		else
+			log_idx = ba_alloc(pool);
+		if (log_idx == BA_FAIL) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Allocation failed, rc:%s\n",
+				    tf_dir_2_str(parms->dir),
+				    strerror(ENOMEM));
+			return -ENOMEM;
+		}
+		/* return the index without the start of each row */
+		if (i == 0)
+			parms->idx = log_idx;
+	}
+	return 0;
+}
+
+int
+tf_tcam_shared_free(struct tf *tfp,
+		    struct tf_tcam_free_parms *parms)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int allocated = 0;
+	int i;
+	uint16_t start;
+	int phy_idx;
+	struct bitalloc *pool;
+	enum tf_tcam_shared_wc_pool_id id;
+	struct tf_tcam_free_parms nparms;
+	uint16_t num_slices;
+	uint16_t hcapi_type;
+	struct tf_rm_alloc_info info;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* If we aren't the shared session or the type is
+	 * not one of the special WC TCAM types, call the normal
+	 * allocation.
+	 */
+	if (!tf_session_is_shared_session(tfs) ||
+	    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
+	     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
+		/* Perform normal free
+		 */
+		rc = tf_tcam_free(tfp, parms);
+		return rc;
+	}
+
+	if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
+		TFP_DRV_LOG(ERR,
+			    "%s: tcam shared pool doesn't exist\n",
+			    tf_dir_2_str(parms->dir));
+		return -ENOMEM;
+	}
+
+	if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
+		id = TF_TCAM_SHARED_WC_POOL_HI;
+	else
+		id = TF_TCAM_SHARED_WC_POOL_LO;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
+	if (rc)
+		return rc;
+
+	rc = tf_tcam_shared_get_rm_info(tfp,
+					parms->dir,
+					&hcapi_type,
+					&info);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM rm info get failed\n",
+			    tf_dir_2_str(parms->dir));
+		return rc;
+	}
+
+	pool = tcam_shared_wc[parms->dir][id].pool;
+	start = tcam_shared_wc[parms->dir][id].info.start;
+
+	if (parms->idx % num_slices) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM reserved resource is not multiple of %d\n",
+			    tf_dir_2_str(parms->dir), num_slices);
+		return -EINVAL;
+	}
+
+	phy_idx = parms->idx + start;
+	allocated = ba_inuse(pool, parms->idx);
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry already free, type:%d, idx:%d\n",
+			    tf_dir_2_str(parms->dir), parms->type, parms->idx);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_slices; i++) {
+		rc = ba_free(pool, parms->idx + i);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: Free failed, type:%s, idx:%d\n",
+				    tf_dir_2_str(parms->dir),
+				    tf_tcam_tbl_2_str(parms->type),
+				    parms->idx);
+			return rc;
+		}
+	}
+
+	/* Override HI/LO type with parent WC TCAM type */
+	nparms = *parms;
+	nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
+	nparms.hcapi_type = hcapi_type;
+	nparms.idx = phy_idx;
+
+	rc = tf_msg_tcam_entry_free(tfp, dev, &nparms);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR,
+			    "%s: %s: log%d free failed, rc:%s\n",
+			    tf_dir_2_str(nparms.dir),
+			    tf_tcam_tbl_2_str(nparms.type),
+			    phy_idx,
+			    strerror(-rc));
+		return rc;
+	}
+	return 0;
+}
+
+int
+tf_tcam_shared_set(struct tf *tfp __rte_unused,
+		   struct tf_tcam_set_parms *parms __rte_unused)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int allocated = 0;
+	int phy_idx, log_idx;
+	uint16_t num_slices;
+	struct tf_tcam_set_parms nparms;
+	struct bitalloc *pool;
+	uint16_t start;
+	enum tf_tcam_shared_wc_pool_id id;
+	uint16_t hcapi_type;
+	struct tf_rm_alloc_info info;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* If we aren't the shared session or one of our
+	 * special types
+	 */
+	if (!tf_session_is_shared_session(tfs) ||
+	    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
+	     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
+		/* Perform normal set and exit
+		 */
+		rc = tf_tcam_set(tfp, parms);
+		return rc;
+	}
+
+	if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
+		TFP_DRV_LOG(ERR,
+			    "%s: tcam shared pool doesn't exist\n",
+			    tf_dir_2_str(parms->dir));
+		return -ENOMEM;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
+		id = TF_TCAM_SHARED_WC_POOL_HI;
+	else
+		id = TF_TCAM_SHARED_WC_POOL_LO;
+
+	pool = tcam_shared_wc[parms->dir][id].pool;
+	start = tcam_shared_wc[parms->dir][id].info.start;
+
+	log_idx = parms->idx;
+	phy_idx = parms->idx + start;
+	allocated = ba_inuse(pool, parms->idx);
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry is not allocated, type:%d, logid:%d\n",
+			    tf_dir_2_str(parms->dir), parms->type, log_idx);
+		return -EINVAL;
+	}
+	rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
+	if (rc)
+		return rc;
+
+	if (parms->idx % num_slices) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM reserved resource is not multiple of %d\n",
+			    tf_dir_2_str(parms->dir), num_slices);
+		return -EINVAL;
+	}
+	rc = tf_tcam_shared_get_rm_info(tfp,
+					parms->dir,
+					&hcapi_type,
+					&info);
+	if (rc)
+		return rc;
+
+	/* Override HI/LO type with parent WC TCAM type */
+	nparms.hcapi_type = hcapi_type;
+	nparms.dir = parms->dir;
+	nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
+	nparms.idx = phy_idx;
+	nparms.key = parms->key;
+	nparms.mask = parms->mask;
+	nparms.key_size = parms->key_size;
+	nparms.result = parms->result;
+	nparms.result_size = parms->result_size;
+
+	rc = tf_msg_tcam_entry_set(tfp, dev, &nparms);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR,
+			    "%s: %s: phy entry %d set failed, rc:%s",
+			    tf_dir_2_str(parms->dir),
+			    tf_tcam_tbl_2_str(nparms.type),
+			    phy_idx,
+			    strerror(-rc));
+		return rc;
+	}
+	return 0;
+}
+
+int
+tf_tcam_shared_get(struct tf *tfp __rte_unused,
+		   struct tf_tcam_get_parms *parms)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int allocated = 0;
+	int phy_idx, log_idx;
+	uint16_t num_slices;
+	struct tf_tcam_get_parms nparms;
+	struct bitalloc *pool;
+	uint16_t start;
+	enum tf_tcam_shared_wc_pool_id id;
+	uint16_t hcapi_type;
+	struct tf_rm_alloc_info info;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* If we aren't the shared session or one of our
+	 * special types
+	 */
+	if (!tf_session_is_shared_session(tfs) ||
+	    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
+	     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
+		/* Perform normal get and exit
+		 */
+		rc = tf_tcam_get(tfp, parms);
+		return rc;
+	}
+
+	if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
+		TFP_DRV_LOG(ERR,
+			    "%s: tcam shared pool doesn't exist\n",
+			    tf_dir_2_str(parms->dir));
+		return -ENOMEM;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+	if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
+		id = TF_TCAM_SHARED_WC_POOL_HI;
+	else
+		id = TF_TCAM_SHARED_WC_POOL_LO;
+
+	pool = tcam_shared_wc[parms->dir][id].pool;
+	start = tcam_shared_wc[parms->dir][id].info.start;
+
+	rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
+	if (rc)
+		return rc;
+
+	if (parms->idx % num_slices) {
+		TFP_DRV_LOG(ERR,
+			    "%s: TCAM reserved resource is not multiple of %d\n",
+			    tf_dir_2_str(parms->dir), num_slices);
+		return -EINVAL;
+	}
+	log_idx = parms->idx;
+	phy_idx = parms->idx + start;
+	allocated = ba_inuse(pool, parms->idx);
+
+	if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Entry is not allocated, type:%d, logid:%d\n",
+			    tf_dir_2_str(parms->dir), parms->type, log_idx);
+		return -EINVAL;
+	}
+
+	rc = tf_tcam_shared_get_rm_info(tfp,
+					parms->dir,
+					&hcapi_type,
+					&info);
+	if (rc)
+		return rc;
+
+	/* Override HI/LO type with parent WC TCAM type */
+	nparms = *parms;
+	nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
+	nparms.hcapi_type = hcapi_type;
+	nparms.idx = phy_idx;
+
+	rc = tf_msg_tcam_entry_get(tfp, dev, &nparms);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR,
+			    "%s: %s: Entry %d set failed, rc:%s",
+			    tf_dir_2_str(nparms.dir),
+			    tf_tcam_tbl_2_str(nparms.type),
+			    nparms.idx,
+			    strerror(-rc));
+		return rc;
+	}
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.h b/drivers/net/bnxt/tf_core/tf_tcam_shared.h
new file mode 100644
index 0000000000..fad6e23b4c
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.h
@@ -0,0 +1,127 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2021 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_TCAM_SHARED_H_
+#define _TF_TCAM_SHARED_H_
+
+#include "tf_core.h"
+#include "tf_tcam.h"
+
+/**
+ * @page tcam_shared TCAM SHARED
+ *
+ * @ref tf_tcam_shared_bind
+ *
+ * @ref tf_tcam_shared_unbind
+ *
+ * @ref tf_tcam_shared_alloc
+ *
+ * @ref tf_tcam_shared_free
+ *
+ * @ref tf_tcam_shared_set
+ *
+ * @ref tf_tcam_shared_get
+ *
+ */
+
+/**
+ * Initializes the TCAM shared module with the requested DBs. Must be
+ * invoked as the first thing before any of the access functions.
+ *
+ * [in] tfp
+ *   Pointer to the truflow handle
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_shared_bind(struct tf *tfp,
+			struct tf_tcam_cfg_parms *parms);
+
+/**
+ * Cleans up the private DBs and releases all the data.
+ *
+ * [in] tfp
+ *   Pointer to the truflow handle
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_shared_unbind(struct tf *tfp);
+
+/**
+ * Allocates the requested tcam type from the internal RM DB.
+ *
+ * [in] tfp
+ *   Pointer to the truflow handle
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_shared_alloc(struct tf *tfp,
+			 struct tf_tcam_alloc_parms *parms);
+
+/**
+ * Free's the requested table type and returns it to the DB.
+ *
+ * [in] tfp
+ *   Pointer to the truflow handle
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_shared_free(struct tf *tfp,
+			struct tf_tcam_free_parms *parms);
+
+/**
+ * Configures the requested element by sending a firmware request which
+ * then installs it into the device internal structures.
+ *
+ * [in] tfp
+ *   Pointer to the truflow handle
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_shared_set(struct tf *tfp,
+		       struct tf_tcam_set_parms *parms);
+
+/**
+ * Retrieves the requested element by sending a firmware request to get
+ * the element.
+ *
+ * [in] tfp
+ *   Pointer to the truflow handle
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_shared_get(struct tf *tfp,
+		       struct tf_tcam_get_parms *parms);
+
+#endif /* _TF_TCAM_SHARED_H */
diff --git a/drivers/net/bnxt/tf_core/tf_util.c b/drivers/net/bnxt/tf_core/tf_util.c
index 25f5c152d2..e712816209 100644
--- a/drivers/net/bnxt/tf_core/tf_util.c
+++ b/drivers/net/bnxt/tf_core/tf_util.c
@@ -59,6 +59,12 @@  tf_tcam_tbl_2_str(enum tf_tcam_tbl_type tcam_type)
 		return "sp_tcam";
 	case TF_TCAM_TBL_TYPE_CT_RULE_TCAM:
 		return "ct_rule_tcam";
+#ifdef TF_TCAM_SHARED
+	case TF_TCAM_TBL_TYPE_WC_TCAM_HIGH:
+		return "wc_tcam_hi";
+	case TF_TCAM_TBL_TYPE_WC_TCAM_LOW:
+		return "wc_tcam_lo";
+#endif
 	default:
 		return "Invalid tcam table type";
 	}