common/sfc_efx/base: add efsys option for Riverhead
[dpdk.git] / drivers / common / sfc_efx / base / efx_ev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2007-2019 Solarflare Communications Inc.
5  */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9 #if EFSYS_OPT_MON_MCDI
10 #include "mcdi_mon.h"
11 #endif
12
13 #define EFX_EV_PRESENT(_qword)                                          \
14         (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff &&        \
15         EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
16
17
18
19 #if EFSYS_OPT_SIENA
20
21 static  __checkReturn   efx_rc_t
22 siena_ev_init(
23         __in            efx_nic_t *enp);
24
25 static                  void
26 siena_ev_fini(
27         __in            efx_nic_t *enp);
28
29 static  __checkReturn   efx_rc_t
30 siena_ev_qcreate(
31         __in            efx_nic_t *enp,
32         __in            unsigned int index,
33         __in            efsys_mem_t *esmp,
34         __in            size_t ndescs,
35         __in            uint32_t id,
36         __in            uint32_t us,
37         __in            uint32_t flags,
38         __in            efx_evq_t *eep);
39
40 static                  void
41 siena_ev_qdestroy(
42         __in            efx_evq_t *eep);
43
44 static  __checkReturn   efx_rc_t
45 siena_ev_qprime(
46         __in            efx_evq_t *eep,
47         __in            unsigned int count);
48
49 static                  void
50 siena_ev_qpost(
51         __in    efx_evq_t *eep,
52         __in    uint16_t data);
53
54 static  __checkReturn   efx_rc_t
55 siena_ev_qmoderate(
56         __in            efx_evq_t *eep,
57         __in            unsigned int us);
58
59 #if EFSYS_OPT_QSTATS
60 static                  void
61 siena_ev_qstats_update(
62         __in                            efx_evq_t *eep,
63         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat);
64
65 #endif
66
67 #endif /* EFSYS_OPT_SIENA */
68
69 #if EFX_OPTS_EF10() || EFSYS_OPT_SIENA
70
71 static                  void
72 siena_ef10_ev_qpoll(
73         __in            efx_evq_t *eep,
74         __inout         unsigned int *countp,
75         __in            const efx_ev_callbacks_t *eecp,
76         __in_opt        void *arg);
77
78 #endif  /* EFX_OPTS_EF10() || EFSYS_OPT_SIENA */
79
80 #if EFSYS_OPT_SIENA
81 static const efx_ev_ops_t       __efx_ev_siena_ops = {
82         siena_ev_init,                          /* eevo_init */
83         siena_ev_fini,                          /* eevo_fini */
84         siena_ev_qcreate,                       /* eevo_qcreate */
85         siena_ev_qdestroy,                      /* eevo_qdestroy */
86         siena_ev_qprime,                        /* eevo_qprime */
87         siena_ev_qpost,                         /* eevo_qpost */
88         siena_ef10_ev_qpoll,                    /* eevo_qpoll */
89         siena_ev_qmoderate,                     /* eevo_qmoderate */
90 #if EFSYS_OPT_QSTATS
91         siena_ev_qstats_update,                 /* eevo_qstats_update */
92 #endif
93 };
94 #endif /* EFSYS_OPT_SIENA */
95
96 #if EFX_OPTS_EF10()
97 static const efx_ev_ops_t       __efx_ev_ef10_ops = {
98         ef10_ev_init,                           /* eevo_init */
99         ef10_ev_fini,                           /* eevo_fini */
100         ef10_ev_qcreate,                        /* eevo_qcreate */
101         ef10_ev_qdestroy,                       /* eevo_qdestroy */
102         ef10_ev_qprime,                         /* eevo_qprime */
103         ef10_ev_qpost,                          /* eevo_qpost */
104         siena_ef10_ev_qpoll,                    /* eevo_qpoll */
105         ef10_ev_qmoderate,                      /* eevo_qmoderate */
106 #if EFSYS_OPT_QSTATS
107         ef10_ev_qstats_update,                  /* eevo_qstats_update */
108 #endif
109 };
110 #endif /* EFX_OPTS_EF10() */
111
112
113         __checkReturn   efx_rc_t
114 efx_ev_init(
115         __in            efx_nic_t *enp)
116 {
117         const efx_ev_ops_t *eevop;
118         efx_rc_t rc;
119
120         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
121         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
122
123         if (enp->en_mod_flags & EFX_MOD_EV) {
124                 rc = EINVAL;
125                 goto fail1;
126         }
127
128         switch (enp->en_family) {
129 #if EFSYS_OPT_SIENA
130         case EFX_FAMILY_SIENA:
131                 eevop = &__efx_ev_siena_ops;
132                 break;
133 #endif /* EFSYS_OPT_SIENA */
134
135 #if EFSYS_OPT_HUNTINGTON
136         case EFX_FAMILY_HUNTINGTON:
137                 eevop = &__efx_ev_ef10_ops;
138                 break;
139 #endif /* EFSYS_OPT_HUNTINGTON */
140
141 #if EFSYS_OPT_MEDFORD
142         case EFX_FAMILY_MEDFORD:
143                 eevop = &__efx_ev_ef10_ops;
144                 break;
145 #endif /* EFSYS_OPT_MEDFORD */
146
147 #if EFSYS_OPT_MEDFORD2
148         case EFX_FAMILY_MEDFORD2:
149                 eevop = &__efx_ev_ef10_ops;
150                 break;
151 #endif /* EFSYS_OPT_MEDFORD2 */
152
153         default:
154                 EFSYS_ASSERT(0);
155                 rc = ENOTSUP;
156                 goto fail1;
157         }
158
159         EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
160
161         if ((rc = eevop->eevo_init(enp)) != 0)
162                 goto fail2;
163
164         enp->en_eevop = eevop;
165         enp->en_mod_flags |= EFX_MOD_EV;
166         return (0);
167
168 fail2:
169         EFSYS_PROBE(fail2);
170
171 fail1:
172         EFSYS_PROBE1(fail1, efx_rc_t, rc);
173
174         enp->en_eevop = NULL;
175         enp->en_mod_flags &= ~EFX_MOD_EV;
176         return (rc);
177 }
178
179         __checkReturn   size_t
180 efx_evq_size(
181         __in    const efx_nic_t *enp,
182         __in    unsigned int ndescs)
183 {
184         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
185
186         return (ndescs * encp->enc_ev_desc_size);
187 }
188
189         __checkReturn   unsigned int
190 efx_evq_nbufs(
191         __in    const efx_nic_t *enp,
192         __in    unsigned int ndescs)
193 {
194         return (EFX_DIV_ROUND_UP(efx_evq_size(enp, ndescs), EFX_BUF_SIZE));
195 }
196
197                 void
198 efx_ev_fini(
199         __in    efx_nic_t *enp)
200 {
201         const efx_ev_ops_t *eevop = enp->en_eevop;
202
203         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
204         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
205         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
206         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
207         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
208         EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
209
210         eevop->eevo_fini(enp);
211
212         enp->en_eevop = NULL;
213         enp->en_mod_flags &= ~EFX_MOD_EV;
214 }
215
216
217         __checkReturn   efx_rc_t
218 efx_ev_qcreate(
219         __in            efx_nic_t *enp,
220         __in            unsigned int index,
221         __in            efsys_mem_t *esmp,
222         __in            size_t ndescs,
223         __in            uint32_t id,
224         __in            uint32_t us,
225         __in            uint32_t flags,
226         __deref_out     efx_evq_t **eepp)
227 {
228         const efx_ev_ops_t *eevop = enp->en_eevop;
229         efx_evq_t *eep;
230         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
231         efx_rc_t rc;
232
233         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
234         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
235
236         EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <,
237             enp->en_nic_cfg.enc_evq_limit);
238
239         switch (flags & EFX_EVQ_FLAGS_NOTIFY_MASK) {
240         case EFX_EVQ_FLAGS_NOTIFY_INTERRUPT:
241                 break;
242         case EFX_EVQ_FLAGS_NOTIFY_DISABLED:
243                 if (us != 0) {
244                         rc = EINVAL;
245                         goto fail1;
246                 }
247                 break;
248         default:
249                 rc = EINVAL;
250                 goto fail2;
251         }
252
253         EFSYS_ASSERT(ISP2(encp->enc_evq_max_nevs));
254         EFSYS_ASSERT(ISP2(encp->enc_evq_min_nevs));
255
256         if (!ISP2(ndescs) ||
257             ndescs < encp->enc_evq_min_nevs ||
258             ndescs > encp->enc_evq_max_nevs) {
259                 rc = EINVAL;
260                 goto fail3;
261         }
262
263         /* Allocate an EVQ object */
264         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
265         if (eep == NULL) {
266                 rc = ENOMEM;
267                 goto fail4;
268         }
269
270         eep->ee_magic = EFX_EVQ_MAGIC;
271         eep->ee_enp = enp;
272         eep->ee_index = index;
273         eep->ee_mask = ndescs - 1;
274         eep->ee_flags = flags;
275         eep->ee_esmp = esmp;
276
277         /*
278          * Set outputs before the queue is created because interrupts may be
279          * raised for events immediately after the queue is created, before the
280          * function call below returns. See bug58606.
281          *
282          * The eepp pointer passed in by the client must therefore point to data
283          * shared with the client's event processing context.
284          */
285         enp->en_ev_qcount++;
286         *eepp = eep;
287
288         if ((rc = eevop->eevo_qcreate(enp, index, esmp, ndescs, id, us, flags,
289             eep)) != 0)
290                 goto fail5;
291
292         return (0);
293
294 fail5:
295         EFSYS_PROBE(fail5);
296
297         *eepp = NULL;
298         enp->en_ev_qcount--;
299         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
300 fail4:
301         EFSYS_PROBE(fail4);
302 fail3:
303         EFSYS_PROBE(fail3);
304 fail2:
305         EFSYS_PROBE(fail2);
306 fail1:
307         EFSYS_PROBE1(fail1, efx_rc_t, rc);
308         return (rc);
309 }
310
311                 void
312 efx_ev_qdestroy(
313         __in    efx_evq_t *eep)
314 {
315         efx_nic_t *enp = eep->ee_enp;
316         const efx_ev_ops_t *eevop = enp->en_eevop;
317
318         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
319
320         EFSYS_ASSERT(enp->en_ev_qcount != 0);
321         --enp->en_ev_qcount;
322
323         eevop->eevo_qdestroy(eep);
324
325         /* Free the EVQ object */
326         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
327 }
328
329         __checkReturn   efx_rc_t
330 efx_ev_qprime(
331         __in            efx_evq_t *eep,
332         __in            unsigned int count)
333 {
334         efx_nic_t *enp = eep->ee_enp;
335         const efx_ev_ops_t *eevop = enp->en_eevop;
336         efx_rc_t rc;
337
338         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
339
340         if (!(enp->en_mod_flags & EFX_MOD_INTR)) {
341                 rc = EINVAL;
342                 goto fail1;
343         }
344
345         if ((rc = eevop->eevo_qprime(eep, count)) != 0)
346                 goto fail2;
347
348         return (0);
349
350 fail2:
351         EFSYS_PROBE(fail2);
352 fail1:
353         EFSYS_PROBE1(fail1, efx_rc_t, rc);
354         return (rc);
355 }
356
357         __checkReturn   boolean_t
358 efx_ev_qpending(
359         __in            efx_evq_t *eep,
360         __in            unsigned int count)
361 {
362         size_t offset;
363         efx_qword_t qword;
364
365         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
366
367         offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
368         EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword);
369
370         return (EFX_EV_PRESENT(qword));
371 }
372
373 #if EFSYS_OPT_EV_PREFETCH
374
375                         void
376 efx_ev_qprefetch(
377         __in            efx_evq_t *eep,
378         __in            unsigned int count)
379 {
380         unsigned int offset;
381
382         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
383
384         offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
385         EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
386 }
387
388 #endif  /* EFSYS_OPT_EV_PREFETCH */
389
390                         void
391 efx_ev_qpoll(
392         __in            efx_evq_t *eep,
393         __inout         unsigned int *countp,
394         __in            const efx_ev_callbacks_t *eecp,
395         __in_opt        void *arg)
396 {
397         efx_nic_t *enp = eep->ee_enp;
398         const efx_ev_ops_t *eevop = enp->en_eevop;
399
400         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
401
402         EFSYS_ASSERT(eevop != NULL &&
403             eevop->eevo_qpoll != NULL);
404
405         eevop->eevo_qpoll(eep, countp, eecp, arg);
406 }
407
408                         void
409 efx_ev_qpost(
410         __in    efx_evq_t *eep,
411         __in    uint16_t data)
412 {
413         efx_nic_t *enp = eep->ee_enp;
414         const efx_ev_ops_t *eevop = enp->en_eevop;
415
416         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
417
418         EFSYS_ASSERT(eevop != NULL &&
419             eevop->eevo_qpost != NULL);
420
421         eevop->eevo_qpost(eep, data);
422 }
423
424         __checkReturn   efx_rc_t
425 efx_ev_usecs_to_ticks(
426         __in            efx_nic_t *enp,
427         __in            unsigned int us,
428         __out           unsigned int *ticksp)
429 {
430         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
431         unsigned int ticks;
432         efx_rc_t rc;
433
434         if (encp->enc_evq_timer_quantum_ns == 0) {
435                 rc = ENOTSUP;
436                 goto fail1;
437         }
438
439         /* Convert microseconds to a timer tick count */
440         if (us == 0)
441                 ticks = 0;
442         else if (us * 1000 < encp->enc_evq_timer_quantum_ns)
443                 ticks = 1;      /* Never round down to zero */
444         else
445                 ticks = us * 1000 / encp->enc_evq_timer_quantum_ns;
446
447         *ticksp = ticks;
448         return (0);
449
450 fail1:
451         EFSYS_PROBE1(fail1, efx_rc_t, rc);
452         return (rc);
453 }
454
455         __checkReturn   efx_rc_t
456 efx_ev_qmoderate(
457         __in            efx_evq_t *eep,
458         __in            unsigned int us)
459 {
460         efx_nic_t *enp = eep->ee_enp;
461         const efx_ev_ops_t *eevop = enp->en_eevop;
462         efx_rc_t rc;
463
464         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
465
466         if ((eep->ee_flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
467             EFX_EVQ_FLAGS_NOTIFY_DISABLED) {
468                 rc = EINVAL;
469                 goto fail1;
470         }
471
472         if ((rc = eevop->eevo_qmoderate(eep, us)) != 0)
473                 goto fail2;
474
475         return (0);
476
477 fail2:
478         EFSYS_PROBE(fail2);
479 fail1:
480         EFSYS_PROBE1(fail1, efx_rc_t, rc);
481         return (rc);
482 }
483
484 #if EFSYS_OPT_QSTATS
485                                         void
486 efx_ev_qstats_update(
487         __in                            efx_evq_t *eep,
488         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
489
490 {       efx_nic_t *enp = eep->ee_enp;
491         const efx_ev_ops_t *eevop = enp->en_eevop;
492
493         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
494
495         eevop->eevo_qstats_update(eep, stat);
496 }
497
498 #endif  /* EFSYS_OPT_QSTATS */
499
500 #if EFSYS_OPT_SIENA
501
502 static  __checkReturn   efx_rc_t
503 siena_ev_init(
504         __in            efx_nic_t *enp)
505 {
506         efx_oword_t oword;
507
508         /*
509          * Program the event queue for receive and transmit queue
510          * flush events.
511          */
512         EFX_BAR_READO(enp, FR_AZ_DP_CTRL_REG, &oword);
513         EFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0);
514         EFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword);
515
516         return (0);
517
518 }
519
520 static  __checkReturn   boolean_t
521 siena_ev_rx_not_ok(
522         __in            efx_evq_t *eep,
523         __in            efx_qword_t *eqp,
524         __in            uint32_t label,
525         __in            uint32_t id,
526         __inout         uint16_t *flagsp)
527 {
528         boolean_t ignore = B_FALSE;
529
530         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TOBE_DISC) != 0) {
531                 EFX_EV_QSTAT_INCR(eep, EV_RX_TOBE_DISC);
532                 EFSYS_PROBE(tobe_disc);
533                 /*
534                  * Assume this is a unicast address mismatch, unless below
535                  * we find either FSF_AZ_RX_EV_ETH_CRC_ERR or
536                  * EV_RX_PAUSE_FRM_ERR is set.
537                  */
538                 (*flagsp) |= EFX_ADDR_MISMATCH;
539         }
540
541         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_FRM_TRUNC) != 0) {
542                 EFSYS_PROBE2(frm_trunc, uint32_t, label, uint32_t, id);
543                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
544                 (*flagsp) |= EFX_DISCARD;
545
546 #if EFSYS_OPT_RX_SCATTER
547                 /*
548                  * Lookout for payload queue ran dry errors and ignore them.
549                  *
550                  * Sadly for the header/data split cases, the descriptor
551                  * pointer in this event refers to the header queue and
552                  * therefore cannot be easily detected as duplicate.
553                  * So we drop these and rely on the receive processing seeing
554                  * a subsequent packet with FSF_AZ_RX_EV_SOP set to discard
555                  * the partially received packet.
556                  */
557                 if ((EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_SOP) == 0) &&
558                     (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_JUMBO_CONT) == 0) &&
559                     (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT) == 0))
560                         ignore = B_TRUE;
561 #endif  /* EFSYS_OPT_RX_SCATTER */
562         }
563
564         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_ETH_CRC_ERR) != 0) {
565                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
566                 EFSYS_PROBE(crc_err);
567                 (*flagsp) &= ~EFX_ADDR_MISMATCH;
568                 (*flagsp) |= EFX_DISCARD;
569         }
570
571         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PAUSE_FRM_ERR) != 0) {
572                 EFX_EV_QSTAT_INCR(eep, EV_RX_PAUSE_FRM_ERR);
573                 EFSYS_PROBE(pause_frm_err);
574                 (*flagsp) &= ~EFX_ADDR_MISMATCH;
575                 (*flagsp) |= EFX_DISCARD;
576         }
577
578         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR) != 0) {
579                 EFX_EV_QSTAT_INCR(eep, EV_RX_BUF_OWNER_ID_ERR);
580                 EFSYS_PROBE(owner_id_err);
581                 (*flagsp) |= EFX_DISCARD;
582         }
583
584         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR) != 0) {
585                 EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
586                 EFSYS_PROBE(ipv4_err);
587                 (*flagsp) &= ~EFX_CKSUM_IPV4;
588         }
589
590         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR) != 0) {
591                 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
592                 EFSYS_PROBE(udp_chk_err);
593                 (*flagsp) &= ~EFX_CKSUM_TCPUDP;
594         }
595
596         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_FRAG_ERR) != 0) {
597                 EFX_EV_QSTAT_INCR(eep, EV_RX_IP_FRAG_ERR);
598
599                 /*
600                  * If IP is fragmented FSF_AZ_RX_EV_IP_FRAG_ERR is set. This
601                  * causes FSF_AZ_RX_EV_PKT_OK to be clear. This is not an error
602                  * condition.
603                  */
604                 (*flagsp) &= ~(EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP);
605         }
606
607         return (ignore);
608 }
609
610 static  __checkReturn   boolean_t
611 siena_ev_rx(
612         __in            efx_evq_t *eep,
613         __in            efx_qword_t *eqp,
614         __in            const efx_ev_callbacks_t *eecp,
615         __in_opt        void *arg)
616 {
617         uint32_t id;
618         uint32_t size;
619         uint32_t label;
620         boolean_t ok;
621 #if EFSYS_OPT_RX_SCATTER
622         boolean_t sop;
623         boolean_t jumbo_cont;
624 #endif  /* EFSYS_OPT_RX_SCATTER */
625         uint32_t hdr_type;
626         boolean_t is_v6;
627         uint16_t flags;
628         boolean_t ignore;
629         boolean_t should_abort;
630
631         EFX_EV_QSTAT_INCR(eep, EV_RX);
632
633         /* Basic packet information */
634         id = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_DESC_PTR);
635         size = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT);
636         label = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_Q_LABEL);
637         ok = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_OK) != 0);
638
639 #if EFSYS_OPT_RX_SCATTER
640         sop = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_SOP) != 0);
641         jumbo_cont = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_JUMBO_CONT) != 0);
642 #endif  /* EFSYS_OPT_RX_SCATTER */
643
644         hdr_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_HDR_TYPE);
645
646         is_v6 = (EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_IPV6_PKT) != 0);
647
648         /*
649          * If packet is marked as OK and packet type is TCP/IP or
650          * UDP/IP or other IP, then we can rely on the hardware checksums.
651          */
652         switch (hdr_type) {
653         case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_TCP:
654                 flags = EFX_PKT_TCP | EFX_CKSUM_TCPUDP;
655                 if (is_v6) {
656                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
657                         flags |= EFX_PKT_IPV6;
658                 } else {
659                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
660                         flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4;
661                 }
662                 break;
663
664         case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_UDP:
665                 flags = EFX_PKT_UDP | EFX_CKSUM_TCPUDP;
666                 if (is_v6) {
667                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
668                         flags |= EFX_PKT_IPV6;
669                 } else {
670                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
671                         flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4;
672                 }
673                 break;
674
675         case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_OTHER:
676                 if (is_v6) {
677                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);
678                         flags = EFX_PKT_IPV6;
679                 } else {
680                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);
681                         flags = EFX_PKT_IPV4 | EFX_CKSUM_IPV4;
682                 }
683                 break;
684
685         case FSE_AZ_RX_EV_HDR_TYPE_OTHER:
686                 EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);
687                 flags = 0;
688                 break;
689
690         default:
691                 EFSYS_ASSERT(B_FALSE);
692                 flags = 0;
693                 break;
694         }
695
696 #if EFSYS_OPT_RX_SCATTER
697         /* Report scatter and header/lookahead split buffer flags */
698         if (sop)
699                 flags |= EFX_PKT_START;
700         if (jumbo_cont)
701                 flags |= EFX_PKT_CONT;
702 #endif  /* EFSYS_OPT_RX_SCATTER */
703
704         /* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */
705         if (!ok) {
706                 ignore = siena_ev_rx_not_ok(eep, eqp, label, id, &flags);
707                 if (ignore) {
708                         EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,
709                             uint32_t, size, uint16_t, flags);
710
711                         return (B_FALSE);
712                 }
713         }
714
715         /* If we're not discarding the packet then it is ok */
716         if (~flags & EFX_DISCARD)
717                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
718
719         /* Detect multicast packets that didn't match the filter */
720         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_PKT) != 0) {
721                 EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_PKT);
722
723                 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_HASH_MATCH) != 0) {
724                         EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_HASH_MATCH);
725                 } else {
726                         EFSYS_PROBE(mcast_mismatch);
727                         flags |= EFX_ADDR_MISMATCH;
728                 }
729         } else {
730                 flags |= EFX_PKT_UNICAST;
731         }
732
733         /*
734          * The packet parser in Siena can abort parsing packets under
735          * certain error conditions, setting the PKT_NOT_PARSED bit
736          * (which clears PKT_OK). If this is set, then don't trust
737          * the PKT_TYPE field.
738          */
739         if (!ok) {
740                 uint32_t parse_err;
741
742                 parse_err = EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_PKT_NOT_PARSED);
743                 if (parse_err != 0)
744                         flags |= EFX_CHECK_VLAN;
745         }
746
747         if (~flags & EFX_CHECK_VLAN) {
748                 uint32_t pkt_type;
749
750                 pkt_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_TYPE);
751                 if (pkt_type >= FSE_AZ_RX_EV_PKT_TYPE_VLAN)
752                         flags |= EFX_PKT_VLAN_TAGGED;
753         }
754
755         EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,
756             uint32_t, size, uint16_t, flags);
757
758         EFSYS_ASSERT(eecp->eec_rx != NULL);
759         should_abort = eecp->eec_rx(arg, label, id, size, flags);
760
761         return (should_abort);
762 }
763
764 static  __checkReturn   boolean_t
765 siena_ev_tx(
766         __in            efx_evq_t *eep,
767         __in            efx_qword_t *eqp,
768         __in            const efx_ev_callbacks_t *eecp,
769         __in_opt        void *arg)
770 {
771         uint32_t id;
772         uint32_t label;
773         boolean_t should_abort;
774
775         EFX_EV_QSTAT_INCR(eep, EV_TX);
776
777         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0 &&
778             EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) == 0 &&
779             EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) == 0 &&
780             EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) == 0) {
781
782                 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_DESC_PTR);
783                 label = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_Q_LABEL);
784
785                 EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
786
787                 EFSYS_ASSERT(eecp->eec_tx != NULL);
788                 should_abort = eecp->eec_tx(arg, label, id);
789
790                 return (should_abort);
791         }
792
793         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0)
794                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
795                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
796                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
797
798         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) != 0)
799                 EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_ERR);
800
801         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) != 0)
802                 EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_TOO_BIG);
803
804         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) != 0)
805                 EFX_EV_QSTAT_INCR(eep, EV_TX_WQ_FF_FULL);
806
807         EFX_EV_QSTAT_INCR(eep, EV_TX_UNEXPECTED);
808         return (B_FALSE);
809 }
810
811 static  __checkReturn   boolean_t
812 siena_ev_global(
813         __in            efx_evq_t *eep,
814         __in            efx_qword_t *eqp,
815         __in            const efx_ev_callbacks_t *eecp,
816         __in_opt        void *arg)
817 {
818         _NOTE(ARGUNUSED(eqp, eecp, arg))
819
820         EFX_EV_QSTAT_INCR(eep, EV_GLOBAL);
821
822         return (B_FALSE);
823 }
824
825 static  __checkReturn   boolean_t
826 siena_ev_driver(
827         __in            efx_evq_t *eep,
828         __in            efx_qword_t *eqp,
829         __in            const efx_ev_callbacks_t *eecp,
830         __in_opt        void *arg)
831 {
832         boolean_t should_abort;
833
834         EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
835         should_abort = B_FALSE;
836
837         switch (EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBCODE)) {
838         case FSE_AZ_TX_DESCQ_FLS_DONE_EV: {
839                 uint32_t txq_index;
840
841                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
842
843                 txq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
844
845                 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
846
847                 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
848                 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
849
850                 break;
851         }
852         case FSE_AZ_RX_DESCQ_FLS_DONE_EV: {
853                 uint32_t rxq_index;
854                 uint32_t failed;
855
856                 rxq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
857                 failed = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
858
859                 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
860                 EFSYS_ASSERT(eecp->eec_rxq_flush_failed != NULL);
861
862                 if (failed) {
863                         EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_FAILED);
864
865                         EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index);
866
867                         should_abort = eecp->eec_rxq_flush_failed(arg,
868                                                                     rxq_index);
869                 } else {
870                         EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
871
872                         EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
873
874                         should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
875                 }
876
877                 break;
878         }
879         case FSE_AZ_EVQ_INIT_DONE_EV:
880                 EFSYS_ASSERT(eecp->eec_initialized != NULL);
881                 should_abort = eecp->eec_initialized(arg);
882
883                 break;
884
885         case FSE_AZ_EVQ_NOT_EN_EV:
886                 EFSYS_PROBE(evq_not_en);
887                 break;
888
889         case FSE_AZ_SRM_UPD_DONE_EV: {
890                 uint32_t code;
891
892                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_SRM_UPD_DONE);
893
894                 code = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
895
896                 EFSYS_ASSERT(eecp->eec_sram != NULL);
897                 should_abort = eecp->eec_sram(arg, code);
898
899                 break;
900         }
901         case FSE_AZ_WAKE_UP_EV: {
902                 uint32_t id;
903
904                 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
905
906                 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
907                 should_abort = eecp->eec_wake_up(arg, id);
908
909                 break;
910         }
911         case FSE_AZ_TX_PKT_NON_TCP_UDP:
912                 EFSYS_PROBE(tx_pkt_non_tcp_udp);
913                 break;
914
915         case FSE_AZ_TIMER_EV: {
916                 uint32_t id;
917
918                 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
919
920                 EFSYS_ASSERT(eecp->eec_timer != NULL);
921                 should_abort = eecp->eec_timer(arg, id);
922
923                 break;
924         }
925         case FSE_AZ_RX_DSC_ERROR_EV:
926                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DSC_ERROR);
927
928                 EFSYS_PROBE(rx_dsc_error);
929
930                 EFSYS_ASSERT(eecp->eec_exception != NULL);
931                 should_abort = eecp->eec_exception(arg,
932                         EFX_EXCEPTION_RX_DSC_ERROR, 0);
933
934                 break;
935
936         case FSE_AZ_TX_DSC_ERROR_EV:
937                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DSC_ERROR);
938
939                 EFSYS_PROBE(tx_dsc_error);
940
941                 EFSYS_ASSERT(eecp->eec_exception != NULL);
942                 should_abort = eecp->eec_exception(arg,
943                         EFX_EXCEPTION_TX_DSC_ERROR, 0);
944
945                 break;
946
947         default:
948                 break;
949         }
950
951         return (should_abort);
952 }
953
954 static  __checkReturn   boolean_t
955 siena_ev_drv_gen(
956         __in            efx_evq_t *eep,
957         __in            efx_qword_t *eqp,
958         __in            const efx_ev_callbacks_t *eecp,
959         __in_opt        void *arg)
960 {
961         uint32_t data;
962         boolean_t should_abort;
963
964         EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
965
966         data = EFX_QWORD_FIELD(*eqp, FSF_AZ_EV_DATA_DW0);
967         if (data >= ((uint32_t)1 << 16)) {
968                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
969                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
970                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
971                 return (B_TRUE);
972         }
973
974         EFSYS_ASSERT(eecp->eec_software != NULL);
975         should_abort = eecp->eec_software(arg, (uint16_t)data);
976
977         return (should_abort);
978 }
979
980 #if EFSYS_OPT_MCDI
981
982 static  __checkReturn   boolean_t
983 siena_ev_mcdi(
984         __in            efx_evq_t *eep,
985         __in            efx_qword_t *eqp,
986         __in            const efx_ev_callbacks_t *eecp,
987         __in_opt        void *arg)
988 {
989         efx_nic_t *enp = eep->ee_enp;
990         unsigned int code;
991         boolean_t should_abort = B_FALSE;
992
993         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
994
995         if (enp->en_family != EFX_FAMILY_SIENA)
996                 goto out;
997
998         EFSYS_ASSERT(eecp->eec_link_change != NULL);
999         EFSYS_ASSERT(eecp->eec_exception != NULL);
1000 #if EFSYS_OPT_MON_STATS
1001         EFSYS_ASSERT(eecp->eec_monitor != NULL);
1002 #endif
1003
1004         EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
1005
1006         code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
1007         switch (code) {
1008         case MCDI_EVENT_CODE_BADSSERT:
1009                 efx_mcdi_ev_death(enp, EINTR);
1010                 break;
1011
1012         case MCDI_EVENT_CODE_CMDDONE:
1013                 efx_mcdi_ev_cpl(enp,
1014                     MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
1015                     MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
1016                     MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
1017                 break;
1018
1019         case MCDI_EVENT_CODE_LINKCHANGE: {
1020                 efx_link_mode_t link_mode;
1021
1022                 siena_phy_link_ev(enp, eqp, &link_mode);
1023                 should_abort = eecp->eec_link_change(arg, link_mode);
1024                 break;
1025         }
1026         case MCDI_EVENT_CODE_SENSOREVT: {
1027 #if EFSYS_OPT_MON_STATS
1028                 efx_mon_stat_t id;
1029                 efx_mon_stat_value_t value;
1030                 efx_rc_t rc;
1031
1032                 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0)
1033                         should_abort = eecp->eec_monitor(arg, id, value);
1034                 else if (rc == ENOTSUP) {
1035                         should_abort = eecp->eec_exception(arg,
1036                                 EFX_EXCEPTION_UNKNOWN_SENSOREVT,
1037                                 MCDI_EV_FIELD(eqp, DATA));
1038                 } else
1039                         EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
1040 #else
1041                 should_abort = B_FALSE;
1042 #endif
1043                 break;
1044         }
1045         case MCDI_EVENT_CODE_SCHEDERR:
1046                 /* Informational only */
1047                 break;
1048
1049         case MCDI_EVENT_CODE_REBOOT:
1050                 efx_mcdi_ev_death(enp, EIO);
1051                 break;
1052
1053         case MCDI_EVENT_CODE_MAC_STATS_DMA:
1054 #if EFSYS_OPT_MAC_STATS
1055                 if (eecp->eec_mac_stats != NULL) {
1056                         eecp->eec_mac_stats(arg,
1057                             MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
1058                 }
1059 #endif
1060                 break;
1061
1062         case MCDI_EVENT_CODE_FWALERT: {
1063                 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
1064
1065                 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
1066                         should_abort = eecp->eec_exception(arg,
1067                                 EFX_EXCEPTION_FWALERT_SRAM,
1068                                 MCDI_EV_FIELD(eqp, FWALERT_DATA));
1069                 else
1070                         should_abort = eecp->eec_exception(arg,
1071                                 EFX_EXCEPTION_UNKNOWN_FWALERT,
1072                                 MCDI_EV_FIELD(eqp, DATA));
1073                 break;
1074         }
1075
1076         default:
1077                 EFSYS_PROBE1(mc_pcol_error, int, code);
1078                 break;
1079         }
1080
1081 out:
1082         return (should_abort);
1083 }
1084
1085 #endif  /* EFSYS_OPT_MCDI */
1086
1087 static  __checkReturn   efx_rc_t
1088 siena_ev_qprime(
1089         __in            efx_evq_t *eep,
1090         __in            unsigned int count)
1091 {
1092         efx_nic_t *enp = eep->ee_enp;
1093         uint32_t rptr;
1094         efx_dword_t dword;
1095
1096         rptr = count & eep->ee_mask;
1097
1098         EFX_POPULATE_DWORD_1(dword, FRF_AZ_EVQ_RPTR, rptr);
1099
1100         EFX_BAR_TBL_WRITED(enp, FR_AZ_EVQ_RPTR_REG, eep->ee_index,
1101                             &dword, B_FALSE);
1102
1103         return (0);
1104 }
1105
1106 static          void
1107 siena_ev_qpost(
1108         __in    efx_evq_t *eep,
1109         __in    uint16_t data)
1110 {
1111         efx_nic_t *enp = eep->ee_enp;
1112         efx_qword_t ev;
1113         efx_oword_t oword;
1114
1115         EFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV,
1116             FSF_AZ_EV_DATA_DW0, (uint32_t)data);
1117
1118         EFX_POPULATE_OWORD_3(oword, FRF_AZ_DRV_EV_QID, eep->ee_index,
1119             EFX_DWORD_0, EFX_QWORD_FIELD(ev, EFX_DWORD_0),
1120             EFX_DWORD_1, EFX_QWORD_FIELD(ev, EFX_DWORD_1));
1121
1122         EFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword);
1123 }
1124
1125 static  __checkReturn   efx_rc_t
1126 siena_ev_qmoderate(
1127         __in            efx_evq_t *eep,
1128         __in            unsigned int us)
1129 {
1130         efx_nic_t *enp = eep->ee_enp;
1131         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1132         unsigned int locked;
1133         efx_dword_t dword;
1134         efx_rc_t rc;
1135
1136         if (us > encp->enc_evq_timer_max_us) {
1137                 rc = EINVAL;
1138                 goto fail1;
1139         }
1140
1141         /* If the value is zero then disable the timer */
1142         if (us == 0) {
1143                 EFX_POPULATE_DWORD_2(dword,
1144                     FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS,
1145                     FRF_CZ_TC_TIMER_VAL, 0);
1146         } else {
1147                 unsigned int ticks;
1148
1149                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
1150                         goto fail2;
1151
1152                 EFSYS_ASSERT(ticks > 0);
1153                 EFX_POPULATE_DWORD_2(dword,
1154                     FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_INT_HLDOFF,
1155                     FRF_CZ_TC_TIMER_VAL, ticks - 1);
1156         }
1157
1158         locked = (eep->ee_index == 0) ? 1 : 0;
1159
1160         EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
1161             eep->ee_index, &dword, locked);
1162
1163         return (0);
1164
1165 fail2:
1166         EFSYS_PROBE(fail2);
1167 fail1:
1168         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1169
1170         return (rc);
1171 }
1172
1173 static  __checkReturn   efx_rc_t
1174 siena_ev_qcreate(
1175         __in            efx_nic_t *enp,
1176         __in            unsigned int index,
1177         __in            efsys_mem_t *esmp,
1178         __in            size_t ndescs,
1179         __in            uint32_t id,
1180         __in            uint32_t us,
1181         __in            uint32_t flags,
1182         __in            efx_evq_t *eep)
1183 {
1184         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1185         uint32_t size;
1186         efx_oword_t oword;
1187         efx_rc_t rc;
1188         boolean_t notify_mode;
1189
1190         _NOTE(ARGUNUSED(esmp))
1191
1192         if (index >= encp->enc_evq_limit) {
1193                 rc = EINVAL;
1194                 goto fail1;
1195         }
1196 #if EFSYS_OPT_RX_SCALE
1197         if (enp->en_intr.ei_type == EFX_INTR_LINE &&
1198             index >= EFX_MAXRSS_LEGACY) {
1199                 rc = EINVAL;
1200                 goto fail2;
1201         }
1202 #endif
1203         for (size = 0;
1204             (1U << size) <= encp->enc_evq_max_nevs / encp->enc_evq_min_nevs;
1205             size++)
1206                 if ((1U << size) == (uint32_t)ndescs / encp->enc_evq_min_nevs)
1207                         break;
1208         if (id + (1 << size) >= encp->enc_buftbl_limit) {
1209                 rc = EINVAL;
1210                 goto fail3;
1211         }
1212
1213         /* Set up the handler table */
1214         eep->ee_rx      = siena_ev_rx;
1215         eep->ee_tx      = siena_ev_tx;
1216         eep->ee_driver  = siena_ev_driver;
1217         eep->ee_global  = siena_ev_global;
1218         eep->ee_drv_gen = siena_ev_drv_gen;
1219 #if EFSYS_OPT_MCDI
1220         eep->ee_mcdi    = siena_ev_mcdi;
1221 #endif  /* EFSYS_OPT_MCDI */
1222
1223         notify_mode = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) !=
1224             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT);
1225
1226         /* Set up the new event queue */
1227         EFX_POPULATE_OWORD_3(oword, FRF_CZ_TIMER_Q_EN, 1,
1228             FRF_CZ_HOST_NOTIFY_MODE, notify_mode,
1229             FRF_CZ_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS);
1230         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword, B_TRUE);
1231
1232         EFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size,
1233             FRF_AZ_EVQ_BUF_BASE_ID, id);
1234
1235         EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword, B_TRUE);
1236
1237         /* Set initial interrupt moderation */
1238         siena_ev_qmoderate(eep, us);
1239
1240         return (0);
1241
1242 fail3:
1243         EFSYS_PROBE(fail3);
1244 #if EFSYS_OPT_RX_SCALE
1245 fail2:
1246         EFSYS_PROBE(fail2);
1247 #endif
1248 fail1:
1249         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1250
1251         return (rc);
1252 }
1253
1254 #endif /* EFSYS_OPT_SIENA */
1255
1256 #if EFSYS_OPT_QSTATS
1257 #if EFSYS_OPT_NAMES
1258 /* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock ac223f7134058b4f */
1259 static const char * const __efx_ev_qstat_name[] = {
1260         "all",
1261         "rx",
1262         "rx_ok",
1263         "rx_frm_trunc",
1264         "rx_tobe_disc",
1265         "rx_pause_frm_err",
1266         "rx_buf_owner_id_err",
1267         "rx_ipv4_hdr_chksum_err",
1268         "rx_tcp_udp_chksum_err",
1269         "rx_eth_crc_err",
1270         "rx_ip_frag_err",
1271         "rx_mcast_pkt",
1272         "rx_mcast_hash_match",
1273         "rx_tcp_ipv4",
1274         "rx_tcp_ipv6",
1275         "rx_udp_ipv4",
1276         "rx_udp_ipv6",
1277         "rx_other_ipv4",
1278         "rx_other_ipv6",
1279         "rx_non_ip",
1280         "rx_batch",
1281         "tx",
1282         "tx_wq_ff_full",
1283         "tx_pkt_err",
1284         "tx_pkt_too_big",
1285         "tx_unexpected",
1286         "global",
1287         "global_mnt",
1288         "driver",
1289         "driver_srm_upd_done",
1290         "driver_tx_descq_fls_done",
1291         "driver_rx_descq_fls_done",
1292         "driver_rx_descq_fls_failed",
1293         "driver_rx_dsc_error",
1294         "driver_tx_dsc_error",
1295         "drv_gen",
1296         "mcdi_response",
1297         "rx_parse_incomplete",
1298 };
1299 /* END MKCONFIG GENERATED EfxEventQueueStatNamesBlock */
1300
1301                 const char *
1302 efx_ev_qstat_name(
1303         __in    efx_nic_t *enp,
1304         __in    unsigned int id)
1305 {
1306         _NOTE(ARGUNUSED(enp))
1307
1308         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1309         EFSYS_ASSERT3U(id, <, EV_NQSTATS);
1310
1311         return (__efx_ev_qstat_name[id]);
1312 }
1313 #endif  /* EFSYS_OPT_NAMES */
1314 #endif  /* EFSYS_OPT_QSTATS */
1315
1316 #if EFSYS_OPT_SIENA
1317
1318 #if EFSYS_OPT_QSTATS
1319 static                                  void
1320 siena_ev_qstats_update(
1321         __in                            efx_evq_t *eep,
1322         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
1323 {
1324         unsigned int id;
1325
1326         for (id = 0; id < EV_NQSTATS; id++) {
1327                 efsys_stat_t *essp = &stat[id];
1328
1329                 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
1330                 eep->ee_stat[id] = 0;
1331         }
1332 }
1333 #endif  /* EFSYS_OPT_QSTATS */
1334
1335 static          void
1336 siena_ev_qdestroy(
1337         __in    efx_evq_t *eep)
1338 {
1339         efx_nic_t *enp = eep->ee_enp;
1340         efx_oword_t oword;
1341
1342         /* Purge event queue */
1343         EFX_ZERO_OWORD(oword);
1344
1345         EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL,
1346             eep->ee_index, &oword, B_TRUE);
1347
1348         EFX_ZERO_OWORD(oword);
1349         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, eep->ee_index, &oword, B_TRUE);
1350 }
1351
1352 static          void
1353 siena_ev_fini(
1354         __in    efx_nic_t *enp)
1355 {
1356         _NOTE(ARGUNUSED(enp))
1357 }
1358
1359 #endif /* EFSYS_OPT_SIENA */
1360
1361 #if EFX_OPTS_EF10() || EFSYS_OPT_SIENA
1362
1363 #define EFX_EV_BATCH    8
1364
1365 static                  void
1366 siena_ef10_ev_qpoll(
1367         __in            efx_evq_t *eep,
1368         __inout         unsigned int *countp,
1369         __in            const efx_ev_callbacks_t *eecp,
1370         __in_opt        void *arg)
1371 {
1372         efx_qword_t ev[EFX_EV_BATCH];
1373         unsigned int batch;
1374         unsigned int total;
1375         unsigned int count;
1376         unsigned int index;
1377         size_t offset;
1378
1379         /* Ensure events codes match for EF10 (Huntington/Medford) and Siena */
1380         EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_LBN == FSF_AZ_EV_CODE_LBN);
1381         EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_WIDTH == FSF_AZ_EV_CODE_WIDTH);
1382
1383         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_RX_EV == FSE_AZ_EV_CODE_RX_EV);
1384         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_TX_EV == FSE_AZ_EV_CODE_TX_EV);
1385         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRIVER_EV == FSE_AZ_EV_CODE_DRIVER_EV);
1386         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRV_GEN_EV ==
1387             FSE_AZ_EV_CODE_DRV_GEN_EV);
1388 #if EFSYS_OPT_MCDI
1389         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_MCDI_EV ==
1390             FSE_AZ_EV_CODE_MCDI_EVRESPONSE);
1391 #endif
1392
1393         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
1394         EFSYS_ASSERT(countp != NULL);
1395         EFSYS_ASSERT(eecp != NULL);
1396
1397         count = *countp;
1398         do {
1399                 /* Read up until the end of the batch period */
1400                 batch = EFX_EV_BATCH - (count & (EFX_EV_BATCH - 1));
1401                 offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
1402                 for (total = 0; total < batch; ++total) {
1403                         EFSYS_MEM_READQ(eep->ee_esmp, offset, &(ev[total]));
1404
1405                         if (!EFX_EV_PRESENT(ev[total]))
1406                                 break;
1407
1408                         EFSYS_PROBE3(event, unsigned int, eep->ee_index,
1409                             uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_1),
1410                             uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_0));
1411
1412                         offset += sizeof (efx_qword_t);
1413                 }
1414
1415 #if EFSYS_OPT_EV_PREFETCH && (EFSYS_OPT_EV_PREFETCH_PERIOD > 1)
1416                 /*
1417                  * Prefetch the next batch when we get within PREFETCH_PERIOD
1418                  * of a completed batch. If the batch is smaller, then prefetch
1419                  * immediately.
1420                  */
1421                 if (total == batch && total < EFSYS_OPT_EV_PREFETCH_PERIOD)
1422                         EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
1423 #endif  /* EFSYS_OPT_EV_PREFETCH */
1424
1425                 /* Process the batch of events */
1426                 for (index = 0; index < total; ++index) {
1427                         boolean_t should_abort;
1428                         uint32_t code;
1429
1430 #if EFSYS_OPT_EV_PREFETCH
1431                         /* Prefetch if we've now reached the batch period */
1432                         if (total == batch &&
1433                             index + EFSYS_OPT_EV_PREFETCH_PERIOD == total) {
1434                                 offset = (count + batch) & eep->ee_mask;
1435                                 offset *= sizeof (efx_qword_t);
1436
1437                                 EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
1438                         }
1439 #endif  /* EFSYS_OPT_EV_PREFETCH */
1440
1441                         EFX_EV_QSTAT_INCR(eep, EV_ALL);
1442
1443                         code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE);
1444                         switch (code) {
1445                         case FSE_AZ_EV_CODE_RX_EV:
1446                                 should_abort = eep->ee_rx(eep,
1447                                     &(ev[index]), eecp, arg);
1448                                 break;
1449                         case FSE_AZ_EV_CODE_TX_EV:
1450                                 should_abort = eep->ee_tx(eep,
1451                                     &(ev[index]), eecp, arg);
1452                                 break;
1453                         case FSE_AZ_EV_CODE_DRIVER_EV:
1454                                 should_abort = eep->ee_driver(eep,
1455                                     &(ev[index]), eecp, arg);
1456                                 break;
1457                         case FSE_AZ_EV_CODE_DRV_GEN_EV:
1458                                 should_abort = eep->ee_drv_gen(eep,
1459                                     &(ev[index]), eecp, arg);
1460                                 break;
1461 #if EFSYS_OPT_MCDI
1462                         case FSE_AZ_EV_CODE_MCDI_EVRESPONSE:
1463                                 should_abort = eep->ee_mcdi(eep,
1464                                     &(ev[index]), eecp, arg);
1465                                 break;
1466 #endif
1467                         case FSE_AZ_EV_CODE_GLOBAL_EV:
1468                                 if (eep->ee_global) {
1469                                         should_abort = eep->ee_global(eep,
1470                                             &(ev[index]), eecp, arg);
1471                                         break;
1472                                 }
1473                                 /* else fallthrough */
1474                         default:
1475                                 EFSYS_PROBE3(bad_event,
1476                                     unsigned int, eep->ee_index,
1477                                     uint32_t,
1478                                     EFX_QWORD_FIELD(ev[index], EFX_DWORD_1),
1479                                     uint32_t,
1480                                     EFX_QWORD_FIELD(ev[index], EFX_DWORD_0));
1481
1482                                 EFSYS_ASSERT(eecp->eec_exception != NULL);
1483                                 (void) eecp->eec_exception(arg,
1484                                         EFX_EXCEPTION_EV_ERROR, code);
1485                                 should_abort = B_TRUE;
1486                         }
1487                         if (should_abort) {
1488                                 /* Ignore subsequent events */
1489                                 total = index + 1;
1490
1491                                 /*
1492                                  * Poison batch to ensure the outer
1493                                  * loop is broken out of.
1494                                  */
1495                                 EFSYS_ASSERT(batch <= EFX_EV_BATCH);
1496                                 batch += (EFX_EV_BATCH << 1);
1497                                 EFSYS_ASSERT(total != batch);
1498                                 break;
1499                         }
1500                 }
1501
1502                 /*
1503                  * Now that the hardware has most likely moved onto dma'ing
1504                  * into the next cache line, clear the processed events. Take
1505                  * care to only clear out events that we've processed
1506                  */
1507                 EFX_SET_QWORD(ev[0]);
1508                 offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
1509                 for (index = 0; index < total; ++index) {
1510                         EFSYS_MEM_WRITEQ(eep->ee_esmp, offset, &(ev[0]));
1511                         offset += sizeof (efx_qword_t);
1512                 }
1513
1514                 count += total;
1515
1516         } while (total == batch);
1517
1518         *countp = count;
1519 }
1520
1521 #endif  /* EFX_OPTS_EF10() || EFSYS_OPT_SIENA */