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