5bda315171b3948852dbc0616bf6f064b9da9383
[dpdk.git] / drivers / common / sfc_efx / base / rhead_ev.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 #if EFSYS_OPT_RIVERHEAD
11
12 /*
13  * Non-interrupting event queue requires interrupting event queue to
14  * refer to for wake-up events even if wake ups are never used.
15  * It could be even non-allocated event queue.
16  */
17 #define EFX_RHEAD_ALWAYS_INTERRUPTING_EVQ_INDEX (0)
18
19 static                  boolean_t
20 rhead_ev_dispatch(
21         __in            efx_evq_t *eep,
22         __in            efx_qword_t *eventp,
23         __in            const efx_ev_callbacks_t *eecp,
24         __in_opt        void *arg);
25
26 static  __checkReturn   boolean_t
27 rhead_ev_rx_packets(
28         __in            efx_evq_t *eep,
29         __in            efx_qword_t *eqp,
30         __in            const efx_ev_callbacks_t *eecp,
31         __in_opt        void *arg);
32
33 static  __checkReturn   boolean_t
34 rhead_ev_tx_completion(
35         __in            efx_evq_t *eep,
36         __in            efx_qword_t *eqp,
37         __in            const efx_ev_callbacks_t *eecp,
38         __in_opt        void *arg);
39
40 static  __checkReturn   boolean_t
41 rhead_ev_mcdi(
42         __in            efx_evq_t *eep,
43         __in            efx_qword_t *eqp,
44         __in            const efx_ev_callbacks_t *eecp,
45         __in_opt        void *arg);
46
47 #if EFSYS_OPT_EV_EXTENDED_WIDTH
48 static                  boolean_t
49 rhead_ev_ew_dispatch(
50         __in            efx_evq_t *eep,
51         __in            efx_xword_t *eventp,
52         __in            const efx_ev_callbacks_t *eecp,
53         __in_opt        void *arg);
54
55 static                  void
56 rhead_ev_ew_qpoll(
57         __in            efx_evq_t *eep,
58         __inout         unsigned int *countp,
59         __in            const efx_ev_callbacks_t *eecp,
60         __in_opt        void *arg);
61 #endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */
62
63
64         __checkReturn   efx_rc_t
65 rhead_ev_init(
66         __in            efx_nic_t *enp)
67 {
68         _NOTE(ARGUNUSED(enp))
69
70         return (0);
71 }
72
73                         void
74 rhead_ev_fini(
75         __in            efx_nic_t *enp)
76 {
77         _NOTE(ARGUNUSED(enp))
78 }
79
80         __checkReturn   efx_rc_t
81 rhead_ev_qcreate(
82         __in            efx_nic_t *enp,
83         __in            unsigned int index,
84         __in            efsys_mem_t *esmp,
85         __in            size_t ndescs,
86         __in            uint32_t id,
87         __in            uint32_t us,
88         __in            uint32_t flags,
89         __in            efx_evq_t *eep)
90 {
91         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
92         size_t desc_size;
93         uint32_t irq;
94         efx_rc_t rc;
95
96         _NOTE(ARGUNUSED(id))    /* buftbl id managed by MC */
97
98         desc_size = encp->enc_ev_desc_size;
99 #if EFSYS_OPT_EV_EXTENDED_WIDTH
100         if (flags & EFX_EVQ_FLAGS_EXTENDED_WIDTH)
101                 desc_size = encp->enc_ev_ew_desc_size;
102 #endif
103         EFSYS_ASSERT(desc_size != 0);
104
105         if (EFSYS_MEM_SIZE(esmp) < (ndescs * desc_size)) {
106                 /* Buffer too small for event queue descriptors */
107                 rc = EINVAL;
108                 goto fail1;
109         }
110
111         /* Set up the handler table */
112         eep->ee_rx      = rhead_ev_rx_packets;
113         eep->ee_tx      = rhead_ev_tx_completion;
114         eep->ee_driver  = NULL; /* FIXME */
115         eep->ee_drv_gen = NULL; /* FIXME */
116         eep->ee_mcdi    = rhead_ev_mcdi;
117
118         /* Set up the event queue */
119         /* INIT_EVQ expects function-relative vector number */
120         if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
121             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT) {
122                 irq = index;
123         } else if (index == EFX_RHEAD_ALWAYS_INTERRUPTING_EVQ_INDEX) {
124                 irq = index;
125                 flags = (flags & ~EFX_EVQ_FLAGS_NOTIFY_MASK) |
126                     EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
127         } else {
128                 irq = EFX_RHEAD_ALWAYS_INTERRUPTING_EVQ_INDEX;
129         }
130
131         /*
132          * Interrupts may be raised for events immediately after the queue is
133          * created. See bug58606.
134          */
135         rc = efx_mcdi_init_evq(enp, index, esmp, ndescs, irq, us, flags,
136             B_FALSE);
137         if (rc != 0)
138                 goto fail2;
139
140         return (0);
141
142 fail2:
143         EFSYS_PROBE(fail2);
144 fail1:
145         EFSYS_PROBE1(fail1, efx_rc_t, rc);
146
147         return (rc);
148 }
149
150                         void
151 rhead_ev_qdestroy(
152         __in            efx_evq_t *eep)
153 {
154         efx_nic_t *enp = eep->ee_enp;
155
156         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_RIVERHEAD);
157
158         (void) efx_mcdi_fini_evq(enp, eep->ee_index);
159 }
160
161         __checkReturn   efx_rc_t
162 rhead_ev_qprime(
163         __in            efx_evq_t *eep,
164         __in            unsigned int count)
165 {
166         efx_nic_t *enp = eep->ee_enp;
167         uint32_t rptr;
168         efx_dword_t dword;
169
170         rptr = count & eep->ee_mask;
171
172         EFX_POPULATE_DWORD_2(dword, ERF_GZ_EVQ_ID, eep->ee_index,
173             ERF_GZ_IDX, rptr);
174         /* EVQ_INT_PRIME lives function control window only on Riverhead */
175         EFX_BAR_FCW_WRITED(enp, ER_GZ_EVQ_INT_PRIME, &dword);
176
177         return (0);
178 }
179
180                         void
181 rhead_ev_qpost(
182         __in    efx_evq_t *eep,
183         __in    uint16_t data)
184 {
185         _NOTE(ARGUNUSED(eep, data))
186
187         /* Not implemented yet */
188         EFSYS_ASSERT(B_FALSE);
189 }
190
191 static  __checkReturn   boolean_t
192 rhead_ev_dispatch(
193         __in            efx_evq_t *eep,
194         __in            efx_qword_t *eventp,
195         __in            const efx_ev_callbacks_t *eecp,
196         __in_opt        void *arg)
197 {
198         boolean_t should_abort;
199         uint32_t code;
200
201         code = EFX_QWORD_FIELD(*eventp, ESF_GZ_E_TYPE);
202         switch (code) {
203         case ESE_GZ_EF100_EV_RX_PKTS:
204                 should_abort = eep->ee_rx(eep, eventp, eecp, arg);
205                 break;
206         case ESE_GZ_EF100_EV_TX_COMPLETION:
207                 should_abort = eep->ee_tx(eep, eventp, eecp, arg);
208                 break;
209         case ESE_GZ_EF100_EV_MCDI:
210                 should_abort = eep->ee_mcdi(eep, eventp, eecp, arg);
211                 break;
212         default:
213                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
214                     uint32_t, EFX_QWORD_FIELD(*eventp, EFX_DWORD_1),
215                     uint32_t, EFX_QWORD_FIELD(*eventp, EFX_DWORD_0));
216
217                 EFSYS_ASSERT(eecp->eec_exception != NULL);
218                 (void) eecp->eec_exception(arg, EFX_EXCEPTION_EV_ERROR, code);
219                 should_abort = B_TRUE;
220                 break;
221         }
222
223         return (should_abort);
224 }
225
226 /*
227  * Poll event queue in batches. Size of the batch is equal to cache line
228  * size divided by event size.
229  *
230  * Event queue is written by NIC and read by CPU. If CPU starts reading
231  * of events on the cache line, read all remaining events in a tight
232  * loop while event is present.
233  */
234 #define EF100_EV_BATCH  8
235
236 /*
237  * Check if event is present.
238  *
239  * Riverhead EvQs use a phase bit to indicate the presence of valid events,
240  * by flipping the phase bit on each wrap of the write index.
241  */
242 #define EF100_EV_PRESENT(_qword, _phase_bit)                            \
243         (EFX_QWORD_FIELD((_qword), ESF_GZ_EV_EVQ_PHASE) == _phase_bit)
244
245                         void
246 rhead_ev_qpoll(
247         __in            efx_evq_t *eep,
248         __inout         unsigned int *countp,
249         __in            const efx_ev_callbacks_t *eecp,
250         __in_opt        void *arg)
251 {
252         efx_qword_t ev[EF100_EV_BATCH];
253         unsigned int batch;
254         unsigned int phase_bit;
255         unsigned int total;
256         unsigned int count;
257         unsigned int index;
258         size_t offset;
259
260 #if EFSYS_OPT_EV_EXTENDED_WIDTH
261         if (eep->ee_flags & EFX_EVQ_FLAGS_EXTENDED_WIDTH) {
262                 rhead_ev_ew_qpoll(eep, countp, eecp, arg);
263                 return;
264         }
265 #endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */
266
267         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
268         EFSYS_ASSERT(countp != NULL);
269         EFSYS_ASSERT(eecp != NULL);
270
271         count = *countp;
272         do {
273                 /* Read up until the end of the batch period */
274                 batch = EF100_EV_BATCH - (count & (EF100_EV_BATCH - 1));
275                 phase_bit = (count & (eep->ee_mask + 1)) != 0;
276                 offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
277                 for (total = 0; total < batch; ++total) {
278                         EFSYS_MEM_READQ(eep->ee_esmp, offset, &(ev[total]));
279
280                         if (!EF100_EV_PRESENT(ev[total], phase_bit))
281                                 break;
282
283                         EFSYS_PROBE3(event, unsigned int, eep->ee_index,
284                             uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_1),
285                             uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_0));
286
287                         offset += sizeof (efx_qword_t);
288                 }
289
290                 /* Process the batch of events */
291                 for (index = 0; index < total; ++index) {
292                         boolean_t should_abort;
293
294                         EFX_EV_QSTAT_INCR(eep, EV_ALL);
295
296                         should_abort =
297                             rhead_ev_dispatch(eep, &(ev[index]), eecp, arg);
298
299                         if (should_abort) {
300                                 /* Ignore subsequent events */
301                                 total = index + 1;
302
303                                 /*
304                                  * Poison batch to ensure the outer
305                                  * loop is broken out of.
306                                  */
307                                 EFSYS_ASSERT(batch <= EF100_EV_BATCH);
308                                 batch += (EF100_EV_BATCH << 1);
309                                 EFSYS_ASSERT(total != batch);
310                                 break;
311                         }
312                 }
313
314                 /*
315                  * There is no necessity to clear processed events since
316                  * phase bit which is flipping on each write index wrap
317                  * is used for event presence indication.
318                  */
319
320                 count += total;
321
322         } while (total == batch);
323
324         *countp = count;
325 }
326
327 #if EFSYS_OPT_EV_EXTENDED_WIDTH
328 static                  boolean_t
329 rhead_ev_ew_dispatch(
330         __in            efx_evq_t *eep,
331         __in            efx_xword_t *eventp,
332         __in            const efx_ev_callbacks_t *eecp,
333         __in_opt        void *arg)
334 {
335         boolean_t should_abort;
336         uint32_t code;
337
338         EFSYS_ASSERT((eep->ee_flags & EFX_EVQ_FLAGS_EXTENDED_WIDTH) != 0);
339
340         code = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_256_EV32_TYPE);
341         switch (code) {
342         case ESE_GZ_EF100_EVEW_64BIT:
343                 /* NOTE: ignore phase bit in encapsulated 64bit event. */
344                 should_abort =
345                     rhead_ev_dispatch(eep, &eventp->ex_qword[0], eecp, arg);
346                 break;
347
348         default:
349                 /* Omit currently unused reserved bits from the probe. */
350                 EFSYS_PROBE7(ew_bad_event, unsigned int, eep->ee_index,
351                     uint32_t, EFX_XWORD_FIELD(*eventp, EFX_DWORD_7),
352                     uint32_t, EFX_XWORD_FIELD(*eventp, EFX_DWORD_4),
353                     uint32_t, EFX_XWORD_FIELD(*eventp, EFX_DWORD_3),
354                     uint32_t, EFX_XWORD_FIELD(*eventp, EFX_DWORD_2),
355                     uint32_t, EFX_XWORD_FIELD(*eventp, EFX_DWORD_1),
356                     uint32_t, EFX_XWORD_FIELD(*eventp, EFX_DWORD_0));
357
358                 EFSYS_ASSERT(eecp->eec_exception != NULL);
359                 (void) eecp->eec_exception(arg, EFX_EXCEPTION_EV_ERROR, code);
360                 should_abort = B_TRUE;
361         }
362
363         return (should_abort);
364 }
365
366 /*
367  * Poll extended width event queue. Size of the batch is equal to cache line
368  * size divided by event size.
369  */
370 #define EF100_EV_EW_BATCH       2
371
372 /*
373  * Check if event is present.
374  *
375  * Riverhead EvQs use a phase bit to indicate the presence of valid events,
376  * by flipping the phase bit on each wrap of the write index.
377  */
378 #define EF100_EV_EW_PRESENT(_xword, _phase_bit)                         \
379         (EFX_XWORD_FIELD((_xword), ESF_GZ_EV_256_EV32_PHASE) == (_phase_bit))
380
381 static                  void
382 rhead_ev_ew_qpoll(
383         __in            efx_evq_t *eep,
384         __inout         unsigned int *countp,
385         __in            const efx_ev_callbacks_t *eecp,
386         __in_opt        void *arg)
387 {
388         efx_xword_t ev[EF100_EV_EW_BATCH];
389         unsigned int batch;
390         unsigned int phase_bit;
391         unsigned int total;
392         unsigned int count;
393         unsigned int index;
394         size_t offset;
395
396         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
397         EFSYS_ASSERT((eep->ee_flags & EFX_EVQ_FLAGS_EXTENDED_WIDTH) != 0);
398         EFSYS_ASSERT(countp != NULL);
399         EFSYS_ASSERT(eecp != NULL);
400
401         count = *countp;
402         do {
403                 /* Read up until the end of the batch period */
404                 batch = EF100_EV_EW_BATCH - (count & (EF100_EV_EW_BATCH - 1));
405                 phase_bit = (count & (eep->ee_mask + 1)) != 0;
406                 offset = (count & eep->ee_mask) * sizeof (efx_xword_t);
407                 for (total = 0; total < batch; ++total) {
408                         EFSYS_MEM_READX(eep->ee_esmp, offset, &(ev[total]));
409
410                         if (!EF100_EV_EW_PRESENT(ev[total], phase_bit))
411                                 break;
412
413                         /* Omit unused reserved bits from the probe. */
414                         EFSYS_PROBE7(ew_event, unsigned int, eep->ee_index,
415                             uint32_t, EFX_XWORD_FIELD(ev[total], EFX_DWORD_7),
416                             uint32_t, EFX_XWORD_FIELD(ev[total], EFX_DWORD_4),
417                             uint32_t, EFX_XWORD_FIELD(ev[total], EFX_DWORD_3),
418                             uint32_t, EFX_XWORD_FIELD(ev[total], EFX_DWORD_2),
419                             uint32_t, EFX_XWORD_FIELD(ev[total], EFX_DWORD_1),
420                             uint32_t, EFX_XWORD_FIELD(ev[total], EFX_DWORD_0));
421
422                         offset += sizeof (efx_xword_t);
423                 }
424
425                 /* Process the batch of events */
426                 for (index = 0; index < total; ++index) {
427                         boolean_t should_abort;
428
429                         EFX_EV_QSTAT_INCR(eep, EV_ALL);
430
431                         should_abort =
432                             rhead_ev_ew_dispatch(eep, &(ev[index]), eecp, arg);
433
434                         if (should_abort) {
435                                 /* Ignore subsequent events */
436                                 total = index + 1;
437
438                                 /*
439                                  * Poison batch to ensure the outer
440                                  * loop is broken out of.
441                                  */
442                                 EFSYS_ASSERT(batch <= EF100_EV_EW_BATCH);
443                                 batch += (EF100_EV_EW_BATCH << 1);
444                                 EFSYS_ASSERT(total != batch);
445                                 break;
446                         }
447                 }
448
449                 /*
450                  * There is no necessity to clear processed events since
451                  * phase bit which is flipping on each write index wrap
452                  * is used for event presence indication.
453                  */
454
455                 count += total;
456
457         } while (total == batch);
458
459         *countp = count;
460 }
461 #endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */
462
463
464         __checkReturn   efx_rc_t
465 rhead_ev_qmoderate(
466         __in            efx_evq_t *eep,
467         __in            unsigned int us)
468 {
469         _NOTE(ARGUNUSED(eep, us))
470
471         return (ENOTSUP);
472 }
473
474
475 #if EFSYS_OPT_QSTATS
476                         void
477 rhead_ev_qstats_update(
478         __in                            efx_evq_t *eep,
479         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
480 {
481         unsigned int id;
482
483         for (id = 0; id < EV_NQSTATS; id++) {
484                 efsys_stat_t *essp = &stat[id];
485
486                 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
487                 eep->ee_stat[id] = 0;
488         }
489 }
490 #endif /* EFSYS_OPT_QSTATS */
491
492 static  __checkReturn   boolean_t
493 rhead_ev_rx_packets(
494         __in            efx_evq_t *eep,
495         __in            efx_qword_t *eqp,
496         __in            const efx_ev_callbacks_t *eecp,
497         __in_opt        void *arg)
498 {
499         efx_nic_t *enp = eep->ee_enp;
500         uint32_t label;
501         uint32_t num_packets;
502         boolean_t should_abort;
503
504         EFX_EV_QSTAT_INCR(eep, EV_RX);
505
506         /* Discard events after RXQ/TXQ errors, or hardware not available */
507         if (enp->en_reset_flags &
508             (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
509                 return (B_FALSE);
510
511         label = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_RXPKTS_Q_LABEL);
512
513         /*
514          * On EF100 the EV_RX event reports the number of received
515          * packets (unlike EF10 which reports a descriptor index).
516          * The client driver is responsible for maintaining the Rx
517          * descriptor index, and computing how many descriptors are
518          * occupied by each received packet (based on the Rx buffer size
519          * and the packet length from the Rx prefix).
520          */
521         num_packets = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_RXPKTS_NUM_PKT);
522
523         /*
524          * The receive event may indicate more than one packet, and so
525          * does not contain the packet length. Read the packet length
526          * from the prefix when handling each packet.
527          */
528         EFSYS_ASSERT(eecp->eec_rx_packets != NULL);
529         should_abort = eecp->eec_rx_packets(arg, label, num_packets,
530             EFX_PKT_PREFIX_LEN);
531
532         return (should_abort);
533 }
534
535 static  __checkReturn   boolean_t
536 rhead_ev_tx_completion(
537         __in            efx_evq_t *eep,
538         __in            efx_qword_t *eqp,
539         __in            const efx_ev_callbacks_t *eecp,
540         __in_opt        void *arg)
541 {
542         efx_nic_t *enp = eep->ee_enp;
543         uint32_t num_descs;
544         uint32_t label;
545         boolean_t should_abort;
546
547         EFX_EV_QSTAT_INCR(eep, EV_TX);
548
549         /* Discard events after RXQ/TXQ errors, or hardware not available */
550         if (enp->en_reset_flags &
551             (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
552                 return (B_FALSE);
553
554         label = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_TXCMPL_Q_LABEL);
555
556         /*
557          * On EF100 the EV_TX event reports the number of completed Tx
558          * descriptors (on EF10, the event reports the low bits of the
559          * index of the last completed descriptor).
560          * The client driver completion callback will compute the
561          * descriptor index, so that is not needed here.
562          */
563         num_descs = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_TXCMPL_NUM_DESC);
564
565         EFSYS_PROBE2(tx_ndescs, uint32_t, label, unsigned int, num_descs);
566
567         EFSYS_ASSERT(eecp->eec_tx_ndescs != NULL);
568         should_abort = eecp->eec_tx_ndescs(arg, label, num_descs);
569
570         return (should_abort);
571 }
572
573 static  __checkReturn   boolean_t
574 rhead_ev_mcdi(
575         __in            efx_evq_t *eep,
576         __in            efx_qword_t *eqp,
577         __in            const efx_ev_callbacks_t *eecp,
578         __in_opt        void *arg)
579 {
580         boolean_t ret;
581
582         /*
583          * Event format was changed post Riverhead R1 and now
584          * MCDI event layout on EF100 is exactly the same as on EF10
585          * except added QDMA phase bit which is unused on EF10.
586          */
587         ret = ef10_ev_mcdi(eep, eqp, eecp, arg);
588
589         return (ret);
590 }
591
592 #endif  /* EFSYS_OPT_RIVERHEAD */