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