Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright(c) 2019-2021 Xilinx, Inc.
4 : : * Copyright(c) 2007-2019 Solarflare Communications Inc.
5 : : */
6 : :
7 : : #include "efx.h"
8 : : #include "efx_impl.h"
9 : :
10 : : __checkReturn efx_rc_t
11 : 0 : efx_sram_buf_tbl_set(
12 : : __in efx_nic_t *enp,
13 : : __in uint32_t id,
14 : : __in efsys_mem_t *esmp,
15 : : __in size_t n)
16 : : {
17 : : efx_qword_t qword;
18 : : uint32_t start = id;
19 : 0 : uint32_t stop = start + n;
20 : : efsys_dma_addr_t addr;
21 : : efx_oword_t oword;
22 : : unsigned int count;
23 : : efx_rc_t rc;
24 : :
25 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
26 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
27 : :
28 : : #if EFX_OPTS_EF10()
29 [ # # ]: 0 : if (EFX_FAMILY_IS_EF10(enp)) {
30 : : /*
31 : : * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
32 : : * pulled inside the Falcon/Siena queue create/destroy code,
33 : : * and then the original functions can be removed (see bug30834
34 : : * comment #1). But, for now, we just ensure that they are
35 : : * no-ops for EF10, to allow bringing up existing drivers
36 : : * without modification.
37 : : */
38 : :
39 : : return (0);
40 : : }
41 : : #endif /* EFX_OPTS_EF10() */
42 : :
43 [ # # ]: 0 : if (stop >= EFX_BUF_TBL_SIZE) {
44 : : rc = EFBIG;
45 : 0 : goto fail1;
46 : : }
47 : :
48 : : /* Add the entries into the buffer table */
49 : 0 : addr = EFSYS_MEM_ADDR(esmp);
50 [ # # ]: 0 : for (id = start; id != stop; id++) {
51 : 0 : EFX_POPULATE_QWORD_5(qword,
52 : : FRF_AZ_IP_DAT_BUF_SIZE, 0, FRF_AZ_BUF_ADR_REGION, 0,
53 : : FRF_AZ_BUF_ADR_FBUF_DW0,
54 : : (uint32_t)((addr >> 12) & 0xffffffff),
55 : : FRF_AZ_BUF_ADR_FBUF_DW1,
56 : : (uint32_t)((addr >> 12) >> 32),
57 : : FRF_AZ_BUF_OWNER_ID_FBUF, 0);
58 : :
59 [ # # # # ]: 0 : EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_FULL_TBL,
60 : : id, &qword);
61 : :
62 : 0 : addr += EFX_BUF_SIZE;
63 : : }
64 : :
65 : : EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
66 : :
67 : : /* Flush the write buffer */
68 : 0 : EFX_POPULATE_OWORD_2(oword, FRF_AZ_BUF_UPD_CMD, 1,
69 : : FRF_AZ_BUF_CLR_CMD, 0);
70 [ # # # # ]: 0 : EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
71 : :
72 : : /* Poll for the last entry being written to the buffer table */
73 : : EFSYS_ASSERT3U(id, ==, stop);
74 : 0 : addr -= EFX_BUF_SIZE;
75 : :
76 : : count = 0;
77 : : do {
78 : : EFSYS_PROBE1(wait, unsigned int, count);
79 : :
80 : : /* Spin for 1 ms */
81 : 0 : EFSYS_SPIN(1000);
82 : :
83 [ # # # # ]: 0 : EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL,
84 : : id - 1, &qword);
85 : :
86 : 0 : if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) ==
87 [ # # ]: 0 : (uint32_t)((addr >> 12) & 0xffffffff) &&
88 : 0 : EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) ==
89 [ # # ]: 0 : (uint32_t)((addr >> 12) >> 32))
90 : 0 : goto verify;
91 : :
92 [ # # ]: 0 : } while (++count < 100);
93 : :
94 : : rc = ETIMEDOUT;
95 : 0 : goto fail2;
96 : :
97 : : verify:
98 : : /* Verify the rest of the entries in the buffer table */
99 [ # # ]: 0 : while (--id != start) {
100 : 0 : addr -= EFX_BUF_SIZE;
101 : :
102 : : /* Read the buffer table entry */
103 [ # # # # ]: 0 : EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL,
104 : : id - 1, &qword);
105 : :
106 : 0 : if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) !=
107 [ # # ]: 0 : (uint32_t)((addr >> 12) & 0xffffffff) ||
108 : 0 : EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) !=
109 [ # # ]: 0 : (uint32_t)((addr >> 12) >> 32)) {
110 : : rc = EFAULT;
111 : 0 : goto fail3;
112 : : }
113 : : }
114 : :
115 : : return (0);
116 : :
117 : : fail3:
118 : : EFSYS_PROBE(fail3);
119 : :
120 : : id = stop;
121 : :
122 : 0 : fail2:
123 : : EFSYS_PROBE(fail2);
124 : :
125 : 0 : EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0,
126 : : FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, id - 1,
127 : : FRF_AZ_BUF_CLR_START_ID, start);
128 [ # # # # ]: 0 : EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
129 : :
130 : : fail1:
131 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
132 : :
133 : : return (rc);
134 : : }
135 : :
136 : : void
137 : 0 : efx_sram_buf_tbl_clear(
138 : : __in efx_nic_t *enp,
139 : : __in uint32_t id,
140 : : __in size_t n)
141 : : {
142 : : efx_oword_t oword;
143 : : uint32_t start = id;
144 : 0 : uint32_t stop = start + n;
145 : :
146 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
147 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
148 : :
149 : : #if EFX_OPTS_EF10()
150 [ # # ]: 0 : if (EFX_FAMILY_IS_EF10(enp)) {
151 : : /*
152 : : * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
153 : : * pulled inside the Falcon/Siena queue create/destroy code,
154 : : * and then the original functions can be removed (see bug30834
155 : : * comment #1). But, for now, we just ensure that they are
156 : : * no-ops for EF10, to allow bringing up existing drivers
157 : : * without modification.
158 : : */
159 : :
160 : 0 : return;
161 : : }
162 : : #endif /* EFX_OPTS_EF10() */
163 : :
164 [ # # ]: 0 : EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE);
165 : :
166 : : EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
167 : :
168 : 0 : EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0,
169 : : FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, stop - 1,
170 : : FRF_AZ_BUF_CLR_START_ID, start);
171 [ # # # # : 0 : EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
# ]
172 : : }
173 : :
174 : :
175 : : #if EFSYS_OPT_DIAG
176 : :
177 : : static void
178 : : efx_sram_byte_increment_set(
179 : : __in size_t row,
180 : : __in boolean_t negate,
181 : : __out efx_qword_t *eqp)
182 : : {
183 : : size_t offset = row * FR_AZ_SRM_DBG_REG_STEP;
184 : : unsigned int index;
185 : :
186 : : _NOTE(ARGUNUSED(negate))
187 : :
188 : : for (index = 0; index < sizeof (efx_qword_t); index++)
189 : : eqp->eq_u8[index] = offset + index;
190 : : }
191 : :
192 : : static void
193 : : efx_sram_all_the_same_set(
194 : : __in size_t row,
195 : : __in boolean_t negate,
196 : : __out efx_qword_t *eqp)
197 : : {
198 : : _NOTE(ARGUNUSED(row))
199 : :
200 : : if (negate)
201 : : EFX_SET_QWORD(*eqp);
202 : : else
203 : : EFX_ZERO_QWORD(*eqp);
204 : : }
205 : :
206 : : static void
207 : : efx_sram_bit_alternate_set(
208 : : __in size_t row,
209 : : __in boolean_t negate,
210 : : __out efx_qword_t *eqp)
211 : : {
212 : : _NOTE(ARGUNUSED(row))
213 : :
214 : : EFX_POPULATE_QWORD_2(*eqp,
215 : : EFX_DWORD_0, (negate) ? 0x55555555 : 0xaaaaaaaa,
216 : : EFX_DWORD_1, (negate) ? 0x55555555 : 0xaaaaaaaa);
217 : : }
218 : :
219 : : static void
220 : : efx_sram_byte_alternate_set(
221 : : __in size_t row,
222 : : __in boolean_t negate,
223 : : __out efx_qword_t *eqp)
224 : : {
225 : : _NOTE(ARGUNUSED(row))
226 : :
227 : : EFX_POPULATE_QWORD_2(*eqp,
228 : : EFX_DWORD_0, (negate) ? 0x00ff00ff : 0xff00ff00,
229 : : EFX_DWORD_1, (negate) ? 0x00ff00ff : 0xff00ff00);
230 : : }
231 : :
232 : : static void
233 : : efx_sram_byte_changing_set(
234 : : __in size_t row,
235 : : __in boolean_t negate,
236 : : __out efx_qword_t *eqp)
237 : : {
238 : : size_t offset = row * FR_AZ_SRM_DBG_REG_STEP;
239 : : unsigned int index;
240 : :
241 : : for (index = 0; index < sizeof (efx_qword_t); index++) {
242 : : uint8_t byte;
243 : :
244 : : if (offset / 256 == 0)
245 : : byte = (uint8_t)((offset % 257) % 256);
246 : : else
247 : : byte = (uint8_t)(~((offset - 8) % 257) % 256);
248 : :
249 : : eqp->eq_u8[index] = (negate) ? ~byte : byte;
250 : : }
251 : : }
252 : :
253 : : static void
254 : : efx_sram_bit_sweep_set(
255 : : __in size_t row,
256 : : __in boolean_t negate,
257 : : __out efx_qword_t *eqp)
258 : : {
259 : : size_t offset = row * FR_AZ_SRM_DBG_REG_STEP;
260 : :
261 : : if (negate) {
262 : : EFX_SET_QWORD(*eqp);
263 : : EFX_CLEAR_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64);
264 : : } else {
265 : : EFX_ZERO_QWORD(*eqp);
266 : : EFX_SET_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64);
267 : : }
268 : : }
269 : :
270 : : efx_sram_pattern_fn_t __efx_sram_pattern_fns[] = {
271 : : efx_sram_byte_increment_set,
272 : : efx_sram_all_the_same_set,
273 : : efx_sram_bit_alternate_set,
274 : : efx_sram_byte_alternate_set,
275 : : efx_sram_byte_changing_set,
276 : : efx_sram_bit_sweep_set
277 : : };
278 : :
279 : : __checkReturn efx_rc_t
280 : : efx_sram_test(
281 : : __in efx_nic_t *enp,
282 : : __in efx_pattern_type_t type)
283 : : {
284 : : efx_sram_pattern_fn_t func;
285 : :
286 : : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
287 : :
288 : : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
289 : :
290 : : EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
291 : : EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
292 : : EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
293 : :
294 : : /* SRAM testing is only available on Siena. */
295 : : if (enp->en_family != EFX_FAMILY_SIENA)
296 : : return (0);
297 : :
298 : : /* Select pattern generator */
299 : : EFSYS_ASSERT3U(type, <, EFX_PATTERN_NTYPES);
300 : : func = __efx_sram_pattern_fns[type];
301 : :
302 : : return (siena_sram_test(enp, func));
303 : : }
304 : :
305 : : #endif /* EFSYS_OPT_DIAG */
|