get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 95432,
    "url": "https://patches.dpdk.org/api/patches/95432/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210706223950.71669-1-ajit.khaparde@broadcom.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20210706223950.71669-1-ajit.khaparde@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210706223950.71669-1-ajit.khaparde@broadcom.com",
    "date": "2021-07-06T22:39:50",
    "name": "[v3] net/bnxt: shared TCAM region support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "fcf7bba6cb21c27929cc8dd204b8d31f614a66a0",
    "submitter": {
        "id": 501,
        "url": "https://patches.dpdk.org/api/people/501/?format=api",
        "name": "Ajit Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "https://patches.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210706223950.71669-1-ajit.khaparde@broadcom.com/mbox/",
    "series": [
        {
            "id": 17676,
            "url": "https://patches.dpdk.org/api/series/17676/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=17676",
            "date": "2021-07-06T22:39:50",
            "name": "[v3] net/bnxt: shared TCAM region support",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/17676/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/95432/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/95432/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 D1494A0C48;\n\tWed,  7 Jul 2021 00:39:56 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 500F14069E;\n\tWed,  7 Jul 2021 00:39:56 +0200 (CEST)",
            "from mail-pf1-f172.google.com (mail-pf1-f172.google.com\n [209.85.210.172])\n by mails.dpdk.org (Postfix) with ESMTP id 5BBF84003C\n for <dev@dpdk.org>; Wed,  7 Jul 2021 00:39:55 +0200 (CEST)",
            "by mail-pf1-f172.google.com with SMTP id q10so392470pfj.12\n for <dev@dpdk.org>; Tue, 06 Jul 2021 15:39:55 -0700 (PDT)",
            "from C02VPB22HTD6.wifi.broadcom.net ([192.19.223.252])\n by smtp.gmail.com with ESMTPSA id p24sm14761706pgl.68.2021.07.06.15.39.52\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Tue, 06 Jul 2021 15:39:53 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com;\n s=google;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version; bh=OItnJ2C76wuHwqV2ZODytXF5JhvBDlJG1B664XTaNSs=;\n b=Lpk+CVhX9+kmY1ZJSB0c1MDLXvc10mtfqs2bFxBaQXM/sT/2g95MN264Iu3+hUGR5Z\n vMi/TO9eE/ulVj2prx3TJzyDbpBhMsTg1uK813+s92OPo9sMiLsvZX4rjoIIckwpCvZ+\n 2e6zEoU0Ub2vju+GCTpWoKbnNT1v4gDJUN6W4=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20161025;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references:mime-version;\n bh=OItnJ2C76wuHwqV2ZODytXF5JhvBDlJG1B664XTaNSs=;\n b=ILQMttBHiMBu/kAGJJhkd7hvh7FoUrjRuwt7JJsuyNMu5d0Q1JHd70ToojNUi3z6to\n KmI78xHapdHb4ICNiLG18pCCkYE51Ihic3WGW5YTkPhxJI2nbbZ8iesV8wniLxSdTexK\n NUZ4+ZwIYCSwy8aERax0liv6ZsDZh681ULGA/ZCiPoK/5FxJYJqsEtRppfairL4vG5da\n le6xrlba1XlfiXvx/s3cKCrUJ0m31LisLbX0TOhX4ncs9sqmZQDPFv1UZ7NY9MK5X/Q7\n 9pu096eElzD0FJ6d/hgGmJDOT1TMIDagbd4ZgYqSLwRIeid4IwXICkKkmTTLOMDHRP51\n 3xJw==",
        "X-Gm-Message-State": "AOAM531Hs70Y4Y2Co5L/5hYfNjLNTB5HR/7jsMu1Ptt2NKLPQZgSm48x\n EwE3rMbtYm3tb+tmjat9ayrQBZHRa6ddfCAzWihsnZjfTflZxfqsiVjqFHVRMzqH35NslfWT5Ug\n beyh1NEu93ihXDm6vz4hZywIrelzw/hRwU5e2h7ri+mjHIY6GMU/Y+KNHYyRLvbo=",
        "X-Google-Smtp-Source": "\n ABdhPJwZyjzEEg12awoJ3C6SQIntRX8vMPkEhR/ddd7f0G9ig/Vz+MCzy1t50vFBervh8ra+b6d/cQ==",
        "X-Received": "by 2002:aa7:8749:0:b029:2f1:3dd0:674 with SMTP id\n g9-20020aa787490000b02902f13dd00674mr22128020pfo.65.1625611193893;\n Tue, 06 Jul 2021 15:39:53 -0700 (PDT)",
        "From": "Ajit Khaparde <ajit.khaparde@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, Farah Smith <farah.smith@broadcom.com>,\n Jay Ding <jay.ding@broadcom.com>,\n Randy Schacher <stuart.schacher@broadcom.com>,\n Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>",
        "Date": "Tue,  6 Jul 2021 15:39:50 -0700",
        "Message-Id": "<20210706223950.71669-1-ajit.khaparde@broadcom.com>",
        "X-Mailer": "git-send-email 2.21.1 (Apple Git-122.3)",
        "In-Reply-To": "<1652269.30VuKb5ZA0@thomas>",
        "References": "<1652269.30VuKb5ZA0@thomas>",
        "MIME-Version": "1.0",
        "Content-Type": "multipart/signed; protocol=\"application/pkcs7-signature\";\n micalg=sha-256; boundary=\"000000000000cb97c205c67c1902\"",
        "X-Content-Filtered-By": "Mailman/MimeDel 2.1.29",
        "Subject": "[dpdk-dev] [PATCH v3] net/bnxt: shared TCAM region 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: Farah Smith <farah.smith@broadcom.com>\n\n- switch to single slice management on Wh+\n- Support of shared session WC_TCAM_HIGH and WC_TCAM_LOW regions\n- Enable/disable using TF_TCAM_SHARED flag in tf_core.h\n- Fix empty session module DBs in the case that none are\n  allocated for a given module type\n\nSigned-off-by: Farah Smith <farah.smith@broadcom.com>\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: Ajit Khaparde <ajit.khaparde@broadcom.com>\n---\nv1->v2: rebased to latest code base.\nv2->v3: addressed review comments.\n---\n drivers/net/bnxt/tf_core/meson.build      |  25 +-\n drivers/net/bnxt/tf_core/tf_core.h        |  45 +-\n drivers/net/bnxt/tf_core/tf_device.c      |  72 ++-\n drivers/net/bnxt/tf_core/tf_device.h      |   4 +-\n drivers/net/bnxt/tf_core/tf_device_p4.c   |  17 +-\n drivers/net/bnxt/tf_core/tf_device_p58.c  |  13 +-\n drivers/net/bnxt/tf_core/tf_identifier.c  |   2 +-\n drivers/net/bnxt/tf_core/tf_tbl.c         |   5 +-\n drivers/net/bnxt/tf_core/tf_tcam.c        |   5 +-\n drivers/net/bnxt/tf_core/tf_tcam_shared.c | 743 ++++++++++++++++++++++\n drivers/net/bnxt/tf_core/tf_tcam_shared.h | 127 ++++\n drivers/net/bnxt/tf_core/tf_util.c        |   6 +\n 12 files changed, 1013 insertions(+), 51 deletions(-)\n create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_shared.c\n create mode 100644 drivers/net/bnxt/tf_core/tf_tcam_shared.h",
    "diff": "diff --git a/drivers/net/bnxt/tf_core/meson.build b/drivers/net/bnxt/tf_core/meson.build\nindex 3a91f04bc0..f28e77ec2e 100644\n--- a/drivers/net/bnxt/tf_core/meson.build\n+++ b/drivers/net/bnxt/tf_core/meson.build\n@@ -10,26 +10,27 @@ sources += files(\n         'tf_core.c',\n         'bitalloc.c',\n         'tf_msg.c',\n-\t'dpool.c',\n+        'll.c',\n+        'dpool.c',\n         'rand.c',\n         'stack.c',\n-        'tf_em_common.c',\n-        'tf_em_internal.c',\n         'tf_rm.c',\n         'tf_tbl.c',\n+        'tf_em_common.c',\n+        'tf_em_host.c',\n+        'tf_em_internal.c',\n+        'tf_em_hash_internal.c',\n         'tfp.c',\n-        'tf_session.c',\n+        'tf_util.c',\n         'tf_device.c',\n         'tf_device_p4.c',\n-        'tf_device_p58.c',\n+        'tf_global_cfg.c',\n         'tf_identifier.c',\n+        'tf_if_tbl.c',\n+        'tf_session.c',\n         'tf_shadow_tcam.c',\n         'tf_tcam.c',\n-        'tf_util.c',\n-        'tf_if_tbl.c',\n-        'll.c',\n-        'tf_global_cfg.c',\n-        'tf_em_host.c',\n-        'tf_em_hash_internal.c',\n+        'tf_tcam_shared.c',\n         'tf_shadow_identifier.c',\n-        'tf_hash.c')\n+        'tf_hash.c',\n+        'tf_device_p58.c')\ndiff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h\nindex 3d14dc5391..39a498122b 100644\n--- a/drivers/net/bnxt/tf_core/tf_core.h\n+++ b/drivers/net/bnxt/tf_core/tf_core.h\n@@ -21,7 +21,6 @@\n \n /********** BEGIN Truflow Core DEFINITIONS **********/\n \n-\n #define TF_KILOBYTE  1024\n #define TF_MEGABYTE  (1024 * 1024)\n \n@@ -77,7 +76,6 @@ enum tf_ext_mem_chan_type {\n #define TF_ACT_REC_OFFSET_2_PTR(offset) ((offset) >> 4)\n #define TF_ACT_REC_PTR_2_OFFSET(offset) ((offset) << 4)\n \n-\n /*\n  * Helper Macros\n  */\n@@ -198,7 +196,6 @@ enum tf_module_type {\n \tTF_MODULE_TYPE_MAX\n };\n \n-\n /**\n  * Identifier resource types\n  */\n@@ -317,6 +314,41 @@ enum tf_tbl_type {\n \tTF_TBL_TYPE_MAX\n };\n \n+/** Enable Shared TCAM Management\n+ *\n+ *  This feature allows for management of high and low pools within\n+ *  the WC TCAM.  These pools are only valid when this feature is enabled.\n+ *\n+ *  For normal OVS-DPDK operation, this feature is not required and can\n+ *  be disabled by commenting out TF_TCAM_SHARED in this header file.\n+ *\n+ *  Operation:\n+ *\n+ *  When a shared session is created with WC TCAM entries allocated during\n+ *  tf_open_session(), the TF_TCAM_TBL_TYPE_WC_TCAM pool entries will be divided\n+ *  into 2 equal pools - TF_TCAM_TBL_TYPE_WC_TCAM_HIGH and\n+ *  TF_TCAM_TBL_TYPE_WC_TCAM_LOW.\n+ *\n+ *  The user will allocate and free entries from either of these pools to obtain\n+ *  WC_TCAM entry offsets.  For the WC_TCAM_HI/LO management, alloc/free is done\n+ *  using the tf_alloc_tcam_entry()/tf_free_tcam_entry() APIs for the shared\n+ *  session.\n+ *\n+ *  The use case for this feature is so that applications can have a shared\n+ *  session and use the TF core to allocate/set/free entries within a given\n+ *  region of the WC_TCAM within the shared session.  Application A only writes\n+ *  to the LOW region for example and Application B only writes to the HIGH\n+ *  region during normal operation.  After Application A goes down, Application\n+ *  B may decide to overwrite the LOW region with the HIGH region's entries\n+ *  and switch to the low region.\n+ *\n+ *  For other TCAM types in the  shared session, no alloc/free operations are\n+ *  permitted. Only set should be used for other TCAM table types after getting\n+ *  the range as provided by the tf_get_resource_info() API.\n+ *\n+ */\n+#define TF_TCAM_SHARED 1\n+\n /**\n  * TCAM table type\n  */\n@@ -335,6 +367,12 @@ enum tf_tcam_tbl_type {\n \tTF_TCAM_TBL_TYPE_CT_RULE_TCAM,\n \t/** Virtual Edge Bridge TCAM */\n \tTF_TCAM_TBL_TYPE_VEB_TCAM,\n+#ifdef TF_TCAM_SHARED\n+\t/** Wildcard TCAM HI Priority */\n+\tTF_TCAM_TBL_TYPE_WC_TCAM_HIGH,\n+\t/** Wildcard TCAM Low Priority */\n+\tTF_TCAM_TBL_TYPE_WC_TCAM_LOW,\n+#endif /* TF_TCAM_SHARED */\n \tTF_TCAM_TBL_TYPE_MAX\n };\n \n@@ -1044,7 +1082,6 @@ int tf_search_identifier(struct tf *tfp,\n  * Current thought is that memory is allocated within core.\n  */\n \n-\n /**\n  * tf_alloc_tbl_scope_parms definition\n  */\ndiff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c\nindex 97ae73fa5a..55cf55886a 100644\n--- a/drivers/net/bnxt/tf_core/tf_device.c\n+++ b/drivers/net/bnxt/tf_core/tf_device.c\n@@ -9,6 +9,9 @@\n #include \"tfp.h\"\n #include \"tf_em.h\"\n #include \"tf_rm.h\"\n+#ifdef TF_TCAM_SHARED\n+#include \"tf_tcam_shared.h\"\n+#endif /* TF_TCAM_SHARED */\n \n struct tf;\n \n@@ -92,6 +95,12 @@ tf_dev_bind_p4(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/* Retrieve the session information */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc)\n+\t\treturn rc;\n \n \t/* Initial function initialization */\n \tdev_handle->ops = &tf_dev_ops_p4_init;\n@@ -142,7 +151,11 @@ tf_dev_bind_p4(struct tf *tfp,\n \t\ttcam_cfg.cfg = tf_tcam_p4;\n \t\ttcam_cfg.shadow_copy = shadow_copy;\n \t\ttcam_cfg.resources = resources;\n+#ifdef TF_TCAM_SHARED\n+\t\trc = tf_tcam_shared_bind(tfp, &tcam_cfg);\n+#else /* !TF_TCAM_SHARED */\n \t\trc = tf_tcam_bind(tfp, &tcam_cfg);\n+#endif\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t    \"TCAM initialization failure\\n\");\n@@ -203,31 +216,32 @@ tf_dev_bind_p4(struct tf *tfp,\n \t\treturn -ENOMEM;\n \t}\n \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_p4;\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\t/*\n+\t\t * IF_TBL\n+\t\t */\n+\t\tif_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX;\n+\t\tif_tbl_cfg.cfg = tf_if_tbl_p4;\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_p4;\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_p4;\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 \tdev_handle->ops = &tf_dev_ops_p4;\n \n@@ -265,7 +279,11 @@ tf_dev_unbind_p4(struct tf *tfp)\n \t * In case of residuals TCAMs are cleaned up first as to\n \t * invalidate the pipeline in a clean manner.\n \t */\n+#ifdef TF_TCAM_SHARED\n+\trc = tf_tcam_shared_unbind(tfp);\n+#else /* !TF_TCAM_SHARED */\n \trc = tf_tcam_unbind(tfp);\n+#endif /* TF_TCAM_SHARED */\n \tif (rc) {\n \t\tTFP_DRV_LOG(INFO,\n \t\t\t    \"Device unbind failed, TCAM\\n\");\n@@ -407,7 +425,11 @@ tf_dev_bind_p58(struct tf *tfp,\n \t\ttcam_cfg.cfg = tf_tcam_p58;\n \t\ttcam_cfg.shadow_copy = shadow_copy;\n \t\ttcam_cfg.resources = resources;\n+#ifdef TF_TCAM_SHARED\n+\t\trc = tf_tcam_shared_bind(tfp, &tcam_cfg);\n+#else /* !TF_TCAM_SHARED */\n \t\trc = tf_tcam_bind(tfp, &tcam_cfg);\n+#endif\n \t\tif (rc) {\n \t\t\tTFP_DRV_LOG(ERR,\n \t\t\t\t    \"TCAM initialization failure\\n\");\n@@ -517,7 +539,11 @@ tf_dev_unbind_p58(struct tf *tfp)\n \t * In case of residuals TCAMs are cleaned up first as to\n \t * invalidate the pipeline in a clean manner.\n \t */\n+#ifdef TF_TCAM_SHARED\n+\trc = tf_tcam_shared_unbind(tfp);\n+#else /* !TF_TCAM_SHARED */\n \trc = tf_tcam_unbind(tfp);\n+#endif /* TF_TCAM_SHARED */\n \tif (rc) {\n \t\tTFP_DRV_LOG(INFO,\n \t\t\t    \"Device unbind failed, TCAM\\n\");\ndiff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h\nindex 31806bb289..ea4dcfb8e2 100644\n--- a/drivers/net/bnxt/tf_core/tf_device.h\n+++ b/drivers/net/bnxt/tf_core/tf_device.h\n@@ -10,6 +10,9 @@\n #include \"tf_identifier.h\"\n #include \"tf_tbl.h\"\n #include \"tf_tcam.h\"\n+#ifdef TF_TCAM_SHARED\n+#include \"tf_tcam_shared.h\"\n+#endif\n #include \"tf_if_tbl.h\"\n #include \"tf_global_cfg.h\"\n \n@@ -136,7 +139,6 @@ struct tf_dev_ops {\n \t\t\t\t       uint16_t resource_id,\n \t\t\t\t       const char **resource_str);\n \n-\n \t/**\n \t * Retrieves the WC TCAM slice information that the device\n \t * supports.\ndiff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c\nindex e74ba6cd8f..0d3c35ae3b 100644\n--- a/drivers/net/bnxt/tf_core/tf_device_p4.c\n+++ b/drivers/net/bnxt/tf_core/tf_device_p4.c\n@@ -10,6 +10,9 @@\n #include \"tf_identifier.h\"\n #include \"tf_tbl.h\"\n #include \"tf_tcam.h\"\n+#ifdef TF_TCAM_SHARED\n+#include \"tf_tcam_shared.h\"\n+#endif /* TF_TCAM_SHARED */\n #include \"tf_em.h\"\n #include \"tf_if_tbl.h\"\n #include \"tfp.h\"\n@@ -137,7 +140,8 @@ tf_dev_p4_get_tcam_slice_info(struct tf *tfp __rte_unused,\n \t\t\t      uint16_t key_sz,\n \t\t\t      uint16_t *num_slices_per_row)\n {\n-#define CFA_P4_WC_TCAM_SLICES_PER_ROW 2\n+/* Single slice support */\n+#define CFA_P4_WC_TCAM_SLICES_PER_ROW 1\n #define CFA_P4_WC_TCAM_SLICE_SIZE     12\n \n \tif (type == TF_TCAM_TBL_TYPE_WC_TCAM) {\n@@ -263,11 +267,18 @@ const struct tf_dev_ops tf_dev_ops_p4 = {\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+#ifdef TF_TCAM_SHARED\n+\t.tf_dev_alloc_tcam = tf_tcam_shared_alloc,\n+\t.tf_dev_free_tcam = tf_tcam_shared_free,\n+\t.tf_dev_set_tcam = tf_tcam_shared_set,\n+\t.tf_dev_get_tcam = tf_tcam_shared_get,\n+#else /* !TF_TCAM_SHARED */\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 = tf_tcam_get,\n+#endif\n+\t.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,\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,\ndiff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c\nindex a5b055bac7..5bf52379a7 100644\n--- a/drivers/net/bnxt/tf_core/tf_device_p58.c\n+++ b/drivers/net/bnxt/tf_core/tf_device_p58.c\n@@ -10,6 +10,9 @@\n #include \"tf_identifier.h\"\n #include \"tf_tbl.h\"\n #include \"tf_tcam.h\"\n+#ifdef TF_TCAM_SHARED\n+#include \"tf_tcam_shared.h\"\n+#endif /* TF_TCAM_SHARED */\n #include \"tf_em.h\"\n #include \"tf_if_tbl.h\"\n #include \"tfp.h\"\n@@ -148,7 +151,6 @@ static int tf_dev_p58_word_align(uint16_t size)\n \treturn ((((size) + 63) >> 6) * 8);\n }\n \n-\n #define TF_DEV_P58_BANK_SZ_64B 2048\n /**\n  * Get SRAM table information.\n@@ -287,11 +289,18 @@ const struct tf_dev_ops tf_dev_ops_p58 = {\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+#ifdef TF_TCAM_SHARED\n+\t.tf_dev_alloc_tcam = tf_tcam_shared_alloc,\n+\t.tf_dev_free_tcam = tf_tcam_shared_free,\n+\t.tf_dev_set_tcam = tf_tcam_set,\n+\t.tf_dev_get_tcam = tf_tcam_get,\n+#else /* !TF_TCAM_SHARED */\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+#endif\n+\t.tf_dev_alloc_search_tcam = tf_tcam_alloc_search,\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,\ndiff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c\nindex 3cc87de4ef..3575c3e1a0 100644\n--- a/drivers/net/bnxt/tf_core/tf_identifier.c\n+++ b/drivers/net/bnxt/tf_core/tf_identifier.c\n@@ -76,7 +76,7 @@ tf_ident_bind(struct tf *tfp,\n \t\t\tdb_rc[i] = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (db_rc[i]) {\n \t\t\tTFP_DRV_LOG(INFO,\n-\t\t\t\t    \"%s: Identifier DB creation failed\\n\",\n+\t\t\t\t    \"%s: No Identifier DB required\\n\",\n \t\t\t\t    tf_dir_2_str(i));\n \t\t}\n \ndiff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c\nindex 192115183b..295204ac87 100644\n--- a/drivers/net/bnxt/tf_core/tf_tbl.c\n+++ b/drivers/net/bnxt/tf_core/tf_tbl.c\n@@ -85,7 +85,7 @@ tf_tbl_bind(struct tf *tfp,\n \t\t\tdb_rc[d] = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (db_rc[d]) {\n \t\t\tTFP_DRV_LOG(ERR,\n-\t\t\t\t    \"%s: Table DB creation failed\\n\",\n+\t\t\t\t    \"%s: No Table DB creation required\\n\",\n \t\t\t\t    tf_dir_2_str(d));\n \n \t\t}\n@@ -656,7 +656,6 @@ tf_tbl_get_resc_info(struct tf *tfp,\n \t}\n \ttbl_db = (struct tbl_rm_db *)tbl_db_ptr;\n \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@@ -693,7 +692,5 @@ tf_tbl_get_resc_info(struct tf *tfp,\n \t\t}\n \t}\n \n-\n-\n \treturn 0;\n }\ndiff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c\nindex ce959e3923..5c018f7003 100644\n--- a/drivers/net/bnxt/tf_core/tf_tcam.c\n+++ b/drivers/net/bnxt/tf_core/tf_tcam.c\n@@ -115,7 +115,7 @@ tf_tcam_bind(struct tf *tfp,\n \t\t\tdb_rc[d] = tf_rm_create_db(tfp, &db_cfg);\n \t\tif (db_rc[d]) {\n \t\t\tTFP_DRV_LOG(INFO,\n-\t\t\t\t    \"%s: TCAM DB creation failed\\n\",\n+\t\t\t\t    \"%s: no TCAM DB required\\n\",\n \t\t\t\t    tf_dir_2_str(d));\n \t\t}\n \t}\n@@ -126,6 +126,9 @@ tf_tcam_bind(struct tf *tfp,\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\tif (!tcam_db->tcam_db[d])\n+\t\t\tcontinue;\n+\n \t\tmemset(&info, 0, sizeof(info));\n \t\tainfo.rm_db = tcam_db->tcam_db[d];\n \t\tainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;\ndiff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.c b/drivers/net/bnxt/tf_core/tf_tcam_shared.c\nnew file mode 100644\nindex 0000000000..18beae78bb\n--- /dev/null\n+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.c\n@@ -0,0 +1,743 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019-2021 Broadcom\n+ * All rights reserved.\n+ */\n+\n+#include <string.h>\n+#include <rte_common.h>\n+\n+#include \"tf_tcam_shared.h\"\n+#include \"tf_tcam.h\"\n+#include \"tf_common.h\"\n+#include \"tf_util.h\"\n+#include \"tf_rm.h\"\n+#include \"tf_device.h\"\n+#include \"tfp.h\"\n+#include \"tf_session.h\"\n+#include \"tf_msg.h\"\n+#include \"bitalloc.h\"\n+#include \"tf_core.h\"\n+\n+struct tf;\n+\n+/** Shared WC TCAM pool identifiers\n+ */\n+enum tf_tcam_shared_wc_pool_id {\n+\tTF_TCAM_SHARED_WC_POOL_HI  = 0,\n+\tTF_TCAM_SHARED_WC_POOL_LO  = 1,\n+\tTF_TCAM_SHARED_WC_POOL_MAX = 2\n+};\n+\n+/** Get string representation of a WC TCAM shared pool id\n+ */\n+static const char *\n+tf_pool_2_str(enum tf_tcam_shared_wc_pool_id id)\n+{\n+\tswitch (id) {\n+\tcase TF_TCAM_SHARED_WC_POOL_HI:\n+\t\treturn \"TCAM_SHARED_WC_POOL_HI\";\n+\tcase TF_TCAM_SHARED_WC_POOL_LO:\n+\t\treturn \"TCAM_SHARED_WC_POOL_LO\";\n+\tdefault:\n+\t\treturn \"Invalid TCAM_SHARED_WC_POOL\";\n+\t}\n+}\n+\n+/** The WC TCAM shared pool datastructure\n+ */\n+struct tf_tcam_shared_wc_pool {\n+\t/** Start and stride data */\n+\tstruct tf_resource_info info;\n+\t/** bitalloc pool */\n+\tstruct bitalloc *pool;\n+};\n+\n+/** The WC TCAM shared pool declarations\n+ * TODO: add tcam_shared_wc_db\n+ */\n+struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX];\n+\n+/** Create a WC TCAM shared pool\n+ */\n+static int\n+tf_tcam_shared_create_wc_pool(int dir,\n+\t\t\t      enum tf_tcam_shared_wc_pool_id id,\n+\t\t\t      int start,\n+\t\t\t      int stride)\n+{\n+\tint rc = 0;\n+\tbool free = true;\n+\tstruct tfp_calloc_parms cparms;\n+\tuint32_t pool_size;\n+\n+\t/* Create pool */\n+\tpool_size = (BITALLOC_SIZEOF(stride) / sizeof(struct bitalloc));\n+\tcparms.nitems = pool_size;\n+\tcparms.alignment = 0;\n+\tcparms.size = sizeof(struct bitalloc);\n+\trc = tfp_calloc(&cparms);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: pool memory alloc failed %s:%s\\n\",\n+\t\t\t    tf_dir_2_str(dir), tf_pool_2_str(id),\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\ttcam_shared_wc[dir][id].pool = (struct bitalloc *)cparms.mem_va;\n+\n+\trc = ba_init(tcam_shared_wc[dir][id].pool,\n+\t\t     stride,\n+\t\t     free);\n+\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: pool bitalloc failed %s\\n\",\n+\t\t\t    tf_dir_2_str(dir), tf_pool_2_str(id));\n+\t\treturn rc;\n+\t}\n+\n+\ttcam_shared_wc[dir][id].info.start = start;\n+\ttcam_shared_wc[dir][id].info.stride = stride;\n+\treturn rc;\n+}\n+/** Free a WC TCAM shared pool\n+ */\n+static void\n+tf_tcam_shared_free_wc_pool(int dir,\n+\t\t\t    enum tf_tcam_shared_wc_pool_id id)\n+{\n+\ttcam_shared_wc[dir][id].info.start = 0;\n+\ttcam_shared_wc[dir][id].info.stride = 0;\n+\n+\tif (tcam_shared_wc[dir][id].pool)\n+\t\ttfp_free((void *)tcam_shared_wc[dir][id].pool);\n+}\n+\n+/** Get the number of WC TCAM slices allocated during 1 allocation/free\n+ */\n+static int\n+tf_tcam_shared_get_slices(struct tf *tfp,\n+\t\t\t  struct tf_dev_info *dev,\n+\t\t\t  uint16_t *num_slices)\n+{\n+\tint rc;\n+\n+\tif (dev->ops->tf_dev_get_tcam_slice_info == NULL) {\n+\t\trc = -EOPNOTSUPP;\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Operation not supported, rc:%s\\n\", strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\trc = dev->ops->tf_dev_get_tcam_slice_info(tfp,\n+\t\t\t\t\t\t  TF_TCAM_TBL_TYPE_WC_TCAM,\n+\t\t\t\t\t\t  0,\n+\t\t\t\t\t\t  num_slices);\n+\treturn rc;\n+}\n+\n+static bool\n+tf_tcam_shared_db_valid(struct tf *tfp,\n+\t\t\tenum tf_dir dir)\n+{\n+\tstruct tcam_rm_db *tcam_db;\n+\tvoid *tcam_db_ptr = NULL;\n+\tint rc;\n+\n+\tTF_CHECK_PARMS1(tfp);\n+\n+\trc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);\n+\tif (rc)\n+\t\treturn false;\n+\n+\ttcam_db = (struct tcam_rm_db *)tcam_db_ptr;\n+\n+\tif (tcam_db->tcam_db[dir])\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n+static int\n+tf_tcam_shared_get_rm_info(struct tf *tfp,\n+\t\t\t   enum tf_dir dir,\n+\t\t\t   uint16_t *hcapi_type,\n+\t\t\t   struct tf_rm_alloc_info *info)\n+{\n+\tint rc;\n+\tstruct tcam_rm_db *tcam_db;\n+\tvoid *tcam_db_ptr = NULL;\n+\tstruct tf_rm_get_alloc_info_parms ainfo;\n+\tstruct tf_rm_get_hcapi_parms hparms;\n+\n+\tTF_CHECK_PARMS3(tfp, hcapi_type, info);\n+\n+\trc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(INFO,\n+\t\t\t    \"Tcam_db is not initialized, rc:%s\\n\",\n+\t\t\t    strerror(-rc));\n+\t\treturn 0;\n+\t}\n+\ttcam_db = (struct tcam_rm_db *)tcam_db_ptr;\n+\n+\t/* Convert TF type to HCAPI RM type */\n+\tmemset(&hparms, 0, sizeof(hparms));\n+\thparms.rm_db = tcam_db->tcam_db[dir];\n+\thparms.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;\n+\thparms.hcapi_type = hcapi_type;\n+\n+\trc = tf_rm_get_hcapi_type(&hparms);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: Get RM hcapi type failed %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+\tmemset(info, 0, sizeof(struct tf_rm_alloc_info));\n+\tainfo.rm_db = tcam_db->tcam_db[dir];\n+\tainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;\n+\tainfo.info = info;\n+\n+\trc = tf_rm_get_info(&ainfo);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: TCAM rm info get failed %s\\n\",\n+\t\t\t    tf_dir_2_str(dir),\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\treturn rc;\n+}\n+\n+/**\n+ * tf_tcam_shared_bind\n+ */\n+int\n+tf_tcam_shared_bind(struct tf *tfp,\n+\t\t    struct tf_tcam_cfg_parms *parms)\n+{\n+\tint rc, dir;\n+\tstruct tf_session *tfs;\n+\tstruct tf_dev_info *dev;\n+\tstruct tf_rm_alloc_info info;\n+\tuint16_t start, stride;\n+\tuint16_t num_slices;\n+\tuint16_t hcapi_type;\n+\n+\tTF_CHECK_PARMS2(tfp, parms);\n+\n+\t/* Perform normal bind\n+\t */\n+\trc = tf_tcam_bind(tfp, parms);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* After the normal TCAM bind, if this is a shared session\n+\t * create all required databases for the WC_HI and WC_LO pools\n+\t */\n+\trc = tf_session_get_session_internal(tfp, &tfs);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"Session access failure: %s\\n\", strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\tif (tf_session_is_shared_session(tfs)) {\n+\t\t/* Retrieve the device information */\n+\t\trc = tf_session_get_device(tfs, &dev);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\trc = tf_tcam_shared_get_slices(tfp,\n+\t\t\t\t\t       dev,\n+\t\t\t\t\t       &num_slices);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\n+\t\t/* If there are WC TCAM entries, create 2 pools each with 1/2\n+\t\t * the total number of entries\n+\t\t */\n+\t\tfor (dir = 0; dir < TF_DIR_MAX; dir++) {\n+\t\t\tif (!tf_tcam_shared_db_valid(tfp, dir))\n+\t\t\t\tcontinue;\n+\n+\t\t\trc = tf_tcam_shared_get_rm_info(tfp,\n+\t\t\t\t\t\t\tdir,\n+\t\t\t\t\t\t\t&hcapi_type,\n+\t\t\t\t\t\t\t&info);\n+\t\t\tif (rc) {\n+\t\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t\t    \"%s: TCAM rm info get failed\\n\",\n+\t\t\t\t\t    tf_dir_2_str(dir));\n+\t\t\t\tgoto done;\n+\t\t\t}\n+\n+\t\t\tstart = info.entry.start;\n+\t\t\tstride = info.entry.stride / 2;\n+\n+\t\t\ttf_tcam_shared_create_wc_pool(dir,\n+\t\t\t\t\t\tTF_TCAM_SHARED_WC_POOL_HI,\n+\t\t\t\t\t\tstart,\n+\t\t\t\t\t\tstride);\n+\n+\t\t\tstart += stride;\n+\t\t\ttf_tcam_shared_create_wc_pool(dir,\n+\t\t\t\t\t\tTF_TCAM_SHARED_WC_POOL_LO,\n+\t\t\t\t\t\tstart,\n+\t\t\t\t\t\tstride);\n+\t\t}\n+\t}\n+done:\n+\treturn rc;\n+}\n+/**\n+ * tf_tcam_shared_unbind\n+ */\n+int\n+tf_tcam_shared_unbind(struct tf *tfp)\n+{\n+\tint rc, dir;\n+\tstruct tf_session *tfs;\n+\n+\tTF_CHECK_PARMS1(tfp);\n+\n+\t/* Perform normal unbind, this will write all the\n+\t * allocated TCAM entries in the shared session.\n+\t */\n+\trc = tf_tcam_unbind(tfp);\n+\tif (rc)\n+\t\treturn rc;\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/* If we are the shared session\n+\t */\n+\tif (tf_session_is_shared_session(tfs)) {\n+\t\t/* If there are WC TCAM entries allocated, free them\n+\t\t */\n+\t\tfor (dir = 0; dir < TF_DIR_MAX; dir++) {\n+\t\t\ttf_tcam_shared_free_wc_pool(dir,\n+\t\t\t\t\t\t    TF_TCAM_SHARED_WC_POOL_HI);\n+\t\t\ttf_tcam_shared_free_wc_pool(dir,\n+\t\t\t\t\t\t    TF_TCAM_SHARED_WC_POOL_LO);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+/**\n+ * tf_tcam_shared_alloc\n+ */\n+int\n+tf_tcam_shared_alloc(struct tf *tfp,\n+\t\t     struct tf_tcam_alloc_parms *parms)\n+{\n+\tint rc, i;\n+\tstruct tf_session *tfs;\n+\tstruct tf_dev_info *dev;\n+\tint log_idx;\n+\tstruct bitalloc *pool;\n+\tenum tf_tcam_shared_wc_pool_id id;\n+\tuint16_t num_slices;\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/* If we aren't the shared session or the type is\n+\t * not one of the special WC TCAM types, call the normal\n+\t * allocation.\n+\t */\n+\tif (!tf_session_is_shared_session(tfs) ||\n+\t    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&\n+\t     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {\n+\t\t/* Perform normal alloc\n+\t\t */\n+\t\trc = tf_tcam_alloc(tfp, parms);\n+\t\treturn rc;\n+\t}\n+\n+\tif (!tf_tcam_shared_db_valid(tfp, parms->dir)) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: tcam shared pool doesn't exist\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tif (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)\n+\t\tid = TF_TCAM_SHARED_WC_POOL_HI;\n+\telse\n+\t\tid = TF_TCAM_SHARED_WC_POOL_LO;\n+\n+\t/* Retrieve the device information */\n+\trc = tf_session_get_device(tfs, &dev);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tpool = tcam_shared_wc[parms->dir][id].pool;\n+\n+\tfor (i = 0; i < num_slices; i++) {\n+\t\t/*\n+\t\t * priority  0: allocate from top of the tcam i.e. high\n+\t\t * priority !0: allocate index from bottom i.e lowest\n+\t\t */\n+\t\tif (parms->priority)\n+\t\t\tlog_idx = ba_alloc_reverse(pool);\n+\t\telse\n+\t\t\tlog_idx = ba_alloc(pool);\n+\t\tif (log_idx == BA_FAIL) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"%s: Allocation failed, rc:%s\\n\",\n+\t\t\t\t    tf_dir_2_str(parms->dir),\n+\t\t\t\t    strerror(ENOMEM));\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t\t/* return the index without the start of each row */\n+\t\tif (i == 0)\n+\t\t\tparms->idx = log_idx;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+tf_tcam_shared_free(struct tf *tfp,\n+\t\t    struct tf_tcam_free_parms *parms)\n+{\n+\tint rc;\n+\tstruct tf_session *tfs;\n+\tstruct tf_dev_info *dev;\n+\tint allocated = 0;\n+\tint i;\n+\tuint16_t start;\n+\tint phy_idx;\n+\tstruct bitalloc *pool;\n+\tenum tf_tcam_shared_wc_pool_id id;\n+\tstruct tf_tcam_free_parms nparms;\n+\tuint16_t num_slices;\n+\tuint16_t hcapi_type;\n+\tstruct tf_rm_alloc_info info;\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/* If we aren't the shared session or the type is\n+\t * not one of the special WC TCAM types, call the normal\n+\t * allocation.\n+\t */\n+\tif (!tf_session_is_shared_session(tfs) ||\n+\t    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&\n+\t     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {\n+\t\t/* Perform normal free\n+\t\t */\n+\t\trc = tf_tcam_free(tfp, parms);\n+\t\treturn rc;\n+\t}\n+\n+\tif (!tf_tcam_shared_db_valid(tfp, parms->dir)) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: tcam shared pool doesn't exist\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tif (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)\n+\t\tid = TF_TCAM_SHARED_WC_POOL_HI;\n+\telse\n+\t\tid = TF_TCAM_SHARED_WC_POOL_LO;\n+\n+\t/* Retrieve the device information */\n+\trc = tf_session_get_device(tfs, &dev);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = tf_tcam_shared_get_rm_info(tfp,\n+\t\t\t\t\tparms->dir,\n+\t\t\t\t\t&hcapi_type,\n+\t\t\t\t\t&info);\n+\tif (rc) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: TCAM rm info get failed\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn rc;\n+\t}\n+\n+\tpool = tcam_shared_wc[parms->dir][id].pool;\n+\tstart = tcam_shared_wc[parms->dir][id].info.start;\n+\n+\tif (parms->idx % num_slices) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: TCAM reserved resource is not multiple of %d\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir), num_slices);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tphy_idx = parms->idx + start;\n+\tallocated = ba_inuse(pool, parms->idx);\n+\n+\tif (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: Entry already free, type:%d, idx:%d\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir), parms->type, parms->idx);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < num_slices; i++) {\n+\t\trc = ba_free(pool, parms->idx + i);\n+\t\tif (rc) {\n+\t\t\tTFP_DRV_LOG(ERR,\n+\t\t\t\t    \"%s: Free failed, type:%s, idx:%d\\n\",\n+\t\t\t\t    tf_dir_2_str(parms->dir),\n+\t\t\t\t    tf_tcam_tbl_2_str(parms->type),\n+\t\t\t\t    parms->idx);\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n+\n+\t/* Override HI/LO type with parent WC TCAM type */\n+\tnparms = *parms;\n+\tnparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;\n+\tnparms.hcapi_type = hcapi_type;\n+\tnparms.idx = phy_idx;\n+\n+\trc = tf_msg_tcam_entry_free(tfp, dev, &nparms);\n+\tif (rc) {\n+\t\t/* Log error */\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: %s: log%d free failed, rc:%s\\n\",\n+\t\t\t    tf_dir_2_str(nparms.dir),\n+\t\t\t    tf_tcam_tbl_2_str(nparms.type),\n+\t\t\t    phy_idx,\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+tf_tcam_shared_set(struct tf *tfp __rte_unused,\n+\t\t   struct tf_tcam_set_parms *parms __rte_unused)\n+{\n+\tint rc;\n+\tstruct tf_session *tfs;\n+\tstruct tf_dev_info *dev;\n+\tint allocated = 0;\n+\tint phy_idx, log_idx;\n+\tuint16_t num_slices;\n+\tstruct tf_tcam_set_parms nparms;\n+\tstruct bitalloc *pool;\n+\tuint16_t start;\n+\tenum tf_tcam_shared_wc_pool_id id;\n+\tuint16_t hcapi_type;\n+\tstruct tf_rm_alloc_info info;\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/* If we aren't the shared session or one of our\n+\t * special types\n+\t */\n+\tif (!tf_session_is_shared_session(tfs) ||\n+\t    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&\n+\t     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {\n+\t\t/* Perform normal set and exit\n+\t\t */\n+\t\trc = tf_tcam_set(tfp, parms);\n+\t\treturn rc;\n+\t}\n+\n+\tif (!tf_tcam_shared_db_valid(tfp, parms->dir)) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: tcam shared pool doesn't exist\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Retrieve the device information */\n+\trc = tf_session_get_device(tfs, &dev);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)\n+\t\tid = TF_TCAM_SHARED_WC_POOL_HI;\n+\telse\n+\t\tid = TF_TCAM_SHARED_WC_POOL_LO;\n+\n+\tpool = tcam_shared_wc[parms->dir][id].pool;\n+\tstart = tcam_shared_wc[parms->dir][id].info.start;\n+\n+\tlog_idx = parms->idx;\n+\tphy_idx = parms->idx + start;\n+\tallocated = ba_inuse(pool, parms->idx);\n+\n+\tif (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: Entry is not allocated, type:%d, logid:%d\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir), parms->type, log_idx);\n+\t\treturn -EINVAL;\n+\t}\n+\trc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (parms->idx % num_slices) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: TCAM reserved resource is not multiple of %d\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir), num_slices);\n+\t\treturn -EINVAL;\n+\t}\n+\trc = tf_tcam_shared_get_rm_info(tfp,\n+\t\t\t\t\tparms->dir,\n+\t\t\t\t\t&hcapi_type,\n+\t\t\t\t\t&info);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Override HI/LO type with parent WC TCAM type */\n+\tnparms.hcapi_type = hcapi_type;\n+\tnparms.dir = parms->dir;\n+\tnparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;\n+\tnparms.idx = phy_idx;\n+\tnparms.key = parms->key;\n+\tnparms.mask = parms->mask;\n+\tnparms.key_size = parms->key_size;\n+\tnparms.result = parms->result;\n+\tnparms.result_size = parms->result_size;\n+\n+\trc = tf_msg_tcam_entry_set(tfp, dev, &nparms);\n+\tif (rc) {\n+\t\t/* Log error */\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: %s: phy entry %d set failed, rc:%s\",\n+\t\t\t    tf_dir_2_str(parms->dir),\n+\t\t\t    tf_tcam_tbl_2_str(nparms.type),\n+\t\t\t    phy_idx,\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+tf_tcam_shared_get(struct tf *tfp __rte_unused,\n+\t\t   struct tf_tcam_get_parms *parms)\n+{\n+\tint rc;\n+\tstruct tf_session *tfs;\n+\tstruct tf_dev_info *dev;\n+\tint allocated = 0;\n+\tint phy_idx, log_idx;\n+\tuint16_t num_slices;\n+\tstruct tf_tcam_get_parms nparms;\n+\tstruct bitalloc *pool;\n+\tuint16_t start;\n+\tenum tf_tcam_shared_wc_pool_id id;\n+\tuint16_t hcapi_type;\n+\tstruct tf_rm_alloc_info info;\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/* If we aren't the shared session or one of our\n+\t * special types\n+\t */\n+\tif (!tf_session_is_shared_session(tfs) ||\n+\t    (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&\n+\t     parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {\n+\t\t/* Perform normal get and exit\n+\t\t */\n+\t\trc = tf_tcam_get(tfp, parms);\n+\t\treturn rc;\n+\t}\n+\n+\tif (!tf_tcam_shared_db_valid(tfp, parms->dir)) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: tcam shared pool doesn't exist\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir));\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Retrieve the device information */\n+\trc = tf_session_get_device(tfs, &dev);\n+\tif (rc)\n+\t\treturn rc;\n+\tif (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)\n+\t\tid = TF_TCAM_SHARED_WC_POOL_HI;\n+\telse\n+\t\tid = TF_TCAM_SHARED_WC_POOL_LO;\n+\n+\tpool = tcam_shared_wc[parms->dir][id].pool;\n+\tstart = tcam_shared_wc[parms->dir][id].info.start;\n+\n+\trc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (parms->idx % num_slices) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: TCAM reserved resource is not multiple of %d\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir), num_slices);\n+\t\treturn -EINVAL;\n+\t}\n+\tlog_idx = parms->idx;\n+\tphy_idx = parms->idx + start;\n+\tallocated = ba_inuse(pool, parms->idx);\n+\n+\tif (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: Entry is not allocated, type:%d, logid:%d\\n\",\n+\t\t\t    tf_dir_2_str(parms->dir), parms->type, log_idx);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trc = tf_tcam_shared_get_rm_info(tfp,\n+\t\t\t\t\tparms->dir,\n+\t\t\t\t\t&hcapi_type,\n+\t\t\t\t\t&info);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Override HI/LO type with parent WC TCAM type */\n+\tnparms = *parms;\n+\tnparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;\n+\tnparms.hcapi_type = hcapi_type;\n+\tnparms.idx = phy_idx;\n+\n+\trc = tf_msg_tcam_entry_get(tfp, dev, &nparms);\n+\tif (rc) {\n+\t\t/* Log error */\n+\t\tTFP_DRV_LOG(ERR,\n+\t\t\t    \"%s: %s: Entry %d set failed, rc:%s\",\n+\t\t\t    tf_dir_2_str(nparms.dir),\n+\t\t\t    tf_tcam_tbl_2_str(nparms.type),\n+\t\t\t    nparms.idx,\n+\t\t\t    strerror(-rc));\n+\t\treturn rc;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.h b/drivers/net/bnxt/tf_core/tf_tcam_shared.h\nnew file mode 100644\nindex 0000000000..fad6e23b4c\n--- /dev/null\n+++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.h\n@@ -0,0 +1,127 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019-2021 Broadcom\n+ * All rights reserved.\n+ */\n+\n+#ifndef _TF_TCAM_SHARED_H_\n+#define _TF_TCAM_SHARED_H_\n+\n+#include \"tf_core.h\"\n+#include \"tf_tcam.h\"\n+\n+/**\n+ * @page tcam_shared TCAM SHARED\n+ *\n+ * @ref tf_tcam_shared_bind\n+ *\n+ * @ref tf_tcam_shared_unbind\n+ *\n+ * @ref tf_tcam_shared_alloc\n+ *\n+ * @ref tf_tcam_shared_free\n+ *\n+ * @ref tf_tcam_shared_set\n+ *\n+ * @ref tf_tcam_shared_get\n+ *\n+ */\n+\n+/**\n+ * Initializes the TCAM shared module with the requested DBs. Must be\n+ * invoked as the first thing before any of the access functions.\n+ *\n+ * [in] tfp\n+ *   Pointer to the truflow handle\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_shared_bind(struct tf *tfp,\n+\t\t\tstruct tf_tcam_cfg_parms *parms);\n+\n+/**\n+ * Cleans up the private DBs and releases all the data.\n+ *\n+ * [in] tfp\n+ *   Pointer to the truflow handle\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_shared_unbind(struct tf *tfp);\n+\n+/**\n+ * Allocates the requested tcam type from the internal RM DB.\n+ *\n+ * [in] tfp\n+ *   Pointer to the truflow handle\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_shared_alloc(struct tf *tfp,\n+\t\t\t struct tf_tcam_alloc_parms *parms);\n+\n+/**\n+ * Free's the requested table type and returns it to the DB.\n+ *\n+ * [in] tfp\n+ *   Pointer to the truflow handle\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_shared_free(struct tf *tfp,\n+\t\t\tstruct tf_tcam_free_parms *parms);\n+\n+/**\n+ * Configures the requested element by sending a firmware request which\n+ * then installs it into the device internal structures.\n+ *\n+ * [in] tfp\n+ *   Pointer to the truflow handle\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_shared_set(struct tf *tfp,\n+\t\t       struct tf_tcam_set_parms *parms);\n+\n+/**\n+ * Retrieves the requested element by sending a firmware request to get\n+ * the element.\n+ *\n+ * [in] tfp\n+ *   Pointer to the truflow handle\n+ *\n+ * [in] parms\n+ *   Pointer to parameters\n+ *\n+ * Returns\n+ *   - (0) if successful.\n+ *   - (-EINVAL) on failure.\n+ */\n+int tf_tcam_shared_get(struct tf *tfp,\n+\t\t       struct tf_tcam_get_parms *parms);\n+\n+#endif /* _TF_TCAM_SHARED_H */\ndiff --git a/drivers/net/bnxt/tf_core/tf_util.c b/drivers/net/bnxt/tf_core/tf_util.c\nindex 25f5c152d2..e712816209 100644\n--- a/drivers/net/bnxt/tf_core/tf_util.c\n+++ b/drivers/net/bnxt/tf_core/tf_util.c\n@@ -59,6 +59,12 @@ tf_tcam_tbl_2_str(enum tf_tcam_tbl_type tcam_type)\n \t\treturn \"sp_tcam\";\n \tcase TF_TCAM_TBL_TYPE_CT_RULE_TCAM:\n \t\treturn \"ct_rule_tcam\";\n+#ifdef TF_TCAM_SHARED\n+\tcase TF_TCAM_TBL_TYPE_WC_TCAM_HIGH:\n+\t\treturn \"wc_tcam_hi\";\n+\tcase TF_TCAM_TBL_TYPE_WC_TCAM_LOW:\n+\t\treturn \"wc_tcam_lo\";\n+#endif\n \tdefault:\n \t\treturn \"Invalid tcam table type\";\n \t}\n",
    "prefixes": [
        "v3"
    ]
}