diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index 33e6ebd..35038dc 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -28,7 +28,10 @@ sources = files('bnxt_cpr.c',
 	'tf_core/tf_msg.c',
 	'tf_core/rand.c',
 	'tf_core/stack.c',
-	'tf_core/tf_em.c',
+        'tf_core/tf_em_common.c',
+        'tf_core/tf_em_host.c',
+        'tf_core/tf_em_internal.c',
+        'tf_core/tf_em_system.c',
 	'tf_core/tf_rm.c',
 	'tf_core/tf_tbl.c',
 	'tf_core/tfp.c',
diff --git a/drivers/net/bnxt/tf_core/Makefile b/drivers/net/bnxt/tf_core/Makefile
index ecd5aac..6ae5c34 100644
--- a/drivers/net/bnxt/tf_core/Makefile
+++ b/drivers/net/bnxt/tf_core/Makefile
@@ -12,8 +12,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_core.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_rm.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tfp.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_msg.c
-SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tbl.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_internal.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_host.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_system.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_session.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_device.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_device_p4.c
diff --git a/drivers/net/bnxt/tf_core/cfa_resource_types.h b/drivers/net/bnxt/tf_core/cfa_resource_types.h
index 058d8cc..6e79fac 100644
--- a/drivers/net/bnxt/tf_core/cfa_resource_types.h
+++ b/drivers/net/bnxt/tf_core/cfa_resource_types.h
@@ -202,7 +202,9 @@
 #define CFA_RESOURCE_TYPE_P45_SP_TCAM         0x1fUL
 /* VEB TCAM */
 #define CFA_RESOURCE_TYPE_P45_VEB_TCAM        0x20UL
-#define CFA_RESOURCE_TYPE_P45_LAST           CFA_RESOURCE_TYPE_P45_VEB_TCAM
+/* Table Scope */
+#define CFA_RESOURCE_TYPE_P45_TBL_SCOPE       0x21UL
+#define CFA_RESOURCE_TYPE_P45_LAST           CFA_RESOURCE_TYPE_P45_TBL_SCOPE
 
 
 /* Multicast Group */
@@ -269,7 +271,9 @@
 #define CFA_RESOURCE_TYPE_P4_MIRROR          0x1eUL
 /* Source Property TCAM */
 #define CFA_RESOURCE_TYPE_P4_SP_TCAM         0x1fUL
-#define CFA_RESOURCE_TYPE_P4_LAST           CFA_RESOURCE_TYPE_P4_SP_TCAM
+/* Table Scope */
+#define CFA_RESOURCE_TYPE_P4_TBL_SCOPE       0x20UL
+#define CFA_RESOURCE_TYPE_P4_LAST           CFA_RESOURCE_TYPE_P4_TBL_SCOPE
 
 
 #endif /* _CFA_RESOURCE_TYPES_H_ */
diff --git a/drivers/net/bnxt/tf_core/hwrm_tf.h b/drivers/net/bnxt/tf_core/hwrm_tf.h
index 1e78296..26836e4 100644
--- a/drivers/net/bnxt/tf_core/hwrm_tf.h
+++ b/drivers/net/bnxt/tf_core/hwrm_tf.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2020 Broadcom
+ * Copyright(c) 2019 Broadcom
  * All rights reserved.
  */
 #ifndef _HWRM_TF_H_
@@ -13,20 +13,8 @@ typedef enum tf_type {
 } tf_type_t;
 
 typedef enum tf_subtype {
-	HWRM_TFT_SESSION_ATTACH = 712,
-	HWRM_TFT_SESSION_HW_RESC_QCAPS = 721,
-	HWRM_TFT_SESSION_HW_RESC_ALLOC = 722,
-	HWRM_TFT_SESSION_HW_RESC_FREE = 723,
-	HWRM_TFT_SESSION_HW_RESC_FLUSH = 724,
-	HWRM_TFT_SESSION_SRAM_RESC_QCAPS = 725,
-	HWRM_TFT_SESSION_SRAM_RESC_ALLOC = 726,
-	HWRM_TFT_SESSION_SRAM_RESC_FREE = 727,
-	HWRM_TFT_SESSION_SRAM_RESC_FLUSH = 728,
-	HWRM_TFT_TBL_SCOPE_CFG = 731,
 	HWRM_TFT_REG_GET = 821,
 	HWRM_TFT_REG_SET = 822,
-	HWRM_TFT_TBL_TYPE_SET = 823,
-	HWRM_TFT_TBL_TYPE_GET = 824,
 	HWRM_TFT_TBL_TYPE_BULK_GET = 825,
 	TF_SUBTYPE_LAST = HWRM_TFT_TBL_TYPE_BULK_GET,
 } tf_subtype_t;
@@ -66,858 +54,8 @@ typedef enum tf_subtype {
 #define TF_BITS2BYTES(x) (((x) + 7) >> 3)
 #define TF_BITS2BYTES_WORD_ALIGN(x) ((((x) + 31) >> 5) * 4)
 
-struct tf_session_attach_input;
-struct tf_session_hw_resc_qcaps_input;
-struct tf_session_hw_resc_qcaps_output;
-struct tf_session_hw_resc_alloc_input;
-struct tf_session_hw_resc_alloc_output;
-struct tf_session_hw_resc_free_input;
-struct tf_session_hw_resc_flush_input;
-struct tf_session_sram_resc_qcaps_input;
-struct tf_session_sram_resc_qcaps_output;
-struct tf_session_sram_resc_alloc_input;
-struct tf_session_sram_resc_alloc_output;
-struct tf_session_sram_resc_free_input;
-struct tf_session_sram_resc_flush_input;
-struct tf_tbl_type_set_input;
-struct tf_tbl_type_get_input;
-struct tf_tbl_type_get_output;
 struct tf_tbl_type_bulk_get_input;
 struct tf_tbl_type_bulk_get_output;
-/* Input params for session attach */
-typedef struct tf_session_attach_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* Session Name */
-	char				 session_name[TF_SESSION_NAME_MAX];
-} tf_session_attach_input_t, *ptf_session_attach_input_t;
-
-/* Input params for session resource HW qcaps */
-typedef struct tf_session_hw_resc_qcaps_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_HW_RESC_QCAPS_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_HW_RESC_QCAPS_INPUT_FLAGS_DIR_TX	  (0x1)
-} tf_session_hw_resc_qcaps_input_t, *ptf_session_hw_resc_qcaps_input_t;
-
-/* Output params for session resource HW qcaps */
-typedef struct tf_session_hw_resc_qcaps_output {
-	/* Control Flags */
-	uint32_t			 flags;
-	/* When set to 0, indicates Static partitioning */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_STATIC	  (0x0)
-	/* When set to 1, indicates Strategy 1 */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_1	  (0x1)
-	/* When set to 1, indicates Strategy 2 */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_2	  (0x2)
-	/* When set to 1, indicates Strategy 3 */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_3	  (0x3)
-	/* Unused */
-	uint8_t			  unused[4];
-	/* Minimum guaranteed number of L2 Ctx */
-	uint16_t			 l2_ctx_tcam_entries_min;
-	/* Maximum non-guaranteed number of L2 Ctx */
-	uint16_t			 l2_ctx_tcam_entries_max;
-	/* Minimum guaranteed number of profile functions */
-	uint16_t			 prof_func_min;
-	/* Maximum non-guaranteed number of profile functions */
-	uint16_t			 prof_func_max;
-	/* Minimum guaranteed number of profile TCAM entries */
-	uint16_t			 prof_tcam_entries_min;
-	/* Maximum non-guaranteed number of profile TCAM entries */
-	uint16_t			 prof_tcam_entries_max;
-	/* Minimum guaranteed number of EM profile ID */
-	uint16_t			 em_prof_id_min;
-	/* Maximum non-guaranteed number of EM profile ID */
-	uint16_t			 em_prof_id_max;
-	/* Minimum guaranteed number of EM records entries */
-	uint16_t			 em_record_entries_min;
-	/* Maximum non-guaranteed number of EM record entries */
-	uint16_t			 em_record_entries_max;
-	/* Minimum guaranteed number of WC TCAM profile ID */
-	uint16_t			 wc_tcam_prof_id_min;
-	/* Maximum non-guaranteed number of WC TCAM profile ID */
-	uint16_t			 wc_tcam_prof_id_max;
-	/* Minimum guaranteed number of WC TCAM entries */
-	uint16_t			 wc_tcam_entries_min;
-	/* Maximum non-guaranteed number of WC TCAM entries */
-	uint16_t			 wc_tcam_entries_max;
-	/* Minimum guaranteed number of meter profiles */
-	uint16_t			 meter_profiles_min;
-	/* Maximum non-guaranteed number of meter profiles */
-	uint16_t			 meter_profiles_max;
-	/* Minimum guaranteed number of meter instances */
-	uint16_t			 meter_inst_min;
-	/* Maximum non-guaranteed number of meter instances */
-	uint16_t			 meter_inst_max;
-	/* Minimum guaranteed number of mirrors */
-	uint16_t			 mirrors_min;
-	/* Maximum non-guaranteed number of mirrors */
-	uint16_t			 mirrors_max;
-	/* Minimum guaranteed number of UPAR */
-	uint16_t			 upar_min;
-	/* Maximum non-guaranteed number of UPAR */
-	uint16_t			 upar_max;
-	/* Minimum guaranteed number of SP TCAM entries */
-	uint16_t			 sp_tcam_entries_min;
-	/* Maximum non-guaranteed number of SP TCAM entries */
-	uint16_t			 sp_tcam_entries_max;
-	/* Minimum guaranteed number of L2 Functions */
-	uint16_t			 l2_func_min;
-	/* Maximum non-guaranteed number of L2 Functions */
-	uint16_t			 l2_func_max;
-	/* Minimum guaranteed number of flexible key templates */
-	uint16_t			 flex_key_templ_min;
-	/* Maximum non-guaranteed number of flexible key templates */
-	uint16_t			 flex_key_templ_max;
-	/* Minimum guaranteed number of table Scopes */
-	uint16_t			 tbl_scope_min;
-	/* Maximum non-guaranteed number of table Scopes */
-	uint16_t			 tbl_scope_max;
-	/* Minimum guaranteed number of epoch0 entries */
-	uint16_t			 epoch0_entries_min;
-	/* Maximum non-guaranteed number of epoch0 entries */
-	uint16_t			 epoch0_entries_max;
-	/* Minimum guaranteed number of epoch1 entries */
-	uint16_t			 epoch1_entries_min;
-	/* Maximum non-guaranteed number of epoch1 entries */
-	uint16_t			 epoch1_entries_max;
-	/* Minimum guaranteed number of metadata */
-	uint16_t			 metadata_min;
-	/* Maximum non-guaranteed number of metadata */
-	uint16_t			 metadata_max;
-	/* Minimum guaranteed number of CT states */
-	uint16_t			 ct_state_min;
-	/* Maximum non-guaranteed number of CT states */
-	uint16_t			 ct_state_max;
-	/* Minimum guaranteed number of range profiles */
-	uint16_t			 range_prof_min;
-	/* Maximum non-guaranteed number range profiles */
-	uint16_t			 range_prof_max;
-	/* Minimum guaranteed number of range entries */
-	uint16_t			 range_entries_min;
-	/* Maximum non-guaranteed number of range entries */
-	uint16_t			 range_entries_max;
-	/* Minimum guaranteed number of LAG table entries */
-	uint16_t			 lag_tbl_entries_min;
-	/* Maximum non-guaranteed number of LAG table entries */
-	uint16_t			 lag_tbl_entries_max;
-} tf_session_hw_resc_qcaps_output_t, *ptf_session_hw_resc_qcaps_output_t;
-
-/* Input params for session resource HW alloc */
-typedef struct tf_session_hw_resc_alloc_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_HW_RESC_ALLOC_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_HW_RESC_ALLOC_INPUT_FLAGS_DIR_TX	  (0x1)
-	/* Unused */
-	uint8_t			  unused[2];
-	/* Number of L2 CTX TCAM entries to be allocated */
-	uint16_t			 num_l2_ctx_tcam_entries;
-	/* Number of profile functions to be allocated */
-	uint16_t			 num_prof_func_entries;
-	/* Number of profile TCAM entries to be allocated */
-	uint16_t			 num_prof_tcam_entries;
-	/* Number of EM profile ids to be allocated */
-	uint16_t			 num_em_prof_id;
-	/* Number of EM records entries to be allocated */
-	uint16_t			 num_em_record_entries;
-	/* Number of WC profiles ids to be allocated */
-	uint16_t			 num_wc_tcam_prof_id;
-	/* Number of WC TCAM entries to be allocated */
-	uint16_t			 num_wc_tcam_entries;
-	/* Number of meter profiles to be allocated */
-	uint16_t			 num_meter_profiles;
-	/* Number of meter instances to be allocated */
-	uint16_t			 num_meter_inst;
-	/* Number of mirrors to be allocated */
-	uint16_t			 num_mirrors;
-	/* Number of UPAR to be allocated */
-	uint16_t			 num_upar;
-	/* Number of SP TCAM entries to be allocated */
-	uint16_t			 num_sp_tcam_entries;
-	/* Number of L2 functions to be allocated */
-	uint16_t			 num_l2_func;
-	/* Number of flexible key templates to be allocated */
-	uint16_t			 num_flex_key_templ;
-	/* Number of table scopes to be allocated */
-	uint16_t			 num_tbl_scope;
-	/* Number of epoch0 entries to be allocated */
-	uint16_t			 num_epoch0_entries;
-	/* Number of epoch1 entries to be allocated */
-	uint16_t			 num_epoch1_entries;
-	/* Number of metadata to be allocated */
-	uint16_t			 num_metadata;
-	/* Number of CT states to be allocated */
-	uint16_t			 num_ct_state;
-	/* Number of range profiles to be allocated */
-	uint16_t			 num_range_prof;
-	/* Number of range Entries to be allocated */
-	uint16_t			 num_range_entries;
-	/* Number of LAG table entries to be allocated */
-	uint16_t			 num_lag_tbl_entries;
-} tf_session_hw_resc_alloc_input_t, *ptf_session_hw_resc_alloc_input_t;
-
-/* Output params for session resource HW alloc */
-typedef struct tf_session_hw_resc_alloc_output {
-	/* Starting index of L2 CTX TCAM entries allocated to the session */
-	uint16_t			 l2_ctx_tcam_entries_start;
-	/* Number of L2 CTX TCAM entries allocated */
-	uint16_t			 l2_ctx_tcam_entries_stride;
-	/* Starting index of profile functions allocated to the session */
-	uint16_t			 prof_func_start;
-	/* Number of profile functions allocated */
-	uint16_t			 prof_func_stride;
-	/* Starting index of profile TCAM entries allocated to the session */
-	uint16_t			 prof_tcam_entries_start;
-	/* Number of profile TCAM entries allocated */
-	uint16_t			 prof_tcam_entries_stride;
-	/* Starting index of EM profile ids allocated to the session */
-	uint16_t			 em_prof_id_start;
-	/* Number of EM profile ids allocated */
-	uint16_t			 em_prof_id_stride;
-	/* Starting index of EM record entries allocated to the session */
-	uint16_t			 em_record_entries_start;
-	/* Number of EM record entries allocated */
-	uint16_t			 em_record_entries_stride;
-	/* Starting index of WC TCAM profiles ids allocated to the session */
-	uint16_t			 wc_tcam_prof_id_start;
-	/* Number of WC TCAM profile ids allocated */
-	uint16_t			 wc_tcam_prof_id_stride;
-	/* Starting index of WC TCAM entries allocated to the session */
-	uint16_t			 wc_tcam_entries_start;
-	/* Number of WC TCAM allocated */
-	uint16_t			 wc_tcam_entries_stride;
-	/* Starting index of meter profiles allocated to the session */
-	uint16_t			 meter_profiles_start;
-	/* Number of meter profiles allocated */
-	uint16_t			 meter_profiles_stride;
-	/* Starting index of meter instance allocated to the session */
-	uint16_t			 meter_inst_start;
-	/* Number of meter instance allocated */
-	uint16_t			 meter_inst_stride;
-	/* Starting index of mirrors allocated to the session */
-	uint16_t			 mirrors_start;
-	/* Number of mirrors allocated */
-	uint16_t			 mirrors_stride;
-	/* Starting index of UPAR allocated to the session */
-	uint16_t			 upar_start;
-	/* Number of UPAR allocated */
-	uint16_t			 upar_stride;
-	/* Starting index of SP TCAM entries allocated to the session */
-	uint16_t			 sp_tcam_entries_start;
-	/* Number of SP TCAM entries allocated */
-	uint16_t			 sp_tcam_entries_stride;
-	/* Starting index of L2 functions allocated to the session */
-	uint16_t			 l2_func_start;
-	/* Number of L2 functions allocated */
-	uint16_t			 l2_func_stride;
-	/* Starting index of flexible key templates allocated to the session */
-	uint16_t			 flex_key_templ_start;
-	/* Number of flexible key templates allocated */
-	uint16_t			 flex_key_templ_stride;
-	/* Starting index of table scopes allocated to the session */
-	uint16_t			 tbl_scope_start;
-	/* Number of table scopes allocated */
-	uint16_t			 tbl_scope_stride;
-	/* Starting index of epoch0 entries allocated to the session */
-	uint16_t			 epoch0_entries_start;
-	/* Number of epoch0 entries allocated */
-	uint16_t			 epoch0_entries_stride;
-	/* Starting index of epoch1 entries allocated to the session */
-	uint16_t			 epoch1_entries_start;
-	/* Number of epoch1 entries allocated */
-	uint16_t			 epoch1_entries_stride;
-	/* Starting index of metadata allocated to the session */
-	uint16_t			 metadata_start;
-	/* Number of metadata allocated */
-	uint16_t			 metadata_stride;
-	/* Starting index of CT states allocated to the session */
-	uint16_t			 ct_state_start;
-	/* Number of CT states allocated */
-	uint16_t			 ct_state_stride;
-	/* Starting index of range profiles allocated to the session */
-	uint16_t			 range_prof_start;
-	/* Number range profiles allocated */
-	uint16_t			 range_prof_stride;
-	/* Starting index of range enntries allocated to the session */
-	uint16_t			 range_entries_start;
-	/* Number of range entries allocated */
-	uint16_t			 range_entries_stride;
-	/* Starting index of LAG table entries allocated to the session */
-	uint16_t			 lag_tbl_entries_start;
-	/* Number of LAG table entries allocated */
-	uint16_t			 lag_tbl_entries_stride;
-} tf_session_hw_resc_alloc_output_t, *ptf_session_hw_resc_alloc_output_t;
-
-/* Input params for session resource HW free */
-typedef struct tf_session_hw_resc_free_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_HW_RESC_FREE_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_HW_RESC_FREE_INPUT_FLAGS_DIR_TX	  (0x1)
-	/* Unused */
-	uint8_t			  unused[2];
-	/* Starting index of L2 CTX TCAM entries allocated to the session */
-	uint16_t			 l2_ctx_tcam_entries_start;
-	/* Number of L2 CTX TCAM entries allocated */
-	uint16_t			 l2_ctx_tcam_entries_stride;
-	/* Starting index of profile functions allocated to the session */
-	uint16_t			 prof_func_start;
-	/* Number of profile functions allocated */
-	uint16_t			 prof_func_stride;
-	/* Starting index of profile TCAM entries allocated to the session */
-	uint16_t			 prof_tcam_entries_start;
-	/* Number of profile TCAM entries allocated */
-	uint16_t			 prof_tcam_entries_stride;
-	/* Starting index of EM profile ids allocated to the session */
-	uint16_t			 em_prof_id_start;
-	/* Number of EM profile ids allocated */
-	uint16_t			 em_prof_id_stride;
-	/* Starting index of EM record entries allocated to the session */
-	uint16_t			 em_record_entries_start;
-	/* Number of EM record entries allocated */
-	uint16_t			 em_record_entries_stride;
-	/* Starting index of WC TCAM profiles ids allocated to the session */
-	uint16_t			 wc_tcam_prof_id_start;
-	/* Number of WC TCAM profile ids allocated */
-	uint16_t			 wc_tcam_prof_id_stride;
-	/* Starting index of WC TCAM entries allocated to the session */
-	uint16_t			 wc_tcam_entries_start;
-	/* Number of WC TCAM allocated */
-	uint16_t			 wc_tcam_entries_stride;
-	/* Starting index of meter profiles allocated to the session */
-	uint16_t			 meter_profiles_start;
-	/* Number of meter profiles allocated */
-	uint16_t			 meter_profiles_stride;
-	/* Starting index of meter instance allocated to the session */
-	uint16_t			 meter_inst_start;
-	/* Number of meter instance allocated */
-	uint16_t			 meter_inst_stride;
-	/* Starting index of mirrors allocated to the session */
-	uint16_t			 mirrors_start;
-	/* Number of mirrors allocated */
-	uint16_t			 mirrors_stride;
-	/* Starting index of UPAR allocated to the session */
-	uint16_t			 upar_start;
-	/* Number of UPAR allocated */
-	uint16_t			 upar_stride;
-	/* Starting index of SP TCAM entries allocated to the session */
-	uint16_t			 sp_tcam_entries_start;
-	/* Number of SP TCAM entries allocated */
-	uint16_t			 sp_tcam_entries_stride;
-	/* Starting index of L2 functions allocated to the session */
-	uint16_t			 l2_func_start;
-	/* Number of L2 functions allocated */
-	uint16_t			 l2_func_stride;
-	/* Starting index of flexible key templates allocated to the session */
-	uint16_t			 flex_key_templ_start;
-	/* Number of flexible key templates allocated */
-	uint16_t			 flex_key_templ_stride;
-	/* Starting index of table scopes allocated to the session */
-	uint16_t			 tbl_scope_start;
-	/* Number of table scopes allocated */
-	uint16_t			 tbl_scope_stride;
-	/* Starting index of epoch0 entries allocated to the session */
-	uint16_t			 epoch0_entries_start;
-	/* Number of epoch0 entries allocated */
-	uint16_t			 epoch0_entries_stride;
-	/* Starting index of epoch1 entries allocated to the session */
-	uint16_t			 epoch1_entries_start;
-	/* Number of epoch1 entries allocated */
-	uint16_t			 epoch1_entries_stride;
-	/* Starting index of metadata allocated to the session */
-	uint16_t			 metadata_start;
-	/* Number of metadata allocated */
-	uint16_t			 metadata_stride;
-	/* Starting index of CT states allocated to the session */
-	uint16_t			 ct_state_start;
-	/* Number of CT states allocated */
-	uint16_t			 ct_state_stride;
-	/* Starting index of range profiles allocated to the session */
-	uint16_t			 range_prof_start;
-	/* Number range profiles allocated */
-	uint16_t			 range_prof_stride;
-	/* Starting index of range enntries allocated to the session */
-	uint16_t			 range_entries_start;
-	/* Number of range entries allocated */
-	uint16_t			 range_entries_stride;
-	/* Starting index of LAG table entries allocated to the session */
-	uint16_t			 lag_tbl_entries_start;
-	/* Number of LAG table entries allocated */
-	uint16_t			 lag_tbl_entries_stride;
-} tf_session_hw_resc_free_input_t, *ptf_session_hw_resc_free_input_t;
-
-/* Input params for session resource HW flush */
-typedef struct tf_session_hw_resc_flush_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the flush apply to RX */
-#define TF_SESSION_HW_RESC_FLUSH_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the flush apply to TX */
-#define TF_SESSION_HW_RESC_FLUSH_INPUT_FLAGS_DIR_TX	  (0x1)
-	/* Unused */
-	uint8_t			  unused[2];
-	/* Starting index of L2 CTX TCAM entries allocated to the session */
-	uint16_t			 l2_ctx_tcam_entries_start;
-	/* Number of L2 CTX TCAM entries allocated */
-	uint16_t			 l2_ctx_tcam_entries_stride;
-	/* Starting index of profile functions allocated to the session */
-	uint16_t			 prof_func_start;
-	/* Number of profile functions allocated */
-	uint16_t			 prof_func_stride;
-	/* Starting index of profile TCAM entries allocated to the session */
-	uint16_t			 prof_tcam_entries_start;
-	/* Number of profile TCAM entries allocated */
-	uint16_t			 prof_tcam_entries_stride;
-	/* Starting index of EM profile ids allocated to the session */
-	uint16_t			 em_prof_id_start;
-	/* Number of EM profile ids allocated */
-	uint16_t			 em_prof_id_stride;
-	/* Starting index of EM record entries allocated to the session */
-	uint16_t			 em_record_entries_start;
-	/* Number of EM record entries allocated */
-	uint16_t			 em_record_entries_stride;
-	/* Starting index of WC TCAM profiles ids allocated to the session */
-	uint16_t			 wc_tcam_prof_id_start;
-	/* Number of WC TCAM profile ids allocated */
-	uint16_t			 wc_tcam_prof_id_stride;
-	/* Starting index of WC TCAM entries allocated to the session */
-	uint16_t			 wc_tcam_entries_start;
-	/* Number of WC TCAM allocated */
-	uint16_t			 wc_tcam_entries_stride;
-	/* Starting index of meter profiles allocated to the session */
-	uint16_t			 meter_profiles_start;
-	/* Number of meter profiles allocated */
-	uint16_t			 meter_profiles_stride;
-	/* Starting index of meter instance allocated to the session */
-	uint16_t			 meter_inst_start;
-	/* Number of meter instance allocated */
-	uint16_t			 meter_inst_stride;
-	/* Starting index of mirrors allocated to the session */
-	uint16_t			 mirrors_start;
-	/* Number of mirrors allocated */
-	uint16_t			 mirrors_stride;
-	/* Starting index of UPAR allocated to the session */
-	uint16_t			 upar_start;
-	/* Number of UPAR allocated */
-	uint16_t			 upar_stride;
-	/* Starting index of SP TCAM entries allocated to the session */
-	uint16_t			 sp_tcam_entries_start;
-	/* Number of SP TCAM entries allocated */
-	uint16_t			 sp_tcam_entries_stride;
-	/* Starting index of L2 functions allocated to the session */
-	uint16_t			 l2_func_start;
-	/* Number of L2 functions allocated */
-	uint16_t			 l2_func_stride;
-	/* Starting index of flexible key templates allocated to the session */
-	uint16_t			 flex_key_templ_start;
-	/* Number of flexible key templates allocated */
-	uint16_t			 flex_key_templ_stride;
-	/* Starting index of table scopes allocated to the session */
-	uint16_t			 tbl_scope_start;
-	/* Number of table scopes allocated */
-	uint16_t			 tbl_scope_stride;
-	/* Starting index of epoch0 entries allocated to the session */
-	uint16_t			 epoch0_entries_start;
-	/* Number of epoch0 entries allocated */
-	uint16_t			 epoch0_entries_stride;
-	/* Starting index of epoch1 entries allocated to the session */
-	uint16_t			 epoch1_entries_start;
-	/* Number of epoch1 entries allocated */
-	uint16_t			 epoch1_entries_stride;
-	/* Starting index of metadata allocated to the session */
-	uint16_t			 metadata_start;
-	/* Number of metadata allocated */
-	uint16_t			 metadata_stride;
-	/* Starting index of CT states allocated to the session */
-	uint16_t			 ct_state_start;
-	/* Number of CT states allocated */
-	uint16_t			 ct_state_stride;
-	/* Starting index of range profiles allocated to the session */
-	uint16_t			 range_prof_start;
-	/* Number range profiles allocated */
-	uint16_t			 range_prof_stride;
-	/* Starting index of range enntries allocated to the session */
-	uint16_t			 range_entries_start;
-	/* Number of range entries allocated */
-	uint16_t			 range_entries_stride;
-	/* Starting index of LAG table entries allocated to the session */
-	uint16_t			 lag_tbl_entries_start;
-	/* Number of LAG table entries allocated */
-	uint16_t			 lag_tbl_entries_stride;
-} tf_session_hw_resc_flush_input_t, *ptf_session_hw_resc_flush_input_t;
-
-/* Input params for session resource SRAM qcaps */
-typedef struct tf_session_sram_resc_qcaps_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_SRAM_RESC_QCAPS_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_SRAM_RESC_QCAPS_INPUT_FLAGS_DIR_TX	  (0x1)
-} tf_session_sram_resc_qcaps_input_t, *ptf_session_sram_resc_qcaps_input_t;
-
-/* Output params for session resource SRAM qcaps */
-typedef struct tf_session_sram_resc_qcaps_output {
-	/* Flags */
-	uint32_t			 flags;
-	/* When set to 0, indicates Static partitioning */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_STATIC	  (0x0)
-	/* When set to 1, indicates Strategy 1 */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_1	  (0x1)
-	/* When set to 1, indicates Strategy 2 */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_2	  (0x2)
-	/* When set to 1, indicates Strategy 3 */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_3	  (0x3)
-	/* Minimum guaranteed number of Full Action */
-	uint16_t			 full_action_min;
-	/* Maximum non-guaranteed number of Full Action */
-	uint16_t			 full_action_max;
-	/* Minimum guaranteed number of MCG */
-	uint16_t			 mcg_min;
-	/* Maximum non-guaranteed number of MCG */
-	uint16_t			 mcg_max;
-	/* Minimum guaranteed number of Encap 8B */
-	uint16_t			 encap_8b_min;
-	/* Maximum non-guaranteed number of Encap 8B */
-	uint16_t			 encap_8b_max;
-	/* Minimum guaranteed number of Encap 16B */
-	uint16_t			 encap_16b_min;
-	/* Maximum non-guaranteed number of Encap 16B */
-	uint16_t			 encap_16b_max;
-	/* Minimum guaranteed number of Encap 64B */
-	uint16_t			 encap_64b_min;
-	/* Maximum non-guaranteed number of Encap 64B */
-	uint16_t			 encap_64b_max;
-	/* Minimum guaranteed number of SP SMAC */
-	uint16_t			 sp_smac_min;
-	/* Maximum non-guaranteed number of SP SMAC */
-	uint16_t			 sp_smac_max;
-	/* Minimum guaranteed number of SP SMAC IPv4 */
-	uint16_t			 sp_smac_ipv4_min;
-	/* Maximum non-guaranteed number of SP SMAC IPv4 */
-	uint16_t			 sp_smac_ipv4_max;
-	/* Minimum guaranteed number of SP SMAC IPv6 */
-	uint16_t			 sp_smac_ipv6_min;
-	/* Maximum non-guaranteed number of SP SMAC IPv6 */
-	uint16_t			 sp_smac_ipv6_max;
-	/* Minimum guaranteed number of Counter 64B */
-	uint16_t			 counter_64b_min;
-	/* Maximum non-guaranteed number of Counter 64B */
-	uint16_t			 counter_64b_max;
-	/* Minimum guaranteed number of NAT SPORT */
-	uint16_t			 nat_sport_min;
-	/* Maximum non-guaranteed number of NAT SPORT */
-	uint16_t			 nat_sport_max;
-	/* Minimum guaranteed number of NAT DPORT */
-	uint16_t			 nat_dport_min;
-	/* Maximum non-guaranteed number of NAT DPORT */
-	uint16_t			 nat_dport_max;
-	/* Minimum guaranteed number of NAT S_IPV4 */
-	uint16_t			 nat_s_ipv4_min;
-	/* Maximum non-guaranteed number of NAT S_IPV4 */
-	uint16_t			 nat_s_ipv4_max;
-	/* Minimum guaranteed number of NAT D_IPV4 */
-	uint16_t			 nat_d_ipv4_min;
-	/* Maximum non-guaranteed number of NAT D_IPV4 */
-	uint16_t			 nat_d_ipv4_max;
-} tf_session_sram_resc_qcaps_output_t, *ptf_session_sram_resc_qcaps_output_t;
-
-/* Input params for session resource SRAM alloc */
-typedef struct tf_session_sram_resc_alloc_input {
-	/* FW Session Id */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_SRAM_RESC_ALLOC_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_SRAM_RESC_ALLOC_INPUT_FLAGS_DIR_TX	  (0x1)
-	/* Unused */
-	uint8_t			  unused[2];
-	/* Number of full action SRAM entries to be allocated */
-	uint16_t			 num_full_action;
-	/* Number of multicast groups to be allocated */
-	uint16_t			 num_mcg;
-	/* Number of Encap 8B entries to be allocated */
-	uint16_t			 num_encap_8b;
-	/* Number of Encap 16B entries to be allocated */
-	uint16_t			 num_encap_16b;
-	/* Number of Encap 64B entries to be allocated */
-	uint16_t			 num_encap_64b;
-	/* Number of SP SMAC entries to be allocated */
-	uint16_t			 num_sp_smac;
-	/* Number of SP SMAC IPv4 entries to be allocated */
-	uint16_t			 num_sp_smac_ipv4;
-	/* Number of SP SMAC IPv6 entries to be allocated */
-	uint16_t			 num_sp_smac_ipv6;
-	/* Number of Counter 64B entries to be allocated */
-	uint16_t			 num_counter_64b;
-	/* Number of NAT source ports to be allocated */
-	uint16_t			 num_nat_sport;
-	/* Number of NAT destination ports to be allocated */
-	uint16_t			 num_nat_dport;
-	/* Number of NAT source iPV4 addresses to be allocated */
-	uint16_t			 num_nat_s_ipv4;
-	/* Number of NAT destination IPV4 addresses to be allocated */
-	uint16_t			 num_nat_d_ipv4;
-} tf_session_sram_resc_alloc_input_t, *ptf_session_sram_resc_alloc_input_t;
-
-/* Output params for session resource SRAM alloc */
-typedef struct tf_session_sram_resc_alloc_output {
-	/* Unused */
-	uint8_t			  unused[2];
-	/* Starting index of full action SRAM entries allocated to the session */
-	uint16_t			 full_action_start;
-	/* Number of full action SRAM entries allocated */
-	uint16_t			 full_action_stride;
-	/* Starting index of multicast groups allocated to this session */
-	uint16_t			 mcg_start;
-	/* Number of multicast groups allocated */
-	uint16_t			 mcg_stride;
-	/* Starting index of encap 8B entries allocated to the session */
-	uint16_t			 encap_8b_start;
-	/* Number of encap 8B entries allocated */
-	uint16_t			 encap_8b_stride;
-	/* Starting index of encap 16B entries allocated to the session */
-	uint16_t			 encap_16b_start;
-	/* Number of encap 16B entries allocated */
-	uint16_t			 encap_16b_stride;
-	/* Starting index of encap 64B entries allocated to the session */
-	uint16_t			 encap_64b_start;
-	/* Number of encap 64B entries allocated */
-	uint16_t			 encap_64b_stride;
-	/* Starting index of SP SMAC entries allocated to the session */
-	uint16_t			 sp_smac_start;
-	/* Number of SP SMAC entries allocated */
-	uint16_t			 sp_smac_stride;
-	/* Starting index of SP SMAC IPv4 entries allocated to the session */
-	uint16_t			 sp_smac_ipv4_start;
-	/* Number of SP SMAC IPv4 entries allocated */
-	uint16_t			 sp_smac_ipv4_stride;
-	/* Starting index of SP SMAC IPv6 entries allocated to the session */
-	uint16_t			 sp_smac_ipv6_start;
-	/* Number of SP SMAC IPv6 entries allocated */
-	uint16_t			 sp_smac_ipv6_stride;
-	/* Starting index of Counter 64B entries allocated to the session */
-	uint16_t			 counter_64b_start;
-	/* Number of Counter 64B entries allocated */
-	uint16_t			 counter_64b_stride;
-	/* Starting index of NAT source ports allocated to the session */
-	uint16_t			 nat_sport_start;
-	/* Number of NAT source ports allocated */
-	uint16_t			 nat_sport_stride;
-	/* Starting index of NAT destination ports allocated to the session */
-	uint16_t			 nat_dport_start;
-	/* Number of NAT destination ports allocated */
-	uint16_t			 nat_dport_stride;
-	/* Starting index of NAT source IPV4 addresses allocated to the session */
-	uint16_t			 nat_s_ipv4_start;
-	/* Number of NAT source IPV4 addresses allocated */
-	uint16_t			 nat_s_ipv4_stride;
-	/*
-	 * Starting index of NAT destination IPV4 addresses allocated to the
-	 * session
-	 */
-	uint16_t			 nat_d_ipv4_start;
-	/* Number of NAT destination IPV4 addresses allocated */
-	uint16_t			 nat_d_ipv4_stride;
-} tf_session_sram_resc_alloc_output_t, *ptf_session_sram_resc_alloc_output_t;
-
-/* Input params for session resource SRAM free */
-typedef struct tf_session_sram_resc_free_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_SRAM_RESC_FREE_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_SRAM_RESC_FREE_INPUT_FLAGS_DIR_TX	  (0x1)
-	/* Starting index of full action SRAM entries allocated to the session */
-	uint16_t			 full_action_start;
-	/* Number of full action SRAM entries allocated */
-	uint16_t			 full_action_stride;
-	/* Starting index of multicast groups allocated to this session */
-	uint16_t			 mcg_start;
-	/* Number of multicast groups allocated */
-	uint16_t			 mcg_stride;
-	/* Starting index of encap 8B entries allocated to the session */
-	uint16_t			 encap_8b_start;
-	/* Number of encap 8B entries allocated */
-	uint16_t			 encap_8b_stride;
-	/* Starting index of encap 16B entries allocated to the session */
-	uint16_t			 encap_16b_start;
-	/* Number of encap 16B entries allocated */
-	uint16_t			 encap_16b_stride;
-	/* Starting index of encap 64B entries allocated to the session */
-	uint16_t			 encap_64b_start;
-	/* Number of encap 64B entries allocated */
-	uint16_t			 encap_64b_stride;
-	/* Starting index of SP SMAC entries allocated to the session */
-	uint16_t			 sp_smac_start;
-	/* Number of SP SMAC entries allocated */
-	uint16_t			 sp_smac_stride;
-	/* Starting index of SP SMAC IPv4 entries allocated to the session */
-	uint16_t			 sp_smac_ipv4_start;
-	/* Number of SP SMAC IPv4 entries allocated */
-	uint16_t			 sp_smac_ipv4_stride;
-	/* Starting index of SP SMAC IPv6 entries allocated to the session */
-	uint16_t			 sp_smac_ipv6_start;
-	/* Number of SP SMAC IPv6 entries allocated */
-	uint16_t			 sp_smac_ipv6_stride;
-	/* Starting index of Counter 64B entries allocated to the session */
-	uint16_t			 counter_64b_start;
-	/* Number of Counter 64B entries allocated */
-	uint16_t			 counter_64b_stride;
-	/* Starting index of NAT source ports allocated to the session */
-	uint16_t			 nat_sport_start;
-	/* Number of NAT source ports allocated */
-	uint16_t			 nat_sport_stride;
-	/* Starting index of NAT destination ports allocated to the session */
-	uint16_t			 nat_dport_start;
-	/* Number of NAT destination ports allocated */
-	uint16_t			 nat_dport_stride;
-	/* Starting index of NAT source IPV4 addresses allocated to the session */
-	uint16_t			 nat_s_ipv4_start;
-	/* Number of NAT source IPV4 addresses allocated */
-	uint16_t			 nat_s_ipv4_stride;
-	/*
-	 * Starting index of NAT destination IPV4 addresses allocated to the
-	 * session
-	 */
-	uint16_t			 nat_d_ipv4_start;
-	/* Number of NAT destination IPV4 addresses allocated */
-	uint16_t			 nat_d_ipv4_stride;
-} tf_session_sram_resc_free_input_t, *ptf_session_sram_resc_free_input_t;
-
-/* Input params for session resource SRAM flush */
-typedef struct tf_session_sram_resc_flush_input {
-	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the flush apply to RX */
-#define TF_SESSION_SRAM_RESC_FLUSH_INPUT_FLAGS_DIR_RX	  (0x0)
-	/* When set to 1, indicates the flush apply to TX */
-#define TF_SESSION_SRAM_RESC_FLUSH_INPUT_FLAGS_DIR_TX	  (0x1)
-	/* Starting index of full action SRAM entries allocated to the session */
-	uint16_t			 full_action_start;
-	/* Number of full action SRAM entries allocated */
-	uint16_t			 full_action_stride;
-	/* Starting index of multicast groups allocated to this session */
-	uint16_t			 mcg_start;
-	/* Number of multicast groups allocated */
-	uint16_t			 mcg_stride;
-	/* Starting index of encap 8B entries allocated to the session */
-	uint16_t			 encap_8b_start;
-	/* Number of encap 8B entries allocated */
-	uint16_t			 encap_8b_stride;
-	/* Starting index of encap 16B entries allocated to the session */
-	uint16_t			 encap_16b_start;
-	/* Number of encap 16B entries allocated */
-	uint16_t			 encap_16b_stride;
-	/* Starting index of encap 64B entries allocated to the session */
-	uint16_t			 encap_64b_start;
-	/* Number of encap 64B entries allocated */
-	uint16_t			 encap_64b_stride;
-	/* Starting index of SP SMAC entries allocated to the session */
-	uint16_t			 sp_smac_start;
-	/* Number of SP SMAC entries allocated */
-	uint16_t			 sp_smac_stride;
-	/* Starting index of SP SMAC IPv4 entries allocated to the session */
-	uint16_t			 sp_smac_ipv4_start;
-	/* Number of SP SMAC IPv4 entries allocated */
-	uint16_t			 sp_smac_ipv4_stride;
-	/* Starting index of SP SMAC IPv6 entries allocated to the session */
-	uint16_t			 sp_smac_ipv6_start;
-	/* Number of SP SMAC IPv6 entries allocated */
-	uint16_t			 sp_smac_ipv6_stride;
-	/* Starting index of Counter 64B entries allocated to the session */
-	uint16_t			 counter_64b_start;
-	/* Number of Counter 64B entries allocated */
-	uint16_t			 counter_64b_stride;
-	/* Starting index of NAT source ports allocated to the session */
-	uint16_t			 nat_sport_start;
-	/* Number of NAT source ports allocated */
-	uint16_t			 nat_sport_stride;
-	/* Starting index of NAT destination ports allocated to the session */
-	uint16_t			 nat_dport_start;
-	/* Number of NAT destination ports allocated */
-	uint16_t			 nat_dport_stride;
-	/* Starting index of NAT source IPV4 addresses allocated to the session */
-	uint16_t			 nat_s_ipv4_start;
-	/* Number of NAT source IPV4 addresses allocated */
-	uint16_t			 nat_s_ipv4_stride;
-	/*
-	 * Starting index of NAT destination IPV4 addresses allocated to the
-	 * session
-	 */
-	uint16_t			 nat_d_ipv4_start;
-	/* Number of NAT destination IPV4 addresses allocated */
-	uint16_t			 nat_d_ipv4_stride;
-} tf_session_sram_resc_flush_input_t, *ptf_session_sram_resc_flush_input_t;
-
-/* Input params for table type set */
-typedef struct tf_tbl_type_set_input {
-	/* Session Id */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the get apply to RX */
-#define TF_TBL_TYPE_SET_INPUT_FLAGS_DIR_RX			(0x0)
-	/* When set to 1, indicates the get apply to TX */
-#define TF_TBL_TYPE_SET_INPUT_FLAGS_DIR_TX			(0x1)
-	/* Type of the object to set */
-	uint32_t			 type;
-	/* Size of the data to set in bytes */
-	uint16_t			 size;
-	/* Data to set */
-	uint8_t			  data[TF_BULK_SEND];
-	/* Index to set */
-	uint32_t			 index;
-} tf_tbl_type_set_input_t, *ptf_tbl_type_set_input_t;
-
-/* Input params for table type get */
-typedef struct tf_tbl_type_get_input {
-	/* Session Id */
-	uint32_t			 fw_session_id;
-	/* flags */
-	uint16_t			 flags;
-	/* When set to 0, indicates the get apply to RX */
-#define TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX			(0x0)
-	/* When set to 1, indicates the get apply to TX */
-#define TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX			(0x1)
-	/* Type of the object to set */
-	uint32_t			 type;
-	/* Index to get */
-	uint32_t			 index;
-} tf_tbl_type_get_input_t, *ptf_tbl_type_get_input_t;
-
-/* Output params for table type get */
-typedef struct tf_tbl_type_get_output {
-	/* Size of the data read in bytes */
-	uint16_t			 size;
-	/* Data read */
-	uint8_t			  data[TF_BULK_RECV];
-} tf_tbl_type_get_output_t, *ptf_tbl_type_get_output_t;
 
 /* Input params for table type get */
 typedef struct tf_tbl_type_bulk_get_input {
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 3e23d05..8b3e15c 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -208,7 +208,15 @@ int tf_insert_em_entry(struct tf *tfp,
 		return rc;
 	}
 
-	rc = dev->ops->tf_dev_insert_em_entry(tfp, parms);
+	if (parms->mem == TF_MEM_EXTERNAL &&
+		dev->ops->tf_dev_insert_ext_em_entry != NULL)
+		rc = dev->ops->tf_dev_insert_ext_em_entry(tfp, parms);
+	else if (parms->mem == TF_MEM_INTERNAL &&
+		dev->ops->tf_dev_insert_int_em_entry != NULL)
+		rc = dev->ops->tf_dev_insert_int_em_entry(tfp, parms);
+	else
+		return -EINVAL;
+
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "%s: EM insert failed, rc:%s\n",
@@ -217,7 +225,7 @@ int tf_insert_em_entry(struct tf *tfp,
 		return rc;
 	}
 
-	return -EINVAL;
+	return 0;
 }
 
 /** Delete EM hash entry API
@@ -255,7 +263,13 @@ int tf_delete_em_entry(struct tf *tfp,
 		return rc;
 	}
 
-	rc = dev->ops->tf_dev_delete_em_entry(tfp, parms);
+	if (parms->mem == TF_MEM_EXTERNAL)
+		rc = dev->ops->tf_dev_delete_ext_em_entry(tfp, parms);
+	else if (parms->mem == TF_MEM_INTERNAL)
+		rc = dev->ops->tf_dev_delete_int_em_entry(tfp, parms);
+	else
+		return -EINVAL;
+
 	if (rc) {
 		TFP_DRV_LOG(ERR,
 			    "%s: EM delete failed, rc:%s\n",
@@ -806,3 +820,83 @@ tf_get_tbl_entry(struct tf *tfp,
 
 	return rc;
 }
+
+/* API defined in tf_core.h */
+int
+tf_alloc_tbl_scope(struct tf *tfp,
+		   struct tf_alloc_tbl_scope_parms *parms)
+{
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int rc;
+
+	TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(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;
+	}
+
+	if (dev->ops->tf_dev_alloc_tbl_scope != NULL) {
+		rc = dev->ops->tf_dev_alloc_tbl_scope(tfp, parms);
+	} else {
+		TFP_DRV_LOG(ERR,
+			    "Alloc table scope not supported by device\n");
+		return -EINVAL;
+	}
+
+	return rc;
+}
+
+/* API defined in tf_core.h */
+int
+tf_free_tbl_scope(struct tf *tfp,
+		  struct tf_free_tbl_scope_parms *parms)
+{
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int rc;
+
+	TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(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;
+	}
+
+	if (dev->ops->tf_dev_free_tbl_scope) {
+		rc = dev->ops->tf_dev_free_tbl_scope(tfp, parms);
+	} else {
+		TFP_DRV_LOG(ERR,
+			    "Free table scope not supported by device\n");
+		return -EINVAL;
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c
index 441d0c6..20b0c59 100644
--- a/drivers/net/bnxt/tf_core/tf_device.c
+++ b/drivers/net/bnxt/tf_core/tf_device.c
@@ -6,6 +6,7 @@
 #include "tf_device.h"
 #include "tf_device_p4.h"
 #include "tfp.h"
+#include "tf_em.h"
 
 struct tf;
 
@@ -42,10 +43,7 @@ tf_dev_bind_p4(struct tf *tfp,
 	struct tf_ident_cfg_parms ident_cfg;
 	struct tf_tbl_cfg_parms tbl_cfg;
 	struct tf_tcam_cfg_parms tcam_cfg;
-
-	dev_handle->type = TF_DEVICE_TYPE_WH;
-	/* Initial function initialization */
-	dev_handle->ops = &tf_dev_ops_p4_init;
+	struct tf_em_cfg_parms em_cfg;
 
 	dev_handle->type = TF_DEVICE_TYPE_WH;
 	/* Initial function initialization */
@@ -86,6 +84,36 @@ tf_dev_bind_p4(struct tf *tfp,
 		goto fail;
 	}
 
+	/*
+	 * EEM
+	 */
+	em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
+	em_cfg.cfg = tf_em_ext_p4;
+	em_cfg.resources = resources;
+	em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
+
+	rc = tf_em_ext_common_bind(tfp, &em_cfg);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "EEM initialization failure\n");
+		goto fail;
+	}
+
+	/*
+	 * EM
+	 */
+	em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
+	em_cfg.cfg = tf_em_int_p4;
+	em_cfg.resources = resources;
+	em_cfg.mem_type = 0; /* Not used by EM */
+
+	rc = tf_em_int_bind(tfp, &em_cfg);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "EM initialization failure\n");
+		goto fail;
+	}
+
 	/* Final function initialization */
 	dev_handle->ops = &tf_dev_ops_p4;
 
