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