[v2,04/11] net/bnxt: update Truflow core

Message ID 20230421181155.2160482-5-stuart.schacher@broadcom.com (mailing list archive)
State Superseded, archived
Delegated to: Ajit Khaparde
Headers
Series sync Truflow support with latest release |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Randy Schacher April 21, 2023, 6:11 p.m. UTC
  - Add shared session management
- Add SRAM session management
- Add dynamic TCAM management
- Add shared TCAM session management
- Add Hot Upgrade support
- Update copyright

Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Shahaji Bhosle <shahaji.bhosle@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                       |    1 -
 drivers/net/bnxt/bnxt_irq.h                   |    1 -
 drivers/net/bnxt/bnxt_nvm_defs.h              |    1 -
 drivers/net/bnxt/bnxt_ring.h                  |    1 -
 drivers/net/bnxt/bnxt_rxr.h                   |    1 -
 drivers/net/bnxt/bnxt_txr.h                   |    1 -
 drivers/net/bnxt/bnxt_util.h                  |    1 -
 drivers/net/bnxt/tf_core/cfa_resource_types.h |    2 -
 drivers/net/bnxt/tf_core/cfa_tcam_mgr.c       | 2116 +++++++++++++++++
 drivers/net/bnxt/tf_core/cfa_tcam_mgr.h       |  523 ++++
 .../net/bnxt/tf_core/cfa_tcam_mgr_device.h    |  101 +
 .../net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c  |  201 ++
 .../net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h  |   28 +
 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c    |  921 +++++++
 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h    |   20 +
 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c   |  926 ++++++++
 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h   |   20 +
 drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h  |  126 +
 .../net/bnxt/tf_core/cfa_tcam_mgr_session.c   |  377 +++
 .../net/bnxt/tf_core/cfa_tcam_mgr_session.h   |   54 +
 drivers/net/bnxt/tf_core/meson.build          |   36 +-
 drivers/net/bnxt/tf_core/tf_core.c            |   54 +-
 drivers/net/bnxt/tf_core/tf_core.h            |   97 +-
 drivers/net/bnxt/tf_core/tf_device.c          |   18 +-
 drivers/net/bnxt/tf_core/tf_device.h          |    2 +-
 drivers/net/bnxt/tf_core/tf_device_p4.c       |   14 +-
 drivers/net/bnxt/tf_core/tf_device_p58.c      |   84 +-
 drivers/net/bnxt/tf_core/tf_em_common.c       |    2 +-
 drivers/net/bnxt/tf_core/tf_em_internal.c     |   10 +-
 drivers/net/bnxt/tf_core/tf_identifier.c      |    1 +
 drivers/net/bnxt/tf_core/tf_if_tbl.c          |   59 +-
 drivers/net/bnxt/tf_core/tf_msg.c             |  217 +-
 drivers/net/bnxt/tf_core/tf_msg.h             |   38 +-
 drivers/net/bnxt/tf_core/tf_rm.c              |  117 +-
 drivers/net/bnxt/tf_core/tf_session.c         |  112 +-
 drivers/net/bnxt/tf_core/tf_session.h         |   65 +-
 drivers/net/bnxt/tf_core/tf_sram_mgr.c        |  117 +-
 drivers/net/bnxt/tf_core/tf_sram_mgr.h        |   22 +-
 drivers/net/bnxt/tf_core/tf_tbl.c             |    8 +-
 drivers/net/bnxt/tf_core/tf_tbl_sram.c        |   25 +-
 drivers/net/bnxt/tf_core/tf_tcam.c            |  226 +-
 drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c    |  286 +++
 drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h    |   49 +
 drivers/net/bnxt/tf_core/tf_tcam_shared.c     | 1146 +--------
 drivers/net/bnxt/tf_core/tf_tcam_shared.h     |    3 +-
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c            |    8 +-
 46 files changed, 6686 insertions(+), 1552 deletions(-)
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr.c
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr.h
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c
 create mode 100644 drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h
 create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c
 create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h
  

Patch

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 48bd8f2418..2bccdec7e0 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -1044,5 +1044,4 @@  int bnxt_flow_ops_get_op(struct rte_eth_dev *dev,
 int bnxt_dev_start_op(struct rte_eth_dev *eth_dev);
 int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev);
 void bnxt_handle_vf_cfg_change(void *arg);
-
 #endif
diff --git a/drivers/net/bnxt/bnxt_irq.h b/drivers/net/bnxt/bnxt_irq.h
index e498578968..e2d61bae7a 100644
--- a/drivers/net/bnxt/bnxt_irq.h
+++ b/drivers/net/bnxt/bnxt_irq.h
@@ -20,5 +20,4 @@  void bnxt_enable_int(struct bnxt *bp);
 int bnxt_setup_int(struct bnxt *bp);
 int bnxt_request_int(struct bnxt *bp);
 void bnxt_int_handler(void *param);
-
 #endif
diff --git a/drivers/net/bnxt/bnxt_nvm_defs.h b/drivers/net/bnxt/bnxt_nvm_defs.h
index f5ac4e8c84..57ddefa7a1 100644
--- a/drivers/net/bnxt/bnxt_nvm_defs.h
+++ b/drivers/net/bnxt/bnxt_nvm_defs.h
@@ -66,5 +66,4 @@  enum bnxnvm_pkglog_field_index {
 	BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS		= 5,
 	BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK		= 6
 };
-
 #endif				/* Don't add anything after this line */
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 3d747aba54..baa60b2627 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -142,5 +142,4 @@  static inline void bnxt_db_cq(struct bnxt_cp_ring_info *cpr)
 		B_CP_DIS_DB(cpr, cp_raw_cons);
 	}
 }
-
 #endif
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e132166a18..8e722b7bf0 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -386,5 +386,4 @@  bnxt_parse_pkt_type_v2(struct rte_mbuf *mbuf,
 
 	mbuf->packet_type = pkt_type;
 }
-
 #endif /*  _BNXT_RXR_H_ */
diff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h
index e11343c082..75456df5bd 100644
--- a/drivers/net/bnxt/bnxt_txr.h
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -90,5 +90,4 @@  int bnxt_flush_tx_cmp(struct bnxt_cp_ring_info *cpr);
 					TX_BD_LONG_LFLAGS_IP_CHKSUM)
 #define TX_BD_FLG_TIP_TCP_UDP_CHKSUM	(TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM | \
 					TX_BD_LONG_LFLAGS_T_IP_CHKSUM)
-
 #endif
diff --git a/drivers/net/bnxt/bnxt_util.h b/drivers/net/bnxt/bnxt_util.h
index 3437dc75ae..7f5b4c160e 100644
--- a/drivers/net/bnxt/bnxt_util.h
+++ b/drivers/net/bnxt/bnxt_util.h
@@ -17,5 +17,4 @@ 
 
 int bnxt_check_zero_bytes(const uint8_t *bytes, int len);
 void bnxt_eth_hw_addr_random(uint8_t *mac_addr);
-
 #endif /* _BNXT_UTIL_H_ */
diff --git a/drivers/net/bnxt/tf_core/cfa_resource_types.h b/drivers/net/bnxt/tf_core/cfa_resource_types.h
index 874d7b834f..8431c778e4 100644
--- a/drivers/net/bnxt/tf_core/cfa_resource_types.h
+++ b/drivers/net/bnxt/tf_core/cfa_resource_types.h
@@ -63,7 +63,6 @@ 
 #define CFA_RESOURCE_TYPE_P59_VEB_TCAM           0x18UL
 #define CFA_RESOURCE_TYPE_P59_LAST              CFA_RESOURCE_TYPE_P59_VEB_TCAM
 
-
 /* Meter */
 #define CFA_RESOURCE_TYPE_P58_METER              0x0UL
 /* SRAM_Bank_0 */
@@ -184,7 +183,6 @@ 
 #define CFA_RESOURCE_TYPE_P45_TBL_SCOPE           0x23UL
 #define CFA_RESOURCE_TYPE_P45_LAST               CFA_RESOURCE_TYPE_P45_TBL_SCOPE
 
-
 /* Multicast Group */
 #define CFA_RESOURCE_TYPE_P4_MCG                 0x0UL
 /* Encap 8 byte record */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.c