@@ -144,6 +172,20 @@ tf_dev_unbind_p4(struct tf *tfp)
 		fail = true;
 	}
 
+	rc = tf_em_ext_common_unbind(tfp);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Device unbind failed, EEM\n");
+		fail = true;
+	}
+
+	rc = tf_em_int_unbind(tfp);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Device unbind failed, EM\n");
+		fail = true;
+	}
+
 	if (fail)
 		return -1;
 
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index c8feac5..2712d10 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -15,12 +15,24 @@ struct tf;
 struct tf_session;
 
 /**
- *
+ * Device module types
  */
 enum tf_device_module_type {
+	/**
+	 * Identifier module
+	 */
 	TF_DEVICE_MODULE_TYPE_IDENTIFIER,
+	/**
+	 * Table type module
+	 */
 	TF_DEVICE_MODULE_TYPE_TABLE,
+	/**
+	 * TCAM module
+	 */
 	TF_DEVICE_MODULE_TYPE_TCAM,
+	/**
+	 * EM module
+	 */
 	TF_DEVICE_MODULE_TYPE_EM,
 	TF_DEVICE_MODULE_TYPE_MAX
 };
@@ -395,8 +407,8 @@ struct tf_dev_ops {
 	 *    0       - Success
 	 *    -EINVAL - Error
 	 */
-	int (*tf_dev_insert_em_entry)(struct tf *tfp,
-				      struct tf_insert_em_entry_parms *parms);
+	int (*tf_dev_insert_int_em_entry)(struct tf *tfp,
+					  struct tf_insert_em_entry_parms *parms);
 
 	/**
 	 * Delete EM hash entry API
@@ -411,8 +423,72 @@ struct tf_dev_ops {
 	 *    0       - Success
 	 *    -EINVAL - Error
 	 */
-	int (*tf_dev_delete_em_entry)(struct tf *tfp,
-				      struct tf_delete_em_entry_parms *parms);
+	int (*tf_dev_delete_int_em_entry)(struct tf *tfp,
+					  struct tf_delete_em_entry_parms *parms);
+
+	/**
+	 * Insert EEM hash entry API
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to E/EM insert parameters
+	 *
+	 *  Returns:
+	 *    0       - Success
+	 *    -EINVAL - Error
+	 */
+	int (*tf_dev_insert_ext_em_entry)(struct tf *tfp,
+					  struct tf_insert_em_entry_parms *parms);
+
+	/**
+	 * Delete EEM hash entry API
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to E/EM delete parameters
+	 *
+	 *    returns:
+	 *    0       - Success
+	 *    -EINVAL - Error
+	 */
+	int (*tf_dev_delete_ext_em_entry)(struct tf *tfp,
+					  struct tf_delete_em_entry_parms *parms);
+
+	/**
+	 * Allocate EEM table scope
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to table scope alloc parameters
+	 *
+	 *    returns:
+	 *    0       - Success
+	 *    -EINVAL - Error
+	 */
+	int (*tf_dev_alloc_tbl_scope)(struct tf *tfp,
+				      struct tf_alloc_tbl_scope_parms *parms);
+
+	/**
+	 * Free EEM table scope
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to table scope free parameters
+	 *
+	 *    returns:
+	 *    0       - Success
+	 *    -EINVAL - Error
+	 */
+	int (*tf_dev_free_tbl_scope)(struct tf *tfp,
+				     struct tf_free_tbl_scope_parms *parms);
 };
 
 /**
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index 9e332c5..127c655 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -93,6 +93,12 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_alloc_search_tcam = NULL,
 	.tf_dev_set_tcam = NULL,
 	.tf_dev_get_tcam = NULL,
+	.tf_dev_insert_int_em_entry = NULL,
+	.tf_dev_delete_int_em_entry = NULL,
+	.tf_dev_insert_ext_em_entry = NULL,
+	.tf_dev_delete_ext_em_entry = NULL,
+	.tf_dev_alloc_tbl_scope = NULL,
+	.tf_dev_free_tbl_scope = NULL,
 };
 
 /**
@@ -113,6 +119,10 @@ const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_alloc_search_tcam = NULL,
 	.tf_dev_set_tcam = tf_tcam_set,
 	.tf_dev_get_tcam = NULL,
-	.tf_dev_insert_em_entry = tf_em_insert_entry,
-	.tf_dev_delete_em_entry = tf_em_delete_entry,
+	.tf_dev_insert_int_em_entry = tf_em_insert_int_entry,
+	.tf_dev_delete_int_em_entry = tf_em_delete_int_entry,
+	.tf_dev_insert_ext_em_entry = tf_em_insert_ext_entry,
+	.tf_dev_delete_ext_em_entry = tf_em_delete_ext_entry,
+	.tf_dev_alloc_tbl_scope = tf_em_ext_common_alloc,
+	.tf_dev_free_tbl_scope = tf_em_ext_common_free,
 };
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.h b/drivers/net/bnxt/tf_core/tf_device_p4.h
index 411e216..da6dd65 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.h
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.h
@@ -36,13 +36,12 @@ struct tf_rm_element_cfg tf_tbl_p4[TF_TBL_TYPE_MAX] = {
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_MCG },
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_ENCAP_8B },
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_ENCAP_16B },
-	/* CFA_RESOURCE_TYPE_P4_SRAM_ENCAP_32B */
+	/* CFA_RESOURCE_TYPE_P4_ENCAP_32B */
 	{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_ENCAP_64B },
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_SP_MAC },
-	/* CFA_RESOURCE_TYPE_P4_SRAM_SP_SMAC_IPV4 */
-	{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
-	/* CFA_RESOURCE_TYPE_P4_SRAM_SP_SMAC_IPV6 */
+	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_SP_MAC_IPV4 },
+	/* CFA_RESOURCE_TYPE_P4_SP_MAC_IPV6 */
 	{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_COUNTER_64B },
 	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_NAT_SPORT },
@@ -77,4 +76,17 @@ struct tf_rm_element_cfg tf_tbl_p4[TF_TBL_TYPE_MAX] = {
 	/* CFA_RESOURCE_TYPE_P4_EXT */
 	{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID }
 };
