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