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

Message ID 20230504173612.17696-5-ajit.khaparde@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

Ajit Khaparde May 4, 2023, 5:36 p.m. UTC
  From: Randy Schacher <stuart.schacher@broadcom.com>

Update TruFlow core code to:
- Add shared session management
- Add SRAM session management
- Add dynamic TCAM management
- Add shared TCAM session management
- Add Hot Upgrade support
- Update copyright year

Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Shahaji Bhosle <sbhosle@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@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
  

Comments

Thomas Monjalon June 10, 2023, 6:32 p.m. UTC | #1
04/05/2023 19:36, Ajit Khaparde:
> From: Randy Schacher <stuart.schacher@broadcom.com>
> 
> Update TruFlow core code to:
> - Add shared session management
> - Add SRAM session management
> - Add dynamic TCAM management
> - Add shared TCAM session management
> - Add Hot Upgrade support
> - Update copyright year

I suppose you can update the date in the previous patch
for the whole driver.

Also this patch is removing some blank lines out of Truflow.
And I don't understand the need for removing the blank lines
before the last #ifdef of the file.

More important, you are doing huge update of many different things
in one patch.
It looks like you don't want the community to follow what you are doing.

For info, there are other things to fix in this patchset:
Error: Incorrect indent at drivers/net/bnxt/tf_ulp/generic_templates/meson.build
rte_flow doc out of sync for bnxt
        action set_mac_dst
        action set_mac_src
You can run the following script to catch these issues:
	devtools/check-meson.py
	devtools/check-doc-vs-code.sh
  
Ajit Khaparde June 28, 2023, 4:35 p.m. UTC | #2
On Sat, Jun 10, 2023 at 11:33 AM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> 04/05/2023 19:36, Ajit Khaparde:
> > From: Randy Schacher <stuart.schacher@broadcom.com>
> >
> > Update TruFlow core code to:
> > - Add shared session management
> > - Add SRAM session management
> > - Add dynamic TCAM management
> > - Add shared TCAM session management
> > - Add Hot Upgrade support
> > - Update copyright year
>
> I suppose you can update the date in the previous patch
> for the whole driver.
To some extent the idea was to update the date in the patch when the
code change was happening, instead of a blanket date change.

>
> Also this patch is removing some blank lines out of Truflow.
> And I don't understand the need for removing the blank lines
> before the last #ifdef of the file.
The template files are auto generated using a bunch of scripts.
What we are seeing is probably because of that.
But we have cleaned up many of those in the v4 submission.

>
> More important, you are doing huge update of many different things
> in one patch.
> It looks like you don't want the community to follow what you are doing.
Actually, no.
As I mentioned above, most of the truflow files are auto generated.
The reason for bundling some of the changes together was to avoid
multiple patches hitting the mail server patch size limit.
We thought it might be better to take the patch size hit on one patch
instead of multiple patches.

We are working on some design changes to the auto generation scripts
which will avoid big churn in the template patches in the future.

>
> For info, there are other things to fix in this patchset:
> Error: Incorrect indent at drivers/net/bnxt/tf_ulp/generic_templates/meson.build
> rte_flow doc out of sync for bnxt
>         action set_mac_dst
>         action set_mac_src
> You can run the following script to catch these issues:
>         devtools/check-meson.py
>         devtools/check-doc-vs-code.sh
We have addressed these in the v4 version.

Thanks
>
>
>
  
Thomas Monjalon June 28, 2023, 7:07 p.m. UTC | #3
28/06/2023 18:35, Ajit Khaparde:
> On Sat, Jun 10, 2023 at 11:33 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > More important, you are doing huge update of many different things
> > in one patch.
> > It looks like you don't want the community to follow what you are doing.
> Actually, no.
> As I mentioned above, most of the truflow files are auto generated.
> The reason for bundling some of the changes together was to avoid
> multiple patches hitting the mail server patch size limit.
> We thought it might be better to take the patch size hit on one patch
> instead of multiple patches.

I don't see how it is better to have one huge patch
than multiple big ones.

> 
> We are working on some design changes to the auto generation scripts
> which will avoid big churn in the template patches in the future.
  
Ajit Khaparde June 29, 2023, 4:30 a.m. UTC | #4
On Wed, Jun 28, 2023 at 12:07 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> 28/06/2023 18:35, Ajit Khaparde:
> > On Sat, Jun 10, 2023 at 11:33 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > > More important, you are doing huge update of many different things
> > > in one patch.
> > > It looks like you don't want the community to follow what you are doing.
> > Actually, no.
> > As I mentioned above, most of the truflow files are auto generated.
> > The reason for bundling some of the changes together was to avoid
> > multiple patches hitting the mail server patch size limit.
> > We thought it might be better to take the patch size hit on one patch
> > instead of multiple patches.
>
> I don't see how it is better to have one huge patch
> than multiple big ones.
Well, its debatable now, considering we are having this discussion.
But as I said, the current design of the truflow generator scripts tend to make
a lot of changes even for a small modification or adjustment to the code.
We had patches which were moving around the same lines of code because
of the script. That's why we decided to take this approach.
We could try to split the patch with the template changes, but that may take
time and we are closing in on rc3 date.





>
> >
> > We are working on some design changes to the auto generation scripts
> > which will avoid big churn in the template patches in the future.
>
>
>
  
Ajit Khaparde June 30, 2023, 12:16 p.m. UTC | #5
On Wed, Jun 28, 2023 at 9:30 PM Ajit Khaparde
<ajit.khaparde@broadcom.com> wrote:
>
> On Wed, Jun 28, 2023 at 12:07 PM Thomas Monjalon <thomas@monjalon.net> wrote:
> >
> > 28/06/2023 18:35, Ajit Khaparde:
> > > On Sat, Jun 10, 2023 at 11:33 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > > > More important, you are doing huge update of many different things
> > > > in one patch.
> > > > It looks like you don't want the community to follow what you are doing.
> > > Actually, no.
> > > As I mentioned above, most of the truflow files are auto generated.
> > > The reason for bundling some of the changes together was to avoid
> > > multiple patches hitting the mail server patch size limit.
> > > We thought it might be better to take the patch size hit on one patch
> > > instead of multiple patches.
> >
> > I don't see how it is better to have one huge patch
> > than multiple big ones.
> Well, its debatable now, considering we are having this discussion.
> But as I said, the current design of the truflow generator scripts tend to make
> a lot of changes even for a small modification or adjustment to the code.
> We had patches which were moving around the same lines of code because
> of the script. That's why we decided to take this approach.
> We could try to split the patch with the template changes, but that may take
> time and we are closing in on rc3 date.

Patches applied to dpdk-next-net-brcm. Thanks


>
>
>
>
>
> >
> > >
> > > We are working on some design changes to the auto generation scripts
> > > which will avoid big churn in the template patches in the future.
> >
> >
> >
  

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");