+
+struct tf_rm_element_cfg tf_em_ext_p4[TF_EM_TBL_TYPE_MAX] = {
+	/* CFA_RESOURCE_TYPE_P4_EM_REC */
+	{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
+	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_TBL_SCOPE },
+};
+
+struct tf_rm_element_cfg tf_em_int_p4[TF_EM_TBL_TYPE_MAX] = {
+	{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_EM_REC },
+	/* CFA_RESOURCE_TYPE_P4_TBL_SCOPE */
+	{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
+};
+
 #endif /* _TF_DEVICE_P4_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em.c b/drivers/net/bnxt/tf_core/tf_em.c
deleted file mode 100644
index 7b430fa..0000000
--- a/drivers/net/bnxt/tf_core/tf_em.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2020 Broadcom
- * All rights reserved.
- */
-
-#include <string.h>
-#include <rte_common.h>
-#include <rte_errno.h>
-#include <rte_log.h>
-
-#include "tf_core.h"
-#include "tf_em.h"
-#include "tf_msg.h"
-#include "tfp.h"
-#include "lookup3.h"
-#include "tf_ext_flow_handle.h"
-
-#include "bnxt.h"
-
-
-static uint32_t tf_em_get_key_mask(int num_entries)
-{
-	uint32_t mask = num_entries - 1;
-
-	if (num_entries & 0x7FFF)
-		return 0;
-
-	if (num_entries > (128 * 1024 * 1024))
-		return 0;
-
-	return mask;
-}
-
-static void tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
-				   uint8_t	       *in_key,
-				   struct cfa_p4_eem_64b_entry *key_entry)
-{
-	key_entry->hdr.word1 = result->word1;
-
-	if (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)
-		key_entry->hdr.pointer = result->pointer;
-	else
-		key_entry->hdr.pointer = result->pointer;
-
-	memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);
-
-#ifdef TF_EEM_DEBUG
-	dump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, "Create raw:");
-#endif
-}
-
-/** insert EEM entry API
- *
- * returns:
- *  0
- *  TF_ERR	    - unable to get lock
- *
- * insert callback returns:
- *   0
- *   TF_ERR_EM_DUP  - key is already in table
- */
-static int tf_insert_eem_entry(struct tf_tbl_scope_cb	   *tbl_scope_cb,
-			       struct tf_insert_em_entry_parms *parms)
-{
-	uint32_t	   mask;
-	uint32_t	   key0_hash;
-	uint32_t	   key1_hash;
-	uint32_t	   key0_index;
-	uint32_t	   key1_index;
-	struct cfa_p4_eem_64b_entry key_entry;
-	uint32_t	   index;
-	enum hcapi_cfa_em_table_type table_type;
-	uint32_t	   gfid;
-	struct hcapi_cfa_hwop op;
-	struct hcapi_cfa_key_tbl key_tbl;
-	struct hcapi_cfa_key_data key_obj;
-	struct hcapi_cfa_key_loc key_loc;
-	uint64_t big_hash;
-	int rc;
-
-	/* Get mask to use on hash */
-	mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
-
-	if (!mask)
-		return -EINVAL;
-
-#ifdef TF_EEM_DEBUG
-	dump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, "In Key");
-#endif
-
-	big_hash = hcapi_cfa_key_hash((uint64_t *)parms->key,
-				      (TF_HW_EM_KEY_MAX_SIZE + 4) * 8);
-	key0_hash = (uint32_t)(big_hash >> 32);
-	key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF);
-
-	key0_index = key0_hash & mask;
-	key1_index = key1_hash & mask;
-
-#ifdef TF_EEM_DEBUG
-	TFP_DRV_LOG(DEBUG, "Key0 hash:0x%08x\n", key0_hash);
-	TFP_DRV_LOG(DEBUG, "Key1 hash:0x%08x\n", key1_hash);
-#endif
-	/*
-	 * Use the "result" arg to populate all of the key entry then
-	 * store the byte swapped "raw" entry in a local copy ready
-	 * for insertion in to the table.
-	 */
-	tf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,
-				((uint8_t *)parms->key),
-				&key_entry);
-
-	/*
-	 * Try to add to Key0 table, if that does not work then
-	 * try the key1 table.
-	 */
-	index = key0_index;
-	op.opcode = HCAPI_CFA_HWOPS_ADD;
-	key_tbl.base0 =
-		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];
-	key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
-	key_obj.data = (uint8_t *)&key_entry;
-	key_obj.size = TF_EM_KEY_RECORD_SIZE;
-
-	rc = hcapi_cfa_key_hw_op(&op,
-				 &key_tbl,
-				 &key_obj,
-				 &key_loc);
-
-	if (rc == 0) {
-		table_type = TF_KEY0_TABLE;
-	} else {
-		index = key1_index;
-
-		key_tbl.base0 =
-			(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];
-		key_obj.offset =
-			(index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
-
-		rc = hcapi_cfa_key_hw_op(&op,
-					 &key_tbl,
-					 &key_obj,
-					 &key_loc);
-		if (rc != 0)
-			return rc;
-
-		table_type = TF_KEY1_TABLE;
-	}
-
-	TF_SET_GFID(gfid,
-		    index,
-		    table_type);
-	TF_SET_FLOW_ID(parms->flow_id,
-		       gfid,
-		       TF_GFID_TABLE_EXTERNAL,
-		       parms->dir);
-	TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
-				     0,
-				     0,
-				     0,
-				     index,
-				     0,
-				     table_type);
-
-	return 0;
-}
-
-/**
- * Insert EM internal entry API
- *
- *  returns:
- *     0 - Success
- */
-static int tf_insert_em_internal_entry(struct tf                       *tfp,
-				       struct tf_insert_em_entry_parms *parms)
-{
-	int       rc;
-	uint32_t  gfid;
-	uint16_t  rptr_index = 0;
-	uint8_t   rptr_entry = 0;
-	uint8_t   num_of_entries = 0;
-	struct tf_session *session =
-		(struct tf_session *)(tfp->session->core_data);
-	struct stack *pool = &session->em_pool[parms->dir];
-	uint32_t index;
-
-	rc = stack_pop(pool, &index);
-
-	if (rc != 0) {
-		TFP_DRV_LOG(ERR,
-		   "dir:%d, EM entry index allocation failed\n",
-		   parms->dir);
-		return rc;
-	}
-
-	rptr_index = index * TF_SESSION_EM_ENTRY_SIZE;
-	rc = tf_msg_insert_em_internal_entry(tfp,
-					     parms,
-					     &rptr_index,
-					     &rptr_entry,
-					     &num_of_entries);
-	if (rc != 0)
-		return -1;
-
-	PMD_DRV_LOG(
-		   ERR,
-		   "Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
-		   index * TF_SESSION_EM_ENTRY_SIZE,
-		   rptr_index,
-		   rptr_entry,
-		   num_of_entries);
-
-	TF_SET_GFID(gfid,
-		    ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
-		     rptr_entry),
-		    0); /* N/A for internal table */
-
-	TF_SET_FLOW_ID(parms->flow_id,
-		       gfid,
-		       TF_GFID_TABLE_INTERNAL,
-		       parms->dir);
-
-	TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
-				     num_of_entries,
-				     0,
-				     0,
-				     rptr_index,
-				     rptr_entry,
-				     0);
-	return 0;
-}
-
-/** Delete EM internal entry API
- *
- * returns:
- * 0
- * -EINVAL
- */
-static int tf_delete_em_internal_entry(struct tf                       *tfp,
-				       struct tf_delete_em_entry_parms *parms)
-{
-	int rc;
-	struct tf_session *session =
-		(struct tf_session *)(tfp->session->core_data);
-	struct stack *pool = &session->em_pool[parms->dir];
-
-	rc = tf_msg_delete_em_entry(tfp, parms);
-
-	/* Return resource to pool */
-	if (rc == 0)
-		stack_push(pool, parms->index / TF_SESSION_EM_ENTRY_SIZE);
-
-	return rc;
-}
-
-
-/** delete EEM hash entry API
- *
- * returns:
- *   0
- *   -EINVAL	  - parameter error
- *   TF_NO_SESSION    - bad session ID
- *   TF_ERR_TBL_SCOPE - invalid table scope
- *   TF_ERR_TBL_IF    - invalid table interface
- *
- * insert callback returns
- *   0
- *   TF_NO_EM_MATCH - entry not found
- */
-static int tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
-			       struct tf_delete_em_entry_parms *parms)
-{
-	enum hcapi_cfa_em_table_type hash_type;
-	uint32_t index;
-	struct hcapi_cfa_hwop op;
-	struct hcapi_cfa_key_tbl key_tbl;
-	struct hcapi_cfa_key_data key_obj;
-	struct hcapi_cfa_key_loc key_loc;
-	int rc;
-
-	if (parms->flow_handle == 0)
-		return -EINVAL;
-
-	TF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);
-	TF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);
-
-	op.opcode = HCAPI_CFA_HWOPS_DEL;
-	key_tbl.base0 =
-		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[
-			(hash_type == 0 ? TF_KEY0_TABLE : TF_KEY1_TABLE)];
-	key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
-	key_obj.data = NULL;
-	key_obj.size = TF_EM_KEY_RECORD_SIZE;
-
-	rc = hcapi_cfa_key_hw_op(&op,
-				 &key_tbl,
-				 &key_obj,
-				 &key_loc);
-
-	if (!rc)
-		return rc;
-
-	return 0;
-}
-
-/** insert EM hash entry API
- *
- *    returns:
- *    0       - Success
- *    -EINVAL - Error
- */
-int tf_em_insert_entry(struct tf *tfp,
-		       struct tf_insert_em_entry_parms *parms)
-{
-	struct tf_tbl_scope_cb *tbl_scope_cb;
-
-	tbl_scope_cb = tbl_scope_cb_find
-		((struct tf_session *)(tfp->session->core_data),
-		parms->tbl_scope_id);
-	if (tbl_scope_cb == NULL) {
-		TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
-		return -EINVAL;
-	}
-
-	/* Process the EM entry per Table Scope type */
-	if (parms->mem == TF_MEM_EXTERNAL)
-		/* External EEM */
-		return tf_insert_eem_entry
-			(tbl_scope_cb, parms);
-	else if (parms->mem == TF_MEM_INTERNAL)
-		/* Internal EM */
-		return tf_insert_em_internal_entry(tfp,	parms);
-
-	return -EINVAL;
-}
-
-/** Delete EM hash entry API
- *
- *    returns:
- *    0       - Success
- *    -EINVAL - Error
- */
-int tf_em_delete_entry(struct tf *tfp,
-		       struct tf_delete_em_entry_parms *parms)
-{
-	struct tf_tbl_scope_cb *tbl_scope_cb;
-
-	tbl_scope_cb = tbl_scope_cb_find
-		((struct tf_session *)(tfp->session->core_data),
-		parms->tbl_scope_id);
-	if (tbl_scope_cb == NULL) {
-		TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
-		return -EINVAL;
-	}
-	if (parms->mem == TF_MEM_EXTERNAL)
-		return tf_delete_eem_entry(tbl_scope_cb, parms);
-	else if (parms->mem == TF_MEM_INTERNAL)
-		return tf_delete_em_internal_entry(tfp, parms);
-
-	return -EINVAL;
-}
diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h
index 2262ae7..cf799c2 100644
--- a/drivers/net/bnxt/tf_core/tf_em.h
+++ b/drivers/net/bnxt/tf_core/tf_em.h
@@ -9,6 +9,7 @@
 #include "tf_core.h"
 #include "tf_session.h"
 
+#define TF_HACK_TBL_SCOPE_BASE 68
 #define SUPPORT_CFA_HW_P4 1
 #define SUPPORT_CFA_HW_P58 0
 #define SUPPORT_CFA_HW_P59 0
@@ -19,6 +20,9 @@
 #define TF_HW_EM_KEY_MAX_SIZE 52
 #define TF_EM_KEY_RECORD_SIZE 64
 
+#define TF_EM_MAX_MASK 0x7FFF
+#define TF_EM_MAX_ENTRY (128 * 1024 * 1024)
+
 /*
  * Used to build GFID:
  *
@@ -44,6 +48,47 @@ struct tf_em_64b_entry {
 	uint8_t key[TF_EM_KEY_RECORD_SIZE - sizeof(struct cfa_p4_eem_entry_hdr)];
 };
 
+/** EEM Memory Type
+ *
+ */
+enum tf_mem_type {
+	TF_EEM_MEM_TYPE_INVALID,
+	TF_EEM_MEM_TYPE_HOST,
+	TF_EEM_MEM_TYPE_SYSTEM
+};
+
+/**
+ * tf_em_cfg_parms definition
+ */
+struct tf_em_cfg_parms {
+	/**
+	 * [in] Num entries in resource config
+	 */
+	uint16_t num_elements;
+	/**
+	 * [in] Resource config
+	 */
+	struct tf_rm_element_cfg *cfg;
+	/**
+	 * Session resource allocations
+	 */
+	struct tf_session_resources *resources;
+	/**
+	 * [in] Memory type.
+	 */
+	enum tf_mem_type mem_type;
+};
+
+/**
+ * @page table Table
+ *
+ * @ref tf_alloc_eem_tbl_scope
+ *
+ * @ref tf_free_eem_tbl_scope_cb
+ *
+ * @ref tbl_scope_cb_find
+ */
+
 /**
  * Allocates EEM Table scope
  *
@@ -78,29 +123,258 @@ int tf_free_eem_tbl_scope_cb(struct tf *tfp,
 			     struct tf_free_tbl_scope_parms *parms);
 
 /**
- * Function to search for table scope control block structure
- * with specified table scope ID.
+ * Insert record in to internal EM table
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_insert_int_entry(struct tf *tfp,
+			   struct tf_insert_em_entry_parms *parms);
+
+/**
+ * Delete record from internal EM table
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_delete_int_entry(struct tf *tfp,
+			   struct tf_delete_em_entry_parms *parms);
+
+/**
+ * Insert record in to external EEM table
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_insert_ext_entry(struct tf *tfp,
+			   struct tf_insert_em_entry_parms *parms);
+
+/**
+ * Insert record from external EEM table
  *
- * [in] session
- *   Session to use for the search of the table scope control block
- * [in] tbl_scope_id
- *   Table scope ID to search for
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
  *
  * Returns:
- *  Pointer to the found table scope control block struct or NULL if
- *  table scope control block struct not found
+ *   0       - Success
+ *   -EINVAL - Parameter error
  */
-struct tf_tbl_scope_cb *tbl_scope_cb_find(struct tf_session *session,
-					  uint32_t tbl_scope_id);
+int tf_em_delete_ext_entry(struct tf *tfp,
+			   struct tf_delete_em_entry_parms *parms);
 
