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