From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6B16EA04E1; Tue, 22 Sep 2020 10:59:28 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id ADC7D1DBD8; Tue, 22 Sep 2020 10:51:30 +0200 (CEST) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id F032F1D724 for ; Tue, 22 Sep 2020 10:50:23 +0200 (CEST) Received: from mx1-us1.ppe-hosted.com (unknown [10.110.50.144]) by dispatch1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 9A3E52005B for ; Tue, 22 Sep 2020 08:50:23 +0000 (UTC) Received: from us4-mdac16-22.at1.mdlocal (unknown [10.110.49.204]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 99D3B800A4 for ; Tue, 22 Sep 2020 08:50:23 +0000 (UTC) X-Virus-Scanned: Proofpoint Essentials engine Received: from mx1-us1.ppe-hosted.com (unknown [10.110.50.7]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 13E3040071 for ; Tue, 22 Sep 2020 08:50:23 +0000 (UTC) Received: from webmail.solarflare.com (uk.solarflare.com [193.34.186.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id D0EEA4C005B for ; Tue, 22 Sep 2020 08:50:22 +0000 (UTC) Received: from ukex01.SolarFlarecom.com (10.17.10.4) by ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 22 Sep 2020 09:50:11 +0100 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 22 Sep 2020 09:50:11 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (ukv-loginhost.uk.solarflarecom.com [10.17.10.39]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id 08M8oBMC004786; Tue, 22 Sep 2020 09:50:11 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1]) by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id 742691613AB; Tue, 22 Sep 2020 09:50:11 +0100 (BST) From: Andrew Rybchenko To: CC: Igor Romanov 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 Gkf9zccs/+kXWhtYH7M4To4+gy/tYJ4bb0OHDj0T20204SCJw/or9gVlOIN/6nCR0itW3xfVUNM prKLZkXp14+k4/ABt/BrxLu0Fi00M5/PHRWHr9Zb1xv2JHBkcHz+k5IvvZ1N/V4i674aSi3w7z4 ESg2CZP176+x/jsdTYUAPmZoU3ZU9RQ/p/AdjMtq0gCFoXW3rvk7MaK6tJVFERGC0rW8q1XcR8J o57YWyeMcx2oVpjkHY5QOj/9mEf04qEDaEbYNOr8Otj0KvfR1nXof+XRfBH21B3AZ+9IiUHoQYq Gb1tpo0h2TjaiBROWlSCmfT2v3te3qZ3A4FG8d0HwuCWPSIIAFsP0tBwe3qDkY8eITaSJPhnmli DOiSLQ/ykx8o/TBMCiCV8BQfvEviiBZ84q+TaK+cetZHFh20WWCAreP6x0Xi5ZjHyzYrpGpVDqq LeW+188Bq1zSaLx/35n5AGmg4vC5nYEvs1cJYhBWXr+dSZ1T3zDFXwlHc2qDxZFF39deGHaysPA 2Edn5qOY/xccpZnRvi/CWyim4deM9dcWhEzHMVlpwNsTvdlKWWeR5ETRjYDU6v/653LDVk2M0Oz SwdG2uLzNWBegCW2wgn7iDBesS0gBwKKRHe+r8uhUJ25cNlD05GnEtsurjQNIZGB5BwHdKxSBLp 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 window lookup API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Igor Romanov Riverhead NIC may provide a locator of function control window (EF100 resource locator). The locator may be present in a Xilinx capabilities table which itself is located by looking into extended PCI capabilities. PCI capabilities are made possible to access by adding PCI config space interface to efsys. APIs are implemented to facilitate function control window lookup: - API to find an extended PCI capability given a capability ID; - API to read Xilinx PCI capability; Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 33 ++ drivers/common/sfc_efx/base/efx_check.h | 6 + drivers/common/sfc_efx/base/efx_impl.h | 61 ++++ drivers/common/sfc_efx/base/efx_nic.c | 41 +++ drivers/common/sfc_efx/base/efx_pci.c | 302 ++++++++++++++++++ drivers/common/sfc_efx/base/meson.build | 2 + drivers/common/sfc_efx/base/rhead_impl.h | 13 + drivers/common/sfc_efx/base/rhead_pci.c | 68 ++++ drivers/common/sfc_efx/efsys.h | 2 + .../sfc_efx/rte_common_sfc_efx_version.map | 1 + 10 files changed, 529 insertions(+) create mode 100644 drivers/common/sfc_efx/base/efx_pci.c create mode 100644 drivers/common/sfc_efx/base/rhead_pci.c diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 0d4f5e5e70..f6dd9db301 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -59,6 +59,19 @@ typedef enum efx_family_e { EFX_FAMILY_NTYPES } efx_family_t; +typedef enum efx_bar_type_e { + EFX_BAR_TYPE_MEM, + EFX_BAR_TYPE_IO +} efx_bar_type_t; + +typedef struct efx_bar_region_s { + efx_bar_type_t ebr_type; + int ebr_index; + efsys_dma_addr_t ebr_offset; + efsys_dma_addr_t ebr_length; +} efx_bar_region_t; + +/* The function is deprecated. It is used only if Riverhead is not supported. */ LIBEFX_API extern __checkReturn efx_rc_t efx_family( @@ -67,6 +80,26 @@ efx_family( __out efx_family_t *efp, __out unsigned int *membarp); +#if EFSYS_OPT_PCI + +/* Determine EFX family and perform lookup of the function control window + * + * The function requires PCI config handle from which all memory bars can + * be accessed. + * A user of the API must be aware of memory bars indexes (not available + * on Windows). + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_family_probe_bar( + __in uint16_t venid, + __in uint16_t devid, + __in efsys_pci_config_t *espcp, + __out efx_family_t *efp, + __out efx_bar_region_t *ebrp); + +#endif /* EFSYS_OPT_PCI */ + #define EFX_PCI_VENID_SFC 0x1924 #define EFX_PCI_VENID_XILINX 0x10EE diff --git a/drivers/common/sfc_efx/base/efx_check.h b/drivers/common/sfc_efx/base/efx_check.h index 978321cf67..af90a4c373 100644 --- a/drivers/common/sfc_efx/base/efx_check.h +++ b/drivers/common/sfc_efx/base/efx_check.h @@ -378,4 +378,10 @@ # endif #endif /* EFSYS_OPT_EVB */ +#if EFSYS_OPT_PCI +# if !EFSYS_OPT_RIVERHEAD +# error "PCI requires RIVERHEAD" +# endif +#endif /* EFSYS_OPT_PCI */ + #endif /* _SYS_EFX_CHECK_H */ diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index b1457f361a..422f97c5ca 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -1558,6 +1558,67 @@ efx_mcdi_mac_stats( #endif /* EFSYS_OPT_MAC_STATS */ +#if EFSYS_OPT_PCI + +/* + * Find the next extended capability in a PCI device's config space + * with specified capability id. + * Passing 0 offset makes the function search from the start. + * If search succeeds, found capability is in modified offset. + * + * Returns ENOENT if a capability is not found. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_config_find_next_ext_cap( + __in efsys_pci_config_t *espcp, + __in uint16_t cap_id, + __inout size_t *offsetp); + +/* + * Get the next extended capability in a PCI device's config space. + * Passing 0 offset makes the function get the first capability. + * If search succeeds, the capability is in modified offset. + * + * Returns ENOENT if there is no next capability. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_config_next_ext_cap( + __in efsys_pci_config_t *espcp, + __inout size_t *offsetp); + +/* + * Find the next Xilinx capabilities table location by searching + * PCI extended capabilities. + * + * Returns ENOENT if a table location is not found. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_find_next_xilinx_cap_table( + __in efsys_pci_config_t *espcp, + __inout size_t *pci_cap_offsetp, + __out unsigned int *xilinx_tbl_barp, + __out efsys_dma_addr_t *xilinx_tbl_offsetp); + +/* + * Read a Xilinx extended PCI capability that gives the location + * of a Xilinx capabilities table. + * + * Returns ENOENT if the extended PCI capability does not contain + * Xilinx capabilities table locator. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_read_ext_cap_xilinx_table( + __in efsys_pci_config_t *espcp, + __in size_t cap_offset, + __out unsigned int *barp, + __out efsys_dma_addr_t *offsetp); + +#endif /* EFSYS_OPT_PCI */ + #ifdef __cplusplus } #endif diff --git a/drivers/common/sfc_efx/base/efx_nic.c b/drivers/common/sfc_efx/base/efx_nic.c index 3dc287a095..dcf0987ebf 100644 --- a/drivers/common/sfc_efx/base/efx_nic.c +++ b/drivers/common/sfc_efx/base/efx_nic.c @@ -103,6 +103,47 @@ efx_family( return (ENOTSUP); } +#if EFSYS_OPT_PCI + + __checkReturn efx_rc_t +efx_family_probe_bar( + __in uint16_t venid, + __in uint16_t devid, + __in efsys_pci_config_t *espcp, + __out efx_family_t *efp, + __out efx_bar_region_t *ebrp) +{ + efx_rc_t rc; + unsigned int membar; + + if (venid == EFX_PCI_VENID_XILINX) { + switch (devid) { +#if EFSYS_OPT_RIVERHEAD + case EFX_PCI_DEVID_RIVERHEAD: + case EFX_PCI_DEVID_RIVERHEAD_VF: + rc = rhead_pci_nic_membar_lookup(espcp, ebrp); + if (rc == 0) + *efp = EFX_FAMILY_RIVERHEAD; + + return (rc); +#endif /* EFSYS_OPT_RIVERHEAD */ + default: + break; + } + } + + rc = efx_family(venid, devid, efp, &membar); + if (rc == 0) { + ebrp->ebr_type = EFX_BAR_TYPE_MEM; + ebrp->ebr_index = membar; + ebrp->ebr_offset = 0; + ebrp->ebr_length = 0; + } + + return (rc); +} + +#endif /* EFSYS_OPT_PCI */ #if EFSYS_OPT_SIENA diff --git a/drivers/common/sfc_efx/base/efx_pci.c b/drivers/common/sfc_efx/base/efx_pci.c new file mode 100644 index 0000000000..8707220849 --- /dev/null +++ b/drivers/common/sfc_efx/base/efx_pci.c @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2020 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + */ + +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_PCI + + __checkReturn efx_rc_t +efx_pci_config_next_ext_cap( + __in efsys_pci_config_t *espcp, + __inout size_t *offsetp) +{ + efx_dword_t hdr; + efx_rc_t rc = 0; + size_t next; + + if (offsetp == NULL) { + rc = EINVAL; + goto fail1; + } + + if (*offsetp == 0) { + *offsetp = ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE; + } else { + EFSYS_PCI_CONFIG_READD(espcp, *offsetp + + (EFX_LOW_BIT(ESF_GZ_PCI_EXPRESS_XCAP_ID) / 8), + &hdr, &rc); + if (rc != 0) { + rc = EIO; + goto fail2; + } + + next = EFX_DWORD_FIELD(hdr, ESF_GZ_PCI_EXPRESS_XCAP_NEXT); + if (next < ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE) + rc = ENOENT; + else + *offsetp = next; + } + + /* + * Returns 0 if the next capability is present otherwise ENOENT + * indicating that the function finished correctly. + */ + return (rc); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_pci_config_find_next_ext_cap( + __in efsys_pci_config_t *espcp, + __in uint16_t cap_id, + __inout size_t *offsetp) +{ + efx_dword_t hdr; + size_t position; + efx_rc_t rc; + + if (offsetp == NULL) { + rc = EINVAL; + goto fail1; + } + + position = *offsetp; + + while (1) { + rc = efx_pci_config_next_ext_cap(espcp, &position); + if (rc != 0) { + if (rc == ENOENT) + break; + else + goto fail2; + } + + EFSYS_PCI_CONFIG_READD(espcp, position + + (EFX_LOW_BIT(ESF_GZ_PCI_EXPRESS_XCAP_ID) / 8), + &hdr, &rc); + if (rc != 0) { + rc = EIO; + goto fail3; + } + + if (EFX_DWORD_FIELD(hdr, ESF_GZ_PCI_EXPRESS_XCAP_ID) == + cap_id) { + *offsetp = position; + rc = 0; + break; + } + } + + /* + * Returns 0 if found otherwise ENOENT indicating that search finished + * correctly. + */ + return (rc); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_pci_find_next_xilinx_cap_table( + __in efsys_pci_config_t *espcp, + __inout size_t *pci_cap_offsetp, + __out unsigned int *xilinx_tbl_barp, + __out efsys_dma_addr_t *xilinx_tbl_offsetp) +{ + size_t cap_offset; + efx_rc_t rc; + + if (pci_cap_offsetp == NULL) { + rc = EINVAL; + goto fail1; + } + + cap_offset = *pci_cap_offsetp; + + while (1) { + unsigned int tbl_bar; + efsys_dma_addr_t tbl_offset; + + rc = efx_pci_config_find_next_ext_cap(espcp, + ESE_GZ_PCI_EXPRESS_XCAP_ID_VNDR, &cap_offset); + if (rc != 0) { + if (rc == ENOENT) + break; + else + goto fail2; + } + + /* + * The found extended PCI capability is a vendor-specific + * capability, but not necessarily a Xilinx capabilities table + * locator. Try to read it and skip it if the capability is + * not the locator. + */ + rc = efx_pci_read_ext_cap_xilinx_table(espcp, cap_offset, + &tbl_bar, &tbl_offset); + if (rc == 0) { + *xilinx_tbl_barp = tbl_bar; + *xilinx_tbl_offsetp = tbl_offset; + *pci_cap_offsetp = cap_offset; + break; + } else { + if (rc == ENOENT) + continue; + else + goto fail3; + } + } + + /* + * Returns 0 if found otherwise ENOENT indicating that search finished + * correctly. + */ + return (rc); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_pci_read_ext_cap_xilinx_table( + __in efsys_pci_config_t *espcp, + __in size_t cap_offset, + __out unsigned int *barp, + __out efsys_dma_addr_t *offsetp) +{ + size_t vsec_offset = cap_offset + ESE_GZ_PCI_EXPRESS_XCAP_HDR_SIZE; + efx_dword_t cap_hdr; + efx_oword_t vsec; + uint32_t vsec_len; + uint32_t vsec_id; + uint32_t vsec_rev; + uint32_t offset_low; + uint32_t offset_high = 0; + unsigned int bar; + efsys_dma_addr_t offset; + efx_rc_t rc; + + EFSYS_PCI_CONFIG_READD(espcp, cap_offset + + (EFX_LOW_BIT(ESF_GZ_PCI_EXPRESS_XCAP_ID) / 8), + &cap_hdr, &rc); + if (rc != 0) { + rc = EIO; + goto fail1; + } + + if (EFX_DWORD_FIELD(cap_hdr, ESF_GZ_PCI_EXPRESS_XCAP_VER) != + ESE_GZ_PCI_EXPRESS_XCAP_VER_VSEC) { + rc = EINVAL; + goto fail2; + } + + EFSYS_PCI_CONFIG_READD(espcp, vsec_offset + + (EFX_LOW_BIT(ESF_GZ_VSEC_ID) / 8), + &vsec.eo_dword[0], &rc); + if (rc != 0) { + rc = EIO; + goto fail3; + } + + vsec_len = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_LEN); + vsec_id = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_ID); + vsec_rev = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_VER); + + /* + * Condition of the vendor-specific extended PCI capability not being + * a Xilinx capabilities table locator. + */ + if (vsec_id != ESE_GZ_XILINX_VSEC_ID) { + rc = ENOENT; + goto fail4; + } + + if (vsec_rev != ESE_GZ_VSEC_VER_XIL_CFGBAR || + vsec_len < ESE_GZ_VSEC_LEN_MIN) { + rc = EINVAL; + goto fail5; + } + + EFSYS_PCI_CONFIG_READD(espcp, vsec_offset + + (EFX_LOW_BIT(ESF_GZ_VSEC_TBL_BAR) / 8), + &vsec.eo_dword[1], &rc); + if (rc != 0) { + rc = EIO; + goto fail6; + } + + bar = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_TBL_BAR); + offset_low = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_TBL_OFF_LO); + + if (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT) { + EFSYS_PCI_CONFIG_READD(espcp, vsec_offset + + (EFX_LOW_BIT(ESF_GZ_VSEC_TBL_OFF_HI) / 8), + &vsec.eo_dword[2], &rc); + if (rc != 0) { + rc = EIO; + goto fail7; + } + + offset_high = EFX_OWORD_FIELD32(vsec, ESF_GZ_VSEC_TBL_OFF_HI); + } + + /* High bits of low offset are discarded by the shift */ + offset = offset_low << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT; + + /* + * Avoid the 'left shift count >= width of type' warning on systems + * without uint64_t support. + */ +#if EFSYS_HAS_UINT64 + offset |= (uint64_t)offset_high << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT; +#else + _NOTE(ARGUNUSED(offset_high)) +#endif + + *offsetp = offset; + *barp = bar; + + return (0); + +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_PCI */ diff --git a/drivers/common/sfc_efx/base/meson.build b/drivers/common/sfc_efx/base/meson.build index 8f944bb45b..21feb36c73 100644 --- a/drivers/common/sfc_efx/base/meson.build +++ b/drivers/common/sfc_efx/base/meson.build @@ -19,6 +19,7 @@ sources = [ 'efx_mon.c', 'efx_nic.c', 'efx_nvram.c', + 'efx_pci.c', 'efx_phy.c', 'efx_port.c', 'efx_proxy.c', @@ -55,6 +56,7 @@ sources = [ 'rhead_ev.c', 'rhead_intr.c', 'rhead_nic.c', + 'rhead_pci.c', 'rhead_rx.c', 'rhead_tx.c', ] diff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h index fa5e2b4915..777179fb17 100644 --- a/drivers/common/sfc_efx/base/rhead_impl.h +++ b/drivers/common/sfc_efx/base/rhead_impl.h @@ -437,6 +437,19 @@ rhead_tx_qstats_update( #endif /* EFSYS_OPT_QSTATS */ +#if EFSYS_OPT_PCI + +/* + * Perform discovery of function control window by looking for a + * EF100 locator in Xilinx capabilities tables. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +rhead_pci_nic_membar_lookup( + __in efsys_pci_config_t *espcp, + __out efx_bar_region_t *ebrp); + +#endif /* EFSYS_OPT_PCI */ #ifdef __cplusplus } diff --git a/drivers/common/sfc_efx/base/rhead_pci.c b/drivers/common/sfc_efx/base/rhead_pci.c new file mode 100644 index 0000000000..f8e372b79c --- /dev/null +++ b/drivers/common/sfc_efx/base/rhead_pci.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2020 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + */ + +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI + + __checkReturn efx_rc_t +rhead_pci_nic_membar_lookup( + __in efsys_pci_config_t *espcp, + __out efx_bar_region_t *ebrp) +{ + boolean_t xilinx_tbl_found = B_FALSE; + unsigned int xilinx_tbl_bar; + efsys_dma_addr_t xilinx_tbl_offset; + size_t pci_capa_offset = 0; + boolean_t bar_found = B_FALSE; + efx_rc_t rc = ENOENT; + + /* + * SF-119689-TC Riverhead Host Interface section 4.2.2. describes + * the following discovery steps. + */ + while (1) { + rc = efx_pci_find_next_xilinx_cap_table(espcp, &pci_capa_offset, + &xilinx_tbl_bar, + &xilinx_tbl_offset); + if (rc != 0) { + /* + * SF-119689-TC Riverhead Host Interface section 4.2.2. + * defines the following fallbacks for the memory bar + * and the offset when no Xilinx capabilities table is + * found. + */ + if (rc == ENOENT && xilinx_tbl_found == B_FALSE) { + ebrp->ebr_type = EFX_BAR_TYPE_MEM; + ebrp->ebr_index = EFX_MEM_BAR_RIVERHEAD; + ebrp->ebr_offset = 0; + ebrp->ebr_length = 0; + bar_found = B_TRUE; + break; + } else { + goto fail1; + } + + } + + xilinx_tbl_found = B_TRUE; + } + + if (bar_found == B_FALSE) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI */ diff --git a/drivers/common/sfc_efx/efsys.h b/drivers/common/sfc_efx/efsys.h index e191cb5b6a..de1c1c38e3 100644 --- a/drivers/common/sfc_efx/efsys.h +++ b/drivers/common/sfc_efx/efsys.h @@ -162,6 +162,8 @@ prefetch_read_once(const volatile void *addr) #define EFSYS_OPT_MCDI_PROXY_AUTH_SERVER 0 +#define EFSYS_OPT_PCI 0 + /* ID */ typedef struct __efsys_identifier_s efsys_identifier_t; diff --git a/drivers/common/sfc_efx/rte_common_sfc_efx_version.map b/drivers/common/sfc_efx/rte_common_sfc_efx_version.map index 16fffee321..627469a025 100644 --- a/drivers/common/sfc_efx/rte_common_sfc_efx_version.map +++ b/drivers/common/sfc_efx/rte_common_sfc_efx_version.map @@ -19,6 +19,7 @@ INTERNAL { efx_evq_size; efx_family; + efx_family_probe_bar; efx_filter_fini; efx_filter_init; -- 2.17.1