get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/93563/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 93563,
    "url": "http://patches.dpdk.org/api/patches/93563/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210530085929.29695-15-venkatkumar.duvvuru@broadcom.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210530085929.29695-15-venkatkumar.duvvuru@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210530085929.29695-15-venkatkumar.duvvuru@broadcom.com",
    "date": "2021-05-30T08:58:45",
    "name": "[14/58] net/bnxt: add shared session support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "c88327b0a7c589262da00257bdbf92a90a0a03bf",
    "submitter": {
        "id": 1635,
        "url": "http://patches.dpdk.org/api/people/1635/?format=api",
        "name": "Venkat Duvvuru",
        "email": "venkatkumar.duvvuru@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "http://patches.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210530085929.29695-15-venkatkumar.duvvuru@broadcom.com/mbox/",
    "series": [
        {
            "id": 17161,
            "url": "http://patches.dpdk.org/api/series/17161/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=17161",
            "date": "2021-05-30T08:58:31",
            "name": "enhancements to host based flow table management",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/17161/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/93563/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/93563/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 4D71AA0524;\n\tSun, 30 May 2021 11:02:38 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id CFAFD41162;\n\tSun, 30 May 2021 11:00:52 +0200 (CEST)",
            "from relay.smtp-ext.broadcom.com (saphodev.broadcom.com\n [192.19.11.229]) by mails.dpdk.org (Postfix) with ESMTP id 791BF4115B\n for <dev@dpdk.org>; Sun, 30 May 2021 11:00:50 +0200 (CEST)",
            "from S60.dhcp.broadcom.net (unknown [10.123.66.170])\n (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n (No client certificate requested)\n by relay.smtp-ext.broadcom.com (Postfix) with ESMTPS id D61287DC2;\n Sun, 30 May 2021 02:00:48 -0700 (PDT)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 relay.smtp-ext.broadcom.com D61287DC2",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com;\n s=dkimrelay; t=1622365250;\n bh=wMtnh9gRE505tqsMk1uaLGUYRKoHNRqY5pJN4tdcnsY=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=sDvRgGlSn4DPyh8PwirB4gkR2pOEPIwPO5gq1PIeF6bMhcYvj1YpEqmPzg0ku7bsd\n KJSipEh0YsEJ6dhwHXmJvcik4ZjmVQp61FxONGSR3/Lbx1QHr7vfoAx6ybjwNzAHLC\n zbzIrlxVrYPv/qPKCbKMlIYZ9829jArdCh85imfA=",
        "From": "Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "Jay Ding <jay.ding@broadcom.com>,\n Randy Schacher <stuart.schacher@broadcom.com>,\n Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>",
        "Date": "Sun, 30 May 2021 14:28:45 +0530",
        "Message-Id": "<20210530085929.29695-15-venkatkumar.duvvuru@broadcom.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20210530085929.29695-1-venkatkumar.duvvuru@broadcom.com>",
        "References": "<20210530085929.29695-1-venkatkumar.duvvuru@broadcom.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 14/58] net/bnxt: add shared session support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Jay Ding <jay.ding@broadcom.com>\n\nThere are 2 types of sessions - shared and non-shared.  For non-shared\nall the allocated resources are owned and managed by a single\nsession instance. No other applications have access to the\nresources owned by the non-shared session.  For a shared session,\nresources are shared between 2 applications.\n\nThe FW shared session can only be created by one application and\nshared by other apps. The host session that creates the FW shared\nsession is the creator.\n\nApplications can retrieve the reserved resources through a new API\ntf_get_session_resc_info.\n\nEach module supports two sessions, one is shared session, the other\nis non-shared session.\n\nSigned-off-by: Jay Ding <jay.ding@broadcom.com>\nSigned-off-by: Randy Schacher <stuart.schacher@broadcom.com>\nSigned-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>\nReviewed-by: Farah Smith <farah.smith@broadcom.com>\n---\n drivers/net/bnxt/hsi_struct_def_dpdk.h    | 281 +++++++++++++++++-----\n drivers/net/bnxt/tf_core/bitalloc.c       |  10 +-\n drivers/net/bnxt/tf_core/bitalloc.h       |   3 +-\n drivers/net/bnxt/tf_core/tf_core.c        | 105 ++++++++\n drivers/net/bnxt/tf_core/tf_core.h        | 177 +++++++++++++-\n drivers/net/bnxt/tf_core/tf_device.c      |  76 +++---\n drivers/net/bnxt/tf_core/tf_device.h      |  73 ++++++\n drivers/net/bnxt/tf_core/tf_device_p4.c   |   8 +\n drivers/net/bnxt/tf_core/tf_device_p58.c  |   8 +\n drivers/net/bnxt/tf_core/tf_em.h          |  17 ++\n drivers/net/bnxt/tf_core/tf_em_common.c   |  25 --\n drivers/net/bnxt/tf_core/tf_em_internal.c | 118 +++++----\n drivers/net/bnxt/tf_core/tf_identifier.c  |  89 +++----\n drivers/net/bnxt/tf_core/tf_identifier.h  |  16 ++\n drivers/net/bnxt/tf_core/tf_msg.c         | 223 ++++++++++++++---\n drivers/net/bnxt/tf_core/tf_msg.h         |  47 +++-\n drivers/net/bnxt/tf_core/tf_rm.c          | 277 ++++++++++++++++++++-\n drivers/net/bnxt/tf_core/tf_rm.h          |  34 +++\n drivers/net/bnxt/tf_core/tf_session.c     |  37 ++-\n drivers/net/bnxt/tf_core/tf_session.h     |  66 +++++\n drivers/net/bnxt/tf_core/tf_tbl.c         | 104 ++++----\n drivers/net/bnxt/tf_core/tf_tbl.h         |  17 ++\n drivers/net/bnxt/tf_core/tf_tcam.c        | 103 ++++----\n drivers/net/bnxt/tf_core/tf_tcam.h        |  16 ++\n drivers/net/bnxt/tf_core/tfp.c            |   6 +-\n drivers/net/bnxt/tf_core/tfp.h            |   3 +-\n 26 files changed, 1560 insertions(+), 379 deletions(-)",
    "diff": "diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h\nindex aea9305486..046acb8de2 100644\n--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h\n+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h\n@@ -699,6 +699,8 @@ struct cmd_nums {\n \t/* Experimental */\n \t#define HWRM_TF_SESSION_RESC_FLUSH                UINT32_C(0x2cf)\n \t/* Experimental */\n+\t#define HWRM_TF_SESSION_RESC_INFO                 UINT32_C(0x2d0)\n+\t/* Experimental */\n \t#define HWRM_TF_TBL_TYPE_GET                      UINT32_C(0x2da)\n \t/* Experimental */\n \t#define HWRM_TF_TBL_TYPE_SET                      UINT32_C(0x2db)\n@@ -727,6 +729,8 @@ struct cmd_nums {\n \t/* Experimental */\n \t#define HWRM_TF_EM_HASH_INSERT                    UINT32_C(0x2ec)\n \t/* Experimental */\n+\t#define HWRM_TF_EM_MOVE                           UINT32_C(0x2ed)\n+\t/* Experimental */\n \t#define HWRM_TF_TCAM_SET                          UINT32_C(0x2f8)\n \t/* Experimental */\n \t#define HWRM_TF_TCAM_GET                          UINT32_C(0x2f9)\n@@ -986,8 +990,8 @@ struct hwrm_err_output {\n #define HWRM_VERSION_MINOR 10\n #define HWRM_VERSION_UPDATE 2\n /* non-zero means beta version */\n-#define HWRM_VERSION_RSVD 15\n-#define HWRM_VERSION_STR \"1.10.2.15\"\n+#define HWRM_VERSION_RSVD 22\n+#define HWRM_VERSION_STR \"1.10.2.22\"\n \n /****************\n  * hwrm_ver_get *\n@@ -11971,7 +11975,7 @@ struct hwrm_func_cfg_input {\n \t/*\n \t * Function ID of the function that is being\n \t * configured.\n-\t * If set to 0xFF... (All Fs), then the configuration is\n+\t * If set to 0xFF... (All Fs), then the the configuration is\n \t * for the requesting function.\n \t */\n \tuint16_t\tfid;\n@@ -12671,7 +12675,7 @@ struct hwrm_func_cfg_input {\n \t/*\n \t * When this bit is '1', the caller requests to disable a MPC\n \t * channel with destination to the TX configurable flow processing\n-\t * block. When this bit is ‘0’, this flag has no effect.\n+\t * block block. When this bit is ‘0’, this flag has no effect.\n \t */\n \t#define HWRM_FUNC_CFG_INPUT_MPC_CHNLS_TE_CFA_DISABLE \\\n \t\tUINT32_C(0x20)\n@@ -12685,7 +12689,7 @@ struct hwrm_func_cfg_input {\n \t/*\n \t * When this bit is '1', the caller requests to disable a MPC\n \t * channel with destination to the RX configurable flow processing\n-\t * block. When this bit is ‘0’, this flag has no effect.\n+\t * block block. When this bit is ‘0’, this flag has no effect.\n \t */\n \t#define HWRM_FUNC_CFG_INPUT_MPC_CHNLS_RE_CFA_DISABLE \\\n \t\tUINT32_C(0x80)\n@@ -18041,7 +18045,7 @@ struct hwrm_func_spd_cfg_input {\n \t\tUINT32_C(0x10)\n \t/*\n \t * Ethertype value used in the encapsulated SPD packet header.\n-\t * The user must choose a value that is not conflicting with\n+\t * The user must chooose a value that is not conflicting with\n \t * publicly defined ethertype values. By default, the ethertype\n \t * value of 0xffff is used if there is no user specified value.\n \t */\n@@ -18300,7 +18304,7 @@ struct hwrm_func_spd_qcfg_output {\n \tuint8_t\tunused_1;\n \t/*\n \t * Ethertype value used in the encapsulated SPD packet header.\n-\t * The user must choose a value that is not conflicting with\n+\t * The user must chooose a value that is not conflicting with\n \t * publicly defined ethertype values. By default, the ethertype\n \t * value of 0xffff is used if there is no user specified value.\n \t */\n@@ -29815,7 +29819,7 @@ struct hwrm_vnic_cfg_input {\n \t * queue ID will be arriving on this VNIC.  Packet priority to CoS mapping\n \t * rules can be specified using HWRM_QUEUE_PRI2COS_CFG.  In this mode,\n \t * ntuple filters with VNIC destination specified are invalid since they\n-\t * conflict with the CoS to VNIC steering rules in this mode.\n+\t * conflict with the the CoS to VNIC steering rules in this mode.\n \t *\n \t * If this field is not specified, packet to VNIC steering will be\n \t * subject to the standard L2 filter rules and any additional ntuple\n@@ -41312,14 +41316,14 @@ struct hwrm_cfa_eem_qcaps_output {\n \t#define HWRM_CFA_EEM_QCAPS_OUTPUT_FLAGS_PATH_RX \\\n \t\tUINT32_C(0x2)\n \t/*\n-\t * When set to 1, indicates the FW supports the Centralized\n+\t * When set to 1, indicates the the FW supports the Centralized\n \t * Memory Model. The concept designates one entity for the\n \t * memory allocation while all others ‘subscribe’ to it.\n \t */\n \t#define HWRM_CFA_EEM_QCAPS_OUTPUT_FLAGS_CENTRALIZED_MEMORY_MODEL_SUPPORTED \\\n \t\tUINT32_C(0x4)\n \t/*\n-\t * When set to 1, indicates the FW supports the Detached\n+\t * When set to 1, indicates the the FW supports the Detached\n \t * Centralized Memory Model. The memory is allocated and managed\n \t * as a separate entity. All PFs and VFs will be granted direct\n \t * or semi-direct access to the allocated memory while none of\n@@ -42143,8 +42147,24 @@ struct hwrm_tf_session_open_output {\n \t * the newly created session.\n \t */\n \tuint32_t\tfw_session_client_id;\n-\t/* unused. */\n-\tuint32_t\tunused0;\n+\tuint32_t\tflags;\n+\t/* Indicates if the shared session has been created. */\n+\t#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION \\\n+\t\tUINT32_C(0x1)\n+\t/*\n+\t * If this bit set to 0, then it indicates the shared session\n+\t * has been created by another session.\n+\t */\n+\t#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_NOT_CREATOR \\\n+\t\tUINT32_C(0x0)\n+\t/*\n+\t * If this bit is set to 1, then it indicates the shared session\n+\t * is created by this session.\n+\t */\n+\t#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR \\\n+\t\tUINT32_C(0x1)\n+\t#define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_LAST \\\n+\t\tHWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR\n \t/* unused. */\n \tuint8_t\tunused1[3];\n \t/*\n@@ -42948,6 +42968,105 @@ struct hwrm_tf_session_resc_flush_output {\n \tuint8_t\tvalid;\n } __rte_packed;\n \n+/*****************************\n+ * hwrm_tf_session_resc_info *\n+ *****************************/\n+\n+\n+/* hwrm_tf_session_resc_info_input (size:320b/40B) */\n+struct hwrm_tf_session_resc_info_input {\n+\t/* The HWRM command request type. */\n+\tuint16_t\treq_type;\n+\t/*\n+\t * The completion ring to send the completion event on. This should\n+\t * be the NQ ID returned from the `nq_alloc` HWRM command.\n+\t */\n+\tuint16_t\tcmpl_ring;\n+\t/*\n+\t * The sequence ID is used by the driver for tracking multiple\n+\t * commands. This ID is treated as opaque data by the firmware and\n+\t * the value is returned in the `hwrm_resp_hdr` upon completion.\n+\t */\n+\tuint16_t\tseq_id;\n+\t/*\n+\t * The target ID of the command:\n+\t * * 0x0-0xFFF8 - The function ID\n+\t * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors\n+\t * * 0xFFFD - Reserved for user-space HWRM interface\n+\t * * 0xFFFF - HWRM\n+\t */\n+\tuint16_t\ttarget_id;\n+\t/*\n+\t * A physical address pointer pointing to a host buffer that the\n+\t * command's response data will be written. This can be either a host\n+\t * physical address (HPA) or a guest physical address (GPA) and must\n+\t * point to a physically contiguous block of memory.\n+\t */\n+\tuint64_t\tresp_addr;\n+\t/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent. */\n+\tuint32_t\tfw_session_id;\n+\t/* Control flags. */\n+\tuint16_t\tflags;\n+\t/* Indicates the flow direction. */\n+\t#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR     UINT32_C(0x1)\n+\t/* If this bit set to 0, then it indicates rx flow. */\n+\t#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_RX    UINT32_C(0x0)\n+\t/* If this bit is set to 1, then it indicates tx flow. */\n+\t#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_TX    UINT32_C(0x1)\n+\t#define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_LAST \\\n+\t\tHWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_TX\n+\t/*\n+\t * Defines the array size of the provided req_addr and\n+\t * resv_addr array buffers. Should be set to the number of\n+\t * request entries.\n+\t */\n+\tuint16_t\treq_size;\n+\t/*\n+\t * This is the DMA address for the request input data array\n+\t * buffer. Array is of tf_rm_resc_req_entry type. Size of the\n+\t * array buffer is provided by the 'req_size' field in this\n+\t * message.\n+\t */\n+\tuint64_t\treq_addr;\n+\t/*\n+\t * This is the DMA address for the resc output data array\n+\t * buffer. Array is of tf_rm_resc_entry type. Size of the array\n+\t * buffer is provided by the 'req_size' field in this\n+\t * message.\n+\t */\n+\tuint64_t\tresc_addr;\n+} __rte_packed;\n+\n+/* hwrm_tf_session_resc_info_output (size:128b/16B) */\n+struct hwrm_tf_session_resc_info_output {\n+\t/* The specific error status for the command. */\n+\tuint16_t\terror_code;\n+\t/* The HWRM command request type. */\n+\tuint16_t\treq_type;\n+\t/* The sequence ID from the original command. */\n+\tuint16_t\tseq_id;\n+\t/* The length of the response data in number of bytes. */\n+\tuint16_t\tresp_len;\n+\t/*\n+\t * Size of the returned tf_rm_resc_entry data array. The value\n+\t * cannot exceed the req_size defined by the input msg. The data\n+\t * array is returned using the resv_addr specified DMA\n+\t * address also provided by the input msg.\n+\t */\n+\tuint16_t\tsize;\n+\t/* unused. */\n+\tuint8_t\tunused0[5];\n+\t/*\n+\t * This field is used in Output records to indicate that the output\n+\t * is completely written to RAM. This field should be read as '1'\n+\t * to indicate that the output has been completely written.\n+\t * When writing a command completion or response to an internal\n+\t * processor, the order of writes has to be such that this field is\n+\t * written last.\n+\t */\n+\tuint8_t\tvalid;\n+} __rte_packed;\n+\n /* TruFlow RM capability of a resource. */\n /* tf_rm_resc_req_entry (size:64b/8B) */\n struct tf_rm_resc_req_entry {\n@@ -43608,14 +43727,14 @@ struct hwrm_tf_ext_em_qcaps_output {\n \tuint16_t\tresp_len;\n \tuint32_t\tflags;\n \t/*\n-\t * When set to 1, indicates the FW supports the Centralized\n+\t * When set to 1, indicates the the FW supports the Centralized\n \t * Memory Model. The concept designates one entity for the\n \t * memory allocation while all others ‘subscribe’ to it.\n \t */\n \t#define HWRM_TF_EXT_EM_QCAPS_OUTPUT_FLAGS_CENTRALIZED_MEMORY_MODEL_SUPPORTED \\\n \t\tUINT32_C(0x1)\n \t/*\n-\t * When set to 1, indicates the FW supports the Detached\n+\t * When set to 1, indicates the the FW supports the Detached\n \t * Centralized Memory Model. The memory is allocated and managed\n \t * as a separate entity. All PFs and VFs will be granted direct\n \t * or semi-direct access to the allocated memory while none of\n@@ -44434,6 +44553,79 @@ struct hwrm_tf_em_delete_output {\n \tuint16_t\tunused0[3];\n } __rte_packed;\n \n+/*******************\n+ * hwrm_tf_em_move *\n+ *******************/\n+\n+\n+/* hwrm_tf_em_move_input (size:320b/40B) */\n+struct hwrm_tf_em_move_input {\n+\t/* The HWRM command request type. */\n+\tuint16_t\treq_type;\n+\t/*\n+\t * The completion ring to send the completion event on. This should\n+\t * be the NQ ID returned from the `nq_alloc` HWRM command.\n+\t */\n+\tuint16_t\tcmpl_ring;\n+\t/*\n+\t * The sequence ID is used by the driver for tracking multiple\n+\t * commands. This ID is treated as opaque data by the firmware and\n+\t * the value is returned in the `hwrm_resp_hdr` upon completion.\n+\t */\n+\tuint16_t\tseq_id;\n+\t/*\n+\t * The target ID of the command:\n+\t * * 0x0-0xFFF8 - The function ID\n+\t * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors\n+\t * * 0xFFFD - Reserved for user-space HWRM interface\n+\t * * 0xFFFF - HWRM\n+\t */\n+\tuint16_t\ttarget_id;\n+\t/*\n+\t * A physical address pointer pointing to a host buffer that the\n+\t * command's response data will be written. This can be either a host\n+\t * physical address (HPA) or a guest physical address (GPA) and must\n+\t * point to a physically contiguous block of memory.\n+\t */\n+\tuint64_t\tresp_addr;\n+\t/* Session Id. */\n+\tuint32_t\tfw_session_id;\n+\t/* Control flags. */\n+\tuint16_t\tflags;\n+\t/* Indicates the flow direction. */\n+\t#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR     UINT32_C(0x1)\n+\t/* If this bit set to 0, then it indicates rx flow. */\n+\t#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_RX    UINT32_C(0x0)\n+\t/* If this bit is set to 1, then it indicates tx flow. */\n+\t#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_TX    UINT32_C(0x1)\n+\t#define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_LAST \\\n+\t\tHWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_TX\n+\t/* Number of EM entry blocks */\n+\tuint16_t\tnum_blocks;\n+\t/* New index for entry */\n+\tuint32_t\tnew_index;\n+\t/* Unused */\n+\tuint32_t\tunused0;\n+\t/* EM internal flow handle. */\n+\tuint64_t\tflow_handle;\n+} __rte_packed;\n+\n+/* hwrm_tf_em_move_output (size:128b/16B) */\n+struct hwrm_tf_em_move_output {\n+\t/* The specific error status for the command. */\n+\tuint16_t\terror_code;\n+\t/* The HWRM command request type. */\n+\tuint16_t\treq_type;\n+\t/* The sequence ID from the original command. */\n+\tuint16_t\tseq_id;\n+\t/* The length of the response data in number of bytes. */\n+\tuint16_t\tresp_len;\n+\t/* Index of old entry. */\n+\tuint16_t\tem_index;\n+\t/* unused. */\n+\tuint16_t\tunused0[3];\n+} __rte_packed;\n+\n /********************\n  * hwrm_tf_tcam_set *\n  ********************/\n@@ -46988,10 +47180,7 @@ struct hwrm_nvm_write_input {\n \t * This is where the source data is.\n \t */\n \tuint64_t\thost_src_addr;\n-\t/*\n-\t * The Directory Entry Type (valid values are defined in the bnxnvm\n-\t * directory_type enum defined in the file bnxnvm_defs.h).\n-\t */\n+\t/* The Directory Entry Type (valid values are defined in the bnxnvm_directory_type enum defined in the file bnxnvm_defs.h). */\n \tuint16_t\tdir_type;\n \t/*\n \t * Directory ordinal.\n@@ -47003,10 +47192,8 @@ struct hwrm_nvm_write_input {\n \t/* Directory Entry Attribute flags (see BNX_DIR_ATTR_* in the file bnxnvm_defs.h). */\n \tuint16_t\tdir_attr;\n \t/*\n-\t * Length of data to write, in bytes. May be less than or equal to the allocated\n-\t * size for the directory entry.\n-\t * The data length stored in the directory entry will be updated to reflect\n-\t * this value once the write is complete.\n+\t * Length of data to write, in bytes. May be less than or equal to the allocated size for the directory entry.\n+\t * The data length stored in the directory entry will be updated to reflect this value once the write is complete.\n \t */\n \tuint32_t\tdir_data_length;\n \t/* Option. */\n@@ -47019,15 +47206,11 @@ struct hwrm_nvm_write_input {\n \t#define HWRM_NVM_WRITE_INPUT_FLAGS_KEEP_ORIG_ACTIVE_IMG \\\n \t\tUINT32_C(0x1)\n \t/*\n-\t * The requested length of the allocated NVM for the item, in bytes. This\n-\t * value may be greater than or equal to the specified data length (dir_data_length).\n+\t * 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).\n \t * If this value is less than the specified data length, it will be ignored.\n-\t * The response will contain the actual allocated item length, which may be\n-\t * greater than the requested item length.\n-\t * The purpose for allocating more than the required number of bytes for\n-\t * an item's data is to pre-allocate extra storage (padding) to accommodate\n-\t * the potential future growth of an item (e.g. upgraded firmware with a\n-\t * size increase, log growth, expanded configuration data).\n+\t * The response will contain the actual allocated item length, which may be greater than the requested item length.\n+\t * 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\n+\t * the potential future growth of an item (e.g. upgraded firmware with a size increase, log growth, expanded configuration data).\n \t */\n \tuint32_t\tdir_item_length;\n \tuint32_t\tunused_0;\n@@ -47044,11 +47227,8 @@ struct hwrm_nvm_write_output {\n \t/* The length of the response data in number of bytes. */\n \tuint16_t\tresp_len;\n \t/*\n-\t * Length of the allocated NVM for the item, in bytes. The value may be\n-\t * greater than or equal to the specified data length or the requested\n-\t * item length.\n-\t * The actual item length used when creating a new directory entry will be\n-\t * a multiple of an NVM block size.\n+\t * 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.\n+\t * The actual item length used when creating a new directory entry will be a multiple of an NVM block size.\n \t */\n \tuint32_t\tdir_item_length;\n \t/* The directory index of the created or modified item. */\n@@ -47392,10 +47572,7 @@ struct hwrm_nvm_get_dev_info_output {\n \t/* Total size, in bytes of the NVRAM device. */\n \tuint32_t\tnvram_size;\n \tuint32_t\treserved_size;\n-\t/*\n-\t * Available size that can be used, in bytes.  Available size is the\n-\t * NVRAM size take away the used size and reserved size.\n-\t */\n+\t/* Available size that can be used, in bytes.  Available size is the NVRAM size take away the used size and reserved size. */\n \tuint32_t\tavailable_size;\n \t/* This field represents the major version of NVM cfg */\n \tuint8_t\tnvm_cfg_ver_maj;\n@@ -47537,15 +47714,9 @@ struct hwrm_nvm_mod_dir_entry_input {\n \t * The (0-based) instance of this Directory Type.\n \t */\n \tuint16_t\tdir_ordinal;\n-\t/*\n-\t * The Directory Entry Extension flags (see BNX_DIR_EXT_* for extension\n-\t * flag definitions).\n-\t */\n+\t/* The Directory Entry Extension flags (see BNX_DIR_EXT_* for extension flag definitions). */\n \tuint16_t\tdir_ext;\n-\t/*\n-\t * Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag\n-\t * definitions).\n-\t */\n+\t/* Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag definitions). */\n \tuint16_t\tdir_attr;\n \t/*\n \t * If valid, then this field updates the checksum\n@@ -47712,10 +47883,8 @@ struct hwrm_nvm_install_update_input {\n \t#define HWRM_NVM_INSTALL_UPDATE_INPUT_FLAGS_ERASE_UNUSED_SPACE \\\n \t\tUINT32_C(0x1)\n \t/*\n-\t * If set to 1, then unspecified images, images not in the package file,\n-\t * will be safely deleted.\n-\t * When combined with erase_unused_space then unspecified images will be\n-\t * securely erased.\n+\t * If set to 1, then unspecified images, images not in the package file, will be safely deleted.\n+\t * When combined with erase_unused_space then unspecified images will be securely erased.\n \t */\n \t#define HWRM_NVM_INSTALL_UPDATE_INPUT_FLAGS_REMOVE_UNUSED_PKG \\\n \t\tUINT32_C(0x2)\n@@ -48100,10 +48269,7 @@ struct hwrm_nvm_set_variable_input {\n \t/* index for the 4th dimensions */\n \tuint16_t\tindex_3;\n \tuint8_t\tflags;\n-\t/*\n-\t * When this bit is 1, flush internal cache after this write operation\n-\t * (see hwrm_nvm_flush command.)\n-\t */\n+\t/* When this bit is 1, flush internal cache after this write operation (see hwrm_nvm_flush command.) */\n \t#define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_FORCE_FLUSH \\\n \t\tUINT32_C(0x1)\n \t/* encryption method */\n@@ -48405,10 +48571,7 @@ struct hwrm_fw_reset_input {\n \t */\n \t#define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_HOST \\\n \t\tUINT32_C(0x4)\n-\t/*\n-\t * AP processor complex (in multi-host environment). Use host_idx to\n-\t * control which core is reset\n-\t */\n+\t/* AP processor complex (in multi-host environment). Use host_idx to control which core is reset */\n \t#define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_AP \\\n \t\tUINT32_C(0x5)\n \t/* Reset all blocks of the chip (including all processors) */\ndiff --git a/drivers/net/bnxt/tf_core/bitalloc.c b/drivers/net/bnxt/tf_core/bitalloc.c\nindex af1397071b..e253cfc3a6 100644\n--- a/drivers/net/bnxt/tf_core/bitalloc.c\n+++ b/drivers/net/bnxt/tf_core/bitalloc.c\n@@ -65,7 +65,7 @@ ba_ffs(bitalloc_word_t v)\n }\n \n int\n-ba_init(struct bitalloc *pool, int size)\n+ba_init(struct bitalloc *pool, int size, bool free)\n {\n \tbitalloc_word_t *mem = (bitalloc_word_t *)pool;\n \tint       i;\n@@ -101,9 +101,11 @@ ba_init(struct bitalloc *pool, int size)\n \t\tpool->storage[offset++] = words[--lev];\n \t}\n \n-\t/* Free the entire pool */\n-\tfor (i = 0; i < size; i++)\n-\t\tba_free(pool, i);\n+\t/* Free the entire pool if it is required*/\n+\tif (free) {\n+\t\tfor (i = 0; i < size; i++)\n+\t\t\tba_free(pool, i);\n+\t}\n \n \treturn 0;\n }\ndiff --git a/drivers/net/bnxt/tf_core/bitalloc.h b/drivers/net/bnxt/tf_core/bitalloc.h\nindex 7244b86e95..e3b389e68d 100644\n--- a/drivers/net/bnxt/tf_core/bitalloc.h\n+++ b/drivers/net/bnxt/tf_core/bitalloc.h\n@@ -7,6 +7,7 @@\n #define _BITALLOC_H_\n \n #include <stdint.h>\n+#include <stdbool.h>\n \n /* Bitalloc works on uint32_t as its word size */\n typedef uint32_t bitalloc_word_t;\n@@ -64,7 +65,7 @@ struct bitalloc {\n  * Returns 0 on success, -1 on failure.  Size is arbitrary up to\n  * BITALLOC_MAX_SIZE\n  */\n-int ba_init(struct bitalloc *pool, int size);\n+int ba_init(struct bitalloc *pool, int size, bool free);\n \n /**\n  * Returns -1 on failure, or index of allocated entry\ndiff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c\nindex 9b8677caac..69f5c10293 100644\n--- a/drivers/net/bnxt/tf_core/tf_core.c\n+++ b/drivers/net/bnxt/tf_core/tf_core.c\n@@ -27,6 +27,8 @@ tf_open_session(struct tf *tfp,\n \tint rc;\n \tunsigned int domain, bus, slot, device;\n \tstruct tf_session_open_session_parms oparms;\n+\tint name_len;\n+\tchar *name;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n@@ -69,6 +71,13 @@ tf_open_session(struct tf *tfp,\n \t\t}\n \t}\n \n+\tname_len = strlen(parms->ctrl_chan_name);\n+\tname = &parms->ctrl_chan_name[name_len - strlen(\"tf_shared\")];\n+\tif (!strncmp(name, \"tf_shared\", strlen(\"tf_shared\"))) {\n+\t\tmemset(parms->ctrl_chan_name, 0, strlen(parms->ctrl_chan_name));\n+\t\tstrcpy(parms->ctrl_chan_name, \"tf_share\");\n+\t}\n+\n \tparms->session_id.internal.domain = domain;\n \tparms->session_id.internal.bus = bus;\n \tparms->session_id.internal.device = device;\n@@ -1593,3 +1602,99 @@ tf_get_if_tbl_entry(struct tf *tfp,\n \n \treturn 0;\n }\n+\n+int tf_get_session_info(struct tf *tfp,\n+\t\t\tstruct tf_get_session_info_parms *parms)\n+{\n+\tint rc;\n+\tstruct tf_session      *tfs;\n+\tstruct tf_dev_info     *dev;\n+\n+\tTF_CHECK_PARMS2(tfp, parms);\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\t/* Retrieve the device information */\n+\trc = tf_session_get_device(tfs, &dev);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup device, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\tTF_CHECK_PARMS2(tfp, parms);\n+\n+\tif (dev->ops->tf_dev_get_ident_resc_info == NULL) {\n+\t\trc = -EOPNOTSUPP;\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Operation not supported, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\trc = dev->ops->tf_dev_get_ident_resc_info(tfp, parms->session_info.ident);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Ident get resc info failed, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\tif (dev->ops->tf_dev_get_tbl_resc_info == NULL) {\n+\t\trc = -EOPNOTSUPP;\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Operation not supported, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\trc = dev->ops->tf_dev_get_tbl_resc_info(tfp, parms->session_info.tbl);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Tbl get resc info failed, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\tif (dev->ops->tf_dev_get_tcam_resc_info == NULL) {\n+\t\trc = -EOPNOTSUPP;\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Operation not supported, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\trc = dev->ops->tf_dev_get_tcam_resc_info(tfp, parms->session_info.tcam);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"TCAM get resc info failed, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\tif (dev->ops->tf_dev_get_em_resc_info == NULL) {\n+\t\trc = -EOPNOTSUPP;\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Operation not supported, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\trc = dev->ops->tf_dev_get_em_resc_info(tfp, parms->session_info.em);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"EM get resc info failed, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h\nindex 7b26b58000..4440d60fe5 100644\n--- a/drivers/net/bnxt/tf_core/tf_core.h\n+++ b/drivers/net/bnxt/tf_core/tf_core.h\n@@ -557,7 +557,8 @@ struct tf_open_session_parms {\n \t * rte_eth_dev_get_name_by_port() within the ULP.\n \t *\n \t * ctrl_chan_name will be used as part of a name for any\n-\t * shared memory allocation.\n+\t * shared memory allocation. The ctrl_chan_name is usually in format\n+\t * 0000:02:00.0. The name for shared session is 0000:02:00.0-tf_shared.\n \t */\n \tchar ctrl_chan_name[TF_SESSION_NAME_MAX];\n \t/**\n@@ -616,29 +617,63 @@ struct tf_open_session_parms {\n \t * Resource allocation for the session.\n \t */\n \tstruct tf_session_resources resources;\n+\n+\t/**\n+\t * [in] bp\n+\t * The pointer to the parent bp struct. This is only used for HWRM\n+\t * message passing within the portability layer. The type is struct\n+\t * bnxt.\n+\t */\n+\tvoid *bp;\n+\n+\t/**\n+\t * [out] shared_session_creator\n+\t *\n+\t * Indicates whether the application created the session if set.\n+\t * Otherwise the shared session already existed.  Just for information\n+\t * purposes.\n+\t */\n+\tint shared_session_creator;\n };\n \n /**\n  * Opens a new TruFlow Session or session client.\n  *\n- * What gets created depends on the passed in tfp content. If the tfp\n- * does not have prior session data a new session with associated\n- * session client. If tfp has a session already a session client will\n- * be created. In both cases the session client is created using the\n- * provided ctrl_chan_name.\n+ * What gets created depends on the passed in tfp content. If the tfp does not\n+ * have prior session data a new session with associated session client. If tfp\n+ * has a session already a session client will be created. In both cases the\n+ * session client is created using the provided ctrl_chan_name.\n  *\n- * In case of session creation TruFlow will allocate session specific\n- * memory, shared memory, to hold its session data. This data is\n- * private to TruFlow.\n+ * In case of session creation TruFlow will allocate session specific memory to\n+ * hold its session data. This data is private to TruFlow.\n  *\n  * No other TruFlow APIs will succeed unless this API is first called\n  * and succeeds.\n  *\n- * tf_open_session() returns a session id and session client id that\n- * is used on all other TF APIs.\n+ * tf_open_session() returns a session id and session client id.  These are\n+ * also stored within the tfp structure passed in to all other APIs.\n  *\n  * A Session or session client can be closed using tf_close_session().\n  *\n+ * There are 2 types of sessions - shared and not.  For non-shared all\n+ * the allocated resources are owned and managed by a single session instance.\n+ * No other applications have access to the resources owned by the non-shared\n+ * session.  For a shared session, resources are shared between 2 applications.\n+ *\n+ * When the caller of tf_open_session() sets the ctrl_chan_name[] to a name\n+ * like \"0000:02:00.0-tf_shared\", it is a request to create a new \"shared\"\n+ * session in the firmware or access the existing shared session. There is\n+ * only 1 shared session that can be created. If the shared session has\n+ * already been created in the firmware, this API will return this indication\n+ * by clearing the shared_session_creator flag. Only the first shared session\n+ * create will have the shared_session_creator flag set.\n+ *\n+ * The shared session should always be the first session to be created by\n+ * application and the last session closed due to RM management preference.\n+ *\n+ * Sessions remain open in the firmware until the last client of the session\n+ * closes the session (tf_close_session()).\n+ *\n  * [in] tfp\n  *   Pointer to TF handle\n  *\n@@ -652,6 +687,126 @@ struct tf_open_session_parms {\n int tf_open_session(struct tf *tfp,\n \t\t    struct tf_open_session_parms *parms);\n \n+/**\n+ * General internal resource info\n+ *\n+ * TODO: remove tf_rm_new_entry structure and use this structure\n+ * internally.\n+ */\n+struct tf_resource_info {\n+\tuint16_t start;\n+\tuint16_t stride;\n+};\n+\n+/**\n+ * Identifier resource definition\n+ */\n+struct tf_identifier_resource_info {\n+\t/**\n+\t * Array of TF Identifiers. The index used is tf_identifier_type.\n+\t */\n+\tstruct tf_resource_info info[TF_IDENT_TYPE_MAX];\n+};\n+\n+/**\n+ * Table type resource info definition\n+ */\n+struct tf_tbl_resource_info {\n+\t/**\n+\t * Array of TF Table types. The index used is tf_tbl_type.\n+\t */\n+\tstruct tf_resource_info info[TF_TBL_TYPE_MAX];\n+};\n+\n+/**\n+ * TCAM type resource definition\n+ */\n+struct tf_tcam_resource_info {\n+\t/**\n+\t * Array of TF TCAM types. The index used is tf_tcam_tbl_type.\n+\t */\n+\tstruct tf_resource_info info[TF_TCAM_TBL_TYPE_MAX];\n+};\n+\n+/**\n+ * EM type resource definition\n+ */\n+struct tf_em_resource_info {\n+\t/**\n+\t * Array of TF EM table types. The index used is tf_em_tbl_type.\n+\t */\n+\tstruct tf_resource_info info[TF_EM_TBL_TYPE_MAX];\n+};\n+\n+/**\n+ * tf_session_resources parameter definition.\n+ */\n+struct tf_session_resource_info {\n+\t/**\n+\t * [in] Requested Identifier Resources\n+\t *\n+\t * Number of identifier resources requested for the\n+\t * session.\n+\t */\n+\tstruct tf_identifier_resource_info ident[TF_DIR_MAX];\n+\t/**\n+\t * [in] Requested Index Table resource counts\n+\t *\n+\t * The number of index table resources requested for the\n+\t * session.\n+\t */\n+\tstruct tf_tbl_resource_info tbl[TF_DIR_MAX];\n+\t/**\n+\t * [in] Requested TCAM Table resource counts\n+\t *\n+\t * The number of TCAM table resources requested for the\n+\t * session.\n+\t */\n+\n+\tstruct tf_tcam_resource_info tcam[TF_DIR_MAX];\n+\t/**\n+\t * [in] Requested EM resource counts\n+\t *\n+\t * The number of internal EM table resources requested for the\n+\t * session.\n+\t */\n+\tstruct tf_em_resource_info em[TF_DIR_MAX];\n+};\n+\n+/**\n+ * tf_get_session_resources parameter definition.\n+ */\n+struct tf_get_session_info_parms {\n+\t/**\n+\t * [out] the structure is used to return the information of\n+\t * allocated resources.\n+\t *\n+\t */\n+\tstruct tf_session_resource_info session_info;\n+};\n+\n+/** (experimental)\n+ * Gets info about a TruFlow Session\n+ *\n+ * Get info about the session which has been created.  Whether it exists and\n+ * what resource start and stride offsets are in use.  This API is primarily\n+ * intended to be used by an application which has created a shared session\n+ * This application needs to obtain the resources which have already been\n+ * allocated for the shared session.\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle\n+ *\n+ * [in] parms\n+ *   Pointer to get parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_get_session_info(struct tf *tfp,\n+\t\t\tstruct tf_get_session_info_parms *parms);\n+\n /**\n  * Experimental\n  *\ndiff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c\nindex 9e71c04bf2..fed4156200 100644\n--- a/drivers/net/bnxt/tf_core/tf_device.c\n+++ b/drivers/net/bnxt/tf_core/tf_device.c\n@@ -351,10 +351,16 @@ tf_dev_bind_p58(struct tf *tfp,\n \tstruct tf_em_cfg_parms em_cfg;\n \tstruct tf_if_tbl_cfg_parms if_tbl_cfg;\n \tstruct tf_global_cfg_cfg_parms global_cfg;\n+\tstruct tf_session *tfs;\n \n \t/* Initial function initialization */\n \tdev_handle->ops = &tf_dev_ops_p58_init;\n \n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n+\n \trsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX,\n \t\t\t\t\t   tf_ident_p58,\n \t\t\t\t\t   (uint16_t *)resources->ident_cnt);\n@@ -440,26 +446,28 @@ tf_dev_bind_p58(struct tf *tfp,\n \t/*\n \t * IF_TBL\n \t */\n-\tif_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;\n-\tif_tbl_cfg.cfg = tf_if_tbl_p58;\n-\tif_tbl_cfg.shadow_copy = shadow_copy;\n-\trc = tf_if_tbl_bind(tfp, &if_tbl_cfg);\n-\tif (rc) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"IF Table initialization failure\\n\");\n-\t\tgoto fail;\n-\t}\n+\tif (!tf_session_is_shared_session(tfs)) {\n+\t\tif_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;\n+\t\tif_tbl_cfg.cfg = tf_if_tbl_p58;\n+\t\tif_tbl_cfg.shadow_copy = shadow_copy;\n+\t\trc = tf_if_tbl_bind(tfp, &if_tbl_cfg);\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"IF Table initialization failure\\n\");\n+\t\t\tgoto fail;\n+\t\t}\n \n-\t/*\n-\t * GLOBAL_CFG\n-\t */\n-\tglobal_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;\n-\tglobal_cfg.cfg = tf_global_cfg_p58;\n-\trc = tf_global_cfg_bind(tfp, &global_cfg);\n-\tif (rc) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"Global Cfg initialization failure\\n\");\n-\t\tgoto fail;\n+\t\t/*\n+\t\t * GLOBAL_CFG\n+\t\t */\n+\t\tglobal_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX;\n+\t\tglobal_cfg.cfg = tf_global_cfg_p58;\n+\t\trc = tf_global_cfg_bind(tfp, &global_cfg);\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"Global Cfg initialization failure\\n\");\n+\t\t\tgoto fail;\n+\t\t}\n \t}\n \n \t/* Final function initialization */\n@@ -491,6 +499,12 @@ tf_dev_unbind_p58(struct tf *tfp)\n {\n \tint rc = 0;\n \tbool fail = false;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/* Unbind all the support modules. As this is only done on\n \t * close we only report errors as everything has to be cleaned\n@@ -527,18 +541,20 @@ tf_dev_unbind_p58(struct tf *tfp)\n \t\tfail = true;\n \t}\n \n-\trc = tf_if_tbl_unbind(tfp);\n-\tif (rc) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"Device unbind failed, IF Table Type\\n\");\n-\t\tfail = true;\n-\t}\n+\tif (!tf_session_is_shared_session(tfs)) {\n+\t\trc = tf_if_tbl_unbind(tfp);\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"Device unbind failed, IF Table Type\\n\");\n+\t\t\tfail = true;\n+\t\t}\n \n-\trc = tf_global_cfg_unbind(tfp);\n-\tif (rc) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"Device unbind failed, Global Cfg Type\\n\");\n-\t\tfail = true;\n+\t\trc = tf_global_cfg_unbind(tfp);\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"Device unbind failed, Global Cfg Type\\n\");\n+\t\t\tfail = true;\n+\t\t}\n \t}\n \n \tif (fail)\ndiff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h\nindex 3f2c24a0c6..16c2fe0f64 100644\n--- a/drivers/net/bnxt/tf_core/tf_device.h\n+++ b/drivers/net/bnxt/tf_core/tf_device.h\n@@ -220,6 +220,25 @@ struct tf_dev_ops {\n \t */\n \tint (*tf_dev_search_ident)(struct tf *tfp,\n \t\t\t\t   struct tf_ident_search_parms *parms);\n+\n+\t/**\n+\t * Retrieves the identifier resource info.\n+\t *\n+\t * This API retrieves the identifier resource info from the rm db.\n+\t *\n+\t * [in] tfp\n+\t *   Pointer to TF handle\n+\t *\n+\t * [in] parms\n+\t *   Pointer to identifier info\n+\t *\n+\t * Returns\n+\t *   - (0) if successful.\n+\t *   - (-EINVAL) on failure.\n+\t */\n+\tint (*tf_dev_get_ident_resc_info)(struct tf *tfp,\n+\t\t\t\t\t  struct tf_identifier_resource_info *parms);\n+\n \t/**\n \t * Get SRAM table information.\n \t *\n@@ -425,6 +444,24 @@ struct tf_dev_ops {\n \tint (*tf_dev_get_bulk_tbl)(struct tf *tfp,\n \t\t\t\t   struct tf_tbl_get_bulk_parms *parms);\n \n+\t/**\n+\t * Retrieves the table resource info.\n+\t *\n+\t * This API retrieves the table resource info from the rm db.\n+\t *\n+\t * [in] tfp\n+\t *   Pointer to TF handle\n+\t *\n+\t * [in] parms\n+\t *   Pointer to tbl info\n+\t *\n+\t * Returns\n+\t *   - (0) if successful.\n+\t *   - (-EINVAL) on failure.\n+\t */\n+\tint (*tf_dev_get_tbl_resc_info)(struct tf *tfp,\n+\t\t\t\t\t struct tf_tbl_resource_info *parms);\n+\n \t/**\n \t * Allocation of a tcam element.\n \t *\n@@ -524,6 +561,24 @@ struct tf_dev_ops {\n \tint (*tf_dev_get_tcam)(struct tf *tfp,\n \t\t\t       struct tf_tcam_get_parms *parms);\n \n+\t/**\n+\t * Retrieves the tcam resource info.\n+\t *\n+\t * This API retrieves the tcam resource info from the rm db.\n+\t *\n+\t * [in] tfp\n+\t *   Pointer to TF handle\n+\t *\n+\t * [in] parms\n+\t *   Pointer to tcam info\n+\t *\n+\t * Returns\n+\t *   - (0) if successful.\n+\t *   - (-EINVAL) on failure.\n+\t */\n+\tint (*tf_dev_get_tcam_resc_info)(struct tf *tfp,\n+\t\t\t\t\t struct tf_tcam_resource_info *parms);\n+\n \t/**\n \t * Insert EM hash entry API\n \t *\n@@ -588,6 +643,24 @@ struct tf_dev_ops {\n \tint (*tf_dev_delete_ext_em_entry)(struct tf *tfp,\n \t\t\t\t\t  struct tf_delete_em_entry_parms *parms);\n \n+\t/**\n+\t * Retrieves the em resource info.\n+\t *\n+\t * This API retrieves the em resource info from the rm db.\n+\t *\n+\t * [in] tfp\n+\t *   Pointer to TF handle\n+\t *\n+\t * [in] parms\n+\t *   Pointer to em info\n+\t *\n+\t * Returns\n+\t *   - (0) if successful.\n+\t *   - (-EINVAL) on failure.\n+\t */\n+\tint (*tf_dev_get_em_resc_info)(struct tf *tfp,\n+\t\t\t\t       struct tf_em_resource_info *parms);\n+\n \t/**\n \t * Allocate EEM table scope\n \t *\ndiff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c\nindex 2fb8fadb56..3f788638c1 100644\n--- a/drivers/net/bnxt/tf_core/tf_device_p4.c\n+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c\n@@ -209,6 +209,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {\n \t.tf_dev_alloc_ident = NULL,\n \t.tf_dev_free_ident = NULL,\n \t.tf_dev_search_ident = NULL,\n+\t.tf_dev_get_ident_resc_info = NULL,\n \t.tf_dev_get_tbl_info = NULL,\n \t.tf_dev_alloc_ext_tbl = NULL,\n \t.tf_dev_alloc_tbl = NULL,\n@@ -219,15 +220,18 @@ const struct tf_dev_ops tf_dev_ops_p4_init = {\n \t.tf_dev_set_ext_tbl = NULL,\n \t.tf_dev_get_tbl = NULL,\n \t.tf_dev_get_bulk_tbl = NULL,\n+\t.tf_dev_get_tbl_resc_info = NULL,\n \t.tf_dev_alloc_tcam = NULL,\n \t.tf_dev_free_tcam = NULL,\n \t.tf_dev_alloc_search_tcam = NULL,\n \t.tf_dev_set_tcam = NULL,\n \t.tf_dev_get_tcam = NULL,\n+\t.tf_dev_get_tcam_resc_info = NULL,\n \t.tf_dev_insert_int_em_entry = NULL,\n \t.tf_dev_delete_int_em_entry = NULL,\n \t.tf_dev_insert_ext_em_entry = NULL,\n \t.tf_dev_delete_ext_em_entry = NULL,\n+\t.tf_dev_get_em_resc_info = NULL,\n \t.tf_dev_alloc_tbl_scope = NULL,\n \t.tf_dev_map_tbl_scope = NULL,\n \t.tf_dev_map_parif = NULL,\n@@ -250,6 +254,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = {\n \t.tf_dev_alloc_ident = tf_ident_alloc,\n \t.tf_dev_free_ident = tf_ident_free,\n \t.tf_dev_search_ident = tf_ident_search,\n+\t.tf_dev_get_ident_resc_info = tf_ident_get_resc_info,\n \t.tf_dev_get_tbl_info = NULL,\n \t.tf_dev_alloc_tbl = tf_tbl_alloc,\n \t.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,\n@@ -260,15 +265,18 @@ const struct tf_dev_ops tf_dev_ops_p4 = {\n \t.tf_dev_set_ext_tbl = tf_tbl_ext_common_set,\n \t.tf_dev_get_tbl = tf_tbl_get,\n \t.tf_dev_get_bulk_tbl = tf_tbl_bulk_get,\n+\t.tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info,\n \t.tf_dev_alloc_tcam = tf_tcam_alloc,\n \t.tf_dev_free_tcam = tf_tcam_free,\n \t.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,\n \t.tf_dev_set_tcam = tf_tcam_set,\n \t.tf_dev_get_tcam = NULL,\n+\t.tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info,\n \t.tf_dev_insert_int_em_entry = tf_em_insert_int_entry,\n \t.tf_dev_delete_int_em_entry = tf_em_delete_int_entry,\n \t.tf_dev_insert_ext_em_entry = tf_em_insert_ext_entry,\n \t.tf_dev_delete_ext_em_entry = tf_em_delete_ext_entry,\n+\t.tf_dev_get_em_resc_info = tf_em_get_resc_info,\n \t.tf_dev_alloc_tbl_scope = tf_em_ext_common_alloc,\n \t.tf_dev_map_tbl_scope = tf_em_ext_map_tbl_scope,\n \t.tf_dev_map_parif = tf_dev_p4_map_parif,\ndiff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c\nindex 517ffc811b..c2bc283220 100644\n--- a/drivers/net/bnxt/tf_core/tf_device_p58.c\n+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c\n@@ -230,6 +230,7 @@ const struct tf_dev_ops tf_dev_ops_p58_init = {\n \t.tf_dev_alloc_ident = NULL,\n \t.tf_dev_free_ident = NULL,\n \t.tf_dev_search_ident = NULL,\n+\t.tf_dev_get_ident_resc_info = NULL,\n \t.tf_dev_get_tbl_info = NULL,\n \t.tf_dev_alloc_ext_tbl = NULL,\n \t.tf_dev_alloc_tbl = NULL,\n@@ -240,15 +241,18 @@ const struct tf_dev_ops tf_dev_ops_p58_init = {\n \t.tf_dev_set_ext_tbl = NULL,\n \t.tf_dev_get_tbl = NULL,\n \t.tf_dev_get_bulk_tbl = NULL,\n+\t.tf_dev_get_tbl_resc_info = NULL,\n \t.tf_dev_alloc_tcam = NULL,\n \t.tf_dev_free_tcam = NULL,\n \t.tf_dev_alloc_search_tcam = NULL,\n \t.tf_dev_set_tcam = NULL,\n \t.tf_dev_get_tcam = NULL,\n+\t.tf_dev_get_tcam_resc_info = NULL,\n \t.tf_dev_insert_int_em_entry = NULL,\n \t.tf_dev_delete_int_em_entry = NULL,\n \t.tf_dev_insert_ext_em_entry = NULL,\n \t.tf_dev_delete_ext_em_entry = NULL,\n+\t.tf_dev_get_em_resc_info = NULL,\n \t.tf_dev_alloc_tbl_scope = NULL,\n \t.tf_dev_map_tbl_scope = NULL,\n \t.tf_dev_map_parif = NULL,\n@@ -271,6 +275,7 @@ const struct tf_dev_ops tf_dev_ops_p58 = {\n \t.tf_dev_alloc_ident = tf_ident_alloc,\n \t.tf_dev_free_ident = tf_ident_free,\n \t.tf_dev_search_ident = tf_ident_search,\n+\t.tf_dev_get_ident_resc_info = tf_ident_get_resc_info,\n \t.tf_dev_get_tbl_info = tf_dev_p58_get_sram_tbl_info,\n \t.tf_dev_alloc_tbl = tf_tbl_alloc,\n \t.tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,\n@@ -281,15 +286,18 @@ const struct tf_dev_ops tf_dev_ops_p58 = {\n \t.tf_dev_set_ext_tbl = tf_tbl_ext_common_set,\n \t.tf_dev_get_tbl = tf_tbl_get,\n \t.tf_dev_get_bulk_tbl = tf_tbl_bulk_get,\n+\t.tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info,\n \t.tf_dev_alloc_tcam = tf_tcam_alloc,\n \t.tf_dev_free_tcam = tf_tcam_free,\n \t.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,\n \t.tf_dev_set_tcam = tf_tcam_set,\n \t.tf_dev_get_tcam = tf_tcam_get,\n+\t.tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info,\n \t.tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry,\n \t.tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry,\n \t.tf_dev_insert_ext_em_entry = NULL,\n \t.tf_dev_delete_ext_em_entry = NULL,\n+\t.tf_dev_get_em_resc_info = tf_em_get_resc_info,\n \t.tf_dev_alloc_tbl_scope = NULL,\n \t.tf_dev_map_tbl_scope = NULL,\n \t.tf_dev_map_parif = NULL,\ndiff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h\nindex 19ad7f12be..60d90e28de 100644\n--- a/drivers/net/bnxt/tf_core/tf_em.h\n+++ b/drivers/net/bnxt/tf_core/tf_em.h\n@@ -530,4 +530,21 @@ tf_em_ext_system_bind(struct tf *tfp,\n \t\t      struct tf_em_cfg_parms *parms);\n \n int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb);\n+\n+/**\n+ * Retrieves the allocated resource info\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle, used for HCAPI communication\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int\n+tf_em_get_resc_info(struct tf *tfp,\n+\t\t    struct tf_em_resource_info *em);\n #endif /* _TF_EM_H_ */\ndiff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c\nindex 4dc3c86b57..ed8f6db58c 100644\n--- a/drivers/net/bnxt/tf_core/tf_em_common.c\n+++ b/drivers/net/bnxt/tf_core/tf_em_common.c\n@@ -26,11 +26,6 @@\n /* Number of pointers per page_size */\n #define MAX_PAGE_PTRS(page_size)  ((page_size) / sizeof(void *))\n \n-/**\n- * Init flag, set on bind and cleared on unbind\n- */\n-static uint8_t init;\n-\n /**\n  * Host or system\n  */\n@@ -924,18 +919,11 @@ tf_em_ext_common_bind(struct tf *tfp,\n \tint rc;\n \tint i;\n \tstruct tf_rm_create_db_parms db_cfg = { 0 };\n-\tuint8_t db_exists = 0;\n \tstruct em_ext_db *ext_db;\n \tstruct tfp_calloc_parms cparms;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"EM Ext DB already initialized\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n \tcparms.nitems = 1;\n \tcparms.size = sizeof(struct em_ext_db);\n \tcparms.alignment = 0;\n@@ -974,12 +962,8 @@ tf_em_ext_common_bind(struct tf *tfp,\n \n \t\t\treturn rc;\n \t\t}\n-\t\tdb_exists = 1;\n \t}\n \n-\tif (db_exists)\n-\t\tinit = 1;\n-\n \tmem_type = parms->mem_type;\n \n \treturn 0;\n@@ -1001,13 +985,6 @@ tf_em_ext_common_unbind(struct tf *tfp)\n \n \tTF_CHECK_PARMS1(tfp);\n \n-\t/* Bail if nothing has been initialized */\n-\tif (!init) {\n-\t\tTFP_DRV_LOG(INFO,\n-\t\t\t    \"No EM Ext DBs created\\n\");\n-\t\treturn 0;\n-\t}\n-\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR, \"Failed to get tf_session, rc:%s\\n\",\n@@ -1064,8 +1041,6 @@ tf_em_ext_common_unbind(struct tf *tfp)\n \ttfp_free(ext_db);\n \ttf_session_set_em_ext_db(tfp, NULL);\n \n-\tinit = 0;\n-\n \treturn 0;\n }\n \ndiff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c\nindex 5a100ef1de..e373a9b029 100644\n--- a/drivers/net/bnxt/tf_core/tf_em_internal.c\n+++ b/drivers/net/bnxt/tf_core/tf_em_internal.c\n@@ -20,11 +20,6 @@\n \n #define TF_EM_DB_EM_REC 0\n \n-/**\n- * Init flag, set on bind and cleared on unbind\n- */\n-static uint8_t init;\n-\n /**\n  * EM Pool\n  */\n@@ -234,19 +229,18 @@ tf_em_int_bind(struct tf *tfp,\n \tint rc;\n \tint i;\n \tstruct tf_rm_create_db_parms db_cfg = { 0 };\n-\tuint8_t db_exists = 0;\n \tstruct tf_rm_get_alloc_info_parms iparms;\n \tstruct tf_rm_alloc_info info;\n \tstruct em_rm_db *em_db;\n \tstruct tfp_calloc_parms cparms;\n+\tstruct tf_session *tfs;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"EM Int DB already initialized\\n\");\n-\t\treturn -EINVAL;\n-\t}\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n \n \tmemset(&db_cfg, 0, sizeof(db_cfg));\n \tcparms.nitems = 1;\n@@ -290,8 +284,11 @@ tf_em_int_bind(struct tf *tfp,\n \t\t}\n \n \t\tdb_cfg.rm_db = (void *)&em_db->em_db[i];\n-\n-\t\trc = tf_rm_create_db(tfp, &db_cfg);\n+\t\tif (tf_session_is_shared_session(tfs) &&\n+\t\t\t(!tf_session_is_shared_session_creator(tfs)))\n+\t\t\trc = tf_rm_create_db_no_reservation(tfp, &db_cfg);\n+\t\telse\n+\t\t\trc = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t    \"%s: EM Int DB creation failed\\n\",\n@@ -299,34 +296,31 @@ tf_em_int_bind(struct tf *tfp,\n \n \t\t\treturn rc;\n \t\t}\n-\t\tdb_exists = 1;\n \t}\n \n-\tif (db_exists)\n-\t\tinit = 1;\n-\n-\tfor (i = 0; i < TF_DIR_MAX; i++) {\n-\t\tiparms.rm_db = em_db->em_db[i];\n-\t\tiparms.subtype = TF_EM_DB_EM_REC;\n-\t\tiparms.info = &info;\n+\tif (!tf_session_is_shared_session(tfs)) {\n+\t\tfor (i = 0; i < TF_DIR_MAX; i++) {\n+\t\t\tiparms.rm_db = em_db->em_db[i];\n+\t\t\tiparms.subtype = TF_EM_DB_EM_REC;\n+\t\t\tiparms.info = &info;\n+\n+\t\t\trc = tf_rm_get_info(&iparms);\n+\t\t\tif (rc) {\n+\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t\t    \"%s: EM DB get info failed\\n\",\n+\t\t\t\t\t    tf_dir_2_str(i));\n+\t\t\t\treturn rc;\n+\t\t\t}\n \n-\t\trc = tf_rm_get_info(&iparms);\n-\t\tif (rc) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"%s: EM DB get info failed\\n\",\n-\t\t\t\t    tf_dir_2_str(i));\n-\t\t\treturn rc;\n+\t\t\trc = tf_create_em_pool(i,\n+\t\t\t\t\t       iparms.info->entry.stride,\n+\t\t\t\t\t       iparms.info->entry.start);\n+\t\t\t/* Logging handled in tf_create_em_pool */\n+\t\t\tif (rc)\n+\t\t\t\treturn rc;\n \t\t}\n-\n-\t\trc = tf_create_em_pool(i,\n-\t\t\t\t       iparms.info->entry.stride,\n-\t\t\t\t       iparms.info->entry.start);\n-\t\t/* Logging handled in tf_create_em_pool */\n-\t\tif (rc)\n-\t\t\treturn rc;\n \t}\n \n-\n \treturn 0;\n }\n \n@@ -338,18 +332,19 @@ tf_em_int_unbind(struct tf *tfp)\n \tstruct tf_rm_free_db_parms fparms = { 0 };\n \tstruct em_rm_db *em_db;\n \tvoid *em_db_ptr = NULL;\n+\tstruct tf_session *tfs;\n \n \tTF_CHECK_PARMS1(tfp);\n \n-\t/* Bail if nothing has been initialized */\n-\tif (!init) {\n-\t\tTFP_DRV_LOG(INFO,\n-\t\t\t    \"No EM Int DBs created\\n\");\n-\t\treturn 0;\n-\t}\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n \n-\tfor (i = 0; i < TF_DIR_MAX; i++)\n-\t\ttf_free_em_pool(i);\n+\tif (!tf_session_is_shared_session(tfs)) {\n+\t\tfor (i = 0; i < TF_DIR_MAX; i++)\n+\t\t\ttf_free_em_pool(i);\n+\t}\n \n \trc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);\n \tif (rc) {\n@@ -372,7 +367,42 @@ tf_em_int_unbind(struct tf *tfp)\n \t\tem_db->em_db[i] = NULL;\n \t}\n \n-\tinit = 0;\n+\treturn 0;\n+}\n+\n+int\n+tf_em_get_resc_info(struct tf *tfp,\n+\t\t    struct tf_em_resource_info *em)\n+{\n+\tint rc;\n+\tint d;\n+\tstruct tf_resource_info *dinfo;\n+\tstruct tf_rm_get_alloc_info_parms ainfo;\n+\tvoid *em_db_ptr = NULL;\n+\tstruct em_rm_db *em_db;\n+\n+\tTF_CHECK_PARMS2(tfp, em);\n+\n+\trc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to get em_ext_db from session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\tem_db = (struct em_rm_db *)em_db_ptr;\n+\n+\t/* check if reserved resource for WC is multiple of num_slices */\n+\tfor (d = 0; d < TF_DIR_MAX; d++) {\n+\t\tainfo.rm_db = em_db->em_db[d];\n+\t\tdinfo = em[d].info;\n+\n+\t\tainfo.info = (struct tf_rm_alloc_info *)dinfo;\n+\t\tainfo.subtype = 0;\n+\t\trc = tf_rm_get_all_info(&ainfo, TF_EM_TBL_TYPE_MAX);\n+\t\tif (rc && rc != -ENOTSUP)\n+\t\t\treturn rc;\n+\t}\n \n \treturn 0;\n }\ndiff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c\nindex ee68b6ca58..4063f3ba17 100644\n--- a/drivers/net/bnxt/tf_core/tf_identifier.c\n+++ b/drivers/net/bnxt/tf_core/tf_identifier.c\n@@ -15,11 +15,6 @@\n \n struct tf;\n \n-/**\n- * Init flag, set on bind and cleared on unbind\n- */\n-static uint8_t init;\n-\n /**\n  * Identifier shadow DBs.\n  */\n@@ -41,14 +36,14 @@ tf_ident_bind(struct tf *tfp,\n \tstruct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };\n \tstruct ident_rm_db *ident_db;\n \tstruct tfp_calloc_parms cparms;\n+\tstruct tf_session *tfs;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"Identifier DB already initialized\\n\");\n-\t\treturn -EINVAL;\n-\t}\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n \n \tmemset(&db_cfg, 0, sizeof(db_cfg));\n \tcparms.nitems = 1;\n@@ -73,7 +68,11 @@ tf_ident_bind(struct tf *tfp,\n \t\tdb_cfg.rm_db = (void *)&ident_db->ident_db[i];\n \t\tdb_cfg.dir = i;\n \t\tdb_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;\n-\t\trc = tf_rm_create_db(tfp, &db_cfg);\n+\t\tif (tf_session_is_shared_session(tfs) &&\n+\t\t\t(!tf_session_is_shared_session_creator(tfs)))\n+\t\t\trc = tf_rm_create_db_no_reservation(tfp, &db_cfg);\n+\t\telse\n+\t\t\trc = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t    \"%s: Identifier DB creation failed\\n\",\n@@ -100,8 +99,6 @@ tf_ident_bind(struct tf *tfp,\n \t\t}\n \t}\n \n-\tinit = 1;\n-\n \tTFP_DRV_LOG(INFO,\n \t\t    \"Identifier - initialized\\n\");\n \n@@ -120,13 +117,6 @@ tf_ident_unbind(struct tf *tfp)\n \n \tTF_CHECK_PARMS1(tfp);\n \n-\t/* Bail if nothing has been initialized */\n-\tif (!init) {\n-\t\tTFP_DRV_LOG(INFO,\n-\t\t\t    \"No Identifier DBs created\\n\");\n-\t\treturn 0;\n-\t}\n-\n \trc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR,\n@@ -158,7 +148,6 @@ tf_ident_unbind(struct tf *tfp)\n \t\tident_db->ident_db[i] = NULL;\n \t}\n \n-\tinit = 0;\n \tshadow_init = 0;\n \n \treturn 0;\n@@ -178,13 +167,6 @@ tf_ident_alloc(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Identifier DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \trc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR,\n@@ -242,13 +224,6 @@ tf_ident_free(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Identifier DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \trc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR,\n@@ -329,13 +304,6 @@ tf_ident_search(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Identifier DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \tif (!shadow_init) {\n \t\tTFP_DRV_LOG(ERR,\n \t\t\t    \"%s: Identifier Shadow copy is not enabled\\n\",\n@@ -388,3 +356,40 @@ tf_ident_search(struct tf *tfp __rte_unused,\n \n \treturn 0;\n }\n+\n+int\n+tf_ident_get_resc_info(struct tf *tfp,\n+\t\t       struct tf_identifier_resource_info *ident)\n+{\n+\tint rc;\n+\tint d;\n+\tstruct tf_resource_info *dinfo;\n+\tstruct tf_rm_get_alloc_info_parms ainfo;\n+\tvoid *ident_db_ptr = NULL;\n+\tstruct ident_rm_db *ident_db;\n+\n+\tTF_CHECK_PARMS2(tfp, ident);\n+\n+\trc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to get ident_db from session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\tident_db = (struct ident_rm_db *)ident_db_ptr;\n+\n+\t/* check if reserved resource for WC is multiple of num_slices */\n+\tfor (d = 0; d < TF_DIR_MAX; d++) {\n+\t\tainfo.rm_db = ident_db->ident_db[d];\n+\t\tdinfo = ident[d].info;\n+\n+\t\tainfo.info = (struct tf_rm_alloc_info *)dinfo;\n+\t\tainfo.subtype = 0;\n+\t\trc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h\nindex 54cecbfd4c..55c093802e 100644\n--- a/drivers/net/bnxt/tf_core/tf_identifier.h\n+++ b/drivers/net/bnxt/tf_core/tf_identifier.h\n@@ -201,4 +201,20 @@ int tf_ident_free(struct tf *tfp,\n int tf_ident_search(struct tf *tfp,\n \t\t    struct tf_ident_search_parms *parms);\n \n+/**\n+ * Retrieves the allocated resource info\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle, used for HCAPI communication\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_ident_get_resc_info(struct tf *tfp,\n+\t\t\t   struct tf_identifier_resource_info *parms);\n+\n #endif /* _TF_IDENTIFIER_H_ */\ndiff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c\nindex c6eb94bee0..4a840f3473 100644\n--- a/drivers/net/bnxt/tf_core/tf_msg.c\n+++ b/drivers/net/bnxt/tf_core/tf_msg.c\n@@ -114,11 +114,12 @@ tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf)\n /* HWRM Direct messages */\n \n int\n-tf_msg_session_open(struct tf *tfp,\n+tf_msg_session_open(struct bnxt *bp,\n \t\t    char *ctrl_chan_name,\n \t\t    uint8_t *fw_session_id,\n \t\t    uint8_t *fw_session_client_id,\n-\t\t    struct tf_dev_info *dev)\n+\t\t    struct tf_dev_info *dev,\n+\t\t    bool *shared_session_creator)\n {\n \tint rc;\n \tstruct hwrm_tf_session_open_input req = { 0 };\n@@ -135,7 +136,7 @@ tf_msg_session_open(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(bp,\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -143,6 +144,8 @@ tf_msg_session_open(struct tf *tfp,\n \t*fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id);\n \t*fw_session_client_id =\n \t\t(uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id);\n+\t*shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags\n+\t\t& HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR);\n \n \treturn rc;\n }\n@@ -198,7 +201,7 @@ tf_msg_session_client_register(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -249,7 +252,7 @@ tf_msg_session_client_unregister(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \n \treturn rc;\n@@ -293,7 +296,7 @@ tf_msg_session_close(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -345,7 +348,7 @@ tf_msg_session_qcfg(struct tf *tfp)\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -367,6 +370,16 @@ tf_msg_session_resc_qcaps(struct tf *tfp,\n \tstruct tf_msg_dma_buf qcaps_buf = { 0 };\n \tstruct tf_rm_resc_req_entry *data;\n \tint dma_size;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n \n \tTF_CHECK_PARMS3(tfp, query, resv_strategy);\n \n@@ -398,7 +411,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \tif (rc)\n \t\tgoto cleanup;\n \n@@ -416,6 +429,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp,\n \n \t/* Post process the response */\n \tdata = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;\n+\n \tfor (i = 0; i < size; i++) {\n \t\tquery[i].type = tfp_le_to_cpu_32(data[i].type);\n \t\tquery[i].min = tfp_le_to_cpu_16(data[i].min);\n@@ -450,6 +464,16 @@ tf_msg_session_resc_alloc(struct tf *tfp,\n \tstruct tf_rm_resc_req_entry *req_data;\n \tstruct tf_rm_resc_entry *resv_data;\n \tint dma_size;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n \n \tTF_CHECK_PARMS3(tfp, request, resv);\n \n@@ -497,7 +521,114 @@ tf_msg_session_resc_alloc(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n+\tif (rc)\n+\t\tgoto cleanup;\n+\n+\t/* Process the response\n+\t * Should always get expected number of entries\n+\t */\n+\tif (tfp_le_to_cpu_32(resp.size) != size) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: Alloc message size error, rc:%s\\n\",\n+\t\t\t    tf_dir_2_str(dir),\n+\t\t\t    strerror(EINVAL));\n+\t\trc = -EINVAL;\n+\t\tgoto cleanup;\n+\t}\n+\n+\t/* Post process the response */\n+\tresv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;\n+\tfor (i = 0; i < size; i++) {\n+\t\tresv[i].type = tfp_le_to_cpu_32(resv_data[i].type);\n+\t\tresv[i].start = tfp_le_to_cpu_16(resv_data[i].start);\n+\t\tresv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);\n+\t}\n+\n+cleanup:\n+\ttf_msg_free_dma_buf(&req_buf);\n+\ttf_msg_free_dma_buf(&resv_buf);\n+\n+\treturn rc;\n+}\n+\n+int\n+tf_msg_session_resc_info(struct tf *tfp,\n+\t\t\t struct tf_dev_info *dev,\n+\t\t\t enum tf_dir dir,\n+\t\t\t uint16_t size,\n+\t\t\t struct tf_rm_resc_req_entry *request,\n+\t\t\t struct tf_rm_resc_entry *resv)\n+{\n+\tint rc;\n+\tint i;\n+\tstruct tfp_send_msg_parms parms = { 0 };\n+\tstruct hwrm_tf_session_resc_info_input req = { 0 };\n+\tstruct hwrm_tf_session_resc_info_output resp = { 0 };\n+\tuint8_t fw_session_id;\n+\tstruct tf_msg_dma_buf req_buf = { 0 };\n+\tstruct tf_msg_dma_buf resv_buf = { 0 };\n+\tstruct tf_rm_resc_req_entry *req_data;\n+\tstruct tf_rm_resc_entry *resv_data;\n+\tint dma_size;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\tTF_CHECK_PARMS3(tfp, request, resv);\n+\n+\trc = tf_session_get_fw_session_id(tfp, &fw_session_id);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: Unable to lookup FW id, rc:%s\\n\",\n+\t\t\t    tf_dir_2_str(dir),\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\n+\t/* Prepare DMA buffers */\n+\tdma_size = size * sizeof(struct tf_rm_resc_req_entry);\n+\trc = tf_msg_alloc_dma_buf(&req_buf, dma_size);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tdma_size = size * sizeof(struct tf_rm_resc_entry);\n+\trc = tf_msg_alloc_dma_buf(&resv_buf, dma_size);\n+\tif (rc) {\n+\t\ttf_msg_free_dma_buf(&req_buf);\n+\t\treturn rc;\n+\t}\n+\n+\t/* Populate the request */\n+\treq.fw_session_id = tfp_cpu_to_le_32(fw_session_id);\n+\treq.flags = tfp_cpu_to_le_16(dir);\n+\treq.req_size = size;\n+\n+\treq_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr;\n+\tfor (i = 0; i < size; i++) {\n+\t\treq_data[i].type = tfp_cpu_to_le_32(request[i].type);\n+\t\treq_data[i].min = tfp_cpu_to_le_16(request[i].min);\n+\t\treq_data[i].max = tfp_cpu_to_le_16(request[i].max);\n+\t}\n+\n+\treq.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr);\n+\treq.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr);\n+\n+\tparms.tf_type = HWRM_TF_SESSION_RESC_INFO;\n+\tparms.req_data = (uint32_t *)&req;\n+\tparms.req_size = sizeof(req);\n+\tparms.resp_data = (uint32_t *)&resp;\n+\tparms.resp_size = sizeof(resp);\n+\tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n+\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \tif (rc)\n \t\tgoto cleanup;\n \n@@ -604,7 +735,7 @@ tf_msg_session_resc_flush(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \n \ttf_msg_free_dma_buf(&resv_buf);\n \n@@ -698,7 +829,7 @@ tf_msg_insert_em_internal_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -793,7 +924,7 @@ tf_msg_hash_insert_em_internal_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -863,7 +994,7 @@ tf_msg_delete_em_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -919,7 +1050,7 @@ int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp,\n \t\tparms.resp_data = (uint32_t *)&resp;\n \t\tparms.resp_size = sizeof(resp);\n \t\tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n-\t\trc = tfp_send_msg_direct(tfp, &parms);\n+\t\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR, \"Failed ext_em_alloc error rc:%s\\n\",\n \t\t\t\tstrerror(-rc));\n@@ -979,7 +1110,7 @@ int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp,\n \tparms.resp_data = (uint32_t *)&resp;\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \n \treturn rc;\n }\n@@ -1030,7 +1161,7 @@ tf_msg_em_mem_rgtr(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -1082,7 +1213,7 @@ tf_msg_em_mem_unrgtr(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -1134,7 +1265,7 @@ tf_msg_em_qcaps(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -1209,7 +1340,7 @@ tf_msg_em_cfg(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -1283,7 +1414,7 @@ tf_msg_ext_em_cfg(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -1333,7 +1464,7 @@ tf_msg_em_op(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -1351,6 +1482,16 @@ tf_msg_tcam_entry_set(struct tf *tfp,\n \tuint8_t *data = NULL;\n \tint data_size = 0;\n \tuint8_t fw_session_id;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n \n \trc = tf_session_get_fw_session_id(tfp, &fw_session_id);\n \tif (rc) {\n@@ -1401,7 +1542,7 @@ tf_msg_tcam_entry_set(struct tf *tfp,\n \tmparms.resp_size = sizeof(resp);\n \tmparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &mparms);\n \n cleanup:\n@@ -1420,6 +1561,16 @@ tf_msg_tcam_entry_get(struct tf *tfp,\n \tstruct hwrm_tf_tcam_get_input req = { 0 };\n \tstruct hwrm_tf_tcam_get_output resp = { 0 };\n \tuint8_t fw_session_id;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n \n \trc = tf_session_get_fw_session_id(tfp, &fw_session_id);\n \tif (rc) {\n@@ -1444,7 +1595,7 @@ tf_msg_tcam_entry_get(struct tf *tfp,\n \tmparms.resp_size = sizeof(resp);\n \tmparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &mparms);\n \n \tif (rc != 0)\n@@ -1480,6 +1631,16 @@ tf_msg_tcam_entry_free(struct tf *tfp,\n \tstruct hwrm_tf_tcam_free_output resp = { 0 };\n \tstruct tfp_send_msg_parms parms = { 0 };\n \tuint8_t fw_session_id;\n+\tstruct tf_session *tfs;\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to lookup session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n \n \trc = tf_session_get_fw_session_id(tfp, &fw_session_id);\n \tif (rc) {\n@@ -1505,7 +1666,7 @@ tf_msg_tcam_entry_free(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \treturn rc;\n }\n@@ -1586,7 +1747,7 @@ tf_msg_set_tbl_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -1652,7 +1813,7 @@ tf_msg_get_tbl_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -1738,7 +1899,7 @@ tf_msg_get_global_cfg(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \tif (rc != 0)\n \t\treturn rc;\n \n@@ -1839,7 +2000,7 @@ tf_msg_set_global_cfg(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \n \tif (rc != 0)\n \t\treturn rc;\n@@ -1912,7 +2073,7 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp,\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs),\n \t\t\t\t &parms);\n \tif (rc)\n \t\treturn rc;\n@@ -1975,7 +2136,7 @@ tf_msg_get_if_tbl_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \n \tif (rc != 0)\n \t\treturn rc;\n@@ -2032,7 +2193,7 @@ tf_msg_set_if_tbl_entry(struct tf *tfp,\n \tparms.resp_size = sizeof(resp);\n \tparms.mailbox = dev->ops->tf_dev_get_mailbox();\n \n-\trc = tfp_send_msg_direct(tfp, &parms);\n+\trc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms);\n \n \tif (rc != 0)\n \t\treturn rc;\ndiff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h\nindex 7b4a6a3d92..5ecaf9e7e7 100644\n--- a/drivers/net/bnxt/tf_core/tf_msg.h\n+++ b/drivers/net/bnxt/tf_core/tf_msg.h\n@@ -14,6 +14,7 @@\n #include \"tf_rm.h\"\n #include \"tf_tcam.h\"\n #include \"tf_global_cfg.h\"\n+#include \"bnxt.h\"\n \n struct tf;\n \n@@ -22,8 +23,8 @@ struct tf;\n /**\n  * Sends session open request to Firmware\n  *\n- * [in] session\n- *   Pointer to session handle\n+ * [in] bp\n+ *   Pointer to bnxt handle\n  *\n  * [in] ctrl_chan_name\n  *   PCI name of the control channel\n@@ -31,14 +32,24 @@ struct tf;\n  * [in/out] fw_session_id\n  *   Pointer to the fw_session_id that is allocated on firmware side\n  *\n+ * [in/out] fw_session_client_id\n+ *   Pointer to the fw_session_client_id that is allocated on firmware side\n+ *\n+ * [in/out] dev\n+ *   Pointer to the associated device\n+ *\n+ * [out] shared_session_creator\n+ *   Pointer to the shared_session_creator\n+ *\n  * Returns:\n  *   0 on Success else internal Truflow error\n  */\n-int tf_msg_session_open(struct tf *tfp,\n+int tf_msg_session_open(struct bnxt *bp,\n \t\t\tchar *ctrl_chan_name,\n \t\t\tuint8_t *fw_session_id,\n \t\t\tuint8_t *fw_session_client_id,\n-\t\t\tstruct tf_dev_info *dev);\n+\t\t\tstruct tf_dev_info *dev,\n+\t\t\tbool *shared_session_creator);\n \n /**\n  * Sends session close request to Firmware\n@@ -178,6 +189,34 @@ int tf_msg_session_resc_alloc(struct tf *tfp,\n \t\t\t      struct tf_rm_resc_req_entry *request,\n \t\t\t      struct tf_rm_resc_entry *resv);\n \n+/**\n+ * Sends session HW resource allocation request to TF Firmware\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle\n+ *\n+ * [in] dir\n+ *   Receive or Transmit direction\n+ *\n+ * [in] size\n+ *   Number of elements in the req and resv arrays\n+ *\n+ * [in] req\n+ *   Pointer to an array of request elements\n+ *\n+ * [in] resv\n+ *   Pointer to an array of reserved elements\n+ *\n+ * Returns:\n+ *   0 on Success else internal Truflow error\n+ */\n+int tf_msg_session_resc_info(struct tf *tfp,\n+\t\t\t      struct tf_dev_info *dev,\n+\t\t\t      enum tf_dir dir,\n+\t\t\t      uint16_t size,\n+\t\t\t      struct tf_rm_resc_req_entry *request,\n+\t\t\t      struct tf_rm_resc_entry *resv);\n+\n /**\n  * Sends session resource flush request to TF Firmware\n  *\ndiff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c\nindex 9fd660543c..761d18413b 100644\n--- a/drivers/net/bnxt/tf_core/tf_rm.c\n+++ b/drivers/net/bnxt/tf_core/tf_rm.c\n@@ -702,7 +702,9 @@ tf_rm_create_db(struct tf *tfp,\n \t\t\t\t}\n \t\t\t\tdb[i].pool = (struct bitalloc *)cparms.mem_va;\n \n-\t\t\t\trc = ba_init(db[i].pool, resv[j].stride);\n+\t\t\t\trc = ba_init(db[i].pool,\n+\t\t\t\t\t     resv[j].stride,\n+\t\t\t\t\t     !tf_session_is_shared_session(tfs));\n \t\t\t\tif (rc) {\n \t\t\t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t\t  \"%s: Pool init failed, type:%d:%s\\n\",\n@@ -746,6 +748,249 @@ tf_rm_create_db(struct tf *tfp,\n \treturn -EINVAL;\n }\n \n+int\n+tf_rm_create_db_no_reservation(struct tf *tfp,\n+\t\t\t       struct tf_rm_create_db_parms *parms)\n+{\n+\tint rc;\n+\tstruct tf_session *tfs;\n+\tstruct tf_dev_info *dev;\n+\tint i, j;\n+\tuint16_t hcapi_items, *req_cnt;\n+\tstruct tfp_calloc_parms cparms;\n+\tstruct tf_rm_resc_req_entry *req;\n+\tstruct tf_rm_resc_entry *resv;\n+\tstruct tf_rm_new_db *rm_db;\n+\tstruct tf_rm_element *db;\n+\tuint32_t pool_size;\n+\n+\tTF_CHECK_PARMS2(tfp, parms);\n+\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Retrieve device information */\n+\trc = tf_session_get_device(tfs, &dev);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Copy requested counts (alloc_cnt) from tf_open_session() to local\n+\t * copy (req_cnt) so that it can be updated if required.\n+\t */\n+\n+\tcparms.nitems = parms->num_elements;\n+\tcparms.size = sizeof(uint16_t);\n+\tcparms.alignment = 0;\n+\trc = tfp_calloc(&cparms);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\treq_cnt = (uint16_t *)cparms.mem_va;\n+\n+\ttfp_memcpy(req_cnt, parms->alloc_cnt,\n+\t\t   parms->num_elements * sizeof(uint16_t));\n+\n+\t/* Process capabilities against DB requirements. However, as a\n+\t * DB can hold elements that are not HCAPI we can reduce the\n+\t * req msg content by removing those out of the request yet\n+\t * the DB holds them all as to give a fast lookup. We can also\n+\t * remove entries where there are no request for elements.\n+\t */\n+\ttf_rm_count_hcapi_reservations(parms->dir,\n+\t\t\t\t       parms->module,\n+\t\t\t\t       parms->cfg,\n+\t\t\t\t       req_cnt,\n+\t\t\t\t       parms->num_elements,\n+\t\t\t\t       &hcapi_items);\n+\n+\tif (hcapi_items == 0) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\"%s: module:%s Empty RM DB create request\\n\",\n+\t\t\ttf_dir_2_str(parms->dir),\n+\t\t\ttf_module_2_str(parms->module));\n+\n+\t\tparms->rm_db = NULL;\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Alloc request, alignment already set */\n+\tcparms.nitems = (size_t)hcapi_items;\n+\tcparms.size = sizeof(struct tf_rm_resc_req_entry);\n+\trc = tfp_calloc(&cparms);\n+\tif (rc)\n+\t\treturn rc;\n+\treq = (struct tf_rm_resc_req_entry *)cparms.mem_va;\n+\n+\t/* Alloc reservation, alignment and nitems already set */\n+\tcparms.size = sizeof(struct tf_rm_resc_entry);\n+\trc = tfp_calloc(&cparms);\n+\tif (rc)\n+\t\treturn rc;\n+\tresv = (struct tf_rm_resc_entry *)cparms.mem_va;\n+\n+\t/* Build the request */\n+\tfor (i = 0, j = 0; i < parms->num_elements; i++) {\n+\t\tstruct tf_rm_element_cfg *cfg = &parms->cfg[i];\n+\t\tuint16_t hcapi_type = cfg->hcapi_type;\n+\n+\t\t/* Only perform reservation for requested entries\n+\t\t */\n+\t\tif (req_cnt[i] == 0)\n+\t\t\tcontinue;\n+\n+\t\t/* Skip any children in the request */\n+\t\tif (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI ||\n+\t\t    cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA ||\n+\t\t    cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_PARENT) {\n+\t\t\treq[j].type = hcapi_type;\n+\t\t\treq[j].min = req_cnt[i];\n+\t\t\treq[j].max = req_cnt[i];\n+\t\t\tj++;\n+\t\t}\n+\t}\n+\n+\t/* Get all resources info for the module type\n+\t */\n+\trc = tf_msg_session_resc_info(tfp,\n+\t\t\t\t      dev,\n+\t\t\t\t      parms->dir,\n+\t\t\t\t      hcapi_items,\n+\t\t\t\t      req,\n+\t\t\t\t      resv);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Build the RM DB per the request */\n+\tcparms.nitems = 1;\n+\tcparms.size = sizeof(struct tf_rm_new_db);\n+\trc = tfp_calloc(&cparms);\n+\tif (rc)\n+\t\treturn rc;\n+\trm_db = (void *)cparms.mem_va;\n+\n+\t/* Build the DB within RM DB */\n+\tcparms.nitems = parms->num_elements;\n+\tcparms.size = sizeof(struct tf_rm_element);\n+\trc = tfp_calloc(&cparms);\n+\tif (rc)\n+\t\treturn rc;\n+\trm_db->db = (struct tf_rm_element *)cparms.mem_va;\n+\n+\tdb = rm_db->db;\n+\tfor (i = 0, j = 0; i < parms->num_elements; i++) {\n+\t\tstruct tf_rm_element_cfg *cfg = &parms->cfg[i];\n+\t\tconst char *type_str;\n+\n+\t\tdev->ops->tf_dev_get_resource_str(tfp,\n+\t\t\t\t\t\t  cfg->hcapi_type,\n+\t\t\t\t\t\t  &type_str);\n+\n+\t\tdb[i].cfg_type = cfg->cfg_type;\n+\t\tdb[i].hcapi_type = cfg->hcapi_type;\n+\n+\t\t/* Save the parent subtype for later use to find the pool\n+\t\t */\n+\t\tif (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD)\n+\t\t\tdb[i].parent_subtype = cfg->parent_subtype;\n+\n+\t\t/* If the element didn't request an allocation no need\n+\t\t * to create a pool nor verify if we got a reservation.\n+\t\t */\n+\t\tif (req_cnt[i] == 0)\n+\t\t\tcontinue;\n+\n+\t\t/* Skip any children or invalid\n+\t\t */\n+\t\tif (cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI &&\n+\t\t    cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI_BA &&\n+\t\t    cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI_BA_PARENT)\n+\t\t\tcontinue;\n+\n+\t\t/* If the element had requested an allocation and that\n+\t\t * allocation was a success (full amount) then\n+\t\t * allocate the pool.\n+\t\t */\n+\t\tif (req_cnt[i] == resv[j].stride) {\n+\t\t\tdb[i].alloc.entry.start = resv[j].start;\n+\t\t\tdb[i].alloc.entry.stride = resv[j].stride;\n+\n+\t\t\t/* Only allocate BA pool if a BA type not a child */\n+\t\t\tif (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA ||\n+\t\t\t    cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_PARENT) {\n+\t\t\t\tif (cfg->divider) {\n+\t\t\t\t\tresv[j].stride =\n+\t\t\t\t\t\tresv[j].stride / cfg->divider;\n+\t\t\t\t\tif (resv[j].stride <= 0) {\n+\t\t\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t\t\t     \"%s:Divide fails:%d:%s\\n\",\n+\t\t\t\t\t\t     tf_dir_2_str(parms->dir),\n+\t\t\t\t\t\t     cfg->hcapi_type, type_str);\n+\t\t\t\t\t\tgoto fail;\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\t/* Create pool */\n+\t\t\t\tpool_size = (BITALLOC_SIZEOF(resv[j].stride) /\n+\t\t\t\t\t     sizeof(struct bitalloc));\n+\t\t\t\t/* Alloc request, alignment already set */\n+\t\t\t\tcparms.nitems = pool_size;\n+\t\t\t\tcparms.size = sizeof(struct bitalloc);\n+\t\t\t\trc = tfp_calloc(&cparms);\n+\t\t\t\tif (rc) {\n+\t\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t\t \"%s: Pool alloc failed, type:%d:%s\\n\",\n+\t\t\t\t\t tf_dir_2_str(parms->dir),\n+\t\t\t\t\t cfg->hcapi_type, type_str);\n+\t\t\t\t\tgoto fail;\n+\t\t\t\t}\n+\t\t\t\tdb[i].pool = (struct bitalloc *)cparms.mem_va;\n+\n+\t\t\t\trc = ba_init(db[i].pool,\n+\t\t\t\t\t     resv[j].stride,\n+\t\t\t\t\t     !tf_session_is_shared_session(tfs));\n+\t\t\t\tif (rc) {\n+\t\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t\t  \"%s: Pool init failed, type:%d:%s\\n\",\n+\t\t\t\t\t  tf_dir_2_str(parms->dir),\n+\t\t\t\t\t  cfg->hcapi_type, type_str);\n+\t\t\t\t\tgoto fail;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tj++;\n+\t\t} else {\n+\t\t\t/* Bail out as we want what we requested for\n+\t\t\t * all elements, not any less.\n+\t\t\t */\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"%s: Alloc failed %d:%s req:%d, alloc:%d\\n\",\n+\t\t\t\t    tf_dir_2_str(parms->dir), cfg->hcapi_type,\n+\t\t\t\t    type_str, req_cnt[i], resv[j].stride);\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\trm_db->num_entries = parms->num_elements;\n+\trm_db->dir = parms->dir;\n+\trm_db->module = parms->module;\n+\t*parms->rm_db = (void *)rm_db;\n+\n+\ttfp_free((void *)req);\n+\ttfp_free((void *)resv);\n+\ttfp_free((void *)req_cnt);\n+\treturn 0;\n+\n+ fail:\n+\ttfp_free((void *)req);\n+\ttfp_free((void *)resv);\n+\ttfp_free((void *)db->pool);\n+\ttfp_free((void *)db);\n+\ttfp_free((void *)rm_db);\n+\ttfp_free((void *)req_cnt);\n+\tparms->rm_db = NULL;\n+\n+\treturn -EINVAL;\n+}\n int\n tf_rm_free_db(struct tf *tfp,\n \t      struct tf_rm_free_db_parms *parms)\n@@ -1043,6 +1288,36 @@ tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms)\n \treturn 0;\n }\n \n+int\n+tf_rm_get_all_info(struct tf_rm_get_alloc_info_parms *parms, int size)\n+{\n+\tstruct tf_rm_new_db *rm_db;\n+\tenum tf_rm_elem_cfg_type cfg_type;\n+\tstruct tf_rm_alloc_info *info = parms->info;\n+\tint i;\n+\n+\tTF_CHECK_PARMS2(parms, parms->rm_db);\n+\trm_db = (struct tf_rm_new_db *)parms->rm_db;\n+\tTF_CHECK_PARMS1(rm_db->db);\n+\n+\tfor (i = 0; i < size; i++) {\n+\t\tcfg_type = rm_db->db[i].cfg_type;\n+\n+\t\t/* Bail out if not controlled by HCAPI */\n+\t\tif (cfg_type == TF_RM_ELEM_CFG_NULL) {\n+\t\t\tinfo++;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tmemcpy(info,\n+\t\t       &rm_db->db[i].alloc,\n+\t\t       sizeof(struct tf_rm_alloc_info));\n+\t\tinfo++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n int\n tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms)\n {\ndiff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h\nindex 6eb6865dac..8b984112e8 100644\n--- a/drivers/net/bnxt/tf_core/tf_rm.h\n+++ b/drivers/net/bnxt/tf_core/tf_rm.h\n@@ -425,6 +425,24 @@ struct tf_rm_check_indexes_in_range_parms {\n int tf_rm_create_db(struct tf *tfp,\n \t\t    struct tf_rm_create_db_parms *parms);\n \n+/**\n+ * Creates and fills a Resource Manager (RM) DB with requested\n+ * elements. The DB is indexed per the parms structure. It only retrieve\n+ * allocated resource information for a exist session.\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle, used for HCAPI communication\n+ *\n+ * [in] parms\n+ *   Pointer to create parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_rm_create_db_no_reservation(struct tf *tfp,\n+\t\t    struct tf_rm_create_db_parms *parms);\n+\n /**\n  * Closes the Resource Manager (RM) DB and frees all allocated\n  * resources per the associated database.\n@@ -498,6 +516,22 @@ int tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms);\n  */\n int tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms);\n \n+/**\n+ * Retrieves all elements allocation information from the Resource\n+ * Manager (RM) DB.\n+ *\n+ * [in] parms\n+ *   Pointer to get info parameters\n+ *\n+ * [in] size\n+ *   number of the elements for the specific module\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_rm_get_all_info(struct tf_rm_get_alloc_info_parms *parms, int size);\n+\n /**\n  * Performs a lookup in the Resource Manager DB and retrieves the\n  * requested HCAPI RM type.\ndiff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c\nindex f591fbe3f5..391d8786ab 100644\n--- a/drivers/net/bnxt/tf_core/tf_session.c\n+++ b/drivers/net/bnxt/tf_core/tf_session.c\n@@ -11,6 +11,7 @@\n #include \"tf_common.h\"\n #include \"tf_msg.h\"\n #include \"tfp.h\"\n+#include \"bnxt.h\"\n \n struct tf_session_client_create_parms {\n \t/**\n@@ -57,6 +58,7 @@ tf_session_create(struct tf *tfp,\n \tuint8_t fw_session_client_id;\n \tunion tf_session_id *session_id;\n \tstruct tf_dev_info dev;\n+\tbool shared_session_creator;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n@@ -64,11 +66,12 @@ tf_session_create(struct tf *tfp,\n \t\t\t&dev);\n \n \t/* Open FW session and get a new session_id */\n-\trc = tf_msg_session_open(tfp,\n+\trc = tf_msg_session_open(parms->open_cfg->bp,\n \t\t\t\t parms->open_cfg->ctrl_chan_name,\n \t\t\t\t &fw_session_id,\n \t\t\t\t &fw_session_client_id,\n-\t\t\t\t &dev);\n+\t\t\t\t &dev,\n+\t\t\t\t &shared_session_creator);\n \tif (rc) {\n \t\t/* Log error */\n \t\tif (rc == -EEXIST)\n@@ -137,6 +140,7 @@ tf_session_create(struct tf *tfp,\n \tsession_id->id = session->session_id.id;\n \n \tsession->shadow_copy = parms->open_cfg->shadow_copy;\n+\tsession->bp = parms->open_cfg->bp;\n \n \t/* Init session client list */\n \tll_init(&session->client_ll);\n@@ -175,12 +179,20 @@ tf_session_create(struct tf *tfp,\n \n \t/* Init session em_ext_db */\n \tsession->em_ext_db_handle = NULL;\n+\tif (!strcmp(parms->open_cfg->ctrl_chan_name, \"tf_share\"))\n+\t\tsession->shared_session = true;\n+\n+\tif (session->shared_session && shared_session_creator) {\n+\t\tsession->shared_session_creator = true;\n+\t\tparms->open_cfg->shared_session_creator = true;\n+\t}\n \n \trc = tf_dev_bind(tfp,\n \t\t\t parms->open_cfg->device_type,\n \t\t\t session->shadow_copy,\n \t\t\t &parms->open_cfg->resources,\n \t\t\t &session->dev);\n+\n \t/* Logging handled by dev_bind */\n \tif (rc)\n \t\tgoto cleanup;\n@@ -857,16 +869,29 @@ tf_session_get_db(struct tf *tfp,\n \n \tswitch (type) {\n \tcase TF_MODULE_TYPE_IDENTIFIER:\n-\t\t*db_handle = tfs->id_db_handle;\n+\t\tif (tfs->id_db_handle)\n+\t\t\t*db_handle = tfs->id_db_handle;\n+\t\telse\n+\t\t\trc = -EINVAL;\n \t\tbreak;\n \tcase TF_MODULE_TYPE_TABLE:\n-\t\t*db_handle = tfs->tbl_db_handle;\n+\t\tif (tfs->tbl_db_handle)\n+\t\t\t*db_handle = tfs->tbl_db_handle;\n+\t\telse\n+\t\t\trc = -EINVAL;\n+\n \t\tbreak;\n \tcase TF_MODULE_TYPE_TCAM:\n-\t\t*db_handle = tfs->tcam_db_handle;\n+\t\tif (tfs->tcam_db_handle)\n+\t\t\t*db_handle = tfs->tcam_db_handle;\n+\t\telse\n+\t\t\trc = -EINVAL;\n \t\tbreak;\n \tcase TF_MODULE_TYPE_EM:\n-\t\t*db_handle = tfs->em_db_handle;\n+\t\tif (tfs->em_db_handle)\n+\t\t\t*db_handle = tfs->em_db_handle;\n+\t\telse\n+\t\t\trc = -EINVAL;\n \t\tbreak;\n \tdefault:\n \t\trc = -EINVAL;\ndiff --git a/drivers/net/bnxt/tf_core/tf_session.h b/drivers/net/bnxt/tf_core/tf_session.h\nindex e5c7a07daf..0b8f63c374 100644\n--- a/drivers/net/bnxt/tf_core/tf_session.h\n+++ b/drivers/net/bnxt/tf_core/tf_session.h\n@@ -70,6 +70,23 @@ struct tf_session {\n \t */\n \tunion tf_session_id session_id;\n \n+\t/**\n+\t * Boolean controlling the use and availability of shared session.\n+\t * Shared session will allow the application to share resources\n+\t * on the firmware side without having to allocate them on firmware.\n+\t * Additional private session core_data will be allocated if this\n+\t * boolean is set to 'true', default 'false'.\n+\t *\n+\t */\n+\tbool shared_session;\n+\n+\t/**\n+\t * This flag indicates the shared session on firmware side is created\n+\t * by this session. Some privileges may be assigned to this session.\n+\t *\n+\t */\n+\tbool shared_session_creator;\n+\n \t/**\n \t * Boolean controlling the use and availability of shadow\n \t * copy. Shadow copy will allow the TruFlow Core to keep track\n@@ -137,6 +154,11 @@ struct tf_session {\n \t * em db reference for the session\n \t */\n \tvoid *em_db_handle;\n+\n+\t/**\n+\t * the pointer to the parent bp struct\n+\t */\n+\tvoid *bp;\n };\n \n /**\n@@ -500,4 +522,48 @@ int\n tf_session_set_db(struct tf *tfp,\n \t\t   enum tf_module_type type,\n \t\t  void *db_handle);\n+\n+/**\n+ * Check if the session is shared session.\n+ *\n+ * [in] session, pointer to the session\n+ *\n+ * Returns:\n+ *   - true if it is shared session\n+ *   - false if it is not shared session\n+ */\n+static inline bool\n+tf_session_is_shared_session(struct tf_session *tfs)\n+{\n+\treturn tfs->shared_session;\n+}\n+\n+/**\n+ * Check if the session is the shared session creator\n+ *\n+ * [in] session, pointer to the session\n+ *\n+ * Returns:\n+ *   - true if it is the shared session creator\n+ *   - false if it is not the shared session creator\n+ */\n+static inline bool\n+tf_session_is_shared_session_creator(struct tf_session *tfs)\n+{\n+\treturn tfs->shared_session_creator;\n+}\n+\n+/**\n+ * Get the pointer to the parent bnxt struct\n+ *\n+ * [in] session, pointer to the session\n+ *\n+ * Returns:\n+ *   - the pointer to the parent bnxt struct\n+ */\n+static inline struct bnxt*\n+tf_session_get_bp(struct tf_session *tfs)\n+{\n+\treturn tfs->bp;\n+}\n #endif /* _TF_SESSION_H_ */\ndiff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c\nindex 2d0dda18c9..17fb550917 100644\n--- a/drivers/net/bnxt/tf_core/tf_tbl.c\n+++ b/drivers/net/bnxt/tf_core/tf_tbl.c\n@@ -31,11 +31,6 @@ struct tf;\n  */\n static void *shadow_tbl_db[TF_DIR_MAX];\n \n-/**\n- * Init flag, set on bind and cleared on unbind\n- */\n-static uint8_t init;\n-\n /**\n  * Shadow init flag, set on bind and cleared on unbind\n  */\n@@ -49,14 +44,14 @@ tf_tbl_bind(struct tf *tfp,\n \tstruct tf_rm_create_db_parms db_cfg = { 0 };\n \tstruct tbl_rm_db *tbl_db;\n \tstruct tfp_calloc_parms cparms;\n+\tstruct tf_session *tfs;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"Table DB already initialized\\n\");\n-\t\treturn -EINVAL;\n-\t}\n+\t/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n \n \tmemset(&db_cfg, 0, sizeof(db_cfg));\n \tcparms.nitems = 1;\n@@ -82,8 +77,11 @@ tf_tbl_bind(struct tf *tfp,\n \t\tdb_cfg.dir = d;\n \t\tdb_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;\n \t\tdb_cfg.rm_db = (void *)&tbl_db->tbl_db[d];\n-\n-\t\trc = tf_rm_create_db(tfp, &db_cfg);\n+\t\tif (tf_session_is_shared_session(tfs) &&\n+\t\t\t(!tf_session_is_shared_session_creator(tfs)))\n+\t\t\trc = tf_rm_create_db_no_reservation(tfp, &db_cfg);\n+\t\telse\n+\t\t\trc = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t    \"%s: Table DB creation failed\\n\",\n@@ -92,7 +90,6 @@ tf_tbl_bind(struct tf *tfp,\n \t\t\treturn rc;\n \t\t}\n \t}\n-\tinit = 1;\n \n \tTFP_DRV_LOG(INFO,\n \t\t    \"Table Type - initialized\\n\");\n@@ -110,13 +107,6 @@ tf_tbl_unbind(struct tf *tfp)\n \tvoid *tbl_db_ptr = NULL;\n \tTF_CHECK_PARMS1(tfp);\n \n-\t/* Bail if nothing has been initialized */\n-\tif (!init) {\n-\t\tTFP_DRV_LOG(INFO,\n-\t\t\t    \"No Table DBs created\\n\");\n-\t\treturn 0;\n-\t}\n-\n \trc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR,\n@@ -136,7 +126,6 @@ tf_tbl_unbind(struct tf *tfp)\n \t\ttbl_db->tbl_db[i] = NULL;\n \t}\n \n-\tinit = 0;\n \tshadow_init = 0;\n \n \treturn 0;\n@@ -157,13 +146,6 @@ tf_tbl_alloc(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Table DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -234,12 +216,6 @@ tf_tbl_free(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Table DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -346,13 +322,6 @@ tf_tbl_set(struct tf *tfp,\n \n \tTF_CHECK_PARMS3(tfp, parms, parms->data);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Table DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -456,14 +425,6 @@ tf_tbl_get(struct tf *tfp,\n \n \tTF_CHECK_PARMS3(tfp, parms, parms->data);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Table DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -567,14 +528,6 @@ tf_tbl_bulk_get(struct tf *tfp,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No Table DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -662,3 +615,40 @@ tf_tbl_bulk_get(struct tf *tfp,\n \n \treturn rc;\n }\n+\n+int\n+tf_tbl_get_resc_info(struct tf *tfp,\n+\t\t     struct tf_tbl_resource_info *tbl)\n+{\n+\tint rc;\n+\tint d;\n+\tstruct tf_resource_info *dinfo;\n+\tstruct tf_rm_get_alloc_info_parms ainfo;\n+\tvoid *tbl_db_ptr = NULL;\n+\tstruct tbl_rm_db *tbl_db;\n+\n+\tTF_CHECK_PARMS2(tfp, tbl);\n+\n+\trc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to get em_ext_db from session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\ttbl_db = (struct tbl_rm_db *)tbl_db_ptr;\n+\n+\t/* check if reserved resource for WC is multiple of num_slices */\n+\tfor (d = 0; d < TF_DIR_MAX; d++) {\n+\t\tainfo.rm_db = tbl_db->tbl_db[d];\n+\t\tdinfo = tbl[d].info;\n+\n+\t\tainfo.info = (struct tf_rm_alloc_info *)dinfo;\n+\t\tainfo.subtype = 0;\n+\t\trc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_core/tf_tbl.h b/drivers/net/bnxt/tf_core/tf_tbl.h\nindex 83b72d1b3f..aba46fd161 100644\n--- a/drivers/net/bnxt/tf_core/tf_tbl.h\n+++ b/drivers/net/bnxt/tf_core/tf_tbl.h\n@@ -396,4 +396,21 @@ int tf_tbl_get(struct tf *tfp,\n int tf_tbl_bulk_get(struct tf *tfp,\n \t\t    struct tf_tbl_get_bulk_parms *parms);\n \n+/**\n+ * Retrieves the allocated resource info\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle, used for HCAPI communication\n+ *\n+ * [in] parms\n+ *   Pointer to Table resource info parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int\n+tf_tbl_get_resc_info(struct tf *tfp,\n+\t\t     struct tf_tbl_resource_info *tbl);\n+\n #endif /* TF_TBL_TYPE_H */\ndiff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c\nindex c2eef26dbb..70dc539f15 100644\n--- a/drivers/net/bnxt/tf_core/tf_tcam.c\n+++ b/drivers/net/bnxt/tf_core/tf_tcam.c\n@@ -23,11 +23,6 @@ struct tf;\n  */\n static void *shadow_tcam_db[TF_DIR_MAX];\n \n-/**\n- * Init flag, set on bind and cleared on unbind\n- */\n-static uint8_t init;\n-\n /**\n  * Shadow init flag, set on bind and cleared on unbind\n  */\n@@ -55,12 +50,6 @@ tf_tcam_bind(struct tf *tfp,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"TCAM DB already initialized\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -118,7 +107,11 @@ tf_tcam_bind(struct tf *tfp,\n \t\tdb_cfg.dir = d;\n \t\tdb_cfg.alloc_cnt = parms->resources->tcam_cnt[d].cnt;\n \t\tdb_cfg.rm_db = (void *)&tcam_db->tcam_db[d];\n-\t\trc = tf_rm_create_db(tfp, &db_cfg);\n+\t\tif (tf_session_is_shared_session(tfs) &&\n+\t\t\t(!tf_session_is_shared_session_creator(tfs)))\n+\t\t\trc = tf_rm_create_db_no_reservation(tfp, &db_cfg);\n+\t\telse\n+\t\t\trc = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t    \"%s: TCAM DB creation failed\\n\",\n@@ -143,7 +136,8 @@ tf_tcam_bind(struct tf *tfp,\n \t\t\t\t    \"%s: TCAM reserved resource is not multiple of %d\\n\",\n \t\t\t\t    tf_dir_2_str(d),\n \t\t\t\t    num_slices);\n-\t\t\treturn -EINVAL;\n+\t\t\trc = -EINVAL;\n+\t\t\tgoto error;\n \t\t}\n \t}\n \n@@ -186,8 +180,6 @@ tf_tcam_bind(struct tf *tfp,\n \t\tshadow_init = 1;\n \t}\n \n-\tinit = 1;\n-\n \tTFP_DRV_LOG(INFO,\n \t\t    \"TCAM - initialized\\n\");\n \n@@ -211,7 +203,6 @@ tf_tcam_bind(struct tf *tfp,\n \t}\n \n \tshadow_init = 0;\n-\tinit = 0;\n \n \treturn rc;\n }\n@@ -227,13 +218,6 @@ tf_tcam_unbind(struct tf *tfp)\n \tstruct tf_shadow_tcam_free_db_parms fshadow;\n \tTF_CHECK_PARMS1(tfp);\n \n-\t/* Bail if nothing has been initialized */\n-\tif (!init) {\n-\t\tTFP_DRV_LOG(INFO,\n-\t\t\t    \"No TCAM DBs created\\n\");\n-\t\treturn 0;\n-\t}\n-\n \trc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR,\n@@ -263,7 +247,6 @@ tf_tcam_unbind(struct tf *tfp)\n \t}\n \n \tshadow_init = 0;\n-\tinit = 0;\n \n \treturn 0;\n }\n@@ -283,13 +266,6 @@ tf_tcam_alloc(struct tf *tfp,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No TCAM DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -372,13 +348,6 @@ tf_tcam_free(struct tf *tfp,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No TCAM DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -529,13 +498,6 @@ tf_tcam_alloc_search(struct tf *tfp,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No TCAM DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \tif (!shadow_init || !shadow_tcam_db[parms->dir]) {\n \t\tTFP_DRV_LOG(ERR, \"%s: TCAM Shadow not initialized for %s\\n\",\n \t\t\t    tf_dir_2_str(parms->dir),\n@@ -660,13 +622,6 @@ tf_tcam_set(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No TCAM DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -781,13 +736,6 @@ tf_tcam_get(struct tf *tfp __rte_unused,\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n-\tif (!init) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s: No TCAM DBs created\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Retrieve the session information */\n \trc = tf_session_get_session_internal(tfp, &tfs);\n \tif (rc)\n@@ -852,3 +800,40 @@ tf_tcam_get(struct tf *tfp __rte_unused,\n \n \treturn 0;\n }\n+\n+int\n+tf_tcam_get_resc_info(struct tf *tfp,\n+\t\t      struct tf_tcam_resource_info *tcam)\n+{\n+\tint rc;\n+\tint d;\n+\tstruct tf_resource_info *dinfo;\n+\tstruct tf_rm_get_alloc_info_parms ainfo;\n+\tvoid *tcam_db_ptr = NULL;\n+\tstruct tcam_rm_db *tcam_db;\n+\n+\tTF_CHECK_PARMS2(tfp, tcam);\n+\n+\trc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to get em_ext_db from session, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\ttcam_db = (struct tcam_rm_db *)tcam_db_ptr;\n+\n+\t/* check if reserved resource for WC is multiple of num_slices */\n+\tfor (d = 0; d < TF_DIR_MAX; d++) {\n+\t\tainfo.rm_db = tcam_db->tcam_db[d];\n+\t\tdinfo = tcam[d].info;\n+\n+\t\tainfo.info = (struct tf_rm_alloc_info *)dinfo;\n+\t\tainfo.subtype = 0;\n+\t\trc = tf_rm_get_all_info(&ainfo, TF_TCAM_TBL_TYPE_MAX);\n+\t\tif (rc && rc != -ENOTSUP)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h\nindex acab223532..bed17af6ae 100644\n--- a/drivers/net/bnxt/tf_core/tf_tcam.h\n+++ b/drivers/net/bnxt/tf_core/tf_tcam.h\n@@ -386,4 +386,20 @@ int tf_tcam_set(struct tf *tfp,\n int tf_tcam_get(struct tf *tfp,\n \t\tstruct tf_tcam_get_parms *parms);\n \n+/**\n+ * Retrieves the allocated resource info\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle, used for HCAPI communication\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_get_resc_info(struct tf *tfp,\n+\t\t\t  struct tf_tcam_resource_info *parms);\n+\n #endif /* _TF_TCAM_H */\ndiff --git a/drivers/net/bnxt/tf_core/tfp.c b/drivers/net/bnxt/tf_core/tfp.c\nindex 37c49b587d..4d9b37f749 100644\n--- a/drivers/net/bnxt/tf_core/tfp.c\n+++ b/drivers/net/bnxt/tf_core/tfp.c\n@@ -28,7 +28,7 @@\n  * Returns success or failure code.\n  */\n int\n-tfp_send_msg_direct(struct tf *tfp,\n+tfp_send_msg_direct(struct bnxt *bp,\n \t\t    struct tfp_send_msg_parms *parms)\n {\n \tint      rc = 0;\n@@ -40,9 +40,7 @@ tfp_send_msg_direct(struct tf *tfp,\n \tif (parms->mailbox == TF_CHIMP_MB)\n \t\tuse_kong_mb = 0;\n \n-\trc = bnxt_hwrm_tf_message_direct(container_of(tfp,\n-\t\t\t\t\t       struct bnxt,\n-\t\t\t\t\t       tfp),\n+\trc = bnxt_hwrm_tf_message_direct(bp,\n \t\t\t\t\t use_kong_mb,\n \t\t\t\t\t parms->tf_type,\n \t\t\t\t\t parms->req_data,\ndiff --git a/drivers/net/bnxt/tf_core/tfp.h b/drivers/net/bnxt/tf_core/tfp.h\nindex bcc56b0a54..58f34bbcab 100644\n--- a/drivers/net/bnxt/tf_core/tfp.h\n+++ b/drivers/net/bnxt/tf_core/tfp.h\n@@ -15,6 +15,7 @@\n #include <rte_spinlock.h>\n #include <rte_log.h>\n #include <rte_byteorder.h>\n+#include <bnxt.h>\n \n /**\n  * DPDK/Driver specific log level for the BNXT Eth driver.\n@@ -130,7 +131,7 @@ struct tfp_calloc_parms {\n  *   -1             - Global error like not supported\n  *   -EINVAL        - Parameter Error\n  */\n-int tfp_send_msg_direct(struct tf *tfp,\n+int tfp_send_msg_direct(struct bnxt *bp,\n \t\t\tstruct tfp_send_msg_parms *parms);\n \n /**\n",
    "prefixes": [
        "14/58"
    ]
}