common/sfc_efx/base: handle MCDI events on Riverhead
[dpdk.git] / drivers / common / sfc_efx / base / rhead_nic.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 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         encp->enc_clk_mult = 1; /* not used for Riverhead */
26
27         /*
28          * FIXME There are TxSend and TxSeg descriptors on Riverhead.
29          * TxSeg is bigger than TxSend.
30          */
31         encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_GZ_TX_SEND_LEN);
32         /* No boundary crossing limits */
33         encp->enc_tx_dma_desc_boundary = 0;
34
35         /*
36          * Maximum number of bytes into the frame the TCP header can start for
37          * firmware assisted TSO to work.
38          * FIXME Get from design parameter DP_TSO_MAX_HDR_LEN.
39          */
40         encp->enc_tx_tso_tcp_header_offset_limit = 0;
41
42         /*
43          * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
44          * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
45          * resources (allocated to this PCIe function), which is zero until
46          * after we have allocated VIs.
47          */
48         encp->enc_evq_limit = 1024;
49         encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
50         encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
51
52         encp->enc_buftbl_limit = UINT32_MAX;
53
54         /*
55          * Riverhead event queue creation completes
56          * immediately (no initial event).
57          */
58         encp->enc_evq_init_done_ev_supported = B_FALSE;
59
60         /*
61          * Enable firmware workarounds for hardware errata.
62          * Expected responses are:
63          *  - 0 (zero):
64          *      Success: workaround enabled or disabled as requested.
65          *  - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
66          *      Firmware does not support the MC_CMD_WORKAROUND request.
67          *      (assume that the workaround is not supported).
68          *  - MC_CMD_ERR_ENOENT (reported as ENOENT):
69          *      Firmware does not support the requested workaround.
70          *  - MC_CMD_ERR_EPERM  (reported as EACCES):
71          *      Unprivileged function cannot enable/disable workarounds.
72          *
73          * See efx_mcdi_request_errcode() for MCDI error translations.
74          */
75
76         /*
77          * Replay engine on Riverhead should suppress duplicate packets
78          * (e.g. because of exact multicast and all-multicast filters
79          * match) to the same RxQ.
80          */
81         encp->enc_bug26807_workaround = B_FALSE;
82
83         /*
84          * Checksums for TSO sends should always be correct on Riverhead.
85          * FIXME: revisit when TSO support is implemented.
86          */
87         encp->enc_bug61297_workaround = B_FALSE;
88
89         encp->enc_evq_max_nevs = RHEAD_EVQ_MAXNEVS;
90         encp->enc_evq_min_nevs = RHEAD_EVQ_MINNEVS;
91         encp->enc_rxq_max_ndescs = RHEAD_RXQ_MAXNDESCS;
92         encp->enc_rxq_min_ndescs = RHEAD_RXQ_MINNDESCS;
93         encp->enc_txq_max_ndescs = RHEAD_TXQ_MAXNDESCS;
94         encp->enc_txq_min_ndescs = RHEAD_TXQ_MINNDESCS;
95
96         /* Riverhead FW does not support event queue timers yet. */
97         encp->enc_evq_timer_quantum_ns = 0;
98         encp->enc_evq_timer_max_us = 0;
99
100         encp->enc_ev_desc_size = RHEAD_EVQ_DESC_SIZE;
101         encp->enc_rx_desc_size = RHEAD_RXQ_DESC_SIZE;
102         encp->enc_tx_desc_size = RHEAD_TXQ_DESC_SIZE;
103
104         /* No required alignment for WPTR updates */
105         encp->enc_rx_push_align = 1;
106
107         /* Riverhead supports a single Rx prefix size. */
108         encp->enc_rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN;
109
110         /* Alignment for receive packet DMA buffers. */
111         encp->enc_rx_buf_align_start = 1;
112
113         /* Get the RX DMA end padding alignment configuration. */
114         if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
115                 if (rc != EACCES)
116                         goto fail2;
117
118                 /* Assume largest tail padding size supported by hardware. */
119                 end_padding = 128;
120         }
121         encp->enc_rx_buf_align_end = end_padding;
122
123         /*
124          * Riverhead stores a single global copy of VPD, not per-PF as on
125          * Huntington.
126          */
127         encp->enc_vpd_is_global = B_TRUE;
128
129         rc = ef10_nic_get_port_mode_bandwidth(enp, &bandwidth);
130         if (rc != 0)
131                 goto fail3;
132         encp->enc_required_pcie_bandwidth_mbps = bandwidth;
133         encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3;
134
135         return (0);
136
137 fail3:
138         EFSYS_PROBE(fail3);
139 fail2:
140         EFSYS_PROBE(fail2);
141 fail1:
142         EFSYS_PROBE1(fail1, efx_rc_t, rc);
143
144         return (rc);
145 }
146
147         __checkReturn   efx_rc_t
148 rhead_nic_probe(
149         __in            efx_nic_t *enp)
150 {
151         const efx_nic_ops_t *enop = enp->en_enop;
152         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
153         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
154         efx_rc_t rc;
155
156         EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
157
158         /* Read and clear any assertion state */
159         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
160                 goto fail1;
161
162         /* Exit the assertion handler */
163         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
164                 if (rc != EACCES)
165                         goto fail2;
166
167         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
168                 goto fail3;
169
170         /* Get remaining controller-specific board config */
171         if ((rc = enop->eno_board_cfg(enp)) != 0)
172                 goto fail4;
173
174         /*
175          * Set default driver config limits (based on board config).
176          *
177          * FIXME: For now allocate a fixed number of VIs which is likely to be
178          * sufficient and small enough to allow multiple functions on the same
179          * port.
180          */
181         edcp->edc_min_vi_count = edcp->edc_max_vi_count =
182             MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
183
184         /*
185          * The client driver must configure and enable PIO buffer support,
186          * but there is no PIO support on Riverhead anyway.
187          */
188         edcp->edc_max_piobuf_count = 0;
189         edcp->edc_pio_alloc_size = 0;
190
191 #if EFSYS_OPT_MAC_STATS
192         /* Wipe the MAC statistics */
193         if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
194                 goto fail5;
195 #endif
196
197 #if EFSYS_OPT_LOOPBACK
198         if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
199                 goto fail6;
200 #endif
201
202         return (0);
203
204 #if EFSYS_OPT_LOOPBACK
205 fail6:
206         EFSYS_PROBE(fail6);
207 #endif
208 #if EFSYS_OPT_MAC_STATS
209 fail5:
210         EFSYS_PROBE(fail5);
211 #endif
212 fail4:
213         EFSYS_PROBE(fail4);
214 fail3:
215         EFSYS_PROBE(fail3);
216 fail2:
217         EFSYS_PROBE(fail2);
218 fail1:
219         EFSYS_PROBE1(fail1, efx_rc_t, rc);
220
221         return (rc);
222 }
223
224         __checkReturn   efx_rc_t
225 rhead_nic_set_drv_limits(
226         __inout         efx_nic_t *enp,
227         __in            efx_drv_limits_t *edlp)
228 {
229         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
230         efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
231         uint32_t min_evq_count, max_evq_count;
232         uint32_t min_rxq_count, max_rxq_count;
233         uint32_t min_txq_count, max_txq_count;
234         efx_rc_t rc;
235
236         if (edlp == NULL) {
237                 rc = EINVAL;
238                 goto fail1;
239         }
240
241         /* Get minimum required and maximum usable VI limits */
242         min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
243         min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
244         min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
245
246         edcp->edc_min_vi_count =
247             MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
248
249         max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
250         max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
251         max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
252
253         edcp->edc_max_vi_count =
254             MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
255
256         /* There is no PIO support on Riverhead */
257         edcp->edc_max_piobuf_count = 0;
258         edcp->edc_pio_alloc_size = 0;
259
260         return (0);
261
262 fail1:
263         EFSYS_PROBE1(fail1, efx_rc_t, rc);
264
265         return (rc);
266 }
267
268         __checkReturn   efx_rc_t
269 rhead_nic_reset(
270         __in            efx_nic_t *enp)
271 {
272         efx_rc_t rc;
273
274         /* ef10_nic_reset() is called to recover from BADASSERT failures. */
275         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
276                 goto fail1;
277         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
278                 goto fail2;
279
280         if ((rc = efx_mcdi_entity_reset(enp)) != 0)
281                 goto fail3;
282
283         /* Clear RX/TX DMA queue errors */
284         enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
285
286         return (0);
287
288 fail3:
289         EFSYS_PROBE(fail3);
290 fail2:
291         EFSYS_PROBE(fail2);
292 fail1:
293         EFSYS_PROBE1(fail1, efx_rc_t, rc);
294
295         return (rc);
296 }
297
298         __checkReturn   efx_rc_t
299 rhead_nic_init(
300         __in            efx_nic_t *enp)
301 {
302         const efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
303         uint32_t min_vi_count, max_vi_count;
304         uint32_t vi_count, vi_base, vi_shift;
305         uint32_t vi_window_size;
306         efx_rc_t rc;
307
308         EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
309         EFSYS_ASSERT3U(edcp->edc_max_piobuf_count, ==, 0);
310
311         /* Enable reporting of some events (e.g. link change) */
312         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
313                 goto fail1;
314
315         min_vi_count = edcp->edc_min_vi_count;
316         max_vi_count = edcp->edc_max_vi_count;
317
318         /* Ensure that the previously attached driver's VIs are freed */
319         if ((rc = efx_mcdi_free_vis(enp)) != 0)
320                 goto fail2;
321
322         /*
323          * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
324          * fails then retrying the request for fewer VI resources may succeed.
325          */
326         vi_count = 0;
327         if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
328                     &vi_base, &vi_count, &vi_shift)) != 0)
329                 goto fail3;
330
331         EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
332
333         if (vi_count < min_vi_count) {
334                 rc = ENOMEM;
335                 goto fail4;
336         }
337
338         enp->en_arch.ef10.ena_vi_base = vi_base;
339         enp->en_arch.ef10.ena_vi_count = vi_count;
340         enp->en_arch.ef10.ena_vi_shift = vi_shift;
341
342         EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=,
343             EFX_VI_WINDOW_SHIFT_INVALID);
344         EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=,
345             EFX_VI_WINDOW_SHIFT_64K);
346         vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift;
347
348         /* Save UC memory mapping details */
349         enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
350         enp->en_arch.ef10.ena_uc_mem_map_size =
351             vi_window_size * enp->en_arch.ef10.ena_vi_count;
352
353         /* No WC memory mapping since PIO is not supported */
354         enp->en_arch.ef10.ena_pio_write_vi_base = 0;
355         enp->en_arch.ef10.ena_wc_mem_map_offset = 0;
356         enp->en_arch.ef10.ena_wc_mem_map_size = 0;
357
358         enp->en_vport_id = EVB_PORT_ID_NULL;
359
360         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
361
362         return (0);
363
364 fail4:
365         EFSYS_PROBE(fail4);
366
367         (void) efx_mcdi_free_vis(enp);
368
369 fail3:
370         EFSYS_PROBE(fail3);
371 fail2:
372         EFSYS_PROBE(fail2);
373 fail1:
374         EFSYS_PROBE1(fail1, efx_rc_t, rc);
375
376         return (rc);
377 }
378
379         __checkReturn   efx_rc_t
380 rhead_nic_get_vi_pool(
381         __in            efx_nic_t *enp,
382         __out           uint32_t *vi_countp)
383 {
384         /*
385          * Report VIs that the client driver can use.
386          * Do not include VIs used for PIO buffer writes.
387          */
388         *vi_countp = enp->en_arch.ef10.ena_vi_count;
389
390         return (0);
391 }
392
393         __checkReturn   efx_rc_t
394 rhead_nic_get_bar_region(
395         __in            efx_nic_t *enp,
396         __in            efx_nic_region_t region,
397         __out           uint32_t *offsetp,
398         __out           size_t *sizep)
399 {
400         efx_rc_t rc;
401
402         EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
403
404         /*
405          * TODO: Specify host memory mapping alignment and granularity
406          * in efx_drv_limits_t so that they can be taken into account
407          * when allocating extra VIs for PIO writes.
408          */
409         switch (region) {
410         case EFX_REGION_VI:
411                 /* UC mapped memory BAR region for VI registers */
412                 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
413                 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
414                 break;
415
416         case EFX_REGION_PIO_WRITE_VI:
417                 /* WC mapped memory BAR region for piobuf writes */
418                 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
419                 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
420                 break;
421
422         default:
423                 rc = EINVAL;
424                 goto fail1;
425         }
426
427         return (0);
428
429 fail1:
430         EFSYS_PROBE1(fail1, efx_rc_t, rc);
431
432         return (rc);
433 }
434
435         __checkReturn   boolean_t
436 rhead_nic_hw_unavailable(
437         __in            efx_nic_t *enp)
438 {
439         efx_dword_t dword;
440
441         if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
442                 return (B_TRUE);
443
444         EFX_BAR_READD(enp, ER_GZ_MC_SFT_STATUS, &dword, B_FALSE);
445         if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
446                 goto unavail;
447
448         return (B_FALSE);
449
450 unavail:
451         rhead_nic_set_hw_unavailable(enp);
452
453         return (B_TRUE);
454 }
455
456                         void
457 rhead_nic_set_hw_unavailable(
458         __in            efx_nic_t *enp)
459 {
460         EFSYS_PROBE(hw_unavail);
461         enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
462 }
463
464                         void
465 rhead_nic_fini(
466         __in            efx_nic_t *enp)
467 {
468         (void) efx_mcdi_free_vis(enp);
469         enp->en_arch.ef10.ena_vi_count = 0;
470 }
471
472                         void
473 rhead_nic_unprobe(
474         __in            efx_nic_t *enp)
475 {
476         (void) efx_mcdi_drv_attach(enp, B_FALSE);
477 }
478
479 #if EFSYS_OPT_DIAG
480
481         __checkReturn   efx_rc_t
482 rhead_nic_register_test(
483         __in            efx_nic_t *enp)
484 {
485         efx_rc_t rc;
486
487         /* FIXME */
488         _NOTE(ARGUNUSED(enp))
489         _NOTE(CONSTANTCONDITION)
490         if (B_FALSE) {
491                 rc = ENOTSUP;
492                 goto fail1;
493         }
494         /* FIXME */
495
496         return (0);
497
498 fail1:
499         EFSYS_PROBE1(fail1, efx_rc_t, rc);
500
501         return (rc);
502 }
503
504 #endif  /* EFSYS_OPT_DIAG */
505
506 #endif  /* EFSYS_OPT_RIVERHEAD */