]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/sfxge/common/hunt_ev.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / sfxge / common / hunt_ev.c
1 /*-
2  * Copyright (c) 2012-2015 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 "efsys.h"
35 #include "efx.h"
36 #include "efx_types.h"
37 #include "efx_regs.h"
38 #include "efx_impl.h"
39 #if EFSYS_OPT_MON_STATS
40 #include "mcdi_mon.h"
41 #endif
42
43 #if EFSYS_OPT_HUNTINGTON
44
45 #if EFSYS_OPT_QSTATS
46 #define EFX_EV_QSTAT_INCR(_eep, _stat)                                  \
47         do {                                                            \
48                 (_eep)->ee_stat[_stat]++;                               \
49         _NOTE(CONSTANTCONDITION)                                        \
50         } while (B_FALSE)
51 #else
52 #define EFX_EV_QSTAT_INCR(_eep, _stat)
53 #endif
54
55
56 static  __checkReturn   boolean_t
57 hunt_ev_rx(
58         __in            efx_evq_t *eep,
59         __in            efx_qword_t *eqp,
60         __in            const efx_ev_callbacks_t *eecp,
61         __in_opt        void *arg);
62
63 static  __checkReturn   boolean_t
64 hunt_ev_tx(
65         __in            efx_evq_t *eep,
66         __in            efx_qword_t *eqp,
67         __in            const efx_ev_callbacks_t *eecp,
68         __in_opt        void *arg);
69
70 static  __checkReturn   boolean_t
71 hunt_ev_driver(
72         __in            efx_evq_t *eep,
73         __in            efx_qword_t *eqp,
74         __in            const efx_ev_callbacks_t *eecp,
75         __in_opt        void *arg);
76
77 static  __checkReturn   boolean_t
78 hunt_ev_drv_gen(
79         __in            efx_evq_t *eep,
80         __in            efx_qword_t *eqp,
81         __in            const efx_ev_callbacks_t *eecp,
82         __in_opt        void *arg);
83
84 static  __checkReturn   boolean_t
85 hunt_ev_mcdi(
86         __in            efx_evq_t *eep,
87         __in            efx_qword_t *eqp,
88         __in            const efx_ev_callbacks_t *eecp,
89         __in_opt        void *arg);
90
91
92 static  __checkReturn   int
93 efx_mcdi_init_evq(
94         __in            efx_nic_t *enp,
95         __in            unsigned int instance,
96         __in            efsys_mem_t *esmp,
97         __in            size_t nevs,
98         __in            uint32_t irq,
99         __out_opt       uint32_t *irqp)
100 {
101         efx_mcdi_req_t req;
102         uint8_t payload[
103             MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
104                 MC_CMD_INIT_EVQ_OUT_LEN)];
105         efx_qword_t *dma_addr;
106         uint64_t addr;
107         int npages;
108         int i;
109         int supports_rx_batching;
110         int rc;
111
112         npages = EFX_EVQ_NBUFS(nevs);
113         if (MC_CMD_INIT_EVQ_IN_LEN(npages) > MC_CMD_INIT_EVQ_IN_LENMAX) {
114                 rc = EINVAL;
115                 goto fail1;
116         }
117
118         (void) memset(payload, 0, sizeof (payload));
119         req.emr_cmd = MC_CMD_INIT_EVQ;
120         req.emr_in_buf = payload;
121         req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
122         req.emr_out_buf = payload;
123         req.emr_out_length = MC_CMD_INIT_EVQ_OUT_LEN;
124
125         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_SIZE, nevs);
126         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_INSTANCE, instance);
127         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_IRQ_NUM, irq);
128
129         /*
130          * On Huntington RX and TX event batching can only be requested
131          * together (even if the datapath firmware doesn't actually support RX
132          * batching).
133          * Cut through is incompatible with RX batching and so enabling cut
134          * through disables RX batching (but it does not affect TX batching).
135          *
136          * So always enable RX and TX event batching, and enable cut through
137          * if RX event batching isn't supported (i.e. on low latency firmware).
138          */
139         supports_rx_batching = enp->en_nic_cfg.enc_rx_batching_enabled ? 1 : 0;
140         MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_IN_FLAGS,
141             INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
142             INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
143             INIT_EVQ_IN_FLAG_INT_ARMD, 0,
144             INIT_EVQ_IN_FLAG_CUT_THRU, !supports_rx_batching,
145             INIT_EVQ_IN_FLAG_RX_MERGE, 1,
146             INIT_EVQ_IN_FLAG_TX_MERGE, 1);
147
148         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
149             MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
150         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, 0);
151         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, 0);
152
153         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_MODE,
154             MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
155         MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_THRSHLD, 0);
156
157         dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_IN_DMA_ADDR);
158         addr = EFSYS_MEM_ADDR(esmp);
159
160         for (i = 0; i < npages; i++) {
161                 EFX_POPULATE_QWORD_2(*dma_addr,
162                     EFX_DWORD_1, (uint32_t)(addr >> 32),
163                     EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
164
165                 dma_addr++;
166                 addr += EFX_BUF_SIZE;
167         }
168
169         efx_mcdi_execute(enp, &req);
170
171         if (req.emr_rc != 0) {
172                 rc = req.emr_rc;
173                 goto fail2;
174         }
175
176         if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) {
177                 rc = EMSGSIZE;
178                 goto fail3;
179         }
180
181         if (irqp != NULL)
182                 *irqp = MCDI_OUT_DWORD(req, INIT_EVQ_OUT_IRQ);
183
184         return (0);
185
186 fail3:
187         EFSYS_PROBE(fail3);
188 fail2:
189         EFSYS_PROBE(fail2);
190 fail1:
191         EFSYS_PROBE1(fail1, int, rc);
192
193         return (rc);
194 }
195
196 static  __checkReturn   int
197 efx_mcdi_fini_evq(
198         __in            efx_nic_t *enp,
199         __in            uint32_t instance)
200 {
201         efx_mcdi_req_t req;
202         uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
203                             MC_CMD_FINI_EVQ_OUT_LEN)];
204         int rc;
205
206         (void) memset(payload, 0, sizeof (payload));
207         req.emr_cmd = MC_CMD_FINI_EVQ;
208         req.emr_in_buf = payload;
209         req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
210         req.emr_out_buf = payload;
211         req.emr_out_length = MC_CMD_FINI_EVQ_OUT_LEN;
212
213         MCDI_IN_SET_DWORD(req, FINI_EVQ_IN_INSTANCE, instance);
214
215         efx_mcdi_execute(enp, &req);
216
217         if (req.emr_rc != 0) {
218                 rc = req.emr_rc;
219                 goto fail1;
220         }
221
222         return (0);
223
224 fail1:
225         EFSYS_PROBE1(fail1, int, rc);
226
227         return (rc);
228 }
229
230
231
232         __checkReturn   int
233 hunt_ev_init(
234         __in            efx_nic_t *enp)
235 {
236         _NOTE(ARGUNUSED(enp))
237         return (0);
238 }
239
240                         void
241 hunt_ev_fini(
242         __in            efx_nic_t *enp)
243 {
244         _NOTE(ARGUNUSED(enp))
245 }
246
247         __checkReturn   int
248 hunt_ev_qcreate(
249         __in            efx_nic_t *enp,
250         __in            unsigned int index,
251         __in            efsys_mem_t *esmp,
252         __in            size_t n,
253         __in            uint32_t id,
254         __in            efx_evq_t *eep)
255 {
256         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
257         uint32_t irq;
258         int rc;
259
260         _NOTE(ARGUNUSED(id))    /* buftbl id managed by MC */
261         EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
262         EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
263
264         if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
265                 rc = EINVAL;
266                 goto fail1;
267         }
268
269         if (index >= encp->enc_evq_limit) {
270                 rc = EINVAL;
271                 goto fail2;
272         }
273
274         /* Set up the handler table */
275         eep->ee_rx      = hunt_ev_rx;
276         eep->ee_tx      = hunt_ev_tx;
277         eep->ee_driver  = hunt_ev_driver;
278         eep->ee_drv_gen = hunt_ev_drv_gen;
279         eep->ee_mcdi    = hunt_ev_mcdi;
280
281         /*
282          * Set up the event queue
283          * NOTE: ignore the returned IRQ param as firmware does not set it.
284          */
285         irq = index;    /* INIT_EVQ expects function-relative vector number */
286         if ((rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, NULL)) != 0)
287                 goto fail3;
288
289         return (0);
290
291 fail3:
292         EFSYS_PROBE(fail3);
293 fail2:
294         EFSYS_PROBE(fail2);
295 fail1:
296         EFSYS_PROBE1(fail1, int, rc);
297
298         return (rc);
299 }
300
301                         void
302 hunt_ev_qdestroy(
303         __in            efx_evq_t *eep)
304 {
305         efx_nic_t *enp = eep->ee_enp;
306
307         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
308
309         (void) efx_mcdi_fini_evq(eep->ee_enp, eep->ee_index);
310 }
311
312         __checkReturn   int
313 hunt_ev_qprime(
314         __in            efx_evq_t *eep,
315         __in            unsigned int count)
316 {
317         efx_nic_t *enp = eep->ee_enp;
318         uint32_t rptr;
319         efx_dword_t dword;
320
321         rptr = count & eep->ee_mask;
322
323         if (enp->en_nic_cfg.enc_bug35388_workaround) {
324                 EFX_STATIC_ASSERT(EFX_EVQ_MINNEVS >
325                     (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
326                 EFX_STATIC_ASSERT(EFX_EVQ_MAXNEVS <
327                     (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
328
329                 EFX_POPULATE_DWORD_2(dword,
330                     ERF_DD_EVQ_IND_RPTR_FLAGS,
331                     EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
332                     ERF_DD_EVQ_IND_RPTR,
333                     (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
334                 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
335                     &dword, B_FALSE);
336
337                 EFX_POPULATE_DWORD_2(dword,
338                     ERF_DD_EVQ_IND_RPTR_FLAGS,
339                     EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
340                     ERF_DD_EVQ_IND_RPTR,
341                     rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
342                 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
343                     &dword, B_FALSE);
344         } else {
345                 EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
346                 EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
347                     &dword, B_FALSE);
348         }
349
350         return (0);
351 }
352
353 static  __checkReturn   int
354 efx_mcdi_driver_event(
355         __in            efx_nic_t *enp,
356         __in            uint32_t evq,
357         __in            efx_qword_t data)
358 {
359         efx_mcdi_req_t req;
360         uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
361                             MC_CMD_DRIVER_EVENT_OUT_LEN)];
362         int rc;
363
364         req.emr_cmd = MC_CMD_DRIVER_EVENT;
365         req.emr_in_buf = payload;
366         req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
367         req.emr_out_buf = payload;
368         req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
369
370         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
371
372         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
373             EFX_QWORD_FIELD(data, EFX_DWORD_0));
374         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
375             EFX_QWORD_FIELD(data, EFX_DWORD_1));
376
377         efx_mcdi_execute(enp, &req);
378
379         if (req.emr_rc != 0) {
380                 rc = req.emr_rc;
381                 goto fail1;
382         }
383
384         return (0);
385
386 fail1:
387         EFSYS_PROBE1(fail1, int, rc);
388
389         return (rc);
390 }
391
392                         void
393 hunt_ev_qpost(
394         __in    efx_evq_t *eep,
395         __in    uint16_t data)
396 {
397         efx_nic_t *enp = eep->ee_enp;
398         efx_qword_t event;
399
400         EFX_POPULATE_QWORD_3(event,
401             ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
402             ESF_DZ_DRV_SUB_CODE, 0,
403             ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
404
405         (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
406 }
407
408         __checkReturn   int
409 hunt_ev_qmoderate(
410         __in            efx_evq_t *eep,
411         __in            unsigned int us)
412 {
413         efx_nic_t *enp = eep->ee_enp;
414         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
415         efx_dword_t dword;
416         uint32_t timer_val, mode;
417         int rc;
418
419         if (us > encp->enc_evq_timer_max_us) {
420                 rc = EINVAL;
421                 goto fail1;
422         }
423
424         /* If the value is zero then disable the timer */
425         if (us == 0) {
426                 timer_val = 0;
427                 mode = FFE_CZ_TIMER_MODE_DIS;
428         } else {
429                 /* Calculate the timer value in quanta */
430                 timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
431
432                 /* Moderation value is base 0 so we need to deduct 1 */
433                 if (timer_val > 0)
434                         timer_val--;
435
436                 mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
437         }
438
439         if (encp->enc_bug35388_workaround) {
440                 EFX_POPULATE_DWORD_3(dword,
441                     ERF_DD_EVQ_IND_TIMER_FLAGS,
442                     EFE_DD_EVQ_IND_TIMER_FLAGS,
443                     ERF_DD_EVQ_IND_TIMER_MODE, mode,
444                     ERF_DD_EVQ_IND_TIMER_VAL, timer_val);
445                 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
446                     eep->ee_index, &dword, 0);
447         } else {
448                 EFX_POPULATE_DWORD_2(dword,
449                     FRF_CZ_TC_TIMER_MODE, mode,
450                     FRF_CZ_TC_TIMER_VAL, timer_val);
451                 EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
452                     eep->ee_index, &dword, 0);
453         }
454
455         return (0);
456
457 fail1:
458         EFSYS_PROBE1(fail1, int, rc);
459
460         return (rc);
461 }
462
463
464 #if EFSYS_OPT_QSTATS
465                         void
466 hunt_ev_qstats_update(
467         __in                            efx_evq_t *eep,
468         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
469 {
470         /*
471          * TBD: Consider a common Siena/Huntington function.  The code is
472          * essentially identical.
473          */
474         unsigned int id;
475
476         for (id = 0; id < EV_NQSTATS; id++) {
477                 efsys_stat_t *essp = &stat[id];
478
479                 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
480                 eep->ee_stat[id] = 0;
481         }
482 }
483 #endif /* EFSYS_OPT_QSTATS */
484
485
486 static  __checkReturn   boolean_t
487 hunt_ev_rx(
488         __in            efx_evq_t *eep,
489         __in            efx_qword_t *eqp,
490         __in            const efx_ev_callbacks_t *eecp,
491         __in_opt        void *arg)
492 {
493         efx_nic_t *enp = eep->ee_enp;
494         uint32_t size;
495         boolean_t parse_err;
496         uint32_t label;
497         uint32_t mcast;
498         uint32_t eth_base_class;
499         uint32_t eth_tag_class;
500         uint32_t l3_class;
501         uint32_t l4_class;
502         uint32_t next_read_lbits;
503         boolean_t soft1, soft2;
504         uint16_t flags;
505         boolean_t should_abort;
506         efx_evq_rxq_state_t *eersp;
507         unsigned int desc_count;
508         unsigned int last_used_id;
509
510         EFX_EV_QSTAT_INCR(eep, EV_RX);
511
512         /* Discard events after RXQ/TXQ errors */
513         if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
514                 return (B_FALSE);
515
516         /*
517          * FIXME: likely to be incomplete, incorrect and inefficient.
518          * Improvements in all three areas are required.
519          */
520
521         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
522                 /* Drop this event */
523                 return (B_FALSE);
524         }
525         flags = 0;
526
527         size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
528
529         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT) != 0) {
530                 /*
531                  * FIXME: There is not yet any driver that supports scatter on
532                  * Huntington.  Scatter support is required for OSX.
533                  */
534                 EFSYS_ASSERT(0);
535                 flags |= EFX_PKT_CONT;
536         }
537
538         parse_err = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE) != 0);
539         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
540
541         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
542                 /* Ethernet frame CRC bad */
543                 flags |= EFX_DISCARD;
544         }
545         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC0_ERR) != 0) {
546                 /* IP+TCP, bad CRC in iSCSI header */
547                 flags |= EFX_DISCARD;
548         }
549         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC1_ERR) != 0) {
550                 /* IP+TCP, bad CRC in iSCSI payload or FCoE or FCoIP */
551                 flags |= EFX_DISCARD;
552         }
553         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
554                 /* ECC memory error */
555                 flags |= EFX_DISCARD;
556         }
557
558         /* FIXME: do we need soft bits from RXDP firmware ? */
559         soft1 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT1) != 0);
560         soft2 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT2) != 0);
561
562         mcast = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
563         if (mcast == ESE_DZ_MAC_CLASS_UCAST)
564                 flags |= EFX_PKT_UNICAST;
565
566         eth_base_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_BASE_CLASS);
567         eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
568         l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
569         l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
570
571         /* bottom 4 bits of incremented index (not last desc consumed) */
572         next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
573
574         /* Increment the count of descriptors read */
575         eersp = &eep->ee_rxq_state[label];
576         desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
577             EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
578         eersp->eers_rx_read_ptr += desc_count;
579
580         /*
581          * FIXME: add error checking to make sure this a batched event.
582          * This could also be an aborted scatter, see Bug36629.
583          */
584         if (desc_count > 1) {
585                 EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
586                 flags |= EFX_PKT_PREFIX_LEN;
587         }
588
589         /* Calculate the index of the the last descriptor consumed */
590         last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
591
592         /* EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_OVERRIDE_HOLDOFF); */
593
594         switch (eth_base_class) {
595         case ESE_DZ_ETH_BASE_CLASS_LLC_SNAP:
596         case ESE_DZ_ETH_BASE_CLASS_LLC:
597         case ESE_DZ_ETH_BASE_CLASS_ETH2:
598         default:
599                 break;
600         }
601
602         switch (eth_tag_class) {
603         case ESE_DZ_ETH_TAG_CLASS_RSVD7:
604         case ESE_DZ_ETH_TAG_CLASS_RSVD6:
605         case ESE_DZ_ETH_TAG_CLASS_RSVD5:
606         case ESE_DZ_ETH_TAG_CLASS_RSVD4:
607                 break;
608
609         case ESE_DZ_ETH_TAG_CLASS_RSVD3: /* Triple tagged */
610         case ESE_DZ_ETH_TAG_CLASS_VLAN2: /* Double tagged */
611         case ESE_DZ_ETH_TAG_CLASS_VLAN1: /* VLAN tagged */
612                 flags |= EFX_PKT_VLAN_TAGGED;
613                 break;
614
615         case ESE_DZ_ETH_TAG_CLASS_NONE:
616         default:
617                 break;
618         }
619
620         switch (l3_class) {
621         case ESE_DZ_L3_CLASS_RSVD7: /* Used by firmware for packet overrun */
622                 parse_err = B_TRUE;
623                 flags |= EFX_DISCARD;
624                 break;
625
626         case ESE_DZ_L3_CLASS_ARP:
627         case ESE_DZ_L3_CLASS_FCOE:
628                 break;
629
630         case ESE_DZ_L3_CLASS_IP6_FRAG:
631         case ESE_DZ_L3_CLASS_IP6:
632                 flags |= EFX_PKT_IPV6;
633                 break;
634
635         case ESE_DZ_L3_CLASS_IP4_FRAG:
636         case ESE_DZ_L3_CLASS_IP4:
637                 flags |= EFX_PKT_IPV4;
638                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR) == 0)
639                         flags |= EFX_CKSUM_IPV4;
640                 break;
641
642         case ESE_DZ_L3_CLASS_UNKNOWN:
643         default:
644                 break;
645         }
646
647         switch (l4_class) {
648         case ESE_DZ_L4_CLASS_RSVD7:
649         case ESE_DZ_L4_CLASS_RSVD6:
650         case ESE_DZ_L4_CLASS_RSVD5:
651         case ESE_DZ_L4_CLASS_RSVD4:
652         case ESE_DZ_L4_CLASS_RSVD3:
653                 break;
654
655         case ESE_DZ_L4_CLASS_UDP:
656                 flags |= EFX_PKT_UDP;
657                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
658                         flags |= EFX_CKSUM_TCPUDP;
659                 break;
660
661         case ESE_DZ_L4_CLASS_TCP:
662                 flags |= EFX_PKT_TCP;
663                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
664                         flags |= EFX_CKSUM_TCPUDP;
665                 break;
666
667         case ESE_DZ_L4_CLASS_UNKNOWN:
668         default:
669                 break;
670         }
671
672         /* If we're not discarding the packet then it is ok */
673         if (~flags & EFX_DISCARD)
674                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
675
676         EFSYS_ASSERT(eecp->eec_rx != NULL);
677         should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
678
679         return (should_abort);
680 }
681
682 static  __checkReturn   boolean_t
683 hunt_ev_tx(
684         __in            efx_evq_t *eep,
685         __in            efx_qword_t *eqp,
686         __in            const efx_ev_callbacks_t *eecp,
687         __in_opt        void *arg)
688 {
689         efx_nic_t *enp = eep->ee_enp;
690         uint32_t id;
691         uint32_t label;
692         boolean_t should_abort;
693
694         EFX_EV_QSTAT_INCR(eep, EV_TX);
695
696         /* Discard events after RXQ/TXQ errors */
697         if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
698                 return (B_FALSE);
699
700         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
701                 /* Drop this event */
702                 return (B_FALSE);
703         }
704
705         /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
706         id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
707         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
708
709         EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
710
711         EFSYS_ASSERT(eecp->eec_tx != NULL);
712         should_abort = eecp->eec_tx(arg, label, id);
713
714         return (should_abort);
715 }
716
717 static  __checkReturn   boolean_t
718 hunt_ev_driver(
719         __in            efx_evq_t *eep,
720         __in            efx_qword_t *eqp,
721         __in            const efx_ev_callbacks_t *eecp,
722         __in_opt        void *arg)
723 {
724         unsigned int code;
725         boolean_t should_abort;
726
727         EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
728         should_abort = B_FALSE;
729
730         code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
731         switch (code) {
732         case ESE_DZ_DRV_TIMER_EV: {
733                 uint32_t id;
734
735                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
736
737                 EFSYS_ASSERT(eecp->eec_timer != NULL);
738                 should_abort = eecp->eec_timer(arg, id);
739                 break;
740         }
741
742         case ESE_DZ_DRV_WAKE_UP_EV: {
743                 uint32_t id;
744
745                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
746
747                 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
748                 should_abort = eecp->eec_wake_up(arg, id);
749                 break;
750         }
751
752         case ESE_DZ_DRV_START_UP_EV:
753                 EFSYS_ASSERT(eecp->eec_initialized != NULL);
754                 should_abort = eecp->eec_initialized(arg);
755                 break;
756
757         default:
758                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
759                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
760                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
761                 break;
762         }
763
764         return (should_abort);
765 }
766
767 static  __checkReturn   boolean_t
768 hunt_ev_drv_gen(
769         __in            efx_evq_t *eep,
770         __in            efx_qword_t *eqp,
771         __in            const efx_ev_callbacks_t *eecp,
772         __in_opt        void *arg)
773 {
774         uint32_t data;
775         boolean_t should_abort;
776
777         EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
778         should_abort = B_FALSE;
779
780         data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
781         if (data >= ((uint32_t)1 << 16)) {
782                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
783                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
784                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
785
786                 return (B_TRUE);
787         }
788
789         EFSYS_ASSERT(eecp->eec_software != NULL);
790         should_abort = eecp->eec_software(arg, (uint16_t)data);
791
792         return (should_abort);
793 }
794
795 static  __checkReturn   boolean_t
796 hunt_ev_mcdi(
797         __in            efx_evq_t *eep,
798         __in            efx_qword_t *eqp,
799         __in            const efx_ev_callbacks_t *eecp,
800         __in_opt        void *arg)
801 {
802         efx_nic_t *enp = eep->ee_enp;
803         unsigned code;
804         boolean_t should_abort = B_FALSE;
805
806         EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
807
808         code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
809         switch (code) {
810         case MCDI_EVENT_CODE_BADSSERT:
811                 efx_mcdi_ev_death(enp, EINTR);
812                 break;
813
814         case MCDI_EVENT_CODE_CMDDONE:
815                 efx_mcdi_ev_cpl(enp,
816                     MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
817                     MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
818                     MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
819                 break;
820
821         case MCDI_EVENT_CODE_LINKCHANGE: {
822                 efx_link_mode_t link_mode;
823
824                 hunt_phy_link_ev(enp, eqp, &link_mode);
825                 should_abort = eecp->eec_link_change(arg, link_mode);
826                 break;
827         }
828
829         case MCDI_EVENT_CODE_SENSOREVT: {
830 #if EFSYS_OPT_MON_STATS
831                 efx_mon_stat_t id;
832                 efx_mon_stat_value_t value;
833                 int rc;
834
835                 /* Decode monitor stat for MCDI sensor (if supported) */
836                 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
837                         /* Report monitor stat change */
838                         should_abort = eecp->eec_monitor(arg, id, value);
839                 } else if (rc == ENOTSUP) {
840                         should_abort = eecp->eec_exception(arg,
841                                 EFX_EXCEPTION_UNKNOWN_SENSOREVT,
842                                 MCDI_EV_FIELD(eqp, DATA));
843                 } else {
844                         EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
845                 }
846 #endif
847                 break;
848         }
849
850         case MCDI_EVENT_CODE_SCHEDERR:
851                 /* Informational only */
852                 break;
853
854         case MCDI_EVENT_CODE_REBOOT:
855                 /* Falcon/Siena only (should not been seen with Huntington). */
856                 efx_mcdi_ev_death(enp, EIO);
857                 break;
858
859         case MCDI_EVENT_CODE_MC_REBOOT:
860                 /* MC_REBOOT event is used for Huntington (EF10) and later. */
861                 efx_mcdi_ev_death(enp, EIO);
862                 break;
863
864         case MCDI_EVENT_CODE_MAC_STATS_DMA:
865 #if EFSYS_OPT_MAC_STATS
866                 if (eecp->eec_mac_stats != NULL) {
867                         eecp->eec_mac_stats(arg,
868                             MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
869                 }
870 #endif
871                 break;
872
873         case MCDI_EVENT_CODE_FWALERT: {
874                 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
875
876                 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
877                         should_abort = eecp->eec_exception(arg,
878                                 EFX_EXCEPTION_FWALERT_SRAM,
879                                 MCDI_EV_FIELD(eqp, FWALERT_DATA));
880                 else
881                         should_abort = eecp->eec_exception(arg,
882                                 EFX_EXCEPTION_UNKNOWN_FWALERT,
883                                 MCDI_EV_FIELD(eqp, DATA));
884                 break;
885         }
886
887         case MCDI_EVENT_CODE_TX_ERR: {
888                 /*
889                  * After a TXQ error is detected, firmware sends a TX_ERR event.
890                  * This may be followed by TX completions (which we discard),
891                  * and then finally by a TX_FLUSH event. Firmware destroys the
892                  * TXQ automatically after sending the TX_FLUSH event.
893                  */
894                 enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
895
896                 EFSYS_PROBE1(tx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
897
898                 /* Inform the driver that a reset is required. */
899                 eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
900                     MCDI_EV_FIELD(eqp, TX_ERR_DATA));
901                 break;
902         }
903
904         case MCDI_EVENT_CODE_TX_FLUSH: {
905                 uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
906
907                 /*
908                  * EF10 firmware sends two TX_FLUSH events: one to the txq's
909                  * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
910                  * We want to wait for all completions, so ignore the events
911                  * with TX_FLUSH_TO_DRIVER.
912                  */
913                 if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
914                         should_abort = B_FALSE;
915                         break;
916                 }
917
918                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
919
920                 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
921
922                 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
923                 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
924                 break;
925         }
926
927         case MCDI_EVENT_CODE_RX_ERR: {
928                 /*
929                  * After an RXQ error is detected, firmware sends an RX_ERR
930                  * event. This may be followed by RX events (which we discard),
931                  * and then finally by an RX_FLUSH event. Firmware destroys the
932                  * RXQ automatically after sending the RX_FLUSH event.
933                  */
934                 enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
935
936                 EFSYS_PROBE1(rx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
937
938                 /* Inform the driver that a reset is required. */
939                 eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
940                     MCDI_EV_FIELD(eqp, RX_ERR_DATA));
941                 break;
942         }
943
944         case MCDI_EVENT_CODE_RX_FLUSH: {
945                 uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
946
947                 /*
948                  * EF10 firmware sends two RX_FLUSH events: one to the rxq's
949                  * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
950                  * We want to wait for all completions, so ignore the events
951                  * with RX_FLUSH_TO_DRIVER.
952                  */
953                 if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
954                         should_abort = B_FALSE;
955                         break;
956                 }
957
958                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
959
960                 EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
961
962                 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
963                 should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
964                 break;
965         }
966
967         default:
968                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
969                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
970                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
971                 break;
972         }
973
974         return (should_abort);
975 }
976
977                 void
978 hunt_ev_rxlabel_init(
979         __in            efx_evq_t *eep,
980         __in            efx_rxq_t *erp,
981         __in            unsigned int label)
982 {
983         efx_evq_rxq_state_t *eersp;
984
985         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
986         eersp = &eep->ee_rxq_state[label];
987
988         EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
989
990         eersp->eers_rx_read_ptr = 0;
991         eersp->eers_rx_mask = erp->er_mask;
992 }
993
994                 void
995 hunt_ev_rxlabel_fini(
996         __in            efx_evq_t *eep,
997         __in            unsigned int label)
998 {
999         efx_evq_rxq_state_t *eersp;
1000
1001         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
1002         eersp = &eep->ee_rxq_state[label];
1003
1004         EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
1005
1006         eersp->eers_rx_read_ptr = 0;
1007         eersp->eers_rx_mask = 0;
1008 }
1009
1010 #endif  /* EFSYS_OPT_HUNTINGTON */