get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 78301,
    "url": "http://patches.dpdk.org/api/patches/78301/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1600764594-14752-45-git-send-email-arybchenko@solarflare.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": "<1600764594-14752-45-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1600764594-14752-45-git-send-email-arybchenko@solarflare.com",
    "date": "2020-09-22T08:49:38",
    "name": "[44/60] common/sfc_efx/base: add function control window lookup API",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8408c28c25c2086fd38a94d3133530c6470375a5",
    "submitter": {
        "id": 607,
        "url": "http://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.com"
    },
    "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/1600764594-14752-45-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [
        {
            "id": 12400,
            "url": "http://patches.dpdk.org/api/series/12400/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12400",
            "date": "2020-09-22T08:48:59",
            "name": "common/sfc_efx: support Riverhead NIC family",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/12400/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/78301/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/78301/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 6B16EA04E1;\n\tTue, 22 Sep 2020 10:59:28 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id ADC7D1DBD8;\n\tTue, 22 Sep 2020 10:51:30 +0200 (CEST)",
            "from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com\n [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id F032F1D724\n for <dev@dpdk.org>; Tue, 22 Sep 2020 10:50:23 +0200 (CEST)",
            "from mx1-us1.ppe-hosted.com (unknown [10.110.50.144])\n by dispatch1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id\n 9A3E52005B for <dev@dpdk.org>; Tue, 22 Sep 2020 08:50:23 +0000 (UTC)",
            "from us4-mdac16-22.at1.mdlocal (unknown [10.110.49.204])\n by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 99D3B800A4\n for <dev@dpdk.org>; Tue, 22 Sep 2020 08:50:23 +0000 (UTC)",
            "from mx1-us1.ppe-hosted.com (unknown [10.110.50.7])\n by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 13E3040071\n for <dev@dpdk.org>; Tue, 22 Sep 2020 08:50:23 +0000 (UTC)",
            "from webmail.solarflare.com (uk.solarflare.com [193.34.186.16])\n (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits))\n (No client certificate requested)\n by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id\n D0EEA4C005B\n for <dev@dpdk.org>; Tue, 22 Sep 2020 08:50:22 +0000 (UTC)",
            "from ukex01.SolarFlarecom.com (10.17.10.4) by\n ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server (TLS) id\n 15.0.1497.2; Tue, 22 Sep 2020 09:50:11 +0100",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server id\n 15.0.1497.2 via Frontend Transport; Tue, 22 Sep 2020 09:50:11 +0100",
            "from ukv-loginhost.uk.solarflarecom.com\n (ukv-loginhost.uk.solarflarecom.com [10.17.10.39])\n by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id 08M8oBMC004786;\n Tue, 22 Sep 2020 09:50:11 +0100",
            "from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1])\n by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id 742691613AB;\n Tue, 22 Sep 2020 09:50:11 +0100 (BST)"
        ],
        "X-Virus-Scanned": "Proofpoint Essentials engine",
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Igor Romanov <igor.romanov@oktetlabs.ru>",
        "Date": "Tue, 22 Sep 2020 09:49:38 +0100",
        "Message-ID": "<1600764594-14752-45-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1600764594-14752-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1600764594-14752-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-TM-AS-Product-Ver": "SMEX-12.5.0.1300-8.6.1012-25674.003",
        "X-TM-AS-Result": "No-10.776200-8.000000-10",
        "X-TMASE-MatchedRID": "mw9trAtyipRG7jIPw/RhEHF+mV3y6zKUUzwbjSjBu8pfUCHPns/+Pp56\n Gkf9zccs/+kXWhtYH7M4To4+gy/tYJ4bb0OHDj0T20204SCJw/or9gVlOIN/6nCR0itW3xfVUNM\n prKLZkXp14+k4/ABt/BrxLu0Fi00M5/PHRWHr9Zb1xv2JHBkcHz+k5IvvZ1N/V4i674aSi3w7z4\n ESg2CZP176+x/jsdTYUAPmZoU3ZU9RQ/p/AdjMtq0gCFoXW3rvk7MaK6tJVFERGC0rW8q1XcR8J\n o57YWyeMcx2oVpjkHY5QOj/9mEf04qEDaEbYNOr8Otj0KvfR1nXof+XRfBH21B3AZ+9IiUHoQYq\n Gb1tpo0h2TjaiBROWlSCmfT2v3te3qZ3A4FG8d0HwuCWPSIIAFsP0tBwe3qDkY8eITaSJPhnmli\n DOiSLQ/ykx8o/TBMCiCV8BQfvEviiBZ84q+TaK+cetZHFh20WWCAreP6x0Xi5ZjHyzYrpGpVDqq\n LeW+188Bq1zSaLx/35n5AGmg4vC5nYEvs1cJYhBWXr+dSZ1T3zDFXwlHc2qDxZFF39deGHaysPA\n 2Edn5qOY/xccpZnRvi/CWyim4deM9dcWhEzHMVlpwNsTvdlKWWeR5ETRjYDU6v/653LDVk2M0Oz\n SwdG2uLzNWBegCW2wgn7iDBesS0gBwKKRHe+r8uhUJ25cNlD05GnEtsurjQNIZGB5BwHdKxSBLp\n rEZyywz8EZAI04X4=",
        "X-TM-AS-User-Approved-Sender": "Yes",
        "X-TM-AS-User-Blocked-Sender": "No",
        "X-TMASE-Result": "10--10.776200-8.000000",
        "X-TMASE-Version": "SMEX-12.5.0.1300-8.6.1012-25674.003",
        "X-MDID": "1600764623-vFpcZ0u_VD5P",
        "Subject": "[dpdk-dev] [PATCH 44/60] common/sfc_efx/base: add function control\n\twindow lookup API",
        "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: Igor Romanov <igor.romanov@oktetlabs.ru>\n\nRiverhead NIC may provide a locator of function control window\n(EF100 resource locator).\nThe locator may be present in a Xilinx capabilities table which\nitself is located by looking into extended PCI capabilities.\n\nPCI capabilities are made possible to access by adding PCI config\nspace interface to efsys.\n\nAPIs are implemented to facilitate function control window lookup:\n - API to find an extended PCI capability given a capability ID;\n - API to read Xilinx PCI capability;\n\nSigned-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\nReviewed-by: Andy Moreton <amoreton@xilinx.com>\n---\n drivers/common/sfc_efx/base/efx.h             |  33 ++\n drivers/common/sfc_efx/base/efx_check.h       |   6 +\n drivers/common/sfc_efx/base/efx_impl.h        |  61 ++++\n drivers/common/sfc_efx/base/efx_nic.c         |  41 +++\n drivers/common/sfc_efx/base/efx_pci.c         | 302 ++++++++++++++++++\n drivers/common/sfc_efx/base/meson.build       |   2 +\n drivers/common/sfc_efx/base/rhead_impl.h      |  13 +\n drivers/common/sfc_efx/base/rhead_pci.c       |  68 ++++\n drivers/common/sfc_efx/efsys.h                |   2 +\n .../sfc_efx/rte_common_sfc_efx_version.map    |   1 +\n 10 files changed, 529 insertions(+)\n create mode 100644 drivers/common/sfc_efx/base/efx_pci.c\n create mode 100644 drivers/common/sfc_efx/base/rhead_pci.c",
    "diff": "diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h\nindex 0d4f5e5e70..f6dd9db301 100644\n--- a/drivers/common/sfc_efx/base/efx.h\n+++ b/drivers/common/sfc_efx/base/efx.h\n@@ -59,6 +59,19 @@ typedef enum efx_family_e {\n \tEFX_FAMILY_NTYPES\n } efx_family_t;\n \n+typedef enum efx_bar_type_e {\n+\tEFX_BAR_TYPE_MEM,\n+\tEFX_BAR_TYPE_IO\n+} efx_bar_type_t;\n+\n+typedef struct efx_bar_region_s {\n+\tefx_bar_type_t\t\tebr_type;\n+\tint\t\t\tebr_index;\n+\tefsys_dma_addr_t\tebr_offset;\n+\tefsys_dma_addr_t\tebr_length;\n+} efx_bar_region_t;\n+\n+/* The function is deprecated. It is used only if Riverhead is not supported. */\n LIBEFX_API\n extern\t__checkReturn\tefx_rc_t\n efx_family(\n@@ -67,6 +80,26 @@ efx_family(\n \t__out\t\tefx_family_t *efp,\n \t__out\t\tunsigned int *membarp);\n \n+#if EFSYS_OPT_PCI\n+\n+/* Determine EFX family and perform lookup of the function control window\n+ *\n+ * The function requires PCI config handle from which all memory bars can\n+ * be accessed.\n+ * A user of the API must be aware of memory bars indexes (not available\n+ * on Windows).\n+ */\n+LIBEFX_API\n+extern\t__checkReturn\tefx_rc_t\n+efx_family_probe_bar(\n+\t__in\t\tuint16_t venid,\n+\t__in\t\tuint16_t devid,\n+\t__in\t\tefsys_pci_config_t *espcp,\n+\t__out\t\tefx_family_t *efp,\n+\t__out\t\tefx_bar_region_t *ebrp);\n+\n+#endif /* EFSYS_OPT_PCI */\n+\n \n #define\tEFX_PCI_VENID_SFC\t\t\t0x1924\n #define\tEFX_PCI_VENID_XILINX\t\t\t0x10EE\ndiff --git a/drivers/common/sfc_efx/base/efx_check.h b/drivers/common/sfc_efx/base/efx_check.h\nindex 978321cf67..af90a4c373 100644\n--- a/drivers/common/sfc_efx/base/efx_check.h\n+++ b/drivers/common/sfc_efx/base/efx_check.h\n@@ -378,4 +378,10 @@\n # endif\n #endif /* EFSYS_OPT_EVB */\n \n+#if EFSYS_OPT_PCI\n+# if !EFSYS_OPT_RIVERHEAD\n+#  error \"PCI requires RIVERHEAD\"\n+# endif\n+#endif /* EFSYS_OPT_PCI */\n+\n #endif /* _SYS_EFX_CHECK_H */\ndiff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h\nindex b1457f361a..422f97c5ca 100644\n--- a/drivers/common/sfc_efx/base/efx_impl.h\n+++ b/drivers/common/sfc_efx/base/efx_impl.h\n@@ -1558,6 +1558,67 @@ efx_mcdi_mac_stats(\n \n #endif\t/* EFSYS_OPT_MAC_STATS */\n \n+#if EFSYS_OPT_PCI\n+\n+/*\n+ * Find the next extended capability in a PCI device's config space\n+ * with specified capability id.\n+ * Passing 0 offset makes the function search from the start.\n+ * If search succeeds, found capability is in modified offset.\n+ *\n+ * Returns ENOENT if a capability is not found.\n+ */\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_config_find_next_ext_cap(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__in\t\t\t\tuint16_t cap_id,\n+\t__inout\t\t\t\tsize_t *offsetp);\n+\n+/*\n+ * Get the next extended capability in a PCI device's config space.\n+ * Passing 0 offset makes the function get the first capability.\n+ * If search succeeds, the capability is in modified offset.\n+ *\n+ * Returns ENOENT if there is no next capability.\n+ */\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_config_next_ext_cap(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__inout\t\t\t\tsize_t *offsetp);\n+\n+/*\n+ * Find the next Xilinx capabilities table location by searching\n+ * PCI extended capabilities.\n+ *\n+ * Returns ENOENT if a table location is not found.\n+ */\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_find_next_xilinx_cap_table(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__inout\t\t\t\tsize_t *pci_cap_offsetp,\n+\t__out\t\t\t\tunsigned int *xilinx_tbl_barp,\n+\t__out\t\t\t\tefsys_dma_addr_t *xilinx_tbl_offsetp);\n+\n+/*\n+ * Read a Xilinx extended PCI capability that gives the location\n+ * of a Xilinx capabilities table.\n+ *\n+ * Returns ENOENT if the extended PCI capability does not contain\n+ * Xilinx capabilities table locator.\n+ */\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_read_ext_cap_xilinx_table(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__in\t\t\t\tsize_t cap_offset,\n+\t__out\t\t\t\tunsigned int *barp,\n+\t__out\t\t\t\tefsys_dma_addr_t *offsetp);\n+\n+#endif /* EFSYS_OPT_PCI */\n+\n #ifdef\t__cplusplus\n }\n #endif\ndiff --git a/drivers/common/sfc_efx/base/efx_nic.c b/drivers/common/sfc_efx/base/efx_nic.c\nindex 3dc287a095..dcf0987ebf 100644\n--- a/drivers/common/sfc_efx/base/efx_nic.c\n+++ b/drivers/common/sfc_efx/base/efx_nic.c\n@@ -103,6 +103,47 @@ efx_family(\n \treturn (ENOTSUP);\n }\n \n+#if EFSYS_OPT_PCI\n+\n+\t__checkReturn\tefx_rc_t\n+efx_family_probe_bar(\n+\t__in\t\tuint16_t venid,\n+\t__in\t\tuint16_t devid,\n+\t__in\t\tefsys_pci_config_t *espcp,\n+\t__out\t\tefx_family_t *efp,\n+\t__out\t\tefx_bar_region_t *ebrp)\n+{\n+\tefx_rc_t rc;\n+\tunsigned int membar;\n+\n+\tif (venid == EFX_PCI_VENID_XILINX) {\n+\t\tswitch (devid) {\n+#if EFSYS_OPT_RIVERHEAD\n+\t\tcase EFX_PCI_DEVID_RIVERHEAD:\n+\t\tcase EFX_PCI_DEVID_RIVERHEAD_VF:\n+\t\t\trc = rhead_pci_nic_membar_lookup(espcp, ebrp);\n+\t\t\tif (rc == 0)\n+\t\t\t\t*efp = EFX_FAMILY_RIVERHEAD;\n+\n+\t\t\treturn (rc);\n+#endif /* EFSYS_OPT_RIVERHEAD */\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\trc = efx_family(venid, devid, efp, &membar);\n+\tif (rc == 0) {\n+\t\tebrp->ebr_type = EFX_BAR_TYPE_MEM;\n+\t\tebrp->ebr_index = membar;\n+\t\tebrp->ebr_offset = 0;\n+\t\tebrp->ebr_length = 0;\n+\t}\n+\n+\treturn (rc);\n+}\n+\n+#endif /* EFSYS_OPT_PCI */\n \n #if EFSYS_OPT_SIENA\n \ndiff --git a/drivers/common/sfc_efx/base/efx_pci.c b/drivers/common/sfc_efx/base/efx_pci.c\nnew file mode 100644\nindex 0000000000..8707220849\n--- /dev/null\n+++ b/drivers/common/sfc_efx/base/efx_pci.c\n@@ -0,0 +1,302 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright(c) 2019-2020 Xilinx, Inc.\n+ * Copyright(c) 2019 Solarflare Communications Inc.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_PCI\n+\n+\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_config_next_ext_cap(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__inout\t\t\t\tsize_t *offsetp)\n+{\n+\tefx_dword_t hdr;\n+\tefx_rc_t rc = 0;\n+\tsize_t next;\n+\n+\tif (offsetp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (*offsetp == 0) {\n+\t\t*offsetp = ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE;\n+\t} else {\n+\t\tEFSYS_PCI_CONFIG_READD(espcp, *offsetp +\n+\t\t\t\t(EFX_LOW_BIT(ESF_GZ_PCI_EXPRESS_XCAP_ID) / 8),\n+\t\t\t\t&hdr, &rc);\n+\t\tif (rc != 0) {\n+\t\t\trc = EIO;\n+\t\t\tgoto fail2;\n+\t\t}\n+\n+\t\tnext = EFX_DWORD_FIELD(hdr, ESF_GZ_PCI_EXPRESS_XCAP_NEXT);\n+\t\tif (next < ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE)\n+\t\t\trc = ENOENT;\n+\t\telse\n+\t\t\t*offsetp = next;\n+\t}\n+\n+\t/*\n+\t * Returns 0 if the next capability is present otherwise ENOENT\n+\t * indicating that the function finished correctly.\n+\t */\n+\treturn (rc);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_config_find_next_ext_cap(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__in\t\t\t\tuint16_t cap_id,\n+\t__inout\t\t\t\tsize_t *offsetp)\n+{\n+\tefx_dword_t hdr;\n+\tsize_t position;\n+\tefx_rc_t rc;\n+\n+\tif (offsetp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tposition = *offsetp;\n+\n+\twhile (1) {\n+\t\trc = efx_pci_config_next_ext_cap(espcp, &position);\n+\t\tif (rc != 0) {\n+\t\t\tif (rc == ENOENT)\n+\t\t\t\tbreak;\n+\t\t\telse\n+\t\t\t\tgoto fail2;\n+\t\t}\n+\n+\t\tEFSYS_PCI_CONFIG_READD(espcp, position +\n+\t\t\t\t(EFX_LOW_BIT(ESF_GZ_PCI_EXPRESS_XCAP_ID) / 8),\n+\t\t\t\t&hdr, &rc);\n+\t\tif (rc != 0) {\n+\t\t\trc = EIO;\n+\t\t\tgoto fail3;\n+\t\t}\n+\n+\t\tif (EFX_DWORD_FIELD(hdr, ESF_GZ_PCI_EXPRESS_XCAP_ID) ==\n+\t\t    cap_id) {\n+\t\t\t*offsetp = position;\n+\t\t\trc = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Returns 0 if found otherwise ENOENT indicating that search finished\n+\t * correctly.\n+\t */\n+\treturn (rc);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_find_next_xilinx_cap_table(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__inout\t\t\t\tsize_t *pci_cap_offsetp,\n+\t__out\t\t\t\tunsigned int *xilinx_tbl_barp,\n+\t__out\t\t\t\tefsys_dma_addr_t *xilinx_tbl_offsetp)\n+{\n+\tsize_t cap_offset;\n+\tefx_rc_t rc;\n+\n+\tif (pci_cap_offsetp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tcap_offset = *pci_cap_offsetp;\n+\n+\twhile (1) {\n+\t\tunsigned int tbl_bar;\n+\t\tefsys_dma_addr_t tbl_offset;\n+\n+\t\trc = efx_pci_config_find_next_ext_cap(espcp,\n+\t\t\t\tESE_GZ_PCI_EXPRESS_XCAP_ID_VNDR, &cap_offset);\n+\t\tif (rc != 0) {\n+\t\t\tif (rc == ENOENT)\n+\t\t\t\tbreak;\n+\t\t\telse\n+\t\t\t\tgoto fail2;\n+\t\t}\n+\n+\t\t/*\n+\t\t * The found extended PCI capability is a vendor-specific\n+\t\t * capability, but not necessarily a Xilinx capabilities table\n+\t\t * locator. Try to read it and skip it if the capability is\n+\t\t * not the locator.\n+\t\t */\n+\t\trc = efx_pci_read_ext_cap_xilinx_table(espcp, cap_offset,\n+\t\t\t\t\t\t       &tbl_bar, &tbl_offset);\n+\t\tif (rc == 0) {\n+\t\t\t*xilinx_tbl_barp = tbl_bar;\n+\t\t\t*xilinx_tbl_offsetp = tbl_offset;\n+\t\t\t*pci_cap_offsetp = cap_offset;\n+\t\t\tbreak;\n+\t\t} else {\n+\t\t\tif (rc == ENOENT)\n+\t\t\t\tcontinue;\n+\t\t\telse\n+\t\t\t\tgoto fail3;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Returns 0 if found otherwise ENOENT indicating that search finished\n+\t * correctly.\n+\t */\n+\treturn (rc);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\t\t\tefx_rc_t\n+efx_pci_read_ext_cap_xilinx_table(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__in\t\t\t\tsize_t cap_offset,\n+\t__out\t\t\t\tunsigned int *barp,\n+\t__out\t\t\t\tefsys_dma_addr_t *offsetp)\n+{\n+\tsize_t vsec_offset = cap_offset + ESE_GZ_PCI_EXPRESS_XCAP_HDR_SIZE;\n+\tefx_dword_t cap_hdr;\n+\tefx_oword_t vsec;\n+\tuint32_t vsec_len;\n+\tuint32_t vsec_id;\n+\tuint32_t vsec_rev;\n+\tuint32_t offset_low;\n+\tuint32_t offset_high = 0;\n+\tunsigned int bar;\n+\tefsys_dma_addr_t offset;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_PCI_CONFIG_READD(espcp, cap_offset +\n+\t\t\t       (EFX_LOW_BIT(ESF_GZ_PCI_EXPRESS_XCAP_ID) / 8),\n+\t\t\t       &cap_hdr, &rc);\n+\tif (rc != 0) {\n+\t\trc = EIO;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (EFX_DWORD_FIELD(cap_hdr, ESF_GZ_PCI_EXPRESS_XCAP_VER) !=\n+\t    ESE_GZ_PCI_EXPRESS_XCAP_VER_VSEC) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\tEFSYS_PCI_CONFIG_READD(espcp, vsec_offset +\n+\t\t\t       (EFX_LOW_BIT(ESF_GZ_VSEC_ID) / 8),\n+\t\t\t       &vsec.eo_dword[0], &rc);\n+\tif (rc != 0) {\n+\t\trc = EIO;\n+\t\tgoto fail3;\n+\t}\n+\n+\tvsec_len = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_LEN);\n+\tvsec_id = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_ID);\n+\tvsec_rev = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_VER);\n+\n+\t/*\n+\t * Condition of the vendor-specific extended PCI capability not being\n+\t * a Xilinx capabilities table locator.\n+\t */\n+\tif (vsec_id != ESE_GZ_XILINX_VSEC_ID) {\n+\t\trc = ENOENT;\n+\t\tgoto fail4;\n+\t}\n+\n+\tif (vsec_rev != ESE_GZ_VSEC_VER_XIL_CFGBAR ||\n+\t    vsec_len < ESE_GZ_VSEC_LEN_MIN) {\n+\t\trc = EINVAL;\n+\t\tgoto fail5;\n+\t}\n+\n+\tEFSYS_PCI_CONFIG_READD(espcp, vsec_offset +\n+\t\t\t       (EFX_LOW_BIT(ESF_GZ_VSEC_TBL_BAR) / 8),\n+\t\t\t       &vsec.eo_dword[1], &rc);\n+\tif (rc != 0) {\n+\t\trc = EIO;\n+\t\tgoto fail6;\n+\t}\n+\n+\tbar = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_TBL_BAR);\n+\toffset_low = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_TBL_OFF_LO);\n+\n+\tif (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT) {\n+\t\tEFSYS_PCI_CONFIG_READD(espcp, vsec_offset +\n+\t\t\t\t(EFX_LOW_BIT(ESF_GZ_VSEC_TBL_OFF_HI) / 8),\n+\t\t\t\t&vsec.eo_dword[2], &rc);\n+\t\tif (rc != 0) {\n+\t\t\trc = EIO;\n+\t\t\tgoto fail7;\n+\t\t}\n+\n+\t\toffset_high = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_TBL_OFF_HI);\n+\t}\n+\n+\t/* High bits of low offset are discarded by the shift */\n+\toffset = offset_low << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT;\n+\n+\t/*\n+\t * Avoid the 'left shift count >= width of type' warning on systems\n+\t * without uint64_t support.\n+\t */\n+#if EFSYS_HAS_UINT64\n+\toffset |= (uint64_t)offset_high << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT;\n+#else\n+\t_NOTE(ARGUNUSED(offset_high))\n+#endif\n+\n+\t*offsetp = offset;\n+\t*barp = bar;\n+\n+\treturn (0);\n+\n+fail7:\n+\tEFSYS_PROBE(fail7);\n+fail6:\n+\tEFSYS_PROBE(fail6);\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+#endif /* EFSYS_OPT_PCI */\ndiff --git a/drivers/common/sfc_efx/base/meson.build b/drivers/common/sfc_efx/base/meson.build\nindex 8f944bb45b..21feb36c73 100644\n--- a/drivers/common/sfc_efx/base/meson.build\n+++ b/drivers/common/sfc_efx/base/meson.build\n@@ -19,6 +19,7 @@ sources = [\n \t'efx_mon.c',\n \t'efx_nic.c',\n \t'efx_nvram.c',\n+\t'efx_pci.c',\n \t'efx_phy.c',\n \t'efx_port.c',\n \t'efx_proxy.c',\n@@ -55,6 +56,7 @@ sources = [\n \t'rhead_ev.c',\n \t'rhead_intr.c',\n \t'rhead_nic.c',\n+\t'rhead_pci.c',\n \t'rhead_rx.c',\n \t'rhead_tx.c',\n ]\ndiff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h\nindex fa5e2b4915..777179fb17 100644\n--- a/drivers/common/sfc_efx/base/rhead_impl.h\n+++ b/drivers/common/sfc_efx/base/rhead_impl.h\n@@ -437,6 +437,19 @@ rhead_tx_qstats_update(\n \n #endif /* EFSYS_OPT_QSTATS */\n \n+#if EFSYS_OPT_PCI\n+\n+/*\n+ * Perform discovery of function control window by looking for a\n+ * EF100 locator in Xilinx capabilities tables.\n+ */\n+LIBEFX_INTERNAL\n+extern\t__checkReturn\t\t\tefx_rc_t\n+rhead_pci_nic_membar_lookup(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__out\t\t\t\tefx_bar_region_t *ebrp);\n+\n+#endif /* EFSYS_OPT_PCI */\n \n #ifdef\t__cplusplus\n }\ndiff --git a/drivers/common/sfc_efx/base/rhead_pci.c b/drivers/common/sfc_efx/base/rhead_pci.c\nnew file mode 100644\nindex 0000000000..f8e372b79c\n--- /dev/null\n+++ b/drivers/common/sfc_efx/base/rhead_pci.c\n@@ -0,0 +1,68 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ *\n+ * Copyright(c) 2019-2020 Xilinx, Inc.\n+ * Copyright(c) 2019 Solarflare Communications Inc.\n+ */\n+\n+#include \"efx.h\"\n+#include \"efx_impl.h\"\n+\n+#if EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI\n+\n+\t__checkReturn\t\t\tefx_rc_t\n+rhead_pci_nic_membar_lookup(\n+\t__in\t\t\t\tefsys_pci_config_t *espcp,\n+\t__out\t\t\t\tefx_bar_region_t *ebrp)\n+{\n+\tboolean_t xilinx_tbl_found = B_FALSE;\n+\tunsigned int xilinx_tbl_bar;\n+\tefsys_dma_addr_t xilinx_tbl_offset;\n+\tsize_t pci_capa_offset = 0;\n+\tboolean_t bar_found = B_FALSE;\n+\tefx_rc_t rc = ENOENT;\n+\n+\t/*\n+\t * SF-119689-TC Riverhead Host Interface section 4.2.2. describes\n+\t * the following discovery steps.\n+\t */\n+\twhile (1) {\n+\t\trc = efx_pci_find_next_xilinx_cap_table(espcp, &pci_capa_offset,\n+\t\t\t\t\t\t\t&xilinx_tbl_bar,\n+\t\t\t\t\t\t\t&xilinx_tbl_offset);\n+\t\tif (rc != 0) {\n+\t\t\t/*\n+\t\t\t * SF-119689-TC Riverhead Host Interface section 4.2.2.\n+\t\t\t * defines the following fallbacks for the memory bar\n+\t\t\t * and the offset when no Xilinx capabilities table is\n+\t\t\t * found.\n+\t\t\t */\n+\t\t\tif (rc == ENOENT && xilinx_tbl_found == B_FALSE) {\n+\t\t\t\tebrp->ebr_type = EFX_BAR_TYPE_MEM;\n+\t\t\t\tebrp->ebr_index = EFX_MEM_BAR_RIVERHEAD;\n+\t\t\t\tebrp->ebr_offset = 0;\n+\t\t\t\tebrp->ebr_length = 0;\n+\t\t\t\tbar_found = B_TRUE;\n+\t\t\t\tbreak;\n+\t\t\t} else {\n+\t\t\t\tgoto fail1;\n+\t\t\t}\n+\n+\t\t}\n+\n+\t\txilinx_tbl_found = B_TRUE;\n+\t}\n+\n+\tif (bar_found == B_FALSE)\n+\t\tgoto fail2;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+#endif /* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI */\ndiff --git a/drivers/common/sfc_efx/efsys.h b/drivers/common/sfc_efx/efsys.h\nindex e191cb5b6a..de1c1c38e3 100644\n--- a/drivers/common/sfc_efx/efsys.h\n+++ b/drivers/common/sfc_efx/efsys.h\n@@ -162,6 +162,8 @@ prefetch_read_once(const volatile void *addr)\n \n #define EFSYS_OPT_MCDI_PROXY_AUTH_SERVER 0\n \n+#define EFSYS_OPT_PCI 0\n+\n /* ID */\n \n typedef struct __efsys_identifier_s efsys_identifier_t;\ndiff --git a/drivers/common/sfc_efx/rte_common_sfc_efx_version.map b/drivers/common/sfc_efx/rte_common_sfc_efx_version.map\nindex 16fffee321..627469a025 100644\n--- a/drivers/common/sfc_efx/rte_common_sfc_efx_version.map\n+++ b/drivers/common/sfc_efx/rte_common_sfc_efx_version.map\n@@ -19,6 +19,7 @@ INTERNAL {\n \tefx_evq_size;\n \n \tefx_family;\n+\tefx_family_probe_bar;\n \n \tefx_filter_fini;\n \tefx_filter_init;\n",
    "prefixes": [
        "44/60"
    ]
}