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