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