common/sfc_efx: update copyright year
[dpdk.git] / drivers / common / sfc_efx / base / rhead_pci.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2021 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 /*
13  * Search for a EF100 resource locator from the given offset of an entry
14  * in a Xilinx capabilities table.
15  */
16 static  __checkReturn                   efx_rc_t
17 rhead_xilinx_cap_tbl_find_ef100_locator(
18         __in                            efsys_bar_t *esbp,
19         __in                            efsys_dma_addr_t tbl_offset,
20         __out                           efx_bar_region_t *ef100_ebrp)
21 {
22         efx_rc_t rc;
23         efsys_dma_addr_t entry_offset = tbl_offset;
24
25         rc = efx_pci_xilinx_cap_tbl_find(esbp, ESE_GZ_CFGBAR_ENTRY_EF100,
26                                            B_FALSE, &entry_offset);
27         if (rc != 0) {
28                 /* EF100 locator not found (ENOENT) or other error */
29                 goto fail1;
30         }
31
32         rc = rhead_nic_xilinx_cap_tbl_read_ef100_locator(esbp, entry_offset,
33                                                          ef100_ebrp);
34         if (rc != 0)
35                 goto fail2;
36
37         return (0);
38
39 fail2:
40         EFSYS_PROBE(fail2);
41 fail1:
42         EFSYS_PROBE1(fail1, efx_rc_t, rc);
43
44         return (rc);
45 }
46
47         __checkReturn                   efx_rc_t
48 rhead_pci_nic_membar_lookup(
49         __in                            efsys_pci_config_t *espcp,
50         __in                            const efx_pci_ops_t *epop,
51         __out                           efx_bar_region_t *ebrp)
52 {
53         boolean_t xilinx_tbl_found = B_FALSE;
54         unsigned int xilinx_tbl_bar;
55         efsys_dma_addr_t xilinx_tbl_offset;
56         size_t pci_capa_offset = 0;
57         boolean_t bar_found = B_FALSE;
58         efx_rc_t rc = ENOENT;
59         efsys_bar_t xil_eb;
60         efsys_bar_t nic_eb;
61         efx_dword_t magic_ed;
62         uint32_t magic;
63
64         /*
65          * SF-119689-TC Riverhead Host Interface section 4.2.2. describes
66          * the following discovery steps.
67          */
68         while (1) {
69                 rc = efx_pci_find_next_xilinx_cap_table(espcp, epop,
70                                                         &pci_capa_offset,
71                                                         &xilinx_tbl_bar,
72                                                         &xilinx_tbl_offset);
73                 if (rc != 0) {
74                         /*
75                          * SF-119689-TC Riverhead Host Interface section 4.2.2.
76                          * defines the following fallbacks for the memory bar
77                          * and the offset when no Xilinx capabilities table is
78                          * found.
79                          */
80                         if (rc == ENOENT && xilinx_tbl_found == B_FALSE) {
81                                 ebrp->ebr_type = EFX_BAR_TYPE_MEM;
82                                 ebrp->ebr_index = EFX_MEM_BAR_RIVERHEAD;
83                                 ebrp->ebr_offset = 0;
84                                 ebrp->ebr_length = 0;
85                                 bar_found = B_TRUE;
86                                 break;
87                         } else {
88                                 goto fail1;
89                         }
90
91                 }
92
93                 xilinx_tbl_found = B_TRUE;
94
95                 rc = epop->epo_find_mem_bar(espcp, xilinx_tbl_bar, &xil_eb);
96                 if (rc != 0)
97                         goto fail2;
98
99                 rc = rhead_xilinx_cap_tbl_find_ef100_locator(&xil_eb,
100                                                              xilinx_tbl_offset,
101                                                              ebrp);
102                 if (rc == 0) {
103                         /* Found valid EF100 locator. */
104                         bar_found = B_TRUE;
105                         break;
106                 } else if (rc != ENOENT) {
107                         /* Table access failed, so terminate search. */
108                         goto fail3;
109                 }
110         }
111
112         if (bar_found == B_FALSE)
113                 goto fail4;
114
115         rc = epop->epo_find_mem_bar(espcp, ebrp->ebr_index, &nic_eb);
116         if (rc != 0)
117                 goto fail5;
118
119         EFSYS_BAR_READD(&nic_eb, ebrp->ebr_offset + ER_GZ_NIC_MAGIC_OFST,
120                         &magic_ed, B_FALSE);
121
122         magic = EFX_DWORD_FIELD(magic_ed, ERF_GZ_NIC_MAGIC);
123         if (magic != EFE_GZ_NIC_MAGIC_EXPECTED) {
124                 rc = EINVAL;
125                 goto fail6;
126         }
127
128         return (0);
129
130 fail6:
131         EFSYS_PROBE(fail6);
132 fail5:
133         EFSYS_PROBE(fail5);
134 fail4:
135         EFSYS_PROBE(fail4);
136 fail3:
137         EFSYS_PROBE(fail3);
138 fail2:
139         EFSYS_PROBE(fail2);
140 fail1:
141         EFSYS_PROBE1(fail1, efx_rc_t, rc);
142
143         return (rc);
144 }
145
146 #endif /* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_PCI */