Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright(c) 2019-2021 Xilinx, Inc.
4 : : * Copyright(c) 2018-2019 Solarflare Communications Inc.
5 : : */
6 : :
7 : : #include "efx.h"
8 : : #include "efx_impl.h"
9 : :
10 : :
11 : : #if EFSYS_OPT_RIVERHEAD
12 : :
13 : : __checkReturn efx_rc_t
14 : 0 : rhead_board_cfg(
15 : : __in efx_nic_t *enp)
16 : : {
17 : : efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
18 : : uint32_t end_padding;
19 : : uint32_t bandwidth;
20 : : efx_rc_t rc;
21 : :
22 [ # # ]: 0 : if ((rc = efx_mcdi_nic_board_cfg(enp)) != 0)
23 : 0 : goto fail1;
24 : :
25 : : /*
26 : : * The tunnel encapsulation initialization happens unconditionally
27 : : * for now.
28 : : */
29 : 0 : encp->enc_tunnel_encapsulations_supported =
30 : : (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
31 : : (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
32 : :
33 : : /*
34 : : * Software limitation inherited from EF10. This limit is not
35 : : * increased since the hardware does not report this limit, it is
36 : : * handled internally resulting in a tunnel add error when there is no
37 : : * space for more UDP tunnels.
38 : : */
39 : 0 : encp->enc_tunnel_config_udp_entries_max = EFX_TUNNEL_MAXNENTRIES;
40 : :
41 : 0 : encp->enc_clk_mult = 1; /* not used for Riverhead */
42 : :
43 : : EFX_STATIC_ASSERT(MC_CMD_INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES_LEN == 4);
44 : : /* Agrees with MC_CMD_INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES_LEN */
45 : 0 : encp->enc_rx_dma_desc_size_max = UINT32_MAX;
46 : :
47 : : /*
48 : : * FIXME There are TxSend and TxSeg descriptors on Riverhead.
49 : : * TxSeg is bigger than TxSend.
50 : : */
51 : 0 : encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_GZ_TX_SEND_LEN);
52 : : /* No boundary crossing limits */
53 : 0 : encp->enc_tx_dma_desc_boundary = 0;
54 : :
55 : : /*
56 : : * Initialise design parameters to either a runtime value read from
57 : : * the design parameters area or the well known default value
58 : : * (see SF-119689-TC section 4.4 for details).
59 : : * FIXME: Read design parameters area values.
60 : : */
61 : 0 : encp->enc_tx_tso_max_header_ndescs =
62 : : ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT;
63 : 0 : encp->enc_tx_tso_max_header_length =
64 : : ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
65 : 0 : encp->enc_tx_tso_max_payload_ndescs =
66 : : ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT;
67 : 0 : encp->enc_tx_tso_max_payload_length =
68 : : ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT;
69 : 0 : encp->enc_tx_tso_max_nframes =
70 : : ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT;
71 : :
72 : : /*
73 : : * Riverhead does not put any restrictions on TCP header offset limit.
74 : : */
75 : 0 : encp->enc_tx_tso_tcp_header_offset_limit = UINT32_MAX;
76 : :
77 : : /*
78 : : * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
79 : : * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
80 : : * resources (allocated to this PCIe function), which is zero until
81 : : * after we have allocated VIs.
82 : : */
83 : 0 : encp->enc_evq_limit = 1024;
84 : 0 : encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
85 : 0 : encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
86 : :
87 : 0 : encp->enc_buftbl_limit = UINT32_MAX;
88 : :
89 : : /*
90 : : * Riverhead event queue creation completes
91 : : * immediately (no initial event).
92 : : */
93 : 0 : encp->enc_evq_init_done_ev_supported = B_FALSE;
94 : :
95 : : /*
96 : : * Enable firmware workarounds for hardware errata.
97 : : * Expected responses are:
98 : : * - 0 (zero):
99 : : * Success: workaround enabled or disabled as requested.
100 : : * - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
101 : : * Firmware does not support the MC_CMD_WORKAROUND request.
102 : : * (assume that the workaround is not supported).
103 : : * - MC_CMD_ERR_ENOENT (reported as ENOENT):
104 : : * Firmware does not support the requested workaround.
105 : : * - MC_CMD_ERR_EPERM (reported as EACCES):
106 : : * Unprivileged function cannot enable/disable workarounds.
107 : : *
108 : : * See efx_mcdi_request_errcode() for MCDI error translations.
109 : : */
110 : :
111 : : /*
112 : : * Replay engine on Riverhead should suppress duplicate packets
113 : : * (e.g. because of exact multicast and all-multicast filters
114 : : * match) to the same RxQ.
115 : : */
116 : 0 : encp->enc_bug26807_workaround = B_FALSE;
117 : :
118 : : /*
119 : : * Checksums for TSO sends should always be correct on Riverhead.
120 : : * FIXME: revisit when TSO support is implemented.
121 : : */
122 : 0 : encp->enc_bug61297_workaround = B_FALSE;
123 : :
124 : 0 : encp->enc_evq_max_nevs = RHEAD_EVQ_MAXNEVS;
125 : 0 : encp->enc_evq_min_nevs = RHEAD_EVQ_MINNEVS;
126 : 0 : encp->enc_rxq_max_ndescs = RHEAD_RXQ_MAXNDESCS;
127 : 0 : encp->enc_rxq_min_ndescs = RHEAD_RXQ_MINNDESCS;
128 : 0 : encp->enc_txq_max_ndescs = RHEAD_TXQ_MAXNDESCS;
129 : 0 : encp->enc_txq_min_ndescs = RHEAD_TXQ_MINNDESCS;
130 : :
131 : : /* Riverhead FW does not support event queue timers yet. */
132 : 0 : encp->enc_evq_timer_quantum_ns = 0;
133 : 0 : encp->enc_evq_timer_max_us = 0;
134 : :
135 : : #if EFSYS_OPT_EV_EXTENDED_WIDTH
136 : : encp->enc_ev_ew_desc_size = RHEAD_EVQ_EW_DESC_SIZE;
137 : : #else
138 : 0 : encp->enc_ev_ew_desc_size = 0;
139 : : #endif
140 : :
141 : 0 : encp->enc_ev_desc_size = RHEAD_EVQ_DESC_SIZE;
142 : 0 : encp->enc_rx_desc_size = RHEAD_RXQ_DESC_SIZE;
143 : 0 : encp->enc_tx_desc_size = RHEAD_TXQ_DESC_SIZE;
144 : :
145 : : /* No required alignment for WPTR updates */
146 : 0 : encp->enc_rx_push_align = 1;
147 : :
148 : : /* Riverhead supports a single Rx prefix size. */
149 : 0 : encp->enc_rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN;
150 : :
151 : : /* Alignment for receive packet DMA buffers. */
152 : 0 : encp->enc_rx_buf_align_start = 1;
153 : :
154 : : /* Get the RX DMA end padding alignment configuration. */
155 [ # # ]: 0 : if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
156 [ # # ]: 0 : if (rc != EACCES)
157 : 0 : goto fail2;
158 : :
159 : : /* Assume largest tail padding size supported by hardware. */
160 : 0 : end_padding = 128;
161 : : }
162 : 0 : encp->enc_rx_buf_align_end = end_padding;
163 : :
164 : : /* FIXME: It should be extracted from design parameters (Bug 86844) */
165 : 0 : encp->enc_rx_scatter_max = 7;
166 : :
167 : : /*
168 : : * Riverhead stores a single global copy of VPD, not per-PF as on
169 : : * Huntington.
170 : : */
171 : 0 : encp->enc_vpd_is_global = B_TRUE;
172 : :
173 : 0 : rc = ef10_nic_get_port_mode_bandwidth(enp, &bandwidth);
174 [ # # ]: 0 : if (rc != 0)
175 : 0 : goto fail3;
176 : 0 : encp->enc_required_pcie_bandwidth_mbps = bandwidth;
177 : 0 : encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3;
178 : :
179 : : /*
180 : : * FIXME: MCDI table API support depends on an EF100 firmware build
181 : : * and an EF100 platform. It should be discovered by using a capability
182 : : * flag from MCDI that is not implemented yet.
183 : : * Right now we can safely rely on the return code from the libefx
184 : : * MCDI Table API.
185 : : */
186 : 0 : encp->enc_table_api_supported = B_TRUE;
187 : :
188 : 0 : return (0);
189 : :
190 : : fail3:
191 : : EFSYS_PROBE(fail3);
192 : : fail2:
193 : : EFSYS_PROBE(fail2);
194 : : fail1:
195 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
196 : :
197 : : return (rc);
198 : : }
199 : :
200 : : __checkReturn efx_rc_t
201 : 0 : rhead_nic_probe(
202 : : __in efx_nic_t *enp)
203 : : {
204 : 0 : const efx_nic_ops_t *enop = enp->en_enop;
205 : : efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
206 : : efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
207 : : efx_rc_t rc;
208 : :
209 [ # # ]: 0 : EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
210 : :
211 : : /* Read and clear any assertion state */
212 [ # # ]: 0 : if ((rc = efx_mcdi_read_assertion(enp)) != 0)
213 : 0 : goto fail1;
214 : :
215 : : /* Exit the assertion handler */
216 [ # # ]: 0 : if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
217 [ # # ]: 0 : if (rc != EACCES)
218 : 0 : goto fail2;
219 : :
220 [ # # ]: 0 : if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
221 : 0 : goto fail3;
222 : :
223 : : /* Get remaining controller-specific board config */
224 [ # # ]: 0 : if ((rc = enop->eno_board_cfg(enp)) != 0)
225 : 0 : goto fail4;
226 : :
227 : : /*
228 : : * Set default driver config limits (based on board config).
229 : : *
230 : : * FIXME: For now allocate a fixed number of VIs which is likely to be
231 : : * sufficient and small enough to allow multiple functions on the same
232 : : * port.
233 : : */
234 : 0 : edcp->edc_min_vi_count = edcp->edc_max_vi_count =
235 : 0 : MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
236 : :
237 : : /*
238 : : * The client driver must configure and enable PIO buffer support,
239 : : * but there is no PIO support on Riverhead anyway.
240 : : */
241 : 0 : edcp->edc_max_piobuf_count = 0;
242 : 0 : edcp->edc_pio_alloc_size = 0;
243 : :
244 : : #if EFSYS_OPT_MAC_STATS
245 : : /* Wipe the MAC statistics */
246 [ # # ]: 0 : if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
247 : 0 : goto fail5;
248 : : #endif
249 : :
250 : : #if EFSYS_OPT_LOOPBACK
251 [ # # ]: 0 : if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
252 : 0 : goto fail6;
253 : : #endif
254 : :
255 : : return (0);
256 : :
257 : : #if EFSYS_OPT_LOOPBACK
258 : : fail6:
259 : : EFSYS_PROBE(fail6);
260 : : #endif
261 : : #if EFSYS_OPT_MAC_STATS
262 : : fail5:
263 : : EFSYS_PROBE(fail5);
264 : : #endif
265 : : fail4:
266 : : EFSYS_PROBE(fail4);
267 : : fail3:
268 : : EFSYS_PROBE(fail3);
269 : : fail2:
270 : : EFSYS_PROBE(fail2);
271 : : fail1:
272 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
273 : :
274 : : return (rc);
275 : : }
276 : :
277 : : __checkReturn efx_rc_t
278 : 0 : rhead_nic_set_drv_limits(
279 : : __inout efx_nic_t *enp,
280 : : __in efx_drv_limits_t *edlp)
281 : : {
282 : 0 : const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
283 : : efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
284 : : uint32_t min_evq_count, max_evq_count;
285 : : uint32_t min_rxq_count, max_rxq_count;
286 : : uint32_t min_txq_count, max_txq_count;
287 : : efx_rc_t rc;
288 : :
289 [ # # ]: 0 : if (edlp == NULL) {
290 : : rc = EINVAL;
291 : 0 : goto fail1;
292 : : }
293 : :
294 : : /* Get minimum required and maximum usable VI limits */
295 : 0 : min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
296 : 0 : min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
297 : 0 : min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
298 : :
299 : 0 : edcp->edc_min_vi_count =
300 : 0 : MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
301 : :
302 : 0 : max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
303 : 0 : max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
304 : 0 : max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
305 : :
306 : 0 : edcp->edc_max_vi_count =
307 : 0 : MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
308 : :
309 : : /* There is no PIO support on Riverhead */
310 : 0 : edcp->edc_max_piobuf_count = 0;
311 : 0 : edcp->edc_pio_alloc_size = 0;
312 : :
313 : 0 : return (0);
314 : :
315 : : fail1:
316 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
317 : :
318 : 0 : return (rc);
319 : : }
320 : :
321 : : __checkReturn efx_rc_t
322 : 0 : rhead_nic_reset(
323 : : __in efx_nic_t *enp)
324 : : {
325 : : efx_rc_t rc;
326 : :
327 : : /* ef10_nic_reset() is called to recover from BADASSERT failures. */
328 [ # # ]: 0 : if ((rc = efx_mcdi_read_assertion(enp)) != 0)
329 : 0 : goto fail1;
330 [ # # ]: 0 : if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
331 : 0 : goto fail2;
332 : :
333 [ # # ]: 0 : if ((rc = efx_mcdi_entity_reset(enp)) != 0)
334 : 0 : goto fail3;
335 : :
336 : : /* Clear RX/TX DMA queue errors */
337 : 0 : enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
338 : :
339 : 0 : return (0);
340 : :
341 : : fail3:
342 : : EFSYS_PROBE(fail3);
343 : : fail2:
344 : : EFSYS_PROBE(fail2);
345 : : fail1:
346 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
347 : :
348 : : return (rc);
349 : : }
350 : :
351 : : __checkReturn efx_rc_t
352 : 0 : rhead_nic_init(
353 : : __in efx_nic_t *enp)
354 : : {
355 : : const efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
356 : : uint32_t min_vi_count, max_vi_count;
357 : : uint32_t vi_count, vi_base, vi_shift;
358 : : uint32_t vi_window_size;
359 : : efx_rc_t rc;
360 : : boolean_t alloc_vadaptor = B_TRUE;
361 : :
362 [ # # ]: 0 : EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
363 [ # # ]: 0 : EFSYS_ASSERT3U(edcp->edc_max_piobuf_count, ==, 0);
364 : :
365 : : /* Enable reporting of some events (e.g. link change) */
366 [ # # ]: 0 : if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
367 : 0 : goto fail1;
368 : :
369 : 0 : min_vi_count = edcp->edc_min_vi_count;
370 : 0 : max_vi_count = edcp->edc_max_vi_count;
371 : :
372 : : /* Ensure that the previously attached driver's VIs are freed */
373 [ # # ]: 0 : if ((rc = efx_mcdi_free_vis(enp)) != 0)
374 : 0 : goto fail2;
375 : :
376 : : /*
377 : : * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
378 : : * fails then retrying the request for fewer VI resources may succeed.
379 : : */
380 : 0 : vi_count = 0;
381 [ # # ]: 0 : if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
382 : : &vi_base, &vi_count, &vi_shift)) != 0)
383 : 0 : goto fail3;
384 : :
385 : : EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
386 : :
387 [ # # ]: 0 : if (vi_count < min_vi_count) {
388 : : rc = ENOMEM;
389 : 0 : goto fail4;
390 : : }
391 : :
392 : 0 : enp->en_arch.ef10.ena_vi_base = vi_base;
393 : 0 : enp->en_arch.ef10.ena_vi_count = vi_count;
394 : 0 : enp->en_arch.ef10.ena_vi_shift = vi_shift;
395 : :
396 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=,
397 : : EFX_VI_WINDOW_SHIFT_INVALID);
398 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=,
399 : : EFX_VI_WINDOW_SHIFT_64K);
400 : : vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift;
401 : :
402 : : /* Save UC memory mapping details */
403 : 0 : enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
404 : 0 : enp->en_arch.ef10.ena_uc_mem_map_size =
405 : 0 : vi_window_size * enp->en_arch.ef10.ena_vi_count;
406 : :
407 : : /* No WC memory mapping since PIO is not supported */
408 : 0 : enp->en_arch.ef10.ena_pio_write_vi_base = 0;
409 : 0 : enp->en_arch.ef10.ena_wc_mem_map_offset = 0;
410 : 0 : enp->en_arch.ef10.ena_wc_mem_map_size = 0;
411 : :
412 : 0 : enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
413 : :
414 : : /*
415 : : * For SR-IOV use case, vAdaptor is allocated for PF and associated VFs
416 : : * during NIC initialization when vSwitch is created and vPorts are
417 : : * allocated. Hence, skip vAdaptor allocation for EVB and update vPort
418 : : * ID in NIC structure with the one allocated for PF.
419 : : */
420 : :
421 : 0 : enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
422 : : #if EFSYS_OPT_EVB
423 [ # # # # ]: 0 : if ((enp->en_vswitchp != NULL) && (enp->en_vswitchp->ev_evcp != NULL)) {
424 : : /* For EVB use vPort allocated on vSwitch */
425 : 0 : enp->en_vport_id = enp->en_vswitchp->ev_evcp->evc_vport_id;
426 : : alloc_vadaptor = B_FALSE;
427 : : }
428 : : #endif
429 : : if (alloc_vadaptor != B_FALSE) {
430 : : /* Allocate a vAdaptor attached to our upstream vPort/pPort */
431 [ # # ]: 0 : if ((rc = ef10_upstream_port_vadaptor_alloc(enp)) != 0)
432 : 0 : goto fail5;
433 : : }
434 : :
435 : : return (0);
436 : :
437 : : fail5:
438 : : EFSYS_PROBE(fail5);
439 : :
440 : 0 : fail4:
441 : : EFSYS_PROBE(fail4);
442 : :
443 : 0 : (void) efx_mcdi_free_vis(enp);
444 : :
445 : : fail3:
446 : : EFSYS_PROBE(fail3);
447 : : fail2:
448 : : EFSYS_PROBE(fail2);
449 : : fail1:
450 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
451 : :
452 : : return (rc);
453 : : }
454 : :
455 : : __checkReturn efx_rc_t
456 : 0 : rhead_nic_get_vi_pool(
457 : : __in efx_nic_t *enp,
458 : : __out uint32_t *vi_countp)
459 : : {
460 : : /*
461 : : * Report VIs that the client driver can use.
462 : : * Do not include VIs used for PIO buffer writes.
463 : : */
464 : 0 : *vi_countp = enp->en_arch.ef10.ena_vi_count;
465 : :
466 : 0 : return (0);
467 : : }
468 : :
469 : : __checkReturn efx_rc_t
470 : 0 : rhead_nic_get_bar_region(
471 : : __in efx_nic_t *enp,
472 : : __in efx_nic_region_t region,
473 : : __out uint32_t *offsetp,
474 : : __out size_t *sizep)
475 : : {
476 : : efx_rc_t rc;
477 : :
478 [ # # ]: 0 : EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
479 : :
480 : : /*
481 : : * TODO: Specify host memory mapping alignment and granularity
482 : : * in efx_drv_limits_t so that they can be taken into account
483 : : * when allocating extra VIs for PIO writes.
484 : : */
485 [ # # # ]: 0 : switch (region) {
486 : 0 : case EFX_REGION_VI:
487 : : /* UC mapped memory BAR region for VI registers */
488 : 0 : *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
489 : 0 : *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
490 : 0 : break;
491 : :
492 : 0 : case EFX_REGION_PIO_WRITE_VI:
493 : : /* WC mapped memory BAR region for piobuf writes */
494 : 0 : *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
495 : 0 : *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
496 : 0 : break;
497 : :
498 : 0 : default:
499 : : rc = EINVAL;
500 : 0 : goto fail1;
501 : : }
502 : :
503 : : return (0);
504 : :
505 : : fail1:
506 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
507 : :
508 : 0 : return (rc);
509 : : }
510 : :
511 : : __checkReturn boolean_t
512 : 0 : rhead_nic_hw_unavailable(
513 : : __in efx_nic_t *enp)
514 : : {
515 : : efx_dword_t dword;
516 : :
517 [ # # ]: 0 : if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
518 : : return (B_TRUE);
519 : :
520 [ # # # # : 0 : EFX_BAR_FCW_READD(enp, ER_GZ_MC_SFT_STATUS, &dword);
# # ]
521 [ # # ]: 0 : if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
522 : 0 : goto unavail;
523 : :
524 : : return (B_FALSE);
525 : :
526 : : unavail:
527 : 0 : rhead_nic_set_hw_unavailable(enp);
528 : :
529 : 0 : return (B_TRUE);
530 : : }
531 : :
532 : : void
533 : 0 : rhead_nic_set_hw_unavailable(
534 : : __in efx_nic_t *enp)
535 : : {
536 : : EFSYS_PROBE(hw_unavail);
537 : 0 : enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
538 : 0 : }
539 : :
540 : : void
541 : 0 : rhead_nic_fini(
542 : : __in efx_nic_t *enp)
543 : : {
544 : : boolean_t do_vadaptor_free = B_TRUE;
545 : :
546 : : #if EFSYS_OPT_EVB
547 [ # # ]: 0 : if (enp->en_vswitchp != NULL) {
548 : : /*
549 : : * For SR-IOV the vAdaptor is freed with the vSwitch,
550 : : * so do not free it here.
551 : : */
552 : : do_vadaptor_free = B_FALSE;
553 : : }
554 : : #endif
555 : : if (do_vadaptor_free != B_FALSE) {
556 : 0 : (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
557 : 0 : enp->en_vport_id = EVB_PORT_ID_NULL;
558 : : }
559 : :
560 : 0 : (void) efx_mcdi_free_vis(enp);
561 : 0 : enp->en_arch.ef10.ena_vi_count = 0;
562 : 0 : }
563 : :
564 : : void
565 : 0 : rhead_nic_unprobe(
566 : : __in efx_nic_t *enp)
567 : : {
568 : 0 : (void) efx_mcdi_drv_attach(enp, B_FALSE);
569 : 0 : }
570 : :
571 : : #if EFSYS_OPT_DIAG
572 : :
573 : : __checkReturn efx_rc_t
574 : : rhead_nic_register_test(
575 : : __in efx_nic_t *enp)
576 : : {
577 : : efx_rc_t rc;
578 : :
579 : : /* FIXME */
580 : : _NOTE(ARGUNUSED(enp))
581 : : _NOTE(CONSTANTCONDITION)
582 : : if (B_FALSE) {
583 : : rc = ENOTSUP;
584 : : goto fail1;
585 : : }
586 : : /* FIXME */
587 : :
588 : : return (0);
589 : :
590 : : fail1:
591 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
592 : :
593 : : return (rc);
594 : : }
595 : :
596 : : #endif /* EFSYS_OPT_DIAG */
597 : :
598 : : __checkReturn efx_rc_t
599 : 0 : rhead_nic_xilinx_cap_tbl_read_ef100_locator(
600 : : __in efsys_bar_t *esbp,
601 : : __in efsys_dma_addr_t offset,
602 : : __out efx_bar_region_t *ebrp)
603 : : {
604 : : efx_oword_t entry;
605 : : uint32_t rev;
606 : : uint32_t len;
607 : : efx_rc_t rc;
608 : :
609 : : /*
610 : : * Xilinx Capabilities Table requires 32bit aligned reads.
611 : : * See SF-119689-TC section 4.2.2 "Discovery Steps".
612 : : */
613 [ # # ]: 0 : EFSYS_BAR_READD(esbp, offset +
614 : : (EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_FORMAT) / 8),
615 : : &entry.eo_dword[0], B_FALSE);
616 : 0 : EFSYS_BAR_READD(esbp, offset +
617 : : (EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_SIZE) / 8),
618 : : &entry.eo_dword[1], B_FALSE);
619 : :
620 : 0 : rev = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_REV);
621 : : len = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_SIZE);
622 : :
623 : 0 : if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
624 [ # # ]: 0 : len < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
625 : : rc = EINVAL;
626 : 0 : goto fail1;
627 : : }
628 : :
629 : 0 : EFSYS_BAR_READD(esbp, offset +
630 : : (EFX_LOW_BIT(ESF_GZ_CFGBAR_EF100_BAR) / 8),
631 : : &entry.eo_dword[2], B_FALSE);
632 : :
633 : 0 : ebrp->ebr_index = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_EF100_BAR);
634 : 0 : ebrp->ebr_offset = EFX_OWORD_FIELD32(entry,
635 : 0 : ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF) <<
636 : : ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
637 : 0 : ebrp->ebr_type = EFX_BAR_TYPE_MEM;
638 : 0 : ebrp->ebr_length = 0;
639 : :
640 : 0 : return (0);
641 : :
642 : : fail1:
643 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
644 : :
645 : 0 : return (rc);
646 : : }
647 : :
648 : : #endif /* EFSYS_OPT_RIVERHEAD */
|