new file mode 100644
index 0000000000..f26d93e7a9
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.c
@@ -0,0 +1,2116 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include <signal.h>
+
+#include "hcapi_cfa_defs.h"
+
+#include "tfp.h"
+#include "tf_session.h"
+#include "tf_util.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_hwop_msg.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_session.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr_p4.h"
+
+#define TF_TCAM_SLICE_INVALID (-1)
+
+/*
+ * The following macros are for setting the entry status in a row entry.
+ * row is (struct cfa_tcam_mgr_table_rows_0 *)
+ */
+#define ROW_ENTRY_INUSE(row, entry)  ((row)->entry_inuse &   (1U << (entry)))
+#define ROW_ENTRY_SET(row, entry)    ((row)->entry_inuse |=  (1U << (entry)))
+#define ROW_ENTRY_CLEAR(row, entry)  ((row)->entry_inuse &= ~(1U << (entry)))
+#define ROW_INUSE(row)               ((row)->entry_inuse != 0)
+
+static struct cfa_tcam_mgr_entry_data *entry_data[TF_TCAM_MAX_SESSIONS];
+
+static int global_data_initialized[TF_TCAM_MAX_SESSIONS];
+int cfa_tcam_mgr_max_entries[TF_TCAM_MAX_SESSIONS];
+
+struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables[TF_TCAM_MAX_SESSIONS][TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+
+static int physical_table_types[CFA_TCAM_MGR_TBL_TYPE_MAX] = {
+	[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS] =
+		TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH,
+	[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS]  =
+		TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW,
+	[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS]	      =
+		TF_TCAM_TBL_TYPE_PROF_TCAM,
+	[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS]	      =
+		TF_TCAM_TBL_TYPE_WC_TCAM,
+	[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS]	      =
+		TF_TCAM_TBL_TYPE_SP_TCAM,
+	[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS]      =
+		TF_TCAM_TBL_TYPE_CT_RULE_TCAM,
+	[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS]	      =
+		TF_TCAM_TBL_TYPE_VEB_TCAM,
+	[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS]     =
+		TF_TCAM_TBL_TYPE_WC_TCAM_HIGH,
+	[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS]      =
+		TF_TCAM_TBL_TYPE_WC_TCAM_LOW,
+};
+
+int
+cfa_tcam_mgr_get_phys_table_type(enum cfa_tcam_mgr_tbl_type type)
+{
+	if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX)
+		assert(0);
+	else
+		return physical_table_types[type];
+}
+
+const char *
+cfa_tcam_mgr_tbl_2_str(enum cfa_tcam_mgr_tbl_type tcam_type)
+{
+	switch (tcam_type) {
+	case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM:
+		return "l2_ctxt_tcam_high AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS:
+		return "l2_ctxt_tcam_high Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM:
+		return "l2_ctxt_tcam_low AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS:
+		return "l2_ctxt_tcam_low Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM:
+		return "prof_tcam AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS:
+		return "prof_tcam Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM:
+		return "wc_tcam AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS:
+		return "wc_tcam Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM:
+		return "veb_tcam AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS:
+		return "veb_tcam Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM:
+		return "sp_tcam AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS:
+		return "sp_tcam Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM:
+		return "ct_rule_tcam AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS:
+		return "ct_rule_tcam Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM:
+		return "wc_tcam_high AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS:
+		return "wc_tcam_high Apps";
+	case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM:
+		return "wc_tcam_low AFM";
+	case CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS:
+		return "wc_tcam_low Apps";
+	default:
+		return "Invalid tcam table type";
+	}
+}
+
+/* key_size and slice_width are in bytes */
+static int
+cfa_tcam_mgr_get_num_slices(unsigned int key_size, unsigned int slice_width)
+{
+	int num_slices = 0;
+
+	if (key_size == 0)
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+
+	num_slices = ((key_size - 1U) / slice_width) + 1U;
+	/* Round up to next highest power of 2 */
+	/* This is necessary since, for example, 3 slices is not a valid entry
+	 * width.
+	 */
+	num_slices--;
+	/* Repeat to maximum number of bits actually used */
+	/* This fills in all the bits. */
+	num_slices |= num_slices >> 1;
+	num_slices |= num_slices >> 2;
+	num_slices |= num_slices >> 4;
+	/*
+	 * If the maximum number of slices that are supported by the HW
+	 * increases, then additional shifts are needed.
+	 */
+	num_slices++;
+	return num_slices;
+}
+
+static struct cfa_tcam_mgr_entry_data *
+cfa_tcam_mgr_entry_get(int sess_idx, uint16_t id)
+{
+	if (id > cfa_tcam_mgr_max_entries[sess_idx])
+		return NULL;
+
+	return &entry_data[sess_idx][id];
+}
+
+/* Insert an entry into the entry table */
+static int
+cfa_tcam_mgr_entry_insert(int sess_idx, uint16_t id,
+			  struct cfa_tcam_mgr_entry_data *entry)
+{
+	if (id > cfa_tcam_mgr_max_entries[sess_idx])
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+
+	memcpy(&entry_data[sess_idx][id], entry,
+	       sizeof(entry_data[sess_idx][id]));
+
+	return 0;
+}
+
+/* Delete an entry from the entry table */
+static int
+cfa_tcam_mgr_entry_delete(int sess_idx, uint16_t id)
+{
+	if (id > cfa_tcam_mgr_max_entries[sess_idx])
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+
+	memset(&entry_data[sess_idx][id], 0, sizeof(entry_data[sess_idx][id]));
+
+	return 0;
+}
+
+/* Returns the size of the row structure taking into account how many slices a
+ * TCAM supports.
+ */
+static int
+cfa_tcam_mgr_row_size_get(int sess_idx, enum tf_dir dir,
+			  enum cfa_tcam_mgr_tbl_type type)
+{
+	return sizeof(struct cfa_tcam_mgr_table_rows_0) +
+		(cfa_tcam_mgr_tables[sess_idx][dir][type].max_slices *
+		 sizeof(((struct cfa_tcam_mgr_table_rows_0 *)0)->entries[0]));
+}
+
+static void *
+cfa_tcam_mgr_row_ptr_get(void *base, int index, int row_size)
+{
+	return (uint8_t *)base + (index * row_size);
+}
+
+/*
+ * Searches a table to find the direction and type of an entry.
+ */
+static int
+cfa_tcam_mgr_entry_find_in_table(int sess_idx, int id, enum tf_dir dir,
+				 enum cfa_tcam_mgr_tbl_type type)
+{
+	struct cfa_tcam_mgr_table_data *table_data;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	int max_slices, row_idx, row_size, slice;
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+	if (table_data->max_entries > 0 &&
+	    table_data->hcapi_type > 0) {
+		max_slices = table_data->max_slices;
+		row_size = cfa_tcam_mgr_row_size_get(sess_idx, dir, type);
+		for (row_idx = table_data->start_row;
+		     row_idx <= table_data->end_row;
+		     row_idx++) {
+			row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows,
+						       row_idx, row_size);
+			if (!ROW_INUSE(row))
+				continue;
+			for (slice = 0;
+			     slice < (max_slices / row->entry_size);
+			     slice++) {
+				if (!ROW_ENTRY_INUSE(row, slice))
+					continue;
+				if (row->entries[slice] == id)
+					return 0;
+			}
+		}
+	}
+
+	return -CFA_TCAM_MGR_ERR_CODE(NOENT);
+}
+
+/*
+ * Searches all the tables to find the direction and type of an entry.
+ */
+static int
+cfa_tcam_mgr_entry_find(int sess_idx, int id, enum tf_dir *tbl_dir,
+			enum cfa_tcam_mgr_tbl_type *tbl_type)
+{
+	enum tf_dir dir;
+	enum cfa_tcam_mgr_tbl_type type;
+	int rc = -CFA_TCAM_MGR_ERR_CODE(NOENT);
+
+	for (dir = TF_DIR_RX; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
+		for (type = CFA_TCAM_MGR_TBL_TYPE_START;
+		     type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+		     type++) {
+			rc = cfa_tcam_mgr_entry_find_in_table(sess_idx, id, dir, type);
+			if (rc == 0) {
+				*tbl_dir  = dir;
+				*tbl_type = type;
+				return rc;
+			}
+		}
+	}
+
+	return rc;
+}
+
+static int
+cfa_tcam_mgr_row_is_entry_free(struct cfa_tcam_mgr_table_rows_0 *row,
+			      int max_slices,
+			      int key_slices)
+{
+	int j;
+
+	if (ROW_INUSE(row) &&
+	    row->entry_size == key_slices) {
+		for (j = 0; j < (max_slices / row->entry_size); j++) {
+			if (!ROW_ENTRY_INUSE(row, j))
+				return j;
+		}
+	}
+	return -1;
+}
+
+static int
+cfa_tcam_mgr_entry_move(int sess_idx, struct cfa_tcam_mgr_context *context,
+		       enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type,
+		       int entry_id,
+		       struct cfa_tcam_mgr_table_data *table_data,
+		       int dest_row_index, int dest_row_slice,
+		       struct cfa_tcam_mgr_table_rows_0 *dest_row,
+		       int source_row_index,
+		       struct cfa_tcam_mgr_table_rows_0 *source_row,
+		       bool free_source_entry)
+{
+	struct cfa_tcam_mgr_get_parms gparms = { 0 };
+	struct cfa_tcam_mgr_set_parms sparms = { 0 };
+	struct cfa_tcam_mgr_free_parms fparms = { 0 };
+	struct cfa_tcam_mgr_entry_data *entry;
+	uint8_t  key[CFA_TCAM_MGR_MAX_KEY_SIZE];
+	uint8_t  mask[CFA_TCAM_MGR_MAX_KEY_SIZE];
+	uint8_t  result[CFA_TCAM_MGR_MAX_KEY_SIZE];
+
+	int j, rc;
+
+	entry = cfa_tcam_mgr_entry_get(sess_idx, entry_id);
+	if (entry == NULL)
+		return -1;
+
+	gparms.dir	   = dir;
+	gparms.type	   = type;
+	gparms.hcapi_type  = table_data->hcapi_type;
+	gparms.key	   = key;
+	gparms.mask	   = mask;
+	gparms.result	   = result;
+	gparms.id	   = source_row->entries[entry->slice];
+	gparms.key_size	   = sizeof(key);
+	gparms.result_size = sizeof(result);
+
+	rc = cfa_tcam_mgr_entry_get_msg(sess_idx, context, &gparms,
+					source_row_index,
+					entry->slice * source_row->entry_size,
+					table_data->max_slices);
+	if (rc != 0)
+		return rc;
+
+	sparms.dir	   = dir;
+	sparms.type	   = type;
+	sparms.hcapi_type  = table_data->hcapi_type;
+	sparms.key	   = key;
+	sparms.mask	   = mask;
+	sparms.result	   = result;
+	sparms.id	   = gparms.id;
+	sparms.key_size	   = gparms.key_size;
+	sparms.result_size = gparms.result_size;
+
+	/* Slice in destination row not specified. Find first free slice. */
+	if (dest_row_slice < 0)
+		for (j = 0;
+		     j < (table_data->max_slices / dest_row->entry_size);
+		     j++) {
+			if (!ROW_ENTRY_INUSE(dest_row, j)) {
+				dest_row_slice = j;
+				break;
+			}
+		}
+
+	/* If no free slice found, return error. */
+	if (dest_row_slice < 0)
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+	rc = cfa_tcam_mgr_entry_set_msg(sess_idx, context, &sparms,
+					dest_row_index,
+					dest_row_slice * dest_row->entry_size,
+					table_data->max_slices);
+	if (rc != 0)
+		return rc;
+
+	if (free_source_entry) {
+		fparms.dir	  = dir;
+		fparms.type	  = type;
+		fparms.hcapi_type = table_data->hcapi_type;
+		rc = cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+						 source_row_index,
+						 entry->slice *
+						 dest_row->entry_size,
+						 table_data->row_width /
+						 table_data->max_slices *
+						 source_row->entry_size,
+						 table_data->result_size,
+						 table_data->max_slices);
+		if (rc != 0) {
+			CFA_TCAM_MGR_LOG_DIR_TYPE(ERR,
+						  dir, type,
+						 "Failed to free entry ID %d at"
+						 " row %d, slice %d for sess_idx %d. rc: %d.\n",
+						  gparms.id,
+						  source_row_index,
+						  entry->slice,
+						  sess_idx,
+						  -rc);
+		}
+	}
+
+	ROW_ENTRY_SET(dest_row, dest_row_slice);
+	dest_row->entries[dest_row_slice] = entry_id;
+	ROW_ENTRY_CLEAR(source_row, entry->slice);
+	entry->row   = dest_row_index;
+	entry->slice = dest_row_slice;
+
+	return 0;
+}
+
+static int
+cfa_tcam_mgr_row_move(int sess_idx, struct cfa_tcam_mgr_context *context,
+		      enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type,
+		      struct cfa_tcam_mgr_table_data *table_data,
+		      int dest_row_index,
+		      struct cfa_tcam_mgr_table_rows_0 *dest_row,
+		      int source_row_index,
+		      struct cfa_tcam_mgr_table_rows_0 *source_row)
+{
+	struct cfa_tcam_mgr_free_parms fparms = { 0 };
+	int j, rc;
+
+	dest_row->priority   = source_row->priority;
+	dest_row->entry_size = source_row->entry_size;
+	dest_row->entry_inuse = 0;
+
+	fparms.dir	  = dir;
+	fparms.type	  = type;
+	fparms.hcapi_type = table_data->hcapi_type;
+
+	for (j = 0;
+	     j < (table_data->max_slices / source_row->entry_size);
+	     j++) {
+		if (ROW_ENTRY_INUSE(source_row, j)) {
+			cfa_tcam_mgr_entry_move(sess_idx, context, dir, type,
+						source_row->entries[j],
+						table_data,
+						dest_row_index, j, dest_row,
+						source_row_index, source_row,
+						true);
+		} else {
+			/* Slice not in use, write an empty slice. */
+			rc = cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+							dest_row_index,
+							j *
+							dest_row->entry_size,
+							table_data->row_width /
+							table_data->max_slices *
+							dest_row->entry_size,
+							table_data->result_size,
+							table_data->max_slices);
+			if (rc != 0)
+				return rc;
+		}
+	}
+
+	return 0;
+}
+
+/* Install entry into in-memory tables, not into TCAM (yet). */
+static void
+cfa_tcam_mgr_row_entry_install(int sess_idx,
+			       struct cfa_tcam_mgr_table_rows_0 *row,
+			       struct cfa_tcam_mgr_alloc_parms *parms,
+			       struct cfa_tcam_mgr_entry_data *entry,
+			       uint16_t id,
+			       int key_slices,
+			       int row_index, int slice)
+{
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return;
+	}
+
+	if (slice == TF_TCAM_SLICE_INVALID) {
+		slice = 0;
+		row->entry_size = key_slices;
+		row->priority = parms->priority;
+	}
+
+	ROW_ENTRY_SET(row, slice);
+	row->entries[slice] = id;
+	entry->row = row_index;
+	entry->slice = slice;
+}
+
+/* Finds an empty row that can be used and reserve for entry.  If necessary,
+ * entries will be shuffled in order to make room.
+ */
+static struct cfa_tcam_mgr_table_rows_0 *
+cfa_tcam_mgr_empty_row_alloc(int sess_idx, struct cfa_tcam_mgr_context *context,
+			     struct cfa_tcam_mgr_alloc_parms *parms,
+			     struct cfa_tcam_mgr_entry_data *entry,
+			     uint16_t id,
+			     int key_slices)
+{
+	struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+	struct cfa_tcam_mgr_table_rows_0 *from_row;
+	struct cfa_tcam_mgr_table_rows_0 *to_row;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	struct cfa_tcam_mgr_table_data *table_data;
+	int i, max_slices, row_size;
+	int to_row_idx, from_row_idx, slice, start_row, end_row;
+	int empty_row = -1;
+	int target_row = -1;
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+
+	start_row  = table_data->start_row;
+	end_row	   = table_data->end_row;
+	max_slices = table_data->max_slices;
+	tcam_rows  = table_data->tcam_rows;
+
+	row_size   = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+	/*
+	 * First check for partially used entries, but only if the key needs
+	 * fewer slices than there are in a row.
+	 */
+	if (key_slices < max_slices) {
+		for (i = start_row; i <= end_row; i++) {
+			row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+			if (!ROW_INUSE(row))
+				continue;
+			if (row->priority < parms->priority)
+				break;
+			if (row->priority > parms->priority)
+				continue;
+			slice = cfa_tcam_mgr_row_is_entry_free(row,
+							       max_slices,
+							       key_slices);
+			if (slice >= 0) {
+				cfa_tcam_mgr_row_entry_install(sess_idx, row, parms,
+							       entry, id,
+							       key_slices,
+							       i, slice);
+				return row;
+			}
+		}
+	}
+
+	/* No partially used rows available.  Find an empty row, if any. */
+
+	/*
+	 * All max priority entries are placed in the beginning of the TCAM.  It
+	 * should not be necessary to shuffle any of these entries.  All other
+	 * priorities are placed from the end of the TCAM and may require
+	 * shuffling.
+	 */
+	if (parms->priority == TF_TCAM_PRIORITY_MAX) {
+		/* Handle max priority first. */
+		for (i = start_row; i <= end_row; i++) {
+			row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+			if (!ROW_INUSE(row)) {
+				cfa_tcam_mgr_row_entry_install(sess_idx,
+							       row, parms,
+							       entry,
+							       id, key_slices,
+							       i,
+							 TF_TCAM_SLICE_INVALID);
+				return row;
+			}
+			if (row->priority < parms->priority) {
+				/*
+				 * No free entries before priority change, table
+				 * is full.
+				 */
+				return NULL;
+			}
+		}
+		/* No free entries found, table is full. */
+		return NULL;
+	}
+
+	/* Use the highest available entry */
+	for (i = end_row; i >= start_row; i--) {
+		row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+		if (!ROW_INUSE(row)) {
+			empty_row = i;
+			break;
+		}
+
+		if (row->priority > parms->priority &&
+		    target_row < 0)
+			target_row = i;
+	}
+
+	if (empty_row < 0) {
+		/* No free entries found, table is full. */
+		return NULL;
+	}
+
+	if (target_row < 0) {
+		/*
+		 * Did not find a row with higher priority before unused row so
+		 * just install new entry in empty_row.
+		 */
+		row = cfa_tcam_mgr_row_ptr_get(tcam_rows, empty_row, row_size);
+		cfa_tcam_mgr_row_entry_install(sess_idx, row, parms, entry, id,
+					       key_slices, empty_row,
+					       TF_TCAM_SLICE_INVALID);
+		return row;
+	}
+
+	to_row_idx = empty_row;
+	to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, to_row_idx, row_size);
+	while (to_row_idx < target_row) {
+		from_row_idx = to_row_idx + 1;
+		from_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, from_row_idx,
+						    row_size);
+		/*
+		 * Find the highest row with the same priority as the initial
+		 * source row (from_row).  It's only necessary to copy one row
+		 * of each priority.
+		 */
+		for (i = from_row_idx + 1; i <= target_row; i++) {
+			row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+			if (row->priority != from_row->priority)
+				break;
+			from_row_idx = i;
+			from_row = row;
+		}
+		cfa_tcam_mgr_row_move(sess_idx, context, parms->dir, parms->type,
+				      table_data, to_row_idx, to_row,
+				      from_row_idx, from_row);
+		to_row = from_row;
+		to_row_idx = from_row_idx;
+	}
+	to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, target_row, row_size);
+	memset(to_row, 0, row_size);
+	cfa_tcam_mgr_row_entry_install(sess_idx, to_row, parms, entry, id,
+				       key_slices, target_row,
+				       TF_TCAM_SLICE_INVALID);
+
+	return row;
+}
+
+/*
+ * This function will combine rows when possible to result in the fewest rows
+ * used necessary for the entries that are installed.
+ */
+static void
+cfa_tcam_mgr_rows_combine(int sess_idx, struct cfa_tcam_mgr_context *context,
+			  struct cfa_tcam_mgr_free_parms *parms,
+			  struct cfa_tcam_mgr_table_data *table_data,
+			  int changed_row_index)
+{
+	struct cfa_tcam_mgr_table_rows_0 *from_row = NULL;
+	struct cfa_tcam_mgr_table_rows_0 *to_row;
+	struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+	int  i, j, row_size;
+	int  to_row_idx, from_row_idx, start_row, end_row, max_slices;
+	bool entry_moved = false;
+
+	start_row  = table_data->start_row;
+	end_row	   = table_data->end_row;
+	max_slices = table_data->max_slices;
+	tcam_rows  = table_data->tcam_rows;
+
+	row_size   = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+	from_row_idx = changed_row_index;
+	from_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, from_row_idx, row_size);
+
+	if (ROW_INUSE(from_row)) {
+		/*
+		 * Row is still in partial use.  See if remaining entry(s) can
+		 * be moved to free up a row.
+		 */
+		for (i = 0; i < (max_slices / from_row->entry_size); i++) {
+			if (!ROW_ENTRY_INUSE(from_row, i))
+				continue;
+			for (to_row_idx = end_row;
+			     to_row_idx >= start_row;
+			     to_row_idx--) {
+				to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows,
+								  to_row_idx,
+								  row_size);
+				if (!ROW_INUSE(to_row))
+					continue;
+				if (to_row->priority > from_row->priority)
+					break;
+				if (to_row->priority != from_row->priority)
+					continue;
+				if (to_row->entry_size != from_row->entry_size)
+					continue;
+				if (to_row_idx == changed_row_index)
+					continue;
+				for (j = 0;
+				     j < (max_slices / to_row->entry_size);
+				     j++) {
+					if (!ROW_ENTRY_INUSE(to_row, j)) {
+						cfa_tcam_mgr_entry_move
+							(sess_idx,
+							 context,
+							 parms->dir,
+							 parms->type,
+							 from_row->entries[i],
+							 table_data,
+							 to_row_idx,
+							 -1, to_row,
+							 from_row_idx,
+							 from_row,
+							 true);
+						entry_moved = true;
+						break;
+					}
+				}
+				if (entry_moved)
+					break;
+			}
+			if (ROW_INUSE(from_row))
+				entry_moved = false;
+			else
+				break;
+		}
+	}
+}
+
+/*
+ * This function will ensure that all rows, except those of the highest
+ * priority, at the end of the table.  When this function is finished, all the
+ * empty rows should be between the highest priority rows at the beginning of
+ * the table and the rest of the rows with lower priorities.
+ */
+/*
+ * Will need to free the row left newly empty as a result of moving.
+ *
+ * Return row to free to caller.  If new_row_to_free < 0, then no new row to
+ * free.
+ */
+static void
+cfa_tcam_mgr_rows_compact(int sess_idx, struct cfa_tcam_mgr_context *context,
+			  struct cfa_tcam_mgr_free_parms *parms,
+			  struct cfa_tcam_mgr_table_data *table_data,
+			  int *new_row_to_free,
+			  int changed_row_index)
+{
+	struct cfa_tcam_mgr_table_rows_0 *from_row = NULL;
+	struct cfa_tcam_mgr_table_rows_0 *to_row;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+	int  i, row_size, priority;
+	int  to_row_idx = 0, from_row_idx = 0, start_row = 0, end_row = 0;
+
+	*new_row_to_free = -1;
+
+	start_row  = table_data->start_row;
+	end_row	   = table_data->end_row;
+	tcam_rows  = table_data->tcam_rows;
+
+	row_size   = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+	/*
+	 * The row is no longer in use, so see if rows need to be moved in order
+	 * to not leave any gaps.
+	 */
+	to_row_idx = changed_row_index;
+	to_row = cfa_tcam_mgr_row_ptr_get(tcam_rows, to_row_idx, row_size);
+
+	priority = to_row->priority;
+	if (priority == TF_TCAM_PRIORITY_MAX) {
+		if (changed_row_index == end_row)
+			/*
+			 * Nothing to move - the last row in the TCAM is being
+			 * deleted.
+			 */
+			return;
+		for (i = changed_row_index + 1; i <= end_row; i++) {
+			row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+			if (!ROW_INUSE(row))
+				break;
+
+			if (row->priority < priority)
+				break;
+
+			from_row = row;
+			from_row_idx = i;
+		}
+	} else {
+		if (changed_row_index == start_row)
+			/*
+			 * Nothing to move - the first row in the TCAM is being
+			 * deleted.
+			 */
+			return;
+		for (i = changed_row_index - 1; i >= start_row; i--) {
+			row = cfa_tcam_mgr_row_ptr_get(tcam_rows, i, row_size);
+			if (!ROW_INUSE(row))
+				break;
+
+			if (row->priority > priority) {
+				/* Don't move the highest priority rows. */
+				if (row->priority == TF_TCAM_PRIORITY_MAX)
+					break;
+				/*
+				 * If from_row is NULL, that means that there
+				 * were no rows of the deleted priority.
+				 * Nothing to move yet.
+				 *
+				 * If from_row is not NULL, then it is the last
+				 * row with the same priority and must be moved
+				 * to fill the newly empty (by free or by move)
+				 * row.
+				 */
+				if (from_row != NULL) {
+					cfa_tcam_mgr_row_move(sess_idx, context,
+							      parms->dir,
+							      parms->type,
+							      table_data,
+							     to_row_idx, to_row,
+							      from_row_idx,
+							      from_row);
+					*new_row_to_free = from_row_idx;
+					to_row	   = from_row;
+					to_row_idx = from_row_idx;
+				}
+
+				priority = row->priority;
+			}
+			from_row = row;
+			from_row_idx = i;
+		}
+	}
+
+	if (from_row != NULL) {
+		cfa_tcam_mgr_row_move(sess_idx, context, parms->dir, parms->type,
+				      table_data,
+				      to_row_idx, to_row,
+				      from_row_idx, from_row);
+		*new_row_to_free = from_row_idx;
+	}
+}
+
+/*
+ * This function is to set table limits for the logical TCAM tables.
+ */
+static int
+cfa_tcam_mgr_table_limits_set(int sess_idx, struct cfa_tcam_mgr_init_parms *parms)
+{
+	struct cfa_tcam_mgr_table_data *table_data;
+	unsigned int dir, type;
+	int start, stride;
+
+	if (parms == NULL)
+		return 0;
+
+	for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++)
+		for (type = 0;
+		     type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+		     type++) {
+			table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+			/*
+			 * If num_rows is zero, then TCAM Manager did not
+			 * allocate any row storage for that table so cannot
+			 * manage it.
+			 */
+			if (table_data->num_rows == 0)
+				continue;
+			start  = parms->resc[dir][type].start;
+			stride = parms->resc[dir][type].stride;
+			if (start % table_data->max_slices > 0) {
+				CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+							  "Start of resources (%d) for table (%d) "
+							  "does not begin on row boundary.\n",
+							  start, sess_idx);
+				CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+						     "Start is %d, number of slices "
+						     "is %d.\n",
+						     start,
+						     table_data->max_slices);
+				return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+			}
+			if (stride % table_data->max_slices > 0) {
+				CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+							  "Stride of resources (%d) for table (%d)"
+							  " does not end on row boundary.\n",
+							  stride, sess_idx);
+				CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+						     "Stride is %d, number of "
+						     "slices is %d.\n",
+						     stride,
+						     table_data->max_slices);
+				return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+			}
+			if (stride == 0) {
+				table_data->start_row	= 0;
+				table_data->end_row	= 0;
+				table_data->max_entries = 0;
+			} else {
+				table_data->start_row = start /
+					table_data->max_slices;
+				table_data->end_row = table_data->start_row +
+					(stride / table_data->max_slices) - 1;
+				table_data->max_entries =
+					table_data->max_slices *
+					(table_data->end_row -
+					 table_data->start_row + 1);
+			}
+		}
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_init(int sess_idx, enum cfa_tcam_mgr_device_type type,
+		  struct cfa_tcam_mgr_init_parms *parms)
+{
+	struct cfa_tcam_mgr_table_data *table_data;
+	unsigned int dir, tbl_type;
+	int rc;
+
+	switch (type) {
+	case CFA_TCAM_MGR_DEVICE_TYPE_P4:
+	case CFA_TCAM_MGR_DEVICE_TYPE_SR:
+		rc = cfa_tcam_mgr_init_p4(sess_idx, &entry_data[sess_idx]);
+		break;
+	case CFA_TCAM_MGR_DEVICE_TYPE_P5:
+		rc = cfa_tcam_mgr_init_p58(sess_idx, &entry_data[sess_idx]);
+		break;
+	default:
+		CFA_TCAM_MGR_LOG(ERR, "No such device %d for sess_idx %d\n",
+				 type, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+	if (rc < 0)
+		return rc;
+
+	rc = cfa_tcam_mgr_table_limits_set(sess_idx, parms);
+	if (rc < 0)
+		return rc;
+
+	/* Now calculate the max entries per table and global max entries based
+	 * on the updated table limits.
+	 */
+	for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++)
+		for (tbl_type = 0;
+		     tbl_type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+		     tbl_type++) {
+			table_data = &cfa_tcam_mgr_tables[sess_idx][dir][tbl_type];
+			/*
+			 * If num_rows is zero, then TCAM Manager did not
+			 * allocate any row storage for that table so cannot
+			 * manage it.
+			 */
+			if (table_data->num_rows == 0) {
+				table_data->start_row = 0;
+				table_data->end_row = 0;
+				table_data->max_entries = 0;
+			} else if (table_data->end_row >=
+				   table_data->num_rows) {
+				CFA_TCAM_MGR_LOG_DIR_TYPE(EMERG, dir, tbl_type,
+							  "End row is out of "
+							  "range (%d >= %d) for sess_idx %d\n",
+							  table_data->end_row,
+							  table_data->num_rows,
+							  sess_idx);
+				return -CFA_TCAM_MGR_ERR_CODE(FAULT);
+			} else if (table_data->max_entries == 0 &&
+				   table_data->start_row == 0 &&
+				   table_data->end_row == 0) {
+				/* Nothing to do */
+			} else {
+				table_data->max_entries =
+					table_data->max_slices *
+					(table_data->end_row -
+					 table_data->start_row + 1);
+			}
+			cfa_tcam_mgr_max_entries[sess_idx] += table_data->max_entries;
+		}
+
+	rc = cfa_tcam_mgr_hwops_init(type);
+	if (rc < 0)
+		return rc;
+
+	rc = cfa_tcam_mgr_session_init(sess_idx, type);
+	if (rc < 0)
+		return rc;
+
+	global_data_initialized[sess_idx] = 1;
+
+	if (parms != NULL)
+		parms->max_entries = cfa_tcam_mgr_max_entries[sess_idx];
+
+	CFA_TCAM_MGR_LOG(INFO, "Global TCAM table initialized for sess_idx %d.\n",
+			 sess_idx);
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_qcaps(struct cfa_tcam_mgr_context *context __rte_unused,
+		   struct cfa_tcam_mgr_qcaps_parms *parms)
+{
+	unsigned int type;
+	int rc, sess_idx;
+	uint32_t session_id;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	/*
+	 * This code will indicate if TCAM Manager is managing a logical TCAM
+	 * table or not.  If not, then the physical TCAM will have to be
+	 * accessed using the traditional methods.
+	 */
+	parms->rx_tcam_supported = 0;
+	parms->tx_tcam_supported = 0;
+	for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++) {
+		if (cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX][type].max_entries > 0 &&
+		    cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX][type].hcapi_type > 0)
+			parms->rx_tcam_supported |= 1 << cfa_tcam_mgr_get_phys_table_type(type);
+		if (cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX][type].max_entries > 0 &&
+		    cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX][type].hcapi_type > 0)
+			parms->tx_tcam_supported |= 1 << cfa_tcam_mgr_get_phys_table_type(type);
+	}
+
+	return 0;
+}
+
+/*
+ * Manipulate the tables to split the WC TCAM into HIGH and LOW ranges
+ * and also update the sizes in the tcam count array
+ */
+static int
+cfa_tcam_mgr_shared_wc_bind(uint32_t sess_idx, bool dual_ha_app,
+			    uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX])
+{
+	uint16_t start_row, end_row, max_entries, slices;
+	uint16_t num_pools = dual_ha_app ? 4 : 2;
+	enum tf_dir dir;
+	int rc;
+
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		rc = cfa_tcam_mgr_tables_get(sess_idx, dir,
+					     CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+					     &start_row, &end_row, &max_entries, &slices);
+		if (rc)
+			return rc;
+		if (max_entries) {
+			rc = cfa_tcam_mgr_tables_set(sess_idx, dir,
+						     CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+						     start_row,
+						     start_row +
+						     ((max_entries / slices) / num_pools) - 1,
+						     max_entries / num_pools);
+			if (rc)
+				return rc;
+			rc = cfa_tcam_mgr_tables_set(sess_idx, dir,
+						     CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+						     start_row +
+						     ((max_entries / slices) / num_pools),
+						     start_row +
+						     (max_entries / slices) - 1,
+						     max_entries / num_pools);
+			if (rc)
+				return rc;
+			rc = cfa_tcam_mgr_tables_set(sess_idx, dir,
+						     CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+						     0, 0, 0);
+			if (rc)
+				return rc;
+			tcam_cnt[dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS] =
+				max_entries / num_pools;
+			tcam_cnt[dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS] =
+				max_entries / num_pools;
+			tcam_cnt[dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS] = 0;
+		}
+	}
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_bind(struct cfa_tcam_mgr_context *context,
+		  struct cfa_tcam_mgr_cfg_parms *parms)
+{
+	struct cfa_tcam_mgr_table_data   *table_data;
+	struct tf_dev_info *dev;
+	unsigned int dir;
+	int rc, sess_idx;
+	uint32_t session_id;
+	struct tf_session *tfs;
+	unsigned int type;
+	int prev_max_entries;
+	int start, stride;
+	enum cfa_tcam_mgr_device_type device_type;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(context->tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	switch (dev->type) {
+	case TF_DEVICE_TYPE_P4:
+		device_type = CFA_TCAM_MGR_DEVICE_TYPE_P4;
+		break;
+	case TF_DEVICE_TYPE_SR:
+		device_type = CFA_TCAM_MGR_DEVICE_TYPE_SR;
+		break;
+	case TF_DEVICE_TYPE_P5:
+		device_type = CFA_TCAM_MGR_DEVICE_TYPE_P5;
+		break;
+	default:
+		CFA_TCAM_MGR_LOG(ERR, "No such device %d\n", dev->type);
+		return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_add(session_id);
+	if (sess_idx < 0)
+		return sess_idx;
+
+	if (global_data_initialized[sess_idx] == 0) {
+		rc = cfa_tcam_mgr_init(sess_idx, device_type, NULL);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (parms->num_elements != ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir])) {
+		CFA_TCAM_MGR_LOG(ERR,
+				 "Session element count (%d) differs "
+				 "from table count (%zu) for sess_idx %d.\n",
+				 parms->num_elements,
+				 ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]),
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	/*
+	 * Only managing one session. resv_res contains the resources allocated
+	 * to this session by the resource manager.  Update the limits on TCAMs.
+	 */
+	for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
+		for (type = 0;
+		     type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+		     type++) {
+			table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+			prev_max_entries = table_data->max_entries;
+			/*
+			 * In AFM logical tables, max_entries is initialized to
+			 * zero.  These logical tables are not used when TCAM
+			 * Manager is in the core so skip.
+			 */
+			if (prev_max_entries == 0)
+				continue;
+			start  = parms->resv_res[dir][type].start;
+			stride = parms->resv_res[dir][type].stride;
+			if (start % table_data->max_slices > 0) {
+				CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+					 "Start of resources (%d) for table(%d) "
+					 "does not begin on row boundary.\n",
+					 start, sess_idx);
+				CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+					    "Start is %d, number of slices "
+					    "is %d.\n",
+					    start,
+					    table_data->max_slices);
+				(void)cfa_tcam_mgr_session_free(session_id, context);
+				return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+			}
+			if (stride % table_data->max_slices > 0) {
+				CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+					   "Stride of resources (%d) for table(%d) "
+					   "does not end on row boundary.\n",
+					   stride, sess_idx);
+				CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+					    "Stride is %d, number of "
+					    "slices is %d.\n",
+					    stride,
+					    table_data->max_slices);
+				(void)cfa_tcam_mgr_session_free(session_id, context);
+				return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+			}
+			if (stride == 0) {
+				table_data->start_row	= 0;
+				table_data->end_row	= 0;
+				table_data->max_entries = 0;
+			} else {
+				table_data->start_row = start /
+					table_data->max_slices;
+				table_data->end_row = table_data->start_row +
+					(stride / table_data->max_slices) - 1;
+				table_data->max_entries =
+					table_data->max_slices *
+					(table_data->end_row -
+					 table_data->start_row + 1);
+			}
+			cfa_tcam_mgr_max_entries[sess_idx] += (table_data->max_entries -
+						     prev_max_entries);
+		}
+	}
+
+	if (tf_session_is_shared_hotup_session(tfs)) {
+		rc = cfa_tcam_mgr_shared_wc_bind(sess_idx, false, parms->tcam_cnt);
+		if (rc) {
+			(void)cfa_tcam_mgr_session_free(session_id, context);
+			return rc;
+		}
+	}
+
+	rc = cfa_tcam_mgr_session_cfg(session_id, parms->tcam_cnt);
+	if (rc < 0) {
+		(void)cfa_tcam_mgr_session_free(session_id, context);
+		return rc;
+	}
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_unbind(struct cfa_tcam_mgr_context *context)
+{
+	int rc, sess_idx;
+	uint32_t session_id;
+
+	CFA_TCAM_MGR_CHECK_PARMS1(context);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	(void)cfa_tcam_mgr_session_free(session_id, context);
+
+	global_data_initialized[sess_idx] = 0;
+	return 0;
+}
+
+int
+cfa_tcam_mgr_alloc(struct cfa_tcam_mgr_context *context,
+		   struct cfa_tcam_mgr_alloc_parms *parms)
+{
+	struct cfa_tcam_mgr_entry_data    entry;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	struct cfa_tcam_mgr_table_data   *table_data;
+	int dir, tbl_type;
+	int key_slices, rc, sess_idx;
+	int new_entry_id;
+	uint32_t session_id;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	dir = parms->dir;
+	tbl_type = parms->type;
+
+	if (dir >= TF_DIR_MAX) {
+		CFA_TCAM_MGR_LOG(ERR, "Invalid direction: %d.\n", dir);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	if (tbl_type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+		CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+				     "Invalid table type: %d.\n",
+				     tbl_type);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+#if TF_TCAM_PRIORITY_MAX < UINT16_MAX
+	if (parms->priority > TF_TCAM_PRIORITY_MAX) {
+		CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+				     "Priority (%u) out of range (%u -%u).\n",
+				     parms->priority,
+				     TF_TCAM_PRIORITY_MIN,
+				     TF_TCAM_PRIORITY_MAX);
+	}
+#endif
+
+	/* Check for session limits */
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+				 session_id);
+		return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][dir][tbl_type];
+
+	if (parms->key_size == 0 ||
+	    parms->key_size > table_data->row_width) {
+		CFA_TCAM_MGR_LOG_DIR(ERR, dir,
+				     "Invalid key size:%d (range 1-%d) sess_idx %d.\n",
+				     parms->key_size,
+				     table_data->row_width,
+				     sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	/* Check global limits */
+	if (table_data->used_entries >=
+	    table_data->max_entries) {
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, tbl_type,
+					    "Table full sess_idx %d.\n",
+					    sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+	}
+
+	/* There is room, now increment counts and allocate an entry. */
+	new_entry_id = cfa_tcam_mgr_session_entry_alloc(session_id,
+							parms->dir,
+							parms->type);
+	if (new_entry_id < 0)
+		return new_entry_id;
+
+	memset(&entry, 0, sizeof(entry));
+	entry.ref_cnt++;
+
+	key_slices = cfa_tcam_mgr_get_num_slices(parms->key_size,
+						 (table_data->row_width /
+						  table_data->max_slices));
+
+	row = cfa_tcam_mgr_empty_row_alloc(sess_idx, context, parms, &entry,
+					   new_entry_id, key_slices);
+	if (row == NULL) {
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+					    "Table full (HW) sess_idx %d.\n",
+					    sess_idx);
+		(void)cfa_tcam_mgr_session_entry_free(session_id, new_entry_id,
+						      parms->dir, parms->type);
+		return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+	}
+
+	memcpy(&entry_data[sess_idx][new_entry_id],
+	       &entry,
+	       sizeof(entry_data[sess_idx][new_entry_id]));
+	table_data->used_entries += 1;
+
+	cfa_tcam_mgr_entry_insert(sess_idx, new_entry_id, &entry);
+
+	parms->id = new_entry_id;
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_free(struct cfa_tcam_mgr_context *context,
+		  struct cfa_tcam_mgr_free_parms *parms)
+{
+	struct cfa_tcam_mgr_entry_data *entry;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	struct cfa_tcam_mgr_table_data *table_data;
+	int row_size, rc, sess_idx, new_row_to_free;
+	uint32_t session_id;
+	uint16_t id;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+				 session_id);
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	id = parms->id;
+	entry = cfa_tcam_mgr_entry_get(sess_idx, id);
+	if (entry == NULL) {
+		CFA_TCAM_MGR_LOG(INFO, "Entry %d not found for sess_idx %d.\n",
+				 id, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	if (entry->ref_cnt == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Entry %d not in use for sess_idx %d.\n",
+				 id, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	/*
+	 * If the TCAM type is CFA_TCAM_MGR_TBL_TYPE_MAX, that implies that the
+	 * caller does not know the table or direction of the entry and TCAM
+	 * Manager must search the tables to find out which table has the entry
+	 * installed.
+	 *
+	 * This would be the case if RM has informed TCAM Mgr that an entry must
+	 * be freed.  Clients (sessions, AFM) should always know the type and
+	 * direction of the table where an entry is installed.
+	 */
+	if (parms->type == CFA_TCAM_MGR_TBL_TYPE_MAX) {
+		/* Need to search for the entry in the tables */
+		rc = cfa_tcam_mgr_entry_find(sess_idx, id, &parms->dir, &parms->type);
+		if (rc < 0) {
+			CFA_TCAM_MGR_LOG(ERR, "Entry %d not in tables for sess_idx %d.\n",
+					 id, sess_idx);
+			return rc;
+		}
+	}
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+	parms->hcapi_type = table_data->hcapi_type;
+
+	row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+
+	row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, entry->row,
+				       row_size);
+
+	entry->ref_cnt--;
+
+	(void)cfa_tcam_mgr_session_entry_free(session_id, id,
+					      parms->dir, parms->type);
+
+	if (entry->ref_cnt == 0) {
+		cfa_tcam_mgr_entry_free_msg(sess_idx, context, parms,
+					    entry->row,
+					    entry->slice * row->entry_size,
+					    table_data->row_width /
+					    table_data->max_slices *
+					    row->entry_size,
+					    table_data->result_size,
+					    table_data->max_slices);
+		ROW_ENTRY_CLEAR(row, entry->slice);
+
+		new_row_to_free = entry->row;
+		cfa_tcam_mgr_rows_combine(sess_idx, context, parms, table_data,
+					  new_row_to_free);
+
+		if (!ROW_INUSE(row)) {
+			cfa_tcam_mgr_rows_compact(sess_idx, context,
+						  parms, table_data,
+						  &new_row_to_free,
+						  new_row_to_free);
+			if (new_row_to_free >= 0)
+				cfa_tcam_mgr_entry_free_msg(sess_idx, context, parms,
+						   new_row_to_free, 0,
+						   table_data->row_width,
+						   table_data->result_size,
+						   table_data->max_slices);
+		}
+
+		cfa_tcam_mgr_entry_delete(sess_idx, id);
+		table_data->used_entries -= 1;
+	}
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_set(struct cfa_tcam_mgr_context *context,
+		 struct cfa_tcam_mgr_set_parms *parms)
+{
+	struct cfa_tcam_mgr_entry_data *entry;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	struct cfa_tcam_mgr_table_data *table_data;
+	int rc;
+	int row_size, sess_idx;
+	int entry_size_in_bytes;
+	uint32_t session_id;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+				 session_id);
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	entry = cfa_tcam_mgr_entry_get(sess_idx, parms->id);
+	if (entry == NULL) {
+		CFA_TCAM_MGR_LOG(ERR, "Entry %d not found for sess_idx %d.\n",
+				 parms->id, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+	parms->hcapi_type = table_data->hcapi_type;
+
+	row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+	row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, entry->row,
+				       row_size);
+
+	entry_size_in_bytes = table_data->row_width /
+			      table_data->max_slices *
+			      row->entry_size;
+	if (parms->key_size != entry_size_in_bytes) {
+		CFA_TCAM_MGR_LOG(ERR,
+				"Key size(%d) is different from entry "
+				"size(%d).\n",
+				parms->key_size,
+				entry_size_in_bytes);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	rc = cfa_tcam_mgr_entry_set_msg(sess_idx, context, parms,
+					entry->row,
+					entry->slice * row->entry_size,
+					table_data->max_slices);
+	if (rc < 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Failed to set TCAM data.\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+int
+cfa_tcam_mgr_get(struct cfa_tcam_mgr_context *context __rte_unused,
+		 struct cfa_tcam_mgr_get_parms *parms)
+{
+	struct cfa_tcam_mgr_entry_data *entry;
+	struct cfa_tcam_mgr_table_rows_0 *row;
+	struct cfa_tcam_mgr_table_data *table_data;
+	int rc;
+	int row_size, sess_idx;
+	uint32_t session_id;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+				 session_id);
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	entry = cfa_tcam_mgr_entry_get(sess_idx, parms->id);
+	if (entry == NULL) {
+		CFA_TCAM_MGR_LOG(ERR, "Entry %d not found.\n", parms->id);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+	parms->hcapi_type = table_data->hcapi_type;
+
+	row_size = cfa_tcam_mgr_row_size_get(sess_idx, parms->dir, parms->type);
+	row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, entry->row,
+				       row_size);
+
+	rc = cfa_tcam_mgr_entry_get_msg(sess_idx, context, parms,
+					entry->row,
+					entry->slice * row->entry_size,
+					table_data->max_slices);
+	if (rc < 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Failed to read from TCAM.\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+int cfa_tcam_mgr_shared_clear(struct cfa_tcam_mgr_context *context,
+		     struct cfa_tcam_mgr_shared_clear_parms *parms)
+{
+	int rc;
+	uint16_t row, slice = 0;
+	int sess_idx;
+	uint32_t session_id;
+	struct cfa_tcam_mgr_free_parms fparms;
+	struct cfa_tcam_mgr_table_data *table_data;
+	uint16_t start_row, end_row, max_entries, max_slices;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+				 session_id);
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][parms->dir][parms->type];
+	fparms.dir = parms->dir;
+	fparms.type = parms->type;
+	fparms.hcapi_type = table_data->hcapi_type;
+	fparms.id = 0;
+
+	rc = cfa_tcam_mgr_tables_get(sess_idx, parms->dir, parms->type,
+				&start_row, &end_row, &max_entries, &max_slices);
+	if (rc)
+		return rc;
+
+	for (row = start_row; row <= end_row; row++) {
+		cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+					    row,
+					    slice,
+					    table_data->row_width,
+					    table_data->result_size,
+					    table_data->max_slices);
+	}
+	return rc;
+}
+
+static void
+cfa_tcam_mgr_mv_used_entries_cnt(int sess_idx, enum tf_dir dir,
+				 struct cfa_tcam_mgr_table_data *dst_table_data,
+				 struct cfa_tcam_mgr_table_data *src_table_data)
+{
+	dst_table_data->used_entries++;
+	src_table_data->used_entries--;
+
+	cfa_tcam_mgr_mv_session_used_entries_cnt(sess_idx, dir,
+						 CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+						 CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS);
+}
+
+/*
+ * Move HI WC TCAM entries to LOW TCAM region for HA
+ * This happens when secondary is becoming primary
+ */
+static int
+cfa_tcam_mgr_shared_entry_move(int sess_idx, struct cfa_tcam_mgr_context *context,
+		       enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type,
+		       int entry_id,
+		       struct cfa_tcam_mgr_table_data *dst_table_data,
+		       struct cfa_tcam_mgr_table_data *table_data,
+		       int dst_row_index, int dst_row_slice,
+		       struct cfa_tcam_mgr_table_rows_0 *dst_row,
+		       int src_row_index,
+		       struct cfa_tcam_mgr_table_rows_0 *src_row)
+{
+	struct cfa_tcam_mgr_get_parms gparms = { 0 };
+	struct cfa_tcam_mgr_set_parms sparms = { 0 };
+	struct cfa_tcam_mgr_free_parms fparms = { 0 };
+	struct cfa_tcam_mgr_entry_data *entry;
+	uint8_t  key[CFA_TCAM_MGR_MAX_KEY_SIZE];
+	uint8_t  mask[CFA_TCAM_MGR_MAX_KEY_SIZE];
+	uint8_t  result[CFA_TCAM_MGR_MAX_KEY_SIZE];
+
+	int rc;
+
+	entry = cfa_tcam_mgr_entry_get(sess_idx, entry_id);
+	if (entry == NULL)
+		return -1;
+
+	gparms.dir	   = dir;
+	gparms.type	   = type;
+	gparms.hcapi_type  = table_data->hcapi_type;
+	gparms.key	   = key;
+	gparms.mask	   = mask;
+	gparms.result	   = result;
+	gparms.id	   = src_row->entries[entry->slice];
+	gparms.key_size	   = sizeof(key);
+	gparms.result_size = sizeof(result);
+
+	rc = cfa_tcam_mgr_entry_get_msg(sess_idx, context, &gparms,
+					src_row_index,
+					entry->slice * src_row->entry_size,
+					table_data->max_slices);
+	if (rc != 0)
+		return rc;
+
+	sparms.dir	   = dir;
+	sparms.type	   = CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS;
+	sparms.hcapi_type  = table_data->hcapi_type;
+	sparms.key	   = key;
+	sparms.mask	   = mask;
+	sparms.result	   = result;
+	sparms.id	   = gparms.id;
+	sparms.key_size	   = gparms.key_size;
+	sparms.result_size = gparms.result_size;
+
+	rc = cfa_tcam_mgr_entry_set_msg(sess_idx, context, &sparms,
+					dst_row_index,
+					dst_row_slice * dst_row->entry_size,
+					table_data->max_slices);
+	if (rc != 0)
+		return rc;
+
+	fparms.dir	  = dir;
+	fparms.type	  = type;
+	fparms.hcapi_type = table_data->hcapi_type;
+	rc = cfa_tcam_mgr_entry_free_msg(sess_idx, context, &fparms,
+					 src_row_index,
+					 entry->slice *
+					 dst_row->entry_size,
+					 table_data->row_width /
+					 table_data->max_slices *
+					 src_row->entry_size,
+					 table_data->result_size,
+					 table_data->max_slices);
+	if (rc != 0) {
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR,
+					  dir, type,
+					  "Failed to free entry ID %d at"
+					  " row %d, slice %d for sess_idx %d. rc: %d.\n",
+					  gparms.id,
+					  src_row_index,
+					  entry->slice,
+					  sess_idx,
+					  -rc);
+	}
+
+#ifdef CFA_TCAM_MGR_TRACING
+	CFA_TCAM_MGR_TRACE(INFO, "Moved entry %d from row %d, slice %d to "
+			   "row %d, slice %d.\n",
+			   entry_id, src_row_index, entry->slice,
+			   dst_row_index, dst_row_slice);
+#endif
+
+	ROW_ENTRY_SET(dst_row, dst_row_slice);
+	dst_row->entries[dst_row_slice] = entry_id;
+	dst_row->entry_size = src_row->entry_size;
+	dst_row->priority = src_row->priority;
+	ROW_ENTRY_CLEAR(src_row, entry->slice);
+	entry->row = dst_row_index;
+	entry->slice = dst_row_slice;
+
+	cfa_tcam_mgr_mv_used_entries_cnt(sess_idx, dir, dst_table_data, table_data);
+
+#ifdef CFA_TCAM_MGR_TRACING
+	cfa_tcam_mgr_rows_dump(sess_idx, dir, type);
+	cfa_tcam_mgr_rows_dump(sess_idx, dir, CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS);
+#endif
+
+	return 0;
+}
+
+int cfa_tcam_mgr_shared_move(struct cfa_tcam_mgr_context *context,
+		     struct cfa_tcam_mgr_shared_move_parms *parms)
+{
+	int rc;
+	int sess_idx;
+	uint32_t session_id;
+	uint16_t src_row, dst_row, row_size, slice;
+	struct cfa_tcam_mgr_table_rows_0 *src_table_row;
+	struct cfa_tcam_mgr_table_rows_0 *dst_table_row;
+	struct cfa_tcam_mgr_table_data *src_table_data;
+	struct cfa_tcam_mgr_table_data *dst_table_data;
+
+	CFA_TCAM_MGR_CHECK_PARMS2(context, parms);
+
+	rc = cfa_tcam_mgr_get_session_from_context(context, &session_id);
+	if (rc < 0)
+		return rc;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG(ERR, "Session 0x%08x not found.\n",
+				 session_id);
+		return sess_idx;
+	}
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+	}
+
+	src_table_data =
+		&cfa_tcam_mgr_tables[sess_idx][parms->dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS];
+	dst_table_data =
+		&cfa_tcam_mgr_tables[sess_idx][parms->dir][CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS];
+
+	row_size =
+		cfa_tcam_mgr_row_size_get(sess_idx,
+					  parms->dir,
+					  CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS);
+
+	for (src_row = src_table_data->start_row,
+	     dst_row = dst_table_data->start_row;
+	     src_row <= src_table_data->end_row;
+	     src_row++, dst_row++) {
+		src_table_row = cfa_tcam_mgr_row_ptr_get(src_table_data->tcam_rows,
+							 src_row, row_size);
+		dst_table_row = cfa_tcam_mgr_row_ptr_get(dst_table_data->tcam_rows,
+							 dst_row, row_size);
+		if (ROW_INUSE(src_table_row)) {
+			for (slice = 0;
+			     slice < src_table_data->max_slices / src_table_row->entry_size;
+			     slice++) {
+				if (ROW_ENTRY_INUSE(src_table_row, slice)) {
+#ifdef CFA_TCAM_MGR_TRACING
+					CFA_TCAM_MGR_TRACE(INFO, "Move entry id %d "
+							   "from src_row %d, slice %d "
+							   "to dst_row %d, slice %d.\n",
+							   src_table_row->entries[slice],
+							   src_row, slice,
+							   dst_row, slice);
+#endif
+					rc = cfa_tcam_mgr_shared_entry_move(sess_idx,
+							context,
+							parms->dir,
+							CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+							src_table_row->entries[slice],
+							dst_table_data,
+							src_table_data,
+							dst_row, slice,
+							dst_table_row,
+							src_row,
+							src_table_row);
+				}
+			}
+		}
+	}
+
+	return rc;
+}
+
+static void
+cfa_tcam_mgr_tbl_get(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type,
+				uint16_t *start_row,
+				uint16_t *end_row,
+				uint16_t *max_entries,
+				uint16_t *slices)
+{
+	struct cfa_tcam_mgr_table_data *table_data =
+		&cfa_tcam_mgr_tables[sess_idx][dir][type];
+
+	/* Get start, end and max for tcam type*/
+	*start_row = table_data->start_row;
+	*end_row = table_data->end_row;
+	*max_entries = table_data->max_entries;
+	*slices = table_data->max_slices;
+}
+
+int
+cfa_tcam_mgr_tables_get(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type,
+			uint16_t *start_row,
+			uint16_t *end_row,
+			uint16_t *max_entries,
+			uint16_t *slices)
+{
+	CFA_TCAM_MGR_CHECK_PARMS3(start_row, end_row, max_entries);
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: TCAM not initialized for sess_idx %d.\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	if (dir >= TF_DIR_MAX) {
+		CFA_TCAM_MGR_LOG(ERR, "Must specify valid dir (0-%d) forsess_idx %d.\n",
+				 TF_DIR_MAX - 1, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+		CFA_TCAM_MGR_LOG(ERR, "Must specify valid tbl type (0-%d) forsess_idx %d.\n",
+				 CFA_TCAM_MGR_TBL_TYPE_MAX - 1, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	cfa_tcam_mgr_tbl_get(sess_idx, dir,
+				  type,
+				  start_row,
+				  end_row,
+				  max_entries,
+				  slices);
+	return 0;
+}
+
+static void
+cfa_tcam_mgr_tbl_set(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type,
+				uint16_t start_row,
+				uint16_t end_row,
+				uint16_t max_entries)
+{
+	struct cfa_tcam_mgr_table_data *table_data =
+		&cfa_tcam_mgr_tables[sess_idx][dir][type];
+
+	/* Update start, end and max for tcam type*/
+	table_data->start_row = start_row;
+	table_data->end_row = end_row;
+	table_data->max_entries = max_entries;
+}
+
+int
+cfa_tcam_mgr_tables_set(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type,
+			uint16_t start_row,
+			uint16_t end_row,
+			uint16_t max_entries)
+{
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(ERR, "PANIC: TCAM not initialized for sess_idx %d.\n",
+				 sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	if (dir >= TF_DIR_MAX) {
+		CFA_TCAM_MGR_LOG(ERR, "Must specify valid dir (0-%d) forsess_idx %d.\n",
+				 TF_DIR_MAX - 1, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+		CFA_TCAM_MGR_LOG(ERR, "Must specify valid tbl type (0-%d) forsess_idx %d.\n",
+				 CFA_TCAM_MGR_TBL_TYPE_MAX - 1, sess_idx);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	cfa_tcam_mgr_tbl_set(sess_idx, dir,
+				  type,
+				  start_row,
+				  end_row,
+				  max_entries);
+	return 0;
+}
+
+void
+cfa_tcam_mgr_rows_dump(int sess_idx, enum tf_dir dir,
+		       enum cfa_tcam_mgr_tbl_type type)
+{
+	struct cfa_tcam_mgr_table_data *table_data;
+	struct cfa_tcam_mgr_table_rows_0 *table_row;
+	int i, row, row_size;
+	bool row_found = false;
+	bool empty_row = false;
+
+	if (global_data_initialized[sess_idx] == 0) {
+		printf("PANIC: TCAM not initialized for sess_idx %d.\n", sess_idx);
+		return;
+	}
+
+	if (dir >= TF_DIR_MAX) {
+		printf("Must specify a valid direction (0-%d).\n",
+		       TF_DIR_MAX - 1);
+		return;
+	}
+	if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+		printf("Must specify a valid type (0-%d).\n",
+		       CFA_TCAM_MGR_TBL_TYPE_MAX - 1);
+		return;
+	}
+
+	table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+	row_size = cfa_tcam_mgr_row_size_get(sess_idx, dir, type);
+
+	printf("\nTCAM Rows:\n");
+	printf("Rows for direction %s, Logical table type %s\n",
+	       tf_dir_2_str(dir), cfa_tcam_mgr_tbl_2_str(type));
+	printf("Managed rows %d-%d for sess_idx %d:\n",
+	       table_data->start_row, table_data->end_row, sess_idx);
+
+	printf("Index Pri   Size  Entry IDs\n");
+	printf("                  Sl 0");
+	for (i = 1; i < table_data->max_slices; i++)
+		printf("  Sl %d", i);
+	printf("\n");
+	for (row = table_data->start_row; row <= table_data->end_row; row++) {
+		table_row = cfa_tcam_mgr_row_ptr_get(table_data->tcam_rows, row,
+						    row_size);
+		if (ROW_INUSE(table_row)) {
+			empty_row = false;
+			printf("%5u %5u %4u",
+			       row,
+			       TF_TCAM_PRIORITY_MAX - table_row->priority - 1,
+			       table_row->entry_size);
+			for (i = 0;
+			     i < table_data->max_slices / table_row->entry_size;
+			     i++) {
+				if (ROW_ENTRY_INUSE(table_row, i))
+					printf(" %5u", table_row->entries[i]);
+				else
+					printf("     x");
+			}
+			printf("\n");
+			row_found = true;
+		} else if (!empty_row) {
+			empty_row = true;
+			printf("\n");
+		}
+	}
+
+	if (!row_found)
+		printf("No rows in use.\n");
+}
+
+static void
+cfa_tcam_mgr_table_dump(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type)
+{
+	struct cfa_tcam_mgr_table_data *table_data =
+		&cfa_tcam_mgr_tables[sess_idx][dir][type];
+
+	printf("%3s %-22s %5u %5u %5u %5u %6u %7u %2u\n",
+	       tf_dir_2_str(dir),
+	       cfa_tcam_mgr_tbl_2_str(type),
+	       table_data->row_width,
+	       table_data->num_rows,
+	       table_data->start_row,
+	       table_data->end_row,
+	       table_data->max_entries,
+	       table_data->used_entries,
+	       table_data->max_slices);
+}
+
+#define TABLE_DUMP_HEADER \
+	"Dir Table                  Width  Rows Start   End " \
+	"MaxEnt UsedEnt Slices\n"
+
+void
+cfa_tcam_mgr_tables_dump(int sess_idx, enum tf_dir dir,
+			 enum cfa_tcam_mgr_tbl_type type)
+{
+	if (global_data_initialized[sess_idx] == 0) {
+		printf("PANIC: TCAM not initialized for sess_idx %d.\n", sess_idx);
+		return;
+	}
+
+	printf("\nTCAM Table(s) for sess_idx %d:\n", sess_idx);
+	printf(TABLE_DUMP_HEADER);
+	if (dir >= TF_DIR_MAX) {
+		/* Iterate over all directions */
+		for (dir = 0; dir < TF_DIR_MAX; dir++) {
+			if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+				/* Iterate over all types */
+				for (type = 0;
+				     type < CFA_TCAM_MGR_TBL_TYPE_MAX;
+				     type++) {
+					cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+				}
+			} else {
+				/* Display a specific type */
+				cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+			}
+		}
+	} else if (type >= CFA_TCAM_MGR_TBL_TYPE_MAX) {
+		/* Iterate over all types for a direction */
+		for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++)
+			cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+	} else {
+		/* Display a specific direction and type */
+		cfa_tcam_mgr_table_dump(sess_idx, dir, type);
+	}
+}
+
+#define ENTRY_DUMP_HEADER "Entry RefCnt  Row Slice\n"
+
+void
+cfa_tcam_mgr_entries_dump(int sess_idx)
+{
+	struct cfa_tcam_mgr_entry_data *entry;
+	bool entry_found = false;
+	uint16_t id;
+
+	if (global_data_initialized[sess_idx] == 0) {
+		CFA_TCAM_MGR_LOG(INFO, "PANIC: No TCAM data created for sess_idx %d\n",
+				 sess_idx);
+		return;
+	}
+
+	printf("\nGlobal Maximum Entries: %d\n\n",
+	       cfa_tcam_mgr_max_entries[sess_idx]);
+	printf("TCAM Entry Table:\n");
+	for (id = 0; id < cfa_tcam_mgr_max_entries[sess_idx]; id++) {
+		if (entry_data[sess_idx][id].ref_cnt > 0) {
+			entry = &entry_data[sess_idx][id];
+			if (!entry_found)
+				printf(ENTRY_DUMP_HEADER);
+			printf("%5u %5u %5u %5u",
+			       id, entry->ref_cnt,
+			       entry->row, entry->slice);
+			printf("\n");
+			entry_found = true;
+		}
+	}
+
+	if (!entry_found)
+		printf("No entries found.\n");
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.h
new file mode 100644
index 0000000000..40bfe8e225
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr.h
@@ -0,0 +1,523 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _CFA_TCAM_MGR_H_
+#define _CFA_TCAM_MGR_H_
+
+#include <errno.h>
+#include "rte_common.h"
+#include "hsi_struct_def_dpdk.h"
+#include "tf_core.h"
+
+#ifndef __rte_unused
+#define __rte_unused __attribute__((unused))
+#endif
+
+/**
+ * The TCAM module provides processing of Internal TCAM types.
+ */
+
+#ifndef TF_TCAM_MAX_SESSIONS
+#define TF_TCAM_MAX_SESSIONS 16
+#endif
+
+#define ENTRY_ID_INVALID UINT16_MAX
+
+#define TF_TCAM_PRIORITY_MIN 0
+#define TF_TCAM_PRIORITY_MAX UINT16_MAX
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(_array) (sizeof(_array) / sizeof(_array[0]))
+#endif
+
+/* Use TFP_DRV_LOG definition in tfp.h */
+#define CFA_TCAM_MGR_LOG(level, fmt, args...)	\
+	TFP_DRV_LOG(level, fmt, ## args)
+#define CFA_TCAM_MGR_LOG_DIR(level, dir, fmt, args...)			\
+	TFP_DRV_LOG(level, "%s: " fmt, tf_dir_2_str(dir), ## args)
+#define CFA_TCAM_MGR_LOG_DIR_TYPE(level, dir, type, fmt, args...)	\
+	TFP_DRV_LOG(level, "%s: %s " fmt, tf_dir_2_str(dir),		\
+		    cfa_tcam_mgr_tbl_2_str(type), ## args)
+
+#define CFA_TCAM_MGR_LOG_0(level, fmt)		\
+	TFP_DRV_LOG(level, fmt)
+#define CFA_TCAM_MGR_LOG_DIR_0(level, dir, fmt)			\
+	TFP_DRV_LOG(level, "%s: " fmt, tf_dir_2_str(dir))
+#define CFA_TCAM_MGR_LOG_DIR_TYPE_0(level, dir, type, fmt)	\
+	TFP_DRV_LOG(level, "%s: %s " fmt, tf_dir_2_str(dir),	\
+		    cfa_tcam_mgr_tbl_2_str(type))
+
+#define CFA_TCAM_MGR_ERR_CODE(type) E ## type
+
+/**
+ * Checks 1 parameter against NULL.
+ */
+#define CFA_TCAM_MGR_CHECK_PARMS1(parms) do {				\
+		if ((parms) == NULL) {					\
+			CFA_TCAM_MGR_LOG_0(ERR, "Invalid Argument(s)\n"); \
+			return -CFA_TCAM_MGR_ERR_CODE(INVAL);		\
+		}							\
+	} while (0)
+
+/**
+ * Checks 2 parameters against NULL.
+ */
+#define CFA_TCAM_MGR_CHECK_PARMS2(parms1, parms2) do {			\
+		if ((parms1) == NULL || (parms2) == NULL) {		\
+			CFA_TCAM_MGR_LOG_0(ERR, "Invalid Argument(s)\n"); \
+			return -CFA_TCAM_MGR_ERR_CODE(INVAL);		\
+		}							\
+	} while (0)
+
+/**
+ * Checks 3 parameters against NULL.
+ */
+#define CFA_TCAM_MGR_CHECK_PARMS3(parms1, parms2, parms3) do {		\
+		if ((parms1) == NULL ||					\
+		    (parms2) == NULL ||					\
+		    (parms3) == NULL) {					\
+			CFA_TCAM_MGR_LOG_0(ERR, "Invalid Argument(s)\n"); \
+			return -CFA_TCAM_MGR_ERR_CODE(INVAL);		\
+		}							\
+	} while (0)
+
+enum cfa_tcam_mgr_tbl_type {
+	/* Logical TCAM tables */
+	CFA_TCAM_MGR_TBL_TYPE_START,
+	CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM =
+		CFA_TCAM_MGR_TBL_TYPE_START,
+	CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM,
+	CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+	CFA_TCAM_MGR_TBL_TYPE_MAX
+};
+
+enum cfa_tcam_mgr_device_type {
+	CFA_TCAM_MGR_DEVICE_TYPE_P4 = 0,
+	CFA_TCAM_MGR_DEVICE_TYPE_SR,
+	CFA_TCAM_MGR_DEVICE_TYPE_P5,
+	CFA_TCAM_MGR_DEVICE_TYPE_MAX
+};
+
+struct cfa_tcam_mgr_context {
+	struct tf *tfp;
+};
+
+/**
+ * TCAM Manager initialization parameters
+ */
+struct cfa_tcam_mgr_init_parms {
+	/**
+	 * [in] TCAM resources reserved
+	 *      type element is not used.
+	 */
+	struct tf_rm_resc_entry resc[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+	/**
+	 * [out] maximum number of entries available.
+	 */
+	uint32_t max_entries;
+};
+
+/**
+ * TCAM Manager initialization parameters
+ */
+struct cfa_tcam_mgr_qcaps_parms {
+	/**
+	 * [out] Bitmasks.  Set if TCAM Manager is managing a logical TCAM.
+	 * Each bitmask is indexed by logical TCAM table ID.
+	 */
+	uint32_t rx_tcam_supported;
+	uint32_t tx_tcam_supported;
+};
+
+/**
+ * TCAM Manager configuration parameters
+ */
+struct cfa_tcam_mgr_cfg_parms {
+	/**
+	 * [in] Number of tcam types in each of the configuration arrays
+	 */
+	uint16_t num_elements;
+	/**
+	 * [in] Session resource allocations
+	 */
+	uint16_t tcam_cnt[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+
+	/**
+	 * [in] TCAM Locations reserved
+	 */
+	struct tf_rm_resc_entry (*resv_res)[CFA_TCAM_MGR_TBL_TYPE_MAX];
+};
+
+/**
+ * TCAM Manager allocation parameters
+ */
+struct cfa_tcam_mgr_alloc_parms {
+	/**
+	 * [in] Receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Type of the allocation
+	 */
+	enum cfa_tcam_mgr_tbl_type type;
+	/**
+	 * [in] Type of HCAPI
+	 */
+	uint16_t hcapi_type;
+	/**
+	 * [in] key size (bytes)
+	 */
+	uint16_t key_size;
+	/**
+	 * [in] Priority of entry requested (definition TBD)
+	 */
+	uint16_t priority;
+	/**
+	 * [out] Id of allocated entry or found entry (if search_enable)
+	 */
+	uint16_t id;
+};
+
+/**
+ * TCAM Manager free parameters
+ */
+struct cfa_tcam_mgr_free_parms {
+	/**
+	 * [in] Receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Type of the allocation
+	 * If the type is not known, set the type to CFA_TCAM_MGR_TBL_TYPE_MAX.
+	 */
+	enum cfa_tcam_mgr_tbl_type type;
+	/**
+	 * [in] Type of HCAPI
+	 */
+	uint16_t hcapi_type;
+	/**
+	 * [in] Entry ID to free
+	 */
+	uint16_t id;
+};
+
+/**
+ * TCAM Manager set parameters
+ */
+struct cfa_tcam_mgr_set_parms {
+	/**
+	 * [in] Receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Type of object to set
+	 */
+	enum cfa_tcam_mgr_tbl_type type;
+	/**
+	 * [in] Type of HCAPI
+	 */
+	uint16_t hcapi_type;
+	/**
+	 * [in] Entry ID to write to
+	 */
+	uint16_t id;
+	/**
+	 * [in] array containing key
+	 */
+	uint8_t *key;
+	/**
+	 * [in] array containing mask fields
+	 */
+	uint8_t *mask;
+	/**
+	 * [in] key size (bytes)
+	 */
+	uint16_t key_size;
+	/**
+	 * [in] array containing result
+	 */
+	uint8_t *result;
+	/**
+	 * [in] result size (bytes)
+	 */
+	uint16_t result_size;
+};
+
+/**
+ * TCAM Manager get parameters
+ */
+struct cfa_tcam_mgr_get_parms {
+	/**
+	 * [in] Receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] Type of object to get
+	 */
+	enum cfa_tcam_mgr_tbl_type type;
+	/**
+	 * [in] Type of HCAPI
+	 */
+	uint16_t hcapi_type;
+	/**
+	 * [in] Entry ID to read
+	 */
+	uint16_t id;
+	/**
+	 * [out] array containing key
+	 */
+	uint8_t *key;
+	/**
+	 * [out] array containing mask fields
+	 */
+	uint8_t *mask;
+	/**
+	 * [out] key size (bytes)
+	 */
+	uint16_t key_size;
+	/**
+	 * [out] array containing result
+	 */
+	uint8_t *result;
+	/**
+	 * [out] result size (bytes)
+	 */
+	uint16_t result_size;
+};
+
+/**
+ * cfa_tcam_mgr_shared_clear_parms parameter definition
+ */
+struct cfa_tcam_mgr_shared_clear_parms {
+	/**
+	 * [in] receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] TCAM table type
+	 */
+	enum cfa_tcam_mgr_tbl_type type;
+};
+
+/**
+ * cfa_tcam_mgr_shared_move_parms parameter definition
+ */
+struct cfa_tcam_mgr_shared_move_parms {
+	/**
+	 * [in] receive or transmit direction
+	 */
+	enum tf_dir dir;
+	/**
+	 * [in] TCAM table type
+	 */
+	enum cfa_tcam_mgr_tbl_type type;
+};
+
+/**
+ * @page tcam TCAM Manager
+ *
+ * @ref cfa_tcam_mgr_init
+ *
+ * @ref cfa_tcam_mgr_get_phys_table_type
+ *
+ * @ref cfa_tcam_mgr_bind
+ *
+ * @ref cfa_tcam_mgr_unbind
+ *
+ * @ref cfa_tcam_mgr_alloc
+ *
+ * @ref cfa_tcam_mgr_free
+ *
+ * @ref cfa_tcam_mgr_set
+ *
+ * @ref cfa_tcam_mgr_get
+ *
+ */
+
+const char *
+cfa_tcam_mgr_tbl_2_str(enum cfa_tcam_mgr_tbl_type tcam_type);
+
+/**
+ * Initializes the TCAM Manager
+ *
+ * [in] type
+ *   Device type
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (<0) on failure.
+ */
+int
+cfa_tcam_mgr_init(int sess_idx, enum cfa_tcam_mgr_device_type type,
+		  struct cfa_tcam_mgr_init_parms *parms);
+
+/**
+ * Returns the physical TCAM table that a logical TCAM table uses.
+ *
+ * [in] type
+ *   Logical table type
+ *
+ * Returns
+ *   - (tf_tcam_tbl_type) if successful.
+ *   - (<0) on failure.
+ */
+int
+cfa_tcam_mgr_get_phys_table_type(enum cfa_tcam_mgr_tbl_type type);
+
+/**
+ * Queries the capabilities of TCAM Manager.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [out] parms
+ *   Pointer to parameters to be returned
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (<0) on failure.
+ */
+int
+cfa_tcam_mgr_qcaps(struct cfa_tcam_mgr_context *context __rte_unused,
+		   struct cfa_tcam_mgr_qcaps_parms *parms);
+
+/**
+ * Initializes the TCAM module with the requested DBs. Must be
+ * invoked as the first thing before any of the access functions.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_bind(struct cfa_tcam_mgr_context *context,
+		      struct cfa_tcam_mgr_cfg_parms *parms);
+
+/**
+ * Cleans up the private DBs and releases all the data.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_unbind(struct cfa_tcam_mgr_context *context);
+
+/**
+ * Allocates the requested tcam type from the internal RM DB.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_alloc(struct cfa_tcam_mgr_context *context,
+		       struct cfa_tcam_mgr_alloc_parms *parms);
+
+/**
+ * Free's the requested table type and returns it to the DB.
+ * If refcount goes to 0 then it is returned to the table type DB.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_free(struct cfa_tcam_mgr_context *context,
+		      struct cfa_tcam_mgr_free_parms *parms);
+
+/**
+ * Configures the requested element by sending a firmware request which
+ * then installs it into the device internal structures.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_set(struct cfa_tcam_mgr_context *context,
+		     struct cfa_tcam_mgr_set_parms *parms);
+
+/**
+ * Retrieves the requested element by sending a firmware request to get
+ * the element.
+ *
+ * [in] context
+ *   Pointer to context information
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int cfa_tcam_mgr_get(struct cfa_tcam_mgr_context *context,
+		     struct cfa_tcam_mgr_get_parms *parms);
+
+int
+cfa_tcam_mgr_tables_get(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type,
+			uint16_t *start_row,
+			uint16_t *end_row,
+			uint16_t *max_entries,
+			uint16_t *slices);
+int
+cfa_tcam_mgr_tables_set(int sess_idx, enum tf_dir dir,
+			enum cfa_tcam_mgr_tbl_type type,
+			uint16_t start_row,
+			uint16_t end_row,
+			uint16_t max_entries);
+
+int cfa_tcam_mgr_shared_clear(struct cfa_tcam_mgr_context *context,
+		     struct cfa_tcam_mgr_shared_clear_parms *parms);
+
+int cfa_tcam_mgr_shared_move(struct cfa_tcam_mgr_context *context,
+		     struct cfa_tcam_mgr_shared_move_parms *parms);
+
+void cfa_tcam_mgr_rows_dump(int sess_idx, enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type);
+void cfa_tcam_mgr_tables_dump(int sess_idx, enum tf_dir dir, enum cfa_tcam_mgr_tbl_type type);
+void cfa_tcam_mgr_entries_dump(int sess_idx);
+#endif /* _CFA_TCAM_MGR_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h
new file mode 100644
index 0000000000..6ab9b5e118
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_device.h
@@ -0,0 +1,101 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_DEVICE_H
+#define CFA_TCAM_MGR_DEVICE_H
+
+#include <inttypes.h>
+#include "cfa_tcam_mgr.h"
+
+/*
+ * This identifier is to be used for one-off variable sizes.  Do not use it for
+ * sizing keys in an array.
+ */
+#define CFA_TCAM_MGR_MAX_KEY_SIZE 96
+
+/* Note that this macro's arguments are not macro expanded due to
+ * concatenation.
+ */
+#define TF_TCAM_TABLE_ROWS_DEF(_slices)					\
+	struct cfa_tcam_mgr_table_rows_ ## _slices {			\
+		uint16_t priority;					\
+		uint8_t entry_size;		/* Slices per entry */	\
+		uint8_t entry_inuse;	        /* bit[entry] set if in use */ \
+		uint16_t entries[_slices];				\
+	}
+
+/*
+ * Have to explicitly declare this struct since some compilers don't accept the
+ * GNU C extension of zero length arrays.
+ */
+struct cfa_tcam_mgr_table_rows_0 {
+	uint16_t priority;
+	uint8_t entry_size;		/* Slices per entry */
+	uint8_t entry_inuse;	        /* bit[entry] set if in use */
+	uint16_t entries[];
+};
+
+TF_TCAM_TABLE_ROWS_DEF(1);
+TF_TCAM_TABLE_ROWS_DEF(2);
+TF_TCAM_TABLE_ROWS_DEF(4);
+TF_TCAM_TABLE_ROWS_DEF(8);
+
+#define TF_TCAM_MAX_ENTRIES (L2_CTXT_TCAM_RX_MAX_ENTRIES +	\
+			     L2_CTXT_TCAM_TX_MAX_ENTRIES +	\
+			     PROF_TCAM_RX_MAX_ENTRIES +		\
+			     PROF_TCAM_TX_MAX_ENTRIES +		\
+			     WC_TCAM_RX_MAX_ENTRIES +		\
+			     WC_TCAM_TX_MAX_ENTRIES +		\
+			     SP_TCAM_RX_MAX_ENTRIES +		\
+			     SP_TCAM_TX_MAX_ENTRIES +		\
+			     CT_RULE_TCAM_RX_MAX_ENTRIES +	\
+			     CT_RULE_TCAM_TX_MAX_ENTRIES +	\
+			     VEB_TCAM_RX_MAX_ENTRIES +		\
+			     VEB_TCAM_TX_MAX_ENTRIES)
+
+struct cfa_tcam_mgr_entry_data {
+	uint16_t row;
+	uint8_t slice;
+	uint8_t ref_cnt;
+};
+
+struct cfa_tcam_mgr_table_data {
+	struct cfa_tcam_mgr_table_rows_0 *tcam_rows;
+	uint16_t hcapi_type;
+	uint16_t num_rows;		/* Rows in physical TCAM */
+	uint16_t start_row;		/* Where the logical TCAM starts */
+	uint16_t end_row;		/* Where the logical TCAM ends */
+	uint16_t max_entries;
+	uint16_t used_entries;
+	uint8_t  row_width;		/* bytes */
+	uint8_t  result_size;		/* bytes */
+	uint8_t  max_slices;
+};
+
+extern int cfa_tcam_mgr_max_entries[TF_TCAM_MAX_SESSIONS];
+
+extern struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables[TF_TCAM_MAX_SESSIONS][TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+
+/* HW OP definitions begin here */
+typedef int (*cfa_tcam_mgr_hwop_set_func_t)(int sess_idx,
+					    struct cfa_tcam_mgr_set_parms
+					    *parms, int row, int slice,
+					    int max_slices);
+typedef int (*cfa_tcam_mgr_hwop_get_func_t)(int sess_idx,
+					    struct cfa_tcam_mgr_get_parms
+					    *parms, int row, int slice,
+					    int max_slices);
+typedef int (*cfa_tcam_mgr_hwop_free_func_t)(int sess_idx,
+					     struct cfa_tcam_mgr_free_parms
+					     *parms, int row, int slice,
+					     int max_slices);
+
+struct cfa_tcam_mgr_hwops_funcs {
+	cfa_tcam_mgr_hwop_set_func_t set;
+	cfa_tcam_mgr_hwop_get_func_t get;
+	cfa_tcam_mgr_hwop_free_func_t free;
+};
+#endif /* CFA_TCAM_MGR_DEVICE_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c
new file mode 100644
index 0000000000..0fb5563cc3
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.c
@@ -0,0 +1,201 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+/*
+ * This file will "do the right thing" for each of the primitives set, get and
+ * free. The TCAM manager is running in the core, so the tables will be cached.
+ * Set and free messages will also be sent to the firmware.  Instead of sending
+ * get messages, the entry will be read from the cached copy thus saving a
+ * firmware message.
+ */
+
+#include "tf_tcam.h"
+#include "hcapi_cfa_defs.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_hwop_msg.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr_p4.h"
+#include "tf_session.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "tf_util.h"
+
+/*
+ * The free hwop will free more than a single slice so cannot be used.
+ */
+struct cfa_tcam_mgr_hwops_funcs hwop_funcs;
+
+int
+cfa_tcam_mgr_hwops_init(enum cfa_tcam_mgr_device_type type)
+{
+	switch (type) {
+	case CFA_TCAM_MGR_DEVICE_TYPE_P4:
+	case CFA_TCAM_MGR_DEVICE_TYPE_SR:
+		return cfa_tcam_mgr_hwops_get_funcs_p4(&hwop_funcs);
+	case CFA_TCAM_MGR_DEVICE_TYPE_P5:
+		return cfa_tcam_mgr_hwops_get_funcs_p58(&hwop_funcs);
+	default:
+		CFA_TCAM_MGR_LOG(ERR, "No such device\n");
+		return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+}
+
+/*
+ * This is the glue between the TCAM manager and the firmware HW operations.  It
+ * is intended to abstract out the location of the TCAM manager so that the TCAM
+ * manager code will be the same whether or not it is actually using the
+ * firmware.
+ */
+
+int
+cfa_tcam_mgr_entry_set_msg(int sess_idx, struct cfa_tcam_mgr_context *context
+			   __rte_unused,
+			   struct cfa_tcam_mgr_set_parms *parms,
+			   int row, int slice,
+			   int max_slices __rte_unused)
+{
+	cfa_tcam_mgr_hwop_set_func_t set_func;
+
+	set_func = hwop_funcs.set;
+	if (set_func == NULL)
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+	struct tf_tcam_set_parms sparms;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int rc;
+	enum tf_tcam_tbl_type type =
+		cfa_tcam_mgr_get_phys_table_type(parms->type);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(context->tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	memset(&sparms, 0, sizeof(sparms));
+	sparms.dir	   = parms->dir;
+	sparms.type	   = type;
+	sparms.hcapi_type  = parms->hcapi_type;
+	sparms.idx	   = (row * max_slices) + slice;
+	sparms.key	   = parms->key;
+	sparms.mask	   = parms->mask;
+	sparms.key_size	   = parms->key_size;
+	sparms.result	   = parms->result;
+	sparms.result_size = parms->result_size;
+
+	rc = tf_msg_tcam_entry_set(context->tfp, dev, &sparms);
+	if (rc) {
+		/* Log error */
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+					  "Entry %d set failed, rc:%d\n",
+					  parms->id, -rc);
+		return rc;
+	}
+
+	return set_func(sess_idx, parms, row, slice, max_slices);
+}
+
+int
+cfa_tcam_mgr_entry_get_msg(int sess_idx, struct cfa_tcam_mgr_context *context
+			   __rte_unused,
+			   struct cfa_tcam_mgr_get_parms *parms,
+			   int row, int slice,
+			   int max_slices __rte_unused)
+{
+	cfa_tcam_mgr_hwop_get_func_t get_func;
+
+	get_func = hwop_funcs.get;
+	if (get_func == NULL)
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+	return get_func(sess_idx, parms, row, slice, max_slices);
+}
+
+int
+cfa_tcam_mgr_entry_free_msg(int sess_idx, struct cfa_tcam_mgr_context *context
+			    __rte_unused,
+			    struct cfa_tcam_mgr_free_parms *parms,
+			    int row, int slice,
+			    int key_size,
+			    int result_size,
+			    int max_slices)
+{
+	cfa_tcam_mgr_hwop_free_func_t free_func;
+
+	free_func = hwop_funcs.free;
+	if (free_func == NULL)
+		return -CFA_TCAM_MGR_ERR_CODE(PERM);
+
+	struct tf_dev_info *dev;
+	struct tf_session *tfs;
+	int rc;
+	enum tf_tcam_tbl_type type =
+		cfa_tcam_mgr_get_phys_table_type(parms->type);
+
+	/* Free will clear an entire row. */
+	/* Use set message to clear an individual entry */
+	struct tf_tcam_set_parms sparms;
+	uint8_t key[CFA_TCAM_MGR_MAX_KEY_SIZE] = { 0 };
+	uint8_t mask[CFA_TCAM_MGR_MAX_KEY_SIZE] = { 0 };
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(context->tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	if (key_size > CFA_TCAM_MGR_MAX_KEY_SIZE) {
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+					  "Entry %d key size is %d greater than:%d\n",
+					  parms->id, key_size,
+					  CFA_TCAM_MGR_MAX_KEY_SIZE);
+		return -EINVAL;
+	}
+
+	if (result_size > CFA_TCAM_MGR_MAX_KEY_SIZE) {
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+					  "Entry %d result size is %d greater than:%d\n",
+					  parms->id, result_size,
+					  CFA_TCAM_MGR_MAX_KEY_SIZE);
+		return -EINVAL;
+	}
+
+	memset(&sparms, 0, sizeof(sparms));
+	memset(&key, 0, sizeof(key));
+	memset(&mask, 0xff, sizeof(mask));
+
+	sparms.dir	   = parms->dir;
+	sparms.type	   = type;
+	sparms.hcapi_type  = parms->hcapi_type;
+	sparms.key	   = key;
+	sparms.mask	   = mask;
+	sparms.result	   = key;
+	sparms.idx	   = (row * max_slices) + slice;
+	sparms.key_size	   = key_size;
+	sparms.result_size = result_size;
+
+	rc = tf_msg_tcam_entry_set(context->tfp, dev, &sparms);
+	if (rc) {
+		/* Log error */
+		CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, parms->dir, parms->type,
+					  "Row %d, slice %d set failed, "
+					  "rc:%d.\n",
+					  row,
+					  slice,
+					  rc);
+		return rc;
+	}
+	return free_func(sess_idx, parms, row, slice, max_slices);
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h
new file mode 100644
index 0000000000..f7ba625c07
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_hwop_msg.h
@@ -0,0 +1,28 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_HWOP_MSG_H
+#define CFA_TCAM_MGR_HWOP_MSG_H
+
+int
+cfa_tcam_mgr_hwops_init(enum cfa_tcam_mgr_device_type type);
+
+int
+cfa_tcam_mgr_entry_set_msg(int sess_idx,
+			   struct cfa_tcam_mgr_context *context,
+			   struct cfa_tcam_mgr_set_parms *parms,
+			   int row, int slice, int max_slices);
+int
+cfa_tcam_mgr_entry_get_msg(int sess_idx,
+			   struct cfa_tcam_mgr_context *context,
+			   struct cfa_tcam_mgr_get_parms *parms,
+			   int row, int slice, int max_slices);
+int
+cfa_tcam_mgr_entry_free_msg(int sess_idx,
+			    struct cfa_tcam_mgr_context *context,
+			    struct cfa_tcam_mgr_free_parms *parms,
+			    int row, int slice, int key_size,
+			    int result_size, int max_slices);
+#endif  /* CFA_TCAM_MGR_HWOP_MSG_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c
new file mode 100644
index 0000000000..63c84c5938
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.c
@@ -0,0 +1,921 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include "hcapi_cfa_defs.h"
+
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_p4.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_resource_types.h"
+#include "tfp.h"
+#include "assert.h"
+#include "tf_util.h"
+
+/*
+ * Sizings of the TCAMs on P4
+ */
+
+#define MAX_ROW_WIDTH    48
+#define MAX_RESULT_SIZE  8
+
+#if MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#error MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#endif
+
+/*
+ * TCAM definitions
+ *
+ * These define the TCAMs in HW.
+ *
+ * Note: Set xxx_TCAM_[R|T]X_NUM_ROWS to zero if a TCAM is either not supported
+ * by HW or not supported by TCAM Manager.
+ */
+
+/** L2 Context TCAM */
+#define L2_CTXT_TCAM_RX_MAX_SLICES  1
+#define L2_CTXT_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_WORD_ALIGN(167)
+#define L2_CTXT_TCAM_RX_NUM_ROWS    1024
+#define L2_CTXT_TCAM_RX_MAX_ENTRIES (L2_CTXT_TCAM_RX_MAX_SLICES * \
+				     L2_CTXT_TCAM_RX_NUM_ROWS)
+#define L2_CTXT_TCAM_RX_RESULT_SIZE 8
+
+#define L2_CTXT_TCAM_TX_MAX_SLICES  L2_CTXT_TCAM_RX_MAX_SLICES
+#define L2_CTXT_TCAM_TX_ROW_WIDTH   L2_CTXT_TCAM_RX_ROW_WIDTH
+#define L2_CTXT_TCAM_TX_NUM_ROWS    L2_CTXT_TCAM_RX_NUM_ROWS
+#define L2_CTXT_TCAM_TX_MAX_ENTRIES L2_CTXT_TCAM_RX_MAX_ENTRIES
+#define L2_CTXT_TCAM_TX_RESULT_SIZE L2_CTXT_TCAM_RX_RESULT_SIZE
+
+/** Profile TCAM */
+#define PROF_TCAM_RX_MAX_SLICES  1
+#define PROF_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_WORD_ALIGN(81)
+#define PROF_TCAM_RX_NUM_ROWS    1024
+#define PROF_TCAM_RX_MAX_ENTRIES (PROF_TCAM_RX_MAX_SLICES * \
+				  PROF_TCAM_RX_NUM_ROWS)
+#define PROF_TCAM_RX_RESULT_SIZE 8
+
+#define PROF_TCAM_TX_MAX_SLICES  PROF_TCAM_RX_MAX_SLICES
+#define PROF_TCAM_TX_ROW_WIDTH   PROF_TCAM_RX_ROW_WIDTH
+#define PROF_TCAM_TX_NUM_ROWS    PROF_TCAM_RX_NUM_ROWS
+#define PROF_TCAM_TX_MAX_ENTRIES PROF_TCAM_RX_MAX_ENTRIES
+#define PROF_TCAM_TX_RESULT_SIZE PROF_TCAM_RX_RESULT_SIZE
+
+/** Wildcard TCAM */
+#define WC_TCAM_RX_MAX_SLICES  4
+/* 82 bits per slice */
+#define WC_TCAM_RX_ROW_WIDTH   (TF_BITS2BYTES_WORD_ALIGN(82) *	\
+				WC_TCAM_RX_MAX_SLICES)
+#define WC_TCAM_RX_NUM_ROWS    256
+#define WC_TCAM_RX_MAX_ENTRIES (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define WC_TCAM_RX_RESULT_SIZE 4
+
+#define WC_TCAM_TX_MAX_SLICES  WC_TCAM_RX_MAX_SLICES
+#define WC_TCAM_TX_ROW_WIDTH   WC_TCAM_RX_ROW_WIDTH
+#define WC_TCAM_TX_NUM_ROWS    WC_TCAM_RX_NUM_ROWS
+#define WC_TCAM_TX_MAX_ENTRIES WC_TCAM_RX_MAX_ENTRIES
+#define WC_TCAM_TX_RESULT_SIZE WC_TCAM_RX_RESULT_SIZE
+
+/** Source Properties TCAM */
+#define SP_TCAM_RX_MAX_SLICES  1
+#define SP_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_WORD_ALIGN(89)
+#define SP_TCAM_RX_NUM_ROWS    512
+#define SP_TCAM_RX_MAX_ENTRIES (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define SP_TCAM_RX_RESULT_SIZE 8
+
+#define SP_TCAM_TX_MAX_SLICES  SP_TCAM_RX_MAX_SLICES
+#define SP_TCAM_TX_ROW_WIDTH   SP_TCAM_RX_ROW_WIDTH
+#define SP_TCAM_TX_NUM_ROWS    SP_TCAM_RX_NUM_ROWS
+#define SP_TCAM_TX_MAX_ENTRIES SP_TCAM_RX_MAX_ENTRIES
+#define SP_TCAM_TX_RESULT_SIZE SP_TCAM_RX_RESULT_SIZE
+
+/** Connection Tracking Rule TCAM */
+#define CT_RULE_TCAM_RX_MAX_SLICES  1
+#define CT_RULE_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_WORD_ALIGN(16)
+#define CT_RULE_TCAM_RX_NUM_ROWS    0
+#define CT_RULE_TCAM_RX_MAX_ENTRIES (CT_RULE_TCAM_RX_MAX_SLICES * \
+				     CT_RULE_TCAM_RX_NUM_ROWS)
+#define CT_RULE_TCAM_RX_RESULT_SIZE 8
+
+#define CT_RULE_TCAM_TX_MAX_SLICES  CT_RULE_TCAM_RX_MAX_SLICES
+#define CT_RULE_TCAM_TX_ROW_WIDTH   CT_RULE_TCAM_RX_ROW_WIDTH
+#define CT_RULE_TCAM_TX_NUM_ROWS    CT_RULE_TCAM_RX_NUM_ROWS
+#define CT_RULE_TCAM_TX_MAX_ENTRIES CT_RULE_TCAM_RX_MAX_ENTRIES
+#define CT_RULE_TCAM_TX_RESULT_SIZE CT_RULE_TCAM_RX_RESULT_SIZE
+
+/** Virtual Edge Bridge TCAM */
+#define VEB_TCAM_RX_MAX_SLICES  1
+#define VEB_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_WORD_ALIGN(78)
+/* Tx only */
+#define VEB_TCAM_RX_NUM_ROWS    0
+#define VEB_TCAM_RX_MAX_ENTRIES (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+#define VEB_TCAM_RX_RESULT_SIZE 8
+
+#define VEB_TCAM_TX_MAX_SLICES  VEB_TCAM_RX_MAX_SLICES
+#define VEB_TCAM_TX_ROW_WIDTH   VEB_TCAM_RX_ROW_WIDTH
+#define VEB_TCAM_TX_NUM_ROWS    1024
+#define VEB_TCAM_TX_MAX_ENTRIES (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+#define VEB_TCAM_TX_RESULT_SIZE VEB_TCAM_RX_RESULT_SIZE
+
+/* Declare the table rows for each table here.  If new tables are added to the
+ * enum tf_tcam_tbl_type, then new declarations will be needed here.
+ *
+ * The numeric suffix of the structure type indicates how many slices a
+ * particular TCAM supports.
+ *
+ * Array sizes have 1 added to avoid zero length arrays.
+ */
+
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_PROF_TCAM_RX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_PROF_TCAM_TX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_RX[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_TX[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_SP_TCAM_RX[TF_TCAM_MAX_SESSIONS][SP_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_SP_TCAM_TX[TF_TCAM_MAX_SESSIONS][SP_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_VEB_TCAM_RX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_VEB_TCAM_TX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+
+struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables_p4[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX] = {
+	{				/* RX */
+		{			/* High AFM */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* High APPS */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = (L2_CTXT_TCAM_RX_NUM_ROWS / 2) - 1,
+			.max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* Low AFM */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+		},
+		{			/* Low APPS */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_RX_NUM_ROWS,
+			.start_row   = (L2_CTXT_TCAM_RX_NUM_ROWS / 2),
+			.end_row     = L2_CTXT_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+		},
+		{			/* AFM */
+			.max_slices  = PROF_TCAM_RX_MAX_SLICES,
+			.row_width   = PROF_TCAM_RX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = PROF_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = PROF_TCAM_RX_MAX_SLICES,
+			.row_width   = PROF_TCAM_RX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = PROF_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = PROF_TCAM_RX_MAX_ENTRIES,
+			.result_size = PROF_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_RX_MAX_ENTRIES,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = SP_TCAM_RX_MAX_SLICES,
+			.row_width   = SP_TCAM_RX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = SP_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = SP_TCAM_RX_MAX_SLICES,
+			.row_width   = SP_TCAM_RX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = SP_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = SP_TCAM_RX_MAX_ENTRIES,
+			.result_size = SP_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = CT_RULE_TCAM_RX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_RX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = CT_RULE_TCAM_RX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_RX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+#if CT_RULE_TCAM_RX_NUM_ROWS > 0
+			.end_row     = CT_RULE_TCAM_RX_NUM_ROWS - 1,
+#else
+			.end_row     = CT_RULE_TCAM_RX_NUM_ROWS,
+#endif
+			.max_entries = CT_RULE_TCAM_RX_MAX_ENTRIES,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = VEB_TCAM_RX_MAX_SLICES,
+			.row_width   = VEB_TCAM_RX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = VEB_TCAM_RX_MAX_SLICES,
+			.row_width   = VEB_TCAM_RX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+#if VEB_TCAM_RX_NUM_ROWS > 0
+			.end_row     = VEB_TCAM_RX_NUM_ROWS - 1,
+#else
+			.end_row     = VEB_TCAM_RX_NUM_ROWS,
+#endif
+			.max_entries = VEB_TCAM_RX_MAX_ENTRIES,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_RX_MAX_ENTRIES,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_RX_MAX_ENTRIES,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+	},
+	{				/* TX */
+		{			/* AFM */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* APPS */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = (L2_CTXT_TCAM_TX_NUM_ROWS / 2) - 1,
+			.max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* AFM */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+		},
+		{			/* APPS */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = (L2_CTXT_TCAM_TX_NUM_ROWS / 2),
+			.end_row     = L2_CTXT_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW,
+		},
+		{			/* AFM */
+			.max_slices  = PROF_TCAM_TX_MAX_SLICES,
+			.row_width   = PROF_TCAM_TX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = PROF_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = PROF_TCAM_TX_MAX_SLICES,
+			.row_width   = PROF_TCAM_TX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = PROF_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = PROF_TCAM_TX_MAX_ENTRIES,
+			.result_size = PROF_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_PROF_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_TX_MAX_ENTRIES,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = SP_TCAM_TX_MAX_SLICES,
+			.row_width   = SP_TCAM_TX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = SP_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = SP_TCAM_TX_MAX_SLICES,
+			.row_width   = SP_TCAM_TX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = SP_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = SP_TCAM_TX_MAX_ENTRIES,
+			.result_size = SP_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_SP_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = CT_RULE_TCAM_TX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_TX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = CT_RULE_TCAM_TX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_TX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+#if CT_RULE_TCAM_TX_NUM_ROWS > 0
+			.end_row     = CT_RULE_TCAM_TX_NUM_ROWS - 1,
+#else
+			.end_row     = CT_RULE_TCAM_TX_NUM_ROWS,
+#endif
+			.max_entries = CT_RULE_TCAM_TX_MAX_ENTRIES,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = VEB_TCAM_TX_MAX_SLICES,
+			.row_width   = VEB_TCAM_TX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = VEB_TCAM_TX_MAX_SLICES,
+			.row_width   = VEB_TCAM_TX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = VEB_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = VEB_TCAM_TX_MAX_ENTRIES,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_TX_MAX_ENTRIES,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_TX_MAX_ENTRIES,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P4_WC_TCAM,
+		},
+	},
+};
+
+static struct cfa_tcam_mgr_entry_data entry_data_p4[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+static struct sbmp session_bmp_p4[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+int
+cfa_tcam_mgr_sess_table_get_p4(int sess_idx, struct sbmp **session_bmp)
+{
+	*session_bmp = session_bmp_p4[sess_idx];
+	return 0;
+}
+
+int
+cfa_tcam_mgr_init_p4(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data)
+{
+	int max_row_width = 0;
+	int max_result_size = 0;
+	int dir, type;
+
+	*global_entry_data = entry_data_p4[sess_idx];
+
+	memcpy(&cfa_tcam_mgr_tables[sess_idx],
+	       &cfa_tcam_mgr_tables_p4,
+	       sizeof(cfa_tcam_mgr_tables[sess_idx]));
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++) {
+			if (cfa_tcam_mgr_tables[sess_idx][dir][type].row_width >
+			    max_row_width)
+				max_row_width =
+				       cfa_tcam_mgr_tables[sess_idx][dir][type].row_width;
+			if (cfa_tcam_mgr_tables[sess_idx][dir][type].result_size >
+			    max_result_size)
+				max_result_size =
+				     cfa_tcam_mgr_tables[sess_idx][dir][type].result_size;
+		}
+	}
+
+	if (max_row_width != MAX_ROW_WIDTH) {
+		CFA_TCAM_MGR_LOG(ERR,
+				 "MAX_ROW_WIDTH (%d) does not match actual "
+				 "value (%d).\n",
+				 MAX_ROW_WIDTH,
+				 max_row_width);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+	if (max_result_size != MAX_RESULT_SIZE) {
+		CFA_TCAM_MGR_LOG(ERR,
+				 "MAX_RESULT_SIZE (%d) does not match actual "
+				 "value (%d).\n",
+				 MAX_RESULT_SIZE,
+				 max_result_size);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+	return 0;
+}
+
+/* HW OP declarations begin here */
+struct cfa_tcam_mgr_TCAM_row_data {
+	int key_size;
+	int result_size;
+	uint8_t key[MAX_ROW_WIDTH];
+	uint8_t mask[MAX_ROW_WIDTH];
+	uint8_t result[MAX_RESULT_SIZE];
+};
+
+/* These macros are only needed to avoid exceeding 80 columns */
+#define L2_CTXT_RX_MAX_ROWS \
+	(L2_CTXT_TCAM_RX_MAX_SLICES * L2_CTXT_TCAM_RX_NUM_ROWS)
+#define PROF_RX_MAX_ROWS    (PROF_TCAM_RX_MAX_SLICES * PROF_TCAM_RX_NUM_ROWS)
+#define WC_RX_MAX_ROWS	    (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define SP_RX_MAX_ROWS	    (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define CT_RULE_RX_MAX_ROWS \
+	(CT_RULE_TCAM_RX_MAX_SLICES * CT_RULE_TCAM_RX_NUM_ROWS)
+#define VEB_RX_MAX_ROWS	    (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+
+#define L2_CTXT_TX_MAX_ROWS \
+	(L2_CTXT_TCAM_TX_MAX_SLICES * L2_CTXT_TCAM_TX_NUM_ROWS)
+#define PROF_TX_MAX_ROWS    (PROF_TCAM_TX_MAX_SLICES * PROF_TCAM_TX_NUM_ROWS)
+#define WC_TX_MAX_ROWS	    (WC_TCAM_TX_MAX_SLICES * WC_TCAM_TX_NUM_ROWS)
+#define SP_TX_MAX_ROWS	    (SP_TCAM_TX_MAX_SLICES * SP_TCAM_TX_NUM_ROWS)
+#define CT_RULE_TX_MAX_ROWS \
+	(CT_RULE_TCAM_TX_MAX_SLICES * CT_RULE_TCAM_TX_NUM_ROWS)
+#define VEB_TX_MAX_ROWS	    (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+
+static int cfa_tcam_mgr_max_rows[TF_TCAM_TBL_TYPE_MAX] = {
+	L2_CTXT_RX_MAX_ROWS,
+	L2_CTXT_RX_MAX_ROWS,
+	PROF_RX_MAX_ROWS,
+	WC_RX_MAX_ROWS,
+	SP_RX_MAX_ROWS,
+	CT_RULE_RX_MAX_ROWS,
+	VEB_RX_MAX_ROWS,
+	WC_RX_MAX_ROWS,
+	WC_RX_MAX_ROWS
+};
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_PROF_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][PROF_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_SP_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][SP_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_VEB_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][VEB_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_PROF_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][PROF_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_SP_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][SP_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_VEB_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][VEB_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data *
+row_tables[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX] = {
+	{
+		cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_PROF_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_SP_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_VEB_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+	},
+	{
+		cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_PROF_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_SP_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_VEB_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+	}
+};
+
+static int cfa_tcam_mgr_get_max_rows(enum tf_tcam_tbl_type type)
+{
+	if (type >= TF_TCAM_TBL_TYPE_MAX)
+		assert(0);
+	else
+		return cfa_tcam_mgr_max_rows[type];
+}
+
+static int cfa_tcam_mgr_hwop_set(int sess_idx,
+				 struct cfa_tcam_mgr_set_parms *parms, int row,
+				 int slice, int max_slices)
+{
+	struct cfa_tcam_mgr_TCAM_row_data *this_table;
+	struct cfa_tcam_mgr_TCAM_row_data *this_row;
+	this_table = row_tables[parms->dir]
+		[cfa_tcam_mgr_get_phys_table_type(parms->type)];
+	this_table += (sess_idx *
+		       cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+	this_row   = &this_table[row * max_slices + slice];
+	this_row->key_size = parms->key_size;
+	memcpy(&this_row->key, parms->key, parms->key_size);
+	memcpy(&this_row->mask, parms->mask, parms->key_size);
+	this_row->result_size = parms->result_size;
+	if (parms->result != ((void *)0))
+		memcpy(&this_row->result, parms->result, parms->result_size);
+	return 0;
+};
+
+static int cfa_tcam_mgr_hwop_get(int sess_idx,
+				 struct cfa_tcam_mgr_get_parms *parms, int row,
+				 int slice, int max_slices)
+{
+	struct cfa_tcam_mgr_TCAM_row_data *this_table;
+	struct cfa_tcam_mgr_TCAM_row_data *this_row;
+	this_table = row_tables[parms->dir]
+		[cfa_tcam_mgr_get_phys_table_type(parms->type)];
+	this_table += (sess_idx *
+		       cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+	this_row   = &this_table[row * max_slices + slice];
+	parms->key_size = this_row->key_size;
+	parms->result_size = this_row->result_size;
+	if (parms->key != ((void *)0))
+		memcpy(parms->key, &this_row->key, parms->key_size);
+	if (parms->mask != ((void *)0))
+		memcpy(parms->mask, &this_row->mask, parms->key_size);
+	if (parms->result != ((void *)0))
+		memcpy(parms->result, &this_row->result, parms->result_size);
+	return 0;
+};
+
+static int cfa_tcam_mgr_hwop_free(int sess_idx,
+				  struct cfa_tcam_mgr_free_parms *parms,
+				  int row, int slice, int max_slices)
+{
+	struct cfa_tcam_mgr_TCAM_row_data *this_table;
+	struct cfa_tcam_mgr_TCAM_row_data *this_row;
+	this_table = row_tables[parms->dir]
+		[cfa_tcam_mgr_get_phys_table_type(parms->type)];
+	this_table += (sess_idx *
+		       cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+	this_row   = &this_table[row * max_slices + slice];
+	memset(&this_row->key, 0, sizeof(this_row->key));
+	memset(&this_row->mask, 0, sizeof(this_row->mask));
+	memset(&this_row->result, 0, sizeof(this_row->result));
+	this_row->key_size = 0;
+	this_row->result_size = 0;
+	return 0;
+};
+
+int cfa_tcam_mgr_hwops_get_funcs_p4(struct cfa_tcam_mgr_hwops_funcs *hwop_funcs)
+{
+	hwop_funcs->set	 = cfa_tcam_mgr_hwop_set;
+	hwop_funcs->get	 = cfa_tcam_mgr_hwop_get;
+	hwop_funcs->free = cfa_tcam_mgr_hwop_free;
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h
new file mode 100644
index 0000000000..3ca59b2aeb
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p4.h
@@ -0,0 +1,20 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_P4_H
+#define CFA_TCAM_MGR_P4_H
+
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_sbmp.h"
+
+int
+cfa_tcam_mgr_init_p4(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data);
+
+int
+cfa_tcam_mgr_sess_table_get_p4(int sess_idx, struct sbmp **session_bmp);
+
+int
+cfa_tcam_mgr_hwops_get_funcs_p4(struct cfa_tcam_mgr_hwops_funcs *hwop_funcs);
+#endif /* CFA_TCAM_MGR_P4_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c
new file mode 100644
index 0000000000..c9a04dc4e9
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.c
@@ -0,0 +1,926 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include "hcapi_cfa_defs.h"
+
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_resource_types.h"
+#include "tfp.h"
+#include "assert.h"
+#include "tf_util.h"
+
+/*
+ * Sizings of the TCAMs on P5
+ */
+
+#define MAX_ROW_WIDTH    96
+#define MAX_RESULT_SIZE  8
+
+#if MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#error MAX_ROW_WIDTH > CFA_TCAM_MGR_MAX_KEY_SIZE
+#endif
+
+/*
+ * TCAM definitions
+ *
+ * These define the TCAMs in HW.
+ *
+ * Note: Set xxx_TCAM_[R|T]X_NUM_ROWS to zero if a TCAM is either not supported
+ * by HW or not supported by TCAM Manager.
+ */
+
+/** L2 Context TCAM */
+#define L2_CTXT_TCAM_RX_MAX_SLICES  1
+#define L2_CTXT_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_64B_WORD_ALIGN(214)
+#define L2_CTXT_TCAM_RX_NUM_ROWS    1024
+#define L2_CTXT_TCAM_RX_MAX_ENTRIES (L2_CTXT_TCAM_RX_MAX_SLICES * \
+				     L2_CTXT_TCAM_RX_NUM_ROWS)
+#define L2_CTXT_TCAM_RX_RESULT_SIZE 8
+
+#define L2_CTXT_TCAM_TX_MAX_SLICES  L2_CTXT_TCAM_RX_MAX_SLICES
+#define L2_CTXT_TCAM_TX_ROW_WIDTH   L2_CTXT_TCAM_RX_ROW_WIDTH
+#define L2_CTXT_TCAM_TX_NUM_ROWS    L2_CTXT_TCAM_RX_NUM_ROWS
+#define L2_CTXT_TCAM_TX_MAX_ENTRIES L2_CTXT_TCAM_RX_MAX_ENTRIES
+#define L2_CTXT_TCAM_TX_RESULT_SIZE L2_CTXT_TCAM_RX_RESULT_SIZE
+
+/** Profile TCAM */
+#define PROF_TCAM_RX_MAX_SLICES  1
+#define PROF_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_64B_WORD_ALIGN(94)
+#define PROF_TCAM_RX_NUM_ROWS    256
+#define PROF_TCAM_RX_MAX_ENTRIES (PROF_TCAM_RX_MAX_SLICES * \
+				  PROF_TCAM_RX_NUM_ROWS)
+#define PROF_TCAM_RX_RESULT_SIZE 8
+
+#define PROF_TCAM_TX_MAX_SLICES  PROF_TCAM_RX_MAX_SLICES
+#define PROF_TCAM_TX_ROW_WIDTH   PROF_TCAM_RX_ROW_WIDTH
+#define PROF_TCAM_TX_NUM_ROWS    PROF_TCAM_RX_NUM_ROWS
+#define PROF_TCAM_TX_MAX_ENTRIES PROF_TCAM_RX_MAX_ENTRIES
+#define PROF_TCAM_TX_RESULT_SIZE PROF_TCAM_RX_RESULT_SIZE
+
+/** Wildcard TCAM */
+#define WC_TCAM_RX_MAX_SLICES  4
+/* 162 bits per slice */
+#define WC_TCAM_RX_ROW_WIDTH   (TF_BITS2BYTES_64B_WORD_ALIGN(162) *	\
+				WC_TCAM_RX_MAX_SLICES)
+#define WC_TCAM_RX_NUM_ROWS    2048
+#define WC_TCAM_RX_MAX_ENTRIES (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define WC_TCAM_RX_RESULT_SIZE 8
+
+#define WC_TCAM_TX_MAX_SLICES  WC_TCAM_RX_MAX_SLICES
+#define WC_TCAM_TX_ROW_WIDTH   WC_TCAM_RX_ROW_WIDTH
+#define WC_TCAM_TX_NUM_ROWS    WC_TCAM_RX_NUM_ROWS
+#define WC_TCAM_TX_MAX_ENTRIES WC_TCAM_RX_MAX_ENTRIES
+#define WC_TCAM_TX_RESULT_SIZE WC_TCAM_RX_RESULT_SIZE
+
+/** Source Properties TCAM */
+#define SP_TCAM_RX_MAX_SLICES  1
+#define SP_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_64B_WORD_ALIGN(89)
+#define SP_TCAM_RX_NUM_ROWS    0
+#define SP_TCAM_RX_MAX_ENTRIES (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define SP_TCAM_RX_RESULT_SIZE 8
+
+#define SP_TCAM_TX_MAX_SLICES  SP_TCAM_RX_MAX_SLICES
+#define SP_TCAM_TX_ROW_WIDTH   SP_TCAM_RX_ROW_WIDTH
+#define SP_TCAM_TX_NUM_ROWS    SP_TCAM_RX_NUM_ROWS
+#define SP_TCAM_TX_MAX_ENTRIES SP_TCAM_RX_MAX_ENTRIES
+#define SP_TCAM_TX_RESULT_SIZE SP_TCAM_RX_RESULT_SIZE
+
+/** Connection Tracking Rule TCAM */
+#define CT_RULE_TCAM_RX_MAX_SLICES  1
+#define CT_RULE_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_64B_WORD_ALIGN(16)
+#define CT_RULE_TCAM_RX_NUM_ROWS    0
+#define CT_RULE_TCAM_RX_MAX_ENTRIES (CT_RULE_TCAM_RX_MAX_SLICES * \
+				     CT_RULE_TCAM_RX_NUM_ROWS)
+#define CT_RULE_TCAM_RX_RESULT_SIZE 8
+
+#define CT_RULE_TCAM_TX_MAX_SLICES  CT_RULE_TCAM_RX_MAX_SLICES
+#define CT_RULE_TCAM_TX_ROW_WIDTH   CT_RULE_TCAM_RX_ROW_WIDTH
+#define CT_RULE_TCAM_TX_NUM_ROWS    CT_RULE_TCAM_RX_NUM_ROWS
+#define CT_RULE_TCAM_TX_MAX_ENTRIES CT_RULE_TCAM_RX_MAX_ENTRIES
+#define CT_RULE_TCAM_TX_RESULT_SIZE CT_RULE_TCAM_RX_RESULT_SIZE
+
+/** Virtual Edge Bridge TCAM */
+#define VEB_TCAM_RX_MAX_SLICES  1
+#define VEB_TCAM_RX_ROW_WIDTH   TF_BITS2BYTES_WORD_ALIGN(79)
+/* Tx only */
+#define VEB_TCAM_RX_NUM_ROWS    0
+#define VEB_TCAM_RX_MAX_ENTRIES (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+#define VEB_TCAM_RX_RESULT_SIZE 8
+
+#define VEB_TCAM_TX_MAX_SLICES  VEB_TCAM_RX_MAX_SLICES
+#define VEB_TCAM_TX_ROW_WIDTH   VEB_TCAM_RX_ROW_WIDTH
+#define VEB_TCAM_TX_NUM_ROWS    1024
+#define VEB_TCAM_TX_MAX_ENTRIES (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+#define VEB_TCAM_TX_RESULT_SIZE VEB_TCAM_RX_RESULT_SIZE
+
+/* Declare the table rows for each table here.  If new tables are added to the
+ * enum tf_tcam_tbl_type, then new declarations will be needed here.
+ *
+ * The numeric suffix of the structure type indicates how many slices a
+ * particular TCAM supports.
+ *
+ * Array sizes have 1 added to avoid zero length arrays.
+ */
+
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[TF_TCAM_MAX_SESSIONS][L2_CTXT_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_PROF_TCAM_RX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_PROF_TCAM_TX[TF_TCAM_MAX_SESSIONS][PROF_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_RX[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_TX[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_SP_TCAM_RX[TF_TCAM_MAX_SESSIONS][SP_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_SP_TCAM_TX[TF_TCAM_MAX_SESSIONS][SP_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[TF_TCAM_MAX_SESSIONS][CT_RULE_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_VEB_TCAM_RX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_1
+	cfa_tcam_mgr_table_rows_VEB_TCAM_TX[TF_TCAM_MAX_SESSIONS][VEB_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_RX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+static struct cfa_tcam_mgr_table_rows_4
+	cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[TF_TCAM_MAX_SESSIONS][WC_TCAM_TX_NUM_ROWS + 1];
+
+struct cfa_tcam_mgr_table_data
+cfa_tcam_mgr_tables_p58[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX] = {
+	{				/* RX */
+		{			/* High AFM */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = 0,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* High APPS */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = (L2_CTXT_TCAM_RX_NUM_ROWS / 2) - 1,
+			.max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* Low AFM */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = 0,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+		},
+		{			/* Low APPS */
+			.max_slices  = L2_CTXT_TCAM_RX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_RX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_RX_NUM_ROWS,
+			.start_row   = (L2_CTXT_TCAM_RX_NUM_ROWS / 2),
+			.end_row     = L2_CTXT_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = (L2_CTXT_TCAM_RX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+		},
+		{			/* AFM */
+			.max_slices  = PROF_TCAM_RX_MAX_SLICES,
+			.row_width   = PROF_TCAM_RX_ROW_WIDTH,
+			.num_rows    = 0,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = PROF_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = PROF_TCAM_RX_MAX_SLICES,
+			.row_width   = PROF_TCAM_RX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = PROF_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = PROF_TCAM_RX_MAX_ENTRIES,
+			.result_size = PROF_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_RX_MAX_ENTRIES,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = SP_TCAM_RX_MAX_SLICES,
+			.row_width   = SP_TCAM_RX_ROW_WIDTH,
+			.num_rows    = 0,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = SP_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = SP_TCAM_RX_MAX_SLICES,
+			.row_width   = SP_TCAM_RX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = SP_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = SP_TCAM_RX_MAX_ENTRIES,
+			.result_size = SP_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = CT_RULE_TCAM_RX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_RX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = CT_RULE_TCAM_RX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_RX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+#if CT_RULE_TCAM_RX_NUM_ROWS > 0
+			.end_row     = CT_RULE_TCAM_RX_NUM_ROWS - 1,
+#else
+			.end_row     = CT_RULE_TCAM_RX_NUM_ROWS,
+#endif
+			.max_entries = CT_RULE_TCAM_RX_MAX_ENTRIES,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = VEB_TCAM_RX_MAX_SLICES,
+			.row_width   = VEB_TCAM_RX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = VEB_TCAM_RX_MAX_SLICES,
+			.row_width   = VEB_TCAM_RX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+#if VEB_TCAM_RX_NUM_ROWS > 0
+			.end_row     = VEB_TCAM_RX_NUM_ROWS - 1,
+#else
+			.end_row     = VEB_TCAM_RX_NUM_ROWS,
+#endif
+			.max_entries = VEB_TCAM_RX_MAX_ENTRIES,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_RX_MAX_ENTRIES,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_RX_MAX_SLICES,
+			.row_width   = WC_TCAM_RX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_RX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_RX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_RX_MAX_ENTRIES,
+			.result_size = WC_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+	},
+	{				/* TX */
+		{			/* AFM */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* APPS */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = (L2_CTXT_TCAM_TX_NUM_ROWS / 2) - 1,
+			.max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH,
+		},
+		{			/* AFM */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+		},
+		{			/* APPS */
+			.max_slices  = L2_CTXT_TCAM_TX_MAX_SLICES,
+			.row_width   = L2_CTXT_TCAM_TX_ROW_WIDTH,
+			.num_rows    = L2_CTXT_TCAM_TX_NUM_ROWS,
+			.start_row   = (L2_CTXT_TCAM_TX_NUM_ROWS / 2),
+			.end_row     = L2_CTXT_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = (L2_CTXT_TCAM_TX_MAX_ENTRIES / 2),
+			.result_size = L2_CTXT_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW,
+		},
+		{			/* AFM */
+			.max_slices  = PROF_TCAM_TX_MAX_SLICES,
+			.row_width   = PROF_TCAM_TX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = PROF_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = PROF_TCAM_TX_MAX_SLICES,
+			.row_width   = PROF_TCAM_TX_ROW_WIDTH,
+			.num_rows    = PROF_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = PROF_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = PROF_TCAM_TX_MAX_ENTRIES,
+			.result_size = PROF_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_PROF_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_TX_MAX_ENTRIES,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = SP_TCAM_TX_MAX_SLICES,
+			.row_width   = SP_TCAM_TX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = SP_TCAM_TX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = SP_TCAM_TX_MAX_SLICES,
+			.row_width   = SP_TCAM_TX_ROW_WIDTH,
+			.num_rows    = SP_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = SP_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = SP_TCAM_TX_MAX_ENTRIES,
+			.result_size = SP_TCAM_TX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = CT_RULE_TCAM_TX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_TX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* APPS */
+			.max_slices  = CT_RULE_TCAM_TX_MAX_SLICES,
+			.row_width   = CT_RULE_TCAM_TX_ROW_WIDTH,
+			.num_rows    = CT_RULE_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+#if CT_RULE_TCAM_TX_NUM_ROWS > 0
+			.end_row     = CT_RULE_TCAM_TX_NUM_ROWS - 1,
+#else
+			.end_row     = CT_RULE_TCAM_TX_NUM_ROWS,
+#endif
+			.max_entries = CT_RULE_TCAM_TX_MAX_ENTRIES,
+			.result_size = CT_RULE_TCAM_RX_RESULT_SIZE,
+		},
+		{			/* AFM */
+			.max_slices  = VEB_TCAM_TX_MAX_SLICES,
+			.row_width   = VEB_TCAM_TX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = VEB_TCAM_TX_MAX_SLICES,
+			.row_width   = VEB_TCAM_TX_ROW_WIDTH,
+			.num_rows    = VEB_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = VEB_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = VEB_TCAM_TX_MAX_ENTRIES,
+			.result_size = VEB_TCAM_RX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_VEB_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_TX_MAX_ENTRIES,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* AFM */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = 0,
+			.max_entries = 0,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+		{			/* APPS */
+			.max_slices  = WC_TCAM_TX_MAX_SLICES,
+			.row_width   = WC_TCAM_TX_ROW_WIDTH,
+			.num_rows    = WC_TCAM_TX_NUM_ROWS,
+			.start_row   = 0,
+			.end_row     = WC_TCAM_TX_NUM_ROWS - 1,
+			.max_entries = WC_TCAM_TX_MAX_ENTRIES,
+			.result_size = WC_TCAM_TX_RESULT_SIZE,
+			.hcapi_type  = CFA_RESOURCE_TYPE_P58_WC_TCAM,
+		},
+	},
+};
+
+static struct cfa_tcam_mgr_entry_data entry_data_p58[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+static struct sbmp session_bmp_p58[TF_TCAM_MAX_SESSIONS][TF_TCAM_MAX_ENTRIES];
+
+int
+cfa_tcam_mgr_sess_table_get_p58(int sess_idx, struct sbmp **session_bmp)
+{
+	*session_bmp = session_bmp_p58[sess_idx];
+	return 0;
+}
+
+int
+cfa_tcam_mgr_init_p58(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data)
+{
+	int max_row_width = 0;
+	int max_result_size = 0;
+	int dir, type;
+
+	*global_entry_data = entry_data_p58[sess_idx];
+
+	memcpy(&cfa_tcam_mgr_tables[sess_idx],
+	       &cfa_tcam_mgr_tables_p58,
+	       sizeof(cfa_tcam_mgr_tables[sess_idx]));
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_L2_CTXT_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_PROF_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_SP_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_CT_RULE_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_RX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_VEB_TCAM_TX[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_HIGH[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_HIGH[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_RX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_RX_LOW[sess_idx];
+
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_AFM].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+	cfa_tcam_mgr_tables[sess_idx][TF_DIR_TX]
+		[CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS].tcam_rows =
+		(struct cfa_tcam_mgr_table_rows_0 *)
+		&cfa_tcam_mgr_table_rows_WC_TCAM_TX_LOW[sess_idx];
+
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		for (type = 0; type < CFA_TCAM_MGR_TBL_TYPE_MAX; type++) {
+			if (cfa_tcam_mgr_tables[sess_idx][dir][type].row_width >
+			    max_row_width)
+				max_row_width =
+				       cfa_tcam_mgr_tables[sess_idx][dir][type].row_width;
+			if (cfa_tcam_mgr_tables[sess_idx][dir][type].result_size >
+			    max_result_size)
+				max_result_size =
+				     cfa_tcam_mgr_tables[sess_idx][dir][type].result_size;
+		}
+	}
+
+	if (max_row_width != MAX_ROW_WIDTH) {
+		CFA_TCAM_MGR_LOG(ERR,
+				 "MAX_ROW_WIDTH (%d) does not match actual "
+				 "value (%d).\n",
+				 MAX_ROW_WIDTH,
+				 max_row_width);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+	if (max_result_size != MAX_RESULT_SIZE) {
+		CFA_TCAM_MGR_LOG(ERR,
+				 "MAX_RESULT_SIZE (%d) does not match actual "
+				 "value (%d).\n",
+				 MAX_RESULT_SIZE,
+				 max_result_size);
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+	return 0;
+}
+
+/* HW OP declarations begin here */
+
+struct cfa_tcam_mgr_TCAM_row_data {
+	int key_size;
+	int result_size;
+	uint8_t key[MAX_ROW_WIDTH];
+	uint8_t mask[MAX_ROW_WIDTH];
+	uint8_t result[MAX_RESULT_SIZE];
+};
+
+/* These macros are only needed to avoid exceeding 80 columns */
+#define L2_CTXT_RX_MAX_ROWS \
+	(L2_CTXT_TCAM_RX_MAX_SLICES * L2_CTXT_TCAM_RX_NUM_ROWS)
+#define PROF_RX_MAX_ROWS    (PROF_TCAM_RX_MAX_SLICES * PROF_TCAM_RX_NUM_ROWS)
+#define WC_RX_MAX_ROWS	    (WC_TCAM_RX_MAX_SLICES * WC_TCAM_RX_NUM_ROWS)
+#define SP_RX_MAX_ROWS	    (SP_TCAM_RX_MAX_SLICES * SP_TCAM_RX_NUM_ROWS)
+#define CT_RULE_RX_MAX_ROWS \
+	(CT_RULE_TCAM_RX_MAX_SLICES * CT_RULE_TCAM_RX_NUM_ROWS)
+#define VEB_RX_MAX_ROWS	    (VEB_TCAM_RX_MAX_SLICES * VEB_TCAM_RX_NUM_ROWS)
+
+#define L2_CTXT_TX_MAX_ROWS \
+	(L2_CTXT_TCAM_TX_MAX_SLICES * L2_CTXT_TCAM_TX_NUM_ROWS)
+#define PROF_TX_MAX_ROWS    (PROF_TCAM_TX_MAX_SLICES * PROF_TCAM_TX_NUM_ROWS)
+#define WC_TX_MAX_ROWS	    (WC_TCAM_TX_MAX_SLICES * WC_TCAM_TX_NUM_ROWS)
+#define SP_TX_MAX_ROWS	    (SP_TCAM_TX_MAX_SLICES * SP_TCAM_TX_NUM_ROWS)
+#define CT_RULE_TX_MAX_ROWS \
+	(CT_RULE_TCAM_TX_MAX_SLICES * CT_RULE_TCAM_TX_NUM_ROWS)
+#define VEB_TX_MAX_ROWS	    (VEB_TCAM_TX_MAX_SLICES * VEB_TCAM_TX_NUM_ROWS)
+
+static int cfa_tcam_mgr_max_rows[TF_TCAM_TBL_TYPE_MAX] = {
+	L2_CTXT_RX_MAX_ROWS,
+	L2_CTXT_RX_MAX_ROWS,
+	PROF_RX_MAX_ROWS,
+	WC_RX_MAX_ROWS,
+	SP_RX_MAX_ROWS,
+	CT_RULE_RX_MAX_ROWS,
+	VEB_RX_MAX_ROWS,
+	WC_RX_MAX_ROWS,
+	WC_RX_MAX_ROWS
+};
+
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_PROF_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][PROF_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_SP_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][SP_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_VEB_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][VEB_RX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_RX_row_data[TF_TCAM_MAX_SESSIONS][WC_RX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][L2_CTXT_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_PROF_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][PROF_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_SP_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][SP_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][CT_RULE_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_VEB_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][VEB_TX_MAX_ROWS];
+static struct cfa_tcam_mgr_TCAM_row_data
+	cfa_tcam_mgr_WC_TCAM_TX_row_data[TF_TCAM_MAX_SESSIONS][WC_TX_MAX_ROWS];
+
+static struct cfa_tcam_mgr_TCAM_row_data *
+row_tables[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX] = {
+	{
+		cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_L2_CTXT_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_PROF_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_SP_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_CT_RULE_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_VEB_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_RX_row_data[0],
+	},
+	{
+		cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_L2_CTXT_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_PROF_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_SP_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_CT_RULE_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_VEB_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+		cfa_tcam_mgr_WC_TCAM_TX_row_data[0],
+	}
+};
+
+static int cfa_tcam_mgr_get_max_rows(enum tf_tcam_tbl_type type)
+{
+	if (type >= TF_TCAM_TBL_TYPE_MAX)
+		assert(0);
+	else
+		return cfa_tcam_mgr_max_rows[type];
+}
+
+static int cfa_tcam_mgr_hwop_set(int sess_idx,
+				 struct cfa_tcam_mgr_set_parms *parms, int row,
+				 int slice, int max_slices)
+{
+	struct cfa_tcam_mgr_TCAM_row_data *this_table;
+	struct cfa_tcam_mgr_TCAM_row_data *this_row;
+	this_table = row_tables[parms->dir]
+		[cfa_tcam_mgr_get_phys_table_type(parms->type)];
+	this_table += (sess_idx *
+		       cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+	this_row   = &this_table[row * max_slices + slice];
+	this_row->key_size = parms->key_size;
+	memcpy(&this_row->key, parms->key, parms->key_size);
+	memcpy(&this_row->mask, parms->mask, parms->key_size);
+	this_row->result_size = parms->result_size;
+	if (parms->result != ((void *)0))
+		memcpy(&this_row->result, parms->result, parms->result_size);
+	return 0;
+};
+
+static int cfa_tcam_mgr_hwop_get(int sess_idx,
+				 struct cfa_tcam_mgr_get_parms *parms, int row,
+				 int slice, int max_slices)
+{
+	struct cfa_tcam_mgr_TCAM_row_data *this_table;
+	struct cfa_tcam_mgr_TCAM_row_data *this_row;
+	this_table = row_tables[parms->dir]
+		[cfa_tcam_mgr_get_phys_table_type(parms->type)];
+	this_table += (sess_idx *
+		       cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+	this_row   = &this_table[row * max_slices + slice];
+	parms->key_size = this_row->key_size;
+	parms->result_size = this_row->result_size;
+	if (parms->key != ((void *)0))
+		memcpy(parms->key, &this_row->key, parms->key_size);
+	if (parms->mask != ((void *)0))
+		memcpy(parms->mask, &this_row->mask, parms->key_size);
+	if (parms->result != ((void *)0))
+		memcpy(parms->result, &this_row->result, parms->result_size);
+	return 0;
+};
+
+static int cfa_tcam_mgr_hwop_free(int sess_idx,
+				  struct cfa_tcam_mgr_free_parms *parms,
+				  int row, int slice, int max_slices)
+{
+	struct cfa_tcam_mgr_TCAM_row_data *this_table;
+	struct cfa_tcam_mgr_TCAM_row_data *this_row;
+	this_table = row_tables[parms->dir]
+		[cfa_tcam_mgr_get_phys_table_type(parms->type)];
+	this_table += (sess_idx *
+		       cfa_tcam_mgr_get_max_rows(cfa_tcam_mgr_get_phys_table_type(parms->type)));
+	this_row   = &this_table[row * max_slices + slice];
+	memset(&this_row->key, 0, sizeof(this_row->key));
+	memset(&this_row->mask, 0, sizeof(this_row->mask));
+	memset(&this_row->result, 0, sizeof(this_row->result));
+	this_row->key_size = 0;
+	this_row->result_size = 0;
+	return 0;
+};
+
+int cfa_tcam_mgr_hwops_get_funcs_p58(struct cfa_tcam_mgr_hwops_funcs
+				     *hwop_funcs)
+{
+	hwop_funcs->set	 = cfa_tcam_mgr_hwop_set;
+	hwop_funcs->get	 = cfa_tcam_mgr_hwop_get;
+	hwop_funcs->free = cfa_tcam_mgr_hwop_free;
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h
new file mode 100644
index 0000000000..7640f91911
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_p58.h
@@ -0,0 +1,20 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_P58_H
+#define CFA_TCAM_MGR_P58_H
+
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_sbmp.h"
+
+int
+cfa_tcam_mgr_init_p58(int sess_idx, struct cfa_tcam_mgr_entry_data **global_entry_data);
+
+int
+cfa_tcam_mgr_sess_table_get_p58(int sess_idx, struct sbmp **session_bmp);
+
+int
+cfa_tcam_mgr_hwops_get_funcs_p58(struct cfa_tcam_mgr_hwops_funcs *hwop_funcs);
+#endif /* CFA_TCAM_MGR_P58_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h
new file mode 100644
index 0000000000..6ad158abe8
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_sbmp.h
@@ -0,0 +1,126 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_SBMP_H
+#define CFA_TCAM_MGR_SBMP_H
+
+#include <inttypes.h>
+
+#include "cfa_tcam_mgr.h"
+
+#define SBMP_SESSION_MAX TF_TCAM_MAX_SESSIONS
+#if SBMP_SESSION_MAX <= 16
+#define SBMP_WORD_WIDTH  16
+#else
+#define SBMP_WORD_WIDTH  32
+#endif
+
+#define SBMP_WIDTH       (((SBMP_SESSION_MAX + SBMP_WORD_WIDTH - 1) / \
+			   SBMP_WORD_WIDTH) * SBMP_WORD_WIDTH)
+#define	SBMP_WORD_MAX    ((SBMP_WIDTH + SBMP_WORD_WIDTH - 1) / SBMP_WORD_WIDTH)
+
+struct sbmp {
+#if SBMP_WORD_WIDTH == 16
+	uint16_t bits[SBMP_WORD_MAX];
+#elif SBMP_WORD_WIDTH == 32
+	uint32_t bits[SBMP_WORD_MAX];
+#else
+	uint64_t bits[SBMP_WORD_MAX];
+#endif
+};
+
+#define	SBMP_WORD_GET(bm, word)		((bm).bits[(word)])
+
+#if SBMP_WORD_MAX == 1
+#define	SBMP_WENT(session)		(0)
+#define	SBMP_WBIT(session)		(1U << (session))
+#define SBMP_CLEAR(bm)                  (SBMP_WORD_GET(bm, 0) = 0)
+#define SBMP_IS_NULL(bm)		(SBMP_WORD_GET(bm, 0) == 0)
+#define	SBMP_COUNT(bm, count)	\
+	(count = __builtin_popcount(SBMP_WORD_GET(bm, 0)))
+#elif SBMP_WORD_MAX == 2
+#define	SBMP_WENT(session)		((session) / SBMP_WORD_WIDTH)
+#define	SBMP_WBIT(session)		(1U << ((session) % SBMP_WORD_WIDTH))
+#define SBMP_CLEAR(bm)							\
+	do {								\
+		typeof(bm) *_bm = &(bm);				\
+		SBMP_WORD_GET(*_bm, 0) = SBMP_WORD_GET(*_bm, 1) = 0;	\
+	} while (0)
+#define SBMP_IS_NULL(bm)		\
+	(SBMP_WORD_GET(bm, 0) == 0 && SBMP_WORD_GET(bm, 1) == 0)
+#define	SBMP_COUNT(bm, count)						\
+	do {								\
+		typeof(bm) *_bm = &(bm);				\
+		count = __builtin_popcount(SBMP_WORD_GET(*_bm, 0)) +	\
+			__builtin_popcount(SBMP_WORD_GET(*_bm, 1)));	\
+	} while (0)
+#elif SBMP_WORD_MAX == 3
+#define	SBMP_WENT(session)		((session) / SBMP_WORD_WIDTH)
+#define	SBMP_WBIT(session)		(1U << ((session) % SBMP_WORD_WIDTH))
+#define SBMP_CLEAR(bm)							\
+	do {								\
+		typeof(bm) *_bm = &(bm);				\
+		SBMP_WORD_GET(*_bm, 0) = SBMP_WORD_GET(*_bm, 1) =	\
+			SBMP_WORD_GET(*_bm, 2) = 0;			\
+	} while (0)
+#define SBMP_IS_NULL(bm)		\
+	(SBMP_WORD_GET(bm, 0) == 0 && SBMP_WORD_GET(bm, 1) == 0 && \
+	 SBMP_WORD_GET(bm, 2) == 0)
+#define	SBMP_COUNT(bm, count)						\
+	do {								\
+		typeof(bm) *_bm = &(bm);				\
+		count = __builtin_popcount(SBMP_WORD_GET(*_bm, 0)) +	\
+			__builtin_popcount(SBMP_WORD_GET(*_bm, 1)) +	\
+			__builtin_popcount(SBMP_WORD_GET(*_bm, 2));	\
+	} while (0)
+#else  /* SBMP_WORD_MAX > 3 */
+#define	SBMP_WENT(session)		((session) / SBMP_WORD_WIDTH)
+#define	SBMP_WBIT(session)		(1U << ((session) % SBMP_WORD_WIDTH))
+#define SBMP_CLEAR(bm)							\
+	do {								\
+		typeof(bm) *_bm = &(bm);				\
+		int	_w;						\
+		for (_w = 0; _w < SBMP_WORD_MAX; _w++) {		\
+			SBMP_WORD_GET(*_bm, _w) = 0;			\
+		}							\
+	} while (0)
+#define SBMP_IS_NULL(bm)		(sbmp_bmnull(&(bm)))
+#define	SBMP_COUNT(bm, count)						\
+	do {								\
+		typeof(bm) *_bm = &(bm);				\
+		int	_count, _w;					\
+		_count = 0;						\
+		for (_w = 0; _w < SBMP_WORD_MAX; _w++) {		\
+			_count += __builtin_popcount(SBMP_WORD_GET(*_bm, _w)); \
+		}							\
+		count = _count;						\
+	} while (0)
+
+/* Only needed if SBMP_WORD_MAX > 3 */
+static int
+sbmp_bmnull(struct ebmp *bmp)
+{
+	int	i;
+
+	for (i = 0; i < SBMP_WORD_MAX; i++) {
+		if (SBMP_WORD_GET(*bmp, i) != 0)
+			return 0;
+	}
+	return 1;
+}
+#endif
+
+/* generics that use the previously defined helpers */
+#define SBMP_NOT_NULL(bm)		(!SBMP_IS_NULL(bm))
+
+#define	SBMP_ENTRY(bm, session)	\
+	(SBMP_WORD_GET(bm, SBMP_WENT(session)))
+#define SBMP_MEMBER(bm, session)	\
+	((SBMP_ENTRY(bm, session) & SBMP_WBIT(session)) != 0)
+#define SBMP_SESSION_ADD(bm, session)	\
+	(SBMP_ENTRY(bm, session) |= SBMP_WBIT(session))
+#define SBMP_SESSION_REMOVE(bm, session)	\
+	(SBMP_ENTRY(bm, session) &= ~SBMP_WBIT(session))
+#endif  /* CFA_TCAM_MGR_SBMP_H */
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c
new file mode 100644
index 0000000000..3d085bc69e
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.c
@@ -0,0 +1,377 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include "hcapi_cfa_defs.h"
+#include "tf_util.h"
+#include "cfa_tcam_mgr.h"
+#include "cfa_tcam_mgr_device.h"
+#include "cfa_tcam_mgr_session.h"
+#include "cfa_tcam_mgr_sbmp.h"
+#include "tfp.h"
+#include "cfa_tcam_mgr_p58.h"
+#include "cfa_tcam_mgr_p4.h"
+
+struct cfa_tcam_mgr_session_data {
+	uint32_t session_id;
+	/* The following are per-session values */
+	uint16_t max_entries[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+	uint16_t used_entries[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+};
+
+static struct cfa_tcam_mgr_session_data session_data[TF_TCAM_MAX_SESSIONS];
+
+static uint16_t last_entry_id;
+
+static struct sbmp *session_bmp[TF_TCAM_MAX_SESSIONS];
+
+int
+cfa_tcam_mgr_session_init(int sess_idx, enum cfa_tcam_mgr_device_type type)
+{
+	int rc;
+
+	switch (type) {
+	case CFA_TCAM_MGR_DEVICE_TYPE_P4:
+	case CFA_TCAM_MGR_DEVICE_TYPE_SR:
+		rc = cfa_tcam_mgr_sess_table_get_p4(sess_idx, &session_bmp[sess_idx]);
+		break;
+	case CFA_TCAM_MGR_DEVICE_TYPE_P5:
+		rc = cfa_tcam_mgr_sess_table_get_p58(sess_idx, &session_bmp[sess_idx]);
+		break;
+	default:
+		CFA_TCAM_MGR_LOG(ERR, "No such device %d\n", type);
+		rc = -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+
+	return rc;
+}
+
+int
+cfa_tcam_mgr_get_session_from_context(struct cfa_tcam_mgr_context *context,
+				      uint32_t *session_id)
+{
+	if (context == NULL) {
+		CFA_TCAM_MGR_LOG_0(ERR, "context passed as NULL pointer.\n");
+		return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+	}
+
+	*session_id = context->tfp->session->session_id.id;
+	return 0;
+}
+
+int
+cfa_tcam_mgr_session_find(unsigned int session_id)
+{
+	unsigned int sess_idx;
+
+	for (sess_idx = 0; sess_idx < ARRAY_SIZE(session_data); sess_idx++) {
+		if (session_data[sess_idx].session_id == session_id)
+			return sess_idx;
+	}
+
+	return -CFA_TCAM_MGR_ERR_CODE(INVAL);
+}
+
+int
+cfa_tcam_mgr_session_add(unsigned int session_id)
+{
+	int sess_idx;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx >= 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Session is already bound.\n");
+		return -CFA_TCAM_MGR_ERR_CODE(BUSY);
+	}
+
+	/* Session not found in table, find first empty entry. */
+	for (sess_idx = 0;
+	     sess_idx < (signed int)ARRAY_SIZE(session_data);
+	     sess_idx++) {
+		if (session_data[sess_idx].session_id == 0)
+			break;
+	}
+
+	if (sess_idx >= (signed int)ARRAY_SIZE(session_data)) {
+		/* No room in the session table */
+		CFA_TCAM_MGR_LOG_0(ERR, "Session table is full.\n");
+		return -CFA_TCAM_MGR_ERR_CODE(NOMEM);
+	}
+
+	session_data[sess_idx].session_id = session_id;
+
+	return sess_idx;
+}
+
+int
+cfa_tcam_mgr_session_free(unsigned int session_id,
+		struct cfa_tcam_mgr_context *context)
+{
+	struct cfa_tcam_mgr_free_parms free_parms;
+	int entry_id;
+	int sess_idx = cfa_tcam_mgr_session_find(session_id);
+
+	if (sess_idx < 0)
+		return sess_idx;
+
+	memset(&free_parms, 0, sizeof(free_parms));
+	/* Since we are freeing all pending TCAM entries (which is typically
+	 * done during tcam_unbind), we don't know the type of each entry.
+	 * So we set the type to MAX as a hint to cfa_tcam_mgr_free() to
+	 * figure out the actual type. We need to set it through each
+	 * iteration in the loop below; otherwise, the type determined for
+	 * the first entry would be used for subsequent entries that may or
+	 * may not be of the same type, resulting in errors.
+	 */
+	for (entry_id = 0; entry_id < cfa_tcam_mgr_max_entries[sess_idx]; entry_id++) {
+		if (SBMP_MEMBER(session_bmp[sess_idx][entry_id], sess_idx)) {
+			SBMP_SESSION_REMOVE(session_bmp[sess_idx][entry_id], sess_idx);
+
+			free_parms.id = entry_id;
+			free_parms.type = CFA_TCAM_MGR_TBL_TYPE_MAX;
+			cfa_tcam_mgr_free(context, &free_parms);
+		}
+	}
+
+	memset(&session_data[sess_idx], 0, sizeof(session_data[sess_idx]));
+	return 0;
+}
+
+int
+cfa_tcam_mgr_session_cfg(unsigned int session_id,
+			 uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX])
+{
+	struct cfa_tcam_mgr_table_data *table_data;
+	struct cfa_tcam_mgr_session_data *session_entry;
+	unsigned int dir, type;
+	int sess_idx = cfa_tcam_mgr_session_find(session_id);
+	uint16_t requested_cnt;
+
+	if (sess_idx < 0)
+		return sess_idx;
+
+	session_entry = &session_data[sess_idx];
+
+	/* Validate session request */
+	for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
+		for (type = 0;
+		     type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
+		     type++) {
+			table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
+			requested_cnt = tcam_cnt[dir][type];
+			/*
+			 * Only check if table supported (max_entries > 0).
+			 */
+			if (table_data->max_entries > 0 &&
+			    requested_cnt > table_data->max_entries) {
+				CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
+						"Requested %d, available %d.\n",
+						requested_cnt,
+						table_data->max_entries);
+				return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+			}
+		}
+	}
+
+	memcpy(session_entry->max_entries, tcam_cnt,
+	       sizeof(session_entry->max_entries));
+	return 0;
+}
+
+void
+cfa_tcam_mgr_mv_session_used_entries_cnt(int sess_idx, enum tf_dir dir,
+					 enum cfa_tcam_mgr_tbl_type dst_type,
+					 enum cfa_tcam_mgr_tbl_type src_type)
+{
+	session_data[sess_idx].used_entries[dir][dst_type]++;
+	session_data[sess_idx].used_entries[dir][src_type]--;
+}
+
+int
+cfa_tcam_mgr_session_entry_alloc(unsigned int session_id,
+				 enum tf_dir dir,
+				 enum cfa_tcam_mgr_tbl_type type)
+{
+	int sess_idx;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+		return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+
+	if (session_data[sess_idx].used_entries[dir][type] >=
+	    session_data[sess_idx].max_entries[dir][type]) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Table full (session).\n");
+		return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
+	}
+
+	do {
+		last_entry_id++;
+		if (cfa_tcam_mgr_max_entries[sess_idx] <= last_entry_id)
+			last_entry_id = 0;
+	} while (!SBMP_IS_NULL(session_bmp[sess_idx][last_entry_id]));
+
+	SBMP_SESSION_ADD(session_bmp[sess_idx][last_entry_id], sess_idx);
+
+	session_data[sess_idx].used_entries[dir][type] += 1;
+
+	return last_entry_id;
+}
+
+int
+cfa_tcam_mgr_session_entry_free(unsigned int session_id,
+				unsigned int entry_id,
+				enum tf_dir dir,
+				enum cfa_tcam_mgr_tbl_type type)
+{
+	int sess_idx;
+
+	sess_idx = cfa_tcam_mgr_session_find(session_id);
+	if (sess_idx < 0) {
+		CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
+		return -CFA_TCAM_MGR_ERR_CODE(NODEV);
+	}
+
+	SBMP_SESSION_REMOVE(session_bmp[sess_idx][entry_id], sess_idx);
+	session_data[sess_idx].used_entries[dir][type] -= 1;
+
+	return 0;
+}
+
+#if SBMP_WORD_WIDTH == 16
+#define SBMP_FORMAT PRIX16
+#define SBMP_PRECISION "4"
+#elif SBMP_WORD_WIDTH == 32
+#define SBMP_FORMAT PRIX32
+#define SBMP_PRECISION "8"
+#elif SBMP_WORD_WIDTH == 64
+#define SBMP_FORMAT PRIX64
+#define SBMP_PRECISION "16"
+#else
+#error "Invalid value for SBMP_WORD_WIDTH."
+#endif
+
+static void
+cfa_tcam_mgr_session_bitmap_print(struct sbmp *session_bmp)
+{
+	unsigned int i;
+
+	printf("0x");
+	for (i = 0;
+	     i < ARRAY_SIZE(session_bmp->bits);
+	     i++) {
+		printf("%0" SBMP_PRECISION SBMP_FORMAT,
+		       session_bmp->bits[i]);
+	}
+}
+
+#define SESSION_DUMP_HEADER_1 "                             RX          TX\n"
+#define SESSION_DUMP_HEADER_2 \
+	"                         Max   Used  Max   Used\n"
+
+static void
+cfa_tcam_mgr_session_printf(struct cfa_tcam_mgr_session_data *session,
+			    enum cfa_tcam_mgr_tbl_type tbl_type)
+{
+	printf("%-22s: %5u %5u %5u %5u\n",
+	       cfa_tcam_mgr_tbl_2_str(tbl_type),
+	       session->max_entries[TF_DIR_RX][tbl_type],
+	       session->used_entries[TF_DIR_RX][tbl_type],
+	       session->max_entries[TF_DIR_TX][tbl_type],
+	       session->used_entries[TF_DIR_TX][tbl_type]);
+}
+
+void
+cfa_tcam_mgr_sessions_dump(void)
+{
+	struct cfa_tcam_mgr_session_data *session;
+	unsigned int sess_idx;
+	bool sess_found = false;
+	enum cfa_tcam_mgr_tbl_type tbl_type;
+
+	printf("\nTCAM Sessions Table:\n");
+	for (sess_idx = 0; sess_idx < ARRAY_SIZE(session_data); sess_idx++) {
+		if (session_data[sess_idx].session_id != 0) {
+			session = &session_data[sess_idx];
+			if (!sess_found) {
+				printf(SESSION_DUMP_HEADER_1);
+				printf(SESSION_DUMP_HEADER_2);
+			}
+			printf("Session 0x%08x:\n",
+			       session->session_id);
+			for (tbl_type = CFA_TCAM_MGR_TBL_TYPE_START;
+			     tbl_type < CFA_TCAM_MGR_TBL_TYPE_MAX;
+			     tbl_type++) {
+				cfa_tcam_mgr_session_printf(session, tbl_type);
+			}
+			sess_found = true;
+		}
+	}
+
+	if (!sess_found)
+		printf("No sessions found.\n");
+}
+
+/* This dumps all the sessions using an entry */
+void
+cfa_tcam_mgr_entry_sessions_dump(int sess_idx, uint16_t id)
+{
+	bool session_found = false;
+
+	if (id >= cfa_tcam_mgr_max_entries[sess_idx]) {
+		printf("Entry ID %u out of range for sess_idx %d.  Max ID %u.\n",
+		       id, sess_idx, cfa_tcam_mgr_max_entries[sess_idx] - 1);
+		return;
+	}
+
+	if (!SBMP_IS_NULL(session_bmp[sess_idx][id])) {
+		printf("Sessions using entry ID %u:\n", id);
+		for (sess_idx = 0; sess_idx < SBMP_SESSION_MAX; sess_idx++)
+			if (SBMP_MEMBER(session_bmp[sess_idx][id], (sess_idx))) {
+				if (session_data[sess_idx].session_id != 0) {
+					printf("0x%08x (index %d)\n",
+					  session_data[sess_idx].session_id,
+					  sess_idx);
+					session_found = true;
+				} else {
+					printf("Error! Entry ID %u used by "
+					       "session index %d which is not "
+					       "in use.\n",
+					       id, sess_idx);
+				}
+			}
+		if (!session_found)
+			printf("No sessions using entry ID %u.\n", id);
+	} else {
+		printf("Entry ID %u not in use.\n",
+		       id);
+		return;
+	}
+}
+
+/* This dumps all the entries in use by any session */
+void
+cfa_tcam_mgr_session_entries_dump(int sess_idx)
+{
+	bool entry_found = false;
+	uint16_t id;
+
+	printf("\nGlobal Maximum Entries for sess_idx %d: %d\n\n",
+	       sess_idx, cfa_tcam_mgr_max_entries[sess_idx]);
+	printf("TCAM Session Entry Table:\n");
+	for (id = 0; id < cfa_tcam_mgr_max_entries[sess_idx]; id++) {
+		if (!SBMP_IS_NULL(session_bmp[sess_idx][id])) {
+			if (!entry_found)
+				printf("  EID Session bitmap\n");
+			printf("%5u ", id);
+			cfa_tcam_mgr_session_bitmap_print(&session_bmp[sess_idx][id]);
+			printf("\n");
+			entry_found = true;
+		}
+	}
+
+	if (!entry_found)
+		printf("No entries found.\n");
+}
diff --git a/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h
new file mode 100644
index 0000000000..69311b7e1d
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/cfa_tcam_mgr_session.h
@@ -0,0 +1,54 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef CFA_TCAM_MGR_SESSION_H
+#define CFA_TCAM_MGR_SESSION_H
+
+#include <inttypes.h>
+#include "cfa_tcam_mgr.h"
+
+int
+cfa_tcam_mgr_session_init(int sess_idx, enum cfa_tcam_mgr_device_type type);
+
+int
+cfa_tcam_mgr_get_session_from_context(struct cfa_tcam_mgr_context *context,
+				      uint32_t *session_id);
+
+int
+cfa_tcam_mgr_session_find(unsigned int session_id);
+
+int
+cfa_tcam_mgr_session_add(unsigned int session_id);
+
+int
+cfa_tcam_mgr_session_free(unsigned int session_id,
+		struct cfa_tcam_mgr_context *context);
+
+int
+cfa_tcam_mgr_session_cfg(unsigned int session_id,
+			 uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX]);
+
+int
+cfa_tcam_mgr_session_entry_alloc(unsigned int session_id,
+				 enum tf_dir dir,
+				 enum cfa_tcam_mgr_tbl_type type);
+int
+cfa_tcam_mgr_session_entry_free(unsigned int session_id,
+				unsigned int entry_id,
+				enum tf_dir dir,
+				enum cfa_tcam_mgr_tbl_type type);
+
+void
+cfa_tcam_mgr_sessions_dump(void);
+void
+cfa_tcam_mgr_entry_sessions_dump(int sess_idx, uint16_t id);
+void
+cfa_tcam_mgr_session_entries_dump(int sess_idx);
+
+void
+cfa_tcam_mgr_mv_session_used_entries_cnt(int sess_idx, enum tf_dir dir,
+					 enum cfa_tcam_mgr_tbl_type dst_type,
+					 enum cfa_tcam_mgr_tbl_type src_type);
+#endif  /* CFA_TCAM_MGR_SESSION_H */
diff --git a/drivers/net/bnxt/tf_core/meson.build b/drivers/net/bnxt/tf_core/meson.build
index f812e471d1..ae44aa34cf 100644
--- a/drivers/net/bnxt/tf_core/meson.build
+++ b/drivers/net/bnxt/tf_core/meson.build
@@ -1,36 +1,42 @@ 
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
-# Copyright(c) 2021 Broadcom
+# Copyright(c) 2023 Broadcom
 
 #Include the folder for headers
 includes += include_directories('.')
 
 #Add the source files
 sources += files(
-        'tf_core.c',
         'bitalloc.c',
-        'tf_msg.c',
-        'll.c',
+        'cfa_tcam_mgr.c',
+        'cfa_tcam_mgr_hwop_msg.c',
+        'cfa_tcam_mgr_p4.c',
+        'cfa_tcam_mgr_p58.c',
+        'cfa_tcam_mgr_session.c',
         'dpool.c',
+        'll.c',
         'rand.c',
         'stack.c',
-        'tf_rm.c',
-        'tf_tbl.c',
-        'tf_tbl_sram.c',
-        'tf_sram_mgr.c',
+        'tf_core.c',
+        'tf_device.c',
+        'tf_device_p4.c',
+        'tf_device_p58.c',
         'tf_em_common.c',
+        'tf_em_hash_internal.c',
         'tf_em_host.c',
         'tf_em_internal.c',
-        'tf_em_hash_internal.c',
-        'tfp.c',
-        'tf_util.c',
-        'tf_device.c',
-        'tf_device_p4.c',
         'tf_global_cfg.c',
+        'tf_hash.c',
         'tf_identifier.c',
         'tf_if_tbl.c',
+        'tf_msg.c',
+        'tfp.c',
+        'tf_rm.c',
         'tf_session.c',
+        'tf_sram_mgr.c',
+        'tf_tbl.c',
+        'tf_tbl_sram.c',
         'tf_tcam.c',
+        'tf_tcam_mgr_msg.c',
         'tf_tcam_shared.c',
-        'tf_hash.c',
-        'tf_device_p58.c')
+        'tf_util.c')
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 038e439101..3a812bee3a 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -34,8 +34,8 @@  tf_open_session(struct tf *tfp,
 	 * side. It is assumed that the Firmware will be supported if
 	 * firmware open session succeeds.
 	 */
-	if (parms->device_type != TF_DEVICE_TYPE_WH &&
-	    parms->device_type != TF_DEVICE_TYPE_THOR &&
+	if (parms->device_type != TF_DEVICE_TYPE_P4 &&
+	    parms->device_type != TF_DEVICE_TYPE_P5 &&
 	    parms->device_type != TF_DEVICE_TYPE_SR) {
 		TFP_DRV_LOG(ERR,
 			    "Unsupported device type %d\n",
@@ -83,7 +83,7 @@  tf_open_session(struct tf *tfp,
 		return rc;
 
 	TFP_DRV_LOG(INFO,
-		    "domain:%d, bus:%d, device:%u\n",
+		    "domain:%x, bus:%x, device:%u\n",
 		    parms->session_id.internal.domain,
 		    parms->session_id.internal.bus,
 		    parms->session_id.internal.device);
@@ -176,7 +176,7 @@  tf_close_session(struct tf *tfp)
 		return rc;
 
 	TFP_DRV_LOG(INFO,
-		    "domain:%d, bus:%d, device:%d\n",
+		    "domain:%d, bus:%x, device:%d\n",
 		    cparms.session_id->internal.domain,
 		    cparms.session_id->internal.bus,
 		    cparms.session_id->internal.device);
@@ -742,7 +742,6 @@  tf_set_tcam_entry(struct tf *tfp,
 
 	memset(&sparms, 0, sizeof(struct tf_tcam_set_parms));
 
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session(tfp, &tfs);
 	if (rc) {
@@ -790,6 +789,10 @@  tf_set_tcam_entry(struct tf *tfp,
 			    strerror(-rc));
 		return rc;
 	}
+	TFP_DRV_LOG(DEBUG,
+		    "%s: TCAM type %d set idx:%d key size %d result size %d\n",
+		    tf_dir_2_str(parms->dir), sparms.type,
+		    sparms.idx, sparms.key_size, sparms.result_size);
 
 	return 0;
 }
@@ -807,7 +810,6 @@  tf_get_tcam_entry(struct tf *tfp __rte_unused,
 
 	memset(&gparms, 0, sizeof(struct tf_tcam_get_parms));
 
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session(tfp, &tfs);
 	if (rc) {
@@ -1812,8 +1814,8 @@  int tf_get_version(struct tf *tfp,
 	/* This function can be called before open session, filter
 	 * out any non-supported device types on the Core side.
 	 */
-	if (parms->device_type != TF_DEVICE_TYPE_WH &&
-	    parms->device_type != TF_DEVICE_TYPE_THOR &&
+	if (parms->device_type != TF_DEVICE_TYPE_P4 &&
+	    parms->device_type != TF_DEVICE_TYPE_P5 &&
 	    parms->device_type != TF_DEVICE_TYPE_SR) {
 		TFP_DRV_LOG(ERR,
 			    "Unsupported device type %d\n",
@@ -1845,7 +1847,7 @@  int tf_query_sram_resources(struct tf *tfp,
 	/* This function can be called before open session, filter
 	 * out any non-supported device types on the Core side.
 	 */
-	if (parms->device_type != TF_DEVICE_TYPE_THOR) {
+	if (parms->device_type != TF_DEVICE_TYPE_P5) {
 		TFP_DRV_LOG(ERR,
 			    "Unsupported device type %d\n",
 			    parms->device_type);
@@ -1927,7 +1929,7 @@  int tf_set_sram_policy(struct tf *tfp,
 	/* This function can be called before open session, filter
 	 * out any non-supported device types on the Core side.
 	 */
-	if (parms->device_type != TF_DEVICE_TYPE_THOR) {
+	if (parms->device_type != TF_DEVICE_TYPE_P5) {
 		TFP_DRV_LOG(ERR,
 			    "Unsupported device type %d\n",
 			    parms->device_type);
@@ -1968,7 +1970,7 @@  int tf_get_sram_policy(struct tf *tfp,
 	/* This function can be called before open session, filter
 	 * out any non-supported device types on the Core side.
 	 */
-	if (parms->device_type != TF_DEVICE_TYPE_THOR) {
+	if (parms->device_type != TF_DEVICE_TYPE_P5) {
 		TFP_DRV_LOG(ERR,
 			    "Unsupported device type %d\n",
 			    parms->device_type);
@@ -1997,3 +1999,31 @@  int tf_get_sram_policy(struct tf *tfp,
 
 	return rc;
 }
+
+int tf_set_session_hotup_state(struct tf *tfp,
+			       struct tf_set_session_hotup_state_parms *parms)
+{
+	int rc = 0;
+
+	TF_CHECK_PARMS1(tfp);
+
+	rc = tf_session_set_hotup_state(tfp, parms);
+	if (rc)
+		return rc;
+
+	return rc;
+}
+
+int tf_get_session_hotup_state(struct tf *tfp,
+			       struct tf_get_session_hotup_state_parms *parms)
+{
+	int rc = 0;
+
+	TF_CHECK_PARMS1(tfp);
+
+	rc = tf_session_get_hotup_state(tfp, parms);
+	if (rc)
+		return rc;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index f5fe0a9098..3da1d2a5ca 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -112,6 +112,10 @@  enum tf_sram_bank_id {
  * @ref tf_attach_session
  *
  * @ref tf_close_session
+ *
+ * @ref tf_get_session_info
+ *
+ * @ref tf_get_session_info
  */
 
 /**
@@ -188,10 +192,10 @@  struct tf_session_version {
  * Session supported device types
  */
 enum tf_device_type {
-	TF_DEVICE_TYPE_WH = 0, /**< Whitney+  */
-	TF_DEVICE_TYPE_SR,     /**< Stingray  */
-	TF_DEVICE_TYPE_THOR,   /**< Thor      */
-	TF_DEVICE_TYPE_MAX     /**< Maximum   */
+	TF_DEVICE_TYPE_P4 = 0,
+	TF_DEVICE_TYPE_SR,
+	TF_DEVICE_TYPE_P5,
+	TF_DEVICE_TYPE_MAX
 };
 
 /**
@@ -286,6 +290,8 @@  enum tf_tbl_type {
 	TF_TBL_TYPE_ACT_ENCAP_32B,
 	/** Wh+/SR/TH Action Encap 64 Bytes */
 	TF_TBL_TYPE_ACT_ENCAP_64B,
+	/* TH Action Encap 128 Bytes */
+	TF_TBL_TYPE_ACT_ENCAP_128B,
 	/** WH+/SR/TH Action Source Properties SMAC */
 	TF_TBL_TYPE_ACT_SP_SMAC,
 	/** Wh+/SR/TH Action Source Properties SMAC IPv4 */
@@ -331,7 +337,7 @@  enum tf_tbl_type {
 	 * External table type - initially 1 poolsize entries.
 	 * All External table types are associated with a table
 	 * scope. Internal types are not.  Currently this is
-	 * a pool of 64B entries.
+	 * a pool of 128B entries.
 	 */
 	TF_TBL_TYPE_EXT,
 	TF_TBL_TYPE_MAX
@@ -914,6 +920,71 @@  int tf_attach_session(struct tf *tfp,
  */
 int tf_close_session(struct tf *tfp);
 
+/**
+ * tf_set_session_hotup_state parameter definition.
+ */
+struct tf_set_session_hotup_state_parms {
+	/**
+	 * [in] the structure is used to set the state of
+	 * the hotup shared session.
+	 *
+	 */
+	uint16_t state;
+};
+
+/**
+ * set hot upgrade shared session state
+ *
+ * This API is used to set the state of the shared session.
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] parms
+ *   Pointer to set hotup state parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_set_session_hotup_state(struct tf *tfp,
+			       struct tf_set_session_hotup_state_parms *parms);
+
+/**
+ * tf_get_session_hotup_state parameter definition.
+ */
+struct tf_get_session_hotup_state_parms {
+	/**
+	 * [out] the structure is used to get the state of
+	 * the hotup shared session.
+	 *
+	 */
+	uint16_t state;
+	/**
+	 * [out] get the ref_cnt of the hotup shared session.
+	 *
+	 */
+	uint16_t ref_cnt;
+};
+
+/**
+ * get hot upgrade shared session state
+ *
+ * This API is used to set the state of the shared session.
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] parms
+ *   Pointer to get hotup state parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_get_session_hotup_state(struct tf *tfp,
+			       struct tf_get_session_hotup_state_parms *parms);
+
 /**
  * @page  ident Identity Management
  *
@@ -1192,8 +1263,6 @@  int tf_free_tbl_scope(struct tf *tfp,
  *
  * @ref tf_get_tcam_entry
  *
- * @ref tf_free_tcam_entry
- *
  * @ref tf_move_tcam_shared_entries
  *
  * @ref tf_clear_tcam_shared_entries
@@ -1258,7 +1327,7 @@  struct tf_search_tcam_entry_parms {
 };
 
 /**
- * search TCAM entry (experimental)
+ * search TCAM entry
  *
  * Search for a TCAM entry
  *
@@ -1732,7 +1801,7 @@  struct tf_get_shared_tbl_increment_parms {
  * tf_get_shared_tbl_increment
  *
  * This API is currently only required for use in the shared
- * session for Thor (p58) actions.  An increment count is returned per
+ * session for P5 actions.  An increment count is returned per
  * type to indicate how much to increment the start by for each
  * entry (see tf_resource_info)
  *
@@ -1898,6 +1967,7 @@  struct tf_insert_em_entry_parms {
 	 */
 	uint64_t flow_id;
 };
+
 /**
  * tf_delete_em_entry parameter definition
  */
@@ -1927,6 +1997,7 @@  struct tf_delete_em_entry_parms {
 	 */
 	uint64_t flow_handle;
 };
+
 /**
  * tf_move_em_entry parameter definition
  */
@@ -1969,6 +2040,7 @@  struct tf_move_em_entry_parms {
 	 */
 	uint64_t flow_handle;
 };
+
 /**
  * tf_search_em_entry parameter definition (Future)
  */
@@ -2108,6 +2180,7 @@  int tf_search_em_entry(struct tf *tfp,
  *
  * @ref tf_get_global_cfg
  */
+
 /**
  * Tunnel Encapsulation Offsets
  */
@@ -2121,6 +2194,7 @@  enum tf_tunnel_encap_offsets {
 	TF_TUNNEL_ENCAP_GRE,
 	TF_TUNNEL_ENCAP_FULL_GENERIC
 };
+
 /**
  * Global Configuration Table Types
  */
@@ -2193,9 +2267,8 @@  int tf_set_global_cfg(struct tf *tfp,
  * @ref tf_set_if_tbl_entry
  *
  * @ref tf_get_if_tbl_entry
- *
- * @ref tf_restore_if_tbl_entry
  */
+
 /**
  * Enumeration of TruFlow interface table types.
  */
diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c
index 1c97218b5b..02a9ebd7b2 100644
--- a/drivers/net/bnxt/tf_core/tf_device.c
+++ b/drivers/net/bnxt/tf_core/tf_device.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -332,7 +332,7 @@  tf_dev_unbind_p4(struct tf *tfp)
 }
 
 /**
- * Device specific bind function, THOR
+ * Device specific bind function, P5
  *
  * [in] tfp
  *   Pointer to TF handle
@@ -504,7 +504,7 @@  tf_dev_bind_p58(struct tf *tfp,
 }
 
 /**
- * Device specific unbind function, THOR
+ * Device specific unbind function, P5
  *
  * [in] tfp
  *   Pointer to TF handle
@@ -602,14 +602,14 @@  tf_dev_bind(struct tf *tfp __rte_unused,
 	    struct tf_dev_info *dev_handle)
 {
 	switch (type) {
-	case TF_DEVICE_TYPE_WH:
+	case TF_DEVICE_TYPE_P4:
 	case TF_DEVICE_TYPE_SR:
 		dev_handle->type = type;
 		return tf_dev_bind_p4(tfp,
 				      resources,
 				      dev_handle,
 				      wc_num_slices);
-	case TF_DEVICE_TYPE_THOR:
+	case TF_DEVICE_TYPE_P5:
 		dev_handle->type = type;
 		return tf_dev_bind_p58(tfp,
 				       resources,
@@ -627,11 +627,11 @@  tf_dev_bind_ops(enum tf_device_type type,
 		struct tf_dev_info *dev_handle)
 {
 	switch (type) {
-	case TF_DEVICE_TYPE_WH:
+	case TF_DEVICE_TYPE_P4:
 	case TF_DEVICE_TYPE_SR:
 		dev_handle->ops = &tf_dev_ops_p4_init;
 		break;
-	case TF_DEVICE_TYPE_THOR:
+	case TF_DEVICE_TYPE_P5:
 		dev_handle->ops = &tf_dev_ops_p58_init;
 		break;
 	default:
@@ -648,10 +648,10 @@  tf_dev_unbind(struct tf *tfp,
 	      struct tf_dev_info *dev_handle)
 {
 	switch (dev_handle->type) {
-	case TF_DEVICE_TYPE_WH:
+	case TF_DEVICE_TYPE_P4:
 	case TF_DEVICE_TYPE_SR:
 		return tf_dev_unbind_p4(tfp);
-	case TF_DEVICE_TYPE_THOR:
+	case TF_DEVICE_TYPE_P5:
 		return tf_dev_unbind_p58(tfp);
 	default:
 		TFP_DRV_LOG(ERR,
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 5a42180719..06c17a7212 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index 72c6b1cde8..911ea92471 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -296,11 +296,15 @@  tf_dev_p4_get_tcam_slice_info(struct tf *tfp,
 		return rc;
 
 /* Single slice support */
-#define CFA_P4_WC_TCAM_SLICE_SIZE     12
-
+#define CFA_P4_WC_TCAM_SLICE_SIZE   (12)
 	if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
-		*num_slices_per_row = tfs->wc_num_slices_per_row;
-		if (key_sz > *num_slices_per_row * CFA_P4_WC_TCAM_SLICE_SIZE)
+		if (key_sz <= 1 * CFA_P4_WC_TCAM_SLICE_SIZE)
+			*num_slices_per_row = TF_WC_TCAM_1_SLICE_PER_ROW;
+		else if (key_sz <= 2 * CFA_P4_WC_TCAM_SLICE_SIZE)
+			*num_slices_per_row = TF_WC_TCAM_2_SLICE_PER_ROW;
+		else if (key_sz <= 4 * CFA_P4_WC_TCAM_SLICE_SIZE)
+			*num_slices_per_row = TF_WC_TCAM_4_SLICE_PER_ROW;
+		else
 			return -ENOTSUP;
 	} else { /* for other type of tcam */
 		*num_slices_per_row = 1;
diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c
index f8b424ebc9..6916c50fdc 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p58.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -16,6 +16,7 @@ 
 #include "tfp.h"
 #include "tf_msg_common.h"
 #include "tf_tbl_sram.h"
+#include "tf_util.h"
 
 #define TF_DEV_P58_PARIF_MAX 16
 #define TF_DEV_P58_PF_MASK 0xfUL
@@ -79,33 +80,39 @@  struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
 	[TF_DIR_RX][TF_TBL_TYPE_FULL_ACT_RECORD] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_COMPACT_ACT_RECORD] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_FULL_ACT_RECORD,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	/* Policy - Encaps in bank 2 */
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_8B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_16B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_32B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 2,
+		.slices          = 4,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_64B] = {
+		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
+		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
+		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
+		.slices          = 2,
+	},
+	[TF_DIR_RX][TF_TBL_TYPE_ACT_ENCAP_128B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
@@ -116,49 +123,49 @@  struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_MODIFY_16B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_MODIFY_32B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 2,
+		.slices          = 4,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_MODIFY_64B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 1,
+		.slices          = 2,
 	},
 	/* Policy - SP in bank 0 */
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_SP_SMAC] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_SP_SMAC,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_SP_SMAC_IPV6] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_SP_SMAC,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
-		.slices          = 2,
+		.slices          = 4,
 	},
 	/* Policy - Stats in bank 3 */
 	[TF_DIR_RX][TF_TBL_TYPE_ACT_STATS_64] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_3,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_EM_FKB] = {
 		TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_EM_FKB,
@@ -192,33 +199,39 @@  struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
 	[TF_DIR_TX][TF_TBL_TYPE_FULL_ACT_RECORD] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_COMPACT_ACT_RECORD] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_FULL_ACT_RECORD,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	/* Policy - Encaps in bank 2 */
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_8B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_16B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_32B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 2,
+		.slices          = 4,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_64B] = {
+		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
+		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
+		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
+		.slices          = 2,
+	},
+	[TF_DIR_TX][TF_TBL_TYPE_ACT_ENCAP_128B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
@@ -229,49 +242,49 @@  struct tf_rm_element_cfg tf_tbl_p58[TF_DIR_MAX][TF_TBL_TYPE_MAX] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 8,
+		.slices          = 16,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_MODIFY_16B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 4,
+		.slices          = 8,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_MODIFY_32B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 2,
+		.slices          = 4,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_MODIFY_64B] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_ENCAP_8B,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2,
-		.slices          = 1,
+		.slices          = 2,
 	},
 	/* Policy - SP in bank 0 */
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_SP_SMAC] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
-		.slices	         = 8,
+		.slices	         = 16,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_SP_SMAC,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
-		.slices	         = 4,
+		.slices	         = 8,
 	},
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_SP_SMAC_IPV6] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_CHILD,
 		.parent_subtype  = TF_TBL_TYPE_ACT_SP_SMAC,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0,
-		.slices	         = 2,
+		.slices	         = 4,
 	},
 	/* Policy - Stats in bank 3 */
 	[TF_DIR_TX][TF_TBL_TYPE_ACT_STATS_64] = {
 		.cfg_type        = TF_RM_ELEM_CFG_HCAPI_BA_PARENT,
 		.hcapi_type      = CFA_RESOURCE_TYPE_P58_SRAM_BANK_3,
-		.slices          = 8,
+		.slices          = 16,
 	},
 };
 
@@ -406,10 +419,15 @@  tf_dev_p58_get_tcam_slice_info(struct tf *tfp,
 	if (rc)
 		return rc;
 
-#define CFA_P58_WC_TCAM_SLICE_SIZE     24
+#define CFA_P58_WC_TCAM_SLICE_SIZE (24)
 	if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
-		*num_slices_per_row = tfs->wc_num_slices_per_row;
-		if (key_sz > *num_slices_per_row * CFA_P58_WC_TCAM_SLICE_SIZE)
+		if (key_sz <= 1 * CFA_P58_WC_TCAM_SLICE_SIZE)
+			*num_slices_per_row = TF_WC_TCAM_1_SLICE_PER_ROW;
+		else if (key_sz <= 2 * CFA_P58_WC_TCAM_SLICE_SIZE)
+			*num_slices_per_row = TF_WC_TCAM_2_SLICE_PER_ROW;
+		else if (key_sz <= 4 * CFA_P58_WC_TCAM_SLICE_SIZE)
+			*num_slices_per_row = TF_WC_TCAM_4_SLICE_PER_ROW;
+		else
 			return -ENOTSUP;
 	} else { /* for other type of tcam */
 		*num_slices_per_row = 1;
@@ -452,6 +470,7 @@  static int tf_dev_p58_get_shared_tbl_increment(struct tf *tfp __rte_unused,
 	case TF_TBL_TYPE_ACT_ENCAP_16B:
 	case TF_TBL_TYPE_ACT_ENCAP_32B:
 	case TF_TBL_TYPE_ACT_ENCAP_64B:
+	case TF_TBL_TYPE_ACT_ENCAP_128B:
 	case TF_TBL_TYPE_ACT_SP_SMAC:
 	case TF_TBL_TYPE_ACT_SP_SMAC_IPV4:
 	case TF_TBL_TYPE_ACT_SP_SMAC_IPV6:
@@ -461,7 +480,7 @@  static int tf_dev_p58_get_shared_tbl_increment(struct tf *tfp __rte_unused,
 	case TF_TBL_TYPE_ACT_MODIFY_16B:
 	case TF_TBL_TYPE_ACT_MODIFY_32B:
 	case TF_TBL_TYPE_ACT_MODIFY_64B:
-		parms->increment_cnt = 8;
+		parms->increment_cnt = 16;
 		break;
 	default:
 		parms->increment_cnt = 1;
@@ -493,6 +512,7 @@  static bool tf_dev_p58_is_sram_managed(struct tf *tfp __rte_unused,
 	case TF_TBL_TYPE_ACT_ENCAP_16B:
 	case TF_TBL_TYPE_ACT_ENCAP_32B:
 	case TF_TBL_TYPE_ACT_ENCAP_64B:
+	case TF_TBL_TYPE_ACT_ENCAP_128B:
 	case TF_TBL_TYPE_ACT_SP_SMAC:
 	case TF_TBL_TYPE_ACT_SP_SMAC_IPV4:
 	case TF_TBL_TYPE_ACT_SP_SMAC_IPV6:
@@ -527,7 +547,7 @@  static bool tf_dev_p58_is_sram_managed(struct tf *tfp __rte_unused,
  *
  * [in/out] shift
  *   Pointer to the factor to be used as a multiplier to translate
- *   between the RM units to the user address.  SRAM manages 64B entries
+ *   between the RM units to the user address.  SRAM manages 128B entries
  *   Addresses must be shifted to an 8B address.
  *
  * Returns
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index b56b7cc188..c518150d1f 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -1000,8 +1000,8 @@  tf_em_ext_common_unbind(struct tf *tfp)
 			    strerror(-rc));
 		return rc;
 	}
-	ext_db = (struct em_ext_db *)ext_ptr;
 
+	ext_db = (struct em_ext_db *)ext_ptr;
 	if (ext_db != NULL) {
 		entry = ext_db->tbl_scope_ll.head;
 		while (entry != NULL) {
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
index 8ea5d93672..46de63a9da 100644
--- a/drivers/net/bnxt/tf_core/tf_em_internal.c
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -7,7 +7,6 @@ 
 #include <rte_common.h>
 #include <rte_errno.h>
 #include <rte_log.h>
-
 #include "tf_core.h"
 #include "tf_util.h"
 #include "tf_common.h"
@@ -63,7 +62,6 @@  tf_em_insert_int_entry(struct tf *tfp,
 		return -1;
 	}
 
-
 	rptr_index = index;
 	rc = tf_msg_insert_em_internal_entry(tfp,
 					     parms,
@@ -75,6 +73,7 @@  tf_em_insert_int_entry(struct tf *tfp,
 		dpool_free(pool, index);
 		return -1;
 	}
+
 	TF_SET_GFID(gfid,
 		    ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
 		     rptr_entry),
@@ -95,7 +94,6 @@  tf_em_insert_int_entry(struct tf *tfp,
 	return 0;
 }
 
-
 /** Delete EM internal entry API
  *
  * returns:
@@ -253,7 +251,6 @@  tf_em_int_bind(struct tf *tfp,
 		return db_rc[TF_DIR_RX];
 	}
 
-
 	if (!tf_session_is_shared_session(tfs)) {
 		for (i = 0; i < TF_DIR_MAX; i++) {
 			iparms.rm_db = em_db->em_db[i];
@@ -335,11 +332,10 @@  tf_em_int_unbind(struct tf *tfp)
 	}
 
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
-	if (rc) {
+	if (rc)
 		return 0;
-	}
-	em_db = (struct em_rm_db *)em_db_ptr;
 
+	em_db = (struct em_rm_db *)em_db_ptr;
 	for (i = 0; i < TF_DIR_MAX; i++) {
 		if (em_db->em_db[i] == NULL)
 			continue;
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index 1846675916..7d9d9595dd 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -89,6 +89,7 @@  tf_ident_unbind(struct tf *tfp)
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
 	if (rc)
 		return 0;
+
 	ident_db = (struct ident_rm_db *)ident_db_ptr;
 
 	for (i = 0; i < TF_DIR_MAX; i++) {
diff --git a/drivers/net/bnxt/tf_core/tf_if_tbl.c b/drivers/net/bnxt/tf_core/tf_if_tbl.c
index e667d6fa6d..578d361417 100644
--- a/drivers/net/bnxt/tf_core/tf_if_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_if_tbl.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -21,12 +21,6 @@  struct tf_if_tbl_db {
 	struct tf_if_tbl_cfg *if_tbl_cfg_db[TF_DIR_MAX];
 };
 
-/**
- * Init flag, set on bind and cleared on unbind
- * TODO: Store this data in session db
- */
-static uint8_t init;
-
 /**
  * Convert if_tbl_type to hwrm type.
  *
@@ -80,8 +74,6 @@  tf_if_tbl_bind(struct tf *tfp,
 	if_tbl_db->if_tbl_cfg_db[TF_DIR_TX] = parms->cfg;
 	tf_session_set_if_tbl_db(tfp, (void *)if_tbl_db);
 
-	init = 1;
-
 	TFP_DRV_LOG(INFO,
 		    "Table Type - initialized\n");
 
@@ -92,14 +84,7 @@  int
 tf_if_tbl_unbind(struct tf *tfp)
 {
 	int rc;
-	struct tf_if_tbl_db *if_tbl_db_ptr;
-
-	/* Bail if nothing has been initialized */
-	if (!init) {
-		TFP_DRV_LOG(INFO,
-			    "No Table DBs created\n");
-		return 0;
-	}
+	struct tf_if_tbl_db *if_tbl_db_ptr = NULL;
 
 	TF_CHECK_PARMS1(tfp);
 
@@ -108,9 +93,15 @@  tf_if_tbl_unbind(struct tf *tfp)
 		TFP_DRV_LOG(INFO, "No IF Table DBs initialized\n");
 		return 0;
 	}
+	/* Bail if nothing has been initialized */
+	if (!if_tbl_db_ptr) {
+		TFP_DRV_LOG(INFO,
+			    "No Table DBs created\n");
+		return 0;
+	}
 
 	tfp_free((void *)if_tbl_db_ptr);
-	init = 0;
+	tf_session_set_if_tbl_db(tfp, NULL);
 
 	return 0;
 }
@@ -120,24 +111,24 @@  tf_if_tbl_set(struct tf *tfp,
 	      struct tf_if_tbl_set_parms *parms)
 {
 	int rc;
-	struct tf_if_tbl_db *if_tbl_db_ptr;
+	struct tf_if_tbl_db *if_tbl_db_ptr = NULL;
 	struct tf_if_tbl_get_hcapi_parms hparms;
 
 	TF_CHECK_PARMS3(tfp, parms, parms->data);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	rc = tf_session_get_if_tbl_db(tfp, (void **)&if_tbl_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(INFO, "No IF Table DBs initialized\n");
 		return 0;
 	}
 
+	if (!if_tbl_db_ptr) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No Table DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
 	/* Convert TF type to HCAPI type */
 	hparms.tbl_db = if_tbl_db_ptr->if_tbl_cfg_db[parms->dir];
 	hparms.db_index = parms->type;
@@ -163,24 +154,24 @@  tf_if_tbl_get(struct tf *tfp,
 	      struct tf_if_tbl_get_parms *parms)
 {
 	int rc = 0;
-	struct tf_if_tbl_db *if_tbl_db_ptr;
+	struct tf_if_tbl_db *if_tbl_db_ptr = NULL;
 	struct tf_if_tbl_get_hcapi_parms hparms;
 
 	TF_CHECK_PARMS3(tfp, parms, parms->data);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	rc = tf_session_get_if_tbl_db(tfp, (void **)&if_tbl_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(INFO, "No IF Table DBs initialized\n");
 		return 0;
 	}
 
+	if (!if_tbl_db_ptr) {
+		TFP_DRV_LOG(ERR,
+			    "%s: No Table DBs created\n",
+			    tf_dir_2_str(parms->dir));
+		return -EINVAL;
+	}
+
 	/* Convert TF type to HCAPI type */
 	hparms.tbl_db = if_tbl_db_ptr->if_tbl_cfg_db[parms->dir];
 	hparms.db_index = parms->type;
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index fbc96d374c..1c66c7e01a 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -47,7 +47,6 @@  static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) ==
 static_assert(sizeof(struct hwrm_tf_em_insert_input) ==
 	      TF_MSG_SIZE_HWRM_TF_EM_INSERT,
 	      "HWRM message size changed: hwrm_tf_em_insert_input");
-
 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET   128
 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
 	      TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET,
@@ -61,13 +60,18 @@  static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) ==
 /**
  * This is the length of shared session name "tf_share"
  */
-#define TF_SHARED_SESSION_NAME_LEN 8
+#define TF_SHARED_SESSION_NAME_LEN 9
 
 /**
  * This is the length of tcam shared session name "tf_shared-wc_tcam"
  */
 #define TF_TCAM_SHARED_SESSION_NAME_LEN 17
 
+/**
+ * This is the length of tcam shared session name "tf_shared-poolx"
+ */
+#define TF_POOL_SHARED_SESSION_NAME_LEN 16
+
 /**
  * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method
  */
@@ -135,18 +139,30 @@  tf_msg_session_open(struct bnxt *bp,
 	struct hwrm_tf_session_open_input req = { 0 };
 	struct hwrm_tf_session_open_output resp = { 0 };
 	struct tfp_send_msg_parms parms = { 0 };
-	int name_len;
 	char *session_name;
 	char *tcam_session_name;
+	char *pool_session_name;
 
-	/* Populate the request */
-	name_len = strnlen(ctrl_chan_name, TF_SESSION_NAME_MAX);
-	session_name = &ctrl_chan_name[name_len - strlen("tf_shared")];
-	tcam_session_name = &ctrl_chan_name[name_len - strlen("tf_shared-wc_tcam")];
-	if (!strncmp(tcam_session_name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
-		tfp_memcpy(&req.session_name, tcam_session_name, TF_TCAM_SHARED_SESSION_NAME_LEN);
-	else if (!strncmp(session_name, "tf_shared", strlen("tf_shared")))
-		tfp_memcpy(&req.session_name, session_name, TF_SHARED_SESSION_NAME_LEN);
+	/*
+	 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
+	 * "tf_shared-pool" is defined for version 1.0.1.
+	 * "tf_shared" is used by both verions.
+	 */
+	tcam_session_name = strstr(ctrl_chan_name, "tf_shared-wc_tcam");
+	pool_session_name = strstr(ctrl_chan_name, "tf_shared-pool");
+	session_name = strstr(ctrl_chan_name, "tf_shared");
+	if (tcam_session_name)
+		tfp_memcpy(&req.session_name,
+			   tcam_session_name,
+			   TF_TCAM_SHARED_SESSION_NAME_LEN);
+	else if (pool_session_name)
+		tfp_memcpy(&req.session_name,
+			   pool_session_name,
+			   TF_POOL_SHARED_SESSION_NAME_LEN);
+	else if (session_name)
+		tfp_memcpy(&req.session_name,
+			   session_name,
+			   TF_SHARED_SESSION_NAME_LEN);
 	else
 		tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX);
 
@@ -191,9 +207,9 @@  tf_msg_session_client_register(struct tf *tfp,
 	struct tfp_send_msg_parms parms = { 0 };
 	uint8_t fw_session_id;
 	struct tf_dev_info *dev;
-	int name_len;
 	char *session_name;
 	char *tcam_session_name;
+	char *pool_session_name;
 
 	/* Retrieve the device information */
 	rc = tf_session_get_device(tfs, &dev);
@@ -214,24 +230,31 @@  tf_msg_session_client_register(struct tf *tfp,
 
 	/* Populate the request */
 	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
-	name_len = strnlen(ctrl_channel_name, TF_SESSION_NAME_MAX);
-	session_name = &ctrl_channel_name[name_len - strlen("tf_shared")];
-	tcam_session_name = &ctrl_channel_name[name_len -
-		strlen("tf_shared-wc_tcam")];
-	if (!strncmp(tcam_session_name,
-				"tf_shared-wc_tcam",
-				strlen("tf_shared-wc_tcam")))
+
+	/*
+	 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
+	 * "tf_shared-pool" is defined for version 1.0.1.
+	 * "tf_shared" is used by both verions.
+	 */
+	tcam_session_name = strstr(ctrl_channel_name, "tf_shared-wc_tcam");
+	pool_session_name = strstr(ctrl_channel_name, "tf_shared-pool");
+	session_name = strstr(ctrl_channel_name, "tf_shared");
+	if (tcam_session_name)
+		tfp_memcpy(&req.session_client_name,
+			   tcam_session_name,
+			   TF_TCAM_SHARED_SESSION_NAME_LEN);
+	else if (pool_session_name)
 		tfp_memcpy(&req.session_client_name,
-				tcam_session_name,
-				TF_TCAM_SHARED_SESSION_NAME_LEN);
-	else if (!strncmp(session_name, "tf_shared", strlen("tf_shared")))
+			   pool_session_name,
+			   TF_POOL_SHARED_SESSION_NAME_LEN);
+	else if (session_name)
 		tfp_memcpy(&req.session_client_name,
-				session_name,
-				TF_SHARED_SESSION_NAME_LEN);
+			   session_name,
+			   TF_SHARED_SESSION_NAME_LEN);
 	else
 		tfp_memcpy(&req.session_client_name,
-				ctrl_channel_name,
-				TF_SESSION_NAME_MAX);
+			   ctrl_channel_name,
+			   TF_SESSION_NAME_MAX);
 
 	parms.tf_type = HWRM_TF_SESSION_REGISTER;
 	parms.req_data = (uint32_t *)&req;
@@ -431,7 +454,6 @@  tf_msg_session_resc_qcaps(struct tf *tfp,
 
 	/* Post process the response */
 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
-
 	for (i = 0; i < resp.size; i++) {
 		query[i].type = tfp_le_to_cpu_32(data[i].type);
 		query[i].min = tfp_le_to_cpu_16(data[i].min);
@@ -1757,6 +1779,7 @@  tf_msg_set_tbl_entry(struct tf *tfp,
 	struct hwrm_tf_tbl_type_set_input req = { 0 };
 	struct hwrm_tf_tbl_type_set_output resp = { 0 };
 	struct tfp_send_msg_parms parms = { 0 };
+	struct tf_msg_dma_buf buf = { 0 };
 	uint8_t fw_session_id;
 	struct tf_dev_info *dev;
 	struct tf_session *tfs;
@@ -1802,18 +1825,19 @@  tf_msg_set_tbl_entry(struct tf *tfp,
 
 	/* Check for data size conformity */
 	if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) {
-		rc = -EINVAL;
-		TFP_DRV_LOG(ERR,
-			    "%s: Invalid parameters for msg type, rc:%s\n",
-			    tf_dir_2_str(dir),
-			    strerror(-rc));
-		return rc;
+		/* use dma buffer */
+		req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA;
+		rc = tf_msg_alloc_dma_buf(&buf, size);
+		if (rc)
+			goto cleanup;
+		tfp_memcpy(buf.va_addr, data, size);
+		tfp_memcpy(&req.data[0],
+			   &buf.pa_addr,
+			   sizeof(buf.pa_addr));
+	} else {
+		tfp_memcpy(&req.data, data, size);
 	}
 
-	tfp_memcpy(&req.data,
-		   data,
-		   size);
-
 	parms.tf_type = HWRM_TF_TBL_TYPE_SET;
 	parms.req_data = (uint32_t *)&req;
 	parms.req_size = sizeof(req);
@@ -1823,10 +1847,10 @@  tf_msg_set_tbl_entry(struct tf *tfp,
 
 	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
 				 &parms);
-	if (rc)
-		return rc;
+cleanup:
+	tf_msg_free_dma_buf(&buf);
 
-	return 0;
+	return rc;
 }
 
 int
@@ -2325,3 +2349,114 @@  tf_msg_get_version(struct bnxt *bp,
 
 	return rc;
 }
+
+int
+tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state)
+{
+	int rc;
+	struct hwrm_tf_session_hotup_state_set_input req = { 0 };
+	struct hwrm_tf_session_hotup_state_set_output resp = { 0 };
+	struct tfp_send_msg_parms parms = { 0 };
+	uint8_t fw_session_id;
+	struct tf_dev_info *dev;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup device, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Unable to lookup FW id, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Populate the request */
+	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
+	req.state = tfp_cpu_to_le_16(state);
+
+	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET;
+	parms.req_data = (uint32_t *)&req;
+	parms.req_size = sizeof(req);
+	parms.resp_data = (uint32_t *)&resp;
+	parms.resp_size = sizeof(resp);
+	parms.mailbox = dev->ops->tf_dev_get_mailbox();
+
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
+				 &parms);
+	return rc;
+}
+
+int
+tf_msg_session_get_hotup_state(struct tf *tfp,
+			       uint16_t *state,
+			       uint16_t *ref_cnt)
+{
+	int rc;
+	struct hwrm_tf_session_hotup_state_get_input req = { 0 };
+	struct hwrm_tf_session_hotup_state_get_output resp = { 0 };
+	struct tfp_send_msg_parms parms = { 0 };
+	uint8_t fw_session_id;
+	struct tf_dev_info *dev;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup device, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Unable to lookup FW id, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Populate the request */
+	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
+
+	parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET;
+	parms.req_data = (uint32_t *)&req;
+	parms.req_size = sizeof(req);
+	parms.resp_data = (uint32_t *)&resp;
+	parms.resp_size = sizeof(resp);
+	parms.mailbox = dev->ops->tf_dev_get_mailbox();
+
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfp),
+				 &parms);
+
+	*state = tfp_le_to_cpu_16(resp.state);
+	*ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h
index 188b361d71..24d0ae5f43 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.h
+++ b/drivers/net/bnxt/tf_core/tf_msg.h
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -761,4 +761,40 @@  int
 tf_msg_get_version(struct bnxt *bp,
 		   struct tf_dev_info *dev,
 		   struct tf_get_version_parms *parms);
+
+/**
+ * Send set hot upgrade state request to the firmware.
+ *
+ * [in] tfp
+ *   Pointer to session handle
+ *
+ * [in] state
+ *   Hot upgrade session state
+ *
+ * Returns:
+ *  0 on Success else internal Truflow error
+ */
+int
+tf_msg_session_set_hotup_state(struct tf *tfp,
+			       uint16_t state);
+
+/**
+ * Send get hot upgrade state request to the firmware.
+ *
+ * [in] tfp
+ *   Pointer to session handle
+ *
+ * [out] state
+ *   Pointer to hot upgrade session state
+ *
+ * [out] ref_cnt
+ *   Pointer to hot upgrade session reference count
+ *
+ * Returns:
+ *  0 on Success else internal Truflow error
+ */
+int
+tf_msg_session_get_hotup_state(struct tf *tfp,
+			       uint16_t *state,
+			       uint16_t *ref_cnt);
 #endif  /* _TF_MSG_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index d2045921b9..1fccb698d0 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -1,15 +1,12 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
 #include <string.h>
-
 #include <rte_common.h>
 #include <rte_debug.h>
-
 #include <cfa_resource_types.h>
-
 #include "tf_rm.h"
 #include "tf_common.h"
 #include "tf_util.h"
@@ -18,9 +15,6 @@ 
 #include "tfp.h"
 #include "tf_msg.h"
 
-/* Logging defines */
-#define TF_RM_DEBUG  0
-
 /**
  * Generic RM Element data type that an RM DB is build upon.
  */
@@ -210,45 +204,6 @@  tf_rm_adjust_index(struct tf_rm_element *db,
 	return rc;
 }
 
-/**
- * Logs an array of found residual entries to the console.
- *
- * [in] dir
- *   Receive or transmit direction
- *
- * [in] module
- *   Type of Device Module
- *
- * [in] count
- *   Number of entries in the residual array
- *
- * [in] residuals
- *   Pointer to an array of residual entries. Array is index same as
- *   the DB in which this function is used. Each entry holds residual
- *   value for that entry.
- */
-#if (TF_RM_DEBUG == 1)
-static void
-tf_rm_log_residuals(enum tf_dir dir,
-		    enum tf_module_type module,
-		    uint16_t count,
-		    uint16_t *residuals)
-{
-	int i;
-
-	/* Walk the residual array and log the types that wasn't
-	 * cleaned up to the console.
-	 */
-	for (i = 0; i < count; i++) {
-		if (residuals[i] != 0)
-			TFP_DRV_LOG(INFO,
-				"%s, %s was not cleaned up, %d outstanding\n",
-				tf_dir_2_str(dir),
-				tf_module_subtype_2_str(module, i),
-				residuals[i]);
-	}
-}
-#endif /* TF_RM_DEBUG == 1 */
 /**
  * Performs a check of the passed in DB for any lingering elements. If
  * a resource type was found to not have been cleaned up by the caller
@@ -364,12 +319,6 @@  tf_rm_check_residuals(struct tf_rm_new_db *rm_db,
 		*resv_size = found;
 	}
 
-#if (TF_RM_DEBUG == 1)
-	tf_rm_log_residuals(rm_db->dir,
-			    rm_db->module,
-			    rm_db->num_entries,
-			    residuals);
-#endif
 	tfp_free((void *)residuals);
 	*resv = local_resv;
 
@@ -419,7 +368,7 @@  tf_rm_update_parent_reservations(struct tf *tfp,
 				 bool shared_session)
 {
 	int parent, child;
-	const char *type_str;
+	const char *type_str = NULL;
 
 	/* Search through all the elements */
 	for (parent = 0; parent < num_elements; parent++) {
@@ -444,11 +393,6 @@  tf_rm_update_parent_reservations(struct tf *tfp,
 				dev->ops->tf_dev_get_resource_str(tfp,
 							 cfg[parent].hcapi_type,
 							 &type_str);
-#if (TF_RM_DEBUG == 1)
-				printf("%s:%s cnt(%d) slices(%d)\n",
-				       type_str, tf_tbl_type_2_str(parent),
-				       alloc_cnt[parent], p_slices);
-#endif /* (TF_RM_DEBUG == 1) */
 			}
 
 			/* Search again through all the elements */
@@ -469,13 +413,7 @@  tf_rm_update_parent_reservations(struct tf *tfp,
 					dev->ops->tf_dev_get_resource_str(tfp,
 							  cfg[child].hcapi_type,
 							   &type_str);
-#if (TF_RM_DEBUG == 1)
-					printf("%s:%s cnt(%d) slices(%d)\n",
-					       type_str,
-					       tf_tbl_type_2_str(child),
-					       alloc_cnt[child],
-					       c_slices);
-#endif /* (TF_RM_DEBUG == 1) */
+
 					/* Increment the parents combined count
 					 * with each child's count adjusted for
 					 * number of slices per RM alloc item.
@@ -492,10 +430,6 @@  tf_rm_update_parent_reservations(struct tf *tfp,
 			}
 			/* Save the parent count to be requested */
 			req_cnt[parent] = combined_cnt;
-#if (TF_RM_DEBUG == 1)
-			printf("%s calculated total:%d\n\n",
-			       type_str, req_cnt[parent]);
-#endif /* (TF_RM_DEBUG == 1) */
 		}
 	}
 	return 0;
@@ -595,12 +529,6 @@  tf_rm_create_db(struct tf *tfp,
 				       &hcapi_items);
 
 	if (hcapi_items == 0) {
-#if (TF_RM_DEBUG == 1)
-		TFP_DRV_LOG(INFO,
-			"%s: module: %s Empty RM DB create request\n",
-			tf_dir_2_str(parms->dir),
-			tf_module_2_str(parms->module));
-#endif
 		parms->rm_db = NULL;
 		return -ENOMEM;
 	}
@@ -746,7 +674,7 @@  tf_rm_create_db(struct tf *tfp,
 
 				rc = ba_init(db[i].pool,
 					     resv[j].stride,
-					     !tf_session_is_shared_session(tfs));
+					     true);
 				if (rc) {
 					TFP_DRV_LOG(ERR,
 					  "%s: Pool init failed, type:%d:%s\n",
@@ -773,13 +701,6 @@  tf_rm_create_db(struct tf *tfp,
 	rm_db->module = parms->module;
 	*parms->rm_db = (void *)rm_db;
 
-#if (TF_RM_DEBUG == 1)
-
-	printf("%s: module:%s\n",
-	       tf_dir_2_str(parms->dir),
-	       tf_module_2_str(parms->module));
-#endif /* (TF_RM_DEBUG == 1) */
-
 	tfp_free((void *)req);
 	tfp_free((void *)resv);
 	tfp_free((void *)req_cnt);
@@ -812,6 +733,7 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 	struct tf_rm_new_db *rm_db;
 	struct tf_rm_element *db;
 	uint32_t pool_size;
+	bool shared_session = 0;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -841,6 +763,16 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 	tfp_memcpy(req_cnt, parms->alloc_cnt,
 		   parms->num_elements * sizeof(uint16_t));
 
+	shared_session = tf_session_is_shared_session(tfs);
+
+	/* Update the req_cnt based upon the element configuration
+	 */
+	tf_rm_update_parent_reservations(tfp, dev, parms->cfg,
+					 parms->alloc_cnt,
+					 parms->num_elements,
+					 req_cnt,
+					 shared_session);
+
 	/* Process capabilities against DB requirements. However, as a
 	 * DB can hold elements that are not HCAPI we can reduce the
 	 * req msg content by removing those out of the request yet
@@ -855,11 +787,6 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 				       &hcapi_items);
 
 	if (hcapi_items == 0) {
-		TFP_DRV_LOG(ERR,
-			"%s: module:%s Empty RM DB create request\n",
-			tf_dir_2_str(parms->dir),
-			tf_module_2_str(parms->module));
-
 		parms->rm_db = NULL;
 		return -ENOMEM;
 	}
@@ -938,6 +865,7 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 
 		db[i].cfg_type = cfg->cfg_type;
 		db[i].hcapi_type = cfg->hcapi_type;
+		db[i].slices = cfg->slices;
 
 		/* Save the parent subtype for later use to find the pool
 		 */
@@ -986,7 +914,7 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 
 				rc = ba_init(db[i].pool,
 					     resv[j].stride,
-					     !tf_session_is_shared_session(tfs));
+					     true);
 				if (rc) {
 					TFP_DRV_LOG(ERR,
 					  "%s: Pool init failed, type:%d:%s\n",
@@ -1013,13 +941,6 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 	rm_db->module = parms->module;
 	*parms->rm_db = (void *)rm_db;
 
-#if (TF_RM_DEBUG == 1)
-
-	printf("%s: module:%s\n",
-	       tf_dir_2_str(parms->dir),
-	       tf_module_2_str(parms->module));
-#endif /* (TF_RM_DEBUG == 1) */
-
 	tfp_free((void *)req);
 	tfp_free((void *)resv);
 	tfp_free((void *)req_cnt);
@@ -1036,6 +957,7 @@  tf_rm_create_db_no_reservation(struct tf *tfp,
 
 	return -EINVAL;
 }
+
 int
 tf_rm_free_db(struct tf *tfp,
 	      struct tf_rm_free_db_parms *parms)
@@ -1110,6 +1032,7 @@  tf_rm_free_db(struct tf *tfp,
 
 	return rc;
 }
+
 /**
  * Get the bit allocator pool associated with the subtype and the db
  *
@@ -1388,6 +1311,7 @@  tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms)
 
 	return 0;
 }
+
 int
 tf_rm_get_slices(struct tf_rm_get_slices_parms *parms)
 {
@@ -1440,6 +1364,7 @@  tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
 
 	return rc;
 }
+
 /* Only used for table bulk get at this time
  */
 int
diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c
index d0a0916c6a..253d716572 100644
--- a/drivers/net/bnxt/tf_core/tf_session.c
+++ b/drivers/net/bnxt/tf_core/tf_session.c
@@ -1,12 +1,10 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
 #include <string.h>
-
 #include <rte_common.h>
-
 #include "tf_session.h"
 #include "tf_common.h"
 #include "tf_msg.h"
@@ -59,8 +57,9 @@  tf_session_create(struct tf *tfp,
 	union tf_session_id *session_id;
 	struct tf_dev_info dev;
 	bool shared_session_creator;
-	int name_len;
-	char *name;
+	char *shared_name;
+	char *tcam_session_name;
+	char *pool_session_name;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -180,16 +179,18 @@  tf_session_create(struct tf *tfp,
 	session->em_ext_db_handle = NULL;
 
 	/* Populate the request */
-	name_len = strnlen(parms->open_cfg->ctrl_chan_name,
-			   TF_SESSION_NAME_MAX);
-	name = &parms->open_cfg->ctrl_chan_name[name_len - strlen("tf_shared")];
-	if (!strncmp(name, "tf_shared", strlen("tf_shared")))
-		session->shared_session = true;
-
-	name = &parms->open_cfg->ctrl_chan_name[name_len -
-		strlen("tf_shared-wc_tcam")];
-	if (!strncmp(name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
+	shared_name = strstr(parms->open_cfg->ctrl_chan_name, "tf_shared");
+	if (shared_name) {
 		session->shared_session = true;
+		/*
+		 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0.
+		 * "tf_shared-pool" is defined for version 1.0.1.
+		 */
+		tcam_session_name = strstr(parms->open_cfg->ctrl_chan_name, "tf_shared-wc_tcam");
+		pool_session_name = strstr(parms->open_cfg->ctrl_chan_name, "tf_shared-pool");
+		if (tcam_session_name || pool_session_name)
+			session->shared_session_hotup = true;
+	}
 
 	if (session->shared_session && shared_session_creator) {
 		session->shared_session_creator = true;
@@ -342,7 +343,6 @@  tf_session_client_create(struct tf *tfp,
 	return rc;
 }
 
-
 /**
  * Destroys a Session Client on an existing Session.
  *
@@ -441,7 +441,7 @@  tf_session_open_session(struct tf *tfp,
 
 		TFP_DRV_LOG(INFO,
 		       "Session created, session_client_id:%d,"
-		       "session_id:0x%08x, fw_session_id:%d\n",
+		       " session_id:0x%08x, fw_session_id:%d\n",
 		       parms->open_cfg->session_client_id.id,
 		       parms->open_cfg->session_id.id,
 		       parms->open_cfg->session_id.internal.fw_session_id);
@@ -462,7 +462,7 @@  tf_session_open_session(struct tf *tfp,
 		}
 
 		TFP_DRV_LOG(INFO,
-			"Session Client:%d registered on session:0x%8x\n",
+			"Session Client:%d registered on session:0x%08x\n",
 			scparms.session_client_id->internal.fw_session_client_id,
 			tfp->session->session_id.id);
 	}
@@ -535,6 +535,11 @@  tf_session_close_session(struct tf *tfp,
 		return rc;
 	}
 
+	/* Record the session we're closing so the caller knows the
+	 * details.
+	 */
+	*parms->session_id = tfs->session_id;
+
 	/* In case multiple clients we chose to close those first */
 	if (tfs->ref_count > 1) {
 		/* Linaro gcc can't static init this structure */
@@ -567,11 +572,6 @@  tf_session_close_session(struct tf *tfp,
 		return 0;
 	}
 
-	/* Record the session we're closing so the caller knows the
-	 * details.
-	 */
-	*parms->session_id = tfs->session_id;
-
 	rc = tf_session_get_device(tfs, &tfd);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -1140,3 +1140,71 @@  tf_session_set_if_tbl_db(struct tf *tfp,
 	tfs->if_tbl_db_handle = if_tbl_handle;
 	return rc;
 }
+
+int
+tf_session_set_hotup_state(struct tf *tfp,
+			   struct tf_set_session_hotup_state_parms *parms)
+{
+	int rc = 0;
+	struct tf_session *tfs = NULL;
+
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Session lookup failed, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (!tf_session_is_shared_session(tfs)) {
+		rc = -EINVAL;
+		TFP_DRV_LOG(ERR,
+			    "Only shared session able to set state, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = tf_msg_session_set_hotup_state(tfp, parms->state);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR,
+			    "Set session hot upgrade state failed, rc:%s\n",
+			    strerror(-rc));
+	}
+
+	return rc;
+}
+
+int
+tf_session_get_hotup_state(struct tf *tfp,
+			   struct tf_get_session_hotup_state_parms *parms)
+{
+	int rc = 0;
+	struct tf_session *tfs = NULL;
+
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Session lookup failed, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (!tf_session_is_shared_session(tfs)) {
+		rc = -EINVAL;
+		TFP_DRV_LOG(ERR,
+			    "Only shared session able to get state, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = tf_msg_session_get_hotup_state(tfp, &parms->state, &parms->ref_cnt);
+	if (rc) {
+		/* Log error */
+		TFP_DRV_LOG(ERR,
+			    "Get session hot upgrade state failed, rc:%s\n",
+			    strerror(-rc));
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_session.h b/drivers/net/bnxt/tf_core/tf_session.h
index 5a94b941fa..9bbbccf125 100644
--- a/drivers/net/bnxt/tf_core/tf_session.h
+++ b/drivers/net/bnxt/tf_core/tf_session.h
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -8,7 +8,6 @@ 
 
 #include <stdint.h>
 #include <stdlib.h>
-
 #include "bitalloc.h"
 #include "tf_core.h"
 #include "tf_device.h"
@@ -48,7 +47,7 @@ 
  *
  * Shared memory containing private TruFlow session information.
  * Through this structure the session can keep track of resource
- * allocations.  It also holds info about Session Clients.
+ * allocations. It also holds info about Session Clients.
  *
  * Memory is assigned to the Truflow instance by way of
  * tf_open_session. Memory is allocated and owned by i.e. ULP.
@@ -78,6 +77,11 @@  struct tf_session {
 	 */
 	bool shared_session;
 
+	/**
+	 * Boolean controlling the split of hardware resources for hotupgrade.
+	 */
+	bool shared_session_hotup;
+
 	/**
 	 * This flag indicates the shared session on firmware side is created
 	 * by this session. Some privileges may be assigned to this session.
@@ -169,6 +173,12 @@  struct tf_session {
 	 * Number of slices per row for WC TCAM
 	 */
 	uint16_t wc_num_slices_per_row;
+
+	/**
+	 * Indicates if TCAM is controlled by TCAM Manager
+	 */
+	int tcam_mgr_control[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX];
+
 };
 
 /**
@@ -276,11 +286,9 @@  struct tf_session_close_session_parms {
  *
  * @ref tf_session_is_shared_session
  *
- * #define TF_SHARED
  * @ref tf_session_get_tcam_shared_db
  *
  * @ref tf_session_set_tcam_shared_db
- * #endif
  *
  * @ref tf_session_get_sram_db
  *
@@ -588,6 +596,21 @@  tf_session_is_shared_session(struct tf_session *tfs)
 	return tfs->shared_session;
 }
 
+/**
+ * Check if the session is shared session for hot upgrade.
+ *
+ * [in] session, pointer to the session
+ *
+ * Returns:
+ *   - true if it is shared session for hot upgrade
+ *   - false if it is not shared session for hot upgrade
+ */
+static inline bool
+tf_session_is_shared_hotup_session(struct tf_session *tfs)
+{
+	return tfs->shared_session_hotup;
+}
+
 /**
  * Check if the session is the shared session creator
  *
@@ -716,4 +739,36 @@  tf_session_set_if_tbl_db(struct tf *tfp,
 int
 tf_session_get_if_tbl_db(struct tf *tfp,
 			 void **if_tbl_handle);
+
+/**
+ * Set hot upgrade session state.
+ *
+ * [in] tfp
+ *   Pointer to session handle
+ *
+ * [in] parms
+ *   Hot upgrade session state parms
+ *
+ * Returns:
+ *  0 on Success else internal Truflow error
+ */
+int
+tf_session_set_hotup_state(struct tf *tfp,
+			   struct tf_set_session_hotup_state_parms *parms);
+
+/**
+ * Get hot upgrade session state.
+ *
+ * [in] tfp
+ *   Pointer to session handle
+ *
+ * [out] parms
+ *   Pointer to hot upgrade session state parms
+ *
+ * Returns:
+ *  0 on Success else internal Truflow error
+ */
+int
+tf_session_get_hotup_state(struct tf *tfp,
+			   struct tf_get_session_hotup_state_parms *parms);
 #endif /* _TF_SESSION_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_sram_mgr.c b/drivers/net/bnxt/tf_core/tf_sram_mgr.c
index acb3372486..87e8882fed 100644
--- a/drivers/net/bnxt/tf_core/tf_sram_mgr.c
+++ b/drivers/net/bnxt/tf_core/tf_sram_mgr.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 #include <stdlib.h>
@@ -21,7 +21,7 @@ 
 /**
  * TF SRAM block info
  *
- * Contains all the information about a particular 64B SRAM
+ * Contains all the information about a particular 128B SRAM
  * block and the slices within it.
  */
 struct tf_sram_block {
@@ -36,9 +36,9 @@  struct tf_sram_block {
 	 *  If a bit is set, it indicates the slice
 	 *  in the row is in use.
 	 */
-	uint8_t in_use_mask;
+	uint16_t in_use_mask;
 
-	/** Block id - this is a 64B offset
+	/** Block id - this is a 128B offset
 	 */
 	uint16_t block_id;
 };
@@ -46,7 +46,7 @@  struct tf_sram_block {
 /**
  * TF SRAM block list
  *
- * List of 64B SRAM blocks used for fixed size slices (8, 16, 32, 64B)
+ * List of 128B SRAM blocks used for fixed size slices (8, 16, 32, 64B, 128B)
  */
 struct tf_sram_slice_list {
 	/** Pointer to head of linked list of blocks.
@@ -70,7 +70,6 @@  struct tf_sram_slice_list {
 	enum tf_sram_slice_size size;
 };
 
-
 /**
  * TF SRAM bank info consists of lists of different slice sizes per bank
  */
@@ -111,6 +110,8 @@  const char
 		return "32B slice";
 	case TF_SRAM_SLICE_SIZE_64B:
 		return "64B slice";
+	case TF_SRAM_SLICE_SIZE_128B:
+		return "128B slice";
 	default:
 		return "Invalid slice size";
 	}
@@ -179,8 +180,8 @@  static void
 tf_sram_offset_2_block_id(enum tf_sram_bank_id bank_id, uint16_t offset,
 			  uint16_t *block_id, uint16_t *slice_offset)
 {
-	*slice_offset = offset & 0x7;
-	*block_id = ((offset & ~0x7) >> 3) -
+	*slice_offset = offset & 0xf;
+	*block_id = ((offset & ~0xf) >> 3) -
 		    tf_sram_bank_2_base_offset[bank_id];
 }
 
@@ -232,31 +233,37 @@  tf_sram_free_slice(enum tf_sram_slice_size slice_size,
 		   bool *block_is_empty)
 {
 	int rc = 0;
-	uint8_t shift;
-	uint8_t slice_mask = 0;
+	uint16_t shift;
+	uint16_t slice_mask = 0;
 
 	TF_CHECK_PARMS2(block, block_is_empty);
 
 	switch (slice_size) {
 	case TF_SRAM_SLICE_SIZE_8B:
 		shift = slice_offset >> 0;
-		assert(shift < 8);
+		assert(shift < 16);
 		slice_mask = 1 << shift;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_16B:
 		shift = slice_offset >> 1;
-		assert(shift < 4);
+		assert(shift < 8);
 		slice_mask = 1 << shift;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_32B:
 		shift = slice_offset >> 2;
-		assert(shift < 2);
+		assert(shift < 4);
 		slice_mask = 1 << shift;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_64B:
+		shift = slice_offset >> 3;
+		assert(shift < 2);
+		slice_mask = 1 << shift;
+		break;
+
+	case TF_SRAM_SLICE_SIZE_128B:
 	default:
 		shift = slice_offset >> 0;
 		assert(shift < 1);
@@ -294,27 +301,32 @@  tf_sram_get_next_slice_in_block(struct tf_sram_block *block,
 				bool *block_is_full)
 {
 	int rc, free_id = -1;
-	uint8_t shift, max_slices, mask, i, full_mask;
+	uint16_t shift, max_slices, mask, i, full_mask;
 
 	TF_CHECK_PARMS3(block, slice_offset, block_is_full);
 
 	switch (slice_size) {
 	case TF_SRAM_SLICE_SIZE_8B:
 		shift      = 0;
-		max_slices = 8;
-		full_mask  = 0xff;
+		max_slices = 16;
+		full_mask  = 0xffff;
 		break;
 	case TF_SRAM_SLICE_SIZE_16B:
 		shift      = 1;
-		max_slices = 4;
-		full_mask  = 0xf;
+		max_slices = 8;
+		full_mask  = 0xff;
 		break;
 	case TF_SRAM_SLICE_SIZE_32B:
 		shift      = 2;
+		max_slices = 4;
+		full_mask  = 0xf;
+		break;
+	case TF_SRAM_SLICE_SIZE_64B:
+		shift      = 3;
 		max_slices = 2;
 		full_mask  = 0x3;
 		break;
-	case TF_SRAM_SLICE_SIZE_64B:
+	case TF_SRAM_SLICE_SIZE_128B:
 	default:
 		shift      = 0;
 		max_slices = 1;
@@ -338,7 +350,6 @@  tf_sram_get_next_slice_in_block(struct tf_sram_block *block,
 	else
 		*block_is_full = false;
 
-
 	if (free_id >= 0) {
 		*slice_offset = free_id << shift;
 		rc = 0;
@@ -362,8 +373,8 @@  tf_sram_is_slice_allocated_in_block(struct tf_sram_block *block,
 				    bool *is_allocated)
 {
 	int rc = 0;
-	uint8_t shift;
-	uint8_t slice_mask = 0;
+	uint16_t shift;
+	uint16_t slice_mask = 0;
 
 	TF_CHECK_PARMS2(block, is_allocated);
 
@@ -372,23 +383,29 @@  tf_sram_is_slice_allocated_in_block(struct tf_sram_block *block,
 	switch (slice_size) {
 	case TF_SRAM_SLICE_SIZE_8B:
 		shift = slice_offset >> 0;
-		assert(shift < 8);
+		assert(shift < 16);
 		slice_mask = 1 << shift;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_16B:
 		shift = slice_offset >> 1;
-		assert(shift < 4);
+		assert(shift < 8);
 		slice_mask = 1 << shift;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_32B:
 		shift = slice_offset >> 2;
-		assert(shift < 2);
+		assert(shift < 4);
 		slice_mask = 1 << shift;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_64B:
+		shift = slice_offset >> 3;
+		assert(shift < 2);
+		slice_mask = 1 << shift;
+		break;
+
+	case TF_SRAM_SLICE_SIZE_128B:
 	default:
 		shift = slice_offset >> 0;
 		assert(shift < 1);
@@ -416,7 +433,6 @@  tf_sram_get_block_cnt(struct tf_sram_slice_list *slice_list)
 	return slice_list->cnt;
 }
 
-
 /**
  * Free a block data structure - does not free to the RM
  */
@@ -508,22 +524,26 @@  tf_sram_find_first_not_full_block(struct tf_sram_slice_list *slice_list,
 				  struct tf_sram_block **first_not_full_block)
 {
 	struct tf_sram_block *block = slice_list->head;
-	uint8_t slice_mask, mask;
+	uint16_t slice_mask, mask;
 
 	switch (slice_size) {
 	case TF_SRAM_SLICE_SIZE_8B:
-		slice_mask = 0xff;
+		slice_mask = 0xffff;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_16B:
-		slice_mask = 0xf;
+		slice_mask = 0xff;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_32B:
-		slice_mask = 0x3;
+		slice_mask = 0xf;
 		break;
 
 	case TF_SRAM_SLICE_SIZE_64B:
+		slice_mask = 0x3;
+		break;
+
+	case TF_SRAM_SLICE_SIZE_128B:
 	default:
 		slice_mask = 0x1;
 		break;
@@ -543,7 +563,7 @@  tf_sram_find_first_not_full_block(struct tf_sram_slice_list *slice_list,
 static void
 tf_sram_dump_block(struct tf_sram_block *block)
 {
-	TFP_DRV_LOG(INFO, "block_id(0x%x) in_use_mask(0x%02x)\n",
+	TFP_DRV_LOG(INFO, "block_id(0x%x) in_use_mask(0x%04x)\n",
 		    block->block_id,
 		    block->in_use_mask);
 }
@@ -631,9 +651,10 @@  int tf_sram_mgr_alloc(void *sram_handle,
 	struct tf_sram *sram;
 	struct tf_sram_slice_list *slice_list;
 	uint16_t block_id, slice_offset = 0;
-	uint32_t index;
+	uint32_t index, next_index;
 	struct tf_sram_block *block;
 	struct tf_rm_allocate_parms aparms = { 0 };
+	struct tf_rm_free_parms fparms = { 0 };
 	bool block_is_full;
 	uint16_t block_offset;
 
@@ -662,11 +683,34 @@  int tf_sram_mgr_alloc(void *sram_handle,
 		aparms.subtype = parms->tbl_type;
 		aparms.rm_db = parms->rm_db;
 		rc = tf_rm_allocate(&aparms);
+		if (rc)
+			return rc;
+		/* to support 128B block rows, we are allocating
+		 * 2 sequential 64B blocks from RM, if they are not next to
+		 * each other we are going to have issues
+		 */
+		aparms.index = &next_index;
+		rc = tf_rm_allocate(&aparms);
 		if (rc)
 			return rc;
 
+		/* make sure we do get the next 64B block, else free the
+		 * allocated indexes and return error
+		 */
+		if (unlikely(index + 1 != next_index)) {
+			fparms.index = index;
+			fparms.subtype = parms->tbl_type;
+			fparms.rm_db = parms->rm_db;
+			tf_rm_free(&fparms);
+			fparms.index = next_index;
+			tf_rm_free(&fparms);
+			TFP_DRV_LOG(ERR,
+				    "Could not allocate two sequential 64B blocks\n");
+			return -ENOMEM;
+		}
 		block_id = index;
 		block = tf_sram_alloc_block(slice_list, block_id);
+
 	} else {
 		/* Block exists
 		 */
@@ -742,7 +786,7 @@  tf_sram_mgr_free(void *sram_handle,
 	}
 #if (STATS_CLEAR_ON_READ_SUPPORT == 0)
 	/* If this is a counter, clear it.  In the future we need to switch to
-	 * using the special access registers on Thor to automatically clear on
+	 * using the special access registers on P5 to automatically clear on
 	 * read.
 	 */
 	/* If this is counter table, clear the entry on free */
@@ -794,6 +838,13 @@  tf_sram_mgr_free(void *sram_handle,
 			TFP_DRV_LOG(ERR, "Free block_id(%d) failed error(%s)\n",
 				    block_id, strerror(-rc));
 		}
+		fparms.index = block_id + 1;
+		rc = tf_rm_free(&fparms);
+
+		if (rc) {
+			TFP_DRV_LOG(ERR, "Free next block_id(%d) failed error(%s)\n",
+				    block_id + 1, strerror(-rc));
+		}
 		/* Free local entry regardless */
 		tf_sram_free_block(slice_list, block);
 
diff --git a/drivers/net/bnxt/tf_core/tf_sram_mgr.h b/drivers/net/bnxt/tf_core/tf_sram_mgr.h
index fc78426130..878195c404 100644
--- a/drivers/net/bnxt/tf_core/tf_sram_mgr.h
+++ b/drivers/net/bnxt/tf_core/tf_sram_mgr.h
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -26,28 +26,28 @@ 
  */
 #define STATS_CLEAR_ON_READ_SUPPORT 0
 
-#define TF_SRAM_MGR_BLOCK_SZ_BYTES 64
+#define TF_SRAM_MGR_BLOCK_SZ_BYTES 128
 #define TF_SRAM_MGR_MIN_SLICE_BYTES 8
 
 /**
  * TF slice size.
  *
- * A slice is part of a 64B row
+ * A slice is part of a 128B row
  *
  * Each slice is a multiple of 8B
  */
 enum tf_sram_slice_size {
-	TF_SRAM_SLICE_SIZE_8B,	/**< 8 byte SRAM slice */
-	TF_SRAM_SLICE_SIZE_16B,	/**< 16 byte SRAM slice */
-	TF_SRAM_SLICE_SIZE_32B,	/**< 32 byte SRAM slice */
-	TF_SRAM_SLICE_SIZE_64B,	/**< 64 byte SRAM slice */
-	TF_SRAM_SLICE_SIZE_MAX  /**< slice limit */
+	TF_SRAM_SLICE_SIZE_8B,		/**< 8 byte SRAM slice */
+	TF_SRAM_SLICE_SIZE_16B,		/**< 16 byte SRAM slice */
+	TF_SRAM_SLICE_SIZE_32B,		/**< 32 byte SRAM slice */
+	TF_SRAM_SLICE_SIZE_64B,		/**< 64 byte SRAM slice */
+	TF_SRAM_SLICE_SIZE_128B,	/**< 128 byte SRAM slice */
+	TF_SRAM_SLICE_SIZE_MAX		/**< slice limit */
 };
 
-
 /** Initialize the SRAM slice manager
  *
- *  The SRAM slice manager manages slices within 64B rows. Slices are of size
+ *  The SRAM slice manager manages slices within 128B rows. Slices are of size
  *  tf_sram_slice_size.  This function provides a handle to the SRAM manager
  *  data.
  *
@@ -181,7 +181,7 @@  struct tf_sram_mgr_free_parms {
 /**
  * Free an SRAM Slice
  *
- * Free an SRAM slice to the indicated bank.  This may result in a 64B row
+ * Free an SRAM slice to the indicated bank.  This may result in a 128B row
  * being returned to the RM SRAM bank pool.
  *
  * [in] sram_handle
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index f18e4ba346..f5f3889934 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -1,12 +1,11 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
 /* Truflow Table APIs and supporting code */
 
 #include <rte_common.h>
-
 #include "tf_tbl.h"
 #include "tf_common.h"
 #include "tf_rm.h"
@@ -18,8 +17,8 @@ 
 
 struct tf;
 
-#define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) {          \
-		*(new_idx) = (((idx) + (base)) << (shift));    \
+#define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) {		\
+		*(new_idx) = (((idx) + (base)) << (shift));	\
 }
 
 int
@@ -98,6 +97,7 @@  tf_tbl_unbind(struct tf *tfp)
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
 	if (rc)
 		return 0;
+
 	tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
 
 	for (i = 0; i < TF_DIR_MAX; i++) {
diff --git a/drivers/net/bnxt/tf_core/tf_tbl_sram.c b/drivers/net/bnxt/tf_core/tf_tbl_sram.c
index 567f912dfa..3a6f1c68c7 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl_sram.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl_sram.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -73,11 +73,12 @@  const uint16_t tf_tbl_sram_hcapi_2_bank[CFA_RESOURCE_TYPE_P58_LAST] = {
  * Translate HCAPI type to SRAM Manager bank
  */
 const uint8_t tf_tbl_sram_slices_2_size[TF_TBL_SRAM_SLICES_MAX + 1] = {
-	[0] = TF_SRAM_SLICE_SIZE_64B, /* if 0 slices assume 1 64B block */
-	[1] = TF_SRAM_SLICE_SIZE_64B, /* 1 slice  per 64B block */
-	[2] = TF_SRAM_SLICE_SIZE_32B, /* 2 slices per 64B block */
-	[4] = TF_SRAM_SLICE_SIZE_16B, /* 4 slices per 64B block */
-	[8] = TF_SRAM_SLICE_SIZE_8B   /* 8 slices per 64B block */
+	[0] = TF_SRAM_SLICE_SIZE_128B,	/* if 0 slices assume 1 128B block */
+	[1] = TF_SRAM_SLICE_SIZE_128B,	/* 1 slice  per 128B block */
+	[2] = TF_SRAM_SLICE_SIZE_64B,	/* 2 slice  per 128B block */
+	[4] = TF_SRAM_SLICE_SIZE_32B,	/* 4 slices per 128B block */
+	[8] = TF_SRAM_SLICE_SIZE_16B,	/* 8 slices per 128B block */
+	[16] = TF_SRAM_SLICE_SIZE_8B	/* 16 slices per 128B block */
 };
 
 /**
@@ -340,7 +341,7 @@  tf_tbl_sram_free(struct tf *tfp __rte_unused,
 	rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
 	if (rc || !allocated) {
 		TFP_DRV_LOG(ERR,
-			    "%s: Free of invalid entry:%s idx(%d):(%s)\n",
+			    "%s: Free of invalid entry:%s idx(0x%x):(%s)\n",
 			    tf_dir_2_str(parms->dir),
 			    tf_tbl_type_2_str(parms->type),
 			    parms->idx,
@@ -361,7 +362,7 @@  tf_tbl_sram_free(struct tf *tfp __rte_unused,
 	rc = tf_sram_mgr_free(sram_handle, &fparms);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
-			    "%s: Failed to free entry:%s idx(%d)\n",
+			    "%s: Failed to free entry:%s idx(0x%x)\n",
 			    tf_dir_2_str(parms->dir),
 			    tf_tbl_type_2_str(parms->type),
 			    parms->idx);
@@ -469,7 +470,7 @@  tf_tbl_sram_set(struct tf *tfp,
 
 		if (rallocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
 			TFP_DRV_LOG(ERR,
-			   "%s, Invalid or not allocated index, type:%s, idx:%d\n",
+			   "%s, Invalid or not allocated index, type:%s, idx:0x%x\n",
 			   tf_dir_2_str(parms->dir),
 			   tf_tbl_type_2_str(parms->type),
 			   parms->idx);
@@ -484,7 +485,7 @@  tf_tbl_sram_set(struct tf *tfp,
 		rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
 		if (rc || !allocated) {
 			TFP_DRV_LOG(ERR,
-				    "%s: Entry not allocated:%s idx(%d):(%s)\n",
+				    "%s: Entry not allocated:%s idx(0x%x):(%s)\n",
 				    tf_dir_2_str(parms->dir),
 				    tf_tbl_type_2_str(parms->type),
 				    parms->idx,
@@ -587,7 +588,7 @@  tf_tbl_sram_get(struct tf *tfp,
 	rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
 	if (rc || !allocated) {
 		TFP_DRV_LOG(ERR,
-			    "%s: Entry not allocated:%s idx(%d):(%s)\n",
+			    "%s: Entry not allocated:%s idx(0x%x):(%s)\n",
 			    tf_dir_2_str(parms->dir),
 			    tf_tbl_type_2_str(parms->type),
 			    parms->idx,
@@ -711,7 +712,7 @@  tf_tbl_sram_bulk_get(struct tf *tfp,
 	rc = tf_sram_mgr_is_allocated(sram_handle, &aparms);
 	if (rc || !allocated) {
 		TFP_DRV_LOG(ERR,
-			    "%s: Entry not allocated:%s last_idx(%d):(%s)\n",
+			    "%s: Entry not allocated:%s last_idx(0x%x):(%s)\n",
 			    tf_dir_2_str(parms->dir),
 			    tf_tbl_type_2_str(parms->type),
 			    idx,
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index 1c42a6adc7..9e0671d47b 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -14,6 +14,7 @@ 
 #include "tfp.h"
 #include "tf_session.h"
 #include "tf_msg.h"
+#include "tf_tcam_mgr_msg.h"
 
 struct tf;
 
@@ -23,17 +24,22 @@  tf_tcam_bind(struct tf *tfp,
 {
 	int rc;
 	int db_rc[TF_DIR_MAX] = { 0 };
-	int i, d;
+	int d, t;
 	struct tf_rm_alloc_info info;
 	struct tf_rm_free_db_parms fparms;
 	struct tf_rm_create_db_parms db_cfg;
+	struct tf_tcam_resources local_tcam_cnt[TF_DIR_MAX];
 	struct tf_tcam_resources *tcam_cnt;
 	struct tf_rm_get_alloc_info_parms ainfo;
-	uint16_t num_slices = parms->wc_num_slices;
+	uint16_t num_slices = 1;
 	struct tf_session *tfs;
 	struct tf_dev_info *dev;
 	struct tcam_rm_db *tcam_db;
 	struct tfp_calloc_parms cparms;
+	struct tf_resource_info resv_res[TF_DIR_MAX][TF_TCAM_TBL_TYPE_MAX];
+	uint32_t rx_supported;
+	uint32_t tx_supported;
+	bool no_req = true;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -47,7 +53,7 @@  tf_tcam_bind(struct tf *tfp,
 	if (rc)
 		return rc;
 
-	if (dev->ops->tf_dev_set_tcam_slice_info == NULL) {
+	if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
 		rc = -EOPNOTSUPP;
 		TFP_DRV_LOG(ERR,
 			    "Operation not supported, rc:%s\n",
@@ -55,18 +61,28 @@  tf_tcam_bind(struct tf *tfp,
 		return rc;
 	}
 
-	rc = dev->ops->tf_dev_set_tcam_slice_info(tfp,
-						  num_slices);
+	tcam_cnt = parms->resources->tcam_cnt;
+
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+			rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, t, 0,
+								  &num_slices);
 	if (rc)
 		return rc;
 
-	tcam_cnt = parms->resources->tcam_cnt;
-	if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices) ||
-	    (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices)) {
-		TFP_DRV_LOG(ERR,
-			    "Requested num of WC TCAM entries has to be multiple %d\n",
-			    num_slices);
-		return -EINVAL;
+			if (num_slices == 1)
+				continue;
+
+			if (tcam_cnt[d].cnt[t] % num_slices) {
+				TFP_DRV_LOG(ERR,
+					    "%s: Requested num of %s entries "
+					    "has to be multiple of %d\n",
+					    tf_dir_2_str(d),
+					    tf_tcam_tbl_2_str(t),
+					    num_slices);
+				return -EINVAL;
+			}
+		}
 	}
 
 	memset(&db_cfg, 0, sizeof(db_cfg));
@@ -80,8 +96,8 @@  tf_tcam_bind(struct tf *tfp,
 	}
 
 	tcam_db = cparms.mem_va;
-	for (i = 0; i < TF_DIR_MAX; i++)
-		tcam_db->tcam_db[i] = NULL;
+	for (d = 0; d < TF_DIR_MAX; d++)
+		tcam_db->tcam_db[d] = NULL;
 	tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, tcam_db);
 
 	db_cfg.module = TF_MODULE_TYPE_TCAM;
@@ -90,7 +106,7 @@  tf_tcam_bind(struct tf *tfp,
 
 	for (d = 0; d < TF_DIR_MAX; d++) {
 		db_cfg.dir = d;
-		db_cfg.alloc_cnt = parms->resources->tcam_cnt[d].cnt;
+		db_cfg.alloc_cnt = tcam_cnt[d].cnt;
 		db_cfg.rm_db = (void *)&tcam_db->tcam_db[d];
 		if (tf_session_is_shared_session(tfs) &&
 			(!tf_session_is_shared_session_creator(tfs)))
@@ -98,53 +114,112 @@  tf_tcam_bind(struct tf *tfp,
 		else
 			db_rc[d] = tf_rm_create_db(tfp, &db_cfg);
 	}
-
 	/* No db created */
 	if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX]) {
 		TFP_DRV_LOG(ERR, "No TCAM DB created\n");
 		return db_rc[TF_DIR_RX];
 	}
 
-	/* check if reserved resource for WC is multiple of num_slices */
+	/* Collect info on which entries were reserved. */
 	for (d = 0; d < TF_DIR_MAX; d++) {
-		if (!tcam_db->tcam_db[d])
-			continue;
+		for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+			memset(&info, 0, sizeof(info));
+			if (tcam_cnt[d].cnt[t] == 0) {
+				resv_res[d][t].start  = 0;
+				resv_res[d][t].stride = 0;
+				continue;
+			}
+			ainfo.rm_db = tcam_db->tcam_db[d];
+			ainfo.subtype = t;
+			ainfo.info = &info;
+			rc = tf_rm_get_info(&ainfo);
+			if (rc)
+				goto error;
+
+			rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, t, 0,
+								  &num_slices);
+			if (rc)
+				return rc;
+
+			if (num_slices > 1) {
+				/* check if reserved resource for is multiple of
+				 * num_slices
+				 */
+				if (info.entry.start % num_slices != 0 ||
+				    info.entry.stride % num_slices != 0) {
+					TFP_DRV_LOG(ERR,
+						    "%s: %s reserved resource"
+						    " is not multiple of %d\n",
+						    tf_dir_2_str(d),
+						    tf_tcam_tbl_2_str(t),
+						    num_slices);
+					rc = -EINVAL;
+					goto error;
+				}
+			}
+
+			resv_res[d][t].start  = info.entry.start;
+			resv_res[d][t].stride = info.entry.stride;
+		}
+	}
 
-		memset(&info, 0, sizeof(info));
-		ainfo.rm_db = tcam_db->tcam_db[d];
-		ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
-		ainfo.info = &info;
-		rc = tf_rm_get_info(&ainfo);
-		if (rc)
-			goto error;
-
-		if (info.entry.start % num_slices != 0 ||
-		    info.entry.stride % num_slices != 0) {
-			TFP_DRV_LOG(ERR,
-				    "%s: TCAM reserved resource is not multiple of %d\n",
-				    tf_dir_2_str(d),
-				    num_slices);
-			rc = -EINVAL;
-			goto error;
+	rc = tf_tcam_mgr_bind_msg(tfp, dev, parms, resv_res);
+	if (rc)
+		return rc;
+
+	rc = tf_tcam_mgr_qcaps_msg(tfp, dev,
+				   &rx_supported, &tx_supported);
+	if (rc)
+		return rc;
+
+	for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+		if (rx_supported & 1 << t)
+			tfs->tcam_mgr_control[TF_DIR_RX][t] = 1;
+		if (tx_supported & 1 << t)
+			tfs->tcam_mgr_control[TF_DIR_TX][t] = 1;
+	}
+
+	/*
+	 * Make a local copy of tcam_cnt with only resources not managed by TCAM
+	 * Manager requested.
+	 */
+	memcpy(&local_tcam_cnt, tcam_cnt, sizeof(local_tcam_cnt));
+	tcam_cnt = local_tcam_cnt;
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		for (t = 0; t < TF_TCAM_TBL_TYPE_MAX; t++) {
+			/* If controlled by TCAM Manager */
+			if (tfs->tcam_mgr_control[d][t])
+				tcam_cnt[d].cnt[t] = 0;
+			else if (tcam_cnt[d].cnt[t] > 0)
+				no_req = false;
 		}
 	}
 
-	/* Initialize the TCAM manager. */
+	/* If no resources left to request */
+	if (no_req)
+		goto finished;
+
+finished:
 	TFP_DRV_LOG(INFO,
 		    "TCAM - initialized\n");
 
 	return 0;
 error:
-	for (i = 0; i < TF_DIR_MAX; i++) {
-		memset(&fparms, 0, sizeof(fparms));
-		fparms.dir = i;
-		fparms.rm_db = tcam_db->tcam_db[i];
-		/* Ignoring return here since we are in the error case */
-		(void)tf_rm_free_db(tfp, &fparms);
-		tcam_db->tcam_db[i] = NULL;
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		if (tcam_db->tcam_db[d] != NULL) {
+			memset(&fparms, 0, sizeof(fparms));
+			fparms.dir = d;
+			fparms.rm_db = tcam_db->tcam_db[d];
+			/*
+			 * Ignoring return here since we are in the error case
+			 */
+			(void)tf_rm_free_db(tfp, &fparms);
+
+			tcam_db->tcam_db[d] = NULL;
+		}
+		tcam_db->tcam_db[d] = NULL;
 		tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, NULL);
 	}
-
 	return rc;
 }
 
@@ -156,27 +231,43 @@  tf_tcam_unbind(struct tf *tfp)
 	struct tf_rm_free_db_parms fparms;
 	struct tcam_rm_db *tcam_db;
 	void *tcam_db_ptr = NULL;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
 	TF_CHECK_PARMS1(tfp);
 
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve the device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
-	if (rc) {
+	if (rc)
 		return 0;
-	}
+
 	tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
 
 	for (i = 0; i < TF_DIR_MAX; i++) {
-		if (tcam_db->tcam_db[i] == NULL)
-			continue;
-		memset(&fparms, 0, sizeof(fparms));
-		fparms.dir = i;
-		fparms.rm_db = tcam_db->tcam_db[i];
-		rc = tf_rm_free_db(tfp, &fparms);
-		if (rc)
-			return rc;
+		if (tcam_db->tcam_db[i] != NULL) {
+			memset(&fparms, 0, sizeof(fparms));
+			fparms.dir = i;
+			fparms.rm_db = tcam_db->tcam_db[i];
+			rc = tf_rm_free_db(tfp, &fparms);
+			if (rc)
+				return rc;
+
+			tcam_db->tcam_db[i] = NULL;
+		}
 
-		tcam_db->tcam_db[i] = NULL;
 	}
 
+	rc = tf_tcam_mgr_unbind_msg(tfp, dev);
+	if (rc)
+		return rc;
+
 	return 0;
 }
 
@@ -222,6 +313,9 @@  tf_tcam_alloc(struct tf *tfp,
 	if (rc)
 		return rc;
 
+	/* If TCAM controlled by TCAM Manager */
+	if (tfs->tcam_mgr_control[parms->dir][parms->type])
+		return tf_tcam_mgr_alloc_msg(tfp, dev, parms);
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -251,12 +345,8 @@  tf_tcam_alloc(struct tf *tfp,
 		}
 
 		/* return the start index of each row */
-		if (parms->priority == 0) {
 			if (i == 0)
 				parms->idx = index;
-		} else {
-			parms->idx = index;
-		}
 	}
 
 	return 0;
@@ -307,6 +397,14 @@  tf_tcam_free(struct tf *tfp,
 	if (rc)
 		return rc;
 
+	/* If TCAM controlled by TCAM Manager */
+	if (tfs->tcam_mgr_control[parms->dir][parms->type])
+		/*
+		 * If a session can have multiple references to an entry, check
+		 * the reference count here before actually freeing the entry.
+		 */
+		return tf_tcam_mgr_free_msg(tfp, dev, parms);
+
 	if (parms->idx % num_slices) {
 		TFP_DRV_LOG(ERR,
 			    "%s: TCAM reserved resource is not multiple of %d\n",
@@ -429,6 +527,10 @@  tf_tcam_set(struct tf *tfp __rte_unused,
 	if (rc)
 		return rc;
 
+	/* If TCAM controlled by TCAM Manager */
+	if (tfs->tcam_mgr_control[parms->dir][parms->type])
+		return tf_tcam_mgr_set_msg(tfp, dev, parms);
+
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -508,6 +610,10 @@  tf_tcam_get(struct tf *tfp __rte_unused,
 	if (rc)
 		return rc;
 
+	/* If TCAM controlled by TCAM Manager */
+	if (tfs->tcam_mgr_control[parms->dir][parms->type])
+		return tf_tcam_mgr_get_msg(tfp, dev, parms);
+
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c
new file mode 100644
index 0000000000..c535f4f4f6
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.c
@@ -0,0 +1,286 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#include <errno.h>
+
+#include "tfp.h"
+#include "tf_tcam.h"
+#include "cfa_tcam_mgr.h"
+#include "tf_tcam_mgr_msg.h"
+
+/*
+ * Table to convert TCAM type to logical TCAM type for applications.
+ * Index is tf_tcam_tbl_type.
+ */
+static enum cfa_tcam_mgr_tbl_type tcam_types[TF_TCAM_TBL_TYPE_MAX] = {
+	[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
+		CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS,
+	[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW]  =
+		CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS,
+	[TF_TCAM_TBL_TYPE_PROF_TCAM]	     =
+		CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS,
+	[TF_TCAM_TBL_TYPE_WC_TCAM]	     =
+		CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
+	[TF_TCAM_TBL_TYPE_SP_TCAM]	     =
+		CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS,
+	[TF_TCAM_TBL_TYPE_CT_RULE_TCAM]	     =
+		CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS,
+	[TF_TCAM_TBL_TYPE_VEB_TCAM]	     =
+		CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS,
+	[TF_TCAM_TBL_TYPE_WC_TCAM_HIGH]      =
+		CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
+	[TF_TCAM_TBL_TYPE_WC_TCAM_LOW]       =
+		CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
+};
+
+static uint16_t hcapi_type[TF_TCAM_TBL_TYPE_MAX];
+
+/*
+ * This is the glue between the core tf_tcam and the TCAM manager.  It is
+ * intended to abstract out the location of the TCAM manager so that the core
+ * code will be the same if the TCAM manager is in the core or in firmware.
+ *
+ * If the TCAM manager is in the core, then this file will just translate to
+ * TCAM manager APIs.  If TCAM manager is in firmware, then this file will cause
+ * messages to be sent (except for bind and unbind).
+ */
+
+int
+tf_tcam_mgr_qcaps_msg(struct tf *tfp,
+		      struct tf_dev_info *dev __rte_unused,
+		      uint32_t *rx_tcam_supported,
+		      uint32_t *tx_tcam_supported)
+{
+	struct cfa_tcam_mgr_context   context;
+	struct cfa_tcam_mgr_qcaps_parms mgr_parms;
+	int rc;
+
+	context.tfp = tfp;
+	memset(&mgr_parms, 0, sizeof(mgr_parms));
+	rc = cfa_tcam_mgr_qcaps(&context, &mgr_parms);
+	if (rc >= 0) {
+		*rx_tcam_supported = mgr_parms.rx_tcam_supported;
+		*tx_tcam_supported = mgr_parms.tx_tcam_supported;
+	}
+	return rc;
+}
+
+int
+tf_tcam_mgr_bind_msg(struct tf *tfp,
+		     struct tf_dev_info *dev __rte_unused,
+		     struct tf_tcam_cfg_parms *parms,
+		     struct tf_resource_info resv_res[][TF_TCAM_TBL_TYPE_MAX]
+		     __rte_unused
+	)
+{
+	/* Common Code */
+	int type;
+
+	if (parms->num_elements != TF_TCAM_TBL_TYPE_MAX) {
+		TFP_DRV_LOG(ERR,
+			    "Invalid number of elements in bind request.\n");
+		TFP_DRV_LOG(ERR,
+			    "Expected %d, received %d.\n",
+			    TF_TCAM_TBL_TYPE_MAX,
+			    parms->num_elements);
+		return -EINVAL;
+	}
+
+	for (type = 0; type < TF_TCAM_TBL_TYPE_MAX; type++)
+		hcapi_type[type] = parms->cfg[type].hcapi_type;
+
+	struct cfa_tcam_mgr_context   context;
+	struct cfa_tcam_mgr_cfg_parms mgr_parms;
+	struct tf_rm_resc_entry
+		mgr_resv_res[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
+	int dir, rc;
+
+	context.tfp = tfp;
+
+	memset(&mgr_parms, 0, sizeof(mgr_parms));
+
+	mgr_parms.num_elements = CFA_TCAM_MGR_TBL_TYPE_MAX;
+
+	/* Convert the data to logical tables */
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		for (type = 0; type < TF_TCAM_TBL_TYPE_MAX; type++) {
+			mgr_parms.tcam_cnt[dir][tcam_types[type]] =
+				parms->resources->tcam_cnt[dir].cnt[type];
+			mgr_resv_res[dir][tcam_types[type]].start =
+				resv_res[dir][type].start;
+			mgr_resv_res[dir][tcam_types[type]].stride =
+				resv_res[dir][type].stride;
+		}
+	}
+	mgr_parms.resv_res = mgr_resv_res;
+
+	rc = cfa_tcam_mgr_bind(&context, &mgr_parms);
+
+	return rc;
+}
+
+int
+tf_tcam_mgr_unbind_msg(struct tf *tfp,
+		       struct tf_dev_info *dev __rte_unused)
+{
+	struct cfa_tcam_mgr_context context;
+
+	context.tfp = tfp;
+
+	return cfa_tcam_mgr_unbind(&context);
+}
+
+int
+tf_tcam_mgr_alloc_msg(struct tf *tfp,
+		      struct tf_dev_info *dev __rte_unused,
+		      struct tf_tcam_alloc_parms *parms)
+{
+	struct cfa_tcam_mgr_context context;
+	struct cfa_tcam_mgr_alloc_parms mgr_parms;
+	int rc;
+
+	if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+		TFP_DRV_LOG(ERR,
+			    "No such TCAM table %d.\n",
+			    parms->type);
+		return -EINVAL;
+	}
+
+	context.tfp = tfp;
+
+	mgr_parms.dir	     = parms->dir;
+	mgr_parms.type	     = tcam_types[parms->type];
+	mgr_parms.hcapi_type = hcapi_type[parms->type];
+	mgr_parms.key_size   = parms->key_size;
+	if (parms->priority > TF_TCAM_PRIORITY_MAX)
+		mgr_parms.priority = 0;
+	else
+		mgr_parms.priority = TF_TCAM_PRIORITY_MAX - parms->priority - 1;
+
+	rc = cfa_tcam_mgr_alloc(&context, &mgr_parms);
+	if (rc)
+		return rc;
+
+	parms->idx = mgr_parms.id;
+	return 0;
+}
+
+int
+tf_tcam_mgr_free_msg(struct tf *tfp,
+		     struct tf_dev_info *dev __rte_unused,
+		     struct tf_tcam_free_parms *parms)
+{
+	struct cfa_tcam_mgr_context context;
+	struct cfa_tcam_mgr_free_parms mgr_parms;
+
+	if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+		TFP_DRV_LOG(ERR,
+			    "No such TCAM table %d.\n",
+			    parms->type);
+		return -EINVAL;
+	}
+
+	context.tfp = tfp;
+	mgr_parms.dir	     = parms->dir;
+	mgr_parms.type	     = tcam_types[parms->type];
+	mgr_parms.hcapi_type = hcapi_type[parms->type];
+	mgr_parms.id	     = parms->idx;
+
+	return cfa_tcam_mgr_free(&context, &mgr_parms);
+}
+
+int
+tf_tcam_mgr_set_msg(struct tf *tfp,
+		    struct tf_dev_info *dev __rte_unused,
+		    struct tf_tcam_set_parms *parms)
+{
+	struct cfa_tcam_mgr_context context;
+	struct cfa_tcam_mgr_set_parms mgr_parms;
+
+	if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+		TFP_DRV_LOG(ERR,
+			    "No such TCAM table %d.\n",
+			    parms->type);
+		return -EINVAL;
+	}
+
+	context.tfp = tfp;
+	mgr_parms.dir	      = parms->dir;
+	mgr_parms.type	      = tcam_types[parms->type];
+	mgr_parms.hcapi_type  = hcapi_type[parms->type];
+	mgr_parms.id	      = parms->idx;
+	mgr_parms.key	      = parms->key;
+	mgr_parms.mask	      = parms->mask;
+	mgr_parms.key_size    = parms->key_size;
+	mgr_parms.result      = parms->result;
+	mgr_parms.result_size = parms->result_size;
+
+	return cfa_tcam_mgr_set(&context, &mgr_parms);
+}
+
+int
+tf_tcam_mgr_get_msg(struct tf *tfp,
+		    struct tf_dev_info *dev __rte_unused,
+		    struct tf_tcam_get_parms *parms)
+{
+	int rc;
+	struct cfa_tcam_mgr_context context;
+	struct cfa_tcam_mgr_get_parms mgr_parms;
+
+	if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
+		TFP_DRV_LOG(ERR,
+			    "No such TCAM table %d.\n",
+			    parms->type);
+		return -EINVAL;
+	}
+
+	context.tfp = tfp;
+	mgr_parms.dir	      = parms->dir;
+	mgr_parms.type	      = tcam_types[parms->type];
+	mgr_parms.hcapi_type  = hcapi_type[parms->type];
+	mgr_parms.id	      = parms->idx;
+	mgr_parms.key	      = parms->key;
+	mgr_parms.mask	      = parms->mask;
+	mgr_parms.key_size    = parms->key_size;
+	mgr_parms.result      = parms->result;
+	mgr_parms.result_size = parms->result_size;
+
+	rc = cfa_tcam_mgr_get(&context, &mgr_parms);
+	if (rc)
+		return rc;
+
+	parms->key_size	   = mgr_parms.key_size;
+	parms->result_size = mgr_parms.result_size;
+
+	return rc;
+}
+
+int
+tf_tcam_mgr_shared_clear_msg(struct tf *tfp,
+		     struct tf_clear_tcam_shared_entries_parms *parms)
+{
+	struct cfa_tcam_mgr_context context;
+	struct cfa_tcam_mgr_shared_clear_parms mgr_parms;
+
+	context.tfp = tfp;
+	mgr_parms.dir = parms->dir;
+	mgr_parms.type = tcam_types[parms->tcam_tbl_type];
+
+	return cfa_tcam_mgr_shared_clear(&context, &mgr_parms);
+}
+
+int
+tf_tcam_mgr_shared_move_msg(struct tf *tfp,
+		     struct tf_move_tcam_shared_entries_parms *parms)
+{
+	struct cfa_tcam_mgr_context context;
+	struct cfa_tcam_mgr_shared_move_parms mgr_parms;
+
+	context.tfp = tfp;
+	mgr_parms.dir = parms->dir;
+	mgr_parms.type = tcam_types[parms->tcam_tbl_type];
+
+	return cfa_tcam_mgr_shared_move(&context, &mgr_parms);
+}
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h
new file mode 100644
index 0000000000..8a8d136f5e
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_tcam_mgr_msg.h
@@ -0,0 +1,49 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2023 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_TCAM_MGR_MSG_H_
+#define _TF_TCAM_MGR_MSG_H_
+
+#include "tf_tcam.h"
+#include "tf_rm.h"
+
+int
+tf_tcam_mgr_qcaps_msg(struct tf *tfp,
+		      struct tf_dev_info *dev __rte_unused,
+		      uint32_t *rx_tcam_supported,
+		      uint32_t *tx_tcam_supported);
+
+int
+tf_tcam_mgr_bind_msg(struct tf *tfp,
+		     struct tf_dev_info *dev,
+		     struct tf_tcam_cfg_parms *parms,
+		     struct tf_resource_info resv_res[][TF_TCAM_TBL_TYPE_MAX]);
+int
+tf_tcam_mgr_unbind_msg(struct tf *tfp,
+		       struct tf_dev_info *dev);
+int
+tf_tcam_mgr_alloc_msg(struct tf *tfp,
+		      struct tf_dev_info *dev,
+		      struct tf_tcam_alloc_parms *parms);
+int
+tf_tcam_mgr_free_msg(struct tf *tfp,
+		     struct tf_dev_info *dev,
+		     struct tf_tcam_free_parms *parms);
+int
+tf_tcam_mgr_set_msg(struct tf *tfp,
+		    struct tf_dev_info *dev,
+		    struct tf_tcam_set_parms *parms);
+int
+tf_tcam_mgr_get_msg(struct tf *tfp,
+		    struct tf_dev_info *dev,
+		    struct tf_tcam_get_parms *parms);
+int
+tf_tcam_mgr_shared_clear_msg(struct tf *tfp,
+		     struct tf_clear_tcam_shared_entries_parms *parms);
+
+int
+tf_tcam_mgr_shared_move_msg(struct tf *tfp,
+		     struct tf_move_tcam_shared_entries_parms *parms);
+#endif /* _TF_TCAM_MGR_MSG_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.c b/drivers/net/bnxt/tf_core/tf_tcam_shared.c
index c120c6f577..e853f616f9 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam_shared.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.c
@@ -1,11 +1,13 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
 #include <string.h>
 #include <rte_common.h>
 
+#include "tf_core.h"
+
 #include "tf_tcam_shared.h"
 #include "tf_tcam.h"
 #include "tf_common.h"
@@ -16,229 +18,8 @@ 
 #include "tf_session.h"
 #include "tf_msg.h"
 #include "bitalloc.h"
-#include "tf_core.h"
-
-/** 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;
-};
-
-struct tf_tcam_shared_wc_pools {
-	struct tf_tcam_shared_wc_pool db[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX];
-};
-
-/** The WC TCAM shared pool declarations
- */
-/* struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX]; */
-
-static int
-tf_tcam_shared_create_db(struct tf_tcam_shared_wc_pools **db)
-{
-	struct tfp_calloc_parms cparms;
-	int rc = 0;
-
-	cparms.nitems = 1;
-	cparms.alignment = 0;
-	cparms.size = sizeof(struct tf_tcam_shared_wc_pools);
-	rc = tfp_calloc(&cparms);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "TCAM shared db allocation failed (%s)\n",
-			    strerror(-rc));
-		return rc;
-	}
-	*db = cparms.mem_va;
-
-	return rc;
-}
-
-/** 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,
-			      struct tf_tcam_shared_wc_pools *tcam_shared_wc)
-{
-	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->db[dir][id].pool = (struct bitalloc *)cparms.mem_va;
-
-	rc = ba_init(tcam_shared_wc->db[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->db[dir][id].info.start = start;
-	tcam_shared_wc->db[dir][id].info.stride = stride;
-
-	return rc;
-}
-/** Free a WC TCAM shared pool
- */
-static int
-tf_tcam_shared_free_wc_pool(int dir,
-			    enum tf_tcam_shared_wc_pool_id id,
-			    struct tf_tcam_shared_wc_pools *tcam_shared_wc)
-{
-	int rc = 0;
-	TF_CHECK_PARMS1(tcam_shared_wc);
-
-	tcam_shared_wc->db[dir][id].info.start = 0;
-	tcam_shared_wc->db[dir][id].info.stride = 0;
-
-	if (tcam_shared_wc->db[dir][id].pool)
-		tfp_free((void *)tcam_shared_wc->db[dir][id].pool);
-	return rc;
-}
-
-/** 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_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;
-}
+#include "tf_rm.h"
+#include "tf_tcam_mgr_msg.h"
 
 /**
  * tf_tcam_shared_bind
@@ -247,92 +28,15 @@  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;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc = NULL;
+	int rc;
 
 	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;
-
-		tf_tcam_shared_create_db(&tcam_shared_wc);
-
-
-		/* 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_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,
-						      tcam_shared_wc);
-
-			start += stride;
-			tf_tcam_shared_create_wc_pool(dir,
-						      TF_TCAM_SHARED_WC_POOL_LO,
-						      start,
-						      stride,
-						      tcam_shared_wc);
-
-			tf_session_set_tcam_shared_db(tfp, (void *)tcam_shared_wc);
-		}
-
-		rc = tf_tcam_shared_get_slices(tfp,
-					       dev,
-					       &num_slices);
-		if (rc)
-			return rc;
-
-		if (num_slices > 1) {
-			TFP_DRV_LOG(ERR,
-				    "Only single slice supported\n");
-			return -EOPNOTSUPP;
-		}
-	}
-done:
 	return rc;
+
 }
 /**
  * tf_tcam_shared_unbind
@@ -340,132 +44,10 @@  tf_tcam_shared_bind(struct tf *tfp,
 int
 tf_tcam_shared_unbind(struct tf *tfp)
 {
-	int rc, dir;
-	struct tf_dev_info *dev;
-	struct tf_session *tfs;
-	void *tcam_shared_db_ptr = NULL;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
-	enum tf_tcam_shared_wc_pool_id pool_id;
-	struct tf_tcam_free_parms parms;
-	struct bitalloc *pool;
-	uint16_t start;
-	int log_idx, phy_idx;
-	uint16_t hcapi_type;
-	struct tf_rm_alloc_info info;
-	int i, pool_cnt;
+	int rc;
 
 	TF_CHECK_PARMS1(tfp);
 
-	/* Retrieve the session information */
-	rc = tf_session_get_session_internal(tfp, &tfs);
-	if (rc)
-		return rc;
-
-	/* If not the shared session, call the normal
-	 * tcam unbind and exit
-	 */
-	if (!tf_session_is_shared_session(tfs)) {
-		rc = tf_tcam_unbind(tfp);
-		return rc;
-	}
-
-	/* We must be a shared session, get the database
-	 */
-	rc = tf_session_get_tcam_shared_db(tfp,
-					   (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-
-	tcam_shared_wc =
-		(struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-
-	/* Get the device
-	 */
-	rc = tf_session_get_device(tfs, &dev);
-	if (rc)
-		return rc;
-
-
-	/* If there are WC TCAM entries allocated, free them
-	 */
-	for (dir = 0; dir < TF_DIR_MAX; dir++) {
-		/* If the database is invalid, skip
-		 */
-		if (!tf_tcam_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 shared rm info get failed\n",
-				    tf_dir_2_str(dir));
-			return rc;
-		}
-
-		for (pool_id = TF_TCAM_SHARED_WC_POOL_HI;
-		     pool_id < TF_TCAM_SHARED_WC_POOL_MAX;
-		     pool_id++) {
-			pool = tcam_shared_wc->db[dir][pool_id].pool;
-			start = tcam_shared_wc->db[dir][pool_id].info.start;
-			pool_cnt = ba_inuse_count(pool);
-
-			if (pool_cnt) {
-				TFP_DRV_LOG(INFO,
-					    "%s: %s: %d residuals found, freeing\n",
-					    tf_dir_2_str(dir),
-					    tf_pool_2_str(pool_id),
-					    pool_cnt);
-			}
-
-			log_idx = 0;
-
-			for (i = 0; i < pool_cnt; i++) {
-				log_idx = ba_find_next_inuse(pool, log_idx);
-
-				if (log_idx < 0) {
-					TFP_DRV_LOG(ERR,
-						    "Expected a found %s entry %d\n",
-						    tf_pool_2_str(pool_id),
-						    i);
-					/* attempt normal unbind
-					 */
-					goto done;
-				}
-				phy_idx = start + log_idx;
-
-				parms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
-				parms.hcapi_type = hcapi_type;
-				parms.idx = phy_idx;
-				parms.dir = dir;
-				rc = tf_msg_tcam_entry_free(tfp, dev, &parms);
-				if (rc) {
-					/* Log error */
-					TFP_DRV_LOG(ERR,
-						    "%s: %s: %d free failed, rc:%s\n",
-						    tf_dir_2_str(parms.dir),
-						    tf_tcam_tbl_2_str(parms.type),
-						    phy_idx,
-						    strerror(-rc));
-					return rc;
-				}
-			}
-			/* Free the pool once all the entries
-			 * have been cleared
-			 */
-			tf_tcam_shared_free_wc_pool(dir,
-						    pool_id,
-						    tcam_shared_wc);
-		}
-	}
-done:
 	rc = tf_tcam_unbind(tfp);
 	return rc;
 }
@@ -478,79 +60,11 @@  tf_tcam_shared_alloc(struct tf *tfp,
 		     struct tf_tcam_alloc_parms *parms)
 {
 	int rc;
-	struct tf_session *tfs;
-	struct tf_dev_info *dev;
-	int log_idx;
-	struct bitalloc *pool;
-	enum tf_tcam_shared_wc_pool_id id;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
-	void *tcam_shared_db_ptr = NULL;
 
 	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_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;
-	}
-
-	rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db from session, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-	tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-	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;
-
-	pool = tcam_shared_wc->db[parms->dir][id].pool;
-
-	/*
-	 * 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;
-	}
-	parms->idx = log_idx;
-	return 0;
+	rc = tf_tcam_alloc(tfp, parms);
+	return rc;
 }
 
 int
@@ -558,118 +72,11 @@  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;
-	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 hcapi_type;
-	struct tf_rm_alloc_info info;
-	void *tcam_shared_db_ptr = NULL;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
 
 	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_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;
-	}
-
-	rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db from session, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-	tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-
-	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_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->db[parms->dir][id].pool;
-	start = tcam_shared_wc->db[parms->dir][id].info.start;
-
-	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;
-	}
-
-	rc = ba_free(pool, parms->idx);
-	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;
+	rc = tf_tcam_free(tfp, parms);
+	return rc;
 }
 
 int
@@ -677,109 +84,11 @@  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;
-	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;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
-	void *tcam_shared_db_ptr = NULL;
-
 
 	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_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;
-
-	rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db from session, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-	tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-	pool = tcam_shared_wc->db[parms->dir][id].pool;
-	start = tcam_shared_wc->db[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_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;
+	rc = tf_tcam_set(tfp, parms);
+	return rc;
 }
 
 int
@@ -787,226 +96,10 @@  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;
-	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;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
-	void *tcam_shared_db_ptr = NULL;
 
 	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_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;
-
-
-	rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db from session, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-	tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-	pool = tcam_shared_wc->db[parms->dir][id].pool;
-	start = tcam_shared_wc->db[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_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;
-}
-
-/* Normally, device specific code wouldn't reside here, it belongs
- * in a separate device specific function in tf_device_pxx.c.
- * But this code is placed here as it is not a long term solution
- * and we would like to have this code centrally located for easy
- * removal
- */
-#define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4 12
-#define TF_TCAM_SHARED_REMAP_SZ_BYTES_P4 4
-#define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 24
-#define TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 8
-
-/* Temporary builder defines pulled in here and adjusted
- * for max WC TCAM values
- */
-union tf_tmp_field_obj {
-	uint32_t words[(TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 + 3) / 4];
-	uint8_t bytes[TF_TCAM_SHARED_REMAP_SZ_BYTES_P58];
-};
-
-union tf_tmp_key {
-	uint32_t words[(TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 + 3) / 4];
-	uint8_t bytes[TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58];
-};
-
-/** p58 has an enable bit, p4 does not
- */
-#define TF_TCAM_SHARED_ENTRY_ENABLE 0x8
-
-/** Move a WC TCAM entry from the high offset to the same low offset
- */
-static int
-tf_tcam_shared_move_entry(struct tf *tfp,
-			  struct tf_dev_info *dev,
-			  uint16_t hcapi_type,
-			  enum tf_dir dir,
-			  int sphy_idx,
-			  int dphy_idx,
-			  int key_sz_bytes,
-			  int remap_sz_bytes,
-			  bool set_enable_bit)
-{
-	int rc = 0;
-	struct tf_tcam_get_parms gparms;
-	struct tf_tcam_set_parms sparms;
-	struct tf_tcam_free_parms fparms;
-	union tf_tmp_key tcam_key_obj;
-	union tf_tmp_key tcam_key_msk_obj;
-	union tf_tmp_field_obj tcam_remap_obj;
-
-	memset(&tcam_key_obj, 0, sizeof(tcam_key_obj));
-	memset(&tcam_key_msk_obj, 0, sizeof(tcam_key_msk_obj));
-	memset(&tcam_remap_obj, 0, sizeof(tcam_remap_obj));
-	memset(&gparms, 0, sizeof(gparms));
-
-	gparms.hcapi_type = hcapi_type;
-	gparms.dir = dir;
-	gparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
-	gparms.idx = sphy_idx;
-	gparms.key = (uint8_t *)&tcam_key_obj;
-	gparms.key_size = key_sz_bytes;
-	gparms.mask = (uint8_t *)&tcam_key_msk_obj;
-	gparms.result = (uint8_t *)&tcam_remap_obj;
-	gparms.result_size = remap_sz_bytes;
-
-	rc = tf_msg_tcam_entry_get(tfp, dev, &gparms);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s: %s: phyid(%d) get failed, rc:%s\n",
-			    tf_tcam_tbl_2_str(gparms.type),
-			    tf_dir_2_str(dir),
-			    gparms.idx,
-			    strerror(-rc));
-		return rc;
-	}
-
-	if (set_enable_bit)
-		tcam_key_obj.bytes[0] |= TF_TCAM_SHARED_ENTRY_ENABLE;
-
-	/* Override HI/LO type with parent WC TCAM type */
-	sparms.hcapi_type = hcapi_type;
-	sparms.dir = dir;
-	sparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
-	sparms.idx = dphy_idx;
-	sparms.key = gparms.key;
-	sparms.mask = gparms.mask;
-	sparms.key_size = key_sz_bytes;
-	sparms.result = gparms.result;
-	sparms.result_size = remap_sz_bytes;
-
-	rc = tf_msg_tcam_entry_set(tfp, dev, &sparms);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s: %s phyid(%d/0x%x) set failed, rc:%s\n",
-			    tf_tcam_tbl_2_str(sparms.type),
-			    tf_dir_2_str(dir),
-			    sparms.idx,
-			    sparms.idx,
-			    strerror(-rc));
-		return rc;
-	}
-
-	/* Override HI/LO type with parent WC TCAM type */
-	fparms.dir = dir;
-	fparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
-	fparms.hcapi_type = hcapi_type;
-	fparms.idx = sphy_idx;
-
-	rc = tf_msg_tcam_entry_free(tfp, dev, &fparms);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s: %s: phyid(%d/0x%x) free failed, rc:%s\n",
-			    tf_dir_2_str(dir),
-			    tf_tcam_tbl_2_str(fparms.type),
-			    sphy_idx,
-			    sphy_idx,
-			    strerror(-rc));
-		return rc;
-	}
+	rc = tf_tcam_get(tfp, parms);
 	return rc;
 }
 
@@ -1015,23 +108,10 @@  tf_tcam_shared_move_entry(struct tf *tfp,
  */
 static
 int tf_tcam_shared_move(struct tf *tfp,
-			struct tf_move_tcam_shared_entries_parms *parms,
-			int key_sz_bytes,
-			int remap_sz_bytes,
-			bool set_enable_bit)
+			struct tf_move_tcam_shared_entries_parms *parms)
 {
-	int rc;
 	struct tf_session *tfs;
-	struct tf_dev_info *dev;
-	int log_idx;
-	struct bitalloc *hi_pool, *lo_pool;
-	uint16_t hi_start, lo_start;
-	enum tf_tcam_shared_wc_pool_id hi_id, lo_id;
-	uint16_t hcapi_type;
-	struct tf_rm_alloc_info info;
-	int hi_cnt, i;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
-	void *tcam_shared_db_ptr = NULL;
+	int rc;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -1052,104 +132,7 @@  int tf_tcam_shared_move(struct tf *tfp,
 		return -EOPNOTSUPP;
 	}
 
-	if (!tf_tcam_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) {
-		/* TODO print amazing error */
-		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;
-	}
-
-	rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db from session, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-	tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-	hi_id = TF_TCAM_SHARED_WC_POOL_HI;
-	hi_pool = tcam_shared_wc->db[parms->dir][hi_id].pool;
-	hi_start = tcam_shared_wc->db[parms->dir][hi_id].info.start;
-
-	lo_id = TF_TCAM_SHARED_WC_POOL_LO;
-	lo_pool = tcam_shared_wc->db[parms->dir][lo_id].pool;
-	lo_start = tcam_shared_wc->db[parms->dir][lo_id].info.start;
-
-	if (hi_pool == NULL || lo_pool == NULL)
-		return -ENOMEM;
-
-	/* Get the total count of in use entries in the high pool
-	 */
-	hi_cnt = ba_inuse_count(hi_pool);
-
-	/* Copy each valid entry to the same low pool logical offset
-	 */
-	log_idx = 0;
-
-	for (i = 0; i < hi_cnt; i++) {
-		/* Find next free index starting from where we left off
-		 */
-		log_idx = ba_find_next_inuse(hi_pool, log_idx);
-		if (log_idx < 0) {
-			TFP_DRV_LOG(ERR,
-				    "Expected a found %s entry %d\n",
-				    tf_pool_2_str(hi_id),
-				    i);
-			goto done;
-		}
-		/* The user should have never allocated from the low
-		 * pool because the move only happens when switching
-		 * from the high to the low pool
-		 */
-		if (ba_alloc_index(lo_pool, log_idx) < 0) {
-			TFP_DRV_LOG(ERR,
-				    "Warning %s index %d already allocated\n",
-				    tf_pool_2_str(lo_id),
-				    i);
-
-			/* Since already allocated, continue with move
-			 */
-		}
-
-		rc = tf_tcam_shared_move_entry(tfp, dev,
-					       hcapi_type,
-					       parms->dir,
-					       hi_start + log_idx,
-					       lo_start + log_idx,
-					       key_sz_bytes,
-					       remap_sz_bytes,
-					       set_enable_bit);
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "%s: Move error %s to %s index %d\n",
-				    tf_dir_2_str(parms->dir),
-				    tf_pool_2_str(hi_id),
-				    tf_pool_2_str(lo_id),
-				    i);
-			goto done;
-		}
-		ba_free(hi_pool, log_idx);
-	}
-done:
+	rc = tf_tcam_mgr_shared_move_msg(tfp, parms);
 	return rc;
 }
 
@@ -1159,24 +142,17 @@  tf_tcam_shared_move_p4(struct tf *tfp,
 {
 	int rc = 0;
 	rc = tf_tcam_shared_move(tfp,
-				 parms,
-				 TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4,
-				 TF_TCAM_SHARED_REMAP_SZ_BYTES_P4,
-				 false); /* no enable bit */
+				 parms);
 	return rc;
 }
 
-
 int
 tf_tcam_shared_move_p58(struct tf *tfp,
 			struct tf_move_tcam_shared_entries_parms *parms)
 {
 	int rc = 0;
 	rc = tf_tcam_shared_move(tfp,
-				 parms,
-				 TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58,
-				 TF_TCAM_SHARED_REMAP_SZ_BYTES_P58,
-				 true); /* set enable bit */
+				 parms);
 	return rc;
 }
 
@@ -1186,16 +162,6 @@  tf_tcam_shared_clear(struct tf *tfp,
 {
 	int rc = 0;
 	struct tf_session *tfs;
-	struct tf_dev_info *dev;
-	uint16_t start;
-	int phy_idx;
-	enum tf_tcam_shared_wc_pool_id id;
-	struct tf_tcam_free_parms nparms;
-	uint16_t hcapi_type;
-	struct tf_rm_alloc_info info;
-	void *tcam_shared_db_ptr = NULL;
-	struct tf_tcam_shared_wc_pools *tcam_shared_wc;
-	int i, cnt;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -1209,74 +175,6 @@  tf_tcam_shared_clear(struct tf *tfp,
 	     parms->tcam_tbl_type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW))
 		return -EOPNOTSUPP;
 
-	if (!tf_tcam_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;
-	}
-
-	rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Failed to get tcam_shared_db from session, rc:%s\n",
-			    strerror(-rc));
-		return rc;
-	}
-	tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
-
-
-	if (parms->tcam_tbl_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_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;
-	}
-
-	start = tcam_shared_wc->db[parms->dir][id].info.start;
-	cnt = tcam_shared_wc->db[parms->dir][id].info.stride;
-
-	/* Override HI/LO type with parent WC TCAM type */
-	nparms.dir = parms->dir;
-	nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
-	nparms.hcapi_type = hcapi_type;
-
-	for (i = 0; i < cnt; i++) {
-		phy_idx = start + i;
-		nparms.idx = phy_idx;
-
-		/* Clear entry */
-		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;
-		}
-	}
-
-	TFP_DRV_LOG(DEBUG,
-		    "%s: TCAM shared clear pool(%s)\n",
-		    tf_dir_2_str(nparms.dir),
-		    tf_pool_2_str(id));
-	return 0;
+	rc = tf_tcam_mgr_shared_clear_msg(tfp, parms);
+	return rc;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.h b/drivers/net/bnxt/tf_core/tf_tcam_shared.h
index 524631f262..e25babcd18 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam_shared.h
+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.h
@@ -1,5 +1,5 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2021 Broadcom
+ * Copyright(c) 2019-2023 Broadcom
  * All rights reserved.
  */
 
@@ -129,7 +129,6 @@  int tf_tcam_shared_set(struct tf *tfp,
 int tf_tcam_shared_get(struct tf *tfp,
 		       struct tf_tcam_get_parms *parms);
 
-
 /**
  * Moves entries from the WC_TCAM_HI to the WC_TCAM_LO shared pools
  * for the P4 device.
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 1bb38399e4..8513ee06a9 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -448,13 +448,13 @@  ulp_ctx_shared_session_open(struct bnxt *bp,
 
 	switch (ulp_dev_id) {
 	case BNXT_ULP_DEVICE_ID_WH_PLUS:
-		parms.device_type = TF_DEVICE_TYPE_WH;
+		parms.device_type = TF_DEVICE_TYPE_P5;
 		break;
 	case BNXT_ULP_DEVICE_ID_STINGRAY:
 		parms.device_type = TF_DEVICE_TYPE_SR;
 		break;
 	case BNXT_ULP_DEVICE_ID_THOR:
-		parms.device_type = TF_DEVICE_TYPE_THOR;
+		parms.device_type = TF_DEVICE_TYPE_P4;
 		break;
 	default:
 		BNXT_TF_DBG(ERR, "Unable to determine dev for opening session.\n");
@@ -563,13 +563,13 @@  ulp_ctx_session_open(struct bnxt *bp,
 
 	switch (ulp_dev_id) {
 	case BNXT_ULP_DEVICE_ID_WH_PLUS:
-		params.device_type = TF_DEVICE_TYPE_WH;
+		params.device_type = TF_DEVICE_TYPE_P5;
 		break;
 	case BNXT_ULP_DEVICE_ID_STINGRAY:
 		params.device_type = TF_DEVICE_TYPE_SR;
 		break;
 	case BNXT_ULP_DEVICE_ID_THOR:
-		params.device_type = TF_DEVICE_TYPE_THOR;
+		params.device_type = TF_DEVICE_TYPE_P4;
 		break;
 	default:
 		BNXT_TF_DBG(ERR, "Unable to determine device for opening session.\n");