diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index aea9305486..1f0b37addf 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -699,6 +699,8 @@ struct cmd_nums {
 	/* Experimental */
 	#define HWRM_TF_SESSION_RESC_FLUSH                UINT32_C(0x2cf)
 	/* Experimental */
+	#define HWRM_TF_SESSION_RESC_INFO                 UINT32_C(0x2d0)
+	/* Experimental */
 	#define HWRM_TF_TBL_TYPE_GET                      UINT32_C(0x2da)
 	/* Experimental */
 	#define HWRM_TF_TBL_TYPE_SET                      UINT32_C(0x2db)
@@ -727,6 +729,8 @@ struct cmd_nums {
 	/* Experimental */
 	#define HWRM_TF_EM_HASH_INSERT                    UINT32_C(0x2ec)
 	/* Experimental */
+	#define HWRM_TF_EM_MOVE                           UINT32_C(0x2ed)
+	/* Experimental */
 	#define HWRM_TF_TCAM_SET                          UINT32_C(0x2f8)
 	/* Experimental */
 	#define HWRM_TF_TCAM_GET                          UINT32_C(0x2f9)
@@ -986,8 +990,8 @@ struct hwrm_err_output {
 #define HWRM_VERSION_MINOR 10
 #define HWRM_VERSION_UPDATE 2
 /* non-zero means beta version */
-#define HWRM_VERSION_RSVD 15
-#define HWRM_VERSION_STR "1.10.2.15"
+#define HWRM_VERSION_RSVD 22
+#define HWRM_VERSION_STR "1.10.2.22"
 
 /****************
  * hwrm_ver_get *
@@ -30177,7 +30181,7 @@ struct hwrm_vnic_qcaps_output {
 		UINT32_C(0x20)
 	/*
 	 * When this bit is '1', the capability to
-	 * mirror the the RoCE traffic is supported.
+	 * mirror the RoCE traffic is supported.
 	 * If set to '0', then the capability to mirror the
 	 * RoCE traffic is not supported.
 	 */
@@ -30930,7 +30934,7 @@ struct hwrm_vnic_plcmodes_cfg_input {
 	uint16_t	hds_threshold;
 	/*
 	 * When virtio placement algorithm is enabled, this
-	 * value is used to determine the the maximum number of BDs
+	 * value is used to determine the maximum number of BDs
 	 * that can be used to place an Rx Packet.
 	 * If an incoming packet does not fit in the buffers described
 	 * by the max BDs, the packet will be dropped and an error
@@ -31094,7 +31098,7 @@ struct hwrm_vnic_plcmodes_qcfg_output {
 	uint16_t	hds_threshold;
 	/*
 	 * When virtio placement algorithm is enabled, this
-	 * value is used to determine the the maximum number of BDs
+	 * value is used to determine the maximum number of BDs
 	 * that can be used to place an Rx Packet.
 	 * If an incoming packet does not fit in the buffers described
 	 * by the max BDs, the packet will be dropped and an error
@@ -42143,8 +42147,24 @@ struct hwrm_tf_session_open_output {
 	 * the newly created session.
 	 */
 	uint32_t	fw_session_client_id;
-	/* unused. */
-	uint32_t	unused0;
+	uint32_t	flags;
+	/* Indicates if the shared session has been created. */
+	#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION \
+		UINT32_C(0x1)
+	/*
+	 * If this bit set to 0, then it indicates the shared session
+	 * has been created by another session.
+	 */
+	#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_NOT_CREATOR \
+		UINT32_C(0x0)
+	/*
+	 * If this bit is set to 1, then it indicates the shared session
+	 * is created by this session.
+	 */
+	#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR \
+		UINT32_C(0x1)
+	#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_LAST \
+		HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR
 	/* unused. */
 	uint8_t	unused1[3];
 	/*
@@ -42948,6 +42968,105 @@ struct hwrm_tf_session_resc_flush_output {
 	uint8_t	valid;
 } __rte_packed;
 
+/*****************************
+ * hwrm_tf_session_resc_info *
+ *****************************/
+
+
+/* hwrm_tf_session_resc_info_input (size:320b/40B) */
+struct hwrm_tf_session_resc_info_input {
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/*
+	 * The completion ring to send the completion event on. This should
+	 * be the NQ ID returned from the `nq_alloc` HWRM command.
+	 */
+	uint16_t	cmpl_ring;
+	/*
+	 * The sequence ID is used by the driver for tracking multiple
+	 * commands. This ID is treated as opaque data by the firmware and
+	 * the value is returned in the `hwrm_resp_hdr` upon completion.
+	 */
+	uint16_t	seq_id;
+	/*
+	 * The target ID of the command:
+	 * * 0x0-0xFFF8 - The function ID
+	 * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors
+	 * * 0xFFFD - Reserved for user-space HWRM interface
+	 * * 0xFFFF - HWRM
+	 */
+	uint16_t	target_id;
+	/*
+	 * A physical address pointer pointing to a host buffer that the
+	 * command's response data will be written. This can be either a host
+	 * physical address (HPA) or a guest physical address (GPA) and must
+	 * point to a physically contiguous block of memory.
+	 */
+	uint64_t	resp_addr;
+	/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent. */
+	uint32_t	fw_session_id;
+	/* Control flags. */
+	uint16_t	flags;
+	/* Indicates the flow direction. */
+	#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR     UINT32_C(0x1)
+	/* If this bit set to 0, then it indicates rx flow. */
+	#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_RX    UINT32_C(0x0)
+	/* If this bit is set to 1, then it indicates tx flow. */
+	#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_TX    UINT32_C(0x1)
+	#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_LAST \
+		HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_TX
+	/*
+	 * Defines the array size of the provided req_addr and
+	 * resv_addr array buffers. Should be set to the number of
+	 * request entries.
+	 */
+	uint16_t	req_size;
+	/*
+	 * This is the DMA address for the request input data array
+	 * buffer. Array is of tf_rm_resc_req_entry type. Size of the
+	 * array buffer is provided by the 'req_size' field in this
+	 * message.
+	 */
+	uint64_t	req_addr;
+	/*
+	 * This is the DMA address for the resc output data array
+	 * buffer. Array is of tf_rm_resc_entry type. Size of the array
+	 * buffer is provided by the 'req_size' field in this
+	 * message.
+	 */
+	uint64_t	resc_addr;
+} __rte_packed;
+
+/* hwrm_tf_session_resc_info_output (size:128b/16B) */
+struct hwrm_tf_session_resc_info_output {
+	/* The specific error status for the command. */
+	uint16_t	error_code;
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/* The sequence ID from the original command. */
+	uint16_t	seq_id;
+	/* The length of the response data in number of bytes. */
+	uint16_t	resp_len;
+	/*
+	 * Size of the returned tf_rm_resc_entry data array. The value
+	 * cannot exceed the req_size defined by the input msg. The data
+	 * array is returned using the resv_addr specified DMA
+	 * address also provided by the input msg.
+	 */
+	uint16_t	size;
+	/* unused. */
+	uint8_t	unused0[5];
+	/*
+	 * This field is used in Output records to indicate that the output
+	 * is completely written to RAM. This field should be read as '1'
+	 * to indicate that the output has been completely written.
+	 * When writing a command completion or response to an internal
+	 * processor, the order of writes has to be such that this field is
+	 * written last.
+	 */
+	uint8_t	valid;
+} __rte_packed;
+
 /* TruFlow RM capability of a resource. */
 /* tf_rm_resc_req_entry (size:64b/8B) */
 struct tf_rm_resc_req_entry {
@@ -44434,6 +44553,79 @@ struct hwrm_tf_em_delete_output {
 	uint16_t	unused0[3];
 } __rte_packed;
 
+/*******************
+ * hwrm_tf_em_move *
+ *******************/
+
+
+/* hwrm_tf_em_move_input (size:320b/40B) */
+struct hwrm_tf_em_move_input {
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/*
+	 * The completion ring to send the completion event on. This should
+	 * be the NQ ID returned from the `nq_alloc` HWRM command.
+	 */
+	uint16_t	cmpl_ring;
+	/*
+	 * The sequence ID is used by the driver for tracking multiple
+	 * commands. This ID is treated as opaque data by the firmware and
+	 * the value is returned in the `hwrm_resp_hdr` upon completion.
+	 */
+	uint16_t	seq_id;
+	/*
+	 * The target ID of the command:
+	 * * 0x0-0xFFF8 - The function ID
+	 * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors
+	 * * 0xFFFD - Reserved for user-space HWRM interface
+	 * * 0xFFFF - HWRM
+	 */
+	uint16_t	target_id;
+	/*
+	 * A physical address pointer pointing to a host buffer that the
+	 * command's response data will be written. This can be either a host
+	 * physical address (HPA) or a guest physical address (GPA) and must
+	 * point to a physically contiguous block of memory.
+	 */
+	uint64_t	resp_addr;
+	/* Session Id. */
+	uint32_t	fw_session_id;
+	/* Control flags. */
+	uint16_t	flags;
+	/* Indicates the flow direction. */
+	#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR     UINT32_C(0x1)
+	/* If this bit set to 0, then it indicates rx flow. */
+	#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_RX    UINT32_C(0x0)
+	/* If this bit is set to 1, then it indicates tx flow. */
+	#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_TX    UINT32_C(0x1)
+	#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_LAST \
+		HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_TX
+	/* Number of EM entry blocks */
+	uint16_t	num_blocks;
+	/* New index for entry */
+	uint32_t	new_index;
+	/* Unused */
+	uint32_t	unused0;
+	/* EM internal flow handle. */
+	uint64_t	flow_handle;
+} __rte_packed;
+
+/* hwrm_tf_em_move_output (size:128b/16B) */
+struct hwrm_tf_em_move_output {
+	/* The specific error status for the command. */
+	uint16_t	error_code;
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/* The sequence ID from the original command. */
+	uint16_t	seq_id;
+	/* The length of the response data in number of bytes. */
+	uint16_t	resp_len;
+	/* Index of old entry. */
+	uint16_t	em_index;
+	/* unused. */
+	uint16_t	unused0[3];
+} __rte_packed;
+
 /********************
  * hwrm_tf_tcam_set *
  ********************/
@@ -46989,8 +47181,8 @@ struct hwrm_nvm_write_input {
 	 */
 	uint64_t	host_src_addr;
 	/*
-	 * The Directory Entry Type (valid values are defined in the bnxnvm
-	 * directory_type enum defined in the file bnxnvm_defs.h).
+	 * The Directory Entry Type (valid values are defined in the
+	 * bnxnvm_directory_type enum defined in the file bnxnvm_defs.h).
 	 */
 	uint16_t	dir_type;
 	/*
@@ -47003,10 +47195,10 @@ struct hwrm_nvm_write_input {
 	/* Directory Entry Attribute flags (see BNX_DIR_ATTR_* in the file bnxnvm_defs.h). */
 	uint16_t	dir_attr;
 	/*
-	 * Length of data to write, in bytes. May be less than or equal to the allocated
-	 * size for the directory entry.
-	 * The data length stored in the directory entry will be updated to reflect
-	 * this value once the write is complete.
+	 * Length of data to write, in bytes.May be
+	 * less than or equal to the allocated size for the directory entry.
+	 * The data length stored in the directory entry will be updated to
+	 * reflect this value once the write is complete.
 	 */
 	uint32_t	dir_data_length;
 	/* Option. */
@@ -47019,15 +47211,15 @@ struct hwrm_nvm_write_input {
 	#define HWRM_NVM_WRITE_INPUT_FLAGS_KEEP_ORIG_ACTIVE_IMG \
 		UINT32_C(0x1)
 	/*
-	 * The requested length of the allocated NVM for the item, in bytes. This
-	 * value may be greater than or equal to the specified data length (dir_data_length).
+	 * The requested length of the allocated NVM for the item, in bytes.
+	 * This value may be greater than or equal to the specified data length (dir_data_length).
 	 * If this value is less than the specified data length, it will be ignored.
-	 * The response will contain the actual allocated item length, which may be
-	 * greater than the requested item length.
+	 * The response will contain the actual allocated item length, which may
+	 * be greater than the requested item length.
 	 * The purpose for allocating more than the required number of bytes for
 	 * an item's data is to pre-allocate extra storage (padding) to accommodate
-	 * the potential future growth of an item (e.g. upgraded firmware with a
-	 * size increase, log growth, expanded configuration data).
+	 * the potential future growth of an item (e.g. upgraded firmware with
+	 * a size increase, log growth, expanded configuration data).
 	 */
 	uint32_t	dir_item_length;
 	uint32_t	unused_0;
@@ -47045,10 +47237,9 @@ struct hwrm_nvm_write_output {
 	uint16_t	resp_len;
 	/*
 	 * Length of the allocated NVM for the item, in bytes. The value may be
-	 * greater than or equal to the specified data length or the requested
-	 * item length.
-	 * The actual item length used when creating a new directory entry will be
-	 * a multiple of an NVM block size.
+	 * greater than or equal to the specified data length or the requested item length.
+	 * The actual item length used when creating a new directory entry will
+	 * be a multiple of an NVM block size.
 	 */
 	uint32_t	dir_item_length;
 	/* The directory index of the created or modified item. */
@@ -47538,14 +47729,11 @@ struct hwrm_nvm_mod_dir_entry_input {
 	 */
 	uint16_t	dir_ordinal;
 	/*
-	 * The Directory Entry Extension flags (see BNX_DIR_EXT_* for extension
-	 * flag definitions).
+	 * The Directory Entry Extension flags (see BNX_DIR_EXT_* for
+	 * extension flag definitions).
 	 */
 	uint16_t	dir_ext;
-	/*
-	 * Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag
-	 * definitions).
-	 */
+	/* Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag definitions). */
 	uint16_t	dir_attr;
 	/*
 	 * If valid, then this field updates the checksum
@@ -48406,8 +48594,8 @@ struct hwrm_fw_reset_input {
 	#define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_HOST \
 		UINT32_C(0x4)
 	/*
-	 * AP processor complex (in multi-host environment). Use host_idx to
-	 * control which core is reset
+	 * AP processor complex (in multi-host environment).
+	 * Use host_idx to control which core is reset
 	 */
 	#define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_AP \
 		UINT32_C(0x5)
diff --git a/drivers/net/bnxt/tf_core/bitalloc.c b/drivers/net/bnxt/tf_core/bitalloc.c
index af1397071b..e253cfc3a6 100644
--- a/drivers/net/bnxt/tf_core/bitalloc.c
+++ b/drivers/net/bnxt/tf_core/bitalloc.c
@@ -65,7 +65,7 @@ ba_ffs(bitalloc_word_t v)
 }
 
 int
-ba_init(struct bitalloc *pool, int size)
+ba_init(struct bitalloc *pool, int size, bool free)
 {
 	bitalloc_word_t *mem = (bitalloc_word_t *)pool;
 	int       i;
@@ -101,9 +101,11 @@ ba_init(struct bitalloc *pool, int size)
 		pool->storage[offset++] = words[--lev];
 	}
 
-	/* Free the entire pool */
-	for (i = 0; i < size; i++)
-		ba_free(pool, i);
+	/* Free the entire pool if it is required*/
+	if (free) {
+		for (i = 0; i < size; i++)
+			ba_free(pool, i);
+	}
 
 	return 0;
 }
diff --git a/drivers/net/bnxt/tf_core/bitalloc.h b/drivers/net/bnxt/tf_core/bitalloc.h
index 7244b86e95..e3b389e68d 100644
--- a/drivers/net/bnxt/tf_core/bitalloc.h
+++ b/drivers/net/bnxt/tf_core/bitalloc.h
@@ -7,6 +7,7 @@
 #define _BITALLOC_H_
 
 #include <stdint.h>
+#include <stdbool.h>
 
 /* Bitalloc works on uint32_t as its word size */
 typedef uint32_t bitalloc_word_t;
@@ -64,7 +65,7 @@ struct bitalloc {
  * Returns 0 on success, -1 on failure.  Size is arbitrary up to
  * BITALLOC_MAX_SIZE
  */
-int ba_init(struct bitalloc *pool, int size);
+int ba_init(struct bitalloc *pool, int size, bool free);
 
 /**
  * Returns -1 on failure, or index of allocated entry
diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c
index 9b8677caac..69f5c10293 100644
--- a/drivers/net/bnxt/tf_core/tf_core.c
+++ b/drivers/net/bnxt/tf_core/tf_core.c
@@ -27,6 +27,8 @@ tf_open_session(struct tf *tfp,
 	int rc;
 	unsigned int domain, bus, slot, device;
 	struct tf_session_open_session_parms oparms;
+	int name_len;
+	char *name;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -69,6 +71,13 @@ tf_open_session(struct tf *tfp,
 		}
 	}
 
+	name_len = strlen(parms->ctrl_chan_name);
+	name = &parms->ctrl_chan_name[name_len - strlen("tf_shared")];
+	if (!strncmp(name, "tf_shared", strlen("tf_shared"))) {
+		memset(parms->ctrl_chan_name, 0, strlen(parms->ctrl_chan_name));
+		strcpy(parms->ctrl_chan_name, "tf_share");
+	}
+
 	parms->session_id.internal.domain = domain;
 	parms->session_id.internal.bus = bus;
 	parms->session_id.internal.device = device;
@@ -1593,3 +1602,99 @@ tf_get_if_tbl_entry(struct tf *tfp,
 
 	return 0;
 }
+
+int tf_get_session_info(struct tf *tfp,
+			struct tf_get_session_info_parms *parms)
+{
+	int rc;
+	struct tf_session      *tfs;
+	struct tf_dev_info     *dev;
+
+	TF_CHECK_PARMS2(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;
+	}
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	if (dev->ops->tf_dev_get_ident_resc_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "Operation not supported, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = dev->ops->tf_dev_get_ident_resc_info(tfp, parms->session_info.ident);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Ident get resc info failed, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_get_tbl_resc_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "Operation not supported, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = dev->ops->tf_dev_get_tbl_resc_info(tfp, parms->session_info.tbl);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Tbl get resc info failed, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_get_tcam_resc_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "Operation not supported, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = dev->ops->tf_dev_get_tcam_resc_info(tfp, parms->session_info.tcam);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "TCAM get resc info failed, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	if (dev->ops->tf_dev_get_em_resc_info == NULL) {
+		rc = -EOPNOTSUPP;
+		TFP_DRV_LOG(ERR,
+			    "Operation not supported, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	rc = dev->ops->tf_dev_get_em_resc_info(tfp, parms->session_info.em);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "EM get resc info failed, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h
index 7b26b58000..4440d60fe5 100644
--- a/drivers/net/bnxt/tf_core/tf_core.h
+++ b/drivers/net/bnxt/tf_core/tf_core.h
@@ -557,7 +557,8 @@ struct tf_open_session_parms {
 	 * rte_eth_dev_get_name_by_port() within the ULP.
 	 *
 	 * ctrl_chan_name will be used as part of a name for any
-	 * shared memory allocation.
+	 * shared memory allocation. The ctrl_chan_name is usually in format
+	 * 0000:02:00.0. The name for shared session is 0000:02:00.0-tf_shared.
 	 */
 	char ctrl_chan_name[TF_SESSION_NAME_MAX];
 	/**
@@ -616,29 +617,63 @@ struct tf_open_session_parms {
 	 * Resource allocation for the session.
 	 */
 	struct tf_session_resources resources;
+
+	/**
+	 * [in] bp
+	 * The pointer to the parent bp struct. This is only used for HWRM
+	 * message passing within the portability layer. The type is struct
+	 * bnxt.
+	 */
+	void *bp;
+
+	/**
+	 * [out] shared_session_creator
+	 *
+	 * Indicates whether the application created the session if set.
+	 * Otherwise the shared session already existed.  Just for information
+	 * purposes.
+	 */
+	int shared_session_creator;
 };
 
 /**
  * Opens a new TruFlow Session or session client.
  *
- * What gets created depends on the passed in tfp content. If the tfp
- * does not have prior session data a new session with associated
- * session client. If tfp has a session already a session client will
- * be created. In both cases the session client is created using the
- * provided ctrl_chan_name.
+ * What gets created depends on the passed in tfp content. If the tfp does not
+ * have prior session data a new session with associated session client. If tfp
+ * has a session already a session client will be created. In both cases the
+ * session client is created using the provided ctrl_chan_name.
  *
- * In case of session creation TruFlow will allocate session specific
- * memory, shared memory, to hold its session data. This data is
- * private to TruFlow.
+ * In case of session creation TruFlow will allocate session specific memory to
+ * hold its session data. This data is private to TruFlow.
  *
  * No other TruFlow APIs will succeed unless this API is first called
  * and succeeds.
  *
- * tf_open_session() returns a session id and session client id that
- * is used on all other TF APIs.
+ * tf_open_session() returns a session id and session client id.  These are
+ * also stored within the tfp structure passed in to all other APIs.
  *
  * A Session or session client can be closed using tf_close_session().
  *
+ * There are 2 types of sessions - shared and not.  For non-shared all
+ * the allocated resources are owned and managed by a single session instance.
+ * No other applications have access to the resources owned by the non-shared
+ * session.  For a shared session, resources are shared between 2 applications.
+ *
+ * When the caller of tf_open_session() sets the ctrl_chan_name[] to a name
+ * like "0000:02:00.0-tf_shared", it is a request to create a new "shared"
+ * session in the firmware or access the existing shared session. There is
+ * only 1 shared session that can be created. If the shared session has
+ * already been created in the firmware, this API will return this indication
+ * by clearing the shared_session_creator flag. Only the first shared session
+ * create will have the shared_session_creator flag set.
+ *
+ * The shared session should always be the first session to be created by
+ * application and the last session closed due to RM management preference.
+ *
+ * Sessions remain open in the firmware until the last client of the session
+ * closes the session (tf_close_session()).
+ *
  * [in] tfp
  *   Pointer to TF handle
  *
@@ -652,6 +687,126 @@ struct tf_open_session_parms {
 int tf_open_session(struct tf *tfp,
 		    struct tf_open_session_parms *parms);
 
+/**
+ * General internal resource info
+ *
+ * TODO: remove tf_rm_new_entry structure and use this structure
+ * internally.
+ */
+struct tf_resource_info {
+	uint16_t start;
+	uint16_t stride;
+};
+
+/**
+ * Identifier resource definition
+ */
+struct tf_identifier_resource_info {
+	/**
+	 * Array of TF Identifiers. The index used is tf_identifier_type.
+	 */
+	struct tf_resource_info info[TF_IDENT_TYPE_MAX];
+};
+
+/**
+ * Table type resource info definition
+ */
+struct tf_tbl_resource_info {
+	/**
+	 * Array of TF Table types. The index used is tf_tbl_type.
+	 */
+	struct tf_resource_info info[TF_TBL_TYPE_MAX];
+};
+
+/**
+ * TCAM type resource definition
+ */
+struct tf_tcam_resource_info {
+	/**
+	 * Array of TF TCAM types. The index used is tf_tcam_tbl_type.
+	 */
+	struct tf_resource_info info[TF_TCAM_TBL_TYPE_MAX];
+};
+
+/**
+ * EM type resource definition
+ */
+struct tf_em_resource_info {
+	/**
+	 * Array of TF EM table types. The index used is tf_em_tbl_type.
+	 */
+	struct tf_resource_info info[TF_EM_TBL_TYPE_MAX];
+};
+
+/**
+ * tf_session_resources parameter definition.
+ */
+struct tf_session_resource_info {
+	/**
+	 * [in] Requested Identifier Resources
+	 *
+	 * Number of identifier resources requested for the
+	 * session.
+	 */
+	struct tf_identifier_resource_info ident[TF_DIR_MAX];
+	/**
+	 * [in] Requested Index Table resource counts
+	 *
+	 * The number of index table resources requested for the
+	 * session.
+	 */
+	struct tf_tbl_resource_info tbl[TF_DIR_MAX];
+	/**
+	 * [in] Requested TCAM Table resource counts
+	 *
+	 * The number of TCAM table resources requested for the
+	 * session.
+	 */
+
+	struct tf_tcam_resource_info tcam[TF_DIR_MAX];
+	/**
+	 * [in] Requested EM resource counts
+	 *
+	 * The number of internal EM table resources requested for the
+	 * session.
+	 */
+	struct tf_em_resource_info em[TF_DIR_MAX];
+};
+
+/**
+ * tf_get_session_resources parameter definition.
+ */
+struct tf_get_session_info_parms {
+	/**
+	 * [out] the structure is used to return the information of
+	 * allocated resources.
+	 *
+	 */
+	struct tf_session_resource_info session_info;
+};
+
+/** (experimental)
+ * Gets info about a TruFlow Session
+ *
+ * Get info about the session which has been created.  Whether it exists and
+ * what resource start and stride offsets are in use.  This API is primarily
+ * intended to be used by an application which has created a shared session
+ * This application needs to obtain the resources which have already been
+ * allocated for the shared session.
+ *
+ * [in] tfp
+ *   Pointer to TF handle
+ *
+ * [in] parms
+ *   Pointer to get parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_get_session_info(struct tf *tfp,
+			struct tf_get_session_info_parms *parms);
+
 /**
  * Experimental
  *
diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c
index 9e71c04bf2..fed4156200 100644
--- a/drivers/net/bnxt/tf_core/tf_device.c
+++ b/drivers/net/bnxt/tf_core/tf_device.c
@@ -351,10 +351,16 @@ tf_dev_bind_p58(struct tf *tfp,
 	struct tf_em_cfg_parms em_cfg;
 	struct tf_if_tbl_cfg_parms if_tbl_cfg;
 	struct tf_global_cfg_cfg_parms global_cfg;
+	struct tf_session *tfs;
 
 	/* Initial function initialization */
 	dev_handle->ops = &tf_dev_ops_p58_init;
 
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
 	rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX,
 					   tf_ident_p58,
 					   (uint16_t *)resources->ident_cnt);
@@ -440,26 +446,28 @@ tf_dev_bind_p58(struct tf *tfp,
 	/*
 	 * IF_TBL
 	 */
-	if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
-	if_tbl_cfg.cfg = tf_if_tbl_p58;
-	if_tbl_cfg.shadow_copy = shadow_copy;
-	rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "IF Table initialization failure\n");
-		goto fail;
-	}
+	if (!tf_session_is_shared_session(tfs)) {
+		if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;
+		if_tbl_cfg.cfg = tf_if_tbl_p58;
+		if_tbl_cfg.shadow_copy = shadow_copy;
+		rc = tf_if_tbl_bind(tfp, &if_tbl_cfg);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "IF Table initialization failure\n");
+			goto fail;
+		}
 
-	/*
-	 * GLOBAL_CFG
-	 */
-	global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
-	global_cfg.cfg = tf_global_cfg_p58;
-	rc = tf_global_cfg_bind(tfp, &global_cfg);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Global Cfg initialization failure\n");
-		goto fail;
+		/*
+		 * GLOBAL_CFG
+		 */
+		global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;
+		global_cfg.cfg = tf_global_cfg_p58;
+		rc = tf_global_cfg_bind(tfp, &global_cfg);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "Global Cfg initialization failure\n");
+			goto fail;
+		}
 	}
 
 	/* Final function initialization */
@@ -491,6 +499,12 @@ tf_dev_unbind_p58(struct tf *tfp)
 {
 	int rc = 0;
 	bool fail = false;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
 
 	/* Unbind all the support modules. As this is only done on
 	 * close we only report errors as everything has to be cleaned
@@ -527,18 +541,20 @@ tf_dev_unbind_p58(struct tf *tfp)
 		fail = true;
 	}
 
-	rc = tf_if_tbl_unbind(tfp);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Device unbind failed, IF Table Type\n");
-		fail = true;
-	}
+	if (!tf_session_is_shared_session(tfs)) {
+		rc = tf_if_tbl_unbind(tfp);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "Device unbind failed, IF Table Type\n");
+			fail = true;
+		}
 
-	rc = tf_global_cfg_unbind(tfp);
-	if (rc) {
-		TFP_DRV_LOG(ERR,
-			    "Device unbind failed, Global Cfg Type\n");
-		fail = true;
+		rc = tf_global_cfg_unbind(tfp);
+		if (rc) {
+			TFP_DRV_LOG(ERR,
+				    "Device unbind failed, Global Cfg Type\n");
+			fail = true;
+		}
 	}
 
 	if (fail)
diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h
index 3f2c24a0c6..16c2fe0f64 100644
--- a/drivers/net/bnxt/tf_core/tf_device.h
+++ b/drivers/net/bnxt/tf_core/tf_device.h
@@ -220,6 +220,25 @@ struct tf_dev_ops {
 	 */
 	int (*tf_dev_search_ident)(struct tf *tfp,
 				   struct tf_ident_search_parms *parms);
+
+	/**
+	 * Retrieves the identifier resource info.
+	 *
+	 * This API retrieves the identifier resource info from the rm db.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to identifier info
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_get_ident_resc_info)(struct tf *tfp,
+					  struct tf_identifier_resource_info *parms);
+
 	/**
 	 * Get SRAM table information.
 	 *
@@ -425,6 +444,24 @@ struct tf_dev_ops {
 	int (*tf_dev_get_bulk_tbl)(struct tf *tfp,
 				   struct tf_tbl_get_bulk_parms *parms);
 
+	/**
+	 * Retrieves the table resource info.
+	 *
+	 * This API retrieves the table resource info from the rm db.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to tbl info
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_get_tbl_resc_info)(struct tf *tfp,
+					 struct tf_tbl_resource_info *parms);
+
 	/**
 	 * Allocation of a tcam element.
 	 *
@@ -524,6 +561,24 @@ struct tf_dev_ops {
 	int (*tf_dev_get_tcam)(struct tf *tfp,
 			       struct tf_tcam_get_parms *parms);
 
+	/**
+	 * Retrieves the tcam resource info.
+	 *
+	 * This API retrieves the tcam resource info from the rm db.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to tcam info
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_get_tcam_resc_info)(struct tf *tfp,
+					 struct tf_tcam_resource_info *parms);
+
 	/**
 	 * Insert EM hash entry API
 	 *
@@ -588,6 +643,24 @@ struct tf_dev_ops {
 	int (*tf_dev_delete_ext_em_entry)(struct tf *tfp,
 					  struct tf_delete_em_entry_parms *parms);
 
+	/**
+	 * Retrieves the em resource info.
+	 *
+	 * This API retrieves the em resource info from the rm db.
+	 *
+	 * [in] tfp
+	 *   Pointer to TF handle
+	 *
+	 * [in] parms
+	 *   Pointer to em info
+	 *
+	 * Returns
+	 *   - (0) if successful.
+	 *   - (-EINVAL) on failure.
+	 */
+	int (*tf_dev_get_em_resc_info)(struct tf *tfp,
+				       struct tf_em_resource_info *parms);
+
 	/**
 	 * Allocate EEM table scope
 	 *
diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c
index 8797afa100..e74ba6cd8f 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p4.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c
@@ -206,6 +206,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_alloc_ident = NULL,
 	.tf_dev_free_ident = NULL,
 	.tf_dev_search_ident = NULL,
+	.tf_dev_get_ident_resc_info = NULL,
 	.tf_dev_get_tbl_info = NULL,
 	.tf_dev_alloc_ext_tbl = NULL,
 	.tf_dev_alloc_tbl = NULL,
@@ -216,15 +217,18 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {
 	.tf_dev_set_ext_tbl = NULL,
 	.tf_dev_get_tbl = NULL,
 	.tf_dev_get_bulk_tbl = NULL,
+	.tf_dev_get_tbl_resc_info = NULL,
 	.tf_dev_alloc_tcam = NULL,
 	.tf_dev_free_tcam = NULL,
 	.tf_dev_alloc_search_tcam = NULL,
 	.tf_dev_set_tcam = NULL,
 	.tf_dev_get_tcam = NULL,
+	.tf_dev_get_tcam_resc_info = 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_get_em_resc_info = NULL,
 	.tf_dev_alloc_tbl_scope = NULL,
 	.tf_dev_map_tbl_scope = NULL,
 	.tf_dev_map_parif = NULL,
@@ -247,6 +251,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_alloc_ident = tf_ident_alloc,
 	.tf_dev_free_ident = tf_ident_free,
 	.tf_dev_search_ident = tf_ident_search,
+	.tf_dev_get_ident_resc_info = tf_ident_get_resc_info,
 	.tf_dev_get_tbl_info = NULL,
 	.tf_dev_alloc_tbl = tf_tbl_alloc,
 	.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,
@@ -257,15 +262,18 @@ const struct tf_dev_ops tf_dev_ops_p4 = {
 	.tf_dev_set_ext_tbl = tf_tbl_ext_common_set,
 	.tf_dev_get_tbl = tf_tbl_get,
 	.tf_dev_get_bulk_tbl = tf_tbl_bulk_get,
+	.tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info,
 	.tf_dev_alloc_tcam = tf_tcam_alloc,
 	.tf_dev_free_tcam = tf_tcam_free,
 	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_set_tcam = tf_tcam_set,
 	.tf_dev_get_tcam = NULL,
+	.tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info,
 	.tf_dev_insert_int_em_entry = tf_em_insert_int_entry,
 	.tf_dev_delete_int_em_entry = tf_em_delete_int_entry,
 	.tf_dev_insert_ext_em_entry = tf_em_insert_ext_entry,
 	.tf_dev_delete_ext_em_entry = tf_em_delete_ext_entry,
+	.tf_dev_get_em_resc_info = tf_em_get_resc_info,
 	.tf_dev_alloc_tbl_scope = tf_em_ext_common_alloc,
 	.tf_dev_map_tbl_scope = tf_em_ext_map_tbl_scope,
 	.tf_dev_map_parif = tf_dev_p4_map_parif,
diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c
index b44648d216..32d621e7da 100644
--- a/drivers/net/bnxt/tf_core/tf_device_p58.c
+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c
@@ -227,6 +227,7 @@ const struct tf_dev_ops tf_dev_ops_p58_init = {
 	.tf_dev_alloc_ident = NULL,
 	.tf_dev_free_ident = NULL,
 	.tf_dev_search_ident = NULL,
+	.tf_dev_get_ident_resc_info = NULL,
 	.tf_dev_get_tbl_info = NULL,
 	.tf_dev_alloc_ext_tbl = NULL,
 	.tf_dev_alloc_tbl = NULL,
@@ -237,15 +238,18 @@ const struct tf_dev_ops tf_dev_ops_p58_init = {
 	.tf_dev_set_ext_tbl = NULL,
 	.tf_dev_get_tbl = NULL,
 	.tf_dev_get_bulk_tbl = NULL,
+	.tf_dev_get_tbl_resc_info = NULL,
 	.tf_dev_alloc_tcam = NULL,
 	.tf_dev_free_tcam = NULL,
 	.tf_dev_alloc_search_tcam = NULL,
 	.tf_dev_set_tcam = NULL,
 	.tf_dev_get_tcam = NULL,
+	.tf_dev_get_tcam_resc_info = 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_get_em_resc_info = NULL,
 	.tf_dev_alloc_tbl_scope = NULL,
 	.tf_dev_map_tbl_scope = NULL,
 	.tf_dev_map_parif = NULL,
@@ -268,6 +272,7 @@ const struct tf_dev_ops tf_dev_ops_p58 = {
 	.tf_dev_alloc_ident = tf_ident_alloc,
 	.tf_dev_free_ident = tf_ident_free,
 	.tf_dev_search_ident = tf_ident_search,
+	.tf_dev_get_ident_resc_info = tf_ident_get_resc_info,
 	.tf_dev_get_tbl_info = tf_dev_p58_get_sram_tbl_info,
 	.tf_dev_alloc_tbl = tf_tbl_alloc,
 	.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,
@@ -278,15 +283,18 @@ const struct tf_dev_ops tf_dev_ops_p58 = {
 	.tf_dev_set_ext_tbl = tf_tbl_ext_common_set,
 	.tf_dev_get_tbl = tf_tbl_get,
 	.tf_dev_get_bulk_tbl = tf_tbl_bulk_get,
+	.tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info,
 	.tf_dev_alloc_tcam = tf_tcam_alloc,
 	.tf_dev_free_tcam = tf_tcam_free,
 	.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
 	.tf_dev_set_tcam = tf_tcam_set,
 	.tf_dev_get_tcam = tf_tcam_get,
+	.tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info,
 	.tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry,
 	.tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry,
 	.tf_dev_insert_ext_em_entry = NULL,
 	.tf_dev_delete_ext_em_entry = NULL,
+	.tf_dev_get_em_resc_info = tf_em_get_resc_info,
 	.tf_dev_alloc_tbl_scope = NULL,
 	.tf_dev_map_tbl_scope = NULL,
 	.tf_dev_map_parif = NULL,
diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h
index 19ad7f12be..60d90e28de 100644
--- a/drivers/net/bnxt/tf_core/tf_em.h
+++ b/drivers/net/bnxt/tf_core/tf_em.h
@@ -530,4 +530,21 @@ tf_em_ext_system_bind(struct tf *tfp,
 		      struct tf_em_cfg_parms *parms);
 
 int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb);
+
+/**
+ * Retrieves the allocated resource info
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int
+tf_em_get_resc_info(struct tf *tfp,
+		    struct tf_em_resource_info *em);
 #endif /* _TF_EM_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c
index 4dc3c86b57..ed8f6db58c 100644
--- a/drivers/net/bnxt/tf_core/tf_em_common.c
+++ b/drivers/net/bnxt/tf_core/tf_em_common.c
@@ -26,11 +26,6 @@
 /* Number of pointers per page_size */
 #define MAX_PAGE_PTRS(page_size)  ((page_size) / sizeof(void *))
 
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
 /**
  * Host or system
  */
@@ -924,18 +919,11 @@ tf_em_ext_common_bind(struct tf *tfp,
 	int rc;
 	int i;
 	struct tf_rm_create_db_parms db_cfg = { 0 };
-	uint8_t db_exists = 0;
 	struct em_ext_db *ext_db;
 	struct tfp_calloc_parms cparms;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (init) {
-		TFP_DRV_LOG(ERR,
-			    "EM Ext DB already initialized\n");
-		return -EINVAL;
-	}
-
 	cparms.nitems = 1;
 	cparms.size = sizeof(struct em_ext_db);
 	cparms.alignment = 0;
@@ -974,12 +962,8 @@ tf_em_ext_common_bind(struct tf *tfp,
 
 			return rc;
 		}
-		db_exists = 1;
 	}
 
-	if (db_exists)
-		init = 1;
-
 	mem_type = parms->mem_type;
 
 	return 0;
@@ -1001,13 +985,6 @@ tf_em_ext_common_unbind(struct tf *tfp)
 
 	TF_CHECK_PARMS1(tfp);
 
-	/* Bail if nothing has been initialized */
-	if (!init) {
-		TFP_DRV_LOG(INFO,
-			    "No EM Ext DBs created\n");
-		return 0;
-	}
-
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc) {
 		TFP_DRV_LOG(ERR, "Failed to get tf_session, rc:%s\n",
@@ -1064,8 +1041,6 @@ tf_em_ext_common_unbind(struct tf *tfp)
 	tfp_free(ext_db);
 	tf_session_set_em_ext_db(tfp, NULL);
 
-	init = 0;
-
 	return 0;
 }
 
diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c
index 5a100ef1de..e373a9b029 100644
--- a/drivers/net/bnxt/tf_core/tf_em_internal.c
+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c
@@ -20,11 +20,6 @@
 
 #define TF_EM_DB_EM_REC 0
 
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
 /**
  * EM Pool
  */
@@ -234,19 +229,18 @@ tf_em_int_bind(struct tf *tfp,
 	int rc;
 	int i;
 	struct tf_rm_create_db_parms db_cfg = { 0 };
-	uint8_t db_exists = 0;
 	struct tf_rm_get_alloc_info_parms iparms;
 	struct tf_rm_alloc_info info;
 	struct em_rm_db *em_db;
 	struct tfp_calloc_parms cparms;
+	struct tf_session *tfs;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (init) {
-		TFP_DRV_LOG(ERR,
-			    "EM Int DB already initialized\n");
-		return -EINVAL;
-	}
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
 
 	memset(&db_cfg, 0, sizeof(db_cfg));
 	cparms.nitems = 1;
@@ -290,8 +284,11 @@ tf_em_int_bind(struct tf *tfp,
 		}
 
 		db_cfg.rm_db = (void *)&em_db->em_db[i];
-
-		rc = tf_rm_create_db(tfp, &db_cfg);
+		if (tf_session_is_shared_session(tfs) &&
+			(!tf_session_is_shared_session_creator(tfs)))
+			rc = tf_rm_create_db_no_reservation(tfp, &db_cfg);
+		else
+			rc = tf_rm_create_db(tfp, &db_cfg);
 		if (rc) {
 			TFP_DRV_LOG(ERR,
 				    "%s: EM Int DB creation failed\n",
@@ -299,34 +296,31 @@ tf_em_int_bind(struct tf *tfp,
 
 			return rc;
 		}
-		db_exists = 1;
 	}
 
-	if (db_exists)
-		init = 1;
-
-	for (i = 0; i < TF_DIR_MAX; i++) {
-		iparms.rm_db = em_db->em_db[i];
-		iparms.subtype = TF_EM_DB_EM_REC;
-		iparms.info = &info;
+	if (!tf_session_is_shared_session(tfs)) {
+		for (i = 0; i < TF_DIR_MAX; i++) {
+			iparms.rm_db = em_db->em_db[i];
+			iparms.subtype = TF_EM_DB_EM_REC;
+			iparms.info = &info;
+
+			rc = tf_rm_get_info(&iparms);
+			if (rc) {
+				TFP_DRV_LOG(ERR,
+					    "%s: EM DB get info failed\n",
+					    tf_dir_2_str(i));
+				return rc;
+			}
 
-		rc = tf_rm_get_info(&iparms);
-		if (rc) {
-			TFP_DRV_LOG(ERR,
-				    "%s: EM DB get info failed\n",
-				    tf_dir_2_str(i));
-			return rc;
+			rc = tf_create_em_pool(i,
+					       iparms.info->entry.stride,
+					       iparms.info->entry.start);
+			/* Logging handled in tf_create_em_pool */
+			if (rc)
+				return rc;
 		}
-
-		rc = tf_create_em_pool(i,
-				       iparms.info->entry.stride,
-				       iparms.info->entry.start);
-		/* Logging handled in tf_create_em_pool */
-		if (rc)
-			return rc;
 	}
 
-
 	return 0;
 }
 
@@ -338,18 +332,19 @@ tf_em_int_unbind(struct tf *tfp)
 	struct tf_rm_free_db_parms fparms = { 0 };
 	struct em_rm_db *em_db;
 	void *em_db_ptr = NULL;
+	struct tf_session *tfs;
 
 	TF_CHECK_PARMS1(tfp);
 
-	/* Bail if nothing has been initialized */
-	if (!init) {
-		TFP_DRV_LOG(INFO,
-			    "No EM Int DBs created\n");
-		return 0;
-	}
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
 
-	for (i = 0; i < TF_DIR_MAX; i++)
-		tf_free_em_pool(i);
+	if (!tf_session_is_shared_session(tfs)) {
+		for (i = 0; i < TF_DIR_MAX; i++)
+			tf_free_em_pool(i);
+	}
 
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
 	if (rc) {
@@ -372,7 +367,42 @@ tf_em_int_unbind(struct tf *tfp)
 		em_db->em_db[i] = NULL;
 	}
 
-	init = 0;
+	return 0;
+}
+
+int
+tf_em_get_resc_info(struct tf *tfp,
+		    struct tf_em_resource_info *em)
+{
+	int rc;
+	int d;
+	struct tf_resource_info *dinfo;
+	struct tf_rm_get_alloc_info_parms ainfo;
+	void *em_db_ptr = NULL;
+	struct em_rm_db *em_db;
+
+	TF_CHECK_PARMS2(tfp, em);
+
+	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to get em_ext_db from session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+	em_db = (struct em_rm_db *)em_db_ptr;
+
+	/* check if reserved resource for WC is multiple of num_slices */
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		ainfo.rm_db = em_db->em_db[d];
+		dinfo = em[d].info;
+
+		ainfo.info = (struct tf_rm_alloc_info *)dinfo;
+		ainfo.subtype = 0;
+		rc = tf_rm_get_all_info(&ainfo, TF_EM_TBL_TYPE_MAX);
+		if (rc && rc != -ENOTSUP)
+			return rc;
+	}
 
 	return 0;
 }
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c
index ee68b6ca58..4063f3ba17 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.c
+++ b/drivers/net/bnxt/tf_core/tf_identifier.c
@@ -15,11 +15,6 @@
 
 struct tf;
 
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
 /**
  * Identifier shadow DBs.
  */
@@ -41,14 +36,14 @@ tf_ident_bind(struct tf *tfp,
 	struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
 	struct ident_rm_db *ident_db;
 	struct tfp_calloc_parms cparms;
+	struct tf_session *tfs;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (init) {
-		TFP_DRV_LOG(ERR,
-			    "Identifier DB already initialized\n");
-		return -EINVAL;
-	}
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
 
 	memset(&db_cfg, 0, sizeof(db_cfg));
 	cparms.nitems = 1;
@@ -73,7 +68,11 @@ tf_ident_bind(struct tf *tfp,
 		db_cfg.rm_db = (void *)&ident_db->ident_db[i];
 		db_cfg.dir = i;
 		db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;
-		rc = tf_rm_create_db(tfp, &db_cfg);
+		if (tf_session_is_shared_session(tfs) &&
+			(!tf_session_is_shared_session_creator(tfs)))
+			rc = tf_rm_create_db_no_reservation(tfp, &db_cfg);
+		else
+			rc = tf_rm_create_db(tfp, &db_cfg);
 		if (rc) {
 			TFP_DRV_LOG(ERR,
 				    "%s: Identifier DB creation failed\n",
@@ -100,8 +99,6 @@ tf_ident_bind(struct tf *tfp,
 		}
 	}
 
-	init = 1;
-
 	TFP_DRV_LOG(INFO,
 		    "Identifier - initialized\n");
 
@@ -120,13 +117,6 @@ tf_ident_unbind(struct tf *tfp)
 
 	TF_CHECK_PARMS1(tfp);
 
-	/* Bail if nothing has been initialized */
-	if (!init) {
-		TFP_DRV_LOG(INFO,
-			    "No Identifier DBs created\n");
-		return 0;
-	}
-
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -158,7 +148,6 @@ tf_ident_unbind(struct tf *tfp)
 		ident_db->ident_db[i] = NULL;
 	}
 
-	init = 0;
 	shadow_init = 0;
 
 	return 0;
@@ -178,13 +167,6 @@ tf_ident_alloc(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Identifier DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -242,13 +224,6 @@ tf_ident_free(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Identifier DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -329,13 +304,6 @@ tf_ident_search(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Identifier DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	if (!shadow_init) {
 		TFP_DRV_LOG(ERR,
 			    "%s: Identifier Shadow copy is not enabled\n",
@@ -388,3 +356,40 @@ tf_ident_search(struct tf *tfp __rte_unused,
 
 	return 0;
 }
+
+int
+tf_ident_get_resc_info(struct tf *tfp,
+		       struct tf_identifier_resource_info *ident)
+{
+	int rc;
+	int d;
+	struct tf_resource_info *dinfo;
+	struct tf_rm_get_alloc_info_parms ainfo;
+	void *ident_db_ptr = NULL;
+	struct ident_rm_db *ident_db;
+
+	TF_CHECK_PARMS2(tfp, ident);
+
+	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to get ident_db from session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+	ident_db = (struct ident_rm_db *)ident_db_ptr;
+
+	/* check if reserved resource for WC is multiple of num_slices */
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		ainfo.rm_db = ident_db->ident_db[d];
+		dinfo = ident[d].info;
+
+		ainfo.info = (struct tf_rm_alloc_info *)dinfo;
+		ainfo.subtype = 0;
+		rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h
index 54cecbfd4c..55c093802e 100644
--- a/drivers/net/bnxt/tf_core/tf_identifier.h
+++ b/drivers/net/bnxt/tf_core/tf_identifier.h
@@ -201,4 +201,20 @@ int tf_ident_free(struct tf *tfp,
 int tf_ident_search(struct tf *tfp,
 		    struct tf_ident_search_parms *parms);
 
+/**
+ * Retrieves the allocated resource info
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_ident_get_resc_info(struct tf *tfp,
+			   struct tf_identifier_resource_info *parms);
+
 #endif /* _TF_IDENTIFIER_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c
index c6eb94bee0..4a840f3473 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.c
+++ b/drivers/net/bnxt/tf_core/tf_msg.c
@@ -114,11 +114,12 @@ tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)
 /* HWRM Direct messages */
 
 int
-tf_msg_session_open(struct tf *tfp,
+tf_msg_session_open(struct bnxt *bp,
 		    char *ctrl_chan_name,
 		    uint8_t *fw_session_id,
 		    uint8_t *fw_session_client_id,
-		    struct tf_dev_info *dev)
+		    struct tf_dev_info *dev,
+		    bool *shared_session_creator)
 {
 	int rc;
 	struct hwrm_tf_session_open_input req = { 0 };
@@ -135,7 +136,7 @@ tf_msg_session_open(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(bp,
 				 &parms);
 	if (rc)
 		return rc;
@@ -143,6 +144,8 @@ tf_msg_session_open(struct tf *tfp,
 	*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);
 	*fw_session_client_id =
 		(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);
+	*shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags
+		& HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR);
 
 	return rc;
 }
@@ -198,7 +201,7 @@ tf_msg_session_client_register(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -249,7 +252,7 @@ tf_msg_session_client_unregister(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 
 	return rc;
@@ -293,7 +296,7 @@ tf_msg_session_close(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -345,7 +348,7 @@ tf_msg_session_qcfg(struct tf *tfp)
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -367,6 +370,16 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
 	struct tf_msg_dma_buf qcaps_buf = { 0 };
 	struct tf_rm_resc_req_entry *data;
 	int dma_size;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
 
 	TF_CHECK_PARMS3(tfp, query, resv_strategy);
 
@@ -398,7 +411,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 	if (rc)
 		goto cleanup;
 
@@ -416,6 +429,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp,
 
 	/* Post process the response */
 	data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
+
 	for (i = 0; i < size; i++) {
 		query[i].type = tfp_le_to_cpu_32(data[i].type);
 		query[i].min = tfp_le_to_cpu_16(data[i].min);
@@ -450,6 +464,16 @@ tf_msg_session_resc_alloc(struct tf *tfp,
 	struct tf_rm_resc_req_entry *req_data;
 	struct tf_rm_resc_entry *resv_data;
 	int dma_size;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
 
 	TF_CHECK_PARMS3(tfp, request, resv);
 
@@ -497,7 +521,114 @@ tf_msg_session_resc_alloc(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
+	if (rc)
+		goto cleanup;
+
+	/* Process the response
+	 * Should always get expected number of entries
+	 */
+	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),
+			    strerror(EINVAL));
+		rc = -EINVAL;
+		goto cleanup;
+	}
+
+	/* 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_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);
+	}
+
+cleanup:
+	tf_msg_free_dma_buf(&req_buf);
+	tf_msg_free_dma_buf(&resv_buf);
+
+	return rc;
+}
+
+int
+tf_msg_session_resc_info(struct tf *tfp,
+			 struct tf_dev_info *dev,
+			 enum tf_dir dir,
+			 uint16_t size,
+			 struct tf_rm_resc_req_entry *request,
+			 struct tf_rm_resc_entry *resv)
+{
+	int rc;
+	int i;
+	struct tfp_send_msg_parms parms = { 0 };
+	struct hwrm_tf_session_resc_info_input req = { 0 };
+	struct hwrm_tf_session_resc_info_output resp = { 0 };
+	uint8_t fw_session_id;
+	struct tf_msg_dma_buf req_buf = { 0 };
+	struct tf_msg_dma_buf resv_buf = { 0 };
+	struct tf_rm_resc_req_entry *req_data;
+	struct tf_rm_resc_entry *resv_data;
+	int dma_size;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+
+	TF_CHECK_PARMS3(tfp, request, resv);
+
+	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "%s: Unable to lookup FW id, rc:%s\n",
+			    tf_dir_2_str(dir),
+			    strerror(-rc));
+		return rc;
+	}
+
+	/* Prepare DMA buffers */
+	dma_size = size * sizeof(struct tf_rm_resc_req_entry);
+	rc = tf_msg_alloc_dma_buf(&req_buf, dma_size);
+	if (rc)
+		return rc;
+
+	dma_size = size * sizeof(struct tf_rm_resc_entry);
+	rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);
+	if (rc) {
+		tf_msg_free_dma_buf(&req_buf);
+		return rc;
+	}
+
+	/* Populate the request */
+	req.fw_session_id = tfp_cpu_to_le_32(fw_session_id);
+	req.flags = tfp_cpu_to_le_16(dir);
+	req.req_size = size;
+
+	req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;
+	for (i = 0; i < size; i++) {
+		req_data[i].type = tfp_cpu_to_le_32(request[i].type);
+		req_data[i].min = tfp_cpu_to_le_16(request[i].min);
+		req_data[i].max = tfp_cpu_to_le_16(request[i].max);
+	}
+
+	req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);
+	req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);
+
+	parms.tf_type = HWRM_TF_SESSION_RESC_INFO;
+	parms.req_data = (uint32_t *)&req;
+	parms.req_size = sizeof(req);
+	parms.resp_data = (uint32_t *)&resp;
+	parms.resp_size = sizeof(resp);
+	parms.mailbox = dev->ops->tf_dev_get_mailbox();
+
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 	if (rc)
 		goto cleanup;
 
@@ -604,7 +735,7 @@ tf_msg_session_resc_flush(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 
 	tf_msg_free_dma_buf(&resv_buf);
 
@@ -698,7 +829,7 @@ tf_msg_insert_em_internal_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -793,7 +924,7 @@ tf_msg_hash_insert_em_internal_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -863,7 +994,7 @@ tf_msg_delete_em_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -919,7 +1050,7 @@ int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp,
 		parms.resp_data = (uint32_t *)&resp;
 		parms.resp_size = sizeof(resp);
 		parms.mailbox = dev->ops->tf_dev_get_mailbox();
-		rc = tfp_send_msg_direct(tfp, &parms);
+		rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 		if (rc) {
 			TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n",
 				strerror(-rc));
@@ -979,7 +1110,7 @@ int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp,
 	parms.resp_data = (uint32_t *)&resp;
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 
 	return rc;
 }
@@ -1030,7 +1161,7 @@ tf_msg_em_mem_rgtr(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -1082,7 +1213,7 @@ tf_msg_em_mem_unrgtr(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -1134,7 +1265,7 @@ tf_msg_em_qcaps(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -1209,7 +1340,7 @@ tf_msg_em_cfg(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -1283,7 +1414,7 @@ tf_msg_ext_em_cfg(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -1333,7 +1464,7 @@ tf_msg_em_op(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -1351,6 +1482,16 @@ tf_msg_tcam_entry_set(struct tf *tfp,
 	uint8_t *data = NULL;
 	int data_size = 0;
 	uint8_t fw_session_id;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
 
 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
 	if (rc) {
@@ -1401,7 +1542,7 @@ tf_msg_tcam_entry_set(struct tf *tfp,
 	mparms.resp_size = sizeof(resp);
 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &mparms);
 
 cleanup:
@@ -1420,6 +1561,16 @@ tf_msg_tcam_entry_get(struct tf *tfp,
 	struct hwrm_tf_tcam_get_input req = { 0 };
 	struct hwrm_tf_tcam_get_output resp = { 0 };
 	uint8_t fw_session_id;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
 
 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
 	if (rc) {
@@ -1444,7 +1595,7 @@ tf_msg_tcam_entry_get(struct tf *tfp,
 	mparms.resp_size = sizeof(resp);
 	mparms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &mparms);
 
 	if (rc != 0)
@@ -1480,6 +1631,16 @@ tf_msg_tcam_entry_free(struct tf *tfp,
 	struct hwrm_tf_tcam_free_output resp = { 0 };
 	struct tfp_send_msg_parms parms = { 0 };
 	uint8_t fw_session_id;
+	struct tf_session *tfs;
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to lookup session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
 
 	rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
 	if (rc) {
@@ -1505,7 +1666,7 @@ tf_msg_tcam_entry_free(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	return rc;
 }
@@ -1586,7 +1747,7 @@ tf_msg_set_tbl_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -1652,7 +1813,7 @@ tf_msg_get_tbl_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -1738,7 +1899,7 @@ tf_msg_get_global_cfg(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 	if (rc != 0)
 		return rc;
 
@@ -1839,7 +2000,7 @@ tf_msg_set_global_cfg(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 
 	if (rc != 0)
 		return rc;
@@ -1912,7 +2073,7 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp,
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs),
 				 &parms);
 	if (rc)
 		return rc;
@@ -1975,7 +2136,7 @@ tf_msg_get_if_tbl_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 
 	if (rc != 0)
 		return rc;
@@ -2032,7 +2193,7 @@ tf_msg_set_if_tbl_entry(struct tf *tfp,
 	parms.resp_size = sizeof(resp);
 	parms.mailbox = dev->ops->tf_dev_get_mailbox();
 
-	rc = tfp_send_msg_direct(tfp, &parms);
+	rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);
 
 	if (rc != 0)
 		return rc;
diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h
index 7b4a6a3d92..5ecaf9e7e7 100644
--- a/drivers/net/bnxt/tf_core/tf_msg.h
+++ b/drivers/net/bnxt/tf_core/tf_msg.h
@@ -14,6 +14,7 @@
 #include "tf_rm.h"
 #include "tf_tcam.h"
 #include "tf_global_cfg.h"
+#include "bnxt.h"
 
 struct tf;
 
@@ -22,8 +23,8 @@ struct tf;
 /**
  * Sends session open request to Firmware
  *
- * [in] session
- *   Pointer to session handle
+ * [in] bp
+ *   Pointer to bnxt handle
  *
  * [in] ctrl_chan_name
  *   PCI name of the control channel
@@ -31,14 +32,24 @@ struct tf;
  * [in/out] fw_session_id
  *   Pointer to the fw_session_id that is allocated on firmware side
  *
+ * [in/out] fw_session_client_id
+ *   Pointer to the fw_session_client_id that is allocated on firmware side
+ *
+ * [in/out] dev
+ *   Pointer to the associated device
+ *
+ * [out] shared_session_creator
+ *   Pointer to the shared_session_creator
+ *
  * Returns:
  *   0 on Success else internal Truflow error
  */
-int tf_msg_session_open(struct tf *tfp,
+int tf_msg_session_open(struct bnxt *bp,
 			char *ctrl_chan_name,
 			uint8_t *fw_session_id,
 			uint8_t *fw_session_client_id,
-			struct tf_dev_info *dev);
+			struct tf_dev_info *dev,
+			bool *shared_session_creator);
 
 /**
  * Sends session close request to Firmware
@@ -178,6 +189,34 @@ int tf_msg_session_resc_alloc(struct tf *tfp,
 			      struct tf_rm_resc_req_entry *request,
 			      struct tf_rm_resc_entry *resv);
 
+/**
+ * Sends session HW resource allocation 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] req
+ *   Pointer to an array of request elements
+ *
+ * [in] resv
+ *   Pointer to an array of reserved elements
+ *
+ * Returns:
+ *   0 on Success else internal Truflow error
+ */
+int tf_msg_session_resc_info(struct tf *tfp,
+			      struct tf_dev_info *dev,
+			      enum tf_dir dir,
+			      uint16_t size,
+			      struct tf_rm_resc_req_entry *request,
+			      struct tf_rm_resc_entry *resv);
+
 /**
  * Sends session resource flush request to TF Firmware
  *
diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c
index 50f6b1eeab..f44b5b1ab6 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.c
+++ b/drivers/net/bnxt/tf_core/tf_rm.c
@@ -702,7 +702,9 @@ tf_rm_create_db(struct tf *tfp,
 				}
 				db[i].pool = (struct bitalloc *)cparms.mem_va;
 
-				rc = ba_init(db[i].pool, resv[j].stride);
+				rc = ba_init(db[i].pool,
+					     resv[j].stride,
+					     !tf_session_is_shared_session(tfs));
 				if (rc) {
 					TFP_DRV_LOG(ERR,
 					  "%s: Pool init failed, type:%d:%s\n",
@@ -746,6 +748,249 @@ tf_rm_create_db(struct tf *tfp,
 	return -EINVAL;
 }
 
+int
+tf_rm_create_db_no_reservation(struct tf *tfp,
+			       struct tf_rm_create_db_parms *parms)
+{
+	int rc;
+	struct tf_session *tfs;
+	struct tf_dev_info *dev;
+	int i, j;
+	uint16_t hcapi_items, *req_cnt;
+	struct tfp_calloc_parms cparms;
+	struct tf_rm_resc_req_entry *req;
+	struct tf_rm_resc_entry *resv;
+	struct tf_rm_new_db *rm_db;
+	struct tf_rm_element *db;
+	uint32_t pool_size;
+
+	TF_CHECK_PARMS2(tfp, parms);
+
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
+
+	/* Retrieve device information */
+	rc = tf_session_get_device(tfs, &dev);
+	if (rc)
+		return rc;
+
+	/* Copy requested counts (alloc_cnt) from tf_open_session() to local
+	 * copy (req_cnt) so that it can be updated if required.
+	 */
+
+	cparms.nitems = parms->num_elements;
+	cparms.size = sizeof(uint16_t);
+	cparms.alignment = 0;
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+
+	req_cnt = (uint16_t *)cparms.mem_va;
+
+	tfp_memcpy(req_cnt, parms->alloc_cnt,
+		   parms->num_elements * sizeof(uint16_t));
+
+	/* Process capabilities against DB requirements. However, as a
+	 * DB can hold elements that are not HCAPI we can reduce the
+	 * req msg content by removing those out of the request yet
+	 * 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->dir,
+				       parms->module,
+				       parms->cfg,
+				       req_cnt,
+				       parms->num_elements,
+				       &hcapi_items);
+
+	if (hcapi_items == 0) {
+		TFP_DRV_LOG(ERR,
+			"%s: module:%s Empty RM DB create request\n",
+			tf_dir_2_str(parms->dir),
+			tf_module_2_str(parms->module));
+
+		parms->rm_db = NULL;
+		return -ENOMEM;
+	}
+
+	/* Alloc request, alignment already set */
+	cparms.nitems = (size_t)hcapi_items;
+	cparms.size = sizeof(struct tf_rm_resc_req_entry);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	req = (struct tf_rm_resc_req_entry *)cparms.mem_va;
+
+	/* Alloc reservation, alignment and nitems already set */
+	cparms.size = sizeof(struct tf_rm_resc_entry);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	resv = (struct tf_rm_resc_entry *)cparms.mem_va;
+
+	/* Build the request */
+	for (i = 0, j = 0; i < parms->num_elements; i++) {
+		struct tf_rm_element_cfg *cfg = &parms->cfg[i];
+		uint16_t hcapi_type = cfg->hcapi_type;
+
+		/* Only perform reservation for requested entries
+		 */
+		if (req_cnt[i] == 0)
+			continue;
+
+		/* Skip any children in the request */
+		if (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI ||
+		    cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA ||
+		    cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_PARENT) {
+			req[j].type = hcapi_type;
+			req[j].min = req_cnt[i];
+			req[j].max = req_cnt[i];
+			j++;
+		}
+	}
+
+	/* Get all resources info for the module type
+	 */
+	rc = tf_msg_session_resc_info(tfp,
+				      dev,
+				      parms->dir,
+				      hcapi_items,
+				      req,
+				      resv);
+	if (rc)
+		return rc;
+
+	/* Build the RM DB per the request */
+	cparms.nitems = 1;
+	cparms.size = sizeof(struct tf_rm_new_db);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	rm_db = (void *)cparms.mem_va;
+
+	/* Build the DB within RM DB */
+	cparms.nitems = parms->num_elements;
+	cparms.size = sizeof(struct tf_rm_element);
+	rc = tfp_calloc(&cparms);
+	if (rc)
+		return rc;
+	rm_db->db = (struct tf_rm_element *)cparms.mem_va;
+
+	db = rm_db->db;
+	for (i = 0, j = 0; i < parms->num_elements; i++) {
+		struct tf_rm_element_cfg *cfg = &parms->cfg[i];
+		const char *type_str;
+
+		dev->ops->tf_dev_get_resource_str(tfp,
+						  cfg->hcapi_type,
+						  &type_str);
+
+		db[i].cfg_type = cfg->cfg_type;
+		db[i].hcapi_type = cfg->hcapi_type;
+
+		/* Save the parent subtype for later use to find the pool
+		 */
+		if (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD)
+			db[i].parent_subtype = cfg->parent_subtype;
+
+		/* If the element didn't request an allocation no need
+		 * to create a pool nor verify if we got a reservation.
+		 */
+		if (req_cnt[i] == 0)
+			continue;
+
+		/* Skip any children or invalid
+		 */
+		if (cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI &&
+		    cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI_BA &&
+		    cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI_BA_PARENT)
+			continue;
+
+		/* If the element had requested an allocation and that
+		 * allocation was a success (full amount) then
+		 * allocate the pool.
+		 */
+		if (req_cnt[i] == resv[j].stride) {
+			db[i].alloc.entry.start = resv[j].start;
+			db[i].alloc.entry.stride = resv[j].stride;
+
+			/* Only allocate BA pool if a BA type not a child */
+			if (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA ||
+			    cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_PARENT) {
+				if (cfg->divider) {
+					resv[j].stride =
+						resv[j].stride / cfg->divider;
+					if (resv[j].stride <= 0) {
+						TFP_DRV_LOG(ERR,
+						     "%s:Divide fails:%d:%s\n",
+						     tf_dir_2_str(parms->dir),
+						     cfg->hcapi_type, type_str);
+						goto fail;
+					}
+				}
+				/* Create pool */
+				pool_size = (BITALLOC_SIZEOF(resv[j].stride) /
+					     sizeof(struct bitalloc));
+				/* Alloc request, alignment already set */
+				cparms.nitems = pool_size;
+				cparms.size = sizeof(struct bitalloc);
+				rc = tfp_calloc(&cparms);
+				if (rc) {
+					TFP_DRV_LOG(ERR,
+					 "%s: Pool alloc failed, type:%d:%s\n",
+					 tf_dir_2_str(parms->dir),
+					 cfg->hcapi_type, type_str);
+					goto fail;
+				}
+				db[i].pool = (struct bitalloc *)cparms.mem_va;
+
+				rc = ba_init(db[i].pool,
+					     resv[j].stride,
+					     !tf_session_is_shared_session(tfs));
+				if (rc) {
+					TFP_DRV_LOG(ERR,
+					  "%s: Pool init failed, type:%d:%s\n",
+					  tf_dir_2_str(parms->dir),
+					  cfg->hcapi_type, type_str);
+					goto fail;
+				}
+			}
+			j++;
+		} else {
+			/* Bail out as we want what we requested for
+			 * all elements, not any less.
+			 */
+			TFP_DRV_LOG(ERR,
+				    "%s: Alloc failed %d:%s req:%d, alloc:%d\n",
+				    tf_dir_2_str(parms->dir), cfg->hcapi_type,
+				    type_str, req_cnt[i], resv[j].stride);
+			goto fail;
+		}
+	}
+
+	rm_db->num_entries = parms->num_elements;
+	rm_db->dir = parms->dir;
+	rm_db->module = parms->module;
+	*parms->rm_db = (void *)rm_db;
+
+	tfp_free((void *)req);
+	tfp_free((void *)resv);
+	tfp_free((void *)req_cnt);
+	return 0;
+
+ fail:
+	tfp_free((void *)req);
+	tfp_free((void *)resv);
+	tfp_free((void *)db->pool);
+	tfp_free((void *)db);
+	tfp_free((void *)rm_db);
+	tfp_free((void *)req_cnt);
+	parms->rm_db = NULL;
+
+	return -EINVAL;
+}
 int
 tf_rm_free_db(struct tf *tfp,
 	      struct tf_rm_free_db_parms *parms)
@@ -1043,6 +1288,36 @@ tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms)
 	return 0;
 }
 
+int
+tf_rm_get_all_info(struct tf_rm_get_alloc_info_parms *parms, int size)
+{
+	struct tf_rm_new_db *rm_db;
+	enum tf_rm_elem_cfg_type cfg_type;
+	struct tf_rm_alloc_info *info = parms->info;
+	int i;
+
+	TF_CHECK_PARMS2(parms, parms->rm_db);
+	rm_db = (struct tf_rm_new_db *)parms->rm_db;
+	TF_CHECK_PARMS1(rm_db->db);
+
+	for (i = 0; i < size; i++) {
+		cfg_type = rm_db->db[i].cfg_type;
+
+		/* Bail out if not controlled by HCAPI */
+		if (cfg_type == TF_RM_ELEM_CFG_NULL) {
+			info++;
+			continue;
+		}
+
+		memcpy(info,
+		       &rm_db->db[i].alloc,
+		       sizeof(struct tf_rm_alloc_info));
+		info++;
+	}
+
+	return 0;
+}
+
 int
 tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms)
 {
diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h
index 6eb6865dac..8b984112e8 100644
--- a/drivers/net/bnxt/tf_core/tf_rm.h
+++ b/drivers/net/bnxt/tf_core/tf_rm.h
@@ -425,6 +425,24 @@ struct tf_rm_check_indexes_in_range_parms {
 int tf_rm_create_db(struct tf *tfp,
 		    struct tf_rm_create_db_parms *parms);
 
+/**
+ * Creates and fills a Resource Manager (RM) DB with requested
+ * elements. The DB is indexed per the parms structure. It only retrieve
+ * allocated resource information for a exist session.
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to create parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_rm_create_db_no_reservation(struct tf *tfp,
+		    struct tf_rm_create_db_parms *parms);
+
 /**
  * Closes the Resource Manager (RM) DB and frees all allocated
  * resources per the associated database.
@@ -498,6 +516,22 @@ int tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms);
  */
 int tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms);
 
+/**
+ * Retrieves all elements allocation information from the Resource
+ * Manager (RM) DB.
+ *
+ * [in] parms
+ *   Pointer to get info parameters
+ *
+ * [in] size
+ *   number of the elements for the specific module
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_rm_get_all_info(struct tf_rm_get_alloc_info_parms *parms, int size);
+
 /**
  * Performs a lookup in the Resource Manager DB and retrieves the
  * requested HCAPI RM type.
diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c
index f591fbe3f5..391d8786ab 100644
--- a/drivers/net/bnxt/tf_core/tf_session.c
+++ b/drivers/net/bnxt/tf_core/tf_session.c
@@ -11,6 +11,7 @@
 #include "tf_common.h"
 #include "tf_msg.h"
 #include "tfp.h"
+#include "bnxt.h"
 
 struct tf_session_client_create_parms {
 	/**
@@ -57,6 +58,7 @@ tf_session_create(struct tf *tfp,
 	uint8_t fw_session_client_id;
 	union tf_session_id *session_id;
 	struct tf_dev_info dev;
+	bool shared_session_creator;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
@@ -64,11 +66,12 @@ tf_session_create(struct tf *tfp,
 			&dev);
 
 	/* Open FW session and get a new session_id */
-	rc = tf_msg_session_open(tfp,
+	rc = tf_msg_session_open(parms->open_cfg->bp,
 				 parms->open_cfg->ctrl_chan_name,
 				 &fw_session_id,
 				 &fw_session_client_id,
-				 &dev);
+				 &dev,
+				 &shared_session_creator);
 	if (rc) {
 		/* Log error */
 		if (rc == -EEXIST)
@@ -137,6 +140,7 @@ tf_session_create(struct tf *tfp,
 	session_id->id = session->session_id.id;
 
 	session->shadow_copy = parms->open_cfg->shadow_copy;
+	session->bp = parms->open_cfg->bp;
 
 	/* Init session client list */
 	ll_init(&session->client_ll);
@@ -175,12 +179,20 @@ tf_session_create(struct tf *tfp,
 
 	/* Init session em_ext_db */
 	session->em_ext_db_handle = NULL;
+	if (!strcmp(parms->open_cfg->ctrl_chan_name, "tf_share"))
+		session->shared_session = true;
+
+	if (session->shared_session && shared_session_creator) {
+		session->shared_session_creator = true;
+		parms->open_cfg->shared_session_creator = true;
+	}
 
 	rc = tf_dev_bind(tfp,
 			 parms->open_cfg->device_type,
 			 session->shadow_copy,
 			 &parms->open_cfg->resources,
 			 &session->dev);
+
 	/* Logging handled by dev_bind */
 	if (rc)
 		goto cleanup;
@@ -857,16 +869,29 @@ tf_session_get_db(struct tf *tfp,
 
 	switch (type) {
 	case TF_MODULE_TYPE_IDENTIFIER:
-		*db_handle = tfs->id_db_handle;
+		if (tfs->id_db_handle)
+			*db_handle = tfs->id_db_handle;
+		else
+			rc = -EINVAL;
 		break;
 	case TF_MODULE_TYPE_TABLE:
-		*db_handle = tfs->tbl_db_handle;
+		if (tfs->tbl_db_handle)
+			*db_handle = tfs->tbl_db_handle;
+		else
+			rc = -EINVAL;
+
 		break;
 	case TF_MODULE_TYPE_TCAM:
-		*db_handle = tfs->tcam_db_handle;
+		if (tfs->tcam_db_handle)
+			*db_handle = tfs->tcam_db_handle;
+		else
+			rc = -EINVAL;
 		break;
 	case TF_MODULE_TYPE_EM:
-		*db_handle = tfs->em_db_handle;
+		if (tfs->em_db_handle)
+			*db_handle = tfs->em_db_handle;
+		else
+			rc = -EINVAL;
 		break;
 	default:
 		rc = -EINVAL;
diff --git a/drivers/net/bnxt/tf_core/tf_session.h b/drivers/net/bnxt/tf_core/tf_session.h
index e5c7a07daf..0b8f63c374 100644
--- a/drivers/net/bnxt/tf_core/tf_session.h
+++ b/drivers/net/bnxt/tf_core/tf_session.h
@@ -70,6 +70,23 @@ struct tf_session {
 	 */
 	union tf_session_id session_id;
 
+	/**
+	 * Boolean controlling the use and availability of shared session.
+	 * Shared session will allow the application to share resources
+	 * on the firmware side without having to allocate them on firmware.
+	 * Additional private session core_data will be allocated if this
+	 * boolean is set to 'true', default 'false'.
+	 *
+	 */
+	bool shared_session;
+
+	/**
+	 * This flag indicates the shared session on firmware side is created
+	 * by this session. Some privileges may be assigned to this session.
+	 *
+	 */
+	bool shared_session_creator;
+
 	/**
 	 * Boolean controlling the use and availability of shadow
 	 * copy. Shadow copy will allow the TruFlow Core to keep track
@@ -137,6 +154,11 @@ struct tf_session {
 	 * em db reference for the session
 	 */
 	void *em_db_handle;
+
+	/**
+	 * the pointer to the parent bp struct
+	 */
+	void *bp;
 };
 
 /**
@@ -500,4 +522,48 @@ int
 tf_session_set_db(struct tf *tfp,
 		   enum tf_module_type type,
 		  void *db_handle);
+
+/**
+ * Check if the session is shared session.
+ *
+ * [in] session, pointer to the session
+ *
+ * Returns:
+ *   - true if it is shared session
+ *   - false if it is not shared session
+ */
+static inline bool
+tf_session_is_shared_session(struct tf_session *tfs)
+{
+	return tfs->shared_session;
+}
+
+/**
+ * Check if the session is the shared session creator
+ *
+ * [in] session, pointer to the session
+ *
+ * Returns:
+ *   - true if it is the shared session creator
+ *   - false if it is not the shared session creator
+ */
+static inline bool
+tf_session_is_shared_session_creator(struct tf_session *tfs)
+{
+	return tfs->shared_session_creator;
+}
+
+/**
+ * Get the pointer to the parent bnxt struct
+ *
+ * [in] session, pointer to the session
+ *
+ * Returns:
+ *   - the pointer to the parent bnxt struct
+ */
+static inline struct bnxt*
+tf_session_get_bp(struct tf_session *tfs)
+{
+	return tfs->bp;
+}
 #endif /* _TF_SESSION_H_ */
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c
index 2d0dda18c9..17fb550917 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.c
+++ b/drivers/net/bnxt/tf_core/tf_tbl.c
@@ -31,11 +31,6 @@ struct tf;
  */
 static void *shadow_tbl_db[TF_DIR_MAX];
 
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
 /**
  * Shadow init flag, set on bind and cleared on unbind
  */
@@ -49,14 +44,14 @@ tf_tbl_bind(struct tf *tfp,
 	struct tf_rm_create_db_parms db_cfg = { 0 };
 	struct tbl_rm_db *tbl_db;
 	struct tfp_calloc_parms cparms;
+	struct tf_session *tfs;
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (init) {
-		TFP_DRV_LOG(ERR,
-			    "Table DB already initialized\n");
-		return -EINVAL;
-	}
+	/* Retrieve the session information */
+	rc = tf_session_get_session_internal(tfp, &tfs);
+	if (rc)
+		return rc;
 
 	memset(&db_cfg, 0, sizeof(db_cfg));
 	cparms.nitems = 1;
@@ -82,8 +77,11 @@ tf_tbl_bind(struct tf *tfp,
 		db_cfg.dir = d;
 		db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;
 		db_cfg.rm_db = (void *)&tbl_db->tbl_db[d];
-
-		rc = tf_rm_create_db(tfp, &db_cfg);
+		if (tf_session_is_shared_session(tfs) &&
+			(!tf_session_is_shared_session_creator(tfs)))
+			rc = tf_rm_create_db_no_reservation(tfp, &db_cfg);
+		else
+			rc = tf_rm_create_db(tfp, &db_cfg);
 		if (rc) {
 			TFP_DRV_LOG(ERR,
 				    "%s: Table DB creation failed\n",
@@ -92,7 +90,6 @@ tf_tbl_bind(struct tf *tfp,
 			return rc;
 		}
 	}
-	init = 1;
 
 	TFP_DRV_LOG(INFO,
 		    "Table Type - initialized\n");
@@ -110,13 +107,6 @@ tf_tbl_unbind(struct tf *tfp)
 	void *tbl_db_ptr = NULL;
 	TF_CHECK_PARMS1(tfp);
 
-	/* Bail if nothing has been initialized */
-	if (!init) {
-		TFP_DRV_LOG(INFO,
-			    "No Table DBs created\n");
-		return 0;
-	}
-
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -136,7 +126,6 @@ tf_tbl_unbind(struct tf *tfp)
 		tbl_db->tbl_db[i] = NULL;
 	}
 
-	init = 0;
 	shadow_init = 0;
 
 	return 0;
@@ -157,13 +146,6 @@ tf_tbl_alloc(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -234,12 +216,6 @@ tf_tbl_free(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -346,13 +322,6 @@ tf_tbl_set(struct tf *tfp,
 
 	TF_CHECK_PARMS3(tfp, parms, parms->data);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -456,14 +425,6 @@ tf_tbl_get(struct tf *tfp,
 
 	TF_CHECK_PARMS3(tfp, parms, parms->data);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -567,14 +528,6 @@ tf_tbl_bulk_get(struct tf *tfp,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No Table DBs created\n",
-			    tf_dir_2_str(parms->dir));
-
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -662,3 +615,40 @@ tf_tbl_bulk_get(struct tf *tfp,
 
 	return rc;
 }
+
+int
+tf_tbl_get_resc_info(struct tf *tfp,
+		     struct tf_tbl_resource_info *tbl)
+{
+	int rc;
+	int d;
+	struct tf_resource_info *dinfo;
+	struct tf_rm_get_alloc_info_parms ainfo;
+	void *tbl_db_ptr = NULL;
+	struct tbl_rm_db *tbl_db;
+
+	TF_CHECK_PARMS2(tfp, tbl);
+
+	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to get em_ext_db from session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+	tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
+
+	/* check if reserved resource for WC is multiple of num_slices */
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		ainfo.rm_db = tbl_db->tbl_db[d];
+		dinfo = tbl[d].info;
+
+		ainfo.info = (struct tf_rm_alloc_info *)dinfo;
+		ainfo.subtype = 0;
+		rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_tbl.h b/drivers/net/bnxt/tf_core/tf_tbl.h
index 83b72d1b3f..aba46fd161 100644
--- a/drivers/net/bnxt/tf_core/tf_tbl.h
+++ b/drivers/net/bnxt/tf_core/tf_tbl.h
@@ -396,4 +396,21 @@ int tf_tbl_get(struct tf *tfp,
 int tf_tbl_bulk_get(struct tf *tfp,
 		    struct tf_tbl_get_bulk_parms *parms);
 
+/**
+ * Retrieves the allocated resource info
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to Table resource info parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int
+tf_tbl_get_resc_info(struct tf *tfp,
+		     struct tf_tbl_resource_info *tbl);
+
 #endif /* TF_TBL_TYPE_H */
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c
index c2eef26dbb..70dc539f15 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.c
+++ b/drivers/net/bnxt/tf_core/tf_tcam.c
@@ -23,11 +23,6 @@ struct tf;
  */
 static void *shadow_tcam_db[TF_DIR_MAX];
 
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
 /**
  * Shadow init flag, set on bind and cleared on unbind
  */
@@ -55,12 +50,6 @@ tf_tcam_bind(struct tf *tfp,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (init) {
-		TFP_DRV_LOG(ERR,
-			    "TCAM DB already initialized\n");
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -118,7 +107,11 @@ tf_tcam_bind(struct tf *tfp,
 		db_cfg.dir = d;
 		db_cfg.alloc_cnt = parms->resources->tcam_cnt[d].cnt;
 		db_cfg.rm_db = (void *)&tcam_db->tcam_db[d];
-		rc = tf_rm_create_db(tfp, &db_cfg);
+		if (tf_session_is_shared_session(tfs) &&
+			(!tf_session_is_shared_session_creator(tfs)))
+			rc = tf_rm_create_db_no_reservation(tfp, &db_cfg);
+		else
+			rc = tf_rm_create_db(tfp, &db_cfg);
 		if (rc) {
 			TFP_DRV_LOG(ERR,
 				    "%s: TCAM DB creation failed\n",
@@ -143,7 +136,8 @@ tf_tcam_bind(struct tf *tfp,
 				    "%s: TCAM reserved resource is not multiple of %d\n",
 				    tf_dir_2_str(d),
 				    num_slices);
-			return -EINVAL;
+			rc = -EINVAL;
+			goto error;
 		}
 	}
 
@@ -186,8 +180,6 @@ tf_tcam_bind(struct tf *tfp,
 		shadow_init = 1;
 	}
 
-	init = 1;
-
 	TFP_DRV_LOG(INFO,
 		    "TCAM - initialized\n");
 
@@ -211,7 +203,6 @@ tf_tcam_bind(struct tf *tfp,
 	}
 
 	shadow_init = 0;
-	init = 0;
 
 	return rc;
 }
@@ -227,13 +218,6 @@ tf_tcam_unbind(struct tf *tfp)
 	struct tf_shadow_tcam_free_db_parms fshadow;
 	TF_CHECK_PARMS1(tfp);
 
-	/* Bail if nothing has been initialized */
-	if (!init) {
-		TFP_DRV_LOG(INFO,
-			    "No TCAM DBs created\n");
-		return 0;
-	}
-
 	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
 	if (rc) {
 		TFP_DRV_LOG(ERR,
@@ -263,7 +247,6 @@ tf_tcam_unbind(struct tf *tfp)
 	}
 
 	shadow_init = 0;
-	init = 0;
 
 	return 0;
 }
@@ -283,13 +266,6 @@ tf_tcam_alloc(struct tf *tfp,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No TCAM DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -372,13 +348,6 @@ tf_tcam_free(struct tf *tfp,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No TCAM DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -529,13 +498,6 @@ tf_tcam_alloc_search(struct tf *tfp,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No TCAM DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	if (!shadow_init || !shadow_tcam_db[parms->dir]) {
 		TFP_DRV_LOG(ERR, "%s: TCAM Shadow not initialized for %s\n",
 			    tf_dir_2_str(parms->dir),
@@ -660,13 +622,6 @@ tf_tcam_set(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No TCAM DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -781,13 +736,6 @@ tf_tcam_get(struct tf *tfp __rte_unused,
 
 	TF_CHECK_PARMS2(tfp, parms);
 
-	if (!init) {
-		TFP_DRV_LOG(ERR,
-			    "%s: No TCAM DBs created\n",
-			    tf_dir_2_str(parms->dir));
-		return -EINVAL;
-	}
-
 	/* Retrieve the session information */
 	rc = tf_session_get_session_internal(tfp, &tfs);
 	if (rc)
@@ -852,3 +800,40 @@ tf_tcam_get(struct tf *tfp __rte_unused,
 
 	return 0;
 }
+
+int
+tf_tcam_get_resc_info(struct tf *tfp,
+		      struct tf_tcam_resource_info *tcam)
+{
+	int rc;
+	int d;
+	struct tf_resource_info *dinfo;
+	struct tf_rm_get_alloc_info_parms ainfo;
+	void *tcam_db_ptr = NULL;
+	struct tcam_rm_db *tcam_db;
+
+	TF_CHECK_PARMS2(tfp, tcam);
+
+	rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
+	if (rc) {
+		TFP_DRV_LOG(ERR,
+			    "Failed to get em_ext_db from session, rc:%s\n",
+			    strerror(-rc));
+		return rc;
+	}
+	tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
+
+	/* check if reserved resource for WC is multiple of num_slices */
+	for (d = 0; d < TF_DIR_MAX; d++) {
+		ainfo.rm_db = tcam_db->tcam_db[d];
+		dinfo = tcam[d].info;
+
+		ainfo.info = (struct tf_rm_alloc_info *)dinfo;
+		ainfo.subtype = 0;
+		rc = tf_rm_get_all_info(&ainfo, TF_TCAM_TBL_TYPE_MAX);
+		if (rc && rc != -ENOTSUP)
+			return rc;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h
index acab223532..bed17af6ae 100644
--- a/drivers/net/bnxt/tf_core/tf_tcam.h
+++ b/drivers/net/bnxt/tf_core/tf_tcam.h
@@ -386,4 +386,20 @@ int tf_tcam_set(struct tf *tfp,
 int tf_tcam_get(struct tf *tfp,
 		struct tf_tcam_get_parms *parms);
 
+/**
+ * Retrieves the allocated resource info
+ *
+ * [in] tfp
+ *   Pointer to TF handle, used for HCAPI communication
+ *
+ * [in] parms
+ *   Pointer to parameters
+ *
+ * Returns
+ *   - (0) if successful.
+ *   - (-EINVAL) on failure.
+ */
+int tf_tcam_get_resc_info(struct tf *tfp,
+			  struct tf_tcam_resource_info *parms);
+
 #endif /* _TF_TCAM_H */
diff --git a/drivers/net/bnxt/tf_core/tfp.c b/drivers/net/bnxt/tf_core/tfp.c
index 37c49b587d..4d9b37f749 100644
--- a/drivers/net/bnxt/tf_core/tfp.c
+++ b/drivers/net/bnxt/tf_core/tfp.c
@@ -28,7 +28,7 @@
  * Returns success or failure code.
  */
 int
-tfp_send_msg_direct(struct tf *tfp,
+tfp_send_msg_direct(struct bnxt *bp,
 		    struct tfp_send_msg_parms *parms)
 {
 	int      rc = 0;
@@ -40,9 +40,7 @@ tfp_send_msg_direct(struct tf *tfp,
 	if (parms->mailbox == TF_CHIMP_MB)
 		use_kong_mb = 0;
 
-	rc = bnxt_hwrm_tf_message_direct(container_of(tfp,
-					       struct bnxt,
-					       tfp),
+	rc = bnxt_hwrm_tf_message_direct(bp,
 					 use_kong_mb,
 					 parms->tf_type,
 					 parms->req_data,
diff --git a/drivers/net/bnxt/tf_core/tfp.h b/drivers/net/bnxt/tf_core/tfp.h
index bcc56b0a54..58f34bbcab 100644
--- a/drivers/net/bnxt/tf_core/tfp.h
+++ b/drivers/net/bnxt/tf_core/tfp.h
@@ -15,6 +15,7 @@
 #include <rte_spinlock.h>
 #include <rte_log.h>
 #include <rte_byteorder.h>
+#include <bnxt.h>
 
 /**
  * DPDK/Driver specific log level for the BNXT Eth driver.
@@ -130,7 +131,7 @@ struct tfp_calloc_parms {
  *   -1             - Global error like not supported
  *   -EINVAL        - Parameter Error
  */
-int tfp_send_msg_direct(struct tf *tfp,
+int tfp_send_msg_direct(struct bnxt *bp,
 			struct tfp_send_msg_parms *parms);
 
 /**
