]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sfxge/common/ef10_ev.c
Revert r333006:
[FreeBSD/FreeBSD.git] / sys / dev / sfxge / common / ef10_ev.c
1 /*-
2  * Copyright (c) 2012-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include "efx.h"
35 #include "efx_impl.h"
36 #if EFSYS_OPT_MON_STATS
37 #include "mcdi_mon.h"
38 #endif
39
40 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
41
42 #if EFSYS_OPT_QSTATS
43 #define EFX_EV_QSTAT_INCR(_eep, _stat)                                  \
44         do {                                                            \
45                 (_eep)->ee_stat[_stat]++;                               \
46         _NOTE(CONSTANTCONDITION)                                        \
47         } while (B_FALSE)
48 #else
49 #define EFX_EV_QSTAT_INCR(_eep, _stat)
50 #endif
51
52 /*
53  * Non-interrupting event queue requires interrrupting event queue to
54  * refer to for wake-up events even if wake ups are never used.
55  * It could be even non-allocated event queue.
56  */
57 #define EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX  (0)
58
59 static  __checkReturn   boolean_t
60 ef10_ev_rx(
61         __in            efx_evq_t *eep,
62         __in            efx_qword_t *eqp,
63         __in            const efx_ev_callbacks_t *eecp,
64         __in_opt        void *arg);
65
66 static  __checkReturn   boolean_t
67 ef10_ev_tx(
68         __in            efx_evq_t *eep,
69         __in            efx_qword_t *eqp,
70         __in            const efx_ev_callbacks_t *eecp,
71         __in_opt        void *arg);
72
73 static  __checkReturn   boolean_t
74 ef10_ev_driver(
75         __in            efx_evq_t *eep,
76         __in            efx_qword_t *eqp,
77         __in            const efx_ev_callbacks_t *eecp,
78         __in_opt        void *arg);
79
80 static  __checkReturn   boolean_t
81 ef10_ev_drv_gen(
82         __in            efx_evq_t *eep,
83         __in            efx_qword_t *eqp,
84         __in            const efx_ev_callbacks_t *eecp,
85         __in_opt        void *arg);
86
87 static  __checkReturn   boolean_t
88 ef10_ev_mcdi(
89         __in            efx_evq_t *eep,
90         __in            efx_qword_t *eqp,
91         __in            const efx_ev_callbacks_t *eecp,
92         __in_opt        void *arg);
93
94
95 static  __checkReturn   efx_rc_t
96 efx_mcdi_set_evq_tmr(
97         __in            efx_nic_t *enp,
98         __in            uint32_t instance,
99         __in            uint32_t mode,
100         __in            uint32_t timer_ns)
101 {
102         efx_mcdi_req_t req;
103         uint8_t payload[MAX(MC_CMD_SET_EVQ_TMR_IN_LEN,
104                             MC_CMD_SET_EVQ_TMR_OUT_LEN)];
105         efx_rc_t rc;
106
107         (void) memset(payload, 0, sizeof (payload));
108         req.emr_cmd = MC_CMD_SET_EVQ_TMR;
109         req.emr_in_buf = payload;
110         req.emr_in_length = MC_CMD_SET_EVQ_TMR_IN_LEN;
111         req.emr_out_buf = payload;
112         req.emr_out_length = MC_CMD_SET_EVQ_TMR_OUT_LEN;
113
114         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_INSTANCE, instance);
115         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_LOAD_REQ_NS, timer_ns);
116         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_RELOAD_REQ_NS, timer_ns);
117         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_MODE, mode);
118
119         efx_mcdi_execute(enp, &req);
120
121         if (req.emr_rc != 0) {
122                 rc = req.emr_rc;
123                 goto fail1;
124         }
125
126         if (req.emr_out_length_used < MC_CMD_SET_EVQ_TMR_OUT_LEN) {
127                 rc = EMSGSIZE;
128                 goto fail2;
129         }
130
131         return (0);
132
133 fail2:
134         EFSYS_PROBE(fail2);
135 fail1:
136         EFSYS_PROBE1(fail1, efx_rc_t, rc);
137
138         return (rc);
139 }
140
141 static  __checkReturn   efx_rc_t
142 efx_mcdi_init_evq(
143         __in            efx_nic_t *enp,
144         __in            unsigned int instance,
145         __in            efsys_mem_t *esmp,
146         __in            size_t nevs,
147         __in            uint32_t irq,
148         __in            uint32_t us,
149         __in            uint32_t flags,
150         __in            boolean_t low_latency)
151 {
152         efx_mcdi_req_t req;
153         uint8_t payload[
154             MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
155                 MC_CMD_INIT_EVQ_OUT_LEN)];
156         efx_qword_t *dma_addr;
157         uint64_t addr;
158         int npages;
159         int i;
160         boolean_t interrupting;
161         int ev_cut_through;
162         efx_rc_t rc;
163
164         npages = EFX_EVQ_NBUFS(nevs);
165         if (MC_CMD_INIT_EVQ_IN_LEN(npages) > MC_CMD_INIT_EVQ_IN_LENMAX) {
166                 rc = EINVAL;
167                 goto fail1;
168         }
169
170         (void) memset(payload, 0, sizeof (payload));
171         req.emr_cmd = MC_CMD_INIT_EVQ;
172         req.emr_in_buf = payload;
173         req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
174         req.emr_out_buf = payload;
175         req.emr_out_length = MC_CMD_INIT_EVQ_OUT_LEN;
176
177         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_SIZE, nevs);
178         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_INSTANCE, instance);
179         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_IRQ_NUM, irq);
180
181         interrupting = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
182             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT);
183
184         /*
185          * On Huntington RX and TX event batching can only be requested together
186          * (even if the datapath firmware doesn't actually support RX
187          * batching). If event cut through is enabled no RX batching will occur.
188          *
189          * So always enable RX and TX event batching, and enable event cut
190          * through if we want low latency operation.
191          */
192         switch (flags & EFX_EVQ_FLAGS_TYPE_MASK) {
193         case EFX_EVQ_FLAGS_TYPE_AUTO:
194                 ev_cut_through = low_latency ? 1 : 0;
195                 break;
196         case EFX_EVQ_FLAGS_TYPE_THROUGHPUT:
197                 ev_cut_through = 0;
198                 break;
199         case EFX_EVQ_FLAGS_TYPE_LOW_LATENCY:
200                 ev_cut_through = 1;
201                 break;
202         default:
203                 rc = EINVAL;
204                 goto fail2;
205         }
206         MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_IN_FLAGS,
207             INIT_EVQ_IN_FLAG_INTERRUPTING, interrupting,
208             INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
209             INIT_EVQ_IN_FLAG_INT_ARMD, 0,
210             INIT_EVQ_IN_FLAG_CUT_THRU, ev_cut_through,
211             INIT_EVQ_IN_FLAG_RX_MERGE, 1,
212             INIT_EVQ_IN_FLAG_TX_MERGE, 1);
213
214         /* If the value is zero then disable the timer */
215         if (us == 0) {
216                 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
217                     MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
218                 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, 0);
219                 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, 0);
220         } else {
221                 unsigned int ticks;
222
223                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
224                         goto fail3;
225
226                 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
227                     MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF);
228                 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, ticks);
229                 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, ticks);
230         }
231
232         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_MODE,
233             MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
234         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_THRSHLD, 0);
235
236         dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_IN_DMA_ADDR);
237         addr = EFSYS_MEM_ADDR(esmp);
238
239         for (i = 0; i < npages; i++) {
240                 EFX_POPULATE_QWORD_2(*dma_addr,
241                     EFX_DWORD_1, (uint32_t)(addr >> 32),
242                     EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
243
244                 dma_addr++;
245                 addr += EFX_BUF_SIZE;
246         }
247
248         efx_mcdi_execute(enp, &req);
249
250         if (req.emr_rc != 0) {
251                 rc = req.emr_rc;
252                 goto fail4;
253         }
254
255         if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) {
256                 rc = EMSGSIZE;
257                 goto fail5;
258         }
259
260         /* NOTE: ignore the returned IRQ param as firmware does not set it. */
261
262         return (0);
263
264 fail5:
265         EFSYS_PROBE(fail5);
266 fail4:
267         EFSYS_PROBE(fail4);
268 fail3:
269         EFSYS_PROBE(fail3);
270 fail2:
271         EFSYS_PROBE(fail2);
272 fail1:
273         EFSYS_PROBE1(fail1, efx_rc_t, rc);
274
275         return (rc);
276 }
277
278
279 static  __checkReturn   efx_rc_t
280 efx_mcdi_init_evq_v2(
281         __in            efx_nic_t *enp,
282         __in            unsigned int instance,
283         __in            efsys_mem_t *esmp,
284         __in            size_t nevs,
285         __in            uint32_t irq,
286         __in            uint32_t us,
287         __in            uint32_t flags)
288 {
289         efx_mcdi_req_t req;
290         uint8_t payload[
291                 MAX(MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
292                     MC_CMD_INIT_EVQ_V2_OUT_LEN)];
293         boolean_t interrupting;
294         unsigned int evq_type;
295         efx_qword_t *dma_addr;
296         uint64_t addr;
297         int npages;
298         int i;
299         efx_rc_t rc;
300
301         npages = EFX_EVQ_NBUFS(nevs);
302         if (MC_CMD_INIT_EVQ_V2_IN_LEN(npages) > MC_CMD_INIT_EVQ_V2_IN_LENMAX) {
303                 rc = EINVAL;
304                 goto fail1;
305         }
306
307         (void) memset(payload, 0, sizeof (payload));
308         req.emr_cmd = MC_CMD_INIT_EVQ;
309         req.emr_in_buf = payload;
310         req.emr_in_length = MC_CMD_INIT_EVQ_V2_IN_LEN(npages);
311         req.emr_out_buf = payload;
312         req.emr_out_length = MC_CMD_INIT_EVQ_V2_OUT_LEN;
313
314         MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_SIZE, nevs);
315         MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_INSTANCE, instance);
316         MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_IRQ_NUM, irq);
317
318         interrupting = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
319             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT);
320
321         switch (flags & EFX_EVQ_FLAGS_TYPE_MASK) {
322         case EFX_EVQ_FLAGS_TYPE_AUTO:
323                 evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO;
324                 break;
325         case EFX_EVQ_FLAGS_TYPE_THROUGHPUT:
326                 evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_THROUGHPUT;
327                 break;
328         case EFX_EVQ_FLAGS_TYPE_LOW_LATENCY:
329                 evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_LOW_LATENCY;
330                 break;
331         default:
332                 rc = EINVAL;
333                 goto fail2;
334         }
335         MCDI_IN_POPULATE_DWORD_4(req, INIT_EVQ_V2_IN_FLAGS,
336             INIT_EVQ_V2_IN_FLAG_INTERRUPTING, interrupting,
337             INIT_EVQ_V2_IN_FLAG_RPTR_DOS, 0,
338             INIT_EVQ_V2_IN_FLAG_INT_ARMD, 0,
339             INIT_EVQ_V2_IN_FLAG_TYPE, evq_type);
340
341         /* If the value is zero then disable the timer */
342         if (us == 0) {
343                 MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_MODE,
344                     MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_DIS);
345                 MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_LOAD, 0);
346                 MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_RELOAD, 0);
347         } else {
348                 unsigned int ticks;
349
350                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
351                         goto fail3;
352
353                 MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_MODE,
354                     MC_CMD_INIT_EVQ_V2_IN_TMR_INT_HLDOFF);
355                 MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_LOAD, ticks);
356                 MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_RELOAD, ticks);
357         }
358
359         MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_COUNT_MODE,
360             MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_DIS);
361         MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_COUNT_THRSHLD, 0);
362
363         dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_V2_IN_DMA_ADDR);
364         addr = EFSYS_MEM_ADDR(esmp);
365
366         for (i = 0; i < npages; i++) {
367                 EFX_POPULATE_QWORD_2(*dma_addr,
368                     EFX_DWORD_1, (uint32_t)(addr >> 32),
369                     EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
370
371                 dma_addr++;
372                 addr += EFX_BUF_SIZE;
373         }
374
375         efx_mcdi_execute(enp, &req);
376
377         if (req.emr_rc != 0) {
378                 rc = req.emr_rc;
379                 goto fail4;
380         }
381
382         if (req.emr_out_length_used < MC_CMD_INIT_EVQ_V2_OUT_LEN) {
383                 rc = EMSGSIZE;
384                 goto fail5;
385         }
386
387         /* NOTE: ignore the returned IRQ param as firmware does not set it. */
388
389         EFSYS_PROBE1(mcdi_evq_flags, uint32_t,
390                     MCDI_OUT_DWORD(req, INIT_EVQ_V2_OUT_FLAGS));
391
392         return (0);
393
394 fail5:
395         EFSYS_PROBE(fail5);
396 fail4:
397         EFSYS_PROBE(fail4);
398 fail3:
399         EFSYS_PROBE(fail3);
400 fail2:
401         EFSYS_PROBE(fail2);
402 fail1:
403         EFSYS_PROBE1(fail1, efx_rc_t, rc);
404
405         return (rc);
406 }
407
408 static  __checkReturn   efx_rc_t
409 efx_mcdi_fini_evq(
410         __in            efx_nic_t *enp,
411         __in            uint32_t instance)
412 {
413         efx_mcdi_req_t req;
414         uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
415                             MC_CMD_FINI_EVQ_OUT_LEN)];
416         efx_rc_t rc;
417
418         (void) memset(payload, 0, sizeof (payload));
419         req.emr_cmd = MC_CMD_FINI_EVQ;
420         req.emr_in_buf = payload;
421         req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
422         req.emr_out_buf = payload;
423         req.emr_out_length = MC_CMD_FINI_EVQ_OUT_LEN;
424
425         MCDI_IN_SET_DWORD(req, FINI_EVQ_IN_INSTANCE, instance);
426
427         efx_mcdi_execute_quiet(enp, &req);
428
429         if (req.emr_rc != 0) {
430                 rc = req.emr_rc;
431                 goto fail1;
432         }
433
434         return (0);
435
436 fail1:
437         EFSYS_PROBE1(fail1, efx_rc_t, rc);
438
439         return (rc);
440 }
441
442
443
444         __checkReturn   efx_rc_t
445 ef10_ev_init(
446         __in            efx_nic_t *enp)
447 {
448         _NOTE(ARGUNUSED(enp))
449         return (0);
450 }
451
452                         void
453 ef10_ev_fini(
454         __in            efx_nic_t *enp)
455 {
456         _NOTE(ARGUNUSED(enp))
457 }
458
459         __checkReturn   efx_rc_t
460 ef10_ev_qcreate(
461         __in            efx_nic_t *enp,
462         __in            unsigned int index,
463         __in            efsys_mem_t *esmp,
464         __in            size_t n,
465         __in            uint32_t id,
466         __in            uint32_t us,
467         __in            uint32_t flags,
468         __in            efx_evq_t *eep)
469 {
470         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
471         uint32_t irq;
472         efx_rc_t rc;
473
474         _NOTE(ARGUNUSED(id))    /* buftbl id managed by MC */
475         EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
476         EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
477
478         if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
479                 rc = EINVAL;
480                 goto fail1;
481         }
482
483         if (index >= encp->enc_evq_limit) {
484                 rc = EINVAL;
485                 goto fail2;
486         }
487
488         if (us > encp->enc_evq_timer_max_us) {
489                 rc = EINVAL;
490                 goto fail3;
491         }
492
493         /* Set up the handler table */
494         eep->ee_rx      = ef10_ev_rx;
495         eep->ee_tx      = ef10_ev_tx;
496         eep->ee_driver  = ef10_ev_driver;
497         eep->ee_drv_gen = ef10_ev_drv_gen;
498         eep->ee_mcdi    = ef10_ev_mcdi;
499
500         /* Set up the event queue */
501         /* INIT_EVQ expects function-relative vector number */
502         if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
503             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT) {
504                 irq = index;
505         } else if (index == EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX) {
506                 irq = index;
507                 flags = (flags & ~EFX_EVQ_FLAGS_NOTIFY_MASK) |
508                     EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
509         } else {
510                 irq = EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX;
511         }
512
513         /*
514          * Interrupts may be raised for events immediately after the queue is
515          * created. See bug58606.
516          */
517
518         if (encp->enc_init_evq_v2_supported) {
519                 /*
520                  * On Medford the low latency license is required to enable RX
521                  * and event cut through and to disable RX batching.  If event
522                  * queue type in flags is auto, we let the firmware decide the
523                  * settings to use. If the adapter has a low latency license,
524                  * it will choose the best settings for low latency, otherwise
525                  * it will choose the best settings for throughput.
526                  */
527                 rc = efx_mcdi_init_evq_v2(enp, index, esmp, n, irq, us, flags);
528                 if (rc != 0)
529                         goto fail4;
530         } else {
531                 /*
532                  * On Huntington we need to specify the settings to use.
533                  * If event queue type in flags is auto, we favour throughput
534                  * if the adapter is running virtualization supporting firmware
535                  * (i.e. the full featured firmware variant)
536                  * and latency otherwise. The Ethernet Virtual Bridging
537                  * capability is used to make this decision. (Note though that
538                  * the low latency firmware variant is also best for
539                  * throughput and corresponding type should be specified
540                  * to choose it.)
541                  */
542                 boolean_t low_latency = encp->enc_datapath_cap_evb ? 0 : 1;
543                 rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, us, flags,
544                     low_latency);
545                 if (rc != 0)
546                         goto fail5;
547         }
548
549         return (0);
550
551 fail5:
552         EFSYS_PROBE(fail5);
553 fail4:
554         EFSYS_PROBE(fail4);
555 fail3:
556         EFSYS_PROBE(fail3);
557 fail2:
558         EFSYS_PROBE(fail2);
559 fail1:
560         EFSYS_PROBE1(fail1, efx_rc_t, rc);
561
562         return (rc);
563 }
564
565                         void
566 ef10_ev_qdestroy(
567         __in            efx_evq_t *eep)
568 {
569         efx_nic_t *enp = eep->ee_enp;
570
571         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
572             enp->en_family == EFX_FAMILY_MEDFORD);
573
574         (void) efx_mcdi_fini_evq(eep->ee_enp, eep->ee_index);
575 }
576
577         __checkReturn   efx_rc_t
578 ef10_ev_qprime(
579         __in            efx_evq_t *eep,
580         __in            unsigned int count)
581 {
582         efx_nic_t *enp = eep->ee_enp;
583         uint32_t rptr;
584         efx_dword_t dword;
585
586         rptr = count & eep->ee_mask;
587
588         if (enp->en_nic_cfg.enc_bug35388_workaround) {
589                 EFX_STATIC_ASSERT(EFX_EVQ_MINNEVS >
590                     (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
591                 EFX_STATIC_ASSERT(EFX_EVQ_MAXNEVS <
592                     (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
593
594                 EFX_POPULATE_DWORD_2(dword,
595                     ERF_DD_EVQ_IND_RPTR_FLAGS,
596                     EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
597                     ERF_DD_EVQ_IND_RPTR,
598                     (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
599                 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
600                     &dword, B_FALSE);
601
602                 EFX_POPULATE_DWORD_2(dword,
603                     ERF_DD_EVQ_IND_RPTR_FLAGS,
604                     EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
605                     ERF_DD_EVQ_IND_RPTR,
606                     rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
607                 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
608                     &dword, B_FALSE);
609         } else {
610                 EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
611                 EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
612                     &dword, B_FALSE);
613         }
614
615         return (0);
616 }
617
618 static  __checkReturn   efx_rc_t
619 efx_mcdi_driver_event(
620         __in            efx_nic_t *enp,
621         __in            uint32_t evq,
622         __in            efx_qword_t data)
623 {
624         efx_mcdi_req_t req;
625         uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
626                             MC_CMD_DRIVER_EVENT_OUT_LEN)];
627         efx_rc_t rc;
628
629         req.emr_cmd = MC_CMD_DRIVER_EVENT;
630         req.emr_in_buf = payload;
631         req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
632         req.emr_out_buf = payload;
633         req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
634
635         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
636
637         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
638             EFX_QWORD_FIELD(data, EFX_DWORD_0));
639         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
640             EFX_QWORD_FIELD(data, EFX_DWORD_1));
641
642         efx_mcdi_execute(enp, &req);
643
644         if (req.emr_rc != 0) {
645                 rc = req.emr_rc;
646                 goto fail1;
647         }
648
649         return (0);
650
651 fail1:
652         EFSYS_PROBE1(fail1, efx_rc_t, rc);
653
654         return (rc);
655 }
656
657                         void
658 ef10_ev_qpost(
659         __in    efx_evq_t *eep,
660         __in    uint16_t data)
661 {
662         efx_nic_t *enp = eep->ee_enp;
663         efx_qword_t event;
664
665         EFX_POPULATE_QWORD_3(event,
666             ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
667             ESF_DZ_DRV_SUB_CODE, 0,
668             ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
669
670         (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
671 }
672
673         __checkReturn   efx_rc_t
674 ef10_ev_qmoderate(
675         __in            efx_evq_t *eep,
676         __in            unsigned int us)
677 {
678         efx_nic_t *enp = eep->ee_enp;
679         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
680         efx_dword_t dword;
681         uint32_t mode;
682         efx_rc_t rc;
683
684         /* Check that hardware and MCDI use the same timer MODE values */
685         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_DIS ==
686             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_DIS);
687         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_IMMED_START ==
688             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_IMMED_START);
689         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_TRIG_START ==
690             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_TRIG_START);
691         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_INT_HLDOFF ==
692             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_INT_HLDOFF);
693
694         if (us > encp->enc_evq_timer_max_us) {
695                 rc = EINVAL;
696                 goto fail1;
697         }
698
699         /* If the value is zero then disable the timer */
700         if (us == 0) {
701                 mode = FFE_CZ_TIMER_MODE_DIS;
702         } else {
703                 mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
704         }
705
706         if (encp->enc_bug61265_workaround) {
707                 uint32_t ns = us * 1000;
708
709                 rc = efx_mcdi_set_evq_tmr(enp, eep->ee_index, mode, ns);
710                 if (rc != 0)
711                         goto fail2;
712         } else {
713                 unsigned int ticks;
714
715                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
716                         goto fail3;
717
718                 if (encp->enc_bug35388_workaround) {
719                         EFX_POPULATE_DWORD_3(dword,
720                             ERF_DD_EVQ_IND_TIMER_FLAGS,
721                             EFE_DD_EVQ_IND_TIMER_FLAGS,
722                             ERF_DD_EVQ_IND_TIMER_MODE, mode,
723                             ERF_DD_EVQ_IND_TIMER_VAL, ticks);
724                         EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
725                             eep->ee_index, &dword, 0);
726                 } else {
727                         EFX_POPULATE_DWORD_2(dword,
728                             ERF_DZ_TC_TIMER_MODE, mode,
729                             ERF_DZ_TC_TIMER_VAL, ticks);
730                         EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_TMR_REG,
731                             eep->ee_index, &dword, 0);
732                 }
733         }
734
735         return (0);
736
737 fail3:
738         EFSYS_PROBE(fail3);
739 fail2:
740         EFSYS_PROBE(fail2);
741 fail1:
742         EFSYS_PROBE1(fail1, efx_rc_t, rc);
743
744         return (rc);
745 }
746
747
748 #if EFSYS_OPT_QSTATS
749                         void
750 ef10_ev_qstats_update(
751         __in                            efx_evq_t *eep,
752         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
753 {
754         unsigned int id;
755
756         for (id = 0; id < EV_NQSTATS; id++) {
757                 efsys_stat_t *essp = &stat[id];
758
759                 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
760                 eep->ee_stat[id] = 0;
761         }
762 }
763 #endif /* EFSYS_OPT_QSTATS */
764
765
766 static  __checkReturn   boolean_t
767 ef10_ev_rx(
768         __in            efx_evq_t *eep,
769         __in            efx_qword_t *eqp,
770         __in            const efx_ev_callbacks_t *eecp,
771         __in_opt        void *arg)
772 {
773         efx_nic_t *enp = eep->ee_enp;
774         uint32_t size;
775         uint32_t label;
776         uint32_t mac_class;
777         uint32_t eth_tag_class;
778         uint32_t l3_class;
779         uint32_t l4_class;
780         uint32_t next_read_lbits;
781         uint16_t flags;
782         boolean_t cont;
783         boolean_t should_abort;
784         efx_evq_rxq_state_t *eersp;
785         unsigned int desc_count;
786         unsigned int last_used_id;
787
788         EFX_EV_QSTAT_INCR(eep, EV_RX);
789
790         /* Discard events after RXQ/TXQ errors */
791         if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
792                 return (B_FALSE);
793
794         /* Basic packet information */
795         size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
796         next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
797         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
798         eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
799         mac_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
800         l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
801         l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
802         cont = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT);
803
804         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
805                 /* Drop this event */
806                 return (B_FALSE);
807         }
808         flags = 0;
809
810         if (cont != 0) {
811                 /*
812                  * This may be part of a scattered frame, or it may be a
813                  * truncated frame if scatter is disabled on this RXQ.
814                  * Overlength frames can be received if e.g. a VF is configured
815                  * for 1500 MTU but connected to a port set to 9000 MTU
816                  * (see bug56567).
817                  * FIXME: There is not yet any driver that supports scatter on
818                  * Huntington.  Scatter support is required for OSX.
819                  */
820                 flags |= EFX_PKT_CONT;
821         }
822
823         if (mac_class == ESE_DZ_MAC_CLASS_UCAST)
824                 flags |= EFX_PKT_UNICAST;
825
826         /* Increment the count of descriptors read */
827         eersp = &eep->ee_rxq_state[label];
828         desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
829             EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
830         eersp->eers_rx_read_ptr += desc_count;
831
832         /*
833          * FIXME: add error checking to make sure this a batched event.
834          * This could also be an aborted scatter, see Bug36629.
835          */
836         if (desc_count > 1) {
837                 EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
838                 flags |= EFX_PKT_PREFIX_LEN;
839         }
840
841         /* Calculate the index of the last descriptor consumed */
842         last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
843
844         /* Check for errors that invalidate checksum and L3/L4 fields */
845         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
846                 /* RX frame truncated (error flag is misnamed) */
847                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
848                 flags |= EFX_DISCARD;
849                 goto deliver;
850         }
851         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
852                 /* Bad Ethernet frame CRC */
853                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
854                 flags |= EFX_DISCARD;
855                 goto deliver;
856         }
857         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {
858                 /*
859                  * Hardware parse failed, due to malformed headers
860                  * or headers that are too long for the parser.
861                  * Headers and checksums must be validated by the host.
862                  */
863                 /* TODO: EFX_EV_QSTAT_INCR(eep, EV_RX_PARSE_INCOMPLETE); */
864                 goto deliver;
865         }
866
867         if ((eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN1) ||
868             (eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN2)) {
869                 flags |= EFX_PKT_VLAN_TAGGED;
870         }
871
872         switch (l3_class) {
873         case ESE_DZ_L3_CLASS_IP4:
874         case ESE_DZ_L3_CLASS_IP4_FRAG:
875                 flags |= EFX_PKT_IPV4;
876                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR)) {
877                         EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
878                 } else {
879                         flags |= EFX_CKSUM_IPV4;
880                 }
881
882                 if (l4_class == ESE_DZ_L4_CLASS_TCP) {
883                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
884                         flags |= EFX_PKT_TCP;
885                 } else if (l4_class == ESE_DZ_L4_CLASS_UDP) {
886                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
887                         flags |= EFX_PKT_UDP;
888                 } else {
889                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);
890                 }
891                 break;
892
893         case ESE_DZ_L3_CLASS_IP6:
894         case ESE_DZ_L3_CLASS_IP6_FRAG:
895                 flags |= EFX_PKT_IPV6;
896
897                 if (l4_class == ESE_DZ_L4_CLASS_TCP) {
898                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
899                         flags |= EFX_PKT_TCP;
900                 } else if (l4_class == ESE_DZ_L4_CLASS_UDP) {
901                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
902                         flags |= EFX_PKT_UDP;
903                 } else {
904                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);
905                 }
906                 break;
907
908         default:
909                 EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);
910                 break;
911         }
912
913         if (flags & (EFX_PKT_TCP | EFX_PKT_UDP)) {
914                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR)) {
915                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
916                 } else {
917                         flags |= EFX_CKSUM_TCPUDP;
918                 }
919         }
920
921 deliver:
922         /* If we're not discarding the packet then it is ok */
923         if (~flags & EFX_DISCARD)
924                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
925
926         EFSYS_ASSERT(eecp->eec_rx != NULL);
927         should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
928
929         return (should_abort);
930 }
931
932 static  __checkReturn   boolean_t
933 ef10_ev_tx(
934         __in            efx_evq_t *eep,
935         __in            efx_qword_t *eqp,
936         __in            const efx_ev_callbacks_t *eecp,
937         __in_opt        void *arg)
938 {
939         efx_nic_t *enp = eep->ee_enp;
940         uint32_t id;
941         uint32_t label;
942         boolean_t should_abort;
943
944         EFX_EV_QSTAT_INCR(eep, EV_TX);
945
946         /* Discard events after RXQ/TXQ errors */
947         if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
948                 return (B_FALSE);
949
950         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
951                 /* Drop this event */
952                 return (B_FALSE);
953         }
954
955         /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
956         id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
957         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
958
959         EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
960
961         EFSYS_ASSERT(eecp->eec_tx != NULL);
962         should_abort = eecp->eec_tx(arg, label, id);
963
964         return (should_abort);
965 }
966
967 static  __checkReturn   boolean_t
968 ef10_ev_driver(
969         __in            efx_evq_t *eep,
970         __in            efx_qword_t *eqp,
971         __in            const efx_ev_callbacks_t *eecp,
972         __in_opt        void *arg)
973 {
974         unsigned int code;
975         boolean_t should_abort;
976
977         EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
978         should_abort = B_FALSE;
979
980         code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
981         switch (code) {
982         case ESE_DZ_DRV_TIMER_EV: {
983                 uint32_t id;
984
985                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
986
987                 EFSYS_ASSERT(eecp->eec_timer != NULL);
988                 should_abort = eecp->eec_timer(arg, id);
989                 break;
990         }
991
992         case ESE_DZ_DRV_WAKE_UP_EV: {
993                 uint32_t id;
994
995                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
996
997                 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
998                 should_abort = eecp->eec_wake_up(arg, id);
999                 break;
1000         }
1001
1002         case ESE_DZ_DRV_START_UP_EV:
1003                 EFSYS_ASSERT(eecp->eec_initialized != NULL);
1004                 should_abort = eecp->eec_initialized(arg);
1005                 break;
1006
1007         default:
1008                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
1009                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1010                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1011                 break;
1012         }
1013
1014         return (should_abort);
1015 }
1016
1017 static  __checkReturn   boolean_t
1018 ef10_ev_drv_gen(
1019         __in            efx_evq_t *eep,
1020         __in            efx_qword_t *eqp,
1021         __in            const efx_ev_callbacks_t *eecp,
1022         __in_opt        void *arg)
1023 {
1024         uint32_t data;
1025         boolean_t should_abort;
1026
1027         EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
1028         should_abort = B_FALSE;
1029
1030         data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
1031         if (data >= ((uint32_t)1 << 16)) {
1032                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
1033                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1034                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1035
1036                 return (B_TRUE);
1037         }
1038
1039         EFSYS_ASSERT(eecp->eec_software != NULL);
1040         should_abort = eecp->eec_software(arg, (uint16_t)data);
1041
1042         return (should_abort);
1043 }
1044
1045 static  __checkReturn   boolean_t
1046 ef10_ev_mcdi(
1047         __in            efx_evq_t *eep,
1048         __in            efx_qword_t *eqp,
1049         __in            const efx_ev_callbacks_t *eecp,
1050         __in_opt        void *arg)
1051 {
1052         efx_nic_t *enp = eep->ee_enp;
1053         unsigned int code;
1054         boolean_t should_abort = B_FALSE;
1055
1056         EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
1057
1058         code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
1059         switch (code) {
1060         case MCDI_EVENT_CODE_BADSSERT:
1061                 efx_mcdi_ev_death(enp, EINTR);
1062                 break;
1063
1064         case MCDI_EVENT_CODE_CMDDONE:
1065                 efx_mcdi_ev_cpl(enp,
1066                     MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
1067                     MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
1068                     MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
1069                 break;
1070
1071 #if EFSYS_OPT_MCDI_PROXY_AUTH
1072         case MCDI_EVENT_CODE_PROXY_RESPONSE:
1073                 /*
1074                  * This event notifies a function that an authorization request
1075                  * has been processed. If the request was authorized then the
1076                  * function can now re-send the original MCDI request.
1077                  * See SF-113652-SW "SR-IOV Proxied Network Access Control".
1078                  */
1079                 efx_mcdi_ev_proxy_response(enp,
1080                     MCDI_EV_FIELD(eqp, PROXY_RESPONSE_HANDLE),
1081                     MCDI_EV_FIELD(eqp, PROXY_RESPONSE_RC));
1082                 break;
1083 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
1084
1085         case MCDI_EVENT_CODE_LINKCHANGE: {
1086                 efx_link_mode_t link_mode;
1087
1088                 ef10_phy_link_ev(enp, eqp, &link_mode);
1089                 should_abort = eecp->eec_link_change(arg, link_mode);
1090                 break;
1091         }
1092
1093         case MCDI_EVENT_CODE_SENSOREVT: {
1094 #if EFSYS_OPT_MON_STATS
1095                 efx_mon_stat_t id;
1096                 efx_mon_stat_value_t value;
1097                 efx_rc_t rc;
1098
1099                 /* Decode monitor stat for MCDI sensor (if supported) */
1100                 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
1101                         /* Report monitor stat change */
1102                         should_abort = eecp->eec_monitor(arg, id, value);
1103                 } else if (rc == ENOTSUP) {
1104                         should_abort = eecp->eec_exception(arg,
1105                                 EFX_EXCEPTION_UNKNOWN_SENSOREVT,
1106                                 MCDI_EV_FIELD(eqp, DATA));
1107                 } else {
1108                         EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
1109                 }
1110 #endif
1111                 break;
1112         }
1113
1114         case MCDI_EVENT_CODE_SCHEDERR:
1115                 /* Informational only */
1116                 break;
1117
1118         case MCDI_EVENT_CODE_REBOOT:
1119                 /* Falcon/Siena only (should not been seen with Huntington). */
1120                 efx_mcdi_ev_death(enp, EIO);
1121                 break;
1122
1123         case MCDI_EVENT_CODE_MC_REBOOT:
1124                 /* MC_REBOOT event is used for Huntington (EF10) and later. */
1125                 efx_mcdi_ev_death(enp, EIO);
1126                 break;
1127
1128         case MCDI_EVENT_CODE_MAC_STATS_DMA:
1129 #if EFSYS_OPT_MAC_STATS
1130                 if (eecp->eec_mac_stats != NULL) {
1131                         eecp->eec_mac_stats(arg,
1132                             MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
1133                 }
1134 #endif
1135                 break;
1136
1137         case MCDI_EVENT_CODE_FWALERT: {
1138                 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
1139
1140                 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
1141                         should_abort = eecp->eec_exception(arg,
1142                                 EFX_EXCEPTION_FWALERT_SRAM,
1143                                 MCDI_EV_FIELD(eqp, FWALERT_DATA));
1144                 else
1145                         should_abort = eecp->eec_exception(arg,
1146                                 EFX_EXCEPTION_UNKNOWN_FWALERT,
1147                                 MCDI_EV_FIELD(eqp, DATA));
1148                 break;
1149         }
1150
1151         case MCDI_EVENT_CODE_TX_ERR: {
1152                 /*
1153                  * After a TXQ error is detected, firmware sends a TX_ERR event.
1154                  * This may be followed by TX completions (which we discard),
1155                  * and then finally by a TX_FLUSH event. Firmware destroys the
1156                  * TXQ automatically after sending the TX_FLUSH event.
1157                  */
1158                 enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
1159
1160                 EFSYS_PROBE2(tx_descq_err,
1161                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1162                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1163
1164                 /* Inform the driver that a reset is required. */
1165                 eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
1166                     MCDI_EV_FIELD(eqp, TX_ERR_DATA));
1167                 break;
1168         }
1169
1170         case MCDI_EVENT_CODE_TX_FLUSH: {
1171                 uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
1172
1173                 /*
1174                  * EF10 firmware sends two TX_FLUSH events: one to the txq's
1175                  * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
1176                  * We want to wait for all completions, so ignore the events
1177                  * with TX_FLUSH_TO_DRIVER.
1178                  */
1179                 if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
1180                         should_abort = B_FALSE;
1181                         break;
1182                 }
1183
1184                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
1185
1186                 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
1187
1188                 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
1189                 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
1190                 break;
1191         }
1192
1193         case MCDI_EVENT_CODE_RX_ERR: {
1194                 /*
1195                  * After an RXQ error is detected, firmware sends an RX_ERR
1196                  * event. This may be followed by RX events (which we discard),
1197                  * and then finally by an RX_FLUSH event. Firmware destroys the
1198                  * RXQ automatically after sending the RX_FLUSH event.
1199                  */
1200                 enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
1201
1202                 EFSYS_PROBE2(rx_descq_err,
1203                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1204                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1205
1206                 /* Inform the driver that a reset is required. */
1207                 eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
1208                     MCDI_EV_FIELD(eqp, RX_ERR_DATA));
1209                 break;
1210         }
1211
1212         case MCDI_EVENT_CODE_RX_FLUSH: {
1213                 uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
1214
1215                 /*
1216                  * EF10 firmware sends two RX_FLUSH events: one to the rxq's
1217                  * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
1218                  * We want to wait for all completions, so ignore the events
1219                  * with RX_FLUSH_TO_DRIVER.
1220                  */
1221                 if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
1222                         should_abort = B_FALSE;
1223                         break;
1224                 }
1225
1226                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
1227
1228                 EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
1229
1230                 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
1231                 should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
1232                 break;
1233         }
1234
1235         default:
1236                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
1237                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1238                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1239                 break;
1240         }
1241
1242         return (should_abort);
1243 }
1244
1245                 void
1246 ef10_ev_rxlabel_init(
1247         __in            efx_evq_t *eep,
1248         __in            efx_rxq_t *erp,
1249         __in            unsigned int label)
1250 {
1251         efx_evq_rxq_state_t *eersp;
1252
1253         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
1254         eersp = &eep->ee_rxq_state[label];
1255
1256         EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
1257
1258         eersp->eers_rx_read_ptr = 0;
1259         eersp->eers_rx_mask = erp->er_mask;
1260 }
1261
1262                 void
1263 ef10_ev_rxlabel_fini(
1264         __in            efx_evq_t *eep,
1265         __in            unsigned int label)
1266 {
1267         efx_evq_rxq_state_t *eersp;
1268
1269         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
1270         eersp = &eep->ee_rxq_state[label];
1271
1272         EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
1273
1274         eersp->eers_rx_read_ptr = 0;
1275         eersp->eers_rx_mask = 0;
1276 }
1277
1278 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */