get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 71423,
    "url": "http://patches.dpdk.org/api/patches/71423/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200612132934.16488-32-somnath.kotur@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": "<20200612132934.16488-32-somnath.kotur@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200612132934.16488-32-somnath.kotur@broadcom.com",
    "date": "2020-06-12T13:29:15",
    "name": "[31/50] net/bnxt: add support for EEM System memory",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8424bd439ae712f65fb6a8f873d4a244f5ea1317",
    "submitter": {
        "id": 908,
        "url": "http://patches.dpdk.org/api/people/908/?format=api",
        "name": "Somnath Kotur",
        "email": "somnath.kotur@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/20200612132934.16488-32-somnath.kotur@broadcom.com/mbox/",
    "series": [
        {
            "id": 10436,
            "url": "http://patches.dpdk.org/api/series/10436/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=10436",
            "date": "2020-06-12T13:28:44",
            "name": "add features for host-based flow management",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/10436/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/71423/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/71423/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 614B6A00BE;\n\tFri, 12 Jun 2020 15:47:45 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id CBA9C1C1E1;\n\tFri, 12 Jun 2020 15:34:50 +0200 (CEST)",
            "from relay.smtp.broadcom.com (relay.smtp.broadcom.com\n [192.19.232.149]) by dpdk.org (Postfix) with ESMTP id 8637D1C1B2\n for <dev@dpdk.org>; Fri, 12 Jun 2020 15:34:46 +0200 (CEST)",
            "from dhcp-10-123-153-55.dhcp.broadcom.net\n (dhcp-10-123-153-55.dhcp.broadcom.net [10.123.153.55])\n by relay.smtp.broadcom.com (Postfix) with ESMTP id 5AFFC1BD7AC;\n Fri, 12 Jun 2020 06:34:45 -0700 (PDT)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.10.3 relay.smtp.broadcom.com 5AFFC1BD7AC",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com;\n s=dkimrelay; t=1591968886;\n bh=tgWza4l4HbmKHqOV+fmY4yJzQeym3oENdesFk8sP1lY=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n b=MDaBAjYNyrBZWKtxLg5hGznpgb3c5XP7z56VqN6mMfPKhpoaCNVlTbcMAdd+CP/92\n Yub6hYDVKdACWz2QU4LXT6N5ruTh8Zyin3LLFoj4Eid3TL/voc84J1XN9haVufDZZy\n 52202OD/EOFdbn/KXrLlXA/GmyHq7wWtyXj2V8fo=",
        "From": "Somnath Kotur <somnath.kotur@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com",
        "Date": "Fri, 12 Jun 2020 18:59:15 +0530",
        "Message-Id": "<20200612132934.16488-32-somnath.kotur@broadcom.com>",
        "X-Mailer": "git-send-email 2.10.1.613.g2cc2e70",
        "In-Reply-To": "<20200612132934.16488-1-somnath.kotur@broadcom.com>",
        "References": "<20200612132934.16488-1-somnath.kotur@broadcom.com>",
        "Subject": "[dpdk-dev] [PATCH 31/50] net/bnxt: add support for EEM System memory",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "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: Peter Spreadborough <peter.spreadborough@broadcom.com>\n\n- Select EEM Host or System memory via config parameter\n- Add EEM system memory support for kernel memory\n- Dependent on DPDK changes that add support for the HWRM_OEM_CMD.\n\nSigned-off-by: Peter Spreadborough <peter.spreadborough@broadcom.com>\nReviewed-by: Randy Schacher <stuart.schacher@broadcom.com>\nSigned-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>\n---\n config/common_base                      |   1 +\n drivers/net/bnxt/Makefile               |   3 +\n drivers/net/bnxt/bnxt.h                 |   8 +\n drivers/net/bnxt/bnxt_hwrm.c            |  27 ++\n drivers/net/bnxt/bnxt_hwrm.h            |   1 +\n drivers/net/bnxt/meson.build            |   2 +-\n drivers/net/bnxt/tf_core/Makefile       |   5 +-\n drivers/net/bnxt/tf_core/tf_core.c      |  13 +-\n drivers/net/bnxt/tf_core/tf_core.h      |   4 +-\n drivers/net/bnxt/tf_core/tf_device.c    |   5 +-\n drivers/net/bnxt/tf_core/tf_device_p4.c |   2 +-\n drivers/net/bnxt/tf_core/tf_em.h        | 113 +-----\n drivers/net/bnxt/tf_core/tf_em_common.c | 685 ++++++++++++++++++++++++++++++-\n drivers/net/bnxt/tf_core/tf_em_common.h |  30 ++\n drivers/net/bnxt/tf_core/tf_em_host.c   | 693 +-------------------------------\n drivers/net/bnxt/tf_core/tf_em_system.c | 546 ++++++++++++++++++++++---\n drivers/net/bnxt/tf_core/tf_if_tbl.h    |   4 +-\n drivers/net/bnxt/tf_core/tf_msg.c       |  24 ++\n drivers/net/bnxt/tf_core/tf_tbl.h       |   7 +\n drivers/net/bnxt/tf_core/tfp.c          |  12 +\n drivers/net/bnxt/tf_core/tfp.h          |  15 +\n 21 files changed, 1327 insertions(+), 873 deletions(-)",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex c7d5c73..ccd03aa 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -220,6 +220,7 @@ CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n\n # Compile burst-oriented Broadcom BNXT PMD driver\n #\n CONFIG_RTE_LIBRTE_BNXT_PMD=y\n+CONFIG_RTE_LIBRTE_BNXT_PMD_SYSTEM=n\n \n #\n # Compile burst-oriented Chelsio Terminator (CXGBE) PMD\ndiff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile\nindex 349b09c..6b9544b 100644\n--- a/drivers/net/bnxt/Makefile\n+++ b/drivers/net/bnxt/Makefile\n@@ -50,6 +50,9 @@ CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/tf_ulp -I$(SRCDIR)/tf_core -I$(SRCDIR)/hcapi\n include $(SRCDIR)/tf_ulp/Makefile\n include $(SRCDIR)/tf_core/Makefile\n include $(SRCDIR)/hcapi/Makefile\n+ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD_SYSTEM), y)\n+CFLAGS += -DTF_USE_SYSTEM_MEM\n+endif\n endif\n \n #\ndiff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h\nindex 65862ab..43e5e71 100644\n--- a/drivers/net/bnxt/bnxt.h\n+++ b/drivers/net/bnxt/bnxt.h\n@@ -563,6 +563,13 @@ struct bnxt_rep_info {\n \t\t\t\t     DEV_RX_OFFLOAD_SCATTER | \\\n \t\t\t\t     DEV_RX_OFFLOAD_RSS_HASH)\n \n+#define  MAX_TABLE_SUPPORT 4\n+#define  MAX_DIR_SUPPORT   2\n+struct bnxt_dmabuf_info {\n+\tuint32_t entry_num;\n+\tint      fd[MAX_DIR_SUPPORT][MAX_TABLE_SUPPORT];\n+};\n+\n #define BNXT_HWRM_SHORT_REQ_LEN\t\tsizeof(struct hwrm_short_input)\n \n struct bnxt_flow_stat_info {\n@@ -780,6 +787,7 @@ struct bnxt {\n \tuint16_t\t\tport_svif;\n \n \tstruct tf\t\ttfp;\n+\tstruct bnxt_dmabuf_info dmabuf;\n \tstruct bnxt_ulp_context\t*ulp_ctx;\n \tstruct bnxt_flow_stat_info *flow_stat;\n \tuint8_t\t\t\tflow_xstat;\ndiff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c\nindex e6a28d0..2605ef0 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.c\n+++ b/drivers/net/bnxt/bnxt_hwrm.c\n@@ -5506,3 +5506,30 @@ int bnxt_hwrm_cfa_counter_qstats(struct bnxt *bp,\n \n \treturn 0;\n }\n+\n+#ifdef RTE_LIBRTE_BNXT_PMD_SYSTEM\n+int\n+bnxt_hwrm_oem_cmd(struct bnxt *bp, uint32_t entry_num)\n+{\n+\tstruct hwrm_oem_cmd_input req = {0};\n+\tstruct hwrm_oem_cmd_output *resp = bp->hwrm_cmd_resp_addr;\n+\tstruct bnxt_dmabuf_info oem_data;\n+\tint rc = 0;\n+\n+\tHWRM_PREP(&req, HWRM_OEM_CMD, BNXT_USE_CHIMP_MB);\n+\treq.IANA = 0x14e4;\n+\n+\tmemset(&oem_data, 0, sizeof(struct bnxt_dmabuf_info));\n+\toem_data.entry_num = (entry_num);\n+\tmemcpy(&req.oem_data[0], &oem_data, sizeof(struct bnxt_dmabuf_info));\n+\n+\trc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);\n+\tHWRM_CHECK_RESULT();\n+\n+\tbp->dmabuf.entry_num = entry_num;\n+\n+\tHWRM_UNLOCK();\n+\n+\treturn rc;\n+}\n+#endif /* RTE_LIBRTE_BNXT_PMD_SYSTEM */\ndiff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h\nindex 87cd407..9e0b799 100644\n--- a/drivers/net/bnxt/bnxt_hwrm.h\n+++ b/drivers/net/bnxt/bnxt_hwrm.h\n@@ -276,4 +276,5 @@ int bnxt_hwrm_get_dflt_vnic_svif(struct bnxt *bp, uint16_t fid,\n \t\t\t\t uint16_t *vnic_id, uint16_t *svif);\n int bnxt_hwrm_parent_pf_qcfg(struct bnxt *bp);\n int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp);\n+int bnxt_hwrm_oem_cmd(struct bnxt *bp, uint32_t entry_num);\n #endif\ndiff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build\nindex ace7353..8f6ed41 100644\n--- a/drivers/net/bnxt/meson.build\n+++ b/drivers/net/bnxt/meson.build\n@@ -31,7 +31,6 @@ sources = files('bnxt_cpr.c',\n         'tf_core/tf_em_common.c',\n         'tf_core/tf_em_host.c',\n         'tf_core/tf_em_internal.c',\n-        'tf_core/tf_em_system.c',\n \t'tf_core/tf_rm.c',\n \t'tf_core/tf_tbl.c',\n \t'tf_core/tfp.c',\n@@ -46,6 +45,7 @@ sources = files('bnxt_cpr.c',\n \t'tf_core/tf_if_tbl.c',\n \t'tf_core/ll.c',\n \t'tf_core/tf_global_cfg.c',\n+\t'tf_core/tf_em_host.c',\n \n \t'hcapi/hcapi_cfa_p4.c',\n \ndiff --git a/drivers/net/bnxt/tf_core/Makefile b/drivers/net/bnxt/tf_core/Makefile\nindex d9110ca..0493b55 100644\n--- a/drivers/net/bnxt/tf_core/Makefile\n+++ b/drivers/net/bnxt/tf_core/Makefile\n@@ -16,8 +16,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_msg.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tbl.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_common.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_internal.c\n+ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD_SYSTEM), n)\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_host.c\n-SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_system.c\n+else\n+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD_SYSTEM) += tf_core/tf_em_system.c\n+endif\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_session.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_device.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_device_p4.c\ndiff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c\nindex 0f119b4..00b2775 100644\n--- a/drivers/net/bnxt/tf_core/tf_core.c\n+++ b/drivers/net/bnxt/tf_core/tf_core.c\n@@ -540,10 +540,12 @@ tf_alloc_tcam_entry(struct tf *tfp,\n \tint rc;\n \tstruct tf_session *tfs;\n \tstruct tf_dev_info *dev;\n-\tstruct tf_tcam_alloc_parms aparms = { 0 };\n+\tstruct tf_tcam_alloc_parms aparms;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n+\tmemset(&aparms, 0, sizeof(struct tf_tcam_alloc_parms));\n+\n \t/* Retrieve the session information */\n \trc = tf_session_get_session(tfp, &tfs);\n \tif (rc) {\n@@ -598,10 +600,13 @@ tf_set_tcam_entry(struct tf *tfp,\n \tint rc;\n \tstruct tf_session *tfs;\n \tstruct tf_dev_info *dev;\n-\tstruct tf_tcam_set_parms sparms = { 0 };\n+\tstruct tf_tcam_set_parms sparms;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n+\tmemset(&sparms, 0, sizeof(struct tf_tcam_set_parms));\n+\n+\n \t/* Retrieve the session information */\n \trc = tf_session_get_session(tfp, &tfs);\n \tif (rc) {\n@@ -667,10 +672,12 @@ tf_free_tcam_entry(struct tf *tfp,\n \tint rc;\n \tstruct tf_session *tfs;\n \tstruct tf_dev_info *dev;\n-\tstruct tf_tcam_free_parms fparms = { 0 };\n+\tstruct tf_tcam_free_parms fparms;\n \n \tTF_CHECK_PARMS2(tfp, parms);\n \n+\tmemset(&fparms, 0, sizeof(struct tf_tcam_free_parms));\n+\n \t/* Retrieve the session information */\n \trc = tf_session_get_session(tfp, &tfs);\n \tif (rc) {\ndiff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h\nindex 3f54ab1..9e80426 100644\n--- a/drivers/net/bnxt/tf_core/tf_core.h\n+++ b/drivers/net/bnxt/tf_core/tf_core.h\n@@ -1731,7 +1731,7 @@ struct tf_set_if_tbl_entry_parms {\n \t/**\n \t * [in] Entry data\n \t */\n-\tuint32_t *data;\n+\tuint8_t *data;\n \t/**\n \t * [in] Entry size\n \t */\n@@ -1768,7 +1768,7 @@ struct tf_get_if_tbl_entry_parms {\n \t/**\n \t * [out] Entry data\n \t */\n-\tuint32_t *data;\n+\tuint8_t *data;\n \t/**\n \t * [in] Entry size\n \t */\ndiff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c\nindex ead9584..f08f7eb 100644\n--- a/drivers/net/bnxt/tf_core/tf_device.c\n+++ b/drivers/net/bnxt/tf_core/tf_device.c\n@@ -92,8 +92,11 @@ tf_dev_bind_p4(struct tf *tfp,\n \tem_cfg.num_elements = TF_EM_TBL_TYPE_MAX;\n \tem_cfg.cfg = tf_em_ext_p4;\n \tem_cfg.resources = resources;\n+#ifdef TF_USE_SYSTEM_MEM\n+\tem_cfg.mem_type = TF_EEM_MEM_TYPE_SYSTEM;\n+#else\n \tem_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;\n-\n+#endif\n \trc = tf_em_ext_common_bind(tfp, &em_cfg);\n \tif (rc) {\n \t\tTFP_DRV_LOG(ERR,\ndiff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c\nindex 6526082..dfe626c 100644\n--- a/drivers/net/bnxt/tf_core/tf_device_p4.c\n+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c\n@@ -126,7 +126,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = {\n \t.tf_dev_free_ext_tbl = tf_tbl_ext_free,\n \t.tf_dev_alloc_search_tbl = NULL,\n \t.tf_dev_set_tbl = tf_tbl_set,\n-\t.tf_dev_set_ext_tbl = tf_tbl_ext_set,\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_alloc_tcam = tf_tcam_alloc,\ndiff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h\nindex 1c2369c..45c0e11 100644\n--- a/drivers/net/bnxt/tf_core/tf_em.h\n+++ b/drivers/net/bnxt/tf_core/tf_em.h\n@@ -16,6 +16,9 @@\n \n #include \"hcapi/hcapi_cfa_defs.h\"\n \n+#define TF_EM_MIN_ENTRIES     (1 << 15) /* 32K */\n+#define TF_EM_MAX_ENTRIES     (1 << 27) /* 128M */\n+\n #define TF_HW_EM_KEY_MAX_SIZE 52\n #define TF_EM_KEY_RECORD_SIZE 64\n \n@@ -69,8 +72,16 @@\n #error \"Invalid Page Size specified. Please use a TF_EM_PAGE_SIZE_n define\"\n #endif\n \n+/*\n+ * System memory always uses 4K pages\n+ */\n+#ifdef TF_USE_SYSTEM_MEM\n+#define TF_EM_PAGE_SIZE (1 << TF_EM_PAGE_SIZE_4K)\n+#define TF_EM_PAGE_ALIGNMENT (1 << TF_EM_PAGE_SIZE_4K)\n+#else\n #define TF_EM_PAGE_SIZE\t(1 << TF_EM_PAGE_SHIFT)\n #define TF_EM_PAGE_ALIGNMENT (1 << TF_EM_PAGE_SHIFT)\n+#endif\n \n /*\n  * Used to build GFID:\n@@ -169,39 +180,6 @@ struct tf_em_cfg_parms {\n  */\n \n /**\n- * Allocates EEM Table scope\n- *\n- * [in] tfp\n- *   Pointer to TruFlow handle\n- *\n- * [in] parms\n- *   Pointer to input parameters\n- *\n- * Returns:\n- *   0       - Success\n- *   -EINVAL - Parameter error\n- *   -ENOMEM - Out of memory\n- */\n-int tf_alloc_eem_tbl_scope(struct tf *tfp,\n-\t\t\t   struct tf_alloc_tbl_scope_parms *parms);\n-\n-/**\n- * Free's EEM Table scope control block\n- *\n- * [in] tfp\n- *   Pointer to TruFlow handle\n- *\n- * [in] parms\n- *   Pointer to input parameters\n- *\n- * Returns:\n- *   0       - Success\n- *   -EINVAL - Parameter error\n- */\n-int tf_free_eem_tbl_scope_cb(struct tf *tfp,\n-\t\t\t     struct tf_free_tbl_scope_parms *parms);\n-\n-/**\n  * Insert record in to internal EM table\n  *\n  * [in] tfp\n@@ -374,8 +352,8 @@ int tf_em_ext_common_unbind(struct tf *tfp);\n  *   0       - Success\n  *   -EINVAL - Parameter error\n  */\n-int tf_em_ext_host_alloc(struct tf *tfp,\n-\t\t\t struct tf_alloc_tbl_scope_parms *parms);\n+int tf_em_ext_alloc(struct tf *tfp,\n+\t\t    struct tf_alloc_tbl_scope_parms *parms);\n \n /**\n  * Free for external EEM using host memory\n@@ -390,40 +368,8 @@ int tf_em_ext_host_alloc(struct tf *tfp,\n  *   0       - Success\n  *   -EINVAL - Parameter error\n  */\n-int tf_em_ext_host_free(struct tf *tfp,\n-\t\t\tstruct tf_free_tbl_scope_parms *parms);\n-\n-/**\n- * Alloc for external EEM using system memory\n- *\n- * [in] tfp\n- *   Pointer to TruFlow handle\n- *\n- * [in] parms\n- *   Pointer to input parameters\n- *\n- * Returns:\n- *   0       - Success\n- *   -EINVAL - Parameter error\n- */\n-int tf_em_ext_system_alloc(struct tf *tfp,\n-\t\t\t   struct tf_alloc_tbl_scope_parms *parms);\n-\n-/**\n- * Free for external EEM using system memory\n- *\n- * [in] tfp\n- *   Pointer to TruFlow handle\n- *\n- * [in] parms\n- *   Pointer to input parameters\n- *\n- * Returns:\n- *   0       - Success\n- *   -EINVAL - Parameter error\n- */\n-int tf_em_ext_system_free(struct tf *tfp,\n-\t\t\t  struct tf_free_tbl_scope_parms *parms);\n+int tf_em_ext_free(struct tf *tfp,\n+\t\t   struct tf_free_tbl_scope_parms *parms);\n \n /**\n  * Common free for external EEM using host or system memory\n@@ -510,8 +456,8 @@ tf_tbl_ext_free(struct tf *tfp,\n  *   - (0) if successful.\n  *   - (-EINVAL) on failure.\n  */\n-int tf_tbl_ext_set(struct tf *tfp,\n-\t\t   struct tf_tbl_set_parms *parms);\n+int tf_tbl_ext_common_set(struct tf *tfp,\n+\t\t\t  struct tf_tbl_set_parms *parms);\n \n /**\n  * Sets the specified external table type element.\n@@ -529,26 +475,11 @@ int tf_tbl_ext_set(struct tf *tfp,\n  *   - (0) if successful.\n  *   - (-EINVAL) on failure.\n  */\n-int tf_tbl_ext_host_set(struct tf *tfp,\n-\t\t\tstruct tf_tbl_set_parms *parms);\n+int tf_tbl_ext_set(struct tf *tfp,\n+\t\t   struct tf_tbl_set_parms *parms);\n \n-/**\n- * Sets the specified external table type element.\n- *\n- * This API sets the specified element data by invoking the\n- * firmware.\n- *\n- * [in] tfp\n- *   Pointer to TF handle\n- *\n- * [in] parms\n- *   Pointer to table set parameters\n- *\n- * Returns\n- *   - (0) if successful.\n- *   - (-EINVAL) on failure.\n- */\n-int tf_tbl_ext_system_set(struct tf *tfp,\n-\t\t\t  struct tf_tbl_set_parms *parms);\n+int\n+tf_em_ext_system_bind(struct tf *tfp,\n+\t\t      struct tf_em_cfg_parms *parms);\n \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 23a7fc9..3d903ff 100644\n--- a/drivers/net/bnxt/tf_core/tf_em_common.c\n+++ b/drivers/net/bnxt/tf_core/tf_em_common.c\n@@ -23,6 +23,8 @@\n \n #include \"bnxt.h\"\n \n+/* Number of pointers per page_size */\n+#define MAX_PAGE_PTRS(page_size)  ((page_size) / sizeof(void *))\n \n /**\n  * EM DBs.\n@@ -281,19 +283,604 @@ tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,\n \t\t       struct cfa_p4_eem_64b_entry *key_entry)\n {\n \tkey_entry->hdr.word1 = result->word1;\n+\tkey_entry->hdr.pointer = result->pointer;\n+\tmemcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);\n+}\n \n-\tif (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)\n-\t\tkey_entry->hdr.pointer = result->pointer;\n-\telse\n-\t\tkey_entry->hdr.pointer = result->pointer;\n \n-\tmemcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);\n+/**\n+ * Return the number of page table pages needed to\n+ * reference the given number of next level pages.\n+ *\n+ * [in] num_pages\n+ *   Number of EM pages\n+ *\n+ * [in] page_size\n+ *   Size of each EM page\n+ *\n+ * Returns:\n+ *   Number of EM page table pages\n+ */\n+static uint32_t\n+tf_em_page_tbl_pgcnt(uint32_t num_pages,\n+\t\t     uint32_t page_size)\n+{\n+\treturn roundup(num_pages, MAX_PAGE_PTRS(page_size)) /\n+\t\t       MAX_PAGE_PTRS(page_size);\n+\treturn 0;\n+}\n+\n+/**\n+ * Given the number of data pages, page_size and the maximum\n+ * number of page table levels (already determined), size\n+ * the number of page table pages required at each level.\n+ *\n+ * [in] max_lvl\n+ *   Max number of levels\n+ *\n+ * [in] num_data_pages\n+ *   Number of EM data pages\n+ *\n+ * [in] page_size\n+ *   Size of an EM page\n+ *\n+ * [out] *page_cnt\n+ *   EM page count\n+ */\n+static void\n+tf_em_size_page_tbls(int max_lvl,\n+\t\t     uint64_t num_data_pages,\n+\t\t     uint32_t page_size,\n+\t\t     uint32_t *page_cnt)\n+{\n+\tif (max_lvl == TF_PT_LVL_0) {\n+\t\tpage_cnt[TF_PT_LVL_0] = num_data_pages;\n+\t} else if (max_lvl == TF_PT_LVL_1) {\n+\t\tpage_cnt[TF_PT_LVL_1] = num_data_pages;\n+\t\tpage_cnt[TF_PT_LVL_0] =\n+\t\ttf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);\n+\t} else if (max_lvl == TF_PT_LVL_2) {\n+\t\tpage_cnt[TF_PT_LVL_2] = num_data_pages;\n+\t\tpage_cnt[TF_PT_LVL_1] =\n+\t\ttf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_2], page_size);\n+\t\tpage_cnt[TF_PT_LVL_0] =\n+\t\ttf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);\n+\t} else {\n+\t\treturn;\n+\t}\n+}\n+\n+/**\n+ * Given the page size, size of each data item (entry size),\n+ * and the total number of entries needed, determine the number\n+ * of page table levels and the number of data pages required.\n+ *\n+ * [in] page_size\n+ *   Page size\n+ *\n+ * [in] entry_size\n+ *   Entry size\n+ *\n+ * [in] num_entries\n+ *   Number of entries needed\n+ *\n+ * [out] num_data_pages\n+ *   Number of pages required\n+ *\n+ * Returns:\n+ *   Success  - Number of EM page levels required\n+ *   -ENOMEM  - Out of memory\n+ */\n+static int\n+tf_em_size_page_tbl_lvl(uint32_t page_size,\n+\t\t\tuint32_t entry_size,\n+\t\t\tuint32_t num_entries,\n+\t\t\tuint64_t *num_data_pages)\n+{\n+\tuint64_t lvl_data_size = page_size;\n+\tint lvl = TF_PT_LVL_0;\n+\tuint64_t data_size;\n+\n+\t*num_data_pages = 0;\n+\tdata_size = (uint64_t)num_entries * entry_size;\n+\n+\twhile (lvl_data_size < data_size) {\n+\t\tlvl++;\n+\n+\t\tif (lvl == TF_PT_LVL_1)\n+\t\t\tlvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *\n+\t\t\t\tpage_size;\n+\t\telse if (lvl == TF_PT_LVL_2)\n+\t\t\tlvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *\n+\t\t\t\tMAX_PAGE_PTRS(page_size) * page_size;\n+\t\telse\n+\t\t\treturn -ENOMEM;\n+\t}\n+\n+\t*num_data_pages = roundup(data_size, page_size) / page_size;\n+\n+\treturn lvl;\n+}\n+\n+/**\n+ * Size the EM table based on capabilities\n+ *\n+ * [in] tbl\n+ *   EM table to size\n+ *\n+ * Returns:\n+ *   0        - Success\n+ *   - EINVAL - Parameter error\n+ *   - ENOMEM - Out of memory\n+ */\n+int\n+tf_em_size_table(struct hcapi_cfa_em_table *tbl,\n+\t\t uint32_t page_size)\n+{\n+\tuint64_t num_data_pages;\n+\tuint32_t *page_cnt;\n+\tint max_lvl;\n+\tuint32_t num_entries;\n+\tuint32_t cnt = TF_EM_MIN_ENTRIES;\n+\n+\t/* Ignore entry if both size and number are zero */\n+\tif (!tbl->entry_size && !tbl->num_entries)\n+\t\treturn 0;\n+\n+\t/* If only one is set then error */\n+\tif (!tbl->entry_size || !tbl->num_entries)\n+\t\treturn -EINVAL;\n+\n+\t/* Determine number of page table levels and the number\n+\t * of data pages needed to process the given eem table.\n+\t */\n+\tif (tbl->type == TF_RECORD_TABLE) {\n+\t\t/*\n+\t\t * For action records just a memory size is provided. Work\n+\t\t * backwards to resolve to number of entries\n+\t\t */\n+\t\tnum_entries = tbl->num_entries / tbl->entry_size;\n+\t\tif (num_entries < TF_EM_MIN_ENTRIES) {\n+\t\t\tnum_entries = TF_EM_MIN_ENTRIES;\n+\t\t} else {\n+\t\t\twhile (num_entries > cnt && cnt <= TF_EM_MAX_ENTRIES)\n+\t\t\t\tcnt *= 2;\n+\t\t\tnum_entries = cnt;\n+\t\t}\n+\t} else {\n+\t\tnum_entries = tbl->num_entries;\n+\t}\n+\n+\tmax_lvl = tf_em_size_page_tbl_lvl(page_size,\n+\t\t\t\t\t  tbl->entry_size,\n+\t\t\t\t\t  tbl->num_entries,\n+\t\t\t\t\t  &num_data_pages);\n+\tif (max_lvl < 0) {\n+\t\tTFP_DRV_LOG(WARNING, \"EEM: Failed to size page table levels\\n\");\n+\t\tTFP_DRV_LOG(WARNING,\n+\t\t\t    \"table: %d data-sz: %016\" PRIu64 \" page-sz: %u\\n\",\n+\t\t\t    tbl->type, (uint64_t)num_entries * tbl->entry_size,\n+\t\t\t    page_size);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\ttbl->num_lvl = max_lvl + 1;\n+\ttbl->num_data_pages = num_data_pages;\n+\n+\t/* Determine the number of pages needed at each level */\n+\tpage_cnt = tbl->page_cnt;\n+\tmemset(page_cnt, 0, sizeof(tbl->page_cnt));\n+\ttf_em_size_page_tbls(max_lvl, num_data_pages, page_size,\n+\t\t\t\tpage_cnt);\n+\n+\tTFP_DRV_LOG(INFO, \"EEM: Sized page table: %d\\n\", tbl->type);\n+\tTFP_DRV_LOG(INFO,\n+\t\t    \"EEM: lvls: %d sz: %016\" PRIu64 \" pgs: %016\" PRIu64 \\\n+\t\t    \" l0: %u l1: %u l2: %u\\n\",\n+\t\t    max_lvl + 1,\n+\t\t    (uint64_t)num_data_pages * page_size,\n+\t\t    num_data_pages,\n+\t\t    page_cnt[TF_PT_LVL_0],\n+\t\t    page_cnt[TF_PT_LVL_1],\n+\t\t    page_cnt[TF_PT_LVL_2]);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Validates EM number of entries requested\n+ *\n+ * [in] tbl_scope_cb\n+ *   Pointer to table scope control block to be populated\n+ *\n+ * [in] parms\n+ *   Pointer to input parameters\n+ *\n+ * Returns:\n+ *   0       - Success\n+ *   -EINVAL - Parameter error\n+ */\n+int\n+tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,\n+\t\t\t   struct tf_alloc_tbl_scope_parms *parms)\n+{\n+\tuint32_t cnt;\n+\n+\tif (parms->rx_mem_size_in_mb != 0) {\n+\t\tuint32_t key_b = 2 * ((parms->rx_max_key_sz_in_bits / 8) + 1);\n+\t\tuint32_t action_b = ((parms->rx_max_action_entry_sz_in_bits / 8)\n+\t\t\t\t     + 1);\n+\t\tuint32_t num_entries = (parms->rx_mem_size_in_mb *\n+\t\t\t\t\tTF_MEGABYTE) / (key_b + action_b);\n+\n+\t\tif (num_entries < TF_EM_MIN_ENTRIES) {\n+\t\t\tTFP_DRV_LOG(ERR, \"EEM: Insufficient memory requested:\"\n+\t\t\t\t    \"%uMB\\n\",\n+\t\t\t\t    parms->rx_mem_size_in_mb);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tcnt = TF_EM_MIN_ENTRIES;\n+\t\twhile (num_entries > cnt &&\n+\t\t       cnt <= TF_EM_MAX_ENTRIES)\n+\t\t\tcnt *= 2;\n+\n+\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n+\t\t\tTFP_DRV_LOG(ERR, \"EEM: Invalid number of Tx requested: \"\n+\t\t\t\t    \"%u\\n\",\n+\t\t       (parms->tx_num_flows_in_k * TF_KILOBYTE));\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tparms->rx_num_flows_in_k = cnt / TF_KILOBYTE;\n+\t} else {\n+\t\tif ((parms->rx_num_flows_in_k * TF_KILOBYTE) <\n+\t\t    TF_EM_MIN_ENTRIES ||\n+\t\t    (parms->rx_num_flows_in_k * TF_KILOBYTE) >\n+\t\t    tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Invalid number of Rx flows \"\n+\t\t\t\t    \"requested:%u max:%u\\n\",\n+\t\t\t\t    parms->rx_num_flows_in_k * TF_KILOBYTE,\n+\t\t\ttbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* must be a power-of-2 supported value\n+\t\t * in the range 32K - 128M\n+\t\t */\n+\t\tcnt = TF_EM_MIN_ENTRIES;\n+\t\twhile ((parms->rx_num_flows_in_k * TF_KILOBYTE) != cnt &&\n+\t\t       cnt <= TF_EM_MAX_ENTRIES)\n+\t\t\tcnt *= 2;\n+\n+\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Invalid number of Rx requested: %u\\n\",\n+\t\t\t\t    (parms->rx_num_flows_in_k * TF_KILOBYTE));\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (parms->tx_mem_size_in_mb != 0) {\n+\t\tuint32_t key_b = 2 * (parms->tx_max_key_sz_in_bits / 8 + 1);\n+\t\tuint32_t action_b = ((parms->tx_max_action_entry_sz_in_bits / 8)\n+\t\t\t\t     + 1);\n+\t\tuint32_t num_entries = (parms->tx_mem_size_in_mb *\n+\t\t\t\t\t(TF_KILOBYTE * TF_KILOBYTE)) /\n+\t\t\t(key_b + action_b);\n+\n+\t\tif (num_entries < TF_EM_MIN_ENTRIES) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Insufficient memory requested:%uMB\\n\",\n+\t\t\t\t    parms->rx_mem_size_in_mb);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tcnt = TF_EM_MIN_ENTRIES;\n+\t\twhile (num_entries > cnt &&\n+\t\t       cnt <= TF_EM_MAX_ENTRIES)\n+\t\t\tcnt *= 2;\n+\n+\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Invalid number of Tx requested: %u\\n\",\n+\t\t       (parms->tx_num_flows_in_k * TF_KILOBYTE));\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tparms->tx_num_flows_in_k = cnt / TF_KILOBYTE;\n+\t} else {\n+\t\tif ((parms->tx_num_flows_in_k * TF_KILOBYTE) <\n+\t\t    TF_EM_MIN_ENTRIES ||\n+\t\t    (parms->tx_num_flows_in_k * TF_KILOBYTE) >\n+\t\t    tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Invalid number of Tx flows \"\n+\t\t\t\t    \"requested:%u max:%u\\n\",\n+\t\t\t\t    (parms->tx_num_flows_in_k * TF_KILOBYTE),\n+\t\t\ttbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tcnt = TF_EM_MIN_ENTRIES;\n+\t\twhile ((parms->tx_num_flows_in_k * TF_KILOBYTE) != cnt &&\n+\t\t       cnt <= TF_EM_MAX_ENTRIES)\n+\t\t\tcnt *= 2;\n+\n+\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Invalid number of Tx requested: %u\\n\",\n+\t\t       (parms->tx_num_flows_in_k * TF_KILOBYTE));\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (parms->rx_num_flows_in_k != 0 &&\n+\t    parms->rx_max_key_sz_in_bits / 8 == 0) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"EEM: Rx key size required: %u\\n\",\n+\t\t\t    (parms->rx_max_key_sz_in_bits));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (parms->tx_num_flows_in_k != 0 &&\n+\t    parms->tx_max_key_sz_in_bits / 8 == 0) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"EEM: Tx key size required: %u\\n\",\n+\t\t\t    (parms->tx_max_key_sz_in_bits));\n+\t\treturn -EINVAL;\n+\t}\n+\t/* Rx */\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries =\n+\t\tparms->rx_num_flows_in_k * TF_KILOBYTE;\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].entry_size =\n+\t\tparms->rx_max_key_sz_in_bits / 8;\n+\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].num_entries =\n+\t\tparms->rx_num_flows_in_k * TF_KILOBYTE;\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].entry_size =\n+\t\tparms->rx_max_key_sz_in_bits / 8;\n+\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].num_entries\n+\t\t= parms->rx_num_flows_in_k * TF_KILOBYTE;\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size\n+\t\t= parms->rx_max_action_entry_sz_in_bits / 8;\n+\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries\n+\t\t= 0;\n+\n+\t/* Tx */\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries =\n+\t\tparms->tx_num_flows_in_k * TF_KILOBYTE;\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].entry_size =\n+\t\tparms->tx_max_key_sz_in_bits / 8;\n+\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].num_entries =\n+\t\tparms->tx_num_flows_in_k * TF_KILOBYTE;\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].entry_size =\n+\t\tparms->tx_max_key_sz_in_bits / 8;\n+\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].num_entries\n+\t\t= parms->tx_num_flows_in_k * TF_KILOBYTE;\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size\n+\t\t= parms->tx_max_action_entry_sz_in_bits / 8;\n+\n+\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries\n+\t\t= 0;\n+\n+\treturn 0;\n+}\n+\n+/** insert EEM entry API\n+ *\n+ * returns:\n+ *  0\n+ *  TF_ERR\t    - unable to get lock\n+ *\n+ * insert callback returns:\n+ *   0\n+ *   TF_ERR_EM_DUP  - key is already in table\n+ */\n+static int\n+tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,\n+\t\t    struct tf_insert_em_entry_parms *parms)\n+{\n+\tuint32_t mask;\n+\tuint32_t key0_hash;\n+\tuint32_t key1_hash;\n+\tuint32_t key0_index;\n+\tuint32_t key1_index;\n+\tstruct cfa_p4_eem_64b_entry key_entry;\n+\tuint32_t index;\n+\tenum hcapi_cfa_em_table_type table_type;\n+\tuint32_t gfid;\n+\tstruct hcapi_cfa_hwop op;\n+\tstruct hcapi_cfa_key_tbl key_tbl;\n+\tstruct hcapi_cfa_key_data key_obj;\n+\tstruct hcapi_cfa_key_loc key_loc;\n+\tuint64_t big_hash;\n+\tint rc;\n+\n+\t/* Get mask to use on hash */\n+\tmask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);\n+\n+\tif (!mask)\n+\t\treturn -EINVAL;\n+\n+#ifdef TF_EEM_DEBUG\n+\tdump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, \"In Key\");\n+#endif\n+\n+\tbig_hash = hcapi_cfa_key_hash((uint64_t *)parms->key,\n+\t\t\t\t      (TF_HW_EM_KEY_MAX_SIZE + 4) * 8);\n+\tkey0_hash = (uint32_t)(big_hash >> 32);\n+\tkey1_hash = (uint32_t)(big_hash & 0xFFFFFFFF);\n+\n+\tkey0_index = key0_hash & mask;\n+\tkey1_index = key1_hash & mask;\n \n #ifdef TF_EEM_DEBUG\n-\tdump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, \"Create raw:\");\n+\tTFP_DRV_LOG(DEBUG, \"Key0 hash:0x%08x\\n\", key0_hash);\n+\tTFP_DRV_LOG(DEBUG, \"Key1 hash:0x%08x\\n\", key1_hash);\n #endif\n+\t/*\n+\t * Use the \"result\" arg to populate all of the key entry then\n+\t * store the byte swapped \"raw\" entry in a local copy ready\n+\t * for insertion in to the table.\n+\t */\n+\ttf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,\n+\t\t\t\t((uint8_t *)parms->key),\n+\t\t\t\t&key_entry);\n+\n+\t/*\n+\t * Try to add to Key0 table, if that does not work then\n+\t * try the key1 table.\n+\t */\n+\tindex = key0_index;\n+\top.opcode = HCAPI_CFA_HWOPS_ADD;\n+\tkey_tbl.base0 =\n+\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];\n+\tkey_tbl.page_size = TF_EM_PAGE_SIZE;\n+\tkey_obj.offset = index * TF_EM_KEY_RECORD_SIZE;\n+\tkey_obj.data = (uint8_t *)&key_entry;\n+\tkey_obj.size = TF_EM_KEY_RECORD_SIZE;\n+\n+\trc = hcapi_cfa_key_hw_op(&op,\n+\t\t\t\t &key_tbl,\n+\t\t\t\t &key_obj,\n+\t\t\t\t &key_loc);\n+\n+\tif (rc == 0) {\n+\t\ttable_type = TF_KEY0_TABLE;\n+\t} else {\n+\t\tindex = key1_index;\n+\n+\t\tkey_tbl.base0 =\n+\t\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];\n+\t\tkey_obj.offset = index * TF_EM_KEY_RECORD_SIZE;\n+\n+\t\trc = hcapi_cfa_key_hw_op(&op,\n+\t\t\t\t\t &key_tbl,\n+\t\t\t\t\t &key_obj,\n+\t\t\t\t\t &key_loc);\n+\t\tif (rc != 0)\n+\t\t\treturn rc;\n+\n+\t\ttable_type = TF_KEY1_TABLE;\n+\t}\n+\n+\tTF_SET_GFID(gfid,\n+\t\t    index,\n+\t\t    table_type);\n+\tTF_SET_FLOW_ID(parms->flow_id,\n+\t\t       gfid,\n+\t\t       TF_GFID_TABLE_EXTERNAL,\n+\t\t       parms->dir);\n+\tTF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,\n+\t\t\t\t     0,\n+\t\t\t\t     0,\n+\t\t\t\t     0,\n+\t\t\t\t     index,\n+\t\t\t\t     0,\n+\t\t\t\t     table_type);\n+\n+\treturn 0;\n+}\n+\n+/** delete EEM hash entry API\n+ *\n+ * returns:\n+ *   0\n+ *   -EINVAL\t  - parameter error\n+ *   TF_NO_SESSION    - bad session ID\n+ *   TF_ERR_TBL_SCOPE - invalid table scope\n+ *   TF_ERR_TBL_IF    - invalid table interface\n+ *\n+ * insert callback returns\n+ *   0\n+ *   TF_NO_EM_MATCH - entry not found\n+ */\n+static int\n+tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,\n+\t\t    struct tf_delete_em_entry_parms *parms)\n+{\n+\tenum hcapi_cfa_em_table_type hash_type;\n+\tuint32_t index;\n+\tstruct hcapi_cfa_hwop op;\n+\tstruct hcapi_cfa_key_tbl key_tbl;\n+\tstruct hcapi_cfa_key_data key_obj;\n+\tstruct hcapi_cfa_key_loc key_loc;\n+\tint rc;\n+\n+\tTF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);\n+\tTF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);\n+\n+\top.opcode = HCAPI_CFA_HWOPS_DEL;\n+\tkey_tbl.base0 =\n+\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables\n+\t\t\t[(hash_type == 0 ? TF_KEY0_TABLE : TF_KEY1_TABLE)];\n+\tkey_tbl.page_size = TF_EM_PAGE_SIZE;\n+\tkey_obj.offset = index * TF_EM_KEY_RECORD_SIZE;\n+\tkey_obj.data = NULL;\n+\tkey_obj.size = TF_EM_KEY_RECORD_SIZE;\n+\n+\trc = hcapi_cfa_key_hw_op(&op,\n+\t\t\t\t &key_tbl,\n+\t\t\t\t &key_obj,\n+\t\t\t\t &key_loc);\n+\n+\tif (!rc)\n+\t\treturn rc;\n+\n+\treturn 0;\n+}\n+\n+/** insert EM hash entry API\n+ *\n+ *    returns:\n+ *    0       - Success\n+ *    -EINVAL - Error\n+ */\n+int\n+tf_em_insert_ext_entry(struct tf *tfp __rte_unused,\n+\t\t       struct tf_insert_em_entry_parms *parms)\n+{\n+\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\n+\ttbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);\n+\tif (tbl_scope_cb == NULL) {\n+\t\tTFP_DRV_LOG(ERR, \"Invalid tbl_scope_cb\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn tf_insert_eem_entry\n+\t\t(tbl_scope_cb,\n+\t\tparms);\n+}\n+\n+/** Delete EM hash entry API\n+ *\n+ *    returns:\n+ *    0       - Success\n+ *    -EINVAL - Error\n+ */\n+int\n+tf_em_delete_ext_entry(struct tf *tfp __rte_unused,\n+\t\t       struct tf_delete_em_entry_parms *parms)\n+{\n+\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\n+\ttbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);\n+\tif (tbl_scope_cb == NULL) {\n+\t\tTFP_DRV_LOG(ERR, \"Invalid tbl_scope_cb\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn tf_delete_eem_entry(tbl_scope_cb, parms);\n }\n \n+\n int\n tf_em_ext_common_bind(struct tf *tfp,\n \t\t      struct tf_em_cfg_parms *parms)\n@@ -341,6 +928,7 @@ tf_em_ext_common_bind(struct tf *tfp,\n \t\tinit = 1;\n \n \tmem_type = parms->mem_type;\n+\n \treturn 0;\n }\n \n@@ -375,31 +963,88 @@ tf_em_ext_common_unbind(struct tf *tfp)\n \treturn 0;\n }\n \n-int tf_tbl_ext_set(struct tf *tfp,\n-\t\t   struct tf_tbl_set_parms *parms)\n+/**\n+ * Sets the specified external table type element.\n+ *\n+ * This API sets the specified element data\n+ *\n+ * [in] tfp\n+ *   Pointer to TF handle\n+ *\n+ * [in] parms\n+ *   Pointer to table set parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tbl_ext_common_set(struct tf *tfp,\n+\t\t\t  struct tf_tbl_set_parms *parms)\n {\n-\tif (mem_type == TF_EEM_MEM_TYPE_HOST)\n-\t\treturn tf_tbl_ext_host_set(tfp, parms);\n-\telse\n-\t\treturn tf_tbl_ext_system_set(tfp, parms);\n+\tint rc = 0;\n+\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\tuint32_t tbl_scope_id;\n+\tstruct hcapi_cfa_hwop op;\n+\tstruct hcapi_cfa_key_tbl key_tbl;\n+\tstruct hcapi_cfa_key_data key_obj;\n+\tstruct hcapi_cfa_key_loc key_loc;\n+\n+\tTF_CHECK_PARMS2(tfp, parms);\n+\n+\tif (parms->data == NULL) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s, invalid parms->data\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttbl_scope_id = parms->tbl_scope_id;\n+\n+\tif (tbl_scope_id == TF_TBL_SCOPE_INVALID)  {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s, Table scope not allocated\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Get the table scope control block associated with the\n+\t * external pool\n+\t */\n+\ttbl_scope_cb = tbl_scope_cb_find(tbl_scope_id);\n+\n+\tif (tbl_scope_cb == NULL) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s, table scope error\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\top.opcode = HCAPI_CFA_HWOPS_PUT;\n+\tkey_tbl.base0 =\n+\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_RECORD_TABLE];\n+\tkey_tbl.page_size = TF_EM_PAGE_SIZE;\n+\tkey_obj.offset = parms->idx;\n+\tkey_obj.data = parms->data;\n+\tkey_obj.size = parms->data_sz_in_bytes;\n+\n+\trc = hcapi_cfa_key_hw_op(&op,\n+\t\t\t\t &key_tbl,\n+\t\t\t\t &key_obj,\n+\t\t\t\t &key_loc);\n+\n+\treturn rc;\n }\n \n int\n tf_em_ext_common_alloc(struct tf *tfp,\n \t\t       struct tf_alloc_tbl_scope_parms *parms)\n {\n-\tif (mem_type == TF_EEM_MEM_TYPE_HOST)\n-\t\treturn tf_em_ext_host_alloc(tfp, parms);\n-\telse\n-\t\treturn tf_em_ext_system_alloc(tfp, parms);\n+\treturn tf_em_ext_alloc(tfp, parms);\n }\n \n int\n tf_em_ext_common_free(struct tf *tfp,\n \t\t      struct tf_free_tbl_scope_parms *parms)\n {\n-\tif (mem_type == TF_EEM_MEM_TYPE_HOST)\n-\t\treturn tf_em_ext_host_free(tfp, parms);\n-\telse\n-\t\treturn tf_em_ext_system_free(tfp, parms);\n+\treturn tf_em_ext_free(tfp, parms);\n }\ndiff --git a/drivers/net/bnxt/tf_core/tf_em_common.h b/drivers/net/bnxt/tf_core/tf_em_common.h\nindex bf01df9..fa313c4 100644\n--- a/drivers/net/bnxt/tf_core/tf_em_common.h\n+++ b/drivers/net/bnxt/tf_core/tf_em_common.h\n@@ -101,4 +101,34 @@ void *tf_em_get_table_page(struct tf_tbl_scope_cb *tbl_scope_cb,\n \t\t\t   uint32_t offset,\n \t\t\t   enum hcapi_cfa_em_table_type table_type);\n \n+/**\n+ * Validates EM number of entries requested\n+ *\n+ * [in] tbl_scope_cb\n+ *   Pointer to table scope control block to be populated\n+ *\n+ * [in] parms\n+ *   Pointer to input parameters\n+ *\n+ * Returns:\n+ *   0       - Success\n+ *   -EINVAL - Parameter error\n+ */\n+int tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,\n+\t\t\t       struct tf_alloc_tbl_scope_parms *parms);\n+\n+/**\n+ * Size the EM table based on capabilities\n+ *\n+ * [in] tbl\n+ *   EM table to size\n+ *\n+ * Returns:\n+ *   0        - Success\n+ *   - EINVAL - Parameter error\n+ *   - ENOMEM - Out of memory\n+ */\n+int tf_em_size_table(struct hcapi_cfa_em_table *tbl,\n+\t\t     uint32_t page_size);\n+\n #endif /* _TF_EM_COMMON_H_ */\ndiff --git a/drivers/net/bnxt/tf_core/tf_em_host.c b/drivers/net/bnxt/tf_core/tf_em_host.c\nindex 9abb9b1..4d769cc 100644\n--- a/drivers/net/bnxt/tf_core/tf_em_host.c\n+++ b/drivers/net/bnxt/tf_core/tf_em_host.c\n@@ -22,7 +22,6 @@\n \n #include \"bnxt.h\"\n \n-\n #define PTU_PTE_VALID          0x1UL\n #define PTU_PTE_LAST           0x2UL\n #define PTU_PTE_NEXT_TO_LAST   0x4UL\n@@ -30,20 +29,6 @@\n /* Number of pointers per page_size */\n #define MAX_PAGE_PTRS(page_size)  ((page_size) / sizeof(void *))\n \n-#define TF_EM_PG_SZ_4K        (1 << 12)\n-#define TF_EM_PG_SZ_8K        (1 << 13)\n-#define TF_EM_PG_SZ_64K       (1 << 16)\n-#define TF_EM_PG_SZ_256K      (1 << 18)\n-#define TF_EM_PG_SZ_1M        (1 << 20)\n-#define TF_EM_PG_SZ_2M        (1 << 21)\n-#define TF_EM_PG_SZ_4M        (1 << 22)\n-#define TF_EM_PG_SZ_1G        (1 << 30)\n-\n-#define TF_EM_CTX_ID_INVALID   0xFFFF\n-\n-#define TF_EM_MIN_ENTRIES     (1 << 15) /* 32K */\n-#define TF_EM_MAX_ENTRIES     (1 << 27) /* 128M */\n-\n /**\n  * EM DBs.\n  */\n@@ -295,203 +280,6 @@ tf_em_setup_page_table(struct hcapi_cfa_em_table *tbl)\n }\n \n /**\n- * Given the page size, size of each data item (entry size),\n- * and the total number of entries needed, determine the number\n- * of page table levels and the number of data pages required.\n- *\n- * [in] page_size\n- *   Page size\n- *\n- * [in] entry_size\n- *   Entry size\n- *\n- * [in] num_entries\n- *   Number of entries needed\n- *\n- * [out] num_data_pages\n- *   Number of pages required\n- *\n- * Returns:\n- *   Success  - Number of EM page levels required\n- *   -ENOMEM  - Out of memory\n- */\n-static int\n-tf_em_size_page_tbl_lvl(uint32_t page_size,\n-\t\t\tuint32_t entry_size,\n-\t\t\tuint32_t num_entries,\n-\t\t\tuint64_t *num_data_pages)\n-{\n-\tuint64_t lvl_data_size = page_size;\n-\tint lvl = TF_PT_LVL_0;\n-\tuint64_t data_size;\n-\n-\t*num_data_pages = 0;\n-\tdata_size = (uint64_t)num_entries * entry_size;\n-\n-\twhile (lvl_data_size < data_size) {\n-\t\tlvl++;\n-\n-\t\tif (lvl == TF_PT_LVL_1)\n-\t\t\tlvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *\n-\t\t\t\tpage_size;\n-\t\telse if (lvl == TF_PT_LVL_2)\n-\t\t\tlvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *\n-\t\t\t\tMAX_PAGE_PTRS(page_size) * page_size;\n-\t\telse\n-\t\t\treturn -ENOMEM;\n-\t}\n-\n-\t*num_data_pages = roundup(data_size, page_size) / page_size;\n-\n-\treturn lvl;\n-}\n-\n-/**\n- * Return the number of page table pages needed to\n- * reference the given number of next level pages.\n- *\n- * [in] num_pages\n- *   Number of EM pages\n- *\n- * [in] page_size\n- *   Size of each EM page\n- *\n- * Returns:\n- *   Number of EM page table pages\n- */\n-static uint32_t\n-tf_em_page_tbl_pgcnt(uint32_t num_pages,\n-\t\t     uint32_t page_size)\n-{\n-\treturn roundup(num_pages, MAX_PAGE_PTRS(page_size)) /\n-\t\t       MAX_PAGE_PTRS(page_size);\n-\treturn 0;\n-}\n-\n-/**\n- * Given the number of data pages, page_size and the maximum\n- * number of page table levels (already determined), size\n- * the number of page table pages required at each level.\n- *\n- * [in] max_lvl\n- *   Max number of levels\n- *\n- * [in] num_data_pages\n- *   Number of EM data pages\n- *\n- * [in] page_size\n- *   Size of an EM page\n- *\n- * [out] *page_cnt\n- *   EM page count\n- */\n-static void\n-tf_em_size_page_tbls(int max_lvl,\n-\t\t     uint64_t num_data_pages,\n-\t\t     uint32_t page_size,\n-\t\t     uint32_t *page_cnt)\n-{\n-\tif (max_lvl == TF_PT_LVL_0) {\n-\t\tpage_cnt[TF_PT_LVL_0] = num_data_pages;\n-\t} else if (max_lvl == TF_PT_LVL_1) {\n-\t\tpage_cnt[TF_PT_LVL_1] = num_data_pages;\n-\t\tpage_cnt[TF_PT_LVL_0] =\n-\t\ttf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);\n-\t} else if (max_lvl == TF_PT_LVL_2) {\n-\t\tpage_cnt[TF_PT_LVL_2] = num_data_pages;\n-\t\tpage_cnt[TF_PT_LVL_1] =\n-\t\ttf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_2], page_size);\n-\t\tpage_cnt[TF_PT_LVL_0] =\n-\t\ttf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);\n-\t} else {\n-\t\treturn;\n-\t}\n-}\n-\n-/**\n- * Size the EM table based on capabilities\n- *\n- * [in] tbl\n- *   EM table to size\n- *\n- * Returns:\n- *   0        - Success\n- *   - EINVAL - Parameter error\n- *   - ENOMEM - Out of memory\n- */\n-static int\n-tf_em_size_table(struct hcapi_cfa_em_table *tbl)\n-{\n-\tuint64_t num_data_pages;\n-\tuint32_t *page_cnt;\n-\tint max_lvl;\n-\tuint32_t num_entries;\n-\tuint32_t cnt = TF_EM_MIN_ENTRIES;\n-\n-\t/* Ignore entry if both size and number are zero */\n-\tif (!tbl->entry_size && !tbl->num_entries)\n-\t\treturn 0;\n-\n-\t/* If only one is set then error */\n-\tif (!tbl->entry_size || !tbl->num_entries)\n-\t\treturn -EINVAL;\n-\n-\t/* Determine number of page table levels and the number\n-\t * of data pages needed to process the given eem table.\n-\t */\n-\tif (tbl->type == TF_RECORD_TABLE) {\n-\t\t/*\n-\t\t * For action records just a memory size is provided. Work\n-\t\t * backwards to resolve to number of entries\n-\t\t */\n-\t\tnum_entries = tbl->num_entries / tbl->entry_size;\n-\t\tif (num_entries < TF_EM_MIN_ENTRIES) {\n-\t\t\tnum_entries = TF_EM_MIN_ENTRIES;\n-\t\t} else {\n-\t\t\twhile (num_entries > cnt && cnt <= TF_EM_MAX_ENTRIES)\n-\t\t\t\tcnt *= 2;\n-\t\t\tnum_entries = cnt;\n-\t\t}\n-\t} else {\n-\t\tnum_entries = tbl->num_entries;\n-\t}\n-\n-\tmax_lvl = tf_em_size_page_tbl_lvl(TF_EM_PAGE_SIZE,\n-\t\t\t\t\t  tbl->entry_size,\n-\t\t\t\t\t  tbl->num_entries,\n-\t\t\t\t\t  &num_data_pages);\n-\tif (max_lvl < 0) {\n-\t\tTFP_DRV_LOG(WARNING, \"EEM: Failed to size page table levels\\n\");\n-\t\tTFP_DRV_LOG(WARNING,\n-\t\t\t    \"table: %d data-sz: %016\" PRIu64 \" page-sz: %u\\n\",\n-\t\t\t    tbl->type, (uint64_t)num_entries * tbl->entry_size,\n-\t\t\t    TF_EM_PAGE_SIZE);\n-\t\treturn -ENOMEM;\n-\t}\n-\n-\ttbl->num_lvl = max_lvl + 1;\n-\ttbl->num_data_pages = num_data_pages;\n-\n-\t/* Determine the number of pages needed at each level */\n-\tpage_cnt = tbl->page_cnt;\n-\tmemset(page_cnt, 0, sizeof(tbl->page_cnt));\n-\ttf_em_size_page_tbls(max_lvl, num_data_pages, TF_EM_PAGE_SIZE,\n-\t\t\t\tpage_cnt);\n-\n-\tTFP_DRV_LOG(INFO, \"EEM: Sized page table: %d\\n\", tbl->type);\n-\tTFP_DRV_LOG(INFO,\n-\t\t    \"EEM: lvls: %d sz: %016\" PRIu64 \" pgs: %016\" PRIu64 \" l0: %u l1: %u l2: %u\\n\",\n-\t\t    max_lvl + 1,\n-\t\t    (uint64_t)num_data_pages * TF_EM_PAGE_SIZE,\n-\t\t    num_data_pages,\n-\t\t    page_cnt[TF_PT_LVL_0],\n-\t\t    page_cnt[TF_PT_LVL_1],\n-\t\t    page_cnt[TF_PT_LVL_2]);\n-\n-\treturn 0;\n-}\n-\n-/**\n  * Unregisters EM Ctx in Firmware\n  *\n  * [in] tfp\n@@ -552,7 +340,7 @@ tf_em_ctx_reg(struct tf *tfp,\n \t\ttbl = &ctxp->em_tables[i];\n \n \t\tif (tbl->num_entries && tbl->entry_size) {\n-\t\t\trc = tf_em_size_table(tbl);\n+\t\t\trc = tf_em_size_table(tbl, TF_EM_PAGE_SIZE);\n \n \t\t\tif (rc)\n \t\t\t\tgoto cleanup;\n@@ -578,406 +366,9 @@ tf_em_ctx_reg(struct tf *tfp,\n \treturn rc;\n }\n \n-\n-/**\n- * Validates EM number of entries requested\n- *\n- * [in] tbl_scope_cb\n- *   Pointer to table scope control block to be populated\n- *\n- * [in] parms\n- *   Pointer to input parameters\n- *\n- * Returns:\n- *   0       - Success\n- *   -EINVAL - Parameter error\n- */\n-static int\n-tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,\n-\t\t\t   struct tf_alloc_tbl_scope_parms *parms)\n-{\n-\tuint32_t cnt;\n-\n-\tif (parms->rx_mem_size_in_mb != 0) {\n-\t\tuint32_t key_b = 2 * ((parms->rx_max_key_sz_in_bits / 8) + 1);\n-\t\tuint32_t action_b = ((parms->rx_max_action_entry_sz_in_bits / 8)\n-\t\t\t\t     + 1);\n-\t\tuint32_t num_entries = (parms->rx_mem_size_in_mb *\n-\t\t\t\t\tTF_MEGABYTE) / (key_b + action_b);\n-\n-\t\tif (num_entries < TF_EM_MIN_ENTRIES) {\n-\t\t\tTFP_DRV_LOG(ERR, \"EEM: Insufficient memory requested:\"\n-\t\t\t\t    \"%uMB\\n\",\n-\t\t\t\t    parms->rx_mem_size_in_mb);\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n-\t\tcnt = TF_EM_MIN_ENTRIES;\n-\t\twhile (num_entries > cnt &&\n-\t\t       cnt <= TF_EM_MAX_ENTRIES)\n-\t\t\tcnt *= 2;\n-\n-\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n-\t\t\tTFP_DRV_LOG(ERR, \"EEM: Invalid number of Tx requested: \"\n-\t\t\t\t    \"%u\\n\",\n-\t\t       (parms->tx_num_flows_in_k * TF_KILOBYTE));\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n-\t\tparms->rx_num_flows_in_k = cnt / TF_KILOBYTE;\n-\t} else {\n-\t\tif ((parms->rx_num_flows_in_k * TF_KILOBYTE) <\n-\t\t    TF_EM_MIN_ENTRIES ||\n-\t\t    (parms->rx_num_flows_in_k * TF_KILOBYTE) >\n-\t\t    tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"EEM: Invalid number of Rx flows \"\n-\t\t\t\t    \"requested:%u max:%u\\n\",\n-\t\t\t\t    parms->rx_num_flows_in_k * TF_KILOBYTE,\n-\t\t\ttbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported);\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n-\t\t/* must be a power-of-2 supported value\n-\t\t * in the range 32K - 128M\n-\t\t */\n-\t\tcnt = TF_EM_MIN_ENTRIES;\n-\t\twhile ((parms->rx_num_flows_in_k * TF_KILOBYTE) != cnt &&\n-\t\t       cnt <= TF_EM_MAX_ENTRIES)\n-\t\t\tcnt *= 2;\n-\n-\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"EEM: Invalid number of Rx requested: %u\\n\",\n-\t\t\t\t    (parms->rx_num_flows_in_k * TF_KILOBYTE));\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\t}\n-\n-\tif (parms->tx_mem_size_in_mb != 0) {\n-\t\tuint32_t key_b = 2 * (parms->tx_max_key_sz_in_bits / 8 + 1);\n-\t\tuint32_t action_b = ((parms->tx_max_action_entry_sz_in_bits / 8)\n-\t\t\t\t     + 1);\n-\t\tuint32_t num_entries = (parms->tx_mem_size_in_mb *\n-\t\t\t\t\t(TF_KILOBYTE * TF_KILOBYTE)) /\n-\t\t\t(key_b + action_b);\n-\n-\t\tif (num_entries < TF_EM_MIN_ENTRIES) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"EEM: Insufficient memory requested:%uMB\\n\",\n-\t\t\t\t    parms->rx_mem_size_in_mb);\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n-\t\tcnt = TF_EM_MIN_ENTRIES;\n-\t\twhile (num_entries > cnt &&\n-\t\t       cnt <= TF_EM_MAX_ENTRIES)\n-\t\t\tcnt *= 2;\n-\n-\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"EEM: Invalid number of Tx requested: %u\\n\",\n-\t\t       (parms->tx_num_flows_in_k * TF_KILOBYTE));\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n-\t\tparms->tx_num_flows_in_k = cnt / TF_KILOBYTE;\n-\t} else {\n-\t\tif ((parms->tx_num_flows_in_k * TF_KILOBYTE) <\n-\t\t    TF_EM_MIN_ENTRIES ||\n-\t\t    (parms->tx_num_flows_in_k * TF_KILOBYTE) >\n-\t\t    tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"EEM: Invalid number of Tx flows \"\n-\t\t\t\t    \"requested:%u max:%u\\n\",\n-\t\t\t\t    (parms->tx_num_flows_in_k * TF_KILOBYTE),\n-\t\t\ttbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported);\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\n-\t\tcnt = TF_EM_MIN_ENTRIES;\n-\t\twhile ((parms->tx_num_flows_in_k * TF_KILOBYTE) != cnt &&\n-\t\t       cnt <= TF_EM_MAX_ENTRIES)\n-\t\t\tcnt *= 2;\n-\n-\t\tif (cnt > TF_EM_MAX_ENTRIES) {\n-\t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"EEM: Invalid number of Tx requested: %u\\n\",\n-\t\t       (parms->tx_num_flows_in_k * TF_KILOBYTE));\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\t}\n-\n-\tif ((parms->rx_num_flows_in_k != 0) &&\n-\t    (parms->rx_max_key_sz_in_bits / 8 == 0)) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"EEM: Rx key size required: %u\\n\",\n-\t\t\t    (parms->rx_max_key_sz_in_bits));\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif ((parms->tx_num_flows_in_k != 0) &&\n-\t    (parms->tx_max_key_sz_in_bits / 8 == 0)) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"EEM: Tx key size required: %u\\n\",\n-\t\t\t    (parms->tx_max_key_sz_in_bits));\n-\t\treturn -EINVAL;\n-\t}\n-\t/* Rx */\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries =\n-\t\tparms->rx_num_flows_in_k * TF_KILOBYTE;\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].entry_size =\n-\t\tparms->rx_max_key_sz_in_bits / 8;\n-\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].num_entries =\n-\t\tparms->rx_num_flows_in_k * TF_KILOBYTE;\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].entry_size =\n-\t\tparms->rx_max_key_sz_in_bits / 8;\n-\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].num_entries\n-\t\t= parms->rx_num_flows_in_k * TF_KILOBYTE;\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size\n-\t\t= parms->rx_max_action_entry_sz_in_bits / 8;\n-\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries\n-\t\t= 0;\n-\n-\t/* Tx */\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries =\n-\t\tparms->tx_num_flows_in_k * TF_KILOBYTE;\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].entry_size =\n-\t\tparms->tx_max_key_sz_in_bits / 8;\n-\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].num_entries =\n-\t\tparms->tx_num_flows_in_k * TF_KILOBYTE;\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].entry_size =\n-\t\tparms->tx_max_key_sz_in_bits / 8;\n-\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].num_entries\n-\t\t= parms->tx_num_flows_in_k * TF_KILOBYTE;\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size\n-\t\t= parms->tx_max_action_entry_sz_in_bits / 8;\n-\n-\ttbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries\n-\t\t= 0;\n-\n-\treturn 0;\n-}\n-\n-/** insert EEM entry API\n- *\n- * returns:\n- *  0\n- *  TF_ERR\t    - unable to get lock\n- *\n- * insert callback returns:\n- *   0\n- *   TF_ERR_EM_DUP  - key is already in table\n- */\n-static int\n-tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,\n-\t\t    struct tf_insert_em_entry_parms *parms)\n-{\n-\tuint32_t mask;\n-\tuint32_t key0_hash;\n-\tuint32_t key1_hash;\n-\tuint32_t key0_index;\n-\tuint32_t key1_index;\n-\tstruct cfa_p4_eem_64b_entry key_entry;\n-\tuint32_t index;\n-\tenum hcapi_cfa_em_table_type table_type;\n-\tuint32_t gfid;\n-\tstruct hcapi_cfa_hwop op;\n-\tstruct hcapi_cfa_key_tbl key_tbl;\n-\tstruct hcapi_cfa_key_data key_obj;\n-\tstruct hcapi_cfa_key_loc key_loc;\n-\tuint64_t big_hash;\n-\tint rc;\n-\n-\t/* Get mask to use on hash */\n-\tmask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);\n-\n-\tif (!mask)\n-\t\treturn -EINVAL;\n-\n-#ifdef TF_EEM_DEBUG\n-\tdump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, \"In Key\");\n-#endif\n-\n-\tbig_hash = hcapi_cfa_key_hash((uint64_t *)parms->key,\n-\t\t\t\t      (TF_HW_EM_KEY_MAX_SIZE + 4) * 8);\n-\tkey0_hash = (uint32_t)(big_hash >> 32);\n-\tkey1_hash = (uint32_t)(big_hash & 0xFFFFFFFF);\n-\n-\tkey0_index = key0_hash & mask;\n-\tkey1_index = key1_hash & mask;\n-\n-#ifdef TF_EEM_DEBUG\n-\tTFP_DRV_LOG(DEBUG, \"Key0 hash:0x%08x\\n\", key0_hash);\n-\tTFP_DRV_LOG(DEBUG, \"Key1 hash:0x%08x\\n\", key1_hash);\n-#endif\n-\t/*\n-\t * Use the \"result\" arg to populate all of the key entry then\n-\t * store the byte swapped \"raw\" entry in a local copy ready\n-\t * for insertion in to the table.\n-\t */\n-\ttf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,\n-\t\t\t\t((uint8_t *)parms->key),\n-\t\t\t\t&key_entry);\n-\n-\t/*\n-\t * Try to add to Key0 table, if that does not work then\n-\t * try the key1 table.\n-\t */\n-\tindex = key0_index;\n-\top.opcode = HCAPI_CFA_HWOPS_ADD;\n-\tkey_tbl.base0 =\n-\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];\n-\tkey_tbl.page_size = TF_EM_PAGE_SIZE;\n-\tkey_obj.offset = index * TF_EM_KEY_RECORD_SIZE;\n-\tkey_obj.data = (uint8_t *)&key_entry;\n-\tkey_obj.size = TF_EM_KEY_RECORD_SIZE;\n-\n-\trc = hcapi_cfa_key_hw_op(&op,\n-\t\t\t\t &key_tbl,\n-\t\t\t\t &key_obj,\n-\t\t\t\t &key_loc);\n-\n-\tif (rc == 0) {\n-\t\ttable_type = TF_KEY0_TABLE;\n-\t} else {\n-\t\tindex = key1_index;\n-\n-\t\tkey_tbl.base0 =\n-\t\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];\n-\t\tkey_obj.offset = index * TF_EM_KEY_RECORD_SIZE;\n-\n-\t\trc = hcapi_cfa_key_hw_op(&op,\n-\t\t\t\t\t &key_tbl,\n-\t\t\t\t\t &key_obj,\n-\t\t\t\t\t &key_loc);\n-\t\tif (rc != 0)\n-\t\t\treturn rc;\n-\n-\t\ttable_type = TF_KEY1_TABLE;\n-\t}\n-\n-\tTF_SET_GFID(gfid,\n-\t\t    index,\n-\t\t    table_type);\n-\tTF_SET_FLOW_ID(parms->flow_id,\n-\t\t       gfid,\n-\t\t       TF_GFID_TABLE_EXTERNAL,\n-\t\t       parms->dir);\n-\tTF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,\n-\t\t\t\t     0,\n-\t\t\t\t     0,\n-\t\t\t\t     0,\n-\t\t\t\t     index,\n-\t\t\t\t     0,\n-\t\t\t\t     table_type);\n-\n-\treturn 0;\n-}\n-\n-/** delete EEM hash entry API\n- *\n- * returns:\n- *   0\n- *   -EINVAL\t  - parameter error\n- *   TF_NO_SESSION    - bad session ID\n- *   TF_ERR_TBL_SCOPE - invalid table scope\n- *   TF_ERR_TBL_IF    - invalid table interface\n- *\n- * insert callback returns\n- *   0\n- *   TF_NO_EM_MATCH - entry not found\n- */\n-static int\n-tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,\n-\t\t    struct tf_delete_em_entry_parms *parms)\n-{\n-\tenum hcapi_cfa_em_table_type hash_type;\n-\tuint32_t index;\n-\tstruct hcapi_cfa_hwop op;\n-\tstruct hcapi_cfa_key_tbl key_tbl;\n-\tstruct hcapi_cfa_key_data key_obj;\n-\tstruct hcapi_cfa_key_loc key_loc;\n-\tint rc;\n-\n-\tif (parms->flow_handle == 0)\n-\t\treturn -EINVAL;\n-\n-\tTF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);\n-\tTF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);\n-\n-\top.opcode = HCAPI_CFA_HWOPS_DEL;\n-\tkey_tbl.base0 =\n-\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[\n-\t\t\t(hash_type == 0 ? TF_KEY0_TABLE : TF_KEY1_TABLE)];\n-\tkey_tbl.page_size = TF_EM_PAGE_SIZE;\n-\tkey_obj.offset = index * TF_EM_KEY_RECORD_SIZE;\n-\tkey_obj.data = NULL;\n-\tkey_obj.size = TF_EM_KEY_RECORD_SIZE;\n-\n-\trc = hcapi_cfa_key_hw_op(&op,\n-\t\t\t\t &key_tbl,\n-\t\t\t\t &key_obj,\n-\t\t\t\t &key_loc);\n-\n-\tif (!rc)\n-\t\treturn rc;\n-\n-\treturn 0;\n-}\n-\n-/** insert EM hash entry API\n- *\n- *    returns:\n- *    0       - Success\n- *    -EINVAL - Error\n- */\n int\n-tf_em_insert_ext_entry(struct tf *tfp __rte_unused,\n-\t\t       struct tf_insert_em_entry_parms *parms)\n-{\n-\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n-\n-\ttbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);\n-\tif (tbl_scope_cb == NULL) {\n-\t\tTFP_DRV_LOG(ERR, \"Invalid tbl_scope_cb\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\treturn tf_insert_eem_entry(\n-\t\ttbl_scope_cb,\n-\t\tparms);\n-}\n-\n-/** Delete EM hash entry API\n- *\n- *    returns:\n- *    0       - Success\n- *    -EINVAL - Error\n- */\n-int\n-tf_em_delete_ext_entry(struct tf *tfp __rte_unused,\n-\t\t       struct tf_delete_em_entry_parms *parms)\n-{\n-\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n-\n-\ttbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);\n-\tif (tbl_scope_cb == NULL) {\n-\t\tTFP_DRV_LOG(ERR, \"Invalid tbl_scope_cb\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\treturn tf_delete_eem_entry(tbl_scope_cb, parms);\n-}\n-\n-int\n-tf_em_ext_host_alloc(struct tf *tfp,\n-\t\t     struct tf_alloc_tbl_scope_parms *parms)\n+tf_em_ext_alloc(struct tf *tfp,\n+\t\tstruct tf_alloc_tbl_scope_parms *parms)\n {\n \tint rc;\n \tenum tf_dir dir;\n@@ -1084,7 +475,7 @@ tf_em_ext_host_alloc(struct tf *tfp,\n \n cleanup_full:\n \tfree_parms.tbl_scope_id = parms->tbl_scope_id;\n-\ttf_em_ext_host_free(tfp, &free_parms);\n+\ttf_em_ext_free(tfp, &free_parms);\n \treturn -EINVAL;\n \n cleanup:\n@@ -1097,8 +488,8 @@ tf_em_ext_host_alloc(struct tf *tfp,\n }\n \n int\n-tf_em_ext_host_free(struct tf *tfp,\n-\t\t    struct tf_free_tbl_scope_parms *parms)\n+tf_em_ext_free(struct tf *tfp,\n+\t       struct tf_free_tbl_scope_parms *parms)\n {\n \tint rc = 0;\n \tenum tf_dir  dir;\n@@ -1139,75 +530,3 @@ tf_em_ext_host_free(struct tf *tfp,\n \ttbl_scopes[parms->tbl_scope_id].tbl_scope_id = TF_TBL_SCOPE_INVALID;\n \treturn rc;\n }\n-\n-/**\n- * Sets the specified external table type element.\n- *\n- * This API sets the specified element data\n- *\n- * [in] tfp\n- *   Pointer to TF handle\n- *\n- * [in] parms\n- *   Pointer to table set parameters\n- *\n- * Returns\n- *   - (0) if successful.\n- *   - (-EINVAL) on failure.\n- */\n-int tf_tbl_ext_host_set(struct tf *tfp,\n-\t\t\tstruct tf_tbl_set_parms *parms)\n-{\n-\tint rc = 0;\n-\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n-\tuint32_t tbl_scope_id;\n-\tstruct hcapi_cfa_hwop op;\n-\tstruct hcapi_cfa_key_tbl key_tbl;\n-\tstruct hcapi_cfa_key_data key_obj;\n-\tstruct hcapi_cfa_key_loc key_loc;\n-\n-\tTF_CHECK_PARMS2(tfp, parms);\n-\n-\tif (parms->data == NULL) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s, invalid parms->data\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n-\ttbl_scope_id = parms->tbl_scope_id;\n-\n-\tif (tbl_scope_id == TF_TBL_SCOPE_INVALID)  {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s, Table scope not allocated\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t/* Get the table scope control block associated with the\n-\t * external pool\n-\t */\n-\ttbl_scope_cb = tbl_scope_cb_find(tbl_scope_id);\n-\n-\tif (tbl_scope_cb == NULL) {\n-\t\tTFP_DRV_LOG(ERR,\n-\t\t\t    \"%s, table scope error\\n\",\n-\t\t\t    tf_dir_2_str(parms->dir));\n-\t\treturn -EINVAL;\n-\t}\n-\n-\top.opcode = HCAPI_CFA_HWOPS_PUT;\n-\tkey_tbl.base0 =\n-\t\t(uint8_t *)&tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_RECORD_TABLE];\n-\tkey_tbl.page_size = TF_EM_PAGE_SIZE;\n-\tkey_obj.offset = parms->idx;\n-\tkey_obj.data = parms->data;\n-\tkey_obj.size = parms->data_sz_in_bytes;\n-\n-\trc = hcapi_cfa_key_hw_op(&op,\n-\t\t\t\t &key_tbl,\n-\t\t\t\t &key_obj,\n-\t\t\t\t &key_loc);\n-\n-\treturn rc;\n-}\ndiff --git a/drivers/net/bnxt/tf_core/tf_em_system.c b/drivers/net/bnxt/tf_core/tf_em_system.c\nindex 10768df..e383f1f 100644\n--- a/drivers/net/bnxt/tf_core/tf_em_system.c\n+++ b/drivers/net/bnxt/tf_core/tf_em_system.c\n@@ -4,11 +4,24 @@\n  */\n \n #include <string.h>\n+#include <sys/types.h>\n+#include <sys/stat.h>\n+#include <fcntl.h>\n+#include <stdbool.h>\n+#include <math.h>\n+#include <sys/param.h>\n+#include <sys/mman.h>\n+#include <sys/ioctl.h>\n+#include <unistd.h>\n+#include <string.h>\n+\n #include <rte_common.h>\n #include <rte_errno.h>\n #include <rte_log.h>\n \n #include \"tf_core.h\"\n+#include \"tf_util.h\"\n+#include \"tf_common.h\"\n #include \"tf_em.h\"\n #include \"tf_em_common.h\"\n #include \"tf_msg.h\"\n@@ -18,103 +31,508 @@\n \n #include \"bnxt.h\"\n \n+enum tf_em_req_type {\n+\tTF_EM_BNXT_LFC_CFA_EEM_DMABUF_EXPORT_REQ = 5,\n+};\n \n-/** insert EEM entry API\n- *\n- * returns:\n- *  0\n- *  TF_ERR\t    - unable to get lock\n- *\n- * insert callback returns:\n- *   0\n- *   TF_ERR_EM_DUP  - key is already in table\n+struct tf_em_bnxt_lfc_req_hdr {\n+\tuint32_t ver;\n+\tuint32_t bus;\n+\tuint32_t devfn;\n+\tenum tf_em_req_type req_type;\n+};\n+\n+struct tf_em_bnxt_lfc_cfa_eem_std_hdr {\n+\tuint16_t version;\n+\tuint16_t size;\n+\tuint32_t flags;\n+\t#define TF_EM_BNXT_LFC_EEM_CFG_PRIMARY_FUNC     (1 << 0)\n+};\n+\n+struct tf_em_bnxt_lfc_dmabuf_fd {\n+\tint fd[TF_DIR_MAX][TF_MAX_TABLE];\n+};\n+\n+#ifndef __user\n+#define __user\n+#endif\n+\n+struct tf_em_bnxt_lfc_cfa_eem_dmabuf_export_req {\n+\tstruct tf_em_bnxt_lfc_cfa_eem_std_hdr std;\n+\tuint8_t dir;\n+\tuint32_t flags;\n+\tvoid __user *dma_fd;\n+};\n+\n+struct tf_em_bnxt_lfc_req {\n+\tstruct tf_em_bnxt_lfc_req_hdr hdr;\n+\tunion {\n+\t\tstruct tf_em_bnxt_lfc_cfa_eem_dmabuf_export_req\n+\t\t       eem_dmabuf_export_req;\n+\t\tuint64_t hreq;\n+\t} req;\n+};\n+\n+#define TF_EEM_BNXT_LFC_IOCTL_MAGIC     0x98\n+#define BNXT_LFC_REQ    \\\n+\t_IOW(TF_EEM_BNXT_LFC_IOCTL_MAGIC, 1, struct tf_em_bnxt_lfc_req)\n+\n+/**\n+ * EM DBs.\n  */\n-static int\n-tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb __rte_unused,\n-\t\t    struct tf_insert_em_entry_parms *parms __rte_unused)\n+extern void *eem_db[TF_DIR_MAX];\n+\n+extern struct tf_tbl_scope_cb tbl_scopes[TF_NUM_TBL_SCOPE];\n+\n+static void\n+tf_em_dmabuf_mem_unmap(struct hcapi_cfa_em_table *tbl)\n {\n-\treturn 0;\n+\tstruct hcapi_cfa_em_page_tbl *tp;\n+\tint level;\n+\tuint32_t page_no, pg_count;\n+\n+\tfor (level = (tbl->num_lvl - 1); level < tbl->num_lvl; level++) {\n+\t\ttp = &tbl->pg_tbl[level];\n+\n+\t\tpg_count = tbl->page_cnt[level];\n+\t\tfor (page_no = 0; page_no < pg_count; page_no++) {\n+\t\t\tif (tp->pg_va_tbl != NULL &&\n+\t\t\t    tp->pg_va_tbl[page_no] != NULL &&\n+\t\t\t    tp->pg_size != 0) {\n+\t\t\t\t(void)munmap(tp->pg_va_tbl[page_no],\n+\t\t\t\t\t     tp->pg_size);\n+\t\t\t}\n+\t\t}\n+\n+\t\ttfp_free((void *)tp->pg_va_tbl);\n+\t\ttfp_free((void *)tp->pg_pa_tbl);\n+\t}\n }\n \n-/** delete EEM hash entry API\n+/**\n+ * Unregisters EM Ctx in Firmware\n+ *\n+ * [in] tfp\n+ *   Pointer to a TruFlow handle\n  *\n- * returns:\n- *   0\n- *   -EINVAL\t  - parameter error\n- *   TF_NO_SESSION    - bad session ID\n- *   TF_ERR_TBL_SCOPE - invalid table scope\n- *   TF_ERR_TBL_IF    - invalid table interface\n+ * [in] tbl_scope_cb\n+ *   Pointer to a table scope control block\n  *\n- * insert callback returns\n- *   0\n- *   TF_NO_EM_MATCH - entry not found\n+ * [in] dir\n+ *   Receive or transmit direction\n  */\n+static void\n+tf_em_ctx_unreg(struct tf_tbl_scope_cb *tbl_scope_cb,\n+\t\tint dir)\n+{\n+\tstruct hcapi_cfa_em_ctx_mem_info *ctxp =\n+\t\t&tbl_scope_cb->em_ctx_info[dir];\n+\tstruct hcapi_cfa_em_table *tbl;\n+\tint i;\n+\n+\tfor (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {\n+\t\ttbl = &ctxp->em_tables[i];\n+\t\t\ttf_em_dmabuf_mem_unmap(tbl);\n+\t}\n+}\n+\n+static int tf_export_tbl_scope(int lfc_fd,\n+\t\t\t       int *fd,\n+\t\t\t       int bus,\n+\t\t\t       int devfn)\n+{\n+\tstruct tf_em_bnxt_lfc_req tf_lfc_req;\n+\tstruct tf_em_bnxt_lfc_dmabuf_fd *dma_fd;\n+\tstruct tfp_calloc_parms  mparms;\n+\tint rc;\n+\n+\tmemset(&tf_lfc_req, 0, sizeof(struct tf_em_bnxt_lfc_req));\n+\ttf_lfc_req.hdr.ver = 1;\n+\ttf_lfc_req.hdr.bus = bus;\n+\ttf_lfc_req.hdr.devfn = devfn;\n+\ttf_lfc_req.hdr.req_type = TF_EM_BNXT_LFC_CFA_EEM_DMABUF_EXPORT_REQ;\n+\ttf_lfc_req.req.eem_dmabuf_export_req.flags = O_ACCMODE;\n+\ttf_lfc_req.req.eem_dmabuf_export_req.std.version = 1;\n+\n+\tmparms.nitems = 1;\n+\tmparms.size = sizeof(struct tf_em_bnxt_lfc_dmabuf_fd);\n+\tmparms.alignment = 0;\n+\ttfp_calloc(&mparms);\n+\tdma_fd = (struct tf_em_bnxt_lfc_dmabuf_fd *)mparms.mem_va;\n+\ttf_lfc_req.req.eem_dmabuf_export_req.dma_fd = dma_fd;\n+\n+\trc = ioctl(lfc_fd, BNXT_LFC_REQ, &tf_lfc_req);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"EXT EEM export chanel_fd %d, rc=%d\\n\",\n+\t\t\t    lfc_fd,\n+\t\t\t    rc);\n+\t\ttfp_free(dma_fd);\n+\t\treturn rc;\n+\t}\n+\n+\tmemcpy(fd, dma_fd->fd, sizeof(dma_fd->fd));\n+\ttfp_free(dma_fd);\n+\n+\treturn rc;\n+}\n+\n static int\n-tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb __rte_unused,\n-\t\t    struct tf_delete_em_entry_parms *parms __rte_unused)\n+tf_em_dmabuf_mem_map(struct hcapi_cfa_em_table *tbl,\n+\t\t     int dmabuf_fd)\n {\n+\tstruct hcapi_cfa_em_page_tbl *tp;\n+\tint level;\n+\tuint32_t page_no;\n+\tuint32_t pg_count;\n+\tuint32_t offset;\n+\tstruct tfp_calloc_parms parms;\n+\n+\tfor (level = (tbl->num_lvl - 1); level < tbl->num_lvl; level++) {\n+\t\ttp = &tbl->pg_tbl[level];\n+\n+\t\tpg_count = tbl->page_cnt[level];\n+\t\toffset = 0;\n+\n+\t\tparms.nitems = pg_count;\n+\t\tparms.size = sizeof(void *);\n+\t\tparms.alignment = 0;\n+\n+\t\tif ((tfp_calloc(&parms)) != 0)\n+\t\t\treturn -ENOMEM;\n+\n+\t\ttp->pg_va_tbl = parms.mem_va;\n+\t\tparms.nitems = pg_count;\n+\t\tparms.size = sizeof(void *);\n+\t\tparms.alignment = 0;\n+\n+\t\tif ((tfp_calloc(&parms)) != 0) {\n+\t\t\ttfp_free((void *)tp->pg_va_tbl);\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\n+\t\ttp->pg_pa_tbl = parms.mem_va;\n+\t\ttp->pg_count = 0;\n+\t\ttp->pg_size =  TF_EM_PAGE_SIZE;\n+\n+\t\tfor (page_no = 0; page_no < pg_count; page_no++) {\n+\t\t\ttp->pg_va_tbl[page_no] = mmap(NULL,\n+\t\t\t\t\t\t      TF_EM_PAGE_SIZE,\n+\t\t\t\t\t\t      PROT_READ | PROT_WRITE,\n+\t\t\t\t\t\t      MAP_SHARED,\n+\t\t\t\t\t\t      dmabuf_fd,\n+\t\t\t\t\t\t      offset);\n+\t\t\tif (tp->pg_va_tbl[page_no] == (void *)-1) {\n+\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\"MMap memory error. level:%d page:%d pg_count:%d - %s\\n\",\n+\t\t\t\t\t    level,\n+\t\t\t\t     page_no,\n+\t\t\t\t\t    pg_count,\n+\t\t\t\t\t    strerror(errno));\n+\t\t\t\treturn -ENOMEM;\n+\t\t\t}\n+\t\t\toffset += tp->pg_size;\n+\t\t\ttp->pg_count++;\n+\t\t}\n+\t}\n+\n \treturn 0;\n }\n \n-/** insert EM hash entry API\n- *\n- *    returns:\n- *    0       - Success\n- *    -EINVAL - Error\n- */\n-int\n-tf_em_insert_ext_sys_entry(struct tf *tfp __rte_unused,\n-\t\t\t   struct tf_insert_em_entry_parms *parms)\n+static int tf_mmap_tbl_scope(struct tf_tbl_scope_cb *tbl_scope_cb,\n+\t\t\t     enum tf_dir dir,\n+\t\t\t     int tbl_type,\n+\t\t\t     int dmabuf_fd)\n {\n-\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\tstruct hcapi_cfa_em_table *tbl;\n \n-\ttbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);\n-\tif (tbl_scope_cb == NULL) {\n-\t\tTFP_DRV_LOG(ERR, \"Invalid tbl_scope_cb\\n\");\n-\t\treturn -EINVAL;\n+\tif (tbl_type == TF_EFC_TABLE)\n+\t\treturn 0;\n+\n+\ttbl = &tbl_scope_cb->em_ctx_info[dir].em_tables[tbl_type];\n+\treturn tf_em_dmabuf_mem_map(tbl, dmabuf_fd);\n+}\n+\n+#define TF_LFC_DEVICE \"/dev/bnxt_lfc\"\n+\n+static int\n+tf_prepare_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)\n+{\n+\tint lfc_fd;\n+\n+\tlfc_fd = open(TF_LFC_DEVICE, O_RDWR);\n+\tif (!lfc_fd) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"EEM: open %s device error\\n\",\n+\t\t\t    TF_LFC_DEVICE);\n+\t\treturn -ENOENT;\n \t}\n \n-\treturn tf_insert_eem_entry\n-\t\t(tbl_scope_cb, parms);\n+\ttbl_scope_cb->lfc_fd = lfc_fd;\n+\n+\treturn 0;\n }\n \n-/** Delete EM hash entry API\n- *\n- *    returns:\n- *    0       - Success\n- *    -EINVAL - Error\n- */\n-int\n-tf_em_delete_ext_sys_entry(struct tf *tfp __rte_unused,\n-\t\t\t   struct tf_delete_em_entry_parms *parms)\n+static int\n+offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)\n {\n-\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\tint rc;\n+\tint dmabuf_fd;\n+\tenum tf_dir dir;\n+\tenum hcapi_cfa_em_table_type tbl_type;\n \n-\ttbl_scope_cb = tbl_scope_cb_find(parms->tbl_scope_id);\n-\tif (tbl_scope_cb == NULL) {\n-\t\tTFP_DRV_LOG(ERR, \"Invalid tbl_scope_cb\\n\");\n-\t\treturn -EINVAL;\n+\trc = tf_prepare_dmabuf_bnxt_lfc_device(tbl_scope_cb);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR, \"EEM: Prepare bnxt_lfc channel failed\\n\");\n+\t\treturn rc;\n \t}\n \n-\treturn tf_delete_eem_entry(tbl_scope_cb, parms);\n+\trc = tf_export_tbl_scope(tbl_scope_cb->lfc_fd,\n+\t\t\t\t (int *)tbl_scope_cb->fd,\n+\t\t\t\t tbl_scope_cb->bus,\n+\t\t\t\t tbl_scope_cb->devfn);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"export dmabuf fd failed\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\ttbl_scope_cb->valid = true;\n+\n+\tfor (dir = 0; dir < TF_DIR_MAX; dir++) {\n+\t\tfor (tbl_type = TF_KEY0_TABLE; tbl_type <\n+\t\t\t     TF_MAX_TABLE; tbl_type++) {\n+\t\t\tif (tbl_type == TF_EFC_TABLE)\n+\t\t\t\tcontinue;\n+\n+\t\t\tdmabuf_fd = tbl_scope_cb->fd[(dir ? 0 : 1)][tbl_type];\n+\t\t\trc = tf_mmap_tbl_scope(tbl_scope_cb,\n+\t\t\t\t\t       dir,\n+\t\t\t\t\t       tbl_type,\n+\t\t\t\t\t       dmabuf_fd);\n+\t\t\tif (rc) {\n+\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t\t    \"dir:%d tbl:%d mmap failed rc %d\\n\",\n+\t\t\t\t\t    dir,\n+\t\t\t\t\t    tbl_type,\n+\t\t\t\t\t    rc);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn 0;\n }\n \n-int\n-tf_em_ext_system_alloc(struct tf *tfp __rte_unused,\n-\t\t       struct tf_alloc_tbl_scope_parms *parms __rte_unused)\n+static int\n+tf_destroy_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)\n {\n+\tclose(tbl_scope_cb->lfc_fd);\n+\n \treturn 0;\n }\n \n-int\n-tf_em_ext_system_free(struct tf *tfp __rte_unused,\n-\t\t      struct tf_free_tbl_scope_parms *parms __rte_unused)\n+static int\n+tf_dmabuf_alloc(struct tf *tfp, struct tf_tbl_scope_cb *tbl_scope_cb)\n {\n+\tint rc;\n+\n+\trc = tfp_msg_hwrm_oem_cmd(tfp,\n+\t\t\t\t  tbl_scope_cb->em_ctx_info[TF_DIR_RX].\\\n+\t\t\t\t  em_tables[TF_KEY0_TABLE].num_entries);\n+\tif (rc)\n+\t\tPMD_DRV_LOG(ERR, \"EEM: Failed to prepare system memory rc:%d\\n\",\n+\t\t\t    rc);\n+\n \treturn 0;\n }\n \n-int tf_tbl_ext_system_set(struct tf *tfp __rte_unused,\n-\t\t\t  struct tf_tbl_set_parms *parms __rte_unused)\n+static int\n+tf_dmabuf_free(struct tf *tfp, struct tf_tbl_scope_cb *tbl_scope_cb)\n {\n+\tint rc;\n+\n+\trc = tfp_msg_hwrm_oem_cmd(tfp, 0);\n+\tif (rc)\n+\t\tTFP_DRV_LOG(ERR, \"EEM: Failed to cleanup system memory\\n\");\n+\n+\ttf_destroy_dmabuf_bnxt_lfc_device(tbl_scope_cb);\n+\n \treturn 0;\n }\n+\n+int\n+tf_em_ext_alloc(struct tf *tfp,\n+\t\tstruct tf_alloc_tbl_scope_parms *parms)\n+{\n+\tint rc;\n+\tstruct tf_session *tfs;\n+\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\tstruct tf_rm_allocate_parms aparms = { 0 };\n+\tstruct tf_free_tbl_scope_parms free_parms;\n+\tstruct tf_rm_free_parms fparms = { 0 };\n+\tint dir;\n+\tint i;\n+\tstruct hcapi_cfa_em_table *em_tables;\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+\taparms.rm_db = eem_db[TF_DIR_RX];\n+\taparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;\n+\taparms.index = (uint32_t *)&parms->tbl_scope_id;\n+\trc = tf_rm_allocate(&aparms);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to allocate table scope\\n\");\n+\t\treturn rc;\n+\t}\n+\n+\ttbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];\n+\ttbl_scope_cb->index = parms->tbl_scope_id;\n+\ttbl_scope_cb->tbl_scope_id = parms->tbl_scope_id;\n+\ttbl_scope_cb->bus = tfs->session_id.internal.bus;\n+\ttbl_scope_cb->devfn = tfs->session_id.internal.device;\n+\n+\tfor (dir = 0; dir < TF_DIR_MAX; dir++) {\n+\t\trc = tf_msg_em_qcaps(tfp,\n+\t\t\t\t     dir,\n+\t\t\t\t     &tbl_scope_cb->em_caps[dir]);\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"EEM: Unable to query for EEM capability,\"\n+\t\t\t\t    \" rc:%s\\n\",\n+\t\t\t\t    strerror(-rc));\n+\t\t\tgoto cleanup;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Validate and setup table sizes\n+\t */\n+\tif (tf_em_validate_num_entries(tbl_scope_cb, parms))\n+\t\tgoto cleanup;\n+\n+\trc = tf_dmabuf_alloc(tfp, tbl_scope_cb);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"System DMA buff alloc failed\\n\");\n+\t\treturn -EIO;\n+\t}\n+\n+\tfor (dir = 0; dir < TF_DIR_MAX; dir++) {\n+\t\tfor (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {\n+\n+\t\t\tif (i == TF_EFC_TABLE) {\n+\t\t\t\t/*TFP_DRV_LOG(WARNING,\n+\t\t\t\t\t    \"Not support EFC table in WH+\\n\");*/\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tem_tables =\n+\t\t\t\t&tbl_scope_cb->em_ctx_info[dir].em_tables[i];\n+\n+\t\t\trc = tf_em_size_table(em_tables, TF_EM_PAGE_SIZE);\n+\t\t\tif (rc) {\n+\t\t\t\tTFP_DRV_LOG(ERR, \"Size table failed\\n\");\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n+\t\t}\n+\n+\t\tem_tables = tbl_scope_cb->em_ctx_info[dir].em_tables;\n+\t\trc = tf_create_tbl_pool_external(dir,\n+\t\t\t\t\ttbl_scope_cb,\n+\t\t\t\t\tem_tables[TF_RECORD_TABLE].num_entries,\n+\t\t\t\t\tem_tables[TF_RECORD_TABLE].entry_size);\n+\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"%s TBL: Unable to allocate idx pools %s\\n\",\n+\t\t\t\t    tf_dir_2_str(dir),\n+\t\t\t\t    strerror(-rc));\n+\t\t\tgoto cleanup_full;\n+\t\t}\n+\t}\n+\n+\trc = offload_system_mmap(tbl_scope_cb);\n+\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"System alloc mmap failed\\n\");\n+\t\tgoto cleanup_full;\n+\t}\n+\n+\treturn rc;\n+\n+cleanup_full:\n+\tfree_parms.tbl_scope_id = parms->tbl_scope_id;\n+\ttf_em_ext_free(tfp, &free_parms);\n+\treturn -EINVAL;\n+\n+cleanup:\n+\t/* Free Table control block */\n+\tfparms.rm_db = eem_db[TF_DIR_RX];\n+\tfparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;\n+\tfparms.index = parms->tbl_scope_id;\n+\ttf_rm_free(&fparms);\n+\treturn -EINVAL;\n+}\n+\n+int\n+tf_em_ext_free(struct tf *tfp,\n+\t       struct tf_free_tbl_scope_parms *parms)\n+{\n+\tint rc;\n+\tstruct tf_session *tfs;\n+\tstruct tf_tbl_scope_cb *tbl_scope_cb;\n+\tint dir;\n+\tstruct tf_rm_free_parms aparms = { 0 };\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+\ttbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];\n+\n+\t\t/* Free Table control block */\n+\taparms.rm_db = eem_db[TF_DIR_RX];\n+\taparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;\n+\taparms.index = parms->tbl_scope_id;\n+\trc = tf_rm_free(&aparms);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Failed to free table scope\\n\");\n+\t}\n+\n+\tfor (dir = 0; dir < TF_DIR_MAX; dir++) {\n+\t\t/* Free associated external pools\n+\t\t */\n+\t\ttf_destroy_tbl_pool_external(dir,\n+\t\t\t\t\t     tbl_scope_cb);\n+\n+\t\t/* Unmap memory */\n+\t\ttf_em_ctx_unreg(tbl_scope_cb, dir);\n+\n+\t\ttf_msg_em_op(tfp,\n+\t\t\t     dir,\n+\t\t\t     HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_DISABLE);\n+\t}\n+\n+\ttf_dmabuf_free(tfp, tbl_scope_cb);\n+\n+\treturn rc;\n+}\ndiff --git a/drivers/net/bnxt/tf_core/tf_if_tbl.h b/drivers/net/bnxt/tf_core/tf_if_tbl.h\nindex 54d4c37..7eb72bd 100644\n--- a/drivers/net/bnxt/tf_core/tf_if_tbl.h\n+++ b/drivers/net/bnxt/tf_core/tf_if_tbl.h\n@@ -113,7 +113,7 @@ struct tf_if_tbl_set_parms {\n \t/**\n \t * [in] Entry data\n \t */\n-\tuint32_t *data;\n+\tuint8_t *data;\n \t/**\n \t * [in] Entry size\n \t */\n@@ -143,7 +143,7 @@ struct tf_if_tbl_get_parms {\n \t/**\n \t * [out] Entry data\n \t */\n-\tuint32_t *data;\n+\tuint8_t *data;\n \t/**\n \t * [out] Entry size\n \t */\ndiff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c\nindex 035c094..ed506de 100644\n--- a/drivers/net/bnxt/tf_core/tf_msg.c\n+++ b/drivers/net/bnxt/tf_core/tf_msg.c\n@@ -813,7 +813,19 @@ tf_msg_tcam_entry_set(struct tf *tfp,\n \tstruct tf_msg_dma_buf buf = { 0 };\n \tuint8_t *data = NULL;\n \tint data_size = 0;\n+\tuint8_t fw_session_id;\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(parms->dir),\n+\t\t\t    strerror(-rc));\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.type = parms->hcapi_type;\n \treq.idx = tfp_cpu_to_le_16(parms->idx);\n \tif (parms->dir == TF_DIR_TX)\n@@ -869,7 +881,19 @@ tf_msg_tcam_entry_free(struct tf *tfp,\n \tstruct hwrm_tf_tcam_free_input req =  { 0 };\n \tstruct hwrm_tf_tcam_free_output resp = { 0 };\n \tstruct tfp_send_msg_parms parms = { 0 };\n+\tuint8_t fw_session_id;\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(in_parms->dir),\n+\t\t\t    strerror(-rc));\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.type = in_parms->hcapi_type;\n \treq.count = 1;\n \treq.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);\ndiff --git a/drivers/net/bnxt/tf_core/tf_tbl.h b/drivers/net/bnxt/tf_core/tf_tbl.h\nindex 2a10b47..f20e8d7 100644\n--- a/drivers/net/bnxt/tf_core/tf_tbl.h\n+++ b/drivers/net/bnxt/tf_core/tf_tbl.h\n@@ -38,6 +38,13 @@ struct tf_em_caps {\n  */\n struct tf_tbl_scope_cb {\n \tuint32_t tbl_scope_id;\n+#ifdef TF_USE_SYSTEM_MEM\n+\tint lfc_fd;\n+\tuint32_t bus;\n+\tuint32_t devfn;\n+\tint fd[TF_DIR_MAX][TF_MAX_TABLE];\n+\tbool valid;\n+#endif\n \tint index;\n \tstruct hcapi_cfa_em_ctx_mem_info em_ctx_info[TF_DIR_MAX];\n \tstruct tf_em_caps em_caps[TF_DIR_MAX];\ndiff --git a/drivers/net/bnxt/tf_core/tfp.c b/drivers/net/bnxt/tf_core/tfp.c\nindex 426a182..3eade31 100644\n--- a/drivers/net/bnxt/tf_core/tfp.c\n+++ b/drivers/net/bnxt/tf_core/tfp.c\n@@ -87,6 +87,18 @@ tfp_send_msg_tunneled(struct tf *tfp,\n \treturn rc;\n }\n \n+#ifdef TF_USE_SYSTEM_MEM\n+int\n+tfp_msg_hwrm_oem_cmd(struct tf *tfp,\n+\t\t     uint32_t max_flows)\n+{\n+\treturn bnxt_hwrm_oem_cmd(container_of(tfp,\n+\t\t\t\t\t      struct bnxt,\n+\t\t\t\t\t      tfp),\n+\t\t\t\t max_flows);\n+}\n+#endif /* TF_USE_SYSTEM_MEM */\n+\n /**\n  * Allocates zero'ed memory from the heap.\n  *\ndiff --git a/drivers/net/bnxt/tf_core/tfp.h b/drivers/net/bnxt/tf_core/tfp.h\nindex 8789eba..421a7d9 100644\n--- a/drivers/net/bnxt/tf_core/tfp.h\n+++ b/drivers/net/bnxt/tf_core/tfp.h\n@@ -171,6 +171,21 @@ tfp_msg_hwrm_oem_cmd(struct tf *tfp,\n \t\t     uint32_t max_flows);\n \n /**\n+ * Sends OEM command message to Chimp\n+ *\n+ * [in] session, pointer to session handle\n+ * [in] max_flows, max number of flows requested\n+ *\n+ * Returns:\n+ *   0              - Success\n+ *   -1             - Global error like not supported\n+ *   -EINVAL        - Parameter Error\n+ */\n+int\n+tfp_msg_hwrm_oem_cmd(struct tf *tfp,\n+\t\t     uint32_t max_flows);\n+\n+/**\n  * Allocates zero'ed memory from the heap.\n  *\n  * NOTE: Also performs virt2phy address conversion by default thus is\n",
    "prefixes": [
        "31/50"
    ]
}