-void *tf_em_get_table_page(struct tf_tbl_scope_cb *tbl_scope_cb,
-			   enum tf_dir dir,
-			   uint32_t offset,
-			   enum hcapi_cfa_em_table_type table_type);
+/**
+ * Insert record in to external system EEM table
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_insert_ext_sys_entry(struct tf *tfp,
+			       struct tf_insert_em_entry_parms *parms);
+
+/**
+ * Delete record from external system EEM table
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_delete_ext_sys_entry(struct tf *tfp,
+			       struct tf_delete_em_entry_parms *parms);
 
-int tf_em_insert_entry(struct tf *tfp,
-		       struct tf_insert_em_entry_parms *parms);
+/**
+ * Bind internal EM device interface
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_int_bind(struct tf *tfp,
+		   struct tf_em_cfg_parms *parms);
 
-int tf_em_delete_entry(struct tf *tfp,
-		       struct tf_delete_em_entry_parms *parms);
+/**
+ * Unbind internal EM device interface
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_int_unbind(struct tf *tfp);
+
+/**
+ * Common bind for EEM device interface. Used for both host and
+ * system memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_common_bind(struct tf *tfp,
+			  struct tf_em_cfg_parms *parms);
+
+/**
+ * Common unbind for EEM device interface. Used for both host and
+ * system memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_common_unbind(struct tf *tfp);
+
+/**
+ * Alloc for external EEM using host memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_host_alloc(struct tf *tfp,
+			 struct tf_alloc_tbl_scope_parms *parms);
+
+/**
+ * Free for external EEM using host memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_host_free(struct tf *tfp,
+			struct tf_free_tbl_scope_parms *parms);
+
+/**
+ * Alloc for external EEM using system memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_system_alloc(struct tf *tfp,
+			 struct tf_alloc_tbl_scope_parms *parms);
+
+/**
+ * Free for external EEM using system memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_system_free(struct tf *tfp,
+			struct tf_free_tbl_scope_parms *parms);
+
+/**
+ * Common free for external EEM using host or system memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_common_free(struct tf *tfp,
+			  struct tf_free_tbl_scope_parms *parms);
+
+/**
+ * Common alloc for external EEM using host or system memory
+ *
+ * [in] tfp
+ *   Pointer to TruFlow handle
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+int tf_em_ext_common_alloc(struct tf *tfp,
+			   struct tf_alloc_tbl_scope_parms *parms);
 #endif /* _TF_EM_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
new file mode 100644
index 0000000..ba6aa7a
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -0,0 +1,281 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <math.h>
+#include <sys/param.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+
+#include "tf_core.h"
+#include "tf_util.h"
+#include "tf_common.h"
+#include "tf_em.h"
+#include "tf_em_common.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "tf_device.h"
+#include "tf_ext_flow_handle.h"
+#include "cfa_resource_types.h"
+
+#include "bnxt.h"
+
+
+/**
+ * EM DBs.
+ */
+void *eem_db[TF_DIR_MAX];
+
+/**
+ * Init flag, set on bind and cleared on unbind
+ */
+static uint8_t init;
+
+/**
+ * Host or system
+ */
+static enum tf_mem_type mem_type;
+
+/* API defined in tf_em.h */
+struct tf_tbl_scope_cb *
+tbl_scope_cb_find(struct tf_session *session,
+		  uint32_t tbl_scope_id)
+{
+	int i;
+	struct tf_rm_is_allocated_parms parms;
+	int allocated;
+
+	/* Check that id is valid */
+	parms.rm_db = eem_db[TF_DIR_RX];
+	parms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+	parms.index = tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
+	parms.allocated = &allocated;
+
+	i = tf_rm_is_allocated(&parms);
+
+	if (i < 0 || !allocated)
+		return NULL;
+
+	for (i = 0; i < TF_NUM_TBL_SCOPE; i++) {
+		if (session->tbl_scopes[i].tbl_scope_id == tbl_scope_id)
+			return &session->tbl_scopes[i];
+	}
+
+	return NULL;
+}
+
+int
+tf_create_tbl_pool_external(enum tf_dir dir,
+			    struct tf_tbl_scope_cb *tbl_scope_cb,
+			    uint32_t num_entries,
+			    uint32_t entry_sz_bytes)
+{
+	struct tfp_calloc_parms parms;
+	uint32_t i;
+	int32_t j;
+	int rc = 0;
+	struct stack *pool = &tbl_scope_cb->ext_act_pool[dir];
+
+	parms.nitems = num_entries;
+	parms.size = sizeof(uint32_t);
+	parms.alignment = 0;
+
+	if (tfp_calloc(&parms) != 0) {
+		TFP_DRV_LOG(ERR, "%s: TBL: external pool failure %s\n",
+			    tf_dir_2_str(dir), strerror(ENOMEM));
+		return -ENOMEM;
+	}
+
+	/* Create empty stack
+	 */
+	rc = stack_init(num_entries, parms.mem_va, pool);
+
+	if (rc != 0) {
+		TFP_DRV_LOG(ERR, "%s: TBL: stack init failure %s\n",
+			    tf_dir_2_str(dir), strerror(-rc));
+		goto cleanup;
+	}
+
+	/* Save the  malloced memory address so that it can
+	 * be freed when the table scope is freed.
+	 */
+	tbl_scope_cb->ext_act_pool_mem[dir] = (uint32_t *)parms.mem_va;
+
+	/* Fill pool with indexes in reverse
+	 */
+	j = (num_entries - 1) * entry_sz_bytes;
+
+	for (i = 0; i < num_entries; i++) {
+		rc = stack_push(pool, j);
+		if (rc != 0) {
+			TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
+				    tf_dir_2_str(dir), strerror(-rc));
+			goto cleanup;
+		}
+
+		if (j < 0) {
+			TFP_DRV_LOG(ERR, "%d TBL: invalid offset (%d)\n",
+				    dir, j);
+			goto cleanup;
+		}
+		j -= entry_sz_bytes;
+	}
+
+	if (!stack_is_full(pool)) {
+		rc = -EINVAL;
+		TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
+			    tf_dir_2_str(dir), strerror(-rc));
+		goto cleanup;
+	}
+	return 0;
+cleanup:
+	tfp_free((void *)parms.mem_va);
+	return rc;
+}
+
+/**
+ * Destroy External Tbl pool of memory indexes.
+ *
+ * [in] dir
+ *   direction
+ * [in] tbl_scope_cb
+ *   pointer to the table scope
+ */
+void
+tf_destroy_tbl_pool_external(enum tf_dir dir,
+			     struct tf_tbl_scope_cb *tbl_scope_cb)
+{
+	uint32_t *ext_act_pool_mem =
+		tbl_scope_cb->ext_act_pool_mem[dir];
+
+	tfp_free(ext_act_pool_mem);
+}
+
+uint32_t
+tf_em_get_key_mask(int num_entries)
+{
+	uint32_t mask = num_entries - 1;
+
+	if (num_entries & TF_EM_MAX_MASK)
+		return 0;
+
+	if (num_entries > TF_EM_MAX_ENTRY)
+		return 0;
+
+	return mask;
+}
+
+void
+tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
+		       uint8_t *in_key,
+		       struct cfa_p4_eem_64b_entry *key_entry)
+{
+	key_entry->hdr.word1 = result->word1;
+
+	if (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)
+		key_entry->hdr.pointer = result->pointer;
+	else
+		key_entry->hdr.pointer = result->pointer;
+
+	memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);
+
+#ifdef TF_EEM_DEBUG
+	dump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, "Create raw:");
+#endif
+}
+
+int
+tf_em_ext_common_bind(struct tf *tfp,
+		      struct tf_em_cfg_parms *parms)
+{
+	int rc;
+	int i;
+	struct tf_rm_create_db_parms db_cfg = { 0 };
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (init) {
+		TFP_DRV_LOG(ERR,
+			    "Identifier already initialized\n");
+		return -EINVAL;
+	}
+
+	db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
+	db_cfg.num_elements = parms->num_elements;
+	db_cfg.cfg = parms->cfg;
+
+	for (i = 0; i < TF_DIR_MAX; i++) {
+		db_cfg.dir = i;
+		db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
+		db_cfg.rm_db = &eem_db[i];
+		rc = tf_rm_create_db(tfp, &db_cfg);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s: EM DB creation failed\n",
+				    tf_dir_2_str(i));
+
+			return rc;
+		}
+	}
+
+	mem_type = parms->mem_type;
+	init = 1;
+
+	return 0;
+}
+
+int
+tf_em_ext_common_unbind(struct tf *tfp)
+{
+	int rc;
+	int i;
+	struct tf_rm_free_db_parms fparms = { 0 };
+
+	TF_CHECK_PARMS1(tfp);
+
+	/* Bail if nothing has been initialized done silent as to
+	 * allow for creation cleanup.
+	 */
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "No EM DBs created\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < TF_DIR_MAX; i++) {
+		fparms.dir = i;
+		fparms.rm_db = eem_db[i];
+		rc = tf_rm_free_db(tfp, &fparms);
+		if (rc)
+			return rc;
+
+		eem_db[i] = NULL;
+	}
+
+	init = 0;
+
+	return 0;
+}
+
+int
+tf_em_ext_common_alloc(struct tf *tfp,
+		       struct tf_alloc_tbl_scope_parms *parms)
+{
+	if (mem_type == TF_EEM_MEM_TYPE_HOST)
+		return tf_em_ext_host_alloc(tfp, parms);
+	else
+		return tf_em_ext_system_alloc(tfp, parms);
+}
+
+int
+tf_em_ext_common_free(struct tf *tfp,
+		      struct tf_free_tbl_scope_parms *parms)
+{
+	if (mem_type == TF_EEM_MEM_TYPE_HOST)
+		return tf_em_ext_host_free(tfp, parms);
+	else
+		return tf_em_ext_system_free(tfp, parms);
+}
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.h b/drivers/net/bnxt/tf_core/tf_em_common.h
new file mode 100644
index 0000000..45699a7
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_em_common.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_EM_COMMON_H_
+#define _TF_EM_COMMON_H_
+
+#include "tf_core.h"
+#include "tf_session.h"
+
+
+/**
+ * Function to search for table scope control block structure
+ * with specified table scope ID.
+ *
+ * [in] session
+ *   Session to use for the search of the table scope control block
+ * [in] tbl_scope_id
+ *   Table scope ID to search for
+ *
+ * Returns:
+ *  Pointer to the found table scope control block struct or NULL if
+ *   table scope control block struct not found
+ */
+struct tf_tbl_scope_cb *tbl_scope_cb_find(struct tf_session *session,
+					  uint32_t tbl_scope_id);
+
+/**
+ * Create and initialize a stack to use for action entries
+ *
+ * [in] dir
+ *   Direction
+ * [in] tbl_scope_id
+ *   Table scope ID
+ * [in] num_entries
+ *   Number of EEM entries
+ * [in] entry_sz_bytes
+ *   Size of the entry
+ *
+ * Returns:
+ *   0       - Success
+ *   -ENOMEM - Out of memory
+ *   -EINVAL - Failure
+ */
+int tf_create_tbl_pool_external(enum tf_dir dir,
+				struct tf_tbl_scope_cb *tbl_scope_cb,
+				uint32_t num_entries,
+				uint32_t entry_sz_bytes);
+
+/**
+ * Delete and cleanup action record allocation stack
+ *
+ * [in] dir
+ *   Direction
+ * [in] tbl_scope_id
+ *   Table scope ID
+ *
+ */
+void tf_destroy_tbl_pool_external(enum tf_dir dir,
+				  struct tf_tbl_scope_cb *tbl_scope_cb);
+
+/**
+ * Get hash mask for current EEM table size
+ *
+ * [in] num_entries
+ *   Number of EEM entries
+ */
+uint32_t tf_em_get_key_mask(int num_entries);
+
+/**
+ * Populate key_entry
+ *
+ * [in] result
+ *   Entry data
+ * [in] in_key
+ *   Key data
+ * [out] key_entry
+ *   Completed key record
+ */
+void tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
+			    uint8_t	       *in_key,
+			    struct cfa_p4_eem_64b_entry *key_entry);
+
+/**
+ * Find base page address for offset into specified table type
+ *
+ * [in] tbl_scope_cb
+ *   Table scope
+ * [in] dir
+ *   Direction
+ * [in] Offset
+ *   Offset in to table
+ * [in] table_type
+ *   Table type
+ *
+ * Returns:
+ *
+ * 0                                 - Failure
+ * Void pointer to page base address - Success
+ */
+void *tf_em_get_table_page(struct tf_tbl_scope_cb *tbl_scope_cb,
+			   enum tf_dir dir,
+			   uint32_t offset,
+			   enum hcapi_cfa_em_table_type table_type);
+
+#endif /* _TF_EM_COMMON_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em_host.c b/drivers/net/bnxt/tf_core/tf_em_host.c
new file mode 100644
index 0000000..11899c6
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_em_host.c
@@ -0,0 +1,1149 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <math.h>
+#include <sys/param.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+
+#include "tf_core.h"
+#include "tf_util.h"
+#include "tf_common.h"
+#include "tf_em.h"
+#include "tf_em_common.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "lookup3.h"
+#include "tf_ext_flow_handle.h"
+
+#include "bnxt.h"
+
+
+#define PTU_PTE_VALID          0x1UL
+#define PTU_PTE_LAST           0x2UL
+#define PTU_PTE_NEXT_TO_LAST   0x4UL
+
+/* Number of pointers per page_size */
+#define MAX_PAGE_PTRS(page_size)  ((page_size) / sizeof(void *))
+
+#define TF_EM_PG_SZ_4K        (1 << 12)
+#define TF_EM_PG_SZ_8K        (1 << 13)
+#define TF_EM_PG_SZ_64K       (1 << 16)
+#define TF_EM_PG_SZ_256K      (1 << 18)
+#define TF_EM_PG_SZ_1M        (1 << 20)
+#define TF_EM_PG_SZ_2M        (1 << 21)
+#define TF_EM_PG_SZ_4M        (1 << 22)
+#define TF_EM_PG_SZ_1G        (1 << 30)
+
+#define TF_EM_CTX_ID_INVALID   0xFFFF
+
+#define TF_EM_MIN_ENTRIES     (1 << 15) /* 32K */
+#define TF_EM_MAX_ENTRIES     (1 << 27) /* 128M */
+
+/**
+ * EM DBs.
+ */
+extern void *eem_db[TF_DIR_MAX];
+
+/**
+ * Function to free a page table
+ *
+ * [in] tp
+ *   Pointer to the page table to free
+ */
+static void
+tf_em_free_pg_tbl(struct hcapi_cfa_em_page_tbl *tp)
+{
+	uint32_t i;
+
+	for (i = 0; i < tp->pg_count; i++) {
+		if (!tp->pg_va_tbl[i]) {
+			TFP_DRV_LOG(WARNING,
+				    "No mapping for page: %d table: %016" PRIu64 "\n",
+				    i,
+				    (uint64_t)(uintptr_t)tp);
+			continue;
+		}
+
+		tfp_free(tp->pg_va_tbl[i]);
+		tp->pg_va_tbl[i] = NULL;
+	}
+
+	tp->pg_count = 0;
+	tfp_free(tp->pg_va_tbl);
+	tp->pg_va_tbl = NULL;
+	tfp_free(tp->pg_pa_tbl);
+	tp->pg_pa_tbl = NULL;
+}
+
+/**
+ * Function to free an EM table
+ *
+ * [in] tbl
+ *   Pointer to the EM table to free
+ */
+static void
+tf_em_free_page_table(struct hcapi_cfa_em_table *tbl)
+{
+	struct hcapi_cfa_em_page_tbl *tp;
+	int i;
+
+	for (i = 0; i < tbl->num_lvl; i++) {
+		tp = &tbl->pg_tbl[i];
+		TFP_DRV_LOG(INFO,
+			   "EEM: Freeing page table: size %u lvl %d cnt %u\n",
+			   TF_EM_PAGE_SIZE,
+			    i,
+			    tp->pg_count);
+
+		tf_em_free_pg_tbl(tp);
+	}
+
+	tbl->l0_addr = NULL;
+	tbl->l0_dma_addr = 0;
+	tbl->num_lvl = 0;
+	tbl->num_data_pages = 0;
+}
+
+/**
+ * Allocation of page tables
+ *
+ * [in] tfp
+ *   Pointer to a TruFlow handle
+ *
+ * [in] pg_count
+ *   Page count to allocate
+ *
+ * [in] pg_size
+ *   Size of each page
+ *
+ * Returns:
+ *   0       - Success
+ *   -ENOMEM - Out of memmory
+ */
+static int
+tf_em_alloc_pg_tbl(struct hcapi_cfa_em_page_tbl *tp,
+		   uint32_t pg_count,
+		   uint32_t pg_size)
+{
+	uint32_t i;
+	struct tfp_calloc_parms parms;
+
+	parms.nitems = pg_count;
+	parms.size = sizeof(void *);
+	parms.alignment = 0;
+
+	if (tfp_calloc(&parms) != 0)
+		return -ENOMEM;
+
+	tp->pg_va_tbl = parms.mem_va;
+
+	if (tfp_calloc(&parms) != 0) {
+		tfp_free(tp->pg_va_tbl);
+		return -ENOMEM;
+	}
+
+	tp->pg_pa_tbl = parms.mem_va;
+
+	tp->pg_count = 0;
+	tp->pg_size = pg_size;
+
+	for (i = 0; i < pg_count; i++) {
+		parms.nitems = 1;
+		parms.size = pg_size;
+		parms.alignment = TF_EM_PAGE_ALIGNMENT;
+
+		if (tfp_calloc(&parms) != 0)
+			goto cleanup;
+
+		tp->pg_pa_tbl[i] = (uintptr_t)parms.mem_pa;
+		tp->pg_va_tbl[i] = parms.mem_va;
+
+		memset(tp->pg_va_tbl[i], 0, pg_size);
+		tp->pg_count++;
+	}
+
+	return 0;
+
+cleanup:
+	tf_em_free_pg_tbl(tp);
+	return -ENOMEM;
+}
+
+/**
+ * Allocates EM page tables
+ *
+ * [in] tbl
+ *   Table to allocate pages for
+ *
+ * Returns:
+ *   0       - Success
+ *   -ENOMEM - Out of memmory
+ */
+static int
+tf_em_alloc_page_table(struct hcapi_cfa_em_table *tbl)
+{
+	struct hcapi_cfa_em_page_tbl *tp;
+	int rc = 0;
+	int i;
+	uint32_t j;
+
+	for (i = 0; i < tbl->num_lvl; i++) {
+		tp = &tbl->pg_tbl[i];
+
+		rc = tf_em_alloc_pg_tbl(tp,
+					tbl->page_cnt[i],
+					TF_EM_PAGE_SIZE);
+		if (rc) {
+			TFP_DRV_LOG(WARNING,
+				"Failed to allocate page table: lvl: %d, rc:%s\n",
+				i,
+				strerror(-rc));
+			goto cleanup;
+		}
+
+		for (j = 0; j < tp->pg_count; j++) {
+			TFP_DRV_LOG(INFO,
+				"EEM: Allocated page table: size %u lvl %d cnt"
+				" %u VA:%p PA:%p\n",
+				TF_EM_PAGE_SIZE,
+				i,
+				tp->pg_count,
+				(void *)(uintptr_t)tp->pg_va_tbl[j],
+				(void *)(uintptr_t)tp->pg_pa_tbl[j]);
+		}
+	}
+	return rc;
+
+cleanup:
+	tf_em_free_page_table(tbl);
+	return rc;
+}
+
+/**
+ * Links EM page tables
+ *
+ * [in] tp
+ *   Pointer to page table
+ *
+ * [in] tp_next
+ *   Pointer to the next page table
+ *
+ * [in] set_pte_last
+ *   Flag controlling if the page table is last
+ */
+static void
+tf_em_link_page_table(struct hcapi_cfa_em_page_tbl *tp,
+		      struct hcapi_cfa_em_page_tbl *tp_next,
+		      bool set_pte_last)
+{
+	uint64_t *pg_pa = tp_next->pg_pa_tbl;
+	uint64_t *pg_va;
+	uint64_t valid;
+	uint32_t k = 0;
+	uint32_t i;
+	uint32_t j;
+
+	for (i = 0; i < tp->pg_count; i++) {
+		pg_va = tp->pg_va_tbl[i];
+
+		for (j = 0; j < MAX_PAGE_PTRS(tp->pg_size); j++) {
+			if (k == tp_next->pg_count - 2 && set_pte_last)
+				valid = PTU_PTE_NEXT_TO_LAST | PTU_PTE_VALID;
+			else if (k == tp_next->pg_count - 1 && set_pte_last)
+				valid = PTU_PTE_LAST | PTU_PTE_VALID;
+			else
+				valid = PTU_PTE_VALID;
+
+			pg_va[j] = tfp_cpu_to_le_64(pg_pa[k] | valid);
+			if (++k >= tp_next->pg_count)
+				return;
+		}
+	}
+}
+
+/**
+ * Setup a EM page table
+ *
+ * [in] tbl
+ *   Pointer to EM page table
+ */
+static void
+tf_em_setup_page_table(struct hcapi_cfa_em_table *tbl)
+{
+	struct hcapi_cfa_em_page_tbl *tp_next;
+	struct hcapi_cfa_em_page_tbl *tp;
+	bool set_pte_last = 0;
+	int i;
+
+	for (i = 0; i < tbl->num_lvl - 1; i++) {
+		tp = &tbl->pg_tbl[i];
+		tp_next = &tbl->pg_tbl[i + 1];
+		if (i == tbl->num_lvl - 2)
+			set_pte_last = 1;
+		tf_em_link_page_table(tp, tp_next, set_pte_last);
+	}
+
+	tbl->l0_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_va_tbl[0];
+	tbl->l0_dma_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_pa_tbl[0];
+}
+
+/**
+ * Given the page size, size of each data item (entry size),
+ * and the total number of entries needed, determine the number
+ * of page table levels and the number of data pages required.
+ *
+ * [in] page_size
+ *   Page size
+ *
+ * [in] entry_size
+ *   Entry size
+ *
+ * [in] num_entries
+ *   Number of entries needed
+ *
+ * [out] num_data_pages
+ *   Number of pages required
+ *
+ * Returns:
+ *   Success  - Number of EM page levels required
+ *   -ENOMEM  - Out of memory
+ */
+static int
+tf_em_size_page_tbl_lvl(uint32_t page_size,
+			uint32_t entry_size,
+			uint32_t num_entries,
+			uint64_t *num_data_pages)
+{
+	uint64_t lvl_data_size = page_size;
+	int lvl = TF_PT_LVL_0;
+	uint64_t data_size;
+
+	*num_data_pages = 0;
+	data_size = (uint64_t)num_entries * entry_size;
+
+	while (lvl_data_size < data_size) {
+		lvl++;
+
+		if (lvl == TF_PT_LVL_1)
+			lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
+				page_size;
+		else if (lvl == TF_PT_LVL_2)
+			lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
+				MAX_PAGE_PTRS(page_size) * page_size;
+		else
+			return -ENOMEM;
+	}
+
+	*num_data_pages = roundup(data_size, page_size) / page_size;
+
+	return lvl;
+}
+
+/**
+ * Return the number of page table pages needed to
+ * reference the given number of next level pages.
+ *
+ * [in] num_pages
+ *   Number of EM pages
+ *
+ * [in] page_size
+ *   Size of each EM page
+ *
+ * Returns:
+ *   Number of EM page table pages
+ */
+static uint32_t
+tf_em_page_tbl_pgcnt(uint32_t num_pages,
+		     uint32_t page_size)
+{
+	return roundup(num_pages, MAX_PAGE_PTRS(page_size)) /
+		       MAX_PAGE_PTRS(page_size);
+	return 0;
+}
+
+/**
+ * Given the number of data pages, page_size and the maximum
+ * number of page table levels (already determined), size
+ * the number of page table pages required at each level.
+ *
+ * [in] max_lvl
+ *   Max number of levels
+ *
+ * [in] num_data_pages
+ *   Number of EM data pages
+ *
+ * [in] page_size
+ *   Size of an EM page
+ *
+ * [out] *page_cnt
+ *   EM page count
+ */
+static void
+tf_em_size_page_tbls(int max_lvl,
+		     uint64_t num_data_pages,
+		     uint32_t page_size,
+		     uint32_t *page_cnt)
+{
+	if (max_lvl == TF_PT_LVL_0) {
+		page_cnt[TF_PT_LVL_0] = num_data_pages;
+	} else if (max_lvl == TF_PT_LVL_1) {
+		page_cnt[TF_PT_LVL_1] = num_data_pages;
+		page_cnt[TF_PT_LVL_0] =
+		tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
+	} else if (max_lvl == TF_PT_LVL_2) {
+		page_cnt[TF_PT_LVL_2] = num_data_pages;
+		page_cnt[TF_PT_LVL_1] =
+		tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_2], page_size);
+		page_cnt[TF_PT_LVL_0] =
+		tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
+	} else {
+		return;
+	}
+}
+
+/**
+ * Size the EM table based on capabilities
+ *
+ * [in] tbl
+ *   EM table to size
+ *
+ * Returns:
+ *   0        - Success
+ *   - EINVAL - Parameter error
+ *   - ENOMEM - Out of memory
+ */
+static int
+tf_em_size_table(struct hcapi_cfa_em_table *tbl)
+{
+	uint64_t num_data_pages;
+	uint32_t *page_cnt;
+	int max_lvl;
+	uint32_t num_entries;
+	uint32_t cnt = TF_EM_MIN_ENTRIES;
+
+	/* Ignore entry if both size and number are zero */
+	if (!tbl->entry_size && !tbl->num_entries)
+		return 0;
+
+	/* If only one is set then error */
+	if (!tbl->entry_size || !tbl->num_entries)
+		return -EINVAL;
+
+	/* Determine number of page table levels and the number
+	 * of data pages needed to process the given eem table.
+	 */
+	if (tbl->type == TF_RECORD_TABLE) {
+		/*
+		 * For action records just a memory size is provided. Work
+		 * backwards to resolve to number of entries
+		 */
+		num_entries = tbl->num_entries / tbl->entry_size;
+		if (num_entries < TF_EM_MIN_ENTRIES) {
+			num_entries = TF_EM_MIN_ENTRIES;
+		} else {
+			while (num_entries > cnt && cnt <= TF_EM_MAX_ENTRIES)
+				cnt *= 2;
+			num_entries = cnt;
+		}
+	} else {
+		num_entries = tbl->num_entries;
+	}
+
+	max_lvl = tf_em_size_page_tbl_lvl(TF_EM_PAGE_SIZE,
+					  tbl->entry_size,
+					  tbl->num_entries,
+					  &num_data_pages);
+	if (max_lvl < 0) {
+		TFP_DRV_LOG(WARNING, "EEM: Failed to size page table levels\n");
+		TFP_DRV_LOG(WARNING,
+			    "table: %d data-sz: %016" PRIu64 " page-sz: %u\n",
+			    tbl->type, (uint64_t)num_entries * tbl->entry_size,
+			    TF_EM_PAGE_SIZE);
+		return -ENOMEM;
+	}
+
+	tbl->num_lvl = max_lvl + 1;
+	tbl->num_data_pages = num_data_pages;
+
+	/* Determine the number of pages needed at each level */
+	page_cnt = tbl->page_cnt;
+	memset(page_cnt, 0, sizeof(tbl->page_cnt));
+	tf_em_size_page_tbls(max_lvl, num_data_pages, TF_EM_PAGE_SIZE,
+				page_cnt);
+
+	TFP_DRV_LOG(INFO, "EEM: Sized page table: %d\n", tbl->type);
+	TFP_DRV_LOG(INFO,
+		    "EEM: lvls: %d sz: %016" PRIu64 " pgs: %016" PRIu64 " l0: %u l1: %u l2: %u\n",
+		    max_lvl + 1,
+		    (uint64_t)num_data_pages * TF_EM_PAGE_SIZE,
+		    num_data_pages,
+		    page_cnt[TF_PT_LVL_0],
+		    page_cnt[TF_PT_LVL_1],
+		    page_cnt[TF_PT_LVL_2]);
+
+	return 0;
+}
+
+/**
+ * Unregisters EM Ctx in Firmware
+ *
+ * [in] tfp
+ *   Pointer to a TruFlow handle
+ *
+ * [in] tbl_scope_cb
+ *   Pointer to a table scope control block
+ *
+ * [in] dir
+ *   Receive or transmit direction
+ */
+static void
+tf_em_ctx_unreg(struct tf *tfp,
+		struct tf_tbl_scope_cb *tbl_scope_cb,
+		int dir)
+{
+	struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
+	struct hcapi_cfa_em_table *tbl;
+	int i;
+
+	for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
+		tbl = &ctxp->em_tables[i];
+
+		if (tbl->num_entries != 0 && tbl->entry_size != 0) {
+			tf_msg_em_mem_unrgtr(tfp, &tbl->ctx_id);
+			tf_em_free_page_table(tbl);
+		}
+	}
+}
+
+/**
+ * Registers EM Ctx in Firmware
+ *
+ * [in] tfp
+ *   Pointer to a TruFlow handle
+ *
+ * [in] tbl_scope_cb
+ *   Pointer to a table scope control block
+ *
+ * [in] dir
+ *   Receive or transmit direction
+ *
+ * Returns:
+ *   0       - Success
+ *   -ENOMEM - Out of Memory
+ */
+static int
+tf_em_ctx_reg(struct tf *tfp,
+	      struct tf_tbl_scope_cb *tbl_scope_cb,
+	      int dir)
+{
+	struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
+	struct hcapi_cfa_em_table *tbl;
+	int rc;
+	int i;
+
+	for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
+		tbl = &ctxp->em_tables[i];
+
+		if (tbl->num_entries && tbl->entry_size) {
+			rc = tf_em_size_table(tbl);
+
+			if (rc)
+				goto cleanup;
+
+			rc = tf_em_alloc_page_table(tbl);
+			if (rc)
+				goto cleanup;
+
+			tf_em_setup_page_table(tbl);
+			rc = tf_msg_em_mem_rgtr(tfp,
+						tbl->num_lvl - 1,
+						TF_EM_PAGE_SIZE_ENUM,
+						tbl->l0_dma_addr,
+						&tbl->ctx_id);
+			if (rc)
+				goto cleanup;
+		}
+	}
+	return rc;
+
+cleanup:
+	tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
+	return rc;
+}
+
+
+/**
+ * Validates EM number of entries requested
+ *
+ * [in] tbl_scope_cb
+ *   Pointer to table scope control block to be populated
+ *
+ * [in] parms
+ *   Pointer to input parameters
+ *
+ * Returns:
+ *   0       - Success
+ *   -EINVAL - Parameter error
+ */
+static int
+tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,
+			   struct tf_alloc_tbl_scope_parms *parms)
+{
+	uint32_t cnt;
+
+	if (parms->rx_mem_size_in_mb != 0) {
+		uint32_t key_b = 2 * ((parms->rx_max_key_sz_in_bits / 8) + 1);
+		uint32_t action_b = ((parms->rx_max_action_entry_sz_in_bits / 8)
+				     + 1);
+		uint32_t num_entries = (parms->rx_mem_size_in_mb *
+					TF_MEGABYTE) / (key_b + action_b);
+
+		if (num_entries < TF_EM_MIN_ENTRIES) {
+			TFP_DRV_LOG(ERR, "EEM: Insufficient memory requested:"
+				    "%uMB\n",
+				    parms->rx_mem_size_in_mb);
+			return -EINVAL;
+		}
+
+		cnt = TF_EM_MIN_ENTRIES;
+		while (num_entries > cnt &&
+		       cnt <= TF_EM_MAX_ENTRIES)
+			cnt *= 2;
+
+		if (cnt > TF_EM_MAX_ENTRIES) {
+			TFP_DRV_LOG(ERR, "EEM: Invalid number of Tx requested: "
+				    "%u\n",
+		       (parms->tx_num_flows_in_k * TF_KILOBYTE));
+			return -EINVAL;
+		}
+
+		parms->rx_num_flows_in_k = cnt / TF_KILOBYTE;
+	} else {
+		if ((parms->rx_num_flows_in_k * TF_KILOBYTE) <
+		    TF_EM_MIN_ENTRIES ||
+		    (parms->rx_num_flows_in_k * TF_KILOBYTE) >
+		    tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Invalid number of Rx flows "
+				    "requested:%u max:%u\n",
+				    parms->rx_num_flows_in_k * TF_KILOBYTE,
+			tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported);
+			return -EINVAL;
+		}
+
+		/* must be a power-of-2 supported value
+		 * in the range 32K - 128M
+		 */
+		cnt = TF_EM_MIN_ENTRIES;
+		while ((parms->rx_num_flows_in_k * TF_KILOBYTE) != cnt &&
+		       cnt <= TF_EM_MAX_ENTRIES)
+			cnt *= 2;
+
+		if (cnt > TF_EM_MAX_ENTRIES) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Invalid number of Rx requested: %u\n",
+				    (parms->rx_num_flows_in_k * TF_KILOBYTE));
+			return -EINVAL;
+		}
+	}
+
+	if (parms->tx_mem_size_in_mb != 0) {
+		uint32_t key_b = 2 * (parms->tx_max_key_sz_in_bits / 8 + 1);
+		uint32_t action_b = ((parms->tx_max_action_entry_sz_in_bits / 8)
+				     + 1);
+		uint32_t num_entries = (parms->tx_mem_size_in_mb *
+					(TF_KILOBYTE * TF_KILOBYTE)) /
+			(key_b + action_b);
+
+		if (num_entries < TF_EM_MIN_ENTRIES) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Insufficient memory requested:%uMB\n",
+				    parms->rx_mem_size_in_mb);
+			return -EINVAL;
+		}
+
+		cnt = TF_EM_MIN_ENTRIES;
+		while (num_entries > cnt &&
+		       cnt <= TF_EM_MAX_ENTRIES)
+			cnt *= 2;
+
+		if (cnt > TF_EM_MAX_ENTRIES) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Invalid number of Tx requested: %u\n",
+		       (parms->tx_num_flows_in_k * TF_KILOBYTE));
+			return -EINVAL;
+		}
+
+		parms->tx_num_flows_in_k = cnt / TF_KILOBYTE;
+	} else {
+		if ((parms->tx_num_flows_in_k * TF_KILOBYTE) <
+		    TF_EM_MIN_ENTRIES ||
+		    (parms->tx_num_flows_in_k * TF_KILOBYTE) >
+		    tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Invalid number of Tx flows "
+				    "requested:%u max:%u\n",
+				    (parms->tx_num_flows_in_k * TF_KILOBYTE),
+			tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported);
+			return -EINVAL;
+		}
+
+		cnt = TF_EM_MIN_ENTRIES;
+		while ((parms->tx_num_flows_in_k * TF_KILOBYTE) != cnt &&
+		       cnt <= TF_EM_MAX_ENTRIES)
+			cnt *= 2;
+
+		if (cnt > TF_EM_MAX_ENTRIES) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Invalid number of Tx requested: %u\n",
+		       (parms->tx_num_flows_in_k * TF_KILOBYTE));
+			return -EINVAL;
+		}
+	}
+
+	if ((parms->rx_num_flows_in_k != 0) &&
+	    (parms->rx_max_key_sz_in_bits / 8 == 0)) {
+		TFP_DRV_LOG(ERR,
+			    "EEM: Rx key size required: %u\n",
+			    (parms->rx_max_key_sz_in_bits));
+		return -EINVAL;
+	}
+
+	if ((parms->tx_num_flows_in_k != 0) &&
+	    (parms->tx_max_key_sz_in_bits / 8 == 0)) {
+		TFP_DRV_LOG(ERR,
+			    "EEM: Tx key size required: %u\n",
+			    (parms->tx_max_key_sz_in_bits));
+		return -EINVAL;
+	}
+	/* Rx */
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries =
+		parms->rx_num_flows_in_k * TF_KILOBYTE;
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].entry_size =
+		parms->rx_max_key_sz_in_bits / 8;
+
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].num_entries =
+		parms->rx_num_flows_in_k * TF_KILOBYTE;
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].entry_size =
+		parms->rx_max_key_sz_in_bits / 8;
+
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].num_entries
+		= parms->rx_num_flows_in_k * TF_KILOBYTE;
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size
+		= parms->rx_max_action_entry_sz_in_bits / 8;
+
+	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries
+		= 0;
+
+	/* Tx */
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries =
+		parms->tx_num_flows_in_k * TF_KILOBYTE;
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].entry_size =
+		parms->tx_max_key_sz_in_bits / 8;
+
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].num_entries =
+		parms->tx_num_flows_in_k * TF_KILOBYTE;
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].entry_size =
+		parms->tx_max_key_sz_in_bits / 8;
+
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].num_entries
+		= parms->tx_num_flows_in_k * TF_KILOBYTE;
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size
+		= parms->tx_max_action_entry_sz_in_bits / 8;
+
+	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries
+		= 0;
+
+	return 0;
+}
+
+/** insert EEM entry API
+ *
+ * returns:
+ *  0
+ *  TF_ERR	    - unable to get lock
+ *
+ * insert callback returns:
+ *   0
+ *   TF_ERR_EM_DUP  - key is already in table
+ */
+static int
+tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
+		    struct tf_insert_em_entry_parms *parms)
+{
+	uint32_t mask;
+	uint32_t key0_hash;
+	uint32_t key1_hash;
+	uint32_t key0_index;
+	uint32_t key1_index;
+	struct cfa_p4_eem_64b_entry key_entry;
+	uint32_t index;
+	enum hcapi_cfa_em_table_type table_type;
+	uint32_t gfid;
+	struct hcapi_cfa_hwop op;
+	struct hcapi_cfa_key_tbl key_tbl;
+	struct hcapi_cfa_key_data key_obj;
+	struct hcapi_cfa_key_loc key_loc;
+	uint64_t big_hash;
+	int rc;
+
+	/* Get mask to use on hash */
+	mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
+
+	if (!mask)
+		return -EINVAL;
+
+#ifdef TF_EEM_DEBUG
+	dump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, "In Key");
+#endif
+
+	big_hash = hcapi_cfa_key_hash((uint64_t *)parms->key,
+				      (TF_HW_EM_KEY_MAX_SIZE + 4) * 8);
+	key0_hash = (uint32_t)(big_hash >> 32);
+	key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF);
+
+	key0_index = key0_hash & mask;
+	key1_index = key1_hash & mask;
+
+#ifdef TF_EEM_DEBUG
+	TFP_DRV_LOG(DEBUG, "Key0 hash:0x%08x\n", key0_hash);
+	TFP_DRV_LOG(DEBUG, "Key1 hash:0x%08x\n", key1_hash);
+#endif
+	/*
+	 * Use the "result" arg to populate all of the key entry then
+	 * store the byte swapped "raw" entry in a local copy ready
+	 * for insertion in to the table.
+	 */
+	tf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,
+				((uint8_t *)parms->key),
+				&key_entry);
+
+	/*
+	 * Try to add to Key0 table, if that does not work then
+	 * try the key1 table.
+	 */
+	index = key0_index;
+	op.opcode = HCAPI_CFA_HWOPS_ADD;
+	key_tbl.base0 =
+		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];
+	key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
+	key_obj.data = (uint8_t *)&key_entry;
+	key_obj.size = TF_EM_KEY_RECORD_SIZE;
+
+	rc = hcapi_cfa_key_hw_op(&op,
+				 &key_tbl,
+				 &key_obj,
+				 &key_loc);
+
+	if (rc == 0) {
+		table_type = TF_KEY0_TABLE;
+	} else {
+		index = key1_index;
+
+		key_tbl.base0 =
+			(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];
+		key_obj.offset =
+			(index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
+
+		rc = hcapi_cfa_key_hw_op(&op,
+					 &key_tbl,
+					 &key_obj,
+					 &key_loc);
+		if (rc != 0)
+			return rc;
+
+		table_type = TF_KEY1_TABLE;
+	}
+
+	TF_SET_GFID(gfid,
+		    index,
+		    table_type);
+	TF_SET_FLOW_ID(parms->flow_id,
+		       gfid,
+		       TF_GFID_TABLE_EXTERNAL,
+		       parms->dir);
+	TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
+				     0,
+				     0,
+				     0,
+				     index,
+				     0,
+				     table_type);
+
+	return 0;
+}
+
+/** delete EEM hash entry API
+ *
+ * returns:
+ *   0
+ *   -EINVAL	  - parameter error
+ *   TF_NO_SESSION    - bad session ID
+ *   TF_ERR_TBL_SCOPE - invalid table scope
+ *   TF_ERR_TBL_IF    - invalid table interface
+ *
+ * insert callback returns
+ *   0
+ *   TF_NO_EM_MATCH - entry not found
+ */
+static int
+tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
+		    struct tf_delete_em_entry_parms *parms)
+{
+	enum hcapi_cfa_em_table_type hash_type;
+	uint32_t index;
+	struct hcapi_cfa_hwop op;
+	struct hcapi_cfa_key_tbl key_tbl;
+	struct hcapi_cfa_key_data key_obj;
+	struct hcapi_cfa_key_loc key_loc;
+	int rc;
+
+	if (parms->flow_handle == 0)
+		return -EINVAL;
+
+	TF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);
+	TF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);
+
+	op.opcode = HCAPI_CFA_HWOPS_DEL;
+	key_tbl.base0 =
+		(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[
+			(hash_type == 0 ? TF_KEY0_TABLE : TF_KEY1_TABLE)];
+	key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
+	key_obj.data = NULL;
+	key_obj.size = TF_EM_KEY_RECORD_SIZE;
+
+	rc = hcapi_cfa_key_hw_op(&op,
+				 &key_tbl,
+				 &key_obj,
+				 &key_loc);
+
+	if (!rc)
+		return rc;
+
+	return 0;
+}
+
+/** insert EM hash entry API
+ *
+ *    returns:
+ *    0       - Success
+ *    -EINVAL - Error
+ */
+int
+tf_em_insert_ext_entry(struct tf *tfp,
+		       struct tf_insert_em_entry_parms *parms)
+{
+	struct tf_tbl_scope_cb *tbl_scope_cb;
+
+	tbl_scope_cb = tbl_scope_cb_find(
+		(struct tf_session *)(tfp->session->core_data),
+		parms->tbl_scope_id);
+	if (tbl_scope_cb == NULL) {
+		TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+		return -EINVAL;
+	}
+
+	return tf_insert_eem_entry(
+		tbl_scope_cb,
+		parms);
+}
+
+/** Delete EM hash entry API
+ *
+ *    returns:
+ *    0       - Success
+ *    -EINVAL - Error
+ */
+int
+tf_em_delete_ext_entry(struct tf *tfp,
+		       struct tf_delete_em_entry_parms *parms)
+{
+	struct tf_tbl_scope_cb *tbl_scope_cb;
+
+	tbl_scope_cb = tbl_scope_cb_find(
+		(struct tf_session *)(tfp->session->core_data),
+		parms->tbl_scope_id);
+	if (tbl_scope_cb == NULL) {
+		TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+		return -EINVAL;
+	}
+
+	return tf_delete_eem_entry(tbl_scope_cb, parms);
+}
+
+int
+tf_em_ext_host_alloc(struct tf *tfp,
+		     struct tf_alloc_tbl_scope_parms *parms)
+{
+	int rc;
+	enum tf_dir dir;
+	struct tf_tbl_scope_cb *tbl_scope_cb;
+	struct hcapi_cfa_em_table *em_tables;
+	struct tf_session *session;
+	struct tf_free_tbl_scope_parms free_parms;
+	struct tf_rm_allocate_parms aparms = { 0 };
+	struct tf_rm_free_parms fparms = { 0 };
+
+	session = (struct tf_session *)tfp->session->core_data;
+
+	/* Get Table Scope control block from the session pool */
+	aparms.rm_db = eem_db[TF_DIR_RX];
+	aparms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+	aparms.index = (uint32_t *)&parms->tbl_scope_id;
+	rc = tf_rm_allocate(&aparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to allocate table scope\n");
+		return rc;
+	}
+
+	parms->tbl_scope_id -= TF_HACK_TBL_SCOPE_BASE;
+	tbl_scope_cb = &session->tbl_scopes[parms->tbl_scope_id];
+	tbl_scope_cb->index = parms->tbl_scope_id;
+	tbl_scope_cb->tbl_scope_id = parms->tbl_scope_id;
+
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		rc = tf_msg_em_qcaps(tfp,
+				     dir,
+				     &tbl_scope_cb->em_caps[dir]);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Unable to query for EEM capability,"
+				    " rc:%s\n",
+				    strerror(-rc));
+			goto cleanup;
+		}
+	}
+
+	/*
+	 * Validate and setup table sizes
+	 */
+	if (tf_em_validate_num_entries(tbl_scope_cb, parms))
+		goto cleanup;
+
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		/*
+		 * Allocate tables and signal configuration to FW
+		 */
+		rc = tf_em_ctx_reg(tfp, tbl_scope_cb, dir);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Unable to register for EEM ctx,"
+				    " rc:%s\n",
+				    strerror(-rc));
+			goto cleanup;
+		}
+
+		em_tables = tbl_scope_cb->em_ctx_info[dir].em_tables;
+		rc = tf_msg_em_cfg(tfp,
+				   em_tables[TF_KEY0_TABLE].num_entries,
+				   em_tables[TF_KEY0_TABLE].ctx_id,
+				   em_tables[TF_KEY1_TABLE].ctx_id,
+				   em_tables[TF_RECORD_TABLE].ctx_id,
+				   em_tables[TF_EFC_TABLE].ctx_id,
+				   parms->hw_flow_cache_flush_timer,
+				   dir);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "TBL: Unable to configure EEM in firmware"
+				    " rc:%s\n",
+				    strerror(-rc));
+			goto cleanup_full;
+		}
+
+		rc = tf_msg_em_op(tfp,
+				  dir,
+				  HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_ENABLE);
+
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "EEM: Unable to enable EEM in firmware"
+				    " rc:%s\n",
+				    strerror(-rc));
+			goto cleanup_full;
+		}
+
+		/* Allocate the pool of offsets of the external memory.
+		 * Initially, this is a single fixed size pool for all external
+		 * actions related to a single table scope.
+		 */
+		rc = tf_create_tbl_pool_external(dir,
+					    tbl_scope_cb,
+					    em_tables[TF_RECORD_TABLE].num_entries,
+					    em_tables[TF_RECORD_TABLE].entry_size);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "%s TBL: Unable to allocate idx pools %s\n",
+				    tf_dir_2_str(dir),
+				    strerror(-rc));
+			goto cleanup_full;
+		}
+	}
+
+	return 0;
+
+cleanup_full:
+	free_parms.tbl_scope_id = parms->tbl_scope_id;
+	tf_em_ext_host_free(tfp, &free_parms);
+	return -EINVAL;
+
+cleanup:
+	/* Free Table control block */
+	fparms.rm_db = eem_db[TF_DIR_RX];
+	fparms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+	fparms.index = parms->tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
+	tf_rm_free(&fparms);
+	return -EINVAL;
+}
+
+int
+tf_em_ext_host_free(struct tf *tfp,
+		    struct tf_free_tbl_scope_parms *parms)
+{
+	int rc = 0;
+	enum tf_dir  dir;
+	struct tf_tbl_scope_cb *tbl_scope_cb;
+	struct tf_session *session;
+	struct tf_rm_free_parms aparms = { 0 };
+
+	session = (struct tf_session *)(tfp->session->core_data);
+
+	tbl_scope_cb = tbl_scope_cb_find(session,
+					 parms->tbl_scope_id);
+
+	if (tbl_scope_cb == NULL) {
+		TFP_DRV_LOG(ERR, "Table scope error\n");
+		return -EINVAL;
+	}
+
+	/* Free Table control block */
+	aparms.rm_db = eem_db[TF_DIR_RX];
+	aparms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+	aparms.index = parms->tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
+	rc = tf_rm_free(&aparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to free table scope\n");
+	}
+
+	/* free table scope locks */
+	for (dir = 0; dir < TF_DIR_MAX; dir++) {
+		/* Free associated external pools
+		 */
+		tf_destroy_tbl_pool_external(dir,
+					     tbl_scope_cb);
+		tf_msg_em_op(tfp,
+			     dir,
+			     HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_DISABLE);
+
+		/* free table scope and all associated resources */
+		tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
new file mode 100644
index 0000000..9be91ad
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+
+#include "tf_core.h"
+#include "tf_util.h"
+#include "tf_common.h"
+#include "tf_em.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "tf_ext_flow_handle.h"
+
+#include "bnxt.h"
+
+/**
+ * EM DBs.
+ */
+static void *em_db[TF_DIR_MAX];
+
+/**
+ * Init flag, set on bind and cleared on unbind
+ */
+static uint8_t init;
+
+/**
+ * Create EM Tbl pool of memory indexes.
+ *
+ * [in] session
+ *   Pointer to session
+ * [in] dir
+ *   direction
+ * [in] num_entries
+ *   number of entries to write
+ *
+ * Return:
+ *  0       - Success, entry allocated - no search support
+ *  -ENOMEM -EINVAL -EOPNOTSUPP
+ *          - Failure, entry not allocated, out of resources
+ */
+static int
+tf_create_em_pool(struct tf_session *session,
+		  enum tf_dir dir,
+		  uint32_t num_entries)
+{
+	struct tfp_calloc_parms parms;
+	uint32_t i, j;
+	int rc = 0;
+	struct stack *pool = &session->em_pool[dir];
+
+	parms.nitems = num_entries;
+	parms.size = sizeof(uint32_t);
+	parms.alignment = 0;
+
+	rc = tfp_calloc(&parms);
+
+	if (rc) {
+		TFP_DRV_LOG(ERR, "EM pool allocation failure %s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Create empty stack
+	 */
+	rc = stack_init(num_entries, (uint32_t *)parms.mem_va, pool);
+
+	if (rc) {
+		TFP_DRV_LOG(ERR, "EM pool stack init failure %s\n",
+			    strerror(-rc));
+		goto cleanup;
+	}
+
+	/* Fill pool with indexes
+	 */
+	j = num_entries - 1;
+
+	for (i = 0; i < num_entries; i++) {
+		rc = stack_push(pool, j);
+		if (rc) {
+			TFP_DRV_LOG(ERR, "EM pool stack push failure %s\n",
+				    strerror(-rc));
+			goto cleanup;
+		}
+		j--;
+	}
+
+	if (!stack_is_full(pool)) {
+		rc = -EINVAL;
+		TFP_DRV_LOG(ERR, "EM pool stack failure %s\n",
+			    strerror(-rc));
+		goto cleanup;
+	}
+
+	return 0;
+cleanup:
+	tfp_free((void *)parms.mem_va);
+	return rc;
+}
+
+/**
+ * Create EM Tbl pool of memory indexes.
+ *
+ * [in] session
+ *   Pointer to session
+ * [in] dir
+ *   direction
+ *
+ * Return:
+ */
+static void
+tf_free_em_pool(struct tf_session *session,
+		enum tf_dir dir)
+{
+	struct stack *pool = &session->em_pool[dir];
+	uint32_t *ptr;
+
+	ptr = stack_items(pool);
+
+	if (ptr != NULL)
+		tfp_free(ptr);
+}
+
+/**
+ * Insert EM internal entry API
+ *
+ *  returns:
+ *     0 - Success
+ */
+int
+tf_em_insert_int_entry(struct tf *tfp,
+		       struct tf_insert_em_entry_parms *parms)
+{
+	int rc;
+	uint32_t gfid;
+	uint16_t rptr_index = 0;
+	uint8_t rptr_entry = 0;
+	uint8_t num_of_entries = 0;
+	struct tf_session *session =
+		(struct tf_session *)(tfp->session->core_data);
+	struct stack *pool = &session->em_pool[parms->dir];
+	uint32_t index;
+
+	rc = stack_pop(pool, &index);
+
+	if (rc) {
+		PMD_DRV_LOG
+		  (ERR,
+		   "dir:%d, EM entry index allocation failed\n",
+		   parms->dir);
+		return rc;
+	}
+
+	rptr_index = index * TF_SESSION_EM_ENTRY_SIZE;
+	rc = tf_msg_insert_em_internal_entry(tfp,
+					     parms,
+					     &rptr_index,
+					     &rptr_entry,
+					     &num_of_entries);
+	if (rc)
+		return -1;
+
+	PMD_DRV_LOG
+		  (ERR,
+		   "Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
+		   index * TF_SESSION_EM_ENTRY_SIZE,
+		   rptr_index,
+		   rptr_entry,
+		   num_of_entries);
+
+	TF_SET_GFID(gfid,
+		    ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
+		     rptr_entry),
+		    0); /* N/A for internal table */
+
+	TF_SET_FLOW_ID(parms->flow_id,
+		       gfid,
+		       TF_GFID_TABLE_INTERNAL,
+		       parms->dir);
+
+	TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
+				     (uint32_t)num_of_entries,
+				     0,
+				     0,
+				     rptr_index,
+				     rptr_entry,
+				     0);
+	return 0;
+}
+
+
+/** Delete EM internal entry API
+ *
+ * returns:
+ * 0
+ * -EINVAL
+ */
+int
+tf_em_delete_int_entry(struct tf *tfp,
+		       struct tf_delete_em_entry_parms *parms)
+{
+	int rc = 0;
+	struct tf_session *session =
+		(struct tf_session *)(tfp->session->core_data);
+	struct stack *pool = &session->em_pool[parms->dir];
+
+	rc = tf_msg_delete_em_entry(tfp, parms);
+
+	/* Return resource to pool */
+	if (rc == 0)
+		stack_push(pool, parms->index / TF_SESSION_EM_ENTRY_SIZE);
+
+	return rc;
+}
+
+int
+tf_em_int_bind(struct tf *tfp,
+	       struct tf_em_cfg_parms *parms)
+{
+	int rc;
+	int i;
+	struct tf_rm_create_db_parms db_cfg = { 0 };
+	struct tf_session *session;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (init) {
+		TFP_DRV_LOG(ERR,
+			    "Identifier already initialized\n");
+		return -EINVAL;
+	}
+
+	session = (struct tf_session *)tfp->session->core_data;
+
+	for (i = 0; i < TF_DIR_MAX; i++) {
+		tf_create_em_pool(session,
+				  i,
+				  TF_SESSION_EM_POOL_SIZE);
+	}
+
+	/*
+	 * I'm not sure that this code is needed.
+	 * leaving for now until resolved
+	 */
+	if (parms->num_elements) {
+		db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
+		db_cfg.num_elements = parms->num_elements;
+		db_cfg.cfg = parms->cfg;
+
+		for (i = 0; i < TF_DIR_MAX; i++) {
+			db_cfg.dir = i;
+			db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
+			db_cfg.rm_db = &em_db[i];
+			rc = tf_rm_create_db(tfp, &db_cfg);
+			if (rc) {
+				TFP_DRV_LOG(ERR,
+					    "%s: EM DB creation failed\n",
+					    tf_dir_2_str(i));
+
+				return rc;
+			}
+		}
+	}
+
+	init = 1;
+	return 0;
+}
+
+int
+tf_em_int_unbind(struct tf *tfp)
+{
+	int rc;
+	int i;
+	struct tf_rm_free_db_parms fparms = { 0 };
+	struct tf_session *session;
+
+	TF_CHECK_PARMS1(tfp);
+
+	/* Bail if nothing has been initialized done silent as to
+	 * allow for creation cleanup.
+	 */
+	if (!init) {
+		TFP_DRV_LOG(ERR,
+			    "No EM DBs created\n");
+		return -EINVAL;
+	}
+
+	session = (struct tf_session *)tfp->session->core_data;
+
+	for (i = 0; i < TF_DIR_MAX; i++)
+		tf_free_em_pool(session, i);
+
+	for (i = 0; i < TF_DIR_MAX; i++) {
+		fparms.dir = i;
+		fparms.rm_db = em_db[i];
+		if (em_db[i] != NULL) {
+			rc = tf_rm_free_db(tfp, &fparms);
+			if (rc)
+				return rc;
+		}
+
+		em_db[i] = NULL;
+	}
+
+	init = 0;
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c
new file mode 100644
index 0000000..ee18a0c
--- /dev/null
+++ b/drivers/net/bnxt/tf_core/tf_em_system.c
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+
+#include "tf_core.h"
+#include "tf_em.h"
+#include "tf_em_common.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "lookup3.h"
+#include "tf_ext_flow_handle.h"
+
+#include "bnxt.h"
+
+
+/** insert EEM entry API
+ *
+ * returns:
+ *  0
+ *  TF_ERR	    - unable to get lock
+ *
+ * insert callback returns:
+ *   0
+ *   TF_ERR_EM_DUP  - key is already in table
+ */
+static int
+tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb __rte_unused,
+		    struct tf_insert_em_entry_parms *parms __rte_unused)
+{
+	return 0;
+}
+
+/** delete EEM hash entry API
+ *
+ * returns:
+ *   0
+ *   -EINVAL	  - parameter error
+ *   TF_NO_SESSION    - bad session ID
+ *   TF_ERR_TBL_SCOPE - invalid table scope
+ *   TF_ERR_TBL_IF    - invalid table interface
+ *
+ * insert callback returns
+ *   0
+ *   TF_NO_EM_MATCH - entry not found
+ */
+static int
+tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb __rte_unused,
+		    struct tf_delete_em_entry_parms *parms __rte_unused)
+{
+	return 0;
+}
+
+/** insert EM hash entry API
+ *
+ *    returns:
+ *    0       - Success
+ *    -EINVAL - Error
+ */
+int
+tf_em_insert_ext_sys_entry(struct tf *tfp,
+			   struct tf_insert_em_entry_parms *parms)
+{
+	struct tf_tbl_scope_cb *tbl_scope_cb;
+
+	tbl_scope_cb = tbl_scope_cb_find
+		((struct tf_session *)(tfp->session->core_data),
+		parms->tbl_scope_id);
+	if (tbl_scope_cb == NULL) {
+		TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+		return -EINVAL;
+	}
+
+	return tf_insert_eem_entry
+		(tbl_scope_cb, parms);
+}
+
+/** Delete EM hash entry API
+ *
+ *    returns:
+ *    0       - Success
+ *    -EINVAL - Error
+ */
+int
+tf_em_delete_ext_sys_entry(struct tf *tfp,
+			   struct tf_delete_em_entry_parms *parms)
+{
+	struct tf_tbl_scope_cb *tbl_scope_cb;
+
+	tbl_scope_cb = tbl_scope_cb_find
+		((struct tf_session *)(tfp->session->core_data),
+		parms->tbl_scope_id);
+	if (tbl_scope_cb == NULL) {
+		TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+		return -EINVAL;
+	}
+
+	return tf_delete_eem_entry(tbl_scope_cb, parms);
+}
+
+int
+tf_em_ext_system_alloc(struct tf *tfp __rte_unused,
+		       struct tf_alloc_tbl_scope_parms *parms __rte_unused)
+{
+	return 0;
+}
+
+int
+tf_em_ext_system_free(struct tf *tfp __rte_unused,
+		      struct tf_free_tbl_scope_parms *parms __rte_unused)
+{
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index 5020433..d8b80bc 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -19,82 +19,6 @@
 #include "tf_em.h"
 
 /**
- * Endian converts min and max values from the HW response to the query
- */
-#define TF_HW_RESP_TO_QUERY(query, index, response, element) do {            \
-	(query)->hw_query[index].min =                                       \
-		tfp_le_to_cpu_16(response. element ## _min);                 \
-	(query)->hw_query[index].max =                                       \
-		tfp_le_to_cpu_16(response. element ## _max);                 \
-} while (0)
-
-/**
- * Endian converts the number of entries from the alloc to the request
- */
-#define TF_HW_ALLOC_TO_REQ(alloc, index, request, element)                   \
-	(request. num_ ## element = tfp_cpu_to_le_16((alloc)->hw_num[index]))
-
-/**
- * Endian converts the start and stride value from the free to the request
- */
-#define TF_HW_FREE_TO_REQ(hw_entry, index, request, element) do {            \
-	request.element ## _start =                                          \
-		tfp_cpu_to_le_16(hw_entry[index].start);                     \
-	request.element ## _stride =                                         \
-		tfp_cpu_to_le_16(hw_entry[index].stride);                    \
-} while (0)
-
-/**
- * Endian converts the start and stride from the HW response to the
- * alloc
- */
-#define TF_HW_RESP_TO_ALLOC(hw_entry, index, response, element) do {         \
-	hw_entry[index].start =                                              \
-		tfp_le_to_cpu_16(response.element ## _start);                \
-	hw_entry[index].stride =                                             \
-		tfp_le_to_cpu_16(response.element ## _stride);               \
-} while (0)
-
-/**
- * Endian converts min and max values from the SRAM response to the
- * query
- */
-#define TF_SRAM_RESP_TO_QUERY(query, index, response, element) do {          \
-	(query)->sram_query[index].min =                                     \
-		tfp_le_to_cpu_16(response.element ## _min);                  \
-	(query)->sram_query[index].max =                                     \
-		tfp_le_to_cpu_16(response.element ## _max);                  \
-} while (0)
-
-/**
- * Endian converts the number of entries from the action (alloc) to
- * the request
- */
-#define TF_SRAM_ALLOC_TO_REQ(action, index, request, element)                \
-	(request. num_ ## element = tfp_cpu_to_le_16((action)->sram_num[index]))
-
-/**
- * Endian converts the start and stride value from the free to the request
- */
-#define TF_SRAM_FREE_TO_REQ(sram_entry, index, request, element) do {        \
-	request.element ## _start =                                          \
-		tfp_cpu_to_le_16(sram_entry[index].start);                   \
-	request.element ## _stride =                                         \
-		tfp_cpu_to_le_16(sram_entry[index].stride);                  \
-} while (0)
-
-/**
- * Endian converts the start and stride from the HW response to the
- * alloc
- */
-#define TF_SRAM_RESP_TO_ALLOC(sram_entry, index, response, element) do {     \
-	sram_entry[index].start =                                            \
-		tfp_le_to_cpu_16(response.element ## _start);                \
-	sram_entry[index].stride =                                           \
-		tfp_le_to_cpu_16(response.element ## _stride);               \
-} while (0)
-
-/**
  * This is the MAX data we can transport across regular HWRM
  */
 #define TF_PCI_BUF_SIZE_MAX 88
@@ -107,39 +31,6 @@ struct tf_msg_dma_buf {
 	uint64_t pa_addr;
 };
 
-static int
-tf_tcam_tbl_2_hwrm(enum tf_tcam_tbl_type tcam_type,
-		   uint32_t *hwrm_type)
-{
-	int rc = 0;
-
-	switch (tcam_type) {
-	case TF_TCAM_TBL_TYPE_L2_CTXT_TCAM:
-		*hwrm_type = TF_DEV_DATA_TYPE_TF_L2_CTX_ENTRY;
-		break;
-	case TF_TCAM_TBL_TYPE_PROF_TCAM:
-		*hwrm_type = TF_DEV_DATA_TYPE_TF_PROF_TCAM_ENTRY;
-		break;
-	case TF_TCAM_TBL_TYPE_WC_TCAM:
-		*hwrm_type = TF_DEV_DATA_TYPE_TF_WC_ENTRY;
-		break;
-	case TF_TCAM_TBL_TYPE_VEB_TCAM:
-		rc = -EOPNOTSUPP;
-		break;
-	case TF_TCAM_TBL_TYPE_SP_TCAM:
-		rc = -EOPNOTSUPP;
-		break;
-	case TF_TCAM_TBL_TYPE_CT_RULE_TCAM:
-		rc = -EOPNOTSUPP;
-		break;
-	default:
-		rc = -EOPNOTSUPP;
-		break;
-	}
-
-	return rc;
-}
-
 /**
  * Allocates a DMA buffer that can be used for message transfer.
  *
@@ -185,13 +76,8 @@ tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
 	tfp_free(buf->va_addr);
 }
 
-/**
- * NEW HWRM direct messages
- */
+/* HWRM Direct messages */
 
-/**
- * Sends session open request to TF Firmware
- */
 int
 tf_msg_session_open(struct tf *tfp,
 		    char *ctrl_chan_name,
@@ -222,9 +108,6 @@ tf_msg_session_open(struct tf *tfp,
 	return rc;
 }
 
-/**
- * Sends session attach request to TF Firmware
- */
 int
 tf_msg_session_attach(struct tf *tfp __rte_unused,
 		      char *ctrl_chan_name __rte_unused,
@@ -233,9 +116,6 @@ tf_msg_session_attach(struct tf *tfp __rte_unused,
 	return -1;
 }
 
-/**
- * Sends session close request to TF Firmware
- */
 int
 tf_msg_session_close(struct tf *tfp)
 {
@@ -261,14 +141,11 @@ tf_msg_session_close(struct tf *tfp)
 	return rc;
 }
 
-/**
- * Sends session query config request to TF Firmware
- */
 int
 tf_msg_session_qcfg(struct tf *tfp)
 {
 	int rc;
-	struct hwrm_tf_session_qcfg_input  req = { 0 };
+	struct hwrm_tf_session_qcfg_input req = { 0 };
 	struct hwrm_tf_session_qcfg_output resp = { 0 };
 	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
 	struct tfp_send_msg_parms parms = { 0 };
@@ -289,636 +166,6 @@ tf_msg_session_qcfg(struct tf *tfp)
 	return rc;
 }
 
-/**
- * Sends session HW resource query capability request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_qcaps(struct tf *tfp,
-			     enum tf_dir dir,
-			     struct tf_rm_hw_query *query)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_hw_resc_qcaps_input req = { 0 };
-	struct tf_session_hw_resc_qcaps_output resp = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	memset(query, 0, sizeof(*query));
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	MSG_PREP(parms,
-		 TF_KONG_MB,
-		 HWRM_TF,
-		 HWRM_TFT_SESSION_HW_RESC_QCAPS,
-		 req,
-		 resp);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	/* Process the response */
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_L2_CTXT_TCAM, resp,
-			    l2_ctx_tcam_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_PROF_FUNC, resp,
-			    prof_func);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_PROF_TCAM, resp,
-			    prof_tcam_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EM_PROF_ID, resp,
-			    em_prof_id);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EM_REC, resp,
-			    em_record_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, resp,
-			    wc_tcam_prof_id);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_WC_TCAM, resp,
-			    wc_tcam_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METER_PROF, resp,
-			    meter_profiles);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METER_INST,
-			    resp, meter_inst);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_MIRROR, resp,
-			    mirrors);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_UPAR, resp,
-			    upar);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_SP_TCAM, resp,
-			    sp_tcam_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_L2_FUNC, resp,
-			    l2_func);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_FKB, resp,
-			    flex_key_templ);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_TBL_SCOPE, resp,
-			    tbl_scope);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EPOCH0, resp,
-			    epoch0_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EPOCH1, resp,
-			    epoch1_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METADATA, resp,
-			    metadata);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_CT_STATE, resp,
-			    ct_state);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_RANGE_PROF, resp,
-			    range_prof);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_RANGE_ENTRY, resp,
-			    range_entries);
-	TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_LAG_ENTRY, resp,
-			    lag_tbl_entries);
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session HW resource allocation request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_alloc(struct tf *tfp __rte_unused,
-			     enum tf_dir dir,
-			     struct tf_rm_hw_alloc *hw_alloc __rte_unused,
-			     struct tf_rm_entry *hw_entry __rte_unused)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_hw_resc_alloc_input req = { 0 };
-	struct tf_session_hw_resc_alloc_output resp = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	memset(hw_entry, 0, sizeof(*hw_entry));
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
-			   l2_ctx_tcam_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_PROF_FUNC, req,
-			   prof_func_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_PROF_TCAM, req,
-			   prof_tcam_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EM_PROF_ID, req,
-			   em_prof_id);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EM_REC, req,
-			   em_record_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
-			   wc_tcam_prof_id);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_WC_TCAM, req,
-			   wc_tcam_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METER_PROF, req,
-			   meter_profiles);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METER_INST, req,
-			   meter_inst);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_MIRROR, req,
-			   mirrors);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_UPAR, req,
-			   upar);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_SP_TCAM, req,
-			   sp_tcam_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_L2_FUNC, req,
-			   l2_func);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_FKB, req,
-			   flex_key_templ);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_TBL_SCOPE, req,
-			   tbl_scope);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EPOCH0, req,
-			   epoch0_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EPOCH1, req,
-			   epoch1_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METADATA, req,
-			   metadata);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_CT_STATE, req,
-			   ct_state);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_RANGE_PROF, req,
-			   range_prof);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
-			   range_entries);
-	TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_LAG_ENTRY, req,
-			   lag_tbl_entries);
-
-	MSG_PREP(parms,
-		 TF_KONG_MB,
-		 HWRM_TF,
-		 HWRM_TFT_SESSION_HW_RESC_ALLOC,
-		 req,
-		 resp);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	/* Process the response */
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, resp,
-			    l2_ctx_tcam_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, resp,
-			    prof_func);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, resp,
-			    prof_tcam_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, resp,
-			    em_prof_id);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EM_REC, resp,
-			    em_record_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, resp,
-			    wc_tcam_prof_id);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, resp,
-			    wc_tcam_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METER_PROF, resp,
-			    meter_profiles);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METER_INST, resp,
-			    meter_inst);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_MIRROR, resp,
-			    mirrors);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_UPAR, resp,
-			    upar);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, resp,
-			    sp_tcam_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, resp,
-			    l2_func);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_FKB, resp,
-			    flex_key_templ);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, resp,
-			    tbl_scope);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EPOCH0, resp,
-			    epoch0_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EPOCH1, resp,
-			    epoch1_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METADATA, resp,
-			    metadata);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_CT_STATE, resp,
-			    ct_state);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, resp,
-			    range_prof);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, resp,
-			    range_entries);
-	TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, resp,
-			    lag_tbl_entries);
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session HW resource free request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_free(struct tf *tfp,
-			    enum tf_dir dir,
-			    struct tf_rm_entry *hw_entry)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_hw_resc_free_input req = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	memset(hw_entry, 0, sizeof(*hw_entry));
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
-			  l2_ctx_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, req,
-			  prof_func);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, req,
-			  prof_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, req,
-			  em_prof_id);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_REC, req,
-			  em_record_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
-			  wc_tcam_prof_id);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, req,
-			  wc_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_PROF, req,
-			  meter_profiles);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_INST, req,
-			  meter_inst);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_MIRROR, req,
-			  mirrors);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_UPAR, req,
-			  upar);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, req,
-			  sp_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, req,
-			  l2_func);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_FKB, req,
-			  flex_key_templ);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, req,
-			  tbl_scope);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH0, req,
-			  epoch0_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH1, req,
-			  epoch1_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METADATA, req,
-			  metadata);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_CT_STATE, req,
-			  ct_state);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, req,
-			  range_prof);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
-			  range_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, req,
-			  lag_tbl_entries);
-
-	MSG_PREP_NO_RESP(parms,
-			 TF_KONG_MB,
-			 HWRM_TF,
-			 HWRM_TFT_SESSION_HW_RESC_FREE,
-			 req);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session HW resource flush request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_flush(struct tf *tfp,
-			     enum tf_dir dir,
-			     struct tf_rm_entry *hw_entry)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_hw_resc_free_input req = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
-			  l2_ctx_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, req,
-			  prof_func);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, req,
-			  prof_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, req,
-			  em_prof_id);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_REC, req,
-			  em_record_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
-			  wc_tcam_prof_id);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, req,
-			  wc_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_PROF, req,
-			  meter_profiles);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_INST, req,
-			  meter_inst);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_MIRROR, req,
-			  mirrors);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_UPAR, req,
-			  upar);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, req,
-			  sp_tcam_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, req,
-			  l2_func);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_FKB, req,
-			  flex_key_templ);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, req,
-			  tbl_scope);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH0, req,
-			  epoch0_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH1, req,
-			  epoch1_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METADATA, req,
-			  metadata);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_CT_STATE, req,
-			  ct_state);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, req,
-			  range_prof);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
-			  range_entries);
-	TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, req,
-			  lag_tbl_entries);
-
-	MSG_PREP_NO_RESP(parms,
-			 TF_KONG_MB,
-			 TF_TYPE_TRUFLOW,
-			 HWRM_TFT_SESSION_HW_RESC_FLUSH,
-			 req);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource query capability request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_qcaps(struct tf *tfp __rte_unused,
-			       enum tf_dir dir,
-			       struct tf_rm_sram_query *query __rte_unused)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_sram_resc_qcaps_input req = { 0 };
-	struct tf_session_sram_resc_qcaps_output resp = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	MSG_PREP(parms,
-		 TF_KONG_MB,
-		 HWRM_TF,
-		 HWRM_TFT_SESSION_SRAM_RESC_QCAPS,
-		 req,
-		 resp);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	/* Process the response */
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_FULL_ACTION, resp,
-			      full_action);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_MCG, resp,
-			      mcg);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_8B, resp,
-			      encap_8b);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_16B, resp,
-			      encap_16b);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_64B, resp,
-			      encap_64b);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC, resp,
-			      sp_smac);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, resp,
-			      sp_smac_ipv4);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, resp,
-			      sp_smac_ipv6);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_COUNTER_64B, resp,
-			      counter_64b);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_SPORT, resp,
-			      nat_sport);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_DPORT, resp,
-			      nat_dport);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_S_IPV4, resp,
-			      nat_s_ipv4);
-	TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_D_IPV4, resp,
-			      nat_d_ipv4);
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource allocation request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_alloc(struct tf *tfp __rte_unused,
-			       enum tf_dir dir,
-			       struct tf_rm_sram_alloc *sram_alloc __rte_unused,
-			       struct tf_rm_entry *sram_entry __rte_unused)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_sram_resc_alloc_input req = { 0 };
-	struct tf_session_sram_resc_alloc_output resp;
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	memset(&resp, 0, sizeof(resp));
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
-			     full_action);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_MCG, req,
-			     mcg);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
-			     encap_8b);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
-			     encap_16b);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
-			     encap_64b);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC, req,
-			     sp_smac);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4,
-			     req, sp_smac_ipv4);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6,
-			     req, sp_smac_ipv6);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_COUNTER_64B,
-			     req, counter_64b);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
-			     nat_sport);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
-			     nat_dport);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
-			     nat_s_ipv4);
-	TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
-			     nat_d_ipv4);
-
-	MSG_PREP(parms,
-		 TF_KONG_MB,
-		 HWRM_TF,
-		 HWRM_TFT_SESSION_SRAM_RESC_ALLOC,
-		 req,
-		 resp);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	/* Process the response */
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION,
-			      resp, full_action);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_MCG, resp,
-			      mcg);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, resp,
-			      encap_8b);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, resp,
-			      encap_16b);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, resp,
-			      encap_64b);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, resp,
-			      sp_smac);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4,
-			      resp, sp_smac_ipv4);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6,
-			      resp, sp_smac_ipv6);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, resp,
-			      counter_64b);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, resp,
-			      nat_sport);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, resp,
-			      nat_dport);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, resp,
-			      nat_s_ipv4);
-	TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, resp,
-			      nat_d_ipv4);
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource free request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_free(struct tf *tfp __rte_unused,
-			      enum tf_dir dir,
-			      struct tf_rm_entry *sram_entry __rte_unused)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_sram_resc_free_input req = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
-			    full_action);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_MCG, req,
-			    mcg);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
-			    encap_8b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
-			    encap_16b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
-			    encap_64b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, req,
-			    sp_smac);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, req,
-			    sp_smac_ipv4);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, req,
-			    sp_smac_ipv6);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, req,
-			    counter_64b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
-			    nat_sport);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
-			    nat_dport);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
-			    nat_s_ipv4);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
-			    nat_d_ipv4);
-
-	MSG_PREP_NO_RESP(parms,
-			 TF_KONG_MB,
-			 HWRM_TF,
-			 HWRM_TFT_SESSION_SRAM_RESC_FREE,
-			 req);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource flush request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_flush(struct tf *tfp,
-			       enum tf_dir dir,
-			       struct tf_rm_entry *sram_entry)
-{
-	int rc;
-	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_session_sram_resc_free_input req = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
-	/* Populate the request */
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	req.flags = tfp_cpu_to_le_16(dir);
-
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
-			    full_action);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_MCG, req,
-			    mcg);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
-			    encap_8b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
-			    encap_16b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
-			    encap_64b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, req,
-			    sp_smac);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, req,
-			    sp_smac_ipv4);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, req,
-			    sp_smac_ipv6);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, req,
-			    counter_64b);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
-			    nat_sport);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
-			    nat_dport);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
-			    nat_s_ipv4);
-	TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
-			    nat_d_ipv4);
-
-	MSG_PREP_NO_RESP(parms,
-			 TF_KONG_MB,
-			 TF_TYPE_TRUFLOW,
-			 HWRM_TFT_SESSION_SRAM_RESC_FLUSH,
-			 req);
-
-	rc = tfp_send_msg_tunneled(tfp, &parms);
-	if (rc)
-		return rc;
-
-	return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
 int
 tf_msg_session_resc_qcaps(struct tf *tfp,
 			  enum tf_dir dir,
@@ -973,7 +220,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
 	/* Process the response
 	 * Should always get expected number of entries
 	 */
-	if (resp.size != size) {
+	if (tfp_le_to_cpu_32(resp.size) != size) {
 		TFP_DRV_LOG(ERR,
 			    "%s: QCAPS message size error, rc:%s\n",
 			    tf_dir_2_str(dir),
@@ -981,14 +228,14 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
 		return -EINVAL;
 	}
 
-	printf("size: %d\n", resp.size);
+	printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
 
 	/* Post process the response */
 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
 
 	printf("\nQCAPS\n");
 	for (i = 0; i < size; i++) {
-		query[i].type = tfp_cpu_to_le_32(data[i].type);
+		query[i].type = tfp_le_to_cpu_32(data[i].type);
 		query[i].min = tfp_le_to_cpu_16(data[i].min);
 		query[i].max = tfp_le_to_cpu_16(data[i].max);
 
@@ -1078,7 +325,7 @@ tf_msg_session_resc_alloc(struct tf *tfp,
 	/* Process the response
 	 * Should always get expected number of entries
 	 */
-	if (resp.size != size) {
+	if (tfp_le_to_cpu_32(resp.size) != size) {
 		TFP_DRV_LOG(ERR,
 			    "%s: Alloc message size error, rc:%s\n",
 			    tf_dir_2_str(dir),
@@ -1087,14 +334,14 @@ tf_msg_session_resc_alloc(struct tf *tfp,
 	}
 
 	printf("\nRESV\n");
-	printf("size: %d\n", resp.size);
+	printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
 
 	/* Post process the response */
 	resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
 	for (i = 0; i < size; i++) {
-		resv[i].type = tfp_cpu_to_le_32(resv_data[i].type);
-		resv[i].start = tfp_cpu_to_le_16(resv_data[i].start);
-		resv[i].stride = tfp_cpu_to_le_16(resv_data[i].stride);
+		resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
+		resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
+		resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
 
 		printf("%d type: %d(0x%x) %d %d\n",
 		       i,
@@ -1173,24 +420,112 @@ tf_msg_session_resc_flush(struct tf *tfp,
 	return rc;
 }
 
-/**
- * Sends EM mem register request to Firmware
- */
-int tf_msg_em_mem_rgtr(struct tf *tfp,
-		       int           page_lvl,
-		       int           page_size,
-		       uint64_t      dma_addr,
-		       uint16_t     *ctx_id)
+int
+tf_msg_insert_em_internal_entry(struct tf *tfp,
+				struct tf_insert_em_entry_parms *em_parms,
+				uint16_t *rptr_index,
+				uint8_t *rptr_entry,
+				uint8_t *num_of_entries)
 {
 	int rc;
-	struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
-	struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
 	struct tfp_send_msg_parms parms = { 0 };
+	struct hwrm_tf_em_insert_input req = { 0 };
+	struct hwrm_tf_em_insert_output resp = { 0 };
+	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+	struct tf_em_64b_entry *em_result =
+		(struct tf_em_64b_entry *)em_parms->em_record;
+	uint32_t flags;
+
+	req.fw_session_id =
+		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+	tfp_memcpy(req.em_key,
+		   em_parms->key,
+		   ((em_parms->key_sz_in_bits + 7) / 8));
+
+	flags = (em_parms->dir == TF_DIR_TX ?
+		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
+		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
+	req.flags = tfp_cpu_to_le_16(flags);
+	req.strength = (em_result->hdr.word1 &
+			CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
+			CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
+	req.em_key_bitlen = em_parms->key_sz_in_bits;
+	req.action_ptr = em_result->hdr.pointer;
+	req.em_record_idx = *rptr_index;
+
+	parms.tf_type = HWRM_TF_EM_INSERT;
+	parms.req_data = (uint32_t *)&req;
+	parms.req_size = sizeof(req);
+	parms.resp_data = (uint32_t *)&resp;
+	parms.resp_size = sizeof(resp);
+	parms.mailbox = TF_KONG_MB;
+
+	rc = tfp_send_msg_direct(tfp,
+				 &parms);
+	if (rc)
+		return rc;
+
+	*rptr_entry = resp.rptr_entry;
+	*rptr_index = resp.rptr_index;
+	*num_of_entries = resp.num_of_entries;
+
+	return 0;
+}
+
+int
+tf_msg_delete_em_entry(struct tf *tfp,
+		       struct tf_delete_em_entry_parms *em_parms)
+{
+	int rc;
+	struct tfp_send_msg_parms parms = { 0 };
+	struct hwrm_tf_em_delete_input req = { 0 };
+	struct hwrm_tf_em_delete_output resp = { 0 };
+	uint32_t flags;
+	struct tf_session *tfs =
+		(struct tf_session *)(tfp->session->core_data);
+
+	req.fw_session_id =
+		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+
+	flags = (em_parms->dir == TF_DIR_TX ?
+		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
+		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
+	req.flags = tfp_cpu_to_le_16(flags);
+	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
+
+	parms.tf_type = HWRM_TF_EM_DELETE;
+	parms.req_data = (uint32_t *)&req;
+	parms.req_size = sizeof(req);
+	parms.resp_data = (uint32_t *)&resp;
+	parms.resp_size = sizeof(resp);
+	parms.mailbox = TF_KONG_MB;
+
+	rc = tfp_send_msg_direct(tfp,
+				 &parms);
+	if (rc)
+		return rc;
+
+	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
+
+	return 0;
+}
+
+int
+tf_msg_em_mem_rgtr(struct tf *tfp,
+		   int page_lvl,
+		   int page_size,
+		   uint64_t dma_addr,
+		   uint16_t *ctx_id)
+{
+	int rc;
+	struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
+	struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
+	struct tfp_send_msg_parms parms = { 0 };
+
+	req.page_level = page_lvl;
+	req.page_size = page_size;
+	req.page_dir = tfp_cpu_to_le_64(dma_addr);
 
-	req.page_level = page_lvl;
-	req.page_size = page_size;
-	req.page_dir = tfp_cpu_to_le_64(dma_addr);
-
 	parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
 	parms.req_data = (uint32_t *)&req;
 	parms.req_size = sizeof(req);
@@ -1208,11 +543,9 @@ int tf_msg_em_mem_rgtr(struct tf *tfp,
 	return rc;
 }
 
-/**
- * Sends EM mem unregister request to Firmware
- */
-int tf_msg_em_mem_unrgtr(struct tf *tfp,
-			 uint16_t  *ctx_id)
+int
+tf_msg_em_mem_unrgtr(struct tf *tfp,
+		     uint16_t *ctx_id)
 {
 	int rc;
 	struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
@@ -1233,12 +566,10 @@ int tf_msg_em_mem_unrgtr(struct tf *tfp,
 	return rc;
 }
 
-/**
- * Sends EM qcaps request to Firmware
- */
-int tf_msg_em_qcaps(struct tf *tfp,
-		    int dir,
-		    struct tf_em_caps *em_caps)
+int
+tf_msg_em_qcaps(struct tf *tfp,
+		int dir,
+		struct tf_em_caps *em_caps)
 {
 	int rc;
 	struct hwrm_tf_ext_em_qcaps_input  req = {0};
@@ -1273,17 +604,15 @@ int tf_msg_em_qcaps(struct tf *tfp,
 	return rc;
 }
 
-/**
- * Sends EM config request to Firmware
- */
-int tf_msg_em_cfg(struct tf *tfp,
-		  uint32_t   num_entries,
-		  uint16_t   key0_ctx_id,
-		  uint16_t   key1_ctx_id,
-		  uint16_t   record_ctx_id,
-		  uint16_t   efc_ctx_id,
-		  uint8_t    flush_interval,
-		  int        dir)
+int
+tf_msg_em_cfg(struct tf *tfp,
+	      uint32_t num_entries,
+	      uint16_t key0_ctx_id,
+	      uint16_t key1_ctx_id,
+	      uint16_t record_ctx_id,
+	      uint16_t efc_ctx_id,
+	      uint8_t flush_interval,
+	      int dir)
 {
 	int rc;
 	struct hwrm_tf_ext_em_cfg_input  req = {0};
@@ -1317,41 +646,23 @@ int tf_msg_em_cfg(struct tf *tfp,
 	return rc;
 }
 
-/**
- * Sends EM internal insert request to Firmware
- */
-int tf_msg_insert_em_internal_entry(struct tf *tfp,
-				struct tf_insert_em_entry_parms *em_parms,
-				uint16_t *rptr_index,
-				uint8_t *rptr_entry,
-				uint8_t *num_of_entries)
+int
+tf_msg_em_op(struct tf *tfp,
+	     int dir,
+	     uint16_t op)
 {
-	int                         rc;
-	struct tfp_send_msg_parms        parms = { 0 };
-	struct hwrm_tf_em_insert_input   req = { 0 };
-	struct hwrm_tf_em_insert_output  resp = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-	struct tf_em_64b_entry *em_result =
-		(struct tf_em_64b_entry *)em_parms->em_record;
+	int rc;
+	struct hwrm_tf_ext_em_op_input req = {0};
+	struct hwrm_tf_ext_em_op_output resp = {0};
 	uint32_t flags;
+	struct tfp_send_msg_parms parms = { 0 };
 
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
-	tfp_memcpy(req.em_key,
-		   em_parms->key,
-		   ((em_parms->key_sz_in_bits + 7) / 8));
-
-	flags = (em_parms->dir == TF_DIR_TX ?
-		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX :
-		 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX);
-	req.flags = tfp_cpu_to_le_16(flags);
-	req.strength = (em_result->hdr.word1 & CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
-		CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
-	req.em_key_bitlen = em_parms->key_sz_in_bits;
-	req.action_ptr = em_result->hdr.pointer;
-	req.em_record_idx = *rptr_index;
+	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
+		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
+	req.flags = tfp_cpu_to_le_32(flags);
+	req.op = tfp_cpu_to_le_16(op);
 
-	parms.tf_type = HWRM_TF_EM_INSERT;
+	parms.tf_type = HWRM_TF_EXT_EM_OP;
 	parms.req_data = (uint32_t *)&req;
 	parms.req_size = sizeof(req);
 	parms.resp_data = (uint32_t *)&resp;
@@ -1360,75 +671,86 @@ int tf_msg_insert_em_internal_entry(struct tf *tfp,
 
 	rc = tfp_send_msg_direct(tfp,
 				 &parms);
-	if (rc)
-		return rc;
-
-	*rptr_entry = resp.rptr_entry;
-	*rptr_index = resp.rptr_index;
-	*num_of_entries = resp.num_of_entries;
-
-	return 0;
+	return rc;
 }
 
-/**
- * Sends EM delete insert request to Firmware
- */
-int tf_msg_delete_em_entry(struct tf *tfp,
-			   struct tf_delete_em_entry_parms *em_parms)
+int
+tf_msg_tcam_entry_set(struct tf *tfp,
+		      struct tf_tcam_set_parms *parms)
 {
-	int                             rc;
-	struct tfp_send_msg_parms       parms = { 0 };
-	struct hwrm_tf_em_delete_input  req = { 0 };
-	struct hwrm_tf_em_delete_output resp = { 0 };
-	uint32_t flags;
-	struct tf_session *tfs =
-		(struct tf_session *)(tfp->session->core_data);
+	int rc;
+	struct tfp_send_msg_parms mparms = { 0 };
+	struct hwrm_tf_tcam_set_input req = { 0 };
+	struct hwrm_tf_tcam_set_output resp = { 0 };
+	struct tf_msg_dma_buf buf = { 0 };
+	uint8_t *data = NULL;
+	int data_size = 0;
 
-	req.fw_session_id =
-		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+	req.type = parms->hcapi_type;
+	req.idx = tfp_cpu_to_le_16(parms->idx);
+	if (parms->dir == TF_DIR_TX)
+		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
 
-	flags = (em_parms->dir == TF_DIR_TX ?
-		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
-		 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
-	req.flags = tfp_cpu_to_le_16(flags);
-	req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
+	req.key_size = parms->key_size;
+	req.mask_offset = parms->key_size;
+	/* Result follows after key and mask, thus multiply by 2 */
+	req.result_offset = 2 * parms->key_size;
+	req.result_size = parms->result_size;
+	data_size = 2 * req.key_size + req.result_size;
 
-	parms.tf_type = HWRM_TF_EM_DELETE;
-	parms.req_data = (uint32_t *)&req;
-	parms.req_size = sizeof(req);
-	parms.resp_data = (uint32_t *)&resp;
-	parms.resp_size = sizeof(resp);
-	parms.mailbox = TF_KONG_MB;
+	if (data_size <= TF_PCI_BUF_SIZE_MAX) {
+		/* use pci buffer */
+		data = &req.dev_data[0];
+	} else {
+		/* use dma buffer */
+		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
+		rc = tf_msg_alloc_dma_buf(&buf, data_size);
+		if (rc)
+			goto cleanup;
+		data = buf.va_addr;
+		tfp_memcpy(&req.dev_data[0],
+			   &buf.pa_addr,
+			   sizeof(buf.pa_addr));
+	}
+
+	tfp_memcpy(&data[0], parms->key, parms->key_size);
+	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
+	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
+
+	mparms.tf_type = HWRM_TF_TCAM_SET;
+	mparms.req_data = (uint32_t *)&req;
+	mparms.req_size = sizeof(req);
+	mparms.resp_data = (uint32_t *)&resp;
+	mparms.resp_size = sizeof(resp);
+	mparms.mailbox = TF_KONG_MB;
 
 	rc = tfp_send_msg_direct(tfp,
-				 &parms);
+				 &mparms);
 	if (rc)
-		return rc;
+		goto cleanup;
 
-	em_parms->index = tfp_le_to_cpu_16(resp.em_index);
+cleanup:
+	tf_msg_free_dma_buf(&buf);
 
-	return 0;
+	return rc;
 }
 
-/**
- * Sends EM operation request to Firmware
- */
-int tf_msg_em_op(struct tf *tfp,
-		 int dir,
-		 uint16_t op)
+int
+tf_msg_tcam_entry_free(struct tf *tfp,
+		       struct tf_tcam_free_parms *in_parms)
 {
 	int rc;
-	struct hwrm_tf_ext_em_op_input req = {0};
-	struct hwrm_tf_ext_em_op_output resp = {0};
-	uint32_t flags;
+	struct hwrm_tf_tcam_free_input req =  { 0 };
+	struct hwrm_tf_tcam_free_output resp = { 0 };
 	struct tfp_send_msg_parms parms = { 0 };
 
-	flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
-		 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
-	req.flags = tfp_cpu_to_le_32(flags);
-	req.op = tfp_cpu_to_le_16(op);
+	req.type = in_parms->hcapi_type;
+	req.count = 1;
+	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
+	if (in_parms->dir == TF_DIR_TX)
+		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
 
-	parms.tf_type = HWRM_TF_EXT_EM_OP;
+	parms.tf_type = HWRM_TF_TCAM_FREE;
 	parms.req_data = (uint32_t *)&req;
 	parms.req_size = sizeof(req);
 	parms.resp_data = (uint32_t *)&resp;
@@ -1443,21 +765,32 @@ int tf_msg_em_op(struct tf *tfp,
 int
 tf_msg_set_tbl_entry(struct tf *tfp,
 		     enum tf_dir dir,
-		     enum tf_tbl_type type,
+		     uint16_t hcapi_type,
 		     uint16_t size,
 		     uint8_t *data,
 		     uint32_t index)
 {
 	int rc;
+	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_tbl_type_set_input req = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(dir),
+			    strerror(-rc));
+		return rc;
+	}
 
 	/* Populate the request */
 	req.fw_session_id =
 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
 	req.flags = tfp_cpu_to_le_16(dir);
-	req.type = tfp_cpu_to_le_32(type);
+	req.type = tfp_cpu_to_le_32(hcapi_type);
 	req.size = tfp_cpu_to_le_16(size);
 	req.index = tfp_cpu_to_le_32(index);
 
@@ -1465,13 +798,15 @@ tf_msg_set_tbl_entry(struct tf *tfp,
 		   data,
 		   size);
 
-	MSG_PREP_NO_RESP(parms,
-			 TF_KONG_MB,
-			 HWRM_TF,
-			 HWRM_TFT_TBL_TYPE_SET,
-			 req);
+	parms.tf_type = HWRM_TF_TBL_TYPE_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 = TF_KONG_MB;
 
-	rc = tfp_send_msg_tunneled(tfp, &parms);
+	rc = tfp_send_msg_direct(tfp,
+				 &parms);
 	if (rc)
 		return rc;
 
@@ -1481,32 +816,43 @@ tf_msg_set_tbl_entry(struct tf *tfp,
 int
 tf_msg_get_tbl_entry(struct tf *tfp,
 		     enum tf_dir dir,
-		     enum tf_tbl_type type,
+		     uint16_t hcapi_type,
 		     uint16_t size,
 		     uint8_t *data,
 		     uint32_t index)
 {
 	int rc;
+	struct hwrm_tf_tbl_type_get_input req = { 0 };
+	struct hwrm_tf_tbl_type_get_output resp = { 0 };
 	struct tfp_send_msg_parms parms = { 0 };
-	struct tf_tbl_type_get_input req = { 0 };
-	struct tf_tbl_type_get_output resp = { 0 };
-	struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Failed to lookup session, rc:%s\n",
+			    tf_dir_2_str(dir),
+			    strerror(-rc));
+		return rc;
+	}
 
 	/* Populate the request */
 	req.fw_session_id =
 		tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
 	req.flags = tfp_cpu_to_le_16(dir);
-	req.type = tfp_cpu_to_le_32(type);
+	req.type = tfp_cpu_to_le_32(hcapi_type);
 	req.index = tfp_cpu_to_le_32(index);
 
-	MSG_PREP(parms,
-		 TF_KONG_MB,
-		 HWRM_TF,
-		 HWRM_TFT_TBL_TYPE_GET,
-		 req,
-		 resp);
+	parms.tf_type = HWRM_TF_TBL_TYPE_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 = TF_KONG_MB;
 
-	rc = tfp_send_msg_tunneled(tfp, &parms);
+	rc = tfp_send_msg_direct(tfp,
+				 &parms);
 	if (rc)
 		return rc;
 
@@ -1521,6 +867,8 @@ tf_msg_get_tbl_entry(struct tf *tfp,
 	return tfp_le_to_cpu_32(parms.tf_resp_code);
 }
 
+/* HWRM Tunneled messages */
+
 int
 tf_msg_bulk_get_tbl_entry(struct tf *tfp,
 			  struct tf_bulk_get_tbl_entry_parms *params)
@@ -1561,96 +909,3 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp,
 
 	return tfp_le_to_cpu_32(parms.tf_resp_code);
 }
-
-int
-tf_msg_tcam_entry_set(struct tf *tfp,
-		      struct tf_tcam_set_parms *parms)
-{
-	int rc;
-	struct tfp_send_msg_parms mparms = { 0 };
-	struct hwrm_tf_tcam_set_input req = { 0 };
-	struct hwrm_tf_tcam_set_output resp = { 0 };
-	struct tf_msg_dma_buf buf = { 0 };
-	uint8_t *data = NULL;
-	int data_size = 0;
-
-	req.type = parms->type;
-
-	req.idx = tfp_cpu_to_le_16(parms->idx);
-	if (parms->dir == TF_DIR_TX)
-		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
-
-	req.key_size = parms->key_size;
-	req.mask_offset = parms->key_size;
-	/* Result follows after key and mask, thus multiply by 2 */
-	req.result_offset = 2 * parms->key_size;
-	req.result_size = parms->result_size;
-	data_size = 2 * req.key_size + req.result_size;
-
-	if (data_size <= TF_PCI_BUF_SIZE_MAX) {
-		/* use pci buffer */
-		data = &req.dev_data[0];
-	} else {
-		/* use dma buffer */
-		req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
-		rc = tf_msg_alloc_dma_buf(&buf, data_size);
-		if (rc)
-			goto cleanup;
-		data = buf.va_addr;
-		tfp_memcpy(&req.dev_data[0],
-			   &buf.pa_addr,
-			   sizeof(buf.pa_addr));
-	}
-
-	tfp_memcpy(&data[0], parms->key, parms->key_size);
-	tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
-	tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
-
-	mparms.tf_type = HWRM_TF_TCAM_SET;
-	mparms.req_data = (uint32_t *)&req;
-	mparms.req_size = sizeof(req);
-	mparms.resp_data = (uint32_t *)&resp;
-	mparms.resp_size = sizeof(resp);
-	mparms.mailbox = TF_KONG_MB;
-
-	rc = tfp_send_msg_direct(tfp,
-				 &mparms);
-	if (rc)
-		goto cleanup;
-
-cleanup:
-	tf_msg_free_dma_buf(&buf);
-
-	return rc;
-}
-
-int
-tf_msg_tcam_entry_free(struct tf *tfp,
-		       struct tf_tcam_free_parms *in_parms)
-{
-	int rc;
-	struct hwrm_tf_tcam_free_input req =  { 0 };
-	struct hwrm_tf_tcam_free_output resp = { 0 };
-	struct tfp_send_msg_parms parms = { 0 };
-
-	/* Populate the request */
-	rc = tf_tcam_tbl_2_hwrm(in_parms->type, &req.type);
-	if (rc != 0)
-		return rc;
-
-	req.count = 1;
-	req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
-	if (in_parms->dir == TF_DIR_TX)
-		req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
-
-	parms.tf_type = HWRM_TF_TCAM_FREE;
-	parms.req_data = (uint32_t *)&req;
-	parms.req_size = sizeof(req);
-	parms.resp_data = (uint32_t *)&resp;
-	parms.resp_size = sizeof(resp);
-	parms.mailbox = TF_KONG_MB;
-
-	rc = tfp_send_msg_direct(tfp,
-				 &parms);
-	return rc;
-}
diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h
index 1ff1044..8e276d4 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.h
+++ b/drivers/net/bnxt/tf_core/tf_msg.h
@@ -16,6 +16,8 @@
 
 struct tf;
 
+/* HWRM Direct messages */
+
 /**
  * Sends session open request to Firmware
  *
@@ -29,7 +31,7 @@ struct tf;
  *   Pointer to the fw_session_id that is allocated on firmware side
  *
  * Returns:
- *
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_session_open(struct tf *tfp,
 			char *ctrl_chan_name,
@@ -46,7 +48,7 @@ int tf_msg_session_open(struct tf *tfp,
  *   time of session open
  *
  * Returns:
- *
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_session_attach(struct tf *tfp,
 			  char *ctrl_channel_name,
@@ -59,75 +61,23 @@ int tf_msg_session_attach(struct tf *tfp,
  *   Pointer to session handle
  *
  * Returns:
- *
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_session_close(struct tf *tfp);
 
 /**
  * Sends session query config request to TF Firmware
+ *
+ * [in] session
+ *   Pointer to session handle
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_session_qcfg(struct tf *tfp);
 
 /**
  * Sends session HW resource query capability request to TF Firmware
- */
-int tf_msg_session_hw_resc_qcaps(struct tf *tfp,
-				 enum tf_dir dir,
-				 struct tf_rm_hw_query *hw_query);
-
-/**
- * Sends session HW resource allocation request to TF Firmware
- */
-int tf_msg_session_hw_resc_alloc(struct tf *tfp,
-				 enum tf_dir dir,
-				 struct tf_rm_hw_alloc *hw_alloc,
-				 struct tf_rm_entry *hw_entry);
-
-/**
- * Sends session HW resource free request to TF Firmware
- */
-int tf_msg_session_hw_resc_free(struct tf *tfp,
-				enum tf_dir dir,
-				struct tf_rm_entry *hw_entry);
-
-/**
- * Sends session HW resource flush request to TF Firmware
- */
-int tf_msg_session_hw_resc_flush(struct tf *tfp,
-				 enum tf_dir dir,
-				 struct tf_rm_entry *hw_entry);
-
-/**
- * Sends session SRAM resource query capability request to TF Firmware
- */
-int tf_msg_session_sram_resc_qcaps(struct tf *tfp,
-				   enum tf_dir dir,
-				   struct tf_rm_sram_query *sram_query);
-
-/**
- * Sends session SRAM resource allocation request to TF Firmware
- */
-int tf_msg_session_sram_resc_alloc(struct tf *tfp,
-				   enum tf_dir dir,
-				   struct tf_rm_sram_alloc *sram_alloc,
-				   struct tf_rm_entry *sram_entry);
-
-/**
- * Sends session SRAM resource free request to TF Firmware
- */
-int tf_msg_session_sram_resc_free(struct tf *tfp,
-				  enum tf_dir dir,
-				  struct tf_rm_entry *sram_entry);
-
-/**
- * Sends session SRAM resource flush request to TF Firmware
- */
-int tf_msg_session_sram_resc_flush(struct tf *tfp,
-				   enum tf_dir dir,
-				   struct tf_rm_entry *sram_entry);
-
-/**
- * Sends session HW resource query capability request to TF Firmware
  *
  * [in] tfp
  *   Pointer to TF handle
@@ -183,6 +133,21 @@ int tf_msg_session_resc_alloc(struct tf *tfp,
 
 /**
  * Sends session resource flush request to TF Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] dir
+ *   Receive or Transmit direction
+ *
+ * [in] size
+ *   Number of elements in the req and resv arrays
+ *
+ * [in] resv
+ *   Pointer to an array of reserved elements that needs to be flushed
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_session_resc_flush(struct tf *tfp,
 			      enum tf_dir dir,
@@ -190,6 +155,24 @@ int tf_msg_session_resc_flush(struct tf *tfp,
 			      struct tf_rm_resc_entry *resv);
 /**
  * Sends EM internal insert request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] params
+ *   Pointer to em insert parameter list
+ *
+ * [in] rptr_index
+ *   Record ptr index
+ *
+ * [in] rptr_entry
+ *   Record ptr entry
+ *
+ * [in] num_of_entries
+ *   Number of entries to insert
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_insert_em_internal_entry(struct tf *tfp,
 				    struct tf_insert_em_entry_parms *params,
@@ -198,26 +181,75 @@ int tf_msg_insert_em_internal_entry(struct tf *tfp,
 				    uint8_t *num_of_entries);
 /**
  * Sends EM internal delete request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] em_parms
+ *   Pointer to em delete parameters
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_delete_em_entry(struct tf *tfp,
 			   struct tf_delete_em_entry_parms *em_parms);
+
 /**
  * Sends EM mem register request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] page_lvl
+ *   Page level
+ *
+ * [in] page_size
+ *   Page size
+ *
+ * [in] dma_addr
+ *   DMA Address for the memory page
+ *
+ * [in] ctx_id
+ *   Context id
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_em_mem_rgtr(struct tf *tfp,
-		       int           page_lvl,
-		       int           page_size,
-		       uint64_t      dma_addr,
-		       uint16_t     *ctx_id);
+		       int page_lvl,
+		       int page_size,
+		       uint64_t dma_addr,
+		       uint16_t *ctx_id);
 
 /**
  * Sends EM mem unregister request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] ctx_id
+ *   Context id
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_em_mem_unrgtr(struct tf *tfp,
-			 uint16_t     *ctx_id);
+			 uint16_t *ctx_id);
 
 /**
  * Sends EM qcaps request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] dir
+ *   Receive or Transmit direction
+ *
+ * [in] em_caps
+ *   Pointer to EM capabilities
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_em_qcaps(struct tf *tfp,
 		    int dir,
@@ -225,22 +257,63 @@ int tf_msg_em_qcaps(struct tf *tfp,
 
 /**
  * Sends EM config request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] num_entries
+ *   EM Table, key 0, number of entries to configure
+ *
+ * [in] key0_ctx_id
+ *   EM Table, Key 0 context id
+ *
+ * [in] key1_ctx_id
+ *   EM Table, Key 1 context id
+ *
+ * [in] record_ctx_id
+ *   EM Table, Record context id
+ *
+ * [in] efc_ctx_id
+ *   EM Table, EFC Table context id
+ *
+ * [in] flush_interval
+ *   Flush pending HW cached flows every 1/10th of value set in
+ *   seconds, both idle and active flows are flushed from the HW
+ *   cache. If set to 0, this feature will be disabled.
+ *
+ * [in] dir
+ *   Receive or Transmit direction
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_em_cfg(struct tf *tfp,
-		  uint32_t      num_entries,
-		  uint16_t      key0_ctx_id,
-		  uint16_t      key1_ctx_id,
-		  uint16_t      record_ctx_id,
-		  uint16_t      efc_ctx_id,
-		  uint8_t       flush_interval,
-		  int           dir);
+		  uint32_t num_entries,
+		  uint16_t key0_ctx_id,
+		  uint16_t key1_ctx_id,
+		  uint16_t record_ctx_id,
+		  uint16_t efc_ctx_id,
+		  uint8_t flush_interval,
+		  int dir);
 
 /**
  * Sends EM operation request to Firmware
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] dir
+ *   Receive or Transmit direction
+ *
+ * [in] op
+ *   CFA Operator
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
  */
 int tf_msg_em_op(struct tf *tfp,
-		 int        dir,
-		 uint16_t   op);
+		 int dir,
+		 uint16_t op);
 
 /**
  * Sends tcam entry 'set' to the Firmware.
@@ -281,7 +354,7 @@ int tf_msg_tcam_entry_free(struct tf *tfp,
  * [in] dir
  *   Direction location of the element to set
  *
- * [in] type
+ * [in] hcapi_type
  *   Type of the object to set
  *
  * [in] size
@@ -298,7 +371,7 @@ int tf_msg_tcam_entry_free(struct tf *tfp,
  */
 int tf_msg_set_tbl_entry(struct tf *tfp,
 			 enum tf_dir dir,
-			 enum tf_tbl_type type,
+			 uint16_t hcapi_type,
 			 uint16_t size,
 			 uint8_t *data,
 			 uint32_t index);
@@ -312,7 +385,7 @@ int tf_msg_set_tbl_entry(struct tf *tfp,
  * [in] dir
  *   Direction location of the element to get
  *
- * [in] type
+ * [in] hcapi_type
  *   Type of the object to get
  *
  * [in] size
@@ -329,11 +402,13 @@ int tf_msg_set_tbl_entry(struct tf *tfp,
  */
 int tf_msg_get_tbl_entry(struct tf *tfp,
 			 enum tf_dir dir,
-			 enum tf_tbl_type type,
+			 uint16_t hcapi_type,
 			 uint16_t size,
 			 uint8_t *data,
 			 uint32_t index);
 
+/* HWRM Tunneled messages */
+
 /**
  * Sends bulk get message of a Table Type element to the firmware.
  *
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index b6fe2f1..e0a84e6 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -1818,16 +1818,8 @@ tf_rm_allocate_validate_hw(struct tf *tfp,
 		hw_entries = tfs->resc.tx.hw_entry;
 
 	/* Query for Session HW Resources */
-	rc = tf_msg_session_hw_resc_qcaps(tfp, dir, &hw_query);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s, HW qcaps message send failed, rc:%s\n",
-			    tf_dir_2_str(dir),
-			    strerror(-rc));
-		goto cleanup;
-	}
 
+	memset(&hw_query, 0, sizeof(hw_query)); /* RSXX */
 	rc = tf_rm_check_hw_qcaps_static(&hw_query, dir, &error_flag);
 	if (rc) {
 		/* Log error */
@@ -1846,16 +1838,6 @@ tf_rm_allocate_validate_hw(struct tf *tfp,
 		hw_alloc.hw_num[i] = hw_query.hw_query[i].max;
 
 	/* Allocate Session HW Resources */
-	rc = tf_msg_session_hw_resc_alloc(tfp, dir, &hw_alloc, hw_entries);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s, HW alloc message send failed, rc:%s\n",
-			    tf_dir_2_str(dir),
-			    strerror(-rc));
-		goto cleanup;
-	}
-
 	/* Perform HW allocation validation as its possible the
 	 * resource availability changed between qcaps and alloc
 	 */
@@ -1906,17 +1888,7 @@ tf_rm_allocate_validate_sram(struct tf *tfp,
 	else
 		sram_entries = tfs->resc.tx.sram_entry;
 
-	/* Query for Session SRAM Resources */
-	rc = tf_msg_session_sram_resc_qcaps(tfp, dir, &sram_query);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s, SRAM qcaps message send failed, rc:%s\n",
-			    tf_dir_2_str(dir),
-			    strerror(-rc));
-		goto cleanup;
-	}
-
+	memset(&sram_query, 0, sizeof(sram_query)); /* RSXX */
 	rc = tf_rm_check_sram_qcaps_static(&sram_query, dir, &error_flag);
 	if (rc) {
 		/* Log error */
@@ -1934,20 +1906,6 @@ tf_rm_allocate_validate_sram(struct tf *tfp,
 	for (i = 0; i < TF_RESC_TYPE_SRAM_MAX; i++)
 		sram_alloc.sram_num[i] = sram_query.sram_query[i].max;
 
-	/* Allocate Session SRAM Resources */
-	rc = tf_msg_session_sram_resc_alloc(tfp,
-					    dir,
-					    &sram_alloc,
-					    sram_entries);
-	if (rc) {
-		/* Log error */
-		TFP_DRV_LOG(ERR,
-			    "%s, SRAM alloc message send failed, rc:%s\n",
-			    tf_dir_2_str(dir),
-			    strerror(-rc));
-		goto cleanup;
-	}
-
 	/* Perform SRAM allocation validation as its possible the
 	 * resource availability changed between qcaps and alloc
 	 */
@@ -2798,17 +2756,6 @@ tf_rm_close(struct tf *tfp)
 
 			/* Log the entries to be flushed */
 			tf_rm_log_hw_flush(i, hw_flush_entries);
-			rc = tf_msg_session_hw_resc_flush(tfp,
-							  i,
-							  hw_flush_entries);
-			if (rc) {
-				rc_close = rc;
-				/* Log error */
-				TFP_DRV_LOG(ERR,
-					    "%s, HW flush failed, rc:%s\n",
-					    tf_dir_2_str(i),
-					    strerror(-rc));
-			}
 		}
 
 		/* Check for any not previously freed SRAM resources
@@ -2828,38 +2775,6 @@ tf_rm_close(struct tf *tfp)
 
 			/* Log the entries to be flushed */
 			tf_rm_log_sram_flush(i, sram_flush_entries);
-
-			rc = tf_msg_session_sram_resc_flush(tfp,
-							    i,
-							    sram_flush_entries);
-			if (rc) {
-				rc_close = rc;
-				/* Log error */
-				TFP_DRV_LOG(ERR,
-					    "%s, HW flush failed, rc:%s\n",
-					    tf_dir_2_str(i),
-					    strerror(-rc));
-			}
-		}
-
-		rc = tf_msg_session_hw_resc_free(tfp, i, hw_entries);
-		if (rc) {
-			rc_close = rc;
-			/* Log error */
-			TFP_DRV_LOG(ERR,
-				    "%s, HW free failed, rc:%s\n",
-				    tf_dir_2_str(i),
-				    strerror(-rc));
-		}
-
-		rc = tf_msg_session_sram_resc_free(tfp, i, sram_entries);
-		if (rc) {
-			rc_close = rc;
-			/* Log error */
-			TFP_DRV_LOG(ERR,
-				    "%s, SRAM free failed, rc:%s\n",
-				    tf_dir_2_str(i),
-				    strerror(-rc));
 		}
 	}
 
diff --git a/drivers/net/bnxt/tf_core/tf_rm_new.c b/drivers/net/bnxt/tf_core/tf_rm_new.c
index de8f119..2d9be65 100644
--- a/drivers/net/bnxt/tf_core/tf_rm_new.c
+++ b/drivers/net/bnxt/tf_core/tf_rm_new.c
@@ -95,7 +95,9 @@ struct tf_rm_new_db {
  *   - EOPNOTSUPP - Operation not supported
  */
 static void
-tf_rm_count_hcapi_reservations(struct tf_rm_element_cfg *cfg,
+tf_rm_count_hcapi_reservations(enum tf_dir dir,
+			       enum tf_device_module_type type,
+			       struct tf_rm_element_cfg *cfg,
 			       uint16_t *reservations,
 			       uint16_t count,
 			       uint16_t *valid_count)
@@ -107,6 +109,26 @@ tf_rm_count_hcapi_reservations(struct tf_rm_element_cfg *cfg,
 		if (cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI &&
 		    reservations[i] > 0)
 			cnt++;
+
+		/* Only log msg if a type is attempted reserved and
+		 * not supported. We ignore EM module as its using a
+		 * split configuration array thus it would fail for
+		 * this type of check.
+		 */
+		if (type != TF_DEVICE_MODULE_TYPE_EM &&
+		    cfg[i].cfg_type == TF_RM_ELEM_CFG_NULL &&
+		    reservations[i] > 0) {
+			TFP_DRV_LOG(ERR,
+				"%s, %s, %s allocation not supported\n",
+				tf_device_module_type_2_str(type),
+				tf_dir_2_str(dir),
+				tf_device_module_type_subtype_2_str(type, i));
+			printf("%s, %s, %s allocation of %d not supported\n",
+				tf_device_module_type_2_str(type),
+				tf_dir_2_str(dir),
+			       tf_device_module_type_subtype_2_str(type, i),
+			       reservations[i]);
+		}
 	}
 
 	*valid_count = cnt;
@@ -405,7 +427,9 @@ tf_rm_create_db(struct tf *tfp,
 	 * the DB holds them all as to give a fast lookup. We can also
 	 * remove entries where there are no request for elements.
 	 */
-	tf_rm_count_hcapi_reservations(parms->cfg,
+	tf_rm_count_hcapi_reservations(parms->dir,
+				       parms->type,
+				       parms->cfg,
 				       parms->alloc_cnt,
 				       parms->num_elements,
 				       &hcapi_items);
@@ -507,6 +531,11 @@ tf_rm_create_db(struct tf *tfp,
 			db[i].alloc.entry.start = resv[j].start;
 			db[i].alloc.entry.stride = resv[j].stride;
 
+			printf("Entry:%d Start:%d Stride:%d\n",
+			       i,
+			       resv[j].start,
+			       resv[j].stride);
+
 			/* Create pool */
 			pool_size = (BITALLOC_SIZEOF(resv[j].stride) /
 				     sizeof(struct bitalloc));
@@ -548,11 +577,16 @@ tf_rm_create_db(struct tf *tfp,
 		}
 	}
 
-	rm_db->num_entries = i;
+	rm_db->num_entries = parms->num_elements;
 	rm_db->dir = parms->dir;
 	rm_db->type = parms->type;
 	*parms->rm_db = (void *)rm_db;
 
+	printf("%s: type:%d num_entries:%d\n",
+	       tf_dir_2_str(parms->dir),
+	       parms->type,
+	       i);
+
 	tfp_free((void *)req);
 	tfp_free((void *)resv);
 
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index b0a932b..b5ce860 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -26,739 +26,6 @@
 #include "stack.h"
 #include "tf_common.h"
 
-#define PTU_PTE_VALID          0x1UL
-#define PTU_PTE_LAST           0x2UL
-#define PTU_PTE_NEXT_TO_LAST   0x4UL
-
-/* Number of pointers per page_size */
-#define	MAX_PAGE_PTRS(page_size)  ((page_size) / sizeof(void *))
-
-#define TF_EM_PG_SZ_4K        (1 << 12)
-#define TF_EM_PG_SZ_8K        (1 << 13)
-#define TF_EM_PG_SZ_64K       (1 << 16)
-#define TF_EM_PG_SZ_256K      (1 << 18)
-#define TF_EM_PG_SZ_1M        (1 << 20)
-#define TF_EM_PG_SZ_2M        (1 << 21)
-#define TF_EM_PG_SZ_4M        (1 << 22)
-#define TF_EM_PG_SZ_1G        (1 << 30)
-
-#define	TF_EM_CTX_ID_INVALID   0xFFFF
-
-#define	TF_EM_MIN_ENTRIES     (1 << 15) /* 32K */
-#define	TF_EM_MAX_ENTRIES     (1 << 27) /* 128M */
-
-/**
- * Function to free a page table
- *
- * [in] tp
- *   Pointer to the page table to free
- */
-static void
-tf_em_free_pg_tbl(struct hcapi_cfa_em_page_tbl *tp)
-{
-	uint32_t i;
-
-	for (i = 0; i < tp->pg_count; i++) {
-		if (!tp->pg_va_tbl[i]) {
-			TFP_DRV_LOG(WARNING,
-				    "No mapping for page: %d table: %016" PRIu64 "\n",
-				    i,
-				    (uint64_t)(uintptr_t)tp);
-			continue;
-		}
-
-		tfp_free(tp->pg_va_tbl[i]);
-		tp->pg_va_tbl[i] = NULL;
-	}
-
-	tp->pg_count = 0;
-	tfp_free(tp->pg_va_tbl);
-	tp->pg_va_tbl = NULL;
-	tfp_free(tp->pg_pa_tbl);
-	tp->pg_pa_tbl = NULL;
-}
-
-/**
- * Function to free an EM table
- *
- * [in] tbl
- *   Pointer to the EM table to free
- */
-static void
-tf_em_free_page_table(struct hcapi_cfa_em_table *tbl)
-{
-	struct hcapi_cfa_em_page_tbl *tp;
-	int i;
-
-	for (i = 0; i < tbl->num_lvl; i++) {
-		tp = &tbl->pg_tbl[i];
-		TFP_DRV_LOG(INFO,
-			   "EEM: Freeing page table: size %u lvl %d cnt %u\n",
-			   TF_EM_PAGE_SIZE,
-			    i,
-			    tp->pg_count);
-
-		tf_em_free_pg_tbl(tp);
-	}
-
-	tbl->l0_addr = NULL;
-	tbl->l0_dma_addr = 0;
-	tbl->num_lvl = 0;
-	tbl->num_data_pages = 0;
-}
-
-/**
- * Allocation of page tables
- *
- * [in] tfp
- *   Pointer to a TruFlow handle
- *
- * [in] pg_count
- *   Page count to allocate
- *
- * [in] pg_size
- *   Size of each page
- *
- * Returns:
- *   0       - Success
- *   -ENOMEM - Out of memory
- */
-static int
-tf_em_alloc_pg_tbl(struct hcapi_cfa_em_page_tbl *tp,
-		   uint32_t pg_count,
-		   uint32_t pg_size)
-{
-	uint32_t i;
-	struct tfp_calloc_parms parms;
-
-	parms.nitems = pg_count;
-	parms.size = sizeof(void *);
-	parms.alignment = 0;
-
-	if (tfp_calloc(&parms) != 0)
-		return -ENOMEM;
-
-	tp->pg_va_tbl = parms.mem_va;
-
-	if (tfp_calloc(&parms) != 0) {
-		tfp_free(tp->pg_va_tbl);
-		return -ENOMEM;
-	}
-
-	tp->pg_pa_tbl = parms.mem_va;
-
-	tp->pg_count = 0;
-	tp->pg_size = pg_size;
-
-	for (i = 0; i < pg_count; i++) {
-		parms.nitems = 1;
-		parms.size = pg_size;
-		parms.alignment = TF_EM_PAGE_ALIGNMENT;
-
-		if (tfp_calloc(&parms) != 0)
-			goto cleanup;
-
-		tp->pg_pa_tbl[i] = (uintptr_t)parms.mem_pa;
-		tp->pg_va_tbl[i] = parms.mem_va;
-
-		memset(tp->pg_va_tbl[i], 0, pg_size);
-		tp->pg_count++;
-	}
-
-	return 0;
-
-cleanup:
-	tf_em_free_pg_tbl(tp);
-	return -ENOMEM;
-}
-
-/**
- * Allocates EM page tables
- *
- * [in] tbl
- *   Table to allocate pages for
- *
- * Returns:
- *   0       - Success
- *   -ENOMEM - Out of memory
- */
-static int
-tf_em_alloc_page_table(struct hcapi_cfa_em_table *tbl)
-{
-	struct hcapi_cfa_em_page_tbl *tp;
-	int rc = 0;
-	int i;
-	uint32_t j;
-
-	for (i = 0; i < tbl->num_lvl; i++) {
-		tp = &tbl->pg_tbl[i];
-
-		rc = tf_em_alloc_pg_tbl(tp,
-					tbl->page_cnt[i],
-					TF_EM_PAGE_SIZE);
-		if (rc) {
-			TFP_DRV_LOG(WARNING,
-				"Failed to allocate page table: lvl: %d, rc:%s\n",
-				i,
-				strerror(-rc));
-			goto cleanup;
-		}
-
-		for (j = 0; j < tp->pg_count; j++) {
-			TFP_DRV_LOG(INFO,
-				"EEM: Allocated page table: size %u lvl %d cnt"
-				" %u VA:%p PA:%p\n",
-				TF_EM_PAGE_SIZE,
-				i,
-				tp->pg_count,
-				(uint32_t *)tp->pg_va_tbl[j],
-				(uint32_t *)(uintptr_t)tp->pg_pa_tbl[j]);
-		}
-	}
-	return rc;
-
-cleanup:
-	tf_em_free_page_table(tbl);
-	return rc;
-}
-
-/**
- * Links EM page tables
- *
- * [in] tp
- *   Pointer to page table
- *
- * [in] tp_next
- *   Pointer to the next page table
- *
- * [in] set_pte_last
- *   Flag controlling if the page table is last
- */
-static void
-tf_em_link_page_table(struct hcapi_cfa_em_page_tbl *tp,
-		      struct hcapi_cfa_em_page_tbl *tp_next,
-		      bool set_pte_last)
-{
-	uint64_t *pg_pa = tp_next->pg_pa_tbl;
-	uint64_t *pg_va;
-	uint64_t valid;
-	uint32_t k = 0;
-	uint32_t i;
-	uint32_t j;
-
-	for (i = 0; i < tp->pg_count; i++) {
-		pg_va = tp->pg_va_tbl[i];
-
-		for (j = 0; j < MAX_PAGE_PTRS(tp->pg_size); j++) {
-			if (k == tp_next->pg_count - 2 && set_pte_last)
-				valid = PTU_PTE_NEXT_TO_LAST | PTU_PTE_VALID;
-			else if (k == tp_next->pg_count - 1 && set_pte_last)
-				valid = PTU_PTE_LAST | PTU_PTE_VALID;
-			else
-				valid = PTU_PTE_VALID;
-
-			pg_va[j] = tfp_cpu_to_le_64(pg_pa[k] | valid);
-			if (++k >= tp_next->pg_count)
-				return;
-		}
-	}
-}
-
-/**
- * Setup a EM page table
- *
- * [in] tbl
- *   Pointer to EM page table
- */
-static void
-tf_em_setup_page_table(struct hcapi_cfa_em_table *tbl)
-{
-	struct hcapi_cfa_em_page_tbl *tp_next;
-	struct hcapi_cfa_em_page_tbl *tp;
-	bool set_pte_last = 0;
-	int i;
-
-	for (i = 0; i < tbl->num_lvl - 1; i++) {
-		tp = &tbl->pg_tbl[i];
-		tp_next = &tbl->pg_tbl[i + 1];
-		if (i == tbl->num_lvl - 2)
-			set_pte_last = 1;
-		tf_em_link_page_table(tp, tp_next, set_pte_last);
-	}
-
-	tbl->l0_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_va_tbl[0];
-	tbl->l0_dma_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_pa_tbl[0];
-}
-
-/**
- * Given the page size, size of each data item (entry size),
- * and the total number of entries needed, determine the number
- * of page table levels and the number of data pages required.
- *
- * [in] page_size
- *   Page size
- *
- * [in] entry_size
- *   Entry size
- *
- * [in] num_entries
- *   Number of entries needed
- *
- * [out] num_data_pages
- *   Number of pages required
- *
- * Returns:
- *   Success  - Number of EM page levels required
- *   -ENOMEM  - Out of memory
- */
-static int
-tf_em_size_page_tbl_lvl(uint32_t page_size,
-			uint32_t entry_size,
-			uint32_t num_entries,
-			uint64_t *num_data_pages)
-{
-	uint64_t lvl_data_size = page_size;
-	int lvl = TF_PT_LVL_0;
-	uint64_t data_size;
-
-	*num_data_pages = 0;
-	data_size = (uint64_t)num_entries * entry_size;
-
-	while (lvl_data_size < data_size) {
-		lvl++;
-
-		if (lvl == TF_PT_LVL_1)
-			lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
-				page_size;
-		else if (lvl == TF_PT_LVL_2)
-			lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
-				MAX_PAGE_PTRS(page_size) * page_size;
-		else
-			return -ENOMEM;
-	}
-
-	*num_data_pages = roundup(data_size, page_size) / page_size;
-
-	return lvl;
-}
-
-/**
- * Return the number of page table pages needed to
- * reference the given number of next level pages.
- *
- * [in] num_pages
- *   Number of EM pages
- *
- * [in] page_size
- *   Size of each EM page
- *
- * Returns:
- *   Number of EM page table pages
- */
-static uint32_t
-tf_em_page_tbl_pgcnt(uint32_t num_pages,
-		     uint32_t page_size)
-{
-	return roundup(num_pages, MAX_PAGE_PTRS(page_size)) /
-		       MAX_PAGE_PTRS(page_size);
-	return 0;
-}
-
-/**
- * Given the number of data pages, page_size and the maximum
- * number of page table levels (already determined), size
- * the number of page table pages required at each level.
- *
- * [in] max_lvl
- *   Max number of levels
- *
- * [in] num_data_pages
- *   Number of EM data pages
- *
- * [in] page_size
- *   Size of an EM page
- *
- * [out] *page_cnt
- *   EM page count
- */
-static void
-tf_em_size_page_tbls(int max_lvl,
-		     uint64_t num_data_pages,
-		     uint32_t page_size,
-		     uint32_t *page_cnt)
-{
-	if (max_lvl == TF_PT_LVL_0) {
-		page_cnt[TF_PT_LVL_0] = num_data_pages;
-	} else if (max_lvl == TF_PT_LVL_1) {
-		page_cnt[TF_PT_LVL_1] = num_data_pages;
-		page_cnt[TF_PT_LVL_0] =
-		tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
-	} else if (max_lvl == TF_PT_LVL_2) {
-		page_cnt[TF_PT_LVL_2] = num_data_pages;
-		page_cnt[TF_PT_LVL_1] =
-		tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_2], page_size);
-		page_cnt[TF_PT_LVL_0] =
-		tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
-	} else {
-		return;
-	}
-}
-
-/**
- * Size the EM table based on capabilities
- *
- * [in] tbl
- *   EM table to size
- *
- * Returns:
- *   0        - Success
- *   - EINVAL - Parameter error
- *   - ENOMEM - Out of memory
- */
-static int
-tf_em_size_table(struct hcapi_cfa_em_table *tbl)
-{
-	uint64_t num_data_pages;
-	uint32_t *page_cnt;
-	int max_lvl;
-	uint32_t num_entries;
-	uint32_t cnt = TF_EM_MIN_ENTRIES;
-
-	/* Ignore entry if both size and number are zero */
-	if (!tbl->entry_size && !tbl->num_entries)
-		return 0;
-
-	/* If only one is set then error */
-	if (!tbl->entry_size || !tbl->num_entries)
-		return -EINVAL;
-
-	/* Determine number of page table levels and the number
-	 * of data pages needed to process the given eem table.
-	 */
-	if (tbl->type == TF_RECORD_TABLE) {
-		/*
-		 * For action records just a memory size is provided. Work
-		 * backwards to resolve to number of entries
-		 */
-		num_entries = tbl->num_entries / tbl->entry_size;
-		if (num_entries < TF_EM_MIN_ENTRIES) {
-			num_entries = TF_EM_MIN_ENTRIES;
-		} else {
-			while (num_entries > cnt && cnt <= TF_EM_MAX_ENTRIES)
-				cnt *= 2;
-			num_entries = cnt;
-		}
-	} else {
-		num_entries = tbl->num_entries;
-	}
-
-	max_lvl = tf_em_size_page_tbl_lvl(TF_EM_PAGE_SIZE,
-					  tbl->entry_size,
-					  tbl->num_entries,
-					  &num_data_pages);
-	if (max_lvl < 0) {
-		TFP_DRV_LOG(WARNING, "EEM: Failed to size page table levels\n");
-		TFP_DRV_LOG(WARNING,
-			    "table: %d data-sz: %016" PRIu64 " page-sz: %u\n",
-			    tbl->type, (uint64_t)num_entries * tbl->entry_size,
-			    TF_EM_PAGE_SIZE);
-		return -ENOMEM;
-	}
-
-	tbl->num_lvl = max_lvl + 1;
-	tbl->num_data_pages = num_data_pages;
-
-	/* Determine the number of pages needed at each level */
-	page_cnt = tbl->page_cnt;
-	memset(page_cnt, 0, sizeof(tbl->page_cnt));
-	tf_em_size_page_tbls(max_lvl, num_data_pages, TF_EM_PAGE_SIZE,
-				page_cnt);
-
-	TFP_DRV_LOG(INFO, "EEM: Sized page table: %d\n", tbl->type);
-	TFP_DRV_LOG(INFO,
-		    "EEM: lvls: %d sz: %016" PRIu64 " pgs: %016" PRIu64 " l0: %u l1: %u l2: %u\n",
-		    max_lvl + 1,
-		    (uint64_t)num_data_pages * TF_EM_PAGE_SIZE,
-		    num_data_pages,
-		    page_cnt[TF_PT_LVL_0],
-		    page_cnt[TF_PT_LVL_1],
-		    page_cnt[TF_PT_LVL_2]);
-
-	return 0;
-}
-
-/**
- * Unregisters EM Ctx in Firmware
- *
- * [in] tfp
- *   Pointer to a TruFlow handle
- *
- * [in] tbl_scope_cb
- *   Pointer to a table scope control block
- *
- * [in] dir
- *   Receive or transmit direction
- */
-static void
-tf_em_ctx_unreg(struct tf *tfp,
-		struct tf_tbl_scope_cb *tbl_scope_cb,
-		int dir)
-{
-	struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
-	struct hcapi_cfa_em_table *tbl;
-	int i;
-
-	for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
-		tbl = &ctxp->em_tables[i];
-
-		if (tbl->num_entries != 0 && tbl->entry_size != 0) {
-			tf_msg_em_mem_unrgtr(tfp, &tbl->ctx_id);
-			tf_em_free_page_table(tbl);
-		}
-	}
-}
-
-/**
- * Registers EM Ctx in Firmware
- *
- * [in] tfp
- *   Pointer to a TruFlow handle
- *
- * [in] tbl_scope_cb
- *   Pointer to a table scope control block
- *
- * [in] dir
- *   Receive or transmit direction
- *
- * Returns:
- *   0       - Success
- *   -ENOMEM - Out of Memory
- */
-static int
-tf_em_ctx_reg(struct tf *tfp,
-	      struct tf_tbl_scope_cb *tbl_scope_cb,
-	      int dir)
-{
-	struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
-	struct hcapi_cfa_em_table *tbl;
-	int rc = 0;
-	int i;
-
-	for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
-		tbl = &ctxp->em_tables[i];
-
-		if (tbl->num_entries && tbl->entry_size) {
-			rc = tf_em_size_table(tbl);
-
-			if (rc)
-				goto cleanup;
-
-			rc = tf_em_alloc_page_table(tbl);
-			if (rc)
-				goto cleanup;
-
-			tf_em_setup_page_table(tbl);
-			rc = tf_msg_em_mem_rgtr(tfp,
-						tbl->num_lvl - 1,
-						TF_EM_PAGE_SIZE_ENUM,
-						tbl->l0_dma_addr,
-						&tbl->ctx_id);
-			if (rc)
-				goto cleanup;
-		}
-	}
-	return rc;
-
-cleanup:
-	tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
-	return rc;
-}
-
-/**
- * Validates EM number of entries requested
- *
- * [in] tbl_scope_cb
- *   Pointer to table scope control block to be populated
- *
- * [in] parms
- *   Pointer to input parameters
- *
- * Returns:
- *   0       - Success
- *   -EINVAL - Parameter error
- */
-static int
-tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,
-			   struct tf_alloc_tbl_scope_parms *parms)
-{
-	uint32_t cnt;
-
-	if (parms->rx_mem_size_in_mb != 0) {
-		uint32_t key_b = 2 * ((parms->rx_max_key_sz_in_bits / 8) + 1);
-		uint32_t action_b = ((parms->rx_max_action_entry_sz_in_bits / 8)
-				     + 1);
-		uint32_t num_entries = (parms->rx_mem_size_in_mb *
-					TF_MEGABYTE) / (key_b + action_b);
-
-		if (num_entries < TF_EM_MIN_ENTRIES) {
-			TFP_DRV_LOG(ERR, "EEM: Insufficient memory requested:"
-				    "%uMB\n",
-				    parms->rx_mem_size_in_mb);
-			return -EINVAL;
-		}
-
-		cnt = TF_EM_MIN_ENTRIES;
-		while (num_entries > cnt &&
-		       cnt <= TF_EM_MAX_ENTRIES)
-			cnt *= 2;
-
-		if (cnt > TF_EM_MAX_ENTRIES) {
-			TFP_DRV_LOG(ERR, "EEM: Invalid number of Tx requested: "
-				    "%u\n",
-		       (parms->tx_num_flows_in_k * TF_KILOBYTE));
-			return -EINVAL;
-		}
-
-		parms->rx_num_flows_in_k = cnt / TF_KILOBYTE;
-	} else {
-		if ((parms->rx_num_flows_in_k * TF_KILOBYTE) <
-		    TF_EM_MIN_ENTRIES ||
-		    (parms->rx_num_flows_in_k * TF_KILOBYTE) >
-		    tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Invalid number of Rx flows "
-				    "requested:%u max:%u\n",
-				    parms->rx_num_flows_in_k * TF_KILOBYTE,
-			tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported);
-			return -EINVAL;
-		}
-
-		/* must be a power-of-2 supported value
-		 * in the range 32K - 128M
-		 */
-		cnt = TF_EM_MIN_ENTRIES;
-		while ((parms->rx_num_flows_in_k * TF_KILOBYTE) != cnt &&
-		       cnt <= TF_EM_MAX_ENTRIES)
-			cnt *= 2;
-
-		if (cnt > TF_EM_MAX_ENTRIES) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Invalid number of Rx requested: %u\n",
-				    (parms->rx_num_flows_in_k * TF_KILOBYTE));
-			return -EINVAL;
-		}
-	}
-
-	if (parms->tx_mem_size_in_mb != 0) {
-		uint32_t key_b = 2 * (parms->tx_max_key_sz_in_bits / 8 + 1);
-		uint32_t action_b = ((parms->tx_max_action_entry_sz_in_bits / 8)
-				     + 1);
-		uint32_t num_entries = (parms->tx_mem_size_in_mb *
-					(TF_KILOBYTE * TF_KILOBYTE)) /
-			(key_b + action_b);
-
-		if (num_entries < TF_EM_MIN_ENTRIES) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Insufficient memory requested:%uMB\n",
-				    parms->rx_mem_size_in_mb);
-			return -EINVAL;
-		}
-
-		cnt = TF_EM_MIN_ENTRIES;
-		while (num_entries > cnt &&
-		       cnt <= TF_EM_MAX_ENTRIES)
-			cnt *= 2;
-
-		if (cnt > TF_EM_MAX_ENTRIES) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Invalid number of Tx requested: %u\n",
-		       (parms->tx_num_flows_in_k * TF_KILOBYTE));
-			return -EINVAL;
-		}
-
-		parms->tx_num_flows_in_k = cnt / TF_KILOBYTE;
-	} else {
-		if ((parms->tx_num_flows_in_k * TF_KILOBYTE) <
-		    TF_EM_MIN_ENTRIES ||
-		    (parms->tx_num_flows_in_k * TF_KILOBYTE) >
-		    tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Invalid number of Tx flows "
-				    "requested:%u max:%u\n",
-				    (parms->tx_num_flows_in_k * TF_KILOBYTE),
-			tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported);
-			return -EINVAL;
-		}
-
-		cnt = TF_EM_MIN_ENTRIES;
-		while ((parms->tx_num_flows_in_k * TF_KILOBYTE) != cnt &&
-		       cnt <= TF_EM_MAX_ENTRIES)
-			cnt *= 2;
-
-		if (cnt > TF_EM_MAX_ENTRIES) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Invalid number of Tx requested: %u\n",
-		       (parms->tx_num_flows_in_k * TF_KILOBYTE));
-			return -EINVAL;
-		}
-	}
-
-	if ((parms->rx_num_flows_in_k != 0) &&
-	    (parms->rx_max_key_sz_in_bits / 8 == 0)) {
-		TFP_DRV_LOG(ERR,
-			    "EEM: Rx key size required: %u\n",
-			    (parms->rx_max_key_sz_in_bits));
-		return -EINVAL;
-	}
-
-	if ((parms->tx_num_flows_in_k != 0) &&
-	    (parms->tx_max_key_sz_in_bits / 8 == 0)) {
-		TFP_DRV_LOG(ERR,
-			    "EEM: Tx key size required: %u\n",
-			    (parms->tx_max_key_sz_in_bits));
-		return -EINVAL;
-	}
-	/* Rx */
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries =
-		parms->rx_num_flows_in_k * TF_KILOBYTE;
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].entry_size =
-		parms->rx_max_key_sz_in_bits / 8;
-
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].num_entries =
-		parms->rx_num_flows_in_k * TF_KILOBYTE;
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].entry_size =
-		parms->rx_max_key_sz_in_bits / 8;
-
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].num_entries
-		= parms->rx_num_flows_in_k * TF_KILOBYTE;
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size
-		= parms->rx_max_action_entry_sz_in_bits / 8;
-
-	tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries
-		= 0;
-
-	/* Tx */
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries =
-		parms->tx_num_flows_in_k * TF_KILOBYTE;
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].entry_size =
-		parms->tx_max_key_sz_in_bits / 8;
-
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].num_entries =
-		parms->tx_num_flows_in_k * TF_KILOBYTE;
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].entry_size =
-		parms->tx_max_key_sz_in_bits / 8;
-
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].num_entries
-		= parms->tx_num_flows_in_k * TF_KILOBYTE;
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size
-		= parms->tx_max_action_entry_sz_in_bits / 8;
-
-	tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries
-		= 0;
-
-	return 0;
-}
-
 /**
  * Internal function to get a Table Entry. Supports all Table Types
  * except the TF_TBL_TYPE_EXT as that is handled as a table scope.
@@ -881,290 +148,6 @@ tf_free_tbl_entry_shadow(struct tf_session *tfs,
 }
 #endif /* TF_SHADOW */
 
