1
2
3
4
5
6
7#include "efx.h"
8#include "efx_impl.h"
9
10
11#if EFSYS_OPT_RIVERHEAD
12
13 __checkReturn efx_rc_t
14rhead_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
27
28
29 encp->enc_tunnel_encapsulations_supported =
30 (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
31 (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
32
33
34
35
36
37
38
39 encp->enc_tunnel_config_udp_entries_max = EFX_TUNNEL_MAXNENTRIES;
40
41 encp->enc_clk_mult = 1;
42
43
44
45
46
47 encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_GZ_TX_SEND_LEN);
48
49 encp->enc_tx_dma_desc_boundary = 0;
50
51
52
53
54
55
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
70
71 encp->enc_tx_tso_tcp_header_offset_limit = UINT32_MAX;
72
73
74
75
76
77
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
87
88
89 encp->enc_evq_init_done_ev_supported = B_FALSE;
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 encp->enc_bug26807_workaround = B_FALSE;
113
114
115
116
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
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
142 encp->enc_rx_push_align = 1;
143
144
145 encp->enc_rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN;
146
147
148 encp->enc_rx_buf_align_start = 1;
149
150
151 if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
152 if (rc != EACCES)
153 goto fail2;
154
155
156 end_padding = 128;
157 }
158 encp->enc_rx_buf_align_end = end_padding;
159
160
161 encp->enc_rx_scatter_max = 7;
162
163
164
165
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
177fail3:
178 EFSYS_PROBE(fail3);
179fail2:
180 EFSYS_PROBE(fail2);
181fail1:
182 EFSYS_PROBE1(fail1, efx_rc_t, rc);
183
184 return (rc);
185}
186
187 __checkReturn efx_rc_t
188rhead_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
199 if ((rc = efx_mcdi_read_assertion(enp)) != 0)
200 goto fail1;
201
202
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
211 if ((rc = enop->eno_board_cfg(enp)) != 0)
212 goto fail4;
213
214
215
216
217
218
219
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
226
227
228 edcp->edc_max_piobuf_count = 0;
229 edcp->edc_pio_alloc_size = 0;
230
231#if EFSYS_OPT_MAC_STATS
232
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
245fail6:
246 EFSYS_PROBE(fail6);
247#endif
248#if EFSYS_OPT_MAC_STATS
249fail5:
250 EFSYS_PROBE(fail5);
251#endif
252fail4:
253 EFSYS_PROBE(fail4);
254fail3:
255 EFSYS_PROBE(fail3);
256fail2:
257 EFSYS_PROBE(fail2);
258fail1:
259 EFSYS_PROBE1(fail1, efx_rc_t, rc);
260
261 return (rc);
262}
263
264 __checkReturn efx_rc_t
265rhead_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
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
297 edcp->edc_max_piobuf_count = 0;
298 edcp->edc_pio_alloc_size = 0;
299
300 return (0);
301
302fail1:
303 EFSYS_PROBE1(fail1, efx_rc_t, rc);
304
305 return (rc);
306}
307
308 __checkReturn efx_rc_t
309rhead_nic_reset(
310 __in efx_nic_t *enp)
311{
312 efx_rc_t rc;
313
314
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
324 enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
325
326 return (0);
327
328fail3:
329 EFSYS_PROBE(fail3);
330fail2:
331 EFSYS_PROBE(fail2);
332fail1:
333 EFSYS_PROBE1(fail1, efx_rc_t, rc);
334
335 return (rc);
336}
337
338 __checkReturn efx_rc_t
339rhead_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
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
360 if ((rc = efx_mcdi_free_vis(enp)) != 0)
361 goto fail2;
362
363
364
365
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
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
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
403
404
405
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
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
418 if ((rc = ef10_upstream_port_vadaptor_alloc(enp)) != 0)
419 goto fail5;
420 }
421
422 return (0);
423
424fail5:
425 EFSYS_PROBE(fail5);
426
427fail4:
428 EFSYS_PROBE(fail4);
429
430 (void) efx_mcdi_free_vis(enp);
431
432fail3:
433 EFSYS_PROBE(fail3);
434fail2:
435 EFSYS_PROBE(fail2);
436fail1:
437 EFSYS_PROBE1(fail1, efx_rc_t, rc);
438
439 return (rc);
440}
441
442 __checkReturn efx_rc_t
443rhead_nic_get_vi_pool(
444 __in efx_nic_t *enp,
445 __out uint32_t *vi_countp)
446{
447
448
449
450
451 *vi_countp = enp->en_arch.ef10.ena_vi_count;
452
453 return (0);
454}
455
456 __checkReturn efx_rc_t
457rhead_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
469
470
471
472 switch (region) {
473 case EFX_REGION_VI:
474
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
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
492fail1:
493 EFSYS_PROBE1(fail1, efx_rc_t, rc);
494
495 return (rc);
496}
497
498 __checkReturn boolean_t
499rhead_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
513unavail:
514 rhead_nic_set_hw_unavailable(enp);
515
516 return (B_TRUE);
517}
518
519 void
520rhead_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
528rhead_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
537
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
552rhead_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
561rhead_nic_register_test(
562 __in efx_nic_t *enp)
563{
564 efx_rc_t rc;
565
566
567 _NOTE(ARGUNUSED(enp))
568 _NOTE(CONSTANTCONDITION)
569 if (B_FALSE) {
570 rc = ENOTSUP;
571 goto fail1;
572 }
573
574
575 return (0);
576
577fail1:
578 EFSYS_PROBE1(fail1, efx_rc_t, rc);
579
580 return (rc);
581}
582
583#endif
584
585 __checkReturn efx_rc_t
586rhead_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
598
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
629fail1:
630 EFSYS_PROBE1(fail1, efx_rc_t, rc);
631
632 return (rc);
633}
634
635#endif
636