xref: /dpdk/drivers/common/sfc_efx/base/rhead_nic.c (revision 950fe1ed0818e4e3582f62f02030c834decf09c0)
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
rhead_board_cfg(__in efx_nic_t * enp)14 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 	if ((rc = efx_mcdi_nic_board_cfg(enp)) != 0)
23 		goto fail1;
24 
25 	/*
26 	 * The tunnel encapsulation initialization happens unconditionally
27 	 * for now.
28 	 */
29 	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 	encp->enc_tunnel_config_udp_entries_max = EFX_TUNNEL_MAXNENTRIES;
40 
41 	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 	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 	encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_GZ_TX_SEND_LEN);
52 	/* No boundary crossing limits */
53 	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 	encp->enc_tx_tso_max_header_ndescs =
62 	    ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT;
63 	encp->enc_tx_tso_max_header_length =
64 	    ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
65 	encp->enc_tx_tso_max_payload_ndescs =
66 	    ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT;
67 	encp->enc_tx_tso_max_payload_length =
68 	    ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT;
69 	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 	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 	encp->enc_evq_limit = 1024;
84 	encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
85 	encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
86 
87 	encp->enc_buftbl_limit = UINT32_MAX;
88 
89 	/*
90 	 * Riverhead event queue creation completes
91 	 * immediately (no initial event).
92 	 */
93 	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 	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 	encp->enc_bug61297_workaround = B_FALSE;
123 
124 	encp->enc_evq_max_nevs = RHEAD_EVQ_MAXNEVS;
125 	encp->enc_evq_min_nevs = RHEAD_EVQ_MINNEVS;
126 	encp->enc_rxq_max_ndescs = RHEAD_RXQ_MAXNDESCS;
127 	encp->enc_rxq_min_ndescs = RHEAD_RXQ_MINNDESCS;
128 	encp->enc_txq_max_ndescs = RHEAD_TXQ_MAXNDESCS;
129 	encp->enc_txq_min_ndescs = RHEAD_TXQ_MINNDESCS;
130 
131 	/* Riverhead FW does not support event queue timers yet. */
132 	encp->enc_evq_timer_quantum_ns = 0;
133 	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 	encp->enc_ev_ew_desc_size = 0;
139 #endif
140 
141 	encp->enc_ev_desc_size = RHEAD_EVQ_DESC_SIZE;
142 	encp->enc_rx_desc_size = RHEAD_RXQ_DESC_SIZE;
143 	encp->enc_tx_desc_size = RHEAD_TXQ_DESC_SIZE;
144 
145 	/* No required alignment for WPTR updates */
146 	encp->enc_rx_push_align = 1;
147 
148 	/* Riverhead supports a single Rx prefix size. */
149 	encp->enc_rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN;
150 
151 	/* Alignment for receive packet DMA buffers. */
152 	encp->enc_rx_buf_align_start = 1;
153 
154 	/* Get the RX DMA end padding alignment configuration. */
155 	if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
156 		if (rc != EACCES)
157 			goto fail2;
158 
159 		/* Assume largest tail padding size supported by hardware. */
160 		end_padding = 128;
161 	}
162 	encp->enc_rx_buf_align_end = end_padding;
163 
164 	/* FIXME: It should be extracted from design parameters (Bug 86844) */
165 	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 	encp->enc_vpd_is_global = B_TRUE;
172 
173 	rc = ef10_nic_get_port_mode_bandwidth(enp, &bandwidth);
174 	if (rc != 0)
175 		goto fail3;
176 	encp->enc_required_pcie_bandwidth_mbps = bandwidth;
177 	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 	encp->enc_table_api_supported = B_TRUE;
187 
188 	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
rhead_nic_probe(__in efx_nic_t * enp)201 rhead_nic_probe(
202 	__in		efx_nic_t *enp)
203 {
204 	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 	EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
210 
211 	/* Read and clear any assertion state */
212 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
213 		goto fail1;
214 
215 	/* Exit the assertion handler */
216 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
217 		if (rc != EACCES)
218 			goto fail2;
219 
220 	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
221 		goto fail3;
222 
223 	/* Get remaining controller-specific board config */
224 	if ((rc = enop->eno_board_cfg(enp)) != 0)
225 		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 	edcp->edc_min_vi_count = edcp->edc_max_vi_count =
235 	    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 	edcp->edc_max_piobuf_count = 0;
242 	edcp->edc_pio_alloc_size = 0;
243 
244 #if EFSYS_OPT_MAC_STATS
245 	/* Wipe the MAC statistics */
246 	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
247 		goto fail5;
248 #endif
249 
250 #if EFSYS_OPT_LOOPBACK
251 	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
252 		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
rhead_nic_set_drv_limits(__inout efx_nic_t * enp,__in efx_drv_limits_t * edlp)278 rhead_nic_set_drv_limits(
279 	__inout		efx_nic_t *enp,
280 	__in		efx_drv_limits_t *edlp)
281 {
282 	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 	if (edlp == NULL) {
290 		rc = EINVAL;
291 		goto fail1;
292 	}
293 
294 	/* Get minimum required and maximum usable VI limits */
295 	min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
296 	min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
297 	min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
298 
299 	edcp->edc_min_vi_count =
300 	    MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
301 
302 	max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
303 	max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
304 	max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
305 
306 	edcp->edc_max_vi_count =
307 	    MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
308 
309 	/* There is no PIO support on Riverhead */
310 	edcp->edc_max_piobuf_count = 0;
311 	edcp->edc_pio_alloc_size = 0;
312 
313 	return (0);
314 
315 fail1:
316 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
317 
318 	return (rc);
319 }
320 
321 	__checkReturn	efx_rc_t
rhead_nic_reset(__in efx_nic_t * enp)322 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 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
329 		goto fail1;
330 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
331 		goto fail2;
332 
333 	if ((rc = efx_mcdi_entity_reset(enp)) != 0)
334 		goto fail3;
335 
336 	/* Clear RX/TX DMA queue errors */
337 	enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
338 
339 	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
rhead_nic_init(__in efx_nic_t * enp)352 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 	EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
363 	EFSYS_ASSERT3U(edcp->edc_max_piobuf_count, ==, 0);
364 
365 	/* Enable reporting of some events (e.g. link change) */
366 	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
367 		goto fail1;
368 
369 	min_vi_count = edcp->edc_min_vi_count;
370 	max_vi_count = edcp->edc_max_vi_count;
371 
372 	/* Ensure that the previously attached driver's VIs are freed */
373 	if ((rc = efx_mcdi_free_vis(enp)) != 0)
374 		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 	vi_count = 0;
381 	if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
382 		    &vi_base, &vi_count, &vi_shift)) != 0)
383 		goto fail3;
384 
385 	EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
386 
387 	if (vi_count < min_vi_count) {
388 		rc = ENOMEM;
389 		goto fail4;
390 	}
391 
392 	enp->en_arch.ef10.ena_vi_base = vi_base;
393 	enp->en_arch.ef10.ena_vi_count = vi_count;
394 	enp->en_arch.ef10.ena_vi_shift = vi_shift;
395 
396 	EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=,
397 	    EFX_VI_WINDOW_SHIFT_INVALID);
398 	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 	enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
404 	enp->en_arch.ef10.ena_uc_mem_map_size =
405 	    vi_window_size * enp->en_arch.ef10.ena_vi_count;
406 
407 	/* No WC memory mapping since PIO is not supported */
408 	enp->en_arch.ef10.ena_pio_write_vi_base = 0;
409 	enp->en_arch.ef10.ena_wc_mem_map_offset = 0;
410 	enp->en_arch.ef10.ena_wc_mem_map_size = 0;
411 
412 	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 	enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
422 #if EFSYS_OPT_EVB
423 	if ((enp->en_vswitchp != NULL) && (enp->en_vswitchp->ev_evcp != NULL)) {
424 		/* For EVB use vPort allocated on vSwitch */
425 		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 		if ((rc = ef10_upstream_port_vadaptor_alloc(enp)) != 0)
432 			goto fail5;
433 	}
434 
435 	return (0);
436 
437 fail5:
438 	EFSYS_PROBE(fail5);
439 
440 fail4:
441 	EFSYS_PROBE(fail4);
442 
443 	(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
rhead_nic_get_vi_pool(__in efx_nic_t * enp,__out uint32_t * vi_countp)456 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 	*vi_countp = enp->en_arch.ef10.ena_vi_count;
465 
466 	return (0);
467 }
468 
469 	__checkReturn	efx_rc_t
rhead_nic_get_bar_region(__in efx_nic_t * enp,__in efx_nic_region_t region,__out uint32_t * offsetp,__out size_t * sizep)470 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 	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 	switch (region) {
486 	case EFX_REGION_VI:
487 		/* UC mapped memory BAR region for VI registers */
488 		*offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
489 		*sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
490 		break;
491 
492 	case EFX_REGION_PIO_WRITE_VI:
493 		/* WC mapped memory BAR region for piobuf writes */
494 		*offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
495 		*sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
496 		break;
497 
498 	default:
499 		rc = EINVAL;
500 		goto fail1;
501 	}
502 
503 	return (0);
504 
505 fail1:
506 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
507 
508 	return (rc);
509 }
510 
511 	__checkReturn	boolean_t
rhead_nic_hw_unavailable(__in efx_nic_t * enp)512 rhead_nic_hw_unavailable(
513 	__in		efx_nic_t *enp)
514 {
515 	efx_dword_t dword;
516 
517 	if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
518 		return (B_TRUE);
519 
520 	EFX_BAR_FCW_READD(enp, ER_GZ_MC_SFT_STATUS, &dword);
521 	if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
522 		goto unavail;
523 
524 	return (B_FALSE);
525 
526 unavail:
527 	rhead_nic_set_hw_unavailable(enp);
528 
529 	return (B_TRUE);
530 }
531 
532 			void
rhead_nic_set_hw_unavailable(__in efx_nic_t * enp)533 rhead_nic_set_hw_unavailable(
534 	__in		efx_nic_t *enp)
535 {
536 	EFSYS_PROBE(hw_unavail);
537 	enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
538 }
539 
540 			void
rhead_nic_fini(__in efx_nic_t * enp)541 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 	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 		(void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
557 		enp->en_vport_id = EVB_PORT_ID_NULL;
558 	}
559 
560 	(void) efx_mcdi_free_vis(enp);
561 	enp->en_arch.ef10.ena_vi_count = 0;
562 }
563 
564 			void
rhead_nic_unprobe(__in efx_nic_t * enp)565 rhead_nic_unprobe(
566 	__in		efx_nic_t *enp)
567 {
568 	(void) efx_mcdi_drv_attach(enp, B_FALSE);
569 }
570 
571 #if EFSYS_OPT_DIAG
572 
573 	__checkReturn	efx_rc_t
rhead_nic_register_test(__in efx_nic_t * enp)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
rhead_nic_xilinx_cap_tbl_read_ef100_locator(__in efsys_bar_t * esbp,__in efsys_dma_addr_t offset,__out efx_bar_region_t * ebrp)599 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 	EFSYS_BAR_READD(esbp, offset +
614 			(EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_FORMAT) / 8),
615 			&entry.eo_dword[0], B_FALSE);
616 	EFSYS_BAR_READD(esbp, offset +
617 			(EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_SIZE) / 8),
618 			&entry.eo_dword[1], B_FALSE);
619 
620 	rev = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_REV);
621 	len = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_SIZE);
622 
623 	if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
624 	    len < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
625 		rc = EINVAL;
626 		goto fail1;
627 	}
628 
629 	EFSYS_BAR_READD(esbp, offset +
630 			(EFX_LOW_BIT(ESF_GZ_CFGBAR_EF100_BAR) / 8),
631 			&entry.eo_dword[2], B_FALSE);
632 
633 	ebrp->ebr_index = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_EF100_BAR);
634 	ebrp->ebr_offset = EFX_OWORD_FIELD32(entry,
635 			ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF) <<
636 			ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
637 	ebrp->ebr_type = EFX_BAR_TYPE_MEM;
638 	ebrp->ebr_length = 0;
639 
640 	return (0);
641 
642 fail1:
643 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
644 
645 	return (rc);
646 }
647 
648 #endif	/* EFSYS_OPT_RIVERHEAD */
649