-/**
- * Create External Tbl pool of memory indexes.
- *
- * [in] dir
- *   direction
- * [in] tbl_scope_cb
- *   pointer to the table scope
- * [in] num_entries
- *   number of entries to write
- * [in] entry_sz_bytes
- *   size of each entry
- *
- * Return:
- *  0       - Success, entry allocated - no search support
- *  -ENOMEM -EINVAL -EOPNOTSUPP
- *          - Failure, entry not allocated, out of resources
- */
-static int
-tf_create_tbl_pool_external(enum tf_dir dir,
-			    struct tf_tbl_scope_cb *tbl_scope_cb,
-			    uint32_t num_entries,
-			    uint32_t entry_sz_bytes)
-{
-	struct tfp_calloc_parms parms;
-	uint32_t i;
-	int32_t j;
-	int rc = 0;
-	struct stack *pool = &tbl_scope_cb->ext_act_pool[dir];
-
-	parms.nitems = num_entries;
-	parms.size = sizeof(uint32_t);
-	parms.alignment = 0;
-
-	if (tfp_calloc(&parms) != 0) {
-		TFP_DRV_LOG(ERR, "%s: TBL: external pool failure %s\n",
-			    tf_dir_2_str(dir), strerror(ENOMEM));
-		return -ENOMEM;
-	}
-
-	/* Create empty stack
-	 */
-	rc = stack_init(num_entries, parms.mem_va, pool);
-
-	if (rc != 0) {
-		TFP_DRV_LOG(ERR, "%s: TBL: stack init failure %s\n",
-			    tf_dir_2_str(dir), strerror(-rc));
-		goto cleanup;
-	}
-
-	/* Save the  malloced memory address so that it can
-	 * be freed when the table scope is freed.
-	 */
-	tbl_scope_cb->ext_act_pool_mem[dir] = (uint32_t *)parms.mem_va;
-
-	/* Fill pool with indexes in reverse
-	 */
-	j = (num_entries - 1) * entry_sz_bytes;
-
-	for (i = 0; i < num_entries; i++) {
-		rc = stack_push(pool, j);
-		if (rc != 0) {
-			TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
-				    tf_dir_2_str(dir), strerror(-rc));
-			goto cleanup;
-		}
-
-		if (j < 0) {
-			TFP_DRV_LOG(ERR, "%d TBL: invalid offset (%d)\n",
-				    dir, j);
-			goto cleanup;
-		}
-		j -= entry_sz_bytes;
-	}
-
-	if (!stack_is_full(pool)) {
-		rc = -EINVAL;
-		TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
-			    tf_dir_2_str(dir), strerror(-rc));
-		goto cleanup;
-	}
-	return 0;
-cleanup:
-	tfp_free((void *)parms.mem_va);
-	return rc;
-}
-
-/**
- * Destroy External Tbl pool of memory indexes.
- *
- * [in] dir
- *   direction
- * [in] tbl_scope_cb
- *   pointer to the table scope
- *
- */
-static void
-tf_destroy_tbl_pool_external(enum tf_dir dir,
-			     struct tf_tbl_scope_cb *tbl_scope_cb)
-{
-	uint32_t *ext_act_pool_mem =
-		tbl_scope_cb->ext_act_pool_mem[dir];
-
-	tfp_free(ext_act_pool_mem);
-}
-
-/* API defined in tf_em.h */
-struct tf_tbl_scope_cb *
-tbl_scope_cb_find(struct tf_session *session,
-		  uint32_t tbl_scope_id)
-{
-	int i;
-
-	/* Check that id is valid */
-	i = ba_inuse(session->tbl_scope_pool_rx, tbl_scope_id);
-	if (i < 0)
-		return NULL;
-
-	for (i = 0; i < TF_NUM_TBL_SCOPE; i++) {
-		if (session->tbl_scopes[i].tbl_scope_id == tbl_scope_id)
-			return &session->tbl_scopes[i];
-	}
-
-	return NULL;
-}
-
-/* API defined in tf_core.h */
-int
-tf_free_eem_tbl_scope_cb(struct tf *tfp,
-			 struct tf_free_tbl_scope_parms *parms)
-{
-	int rc = 0;
-	enum tf_dir  dir;
-	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct tf_session *session;
-
-	session = (struct tf_session *)(tfp->session->core_data);
-
-	tbl_scope_cb = tbl_scope_cb_find(session,
-					 parms->tbl_scope_id);
-
-	if (tbl_scope_cb == NULL) {
-		TFP_DRV_LOG(ERR, "Table scope error\n");
-		return -EINVAL;
-	}
-
-	/* Free Table control block */
-	ba_free(session->tbl_scope_pool_rx, tbl_scope_cb->index);
-
-	/* free table scope locks */
-	for (dir = 0; dir < TF_DIR_MAX; dir++) {
-		/* Free associated external pools
-		 */
-		tf_destroy_tbl_pool_external(dir,
-					     tbl_scope_cb);
-		tf_msg_em_op(tfp,
-			     dir,
-			     HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_DISABLE);
-
-		/* free table scope and all associated resources */
-		tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
-	}
-
-	return rc;
-}
-
-/* API defined in tf_em.h */
-int
-tf_alloc_eem_tbl_scope(struct tf *tfp,
-		       struct tf_alloc_tbl_scope_parms *parms)
-{
-	int rc;
-	enum tf_dir dir;
-	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct hcapi_cfa_em_table *em_tables;
-	int index;
-	struct tf_session *session;
-	struct tf_free_tbl_scope_parms free_parms;
-
-	session = (struct tf_session *)tfp->session->core_data;
-
-	/* Get Table Scope control block from the session pool */
-	index = ba_alloc(session->tbl_scope_pool_rx);
-	if (index == -1) {
-		TFP_DRV_LOG(ERR, "EEM: Unable to allocate table scope "
-			    "Control Block\n");
-		return -ENOMEM;
-	}
-
-	tbl_scope_cb = &session->tbl_scopes[index];
-	tbl_scope_cb->index = index;
-	tbl_scope_cb->tbl_scope_id = index;
-	parms->tbl_scope_id = index;
-
-	for (dir = 0; dir < TF_DIR_MAX; dir++) {
-		rc = tf_msg_em_qcaps(tfp,
-				     dir,
-				     &tbl_scope_cb->em_caps[dir]);
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Unable to query for EEM capability,"
-				    " rc:%s\n",
-				    strerror(-rc));
-			goto cleanup;
-		}
-	}
-
-	/*
-	 * Validate and setup table sizes
-	 */
-	if (tf_em_validate_num_entries(tbl_scope_cb, parms))
-		goto cleanup;
-
-	for (dir = 0; dir < TF_DIR_MAX; dir++) {
-		/*
-		 * Allocate tables and signal configuration to FW
-		 */
-		rc = tf_em_ctx_reg(tfp, tbl_scope_cb, dir);
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Unable to register for EEM ctx,"
-				    " rc:%s\n",
-				    strerror(-rc));
-			goto cleanup;
-		}
-
-		em_tables = tbl_scope_cb->em_ctx_info[dir].em_tables;
-		rc = tf_msg_em_cfg(tfp,
-				   em_tables[TF_KEY0_TABLE].num_entries,
-				   em_tables[TF_KEY0_TABLE].ctx_id,
-				   em_tables[TF_KEY1_TABLE].ctx_id,
-				   em_tables[TF_RECORD_TABLE].ctx_id,
-				   em_tables[TF_EFC_TABLE].ctx_id,
-				   parms->hw_flow_cache_flush_timer,
-				   dir);
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "TBL: Unable to configure EEM in firmware"
-				    " rc:%s\n",
-				    strerror(-rc));
-			goto cleanup_full;
-		}
-
-		rc = tf_msg_em_op(tfp,
-				  dir,
-				  HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_ENABLE);
-
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "EEM: Unable to enable EEM in firmware"
-				    " rc:%s\n",
-				    strerror(-rc));
-			goto cleanup_full;
-		}
-
-		/* Allocate the pool of offsets of the external memory.
-		 * Initially, this is a single fixed size pool for all external
-		 * actions related to a single table scope.
-		 */
-		rc = tf_create_tbl_pool_external(dir,
-					    tbl_scope_cb,
-					    em_tables[TF_RECORD_TABLE].num_entries,
-					    em_tables[TF_RECORD_TABLE].entry_size);
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "%s TBL: Unable to allocate idx pools %s\n",
-				    tf_dir_2_str(dir),
-				    strerror(-rc));
-			goto cleanup_full;
-		}
-	}
-
-	return 0;
-
-cleanup_full:
-	free_parms.tbl_scope_id = index;
-	tf_free_eem_tbl_scope_cb(tfp, &free_parms);
-	return -EINVAL;
-
-cleanup:
-	/* Free Table control block */
-	ba_free(session->tbl_scope_pool_rx, tbl_scope_cb->index);
-	return -EINVAL;
-}
-
 /* API defined in tf_core.h */
 int
 tf_bulk_get_tbl_entry(struct tf *tfp,
@@ -1194,119 +177,3 @@ tf_bulk_get_tbl_entry(struct tf *tfp,
 
 	return rc;
 }
-
-/* API defined in tf_core.h */
-int
-tf_alloc_tbl_scope(struct tf *tfp,
-		   struct tf_alloc_tbl_scope_parms *parms)
-{
-	int rc;
-
-	TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
-
-	rc = tf_alloc_eem_tbl_scope(tfp, parms);
-
-	return rc;
-}
-
-/* API defined in tf_core.h */
-int
-tf_free_tbl_scope(struct tf *tfp,
-		  struct tf_free_tbl_scope_parms *parms)
-{
-	int rc;
-
-	TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
-
-	/* free table scope and all associated resources */
-	rc = tf_free_eem_tbl_scope_cb(tfp, parms);
-
-	return rc;
-}
-
-static void
-tf_dump_link_page_table(struct hcapi_cfa_em_page_tbl *tp,
-			struct hcapi_cfa_em_page_tbl *tp_next)
-{
-	uint64_t *pg_va;
-	uint32_t i;
-	uint32_t j;
-	uint32_t k = 0;
-
-	printf("pg_count:%d pg_size:0x%x\n",
-	       tp->pg_count,
-	       tp->pg_size);
-	for (i = 0; i < tp->pg_count; i++) {
-		pg_va = tp->pg_va_tbl[i];
-		printf("\t%p\n", (void *)pg_va);
-		for (j = 0; j < MAX_PAGE_PTRS(tp->pg_size); j++) {
-			printf("\t\t%p\n", (void *)(uintptr_t)pg_va[j]);
-			if (((pg_va[j] & 0x7) ==
-			     tfp_cpu_to_le_64(PTU_PTE_LAST |
-					      PTU_PTE_VALID)))
-				return;
-
-			if (!(pg_va[j] & tfp_cpu_to_le_64(PTU_PTE_VALID))) {
-				printf("** Invalid entry **\n");
-				return;
-			}
-
-			if (++k >= tp_next->pg_count) {
-				printf("** Shouldn't get here **\n");
-				return;
-			}
-		}
-	}
-}
-
-void tf_dump_dma(struct tf *tfp, uint32_t tbl_scope_id);
-
-void tf_dump_dma(struct tf *tfp, uint32_t tbl_scope_id)
-{
-	struct tf_session      *session;
-	struct tf_tbl_scope_cb *tbl_scope_cb;
-	struct hcapi_cfa_em_page_tbl *tp;
-	struct hcapi_cfa_em_page_tbl *tp_next;
-	struct hcapi_cfa_em_table *tbl;
-	int i;
-	int j;
-	int dir;
-
-	printf("called %s\n", __func__);
-
-	/* find session struct */
-	session = (struct tf_session *)tfp->session->core_data;
-
-	/* find control block for table scope */
-	tbl_scope_cb = tbl_scope_cb_find(session,
-					 tbl_scope_id);
-	if (tbl_scope_cb == NULL)
-		PMD_DRV_LOG(ERR, "No table scope\n");
-
-	for (dir = 0; dir < TF_DIR_MAX; dir++) {
-		printf("Direction %s:\n", (dir == TF_DIR_RX ? "Rx" : "Tx"));
-
-		for (j = TF_KEY0_TABLE; j < TF_MAX_TABLE; j++) {
-			tbl = &tbl_scope_cb->em_ctx_info[dir].em_tables[j];
-			printf
-	("Table: j:%d type:%d num_entries:%d entry_size:0x%x num_lvl:%d ",
-			       j,
-			       tbl->type,
-			       tbl->num_entries,
-			       tbl->entry_size,
-			       tbl->num_lvl);
-			if (tbl->pg_tbl[0].pg_va_tbl &&
-			    tbl->pg_tbl[0].pg_pa_tbl)
-				printf("%p %p\n",
-			       tbl->pg_tbl[0].pg_va_tbl[0],
-			       (void *)(uintptr_t)tbl->pg_tbl[0].pg_pa_tbl[0]);
-			for (i = 0; i < tbl->num_lvl - 1; i++) {
-				printf("Level:%d\n", i);
-				tp = &tbl->pg_tbl[i];
-				tp_next = &tbl->pg_tbl[i + 1];
-				tf_dump_link_page_table(tp, tp_next);
-			}
-			printf("\n");
-		}
-	}
-}
diff --git a/drivers/net/bnxt/tf_core/tf_tbl_type.c b/drivers/net/bnxt/tf_core/tf_tbl_type.c
index bdf7d20..2f5af60 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl_type.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl_type.c
@@ -209,8 +209,10 @@ tf_tbl_set(struct tf *tfp,
 	   struct tf_tbl_set_parms *parms)
 {
 	int rc;
-	struct tf_rm_is_allocated_parms aparms;
 	int allocated = 0;
+	uint16_t hcapi_type;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_rm_get_hcapi_parms hparms = { 0 };
 
 	TF_CHECK_PARMS3(tfp, parms, parms->data);
 
@@ -240,9 +242,22 @@ tf_tbl_set(struct tf *tfp,
 	}
 
 	/* Set the entry */
+	hparms.rm_db = tbl_db[parms->dir];
+	hparms.db_index = parms->type;
+	hparms.hcapi_type = &hcapi_type;
+	rc = tf_rm_get_hcapi_type(&hparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s, Failed type lookup, type:%d, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    strerror(-rc));
+		return rc;
+	}
+
 	rc = tf_msg_set_tbl_entry(tfp,
 				  parms->dir,
-				  parms->type,
+				  hcapi_type,
 				  parms->data_sz_in_bytes,
 				  parms->data,
 				  parms->idx);
@@ -262,8 +277,10 @@ tf_tbl_get(struct tf *tfp,
 	   struct tf_tbl_get_parms *parms)
 {
 	int rc;
-	struct tf_rm_is_allocated_parms aparms;
+	uint16_t hcapi_type;
 	int allocated = 0;
+	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_rm_get_hcapi_parms hparms = { 0 };
 
 	TF_CHECK_PARMS3(tfp, parms, parms->data);
 
@@ -292,10 +309,24 @@ tf_tbl_get(struct tf *tfp,
 		return -EINVAL;
 	}
 
+	/* Set the entry */
+	hparms.rm_db = tbl_db[parms->dir];
+	hparms.db_index = parms->type;
+	hparms.hcapi_type = &hcapi_type;
+	rc = tf_rm_get_hcapi_type(&hparms);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s, Failed type lookup, type:%d, rc:%s\n",
+			    tf_dir_2_str(parms->dir),
+			    parms->type,
+			    strerror(-rc));
+		return rc;
+	}
+
 	/* Get the entry */
 	rc = tf_msg_get_tbl_entry(tfp,
 				  parms->dir,
-				  parms->type,
+				  hcapi_type,
 				  parms->data_sz_in_bytes,
 				  parms->data,
 				  parms->idx);
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index 260fb15..a1761ad 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -53,7 +53,6 @@ tf_tcam_bind(struct tf *tfp,
 		return -EINVAL;
 	}
 
