common/sfc_efx/base: add efsys API to find a memory BAR
[dpdk.git] / drivers / common / sfc_efx / base / rhead_pci.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2019 Solarflare Communications Inc.
5  */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9
10 #if EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI
11
12         __checkReturn                   efx_rc_t
13 rhead_pci_nic_membar_lookup(
14         __in                            efsys_pci_config_t *espcp,
15         __out                           efx_bar_region_t *ebrp)
16 {
17         boolean_t xilinx_tbl_found = B_FALSE;
18         unsigned int xilinx_tbl_bar;
19         efsys_dma_addr_t xilinx_tbl_offset;
20         size_t pci_capa_offset = 0;
21         boolean_t bar_found = B_FALSE;
22         efx_rc_t rc = ENOENT;
23         efsys_bar_t xil_eb;
24
25         /*
26          * SF-119689-TC Riverhead Host Interface section 4.2.2. describes
27          * the following discovery steps.
28          */
29         while (1) {
30                 rc = efx_pci_find_next_xilinx_cap_table(espcp, &pci_capa_offset,
31                                                         &xilinx_tbl_bar,
32                                                         &xilinx_tbl_offset);
33                 if (rc != 0) {
34                         /*
35                          * SF-119689-TC Riverhead Host Interface section 4.2.2.
36                          * defines the following fallbacks for the memory bar
37                          * and the offset when no Xilinx capabilities table is
38                          * found.
39                          */
40                         if (rc == ENOENT && xilinx_tbl_found == B_FALSE) {
41                                 ebrp->ebr_type = EFX_BAR_TYPE_MEM;
42                                 ebrp->ebr_index = EFX_MEM_BAR_RIVERHEAD;
43                                 ebrp->ebr_offset = 0;
44                                 ebrp->ebr_length = 0;
45                                 bar_found = B_TRUE;
46                                 break;
47                         } else {
48                                 goto fail1;
49                         }
50
51                 }
52
53                 xilinx_tbl_found = B_TRUE;
54
55                 EFSYS_PCI_FIND_MEM_BAR(espcp, xilinx_tbl_bar, &xil_eb, &rc);
56                 if (rc != 0)
57                         goto fail2;
58         }
59
60         if (bar_found == B_FALSE)
61                 goto fail3;
62
63         return (0);
64
65 fail3:
66         EFSYS_PROBE(fail3);
67 fail2:
68         EFSYS_PROBE(fail2);
69 fail1:
70         EFSYS_PROBE1(fail1, efx_rc_t, rc);
71
72         return (rc);
73 }
74
75 #endif /* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI */