get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 128299,
    "url": "http://patches.dpdk.org/api/patches/128299/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230607130245.8048-11-ivan.malov@arknetworks.am/",
    "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": "<20230607130245.8048-11-ivan.malov@arknetworks.am>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230607130245.8048-11-ivan.malov@arknetworks.am",
    "date": "2023-06-07T13:02:21",
    "name": "[v4,10/34] net/sfc: attach to HW table API",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "385030d324336693e81adecadee84ef6f5bc73ab",
    "submitter": {
        "id": 2962,
        "url": "http://patches.dpdk.org/api/people/2962/?format=api",
        "name": "Ivan Malov",
        "email": "ivan.malov@arknetworks.am"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230607130245.8048-11-ivan.malov@arknetworks.am/mbox/",
    "series": [
        {
            "id": 28390,
            "url": "http://patches.dpdk.org/api/series/28390/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=28390",
            "date": "2023-06-07T13:02:11",
            "name": "net/sfc: support HW conntrack assistance",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/28390/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/128299/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/128299/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 1D46242C4D;\n\tWed,  7 Jun 2023 15:04:22 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8CB9F42D5E;\n\tWed,  7 Jun 2023 15:02:59 +0200 (CEST)",
            "from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80])\n by mails.dpdk.org (Postfix) with ESMTP id 8BB7D42D33\n for <dev@dpdk.org>; Wed,  7 Jun 2023 15:02:52 +0200 (CEST)",
            "from localhost.localdomain (unknown [78.109.69.83])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by agw.arknetworks.am (Postfix) with ESMTPSA id 05F16E12C8;\n Wed,  7 Jun 2023 17:02:51 +0400 (+04)"
        ],
        "From": "Ivan Malov <ivan.malov@arknetworks.am>",
        "To": "dev@dpdk.org",
        "Cc": "Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,\n Ferruh Yigit <ferruh.yigit@amd.com>,\n Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>,\n Andy Moreton <amoreton@xilinx.com>",
        "Subject": "[PATCH v4 10/34] net/sfc: attach to HW table API",
        "Date": "Wed,  7 Jun 2023 17:02:21 +0400",
        "Message-Id": "<20230607130245.8048-11-ivan.malov@arknetworks.am>",
        "X-Mailer": "git-send-email 2.30.2",
        "In-Reply-To": "<20230607130245.8048-1-ivan.malov@arknetworks.am>",
        "References": "<20230601195538.8265-1-ivan.malov@arknetworks.am>\n <20230607130245.8048-1-ivan.malov@arknetworks.am>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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"
    },
    "content": "From: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>\n\nThe patch adds APIs to initialise, manipulate and finalise\nHW tables API-specific context in NIC control structure.\nThe context itself will be used to store HW tables-related info,\nlike table descriptors and field descriptors.\n\nSigned-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>\nReviewed-by: Ivan Malov <ivan.malov@arknetworks.am>\nReviewed-by: Andy Moreton <amoreton@xilinx.com>\n---\n drivers/net/sfc/meson.build          |   4 +-\n drivers/net/sfc/sfc.c                |  18 +-\n drivers/net/sfc/sfc.h                |   2 +\n drivers/net/sfc/sfc_tbl_meta.c       |  71 ++++++++\n drivers/net/sfc/sfc_tbl_meta.h       |  37 ++++\n drivers/net/sfc/sfc_tbl_meta_cache.c | 253 +++++++++++++++++++++++++++\n drivers/net/sfc/sfc_tbl_meta_cache.h |  25 +++\n drivers/net/sfc/sfc_tbls.c           |  60 +++++++\n drivers/net/sfc/sfc_tbls.h           |  81 +++++++++\n 9 files changed, 549 insertions(+), 2 deletions(-)\n create mode 100644 drivers/net/sfc/sfc_tbl_meta.c\n create mode 100644 drivers/net/sfc/sfc_tbl_meta.h\n create mode 100644 drivers/net/sfc/sfc_tbl_meta_cache.c\n create mode 100644 drivers/net/sfc/sfc_tbl_meta_cache.h",
    "diff": "diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build\nindex 39c7f24764..c9d4264674 100644\n--- a/drivers/net/sfc/meson.build\n+++ b/drivers/net/sfc/meson.build\n@@ -71,7 +71,7 @@ if not cc.links(atomic_check_code)\n     ext_deps += libatomic_dep\n endif\n \n-deps += ['common_sfc_efx', 'bus_pci']\n+deps += ['common_sfc_efx', 'bus_pci', 'hash']\n sources = files(\n         'sfc_ethdev.c',\n         'sfc_kvargs.c',\n@@ -88,6 +88,8 @@ sources = files(\n         'sfc_filter.c',\n         'sfc_switch.c',\n         'sfc_tbls.c',\n+        'sfc_tbl_meta.c',\n+        'sfc_tbl_meta_cache.c',\n         'sfc_mae.c',\n         'sfc_mae_counter.c',\n         'sfc_flow.c',\ndiff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c\nindex 22753e3417..a56521696a 100644\n--- a/drivers/net/sfc/sfc.c\n+++ b/drivers/net/sfc/sfc.c\n@@ -491,6 +491,10 @@ sfc_try_start(struct sfc_adapter *sa)\n \tif (rc != 0)\n \t\tgoto fail_ev_start;\n \n+\trc = sfc_tbls_start(sa);\n+\tif (rc != 0)\n+\t\tgoto fail_tbls_start;\n+\n \trc = sfc_port_start(sa);\n \tif (rc != 0)\n \t\tgoto fail_port_start;\n@@ -526,9 +530,12 @@ sfc_try_start(struct sfc_adapter *sa)\n fail_rx_start:\n \tsfc_port_stop(sa);\n \n-fail_port_start:\n+fail_tbls_start:\n \tsfc_ev_stop(sa);\n \n+fail_port_start:\n+\tsfc_tbls_stop(sa);\n+\n fail_ev_start:\n \tsfc_intr_stop(sa);\n \n@@ -626,6 +633,7 @@ sfc_stop(struct sfc_adapter *sa)\n \tsfc_tx_stop(sa);\n \tsfc_rx_stop(sa);\n \tsfc_port_stop(sa);\n+\tsfc_tbls_stop(sa);\n \tsfc_ev_stop(sa);\n \tsfc_intr_stop(sa);\n \tefx_nic_fini(sa->nic);\n@@ -983,6 +991,10 @@ sfc_attach(struct sfc_adapter *sa)\n \tif (rc != 0)\n \t\tgoto fail_mae_attach;\n \n+\trc = sfc_tbls_attach(sa);\n+\tif (rc != 0)\n+\t\tgoto fail_tables_attach;\n+\n \trc = sfc_mae_switchdev_init(sa);\n \tif (rc != 0)\n \t\tgoto fail_mae_switchdev_init;\n@@ -1025,6 +1037,9 @@ sfc_attach(struct sfc_adapter *sa)\n \tsfc_mae_switchdev_fini(sa);\n \n fail_mae_switchdev_init:\n+\tsfc_tbls_detach(sa);\n+\n+fail_tables_attach:\n \tsfc_mae_detach(sa);\n \n fail_mae_attach:\n@@ -1088,6 +1103,7 @@ sfc_detach(struct sfc_adapter *sa)\n \n \tsfc_repr_proxy_detach(sa);\n \tsfc_mae_switchdev_fini(sa);\n+\tsfc_tbls_detach(sa);\n \tsfc_mae_detach(sa);\n \tsfc_mae_counter_rxq_detach(sa);\n \tsfc_filter_detach(sa);\ndiff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h\nindex 730d054aea..6b301aad60 100644\n--- a/drivers/net/sfc/sfc.h\n+++ b/drivers/net/sfc/sfc.h\n@@ -31,6 +31,7 @@\n #include \"sfc_flow_tunnel.h\"\n #include \"sfc_sriov.h\"\n #include \"sfc_mae.h\"\n+#include \"sfc_tbls.h\"\n #include \"sfc_dp.h\"\n #include \"sfc_sw_stats.h\"\n #include \"sfc_repr_proxy.h\"\n@@ -244,6 +245,7 @@ struct sfc_adapter {\n \tstruct sfc_ft_ctx\t\tft_ctx_pool[SFC_FT_MAX_NTUNNELS];\n \tstruct sfc_filter\t\tfilter;\n \tstruct sfc_mae\t\t\tmae;\n+\tstruct sfc_tbls\t\t\thw_tables;\n \tstruct sfc_repr_proxy\t\trepr_proxy;\n \n \tstruct sfc_flow_list\t\tflow_list;\ndiff --git a/drivers/net/sfc/sfc_tbl_meta.c b/drivers/net/sfc/sfc_tbl_meta.c\nnew file mode 100644\nindex 0000000000..997082fd74\n--- /dev/null\n+++ b/drivers/net/sfc/sfc_tbl_meta.c\n@@ -0,0 +1,71 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright (c) 2023 Advanced Micro Devices, Inc.\n+ */\n+\n+#include \"sfc.h\"\n+#include \"sfc_tbl_meta.h\"\n+#include \"sfc_tbl_meta_cache.h\"\n+\n+const struct sfc_tbl_meta *\n+sfc_tbl_meta_lookup(struct sfc_adapter *sa, efx_table_id_t table_id)\n+{\n+\tstruct sfc_tbl_meta *meta;\n+\tstruct sfc_tbls *tables = &sa->hw_tables;\n+\tint rc;\n+\n+\tSFC_ASSERT(sfc_adapter_is_locked(sa));\n+\n+\tif (tables->status != SFC_TBLS_STATUS_SUPPORTED)\n+\t\treturn NULL;\n+\n+\trc = rte_hash_lookup_data(tables->meta.cache, (const void *)&table_id,\n+\t\t\t\t  (void **)&meta);\n+\tif (rc < 0)\n+\t\treturn NULL;\n+\n+\tSFC_ASSERT(meta != NULL);\n+\tSFC_ASSERT(meta->table_id == table_id);\n+\n+\treturn meta;\n+}\n+\n+int\n+sfc_tbl_meta_init(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_tbls *tables = &sa->hw_tables;\n+\tstruct sfc_tbl_meta_cache *meta = &tables->meta;\n+\tint rc;\n+\n+\tSFC_ASSERT(sfc_adapter_is_locked(sa));\n+\n+\tif (tables->status != SFC_TBLS_STATUS_SUPPORTED)\n+\t\treturn 0;\n+\n+\trc = sfc_tbl_meta_cache_ctor(&meta->cache);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\trc = sfc_tbl_meta_cache_update(meta->cache, sa->nic);\n+\tif (rc != 0) {\n+\t\tsfc_tbl_meta_cache_dtor(&meta->cache);\n+\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+sfc_tbl_meta_fini(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_tbls *tables = &sa->hw_tables;\n+\tstruct sfc_tbl_meta_cache *meta = &tables->meta;\n+\n+\tif (meta->cache == NULL)\n+\t\treturn;\n+\n+\tSFC_ASSERT(sfc_adapter_is_locked(sa));\n+\tSFC_ASSERT(tables->status == SFC_TBLS_STATUS_SUPPORTED);\n+\n+\tsfc_tbl_meta_cache_dtor(&meta->cache);\n+}\ndiff --git a/drivers/net/sfc/sfc_tbl_meta.h b/drivers/net/sfc/sfc_tbl_meta.h\nnew file mode 100644\nindex 0000000000..7d39957514\n--- /dev/null\n+++ b/drivers/net/sfc/sfc_tbl_meta.h\n@@ -0,0 +1,37 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright (c) 2023 Advanced Micro Devices, Inc.\n+ */\n+\n+#ifndef _SFC_TBL_META_H\n+#define _SFC_TBL_META_H\n+\n+#include <rte_hash.h>\n+\n+#include \"efx.h\"\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/* Metadata about table layout */\n+struct sfc_tbl_meta {\n+\tefx_table_id_t\t\t\ttable_id;\n+\tefx_table_descriptor_t\t\tdescriptor;\n+\tefx_table_field_descriptor_t\t*keys;\n+\tefx_table_field_descriptor_t\t*responses;\n+};\n+\n+struct sfc_tbl_meta_cache {\n+\tstruct rte_hash\t*cache;\n+};\n+\n+struct sfc_adapter;\n+\n+const struct sfc_tbl_meta *sfc_tbl_meta_lookup(struct sfc_adapter *sa,\n+\t\t\t\t\t       efx_table_id_t table_id);\n+\n+int sfc_tbl_meta_init(struct sfc_adapter *sa);\n+void sfc_tbl_meta_fini(struct sfc_adapter *sa);\n+\n+#endif /* _SFC_TBL_META_H */\ndiff --git a/drivers/net/sfc/sfc_tbl_meta_cache.c b/drivers/net/sfc/sfc_tbl_meta_cache.c\nnew file mode 100644\nindex 0000000000..bffbc4a158\n--- /dev/null\n+++ b/drivers/net/sfc/sfc_tbl_meta_cache.c\n@@ -0,0 +1,253 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright (c) 2023 Advanced Micro Devices, Inc.\n+ */\n+\n+#include <rte_malloc.h>\n+#include <rte_jhash.h>\n+\n+#include \"sfc_tbl_meta_cache.h\"\n+#include \"sfc_debug.h\"\n+\n+/* The minimal size of the table meta cache */\n+#define SFC_TBL_META_CACHE_SIZE_MIN\t8\n+\n+int\n+sfc_tbl_meta_cache_ctor(struct rte_hash **ref_cache)\n+{\n+\tsize_t cache_size = RTE_MAX((unsigned int)SFC_TBL_META_CACHE_SIZE_MIN,\n+\t\t\t\t    efx_table_supported_num_get());\n+\tstruct rte_hash *cache = NULL;\n+\tconst struct rte_hash_parameters hash_params = {\n+\t\t.name       = \"meta_hash_table\",\n+\t\t.hash_func  = rte_jhash,\n+\t\t.entries    = cache_size,\n+\t\t.socket_id  = rte_socket_id(),\n+\t\t.key_len    = sizeof(efx_table_id_t),\n+\t};\n+\n+\tcache = rte_hash_create(&hash_params);\n+\tif (cache == NULL)\n+\t\treturn -ENOMEM;\n+\n+\t*ref_cache = cache;\n+\n+\treturn 0;\n+}\n+\n+static void\n+sfc_tbl_meta_cache_free(struct sfc_tbl_meta *meta)\n+{\n+\tSFC_ASSERT(meta != NULL);\n+\n+\trte_free(meta->keys);\n+\trte_free(meta->responses);\n+\trte_free(meta);\n+}\n+\n+void\n+sfc_tbl_meta_cache_dtor(struct rte_hash **ref_cache)\n+{\n+\tstruct rte_hash *cache = *ref_cache;\n+\tconst void *next_key;\n+\tuint32_t iter = 0;\n+\tvoid *next_meta;\n+\n+\tif (cache == NULL)\n+\t\treturn;\n+\n+\twhile (rte_hash_iterate(cache, &next_key, &next_meta, &iter) >= 0)\n+\t\tsfc_tbl_meta_cache_free((struct sfc_tbl_meta *)next_meta);\n+\n+\trte_hash_free(cache);\n+\n+\t*ref_cache = NULL;\n+}\n+\n+/**\n+ * Table descriptor contains information about the table's\n+ * fields that can be associated with both the key and the response.\n+ * Save these fields by separating the key from the response in\n+ * appropriate places based on their lengths.\n+ */\n+static int\n+sfc_tbl_meta_desc_fields_copy(struct sfc_tbl_meta *meta, efx_nic_t *enp,\n+\t\t\t      efx_table_field_descriptor_t *fields,\n+\t\t\t      unsigned int total_n_fields)\n+{\n+\tuint16_t n_key_fields = meta->descriptor.n_key_fields;\n+\tsize_t field_size = sizeof(*fields);\n+\tunsigned int n_field_descs_written;\n+\tuint32_t field_offset;\n+\tint rc;\n+\n+\tfor (n_field_descs_written = 0, field_offset = 0;\n+\t     field_offset < total_n_fields;\n+\t     field_offset += n_field_descs_written) {\n+\t\trc = efx_table_describe(enp, meta->table_id, field_offset, NULL,\n+\t\t\t\t\tfields, total_n_fields, &n_field_descs_written);\n+\t\tif (rc != 0)\n+\t\t\treturn rc;\n+\n+\t\tif (field_offset + n_field_descs_written > total_n_fields)\n+\t\t\treturn -EINVAL;\n+\n+\t\tif (field_offset < n_key_fields &&\n+\t\t    field_offset + n_field_descs_written > n_key_fields) {\n+\t\t\t/*\n+\t\t\t * Some of the descriptors belong to key,\n+\t\t\t * the other to response.\n+\t\t\t */\n+\t\t\trte_memcpy(RTE_PTR_ADD(meta->keys, field_offset * field_size),\n+\t\t\t\t   fields, (n_key_fields - field_offset) * field_size);\n+\t\t\trte_memcpy(meta->responses,\n+\t\t\t\t   RTE_PTR_ADD(fields,\n+\t\t\t\t   (n_key_fields - field_offset) * field_size),\n+\t\t\t\t   (field_offset + n_field_descs_written - n_key_fields) *\n+\t\t\t\t   field_size);\n+\t\t} else if (field_offset < n_key_fields) {\n+\t\t\t/* All fields belong to the key */\n+\t\t\trte_memcpy(RTE_PTR_ADD(meta->keys, field_offset * field_size),\n+\t\t\t\t   fields, n_field_descs_written * field_size);\n+\t\t} else {\n+\t\t\t/* All fields belong to the response */\n+\t\t\trte_memcpy(RTE_PTR_ADD(meta->responses,\n+\t\t\t\t   (field_offset - n_key_fields) * field_size),\n+\t\t\t\t   fields, n_field_descs_written * field_size);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+sfc_tbl_meta_desc_read(struct sfc_tbl_meta *meta, efx_nic_t *enp,\n+\t\t       efx_table_id_t table_id)\n+{\n+\tefx_table_field_descriptor_t *fields;\n+\tunsigned int total_n_fields;\n+\tint rc;\n+\n+\trc = efx_table_describe(enp, table_id, 0, &meta->descriptor, NULL, 0, NULL);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\ttotal_n_fields = meta->descriptor.n_key_fields + meta->descriptor.n_resp_fields;\n+\n+\tfields = rte_calloc(NULL, total_n_fields, sizeof(*fields), 0);\n+\tif (fields == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tmeta->table_id = table_id;\n+\n+\tmeta->keys = rte_calloc(\"efx_table_key_field_descs\",\n+\t\t\t\tmeta->descriptor.n_key_fields,\n+\t\t\t\tsizeof(*meta->keys), 0);\n+\tif (meta->keys == NULL) {\n+\t\trc = -ENOMEM;\n+\t\tgoto fail_alloc_keys;\n+\t}\n+\n+\tmeta->responses = rte_calloc(\"efx_table_response_field_descs\",\n+\t\t\t\t     meta->descriptor.n_resp_fields,\n+\t\t\t\t     sizeof(*meta->responses), 0);\n+\tif (meta->responses == NULL) {\n+\t\trc = -ENOMEM;\n+\t\tgoto fail_alloc_responses;\n+\t}\n+\n+\trc = sfc_tbl_meta_desc_fields_copy(meta, enp, fields, total_n_fields);\n+\tif (rc != 0)\n+\t\tgoto fail_copy_fields;\n+\n+\treturn 0;\n+\n+fail_copy_fields:\n+\trte_free(meta->responses);\n+fail_alloc_responses:\n+\trte_free(meta->keys);\n+fail_alloc_keys:\n+\trte_free(fields);\n+\n+\treturn rc;\n+}\n+\n+static int\n+sfc_tbl_meta_cache_add(struct rte_hash *cache, efx_nic_t *enp,\n+\t\t       efx_table_id_t table_id)\n+{\n+\tstruct sfc_tbl_meta *meta = NULL;\n+\tint rc;\n+\n+\tmeta = rte_zmalloc(\"sfc_tbl_meta\", sizeof(*meta), 0);\n+\tif (meta == NULL)\n+\t\treturn -ENOMEM;\n+\n+\trc = sfc_tbl_meta_desc_read(meta, enp, table_id);\n+\tif (rc != 0)\n+\t\tgoto fail_read_meta;\n+\n+\trc = rte_hash_add_key_data(cache, &table_id, meta);\n+\tif (rc != 0)\n+\t\tgoto fail_add_key;\n+\n+\treturn 0;\n+\n+fail_add_key:\n+\trte_free(meta->keys);\n+\trte_free(meta->responses);\n+fail_read_meta:\n+\trte_free(meta);\n+\n+\treturn rc;\n+}\n+\n+int\n+sfc_tbl_meta_cache_update(struct rte_hash *cache, efx_nic_t *enp)\n+{\n+\tefx_table_id_t *table_ids = NULL;\n+\tunsigned int n_table_ids_written;\n+\tunsigned int total_n_tables;\n+\tunsigned int n_table_ids;\n+\tuint32_t table_index;\n+\tunsigned int i;\n+\tint rc = 0;\n+\n+\trc = efx_table_list(enp, 0, &total_n_tables, NULL, 0, NULL);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\ttable_ids = rte_calloc(NULL, total_n_tables, sizeof(*table_ids), 0);\n+\tif (table_ids == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tn_table_ids = total_n_tables;\n+\n+\tfor (table_index = 0, n_table_ids_written = 0;\n+\t     table_index < total_n_tables;\n+\t     table_index += n_table_ids_written) {\n+\t\trc = efx_table_list(enp, table_index, NULL,\n+\t\t\t\t    table_ids, n_table_ids, &n_table_ids_written);\n+\t\tif (rc != 0)\n+\t\t\tgoto out;\n+\n+\t\tif (table_index + n_table_ids_written > total_n_tables) {\n+\t\t\trc = -EINVAL;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tfor (i = 0; i < n_table_ids_written; i++, table_index++) {\n+\t\t\tif (!efx_table_is_supported(table_ids[i]))\n+\t\t\t\tcontinue;\n+\n+\t\t\trc = sfc_tbl_meta_cache_add(cache, enp, table_ids[i]);\n+\t\t\tif (rc != 0)\n+\t\t\t\tgoto out;\n+\t\t}\n+\t}\n+\n+out:\n+\trte_free(table_ids);\n+\n+\treturn rc;\n+}\ndiff --git a/drivers/net/sfc/sfc_tbl_meta_cache.h b/drivers/net/sfc/sfc_tbl_meta_cache.h\nnew file mode 100644\nindex 0000000000..2deff620a4\n--- /dev/null\n+++ b/drivers/net/sfc/sfc_tbl_meta_cache.h\n@@ -0,0 +1,25 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright (c) 2023 Advanced Micro Devices, Inc.\n+ */\n+\n+#ifndef _SFC_TBL_META_CACHE_H\n+#define _SFC_TBL_META_CACHE_H\n+\n+#include <rte_hash.h>\n+\n+#include \"efx.h\"\n+\n+#include \"sfc_tbl_meta.h\"\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+int sfc_tbl_meta_cache_ctor(struct rte_hash **ref_cache);\n+\n+void sfc_tbl_meta_cache_dtor(struct rte_hash **ref_cache);\n+\n+int sfc_tbl_meta_cache_update(struct rte_hash *cache, efx_nic_t *enp);\n+\n+#endif /* _SFC_TBLS_DESC_CACHE_H */\ndiff --git a/drivers/net/sfc/sfc_tbls.c b/drivers/net/sfc/sfc_tbls.c\nindex 536cf689ba..3108955bc3 100644\n--- a/drivers/net/sfc/sfc_tbls.c\n+++ b/drivers/net/sfc/sfc_tbls.c\n@@ -3,6 +3,7 @@\n  * Copyright (c) 2023 Advanced Micro Devices, Inc.\n  */\n \n+#include \"sfc.h\"\n #include \"sfc_tbls.h\"\n #include \"sfc_debug.h\"\n \n@@ -11,6 +12,65 @@\n /* Number of bits in uint32_t type */\n #define SFC_TBLS_U32_BITS (sizeof(uint32_t) * CHAR_BIT)\n \n+int\n+sfc_tbls_attach(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_tbls *tables = &sa->hw_tables;\n+\tconst struct sfc_mae *mae = &sa->mae;\n+\tconst efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\tif (mae->status != SFC_MAE_STATUS_ADMIN ||\n+\t    !encp->enc_table_api_supported) {\n+\t\ttables->status = SFC_TBLS_STATUS_UNSUPPORTED;\n+\t\treturn 0;\n+\t}\n+\n+\ttables->status = SFC_TBLS_STATUS_SUPPORTED;\n+\n+\trc = sfc_tbl_meta_init(sa);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\tsfc_log_init(sa, \"done\");\n+\n+\treturn 0;\n+}\n+\n+void\n+sfc_tbls_detach(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_tbls *tables = &sa->hw_tables;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\tif (tables->status != SFC_TBLS_STATUS_SUPPORTED)\n+\t\tgoto done;\n+\n+\tsfc_tbl_meta_fini(sa);\n+\n+done:\n+\tsfc_log_init(sa, \"done\");\n+\n+\ttables->status = SFC_TBLS_STATUS_UNKNOWN;\n+}\n+\n+int\n+sfc_tbls_start(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_tbls *tables = &sa->hw_tables;\n+\tint rc;\n+\n+\tif (tables->status == SFC_TBLS_STATUS_UNKNOWN) {\n+\t\trc = sfc_tbls_attach(sa);\n+\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static uint32_t\n sfc_tbls_field_update(uint32_t in, uint16_t lbn, uint16_t width, uint32_t value)\n {\ndiff --git a/drivers/net/sfc/sfc_tbls.h b/drivers/net/sfc/sfc_tbls.h\nindex 74bdfab476..ff619e5141 100644\n--- a/drivers/net/sfc/sfc_tbls.h\n+++ b/drivers/net/sfc/sfc_tbls.h\n@@ -8,6 +8,8 @@\n \n #include \"efx.h\"\n \n+#include \"sfc_tbl_meta.h\"\n+\n #ifdef __cplusplus\n extern \"C\" {\n #endif\n@@ -44,6 +46,85 @@ extern \"C\" {\n /* Mask is used only for STCAM */\n #define SFC_TBLS_BCAM_MASK_WIDTH\t0\n \n+/** Options for HW tables support status */\n+enum sfc_tbls_status {\n+\tSFC_TBLS_STATUS_UNKNOWN = 0,\n+\tSFC_TBLS_STATUS_UNSUPPORTED,\n+\tSFC_TBLS_STATUS_SUPPORTED,\n+};\n+\n+/**\n+ * Entry point to access HW tables\n+ *\n+ * SFC driver can access hardware (HW) tables.\n+ * Interaction with HW tables is done through the MCDI table access API\n+ * that is implemented in EFX.\n+ *\n+ * In order to manipulate data on HW tables it's necessary to\n+ * - discover the list of supported tables;\n+ * - read a table descriptor to get details of the structure\n+ *   of the table;\n+ * - get named fields of the table;\n+ * - insert/delete/update table entries based on given fields\n+ *   and information about the table\n+ *\n+ * All table layout data should be saved in a cache.\n+ * The cache allows to avoid getting the table descriptor each time when you want\n+ * to manipulate table entries. It just contains the table\n+ * descriptors and all associated data. The cache is based on the RTE hash map and\n+ * it uses a table ID as a key.\n+ * The sfc_tbl_meta library serves as a wrapper over the cache and allows to user\n+ * to get all information about the tables without worrying about the cache.\n+ *\n+ * +------------------------+\n+ * | Cache is uninitialized |<----------------------------------+\n+ * +------------------------+\t\t\t\t\t|\n+ *\t|\t\t\t\t\t\t\t|\n+ *\t| sfc_attach()\t\t\t\t\t\t|\n+ *\t| sfc_tbls_attach() -- (fail) -- sfc_tbls_detach()------+\n+ *\tV\t\t\t\t\t^\n+ * +------------------------+\t\t\t|\n+ * |  Cache is initialized  |\t\t\t+-------+\n+ * +------------------------+\t\t\t\t|\n+ *\t| sfc_start()\t\t\t\t\t|\n+ *\t| sfc_tbls_start() -- (fail) -- sfc_tbls_stop()-+\n+ *\tV\t\t\t\t\t\t|\n+ * +------------------------+\t\t\t\t|\n+ * | Cache is initialized   |\t\t\t\t|\n+ * | and valid              |\t\t\t\t|\n+ * +------------------------+\t\t\t\t|\n+ *\t|\t\t\t\t\t\t|\n+ *\t| sfc_restart()\t\t\t\t\t|\n+ *\tV\t\t\t\t\t\t|\n+ * +------------------------+\t\t\t\t|\n+ * | Cache is initialized   |\t\t\t\t|\n+ * | but can be invalid     |\t\t\t\t|\n+ * +------------------------+---------------------------+\n+ */\n+struct sfc_tbls {\n+\tstruct sfc_tbl_meta_cache\tmeta;\n+\tenum sfc_tbls_status\t\tstatus;\n+};\n+\n+struct sfc_adapter;\n+\n+static inline bool\n+sfc_tbls_id_is_supported(struct sfc_adapter *sa,\n+\t\t\t efx_table_id_t table_id)\n+{\n+\treturn (sfc_tbl_meta_lookup(sa, table_id) == NULL ? false : true);\n+}\n+\n+int sfc_tbls_attach(struct sfc_adapter *sa);\n+void sfc_tbls_detach(struct sfc_adapter *sa);\n+int sfc_tbls_start(struct sfc_adapter *sa);\n+\n+static inline void\n+sfc_tbls_stop(struct sfc_adapter *sa)\n+{\n+\tsfc_tbls_detach(sa);\n+}\n+\n static inline int\n sfc_tbls_bcam_entry_insert(efx_nic_t *enp, efx_table_id_t table_id, uint16_t key_width,\n \t\t\t   uint16_t resp_width, uint8_t *data, unsigned int data_size)\n",
    "prefixes": [
        "v4",
        "10/34"
    ]
}