-	db_cfg.num_elements = parms->num_elements;
 	db_cfg.type = TF_DEVICE_MODULE_TYPE_TCAM;
 	db_cfg.num_elements = parms->num_elements;
 	db_cfg.cfg = parms->cfg;
@@ -174,14 +173,15 @@ tf_tcam_alloc(struct tf *tfp,
 }
 
 int
-tf_tcam_free(struct tf *tfp __rte_unused,
-	     struct tf_tcam_free_parms *parms __rte_unused)
+tf_tcam_free(struct tf *tfp,
+	     struct tf_tcam_free_parms *parms)
 {
 	int rc;
 	struct tf_session *tfs;
 	struct tf_dev_info *dev;
 	struct tf_rm_is_allocated_parms aparms = { 0 };
 	struct tf_rm_free_parms fparms = { 0 };
+	struct tf_rm_get_hcapi_parms hparms = { 0 };
 	uint16_t num_slice_per_row = 1;
 	int allocated = 0;
 
@@ -253,6 +253,15 @@ tf_tcam_free(struct tf *tfp __rte_unused,
 		return rc;
 	}
 
+	/* Convert TF type to HCAPI RM type */
+	hparms.rm_db = tcam_db[parms->dir];
+	hparms.db_index = parms->type;
+	hparms.hcapi_type = &parms->hcapi_type;
+
+	rc = tf_rm_get_hcapi_type(&hparms);
+	if (rc)
+		return rc;
+
 	rc = tf_msg_tcam_entry_free(tfp, parms);
 	if (rc) {
 		/* Log error */
@@ -281,6 +290,7 @@ tf_tcam_set(struct tf *tfp __rte_unused,
 	struct tf_session *tfs;
 	struct tf_dev_info *dev;
 	struct tf_rm_is_allocated_parms aparms = { 0 };
+	struct tf_rm_get_hcapi_parms hparms = { 0 };
 	uint16_t num_slice_per_row = 1;
 	int allocated = 0;
 
@@ -338,6 +348,15 @@ tf_tcam_set(struct tf *tfp __rte_unused,
 		return rc;
 	}
 
+	/* Convert TF type to HCAPI RM type */
+	hparms.rm_db = tcam_db[parms->dir];
+	hparms.db_index = parms->type;
+	hparms.hcapi_type = &parms->hcapi_type;
+
+	rc = tf_rm_get_hcapi_type(&hparms);
+	if (rc)
+		return rc;
+
 	rc = tf_msg_tcam_entry_set(tfp, parms);
 	if (rc) {
 		/* Log error */
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h
index 5090dfd..ee5bacc 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.h
+++ b/drivers/net/bnxt/tf_core/tf_tcam.h
@@ -77,6 +77,10 @@ struct tf_tcam_free_parms {
 	 */
 	enum tf_tcam_tbl_type type;
 	/**
+	 * [in] Type of HCAPI
+	 */
+	uint16_t hcapi_type;
+	/**
 	 * [in] Index to free
 	 */
 	uint16_t idx;
diff --git a/drivers/net/bnxt/tf_core/tf_util.c b/drivers/net/bnxt/tf_core/tf_util.c
index 16c43eb..5472a9a 100644
--- a/drivers/net/bnxt/tf_core/tf_util.c
+++ b/drivers/net/bnxt/tf_core/tf_util.c
@@ -152,9 +152,9 @@ tf_device_module_type_subtype_2_str(enum tf_device_module_type dm_type,
 	case TF_DEVICE_MODULE_TYPE_IDENTIFIER:
 		return tf_ident_2_str(mod_type);
 	case TF_DEVICE_MODULE_TYPE_TABLE:
-		return tf_tcam_tbl_2_str(mod_type);
-	case TF_DEVICE_MODULE_TYPE_TCAM:
 		return tf_tbl_type_2_str(mod_type);
+	case TF_DEVICE_MODULE_TYPE_TCAM:
+		return tf_tcam_tbl_2_str(mod_type);
 	case TF_DEVICE_MODULE_TYPE_EM:
 		return tf_em_tbl_type_2_str(mod_type);
 	default:
