common/sfc_efx/base: merge versions of init EvQ wrappers
[dpdk.git] / drivers / common / sfc_efx / base / ef10_ev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2012-2019 Solarflare Communications Inc.
5  */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9 #if EFSYS_OPT_MON_STATS
10 #include "mcdi_mon.h"
11 #endif
12
13 #if EFX_OPTS_EF10()
14
15 /*
16  * Non-interrupting event queue requires interrrupting event queue to
17  * refer to for wake-up events even if wake ups are never used.
18  * It could be even non-allocated event queue.
19  */
20 #define EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX  (0)
21
22 static  __checkReturn   boolean_t
23 ef10_ev_rx(
24         __in            efx_evq_t *eep,
25         __in            efx_qword_t *eqp,
26         __in            const efx_ev_callbacks_t *eecp,
27         __in_opt        void *arg);
28
29 static  __checkReturn   boolean_t
30 ef10_ev_tx(
31         __in            efx_evq_t *eep,
32         __in            efx_qword_t *eqp,
33         __in            const efx_ev_callbacks_t *eecp,
34         __in_opt        void *arg);
35
36 static  __checkReturn   boolean_t
37 ef10_ev_driver(
38         __in            efx_evq_t *eep,
39         __in            efx_qword_t *eqp,
40         __in            const efx_ev_callbacks_t *eecp,
41         __in_opt        void *arg);
42
43 static  __checkReturn   boolean_t
44 ef10_ev_drv_gen(
45         __in            efx_evq_t *eep,
46         __in            efx_qword_t *eqp,
47         __in            const efx_ev_callbacks_t *eecp,
48         __in_opt        void *arg);
49
50 static  __checkReturn   boolean_t
51 ef10_ev_mcdi(
52         __in            efx_evq_t *eep,
53         __in            efx_qword_t *eqp,
54         __in            const efx_ev_callbacks_t *eecp,
55         __in_opt        void *arg);
56
57
58 static  __checkReturn   efx_rc_t
59 efx_mcdi_set_evq_tmr(
60         __in            efx_nic_t *enp,
61         __in            uint32_t instance,
62         __in            uint32_t mode,
63         __in            uint32_t timer_ns)
64 {
65         efx_mcdi_req_t req;
66         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_EVQ_TMR_IN_LEN,
67                 MC_CMD_SET_EVQ_TMR_OUT_LEN);
68         efx_rc_t rc;
69
70         req.emr_cmd = MC_CMD_SET_EVQ_TMR;
71         req.emr_in_buf = payload;
72         req.emr_in_length = MC_CMD_SET_EVQ_TMR_IN_LEN;
73         req.emr_out_buf = payload;
74         req.emr_out_length = MC_CMD_SET_EVQ_TMR_OUT_LEN;
75
76         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_INSTANCE, instance);
77         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_LOAD_REQ_NS, timer_ns);
78         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_RELOAD_REQ_NS, timer_ns);
79         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_MODE, mode);
80
81         efx_mcdi_execute(enp, &req);
82
83         if (req.emr_rc != 0) {
84                 rc = req.emr_rc;
85                 goto fail1;
86         }
87
88         if (req.emr_out_length_used < MC_CMD_SET_EVQ_TMR_OUT_LEN) {
89                 rc = EMSGSIZE;
90                 goto fail2;
91         }
92
93         return (0);
94
95 fail2:
96         EFSYS_PROBE(fail2);
97 fail1:
98         EFSYS_PROBE1(fail1, efx_rc_t, rc);
99
100         return (rc);
101 }
102
103
104         __checkReturn   efx_rc_t
105 ef10_ev_init(
106         __in            efx_nic_t *enp)
107 {
108         _NOTE(ARGUNUSED(enp))
109         return (0);
110 }
111
112                         void
113 ef10_ev_fini(
114         __in            efx_nic_t *enp)
115 {
116         _NOTE(ARGUNUSED(enp))
117 }
118
119         __checkReturn   efx_rc_t
120 ef10_ev_qcreate(
121         __in            efx_nic_t *enp,
122         __in            unsigned int index,
123         __in            efsys_mem_t *esmp,
124         __in            size_t ndescs,
125         __in            uint32_t id,
126         __in            uint32_t us,
127         __in            uint32_t flags,
128         __in            efx_evq_t *eep)
129 {
130         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
131         uint32_t irq;
132         efx_rc_t rc;
133         boolean_t low_latency;
134
135         _NOTE(ARGUNUSED(id))    /* buftbl id managed by MC */
136
137         /*
138          * NO_CONT_EV mode is only requested from the firmware when creating
139          * receive queues, but here it needs to be specified at event queue
140          * creation, as the event handler needs to know which format is in use.
141          *
142          * If EFX_EVQ_FLAGS_NO_CONT_EV is specified, all receive queues for this
143          * event queue will be created in NO_CONT_EV mode.
144          *
145          * See SF-109306-TC 5.11 "Events for RXQs in NO_CONT_EV mode".
146          */
147         if (flags & EFX_EVQ_FLAGS_NO_CONT_EV) {
148                 if (enp->en_nic_cfg.enc_no_cont_ev_mode_supported == B_FALSE) {
149                         rc = EINVAL;
150                         goto fail1;
151                 }
152         }
153
154         /* Set up the handler table */
155         eep->ee_rx      = ef10_ev_rx;
156         eep->ee_tx      = ef10_ev_tx;
157         eep->ee_driver  = ef10_ev_driver;
158         eep->ee_drv_gen = ef10_ev_drv_gen;
159         eep->ee_mcdi    = ef10_ev_mcdi;
160
161         /* Set up the event queue */
162         /* INIT_EVQ expects function-relative vector number */
163         if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
164             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT) {
165                 irq = index;
166         } else if (index == EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX) {
167                 irq = index;
168                 flags = (flags & ~EFX_EVQ_FLAGS_NOTIFY_MASK) |
169                     EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
170         } else {
171                 irq = EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX;
172         }
173
174         /*
175          * Interrupts may be raised for events immediately after the queue is
176          * created. See bug58606.
177          */
178
179         /*
180          * On Huntington we need to specify the settings to use.
181          * If event queue type in flags is auto, we favour throughput
182          * if the adapter is running virtualization supporting firmware
183          * (i.e. the full featured firmware variant)
184          * and latency otherwise. The Ethernet Virtual Bridging
185          * capability is used to make this decision. (Note though that
186          * the low latency firmware variant is also best for
187          * throughput and corresponding type should be specified
188          * to choose it.)
189          *
190          * If FW supports EvQ types (e.g. on Medford and Medford2) the
191          * type which is specified in flags is passed to FW to make the
192          * decision and low_latency hint is ignored.
193          */
194         low_latency = encp->enc_datapath_cap_evb ? 0 : 1;
195         rc = efx_mcdi_init_evq(enp, index, esmp, ndescs, irq, us, flags,
196             low_latency);
197         if (rc != 0)
198                 goto fail2;
199
200         return (0);
201
202 fail2:
203         EFSYS_PROBE(fail2);
204 fail1:
205         EFSYS_PROBE1(fail1, efx_rc_t, rc);
206
207         return (rc);
208 }
209
210                         void
211 ef10_ev_qdestroy(
212         __in            efx_evq_t *eep)
213 {
214         efx_nic_t *enp = eep->ee_enp;
215
216         EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
217
218         (void) efx_mcdi_fini_evq(enp, eep->ee_index);
219 }
220
221         __checkReturn   efx_rc_t
222 ef10_ev_qprime(
223         __in            efx_evq_t *eep,
224         __in            unsigned int count)
225 {
226         efx_nic_t *enp = eep->ee_enp;
227         uint32_t rptr;
228         efx_dword_t dword;
229
230         rptr = count & eep->ee_mask;
231
232         if (enp->en_nic_cfg.enc_bug35388_workaround) {
233                 EFX_STATIC_ASSERT(EF10_EVQ_MINNEVS >
234                     (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
235                 EFX_STATIC_ASSERT(EF10_EVQ_MAXNEVS <
236                     (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
237
238                 EFX_POPULATE_DWORD_2(dword,
239                     ERF_DD_EVQ_IND_RPTR_FLAGS,
240                     EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
241                     ERF_DD_EVQ_IND_RPTR,
242                     (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
243                 EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
244                     &dword, B_FALSE);
245
246                 EFX_POPULATE_DWORD_2(dword,
247                     ERF_DD_EVQ_IND_RPTR_FLAGS,
248                     EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
249                     ERF_DD_EVQ_IND_RPTR,
250                     rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
251                 EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
252                     &dword, B_FALSE);
253         } else {
254                 EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
255                 EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
256                     &dword, B_FALSE);
257         }
258
259         return (0);
260 }
261
262 static  __checkReturn   efx_rc_t
263 efx_mcdi_driver_event(
264         __in            efx_nic_t *enp,
265         __in            uint32_t evq,
266         __in            efx_qword_t data)
267 {
268         efx_mcdi_req_t req;
269         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRIVER_EVENT_IN_LEN,
270                 MC_CMD_DRIVER_EVENT_OUT_LEN);
271         efx_rc_t rc;
272
273         req.emr_cmd = MC_CMD_DRIVER_EVENT;
274         req.emr_in_buf = payload;
275         req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
276         req.emr_out_buf = payload;
277         req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
278
279         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
280
281         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
282             EFX_QWORD_FIELD(data, EFX_DWORD_0));
283         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
284             EFX_QWORD_FIELD(data, EFX_DWORD_1));
285
286         efx_mcdi_execute(enp, &req);
287
288         if (req.emr_rc != 0) {
289                 rc = req.emr_rc;
290                 goto fail1;
291         }
292
293         return (0);
294
295 fail1:
296         EFSYS_PROBE1(fail1, efx_rc_t, rc);
297
298         return (rc);
299 }
300
301                         void
302 ef10_ev_qpost(
303         __in    efx_evq_t *eep,
304         __in    uint16_t data)
305 {
306         efx_nic_t *enp = eep->ee_enp;
307         efx_qword_t event;
308
309         EFX_POPULATE_QWORD_3(event,
310             ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
311             ESF_DZ_DRV_SUB_CODE, 0,
312             ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
313
314         (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
315 }
316
317         __checkReturn   efx_rc_t
318 ef10_ev_qmoderate(
319         __in            efx_evq_t *eep,
320         __in            unsigned int us)
321 {
322         efx_nic_t *enp = eep->ee_enp;
323         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
324         efx_dword_t dword;
325         uint32_t mode;
326         efx_rc_t rc;
327
328         /* Check that hardware and MCDI use the same timer MODE values */
329         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_DIS ==
330             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_DIS);
331         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_IMMED_START ==
332             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_IMMED_START);
333         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_TRIG_START ==
334             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_TRIG_START);
335         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_INT_HLDOFF ==
336             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_INT_HLDOFF);
337
338         if (us > encp->enc_evq_timer_max_us) {
339                 rc = EINVAL;
340                 goto fail1;
341         }
342
343         /* If the value is zero then disable the timer */
344         if (us == 0) {
345                 mode = FFE_CZ_TIMER_MODE_DIS;
346         } else {
347                 mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
348         }
349
350         if (encp->enc_bug61265_workaround) {
351                 uint32_t ns = us * 1000;
352
353                 rc = efx_mcdi_set_evq_tmr(enp, eep->ee_index, mode, ns);
354                 if (rc != 0)
355                         goto fail2;
356         } else {
357                 unsigned int ticks;
358
359                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
360                         goto fail3;
361
362                 if (encp->enc_bug35388_workaround) {
363                         EFX_POPULATE_DWORD_3(dword,
364                             ERF_DD_EVQ_IND_TIMER_FLAGS,
365                             EFE_DD_EVQ_IND_TIMER_FLAGS,
366                             ERF_DD_EVQ_IND_TIMER_MODE, mode,
367                             ERF_DD_EVQ_IND_TIMER_VAL, ticks);
368                         EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT,
369                             eep->ee_index, &dword, 0);
370                 } else {
371                         /*
372                          * NOTE: The TMR_REL field introduced in Medford2 is
373                          * ignored on earlier EF10 controllers. See bug66418
374                          * comment 9 for details.
375                          */
376                         EFX_POPULATE_DWORD_3(dword,
377                             ERF_DZ_TC_TIMER_MODE, mode,
378                             ERF_DZ_TC_TIMER_VAL, ticks,
379                             ERF_FZ_TC_TMR_REL_VAL, ticks);
380                         EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_TMR_REG,
381                             eep->ee_index, &dword, 0);
382                 }
383         }
384
385         return (0);
386
387 fail3:
388         EFSYS_PROBE(fail3);
389 fail2:
390         EFSYS_PROBE(fail2);
391 fail1:
392         EFSYS_PROBE1(fail1, efx_rc_t, rc);
393
394         return (rc);
395 }
396
397
398 #if EFSYS_OPT_QSTATS
399                         void
400 ef10_ev_qstats_update(
401         __in                            efx_evq_t *eep,
402         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
403 {
404         unsigned int id;
405
406         for (id = 0; id < EV_NQSTATS; id++) {
407                 efsys_stat_t *essp = &stat[id];
408
409                 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
410                 eep->ee_stat[id] = 0;
411         }
412 }
413 #endif /* EFSYS_OPT_QSTATS */
414
415 #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
416
417 static  __checkReturn   boolean_t
418 ef10_ev_rx_packed_stream(
419         __in            efx_evq_t *eep,
420         __in            efx_qword_t *eqp,
421         __in            const efx_ev_callbacks_t *eecp,
422         __in_opt        void *arg)
423 {
424         uint32_t label;
425         uint32_t pkt_count_lbits;
426         uint16_t flags;
427         boolean_t should_abort;
428         efx_evq_rxq_state_t *eersp;
429         unsigned int pkt_count;
430         unsigned int current_id;
431         boolean_t new_buffer;
432
433         pkt_count_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
434         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
435         new_buffer = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_ROTATE);
436
437         flags = 0;
438
439         eersp = &eep->ee_rxq_state[label];
440
441         /*
442          * RX_DSC_PTR_LBITS has least significant bits of the global
443          * (not per-buffer) packet counter. It is guaranteed that
444          * maximum number of completed packets fits in lbits-mask.
445          * So, modulo lbits-mask arithmetic should be used to calculate
446          * packet counter increment.
447          */
448         pkt_count = (pkt_count_lbits - eersp->eers_rx_stream_npackets) &
449             EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
450         eersp->eers_rx_stream_npackets += pkt_count;
451
452         if (new_buffer) {
453                 flags |= EFX_PKT_PACKED_STREAM_NEW_BUFFER;
454 #if EFSYS_OPT_RX_PACKED_STREAM
455                 /*
456                  * If both packed stream and equal stride super-buffer
457                  * modes are compiled in, in theory credits should be
458                  * be maintained for packed stream only, but right now
459                  * these modes are not distinguished in the event queue
460                  * Rx queue state and it is OK to increment the counter
461                  * regardless (it might be event cheaper than branching
462                  * since neighbour structure member are updated as well).
463                  */
464                 eersp->eers_rx_packed_stream_credits++;
465 #endif
466                 eersp->eers_rx_read_ptr++;
467         }
468         current_id = eersp->eers_rx_read_ptr & eersp->eers_rx_mask;
469
470         /* Check for errors that invalidate checksum and L3/L4 fields */
471         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TRUNC_ERR) != 0) {
472                 /* RX frame truncated */
473                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
474                 flags |= EFX_DISCARD;
475                 goto deliver;
476         }
477         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
478                 /* Bad Ethernet frame CRC */
479                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
480                 flags |= EFX_DISCARD;
481                 goto deliver;
482         }
483
484         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {
485                 EFX_EV_QSTAT_INCR(eep, EV_RX_PARSE_INCOMPLETE);
486                 flags |= EFX_PKT_PACKED_STREAM_PARSE_INCOMPLETE;
487                 goto deliver;
488         }
489
490         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR))
491                 EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
492
493         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR))
494                 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
495
496 deliver:
497         /* If we're not discarding the packet then it is ok */
498         if (~flags & EFX_DISCARD)
499                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
500
501         EFSYS_ASSERT(eecp->eec_rx_ps != NULL);
502         should_abort = eecp->eec_rx_ps(arg, label, current_id, pkt_count,
503             flags);
504
505         return (should_abort);
506 }
507
508 #endif /* EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER */
509
510 static  __checkReturn   boolean_t
511 ef10_ev_rx(
512         __in            efx_evq_t *eep,
513         __in            efx_qword_t *eqp,
514         __in            const efx_ev_callbacks_t *eecp,
515         __in_opt        void *arg)
516 {
517         efx_nic_t *enp = eep->ee_enp;
518         uint32_t size;
519         uint32_t label;
520         uint32_t mac_class;
521         uint32_t eth_tag_class;
522         uint32_t l3_class;
523         uint32_t l4_class;
524         uint32_t next_read_lbits;
525         uint16_t flags;
526         boolean_t cont;
527         boolean_t should_abort;
528         efx_evq_rxq_state_t *eersp;
529         unsigned int desc_count;
530         unsigned int last_used_id;
531
532         EFX_EV_QSTAT_INCR(eep, EV_RX);
533
534         /* Discard events after RXQ/TXQ errors, or hardware not available */
535         if (enp->en_reset_flags &
536             (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
537                 return (B_FALSE);
538
539         /* Basic packet information */
540         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
541         eersp = &eep->ee_rxq_state[label];
542
543 #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
544         /*
545          * Packed stream events are very different,
546          * so handle them separately
547          */
548         if (eersp->eers_rx_packed_stream)
549                 return (ef10_ev_rx_packed_stream(eep, eqp, eecp, arg));
550 #endif
551
552         size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
553         cont = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT);
554         next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
555         eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
556         mac_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
557         l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
558
559         /*
560          * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is only
561          * 2 bits wide on Medford2. Check it is safe to use the Medford2 field
562          * and values for all EF10 controllers.
563          */
564         EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN == ESF_DE_RX_L4_CLASS_LBN);
565         EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
566         EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
567         EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN == ESE_DE_L4_CLASS_UNKNOWN);
568
569         l4_class = EFX_QWORD_FIELD(*eqp, ESF_FZ_RX_L4_CLASS);
570
571         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
572                 /* Drop this event */
573                 return (B_FALSE);
574         }
575         flags = 0;
576
577         if (cont != 0) {
578                 /*
579                  * This may be part of a scattered frame, or it may be a
580                  * truncated frame if scatter is disabled on this RXQ.
581                  * Overlength frames can be received if e.g. a VF is configured
582                  * for 1500 MTU but connected to a port set to 9000 MTU
583                  * (see bug56567).
584                  * FIXME: There is not yet any driver that supports scatter on
585                  * Huntington.  Scatter support is required for OSX.
586                  */
587                 flags |= EFX_PKT_CONT;
588         }
589
590         if (mac_class == ESE_DZ_MAC_CLASS_UCAST)
591                 flags |= EFX_PKT_UNICAST;
592
593         /*
594          * Increment the count of descriptors read.
595          *
596          * In NO_CONT_EV mode, RX_DSC_PTR_LBITS is actually a packet count, but
597          * when scatter is disabled, there is only one descriptor per packet and
598          * so it can be treated the same.
599          *
600          * TODO: Support scatter in NO_CONT_EV mode.
601          */
602         desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
603             EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
604         eersp->eers_rx_read_ptr += desc_count;
605
606         /* Calculate the index of the last descriptor consumed */
607         last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
608
609         if (eep->ee_flags & EFX_EVQ_FLAGS_NO_CONT_EV) {
610                 if (desc_count > 1)
611                         EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
612
613                 /* Always read the length from the prefix in NO_CONT_EV mode. */
614                 flags |= EFX_PKT_PREFIX_LEN;
615
616                 /*
617                  * Check for an aborted scatter, signalled by the ABORT bit in
618                  * NO_CONT_EV mode. The ABORT bit was not used before NO_CONT_EV
619                  * mode was added as it was broken in Huntington silicon.
620                  */
621                 if (EFX_QWORD_FIELD(*eqp, ESF_EZ_RX_ABORT) != 0) {
622                         flags |= EFX_DISCARD;
623                         goto deliver;
624                 }
625         } else if (desc_count > 1) {
626                 /*
627                  * FIXME: add error checking to make sure this a batched event.
628                  * This could also be an aborted scatter, see Bug36629.
629                  */
630                 EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
631                 flags |= EFX_PKT_PREFIX_LEN;
632         }
633
634         /* Check for errors that invalidate checksum and L3/L4 fields */
635         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TRUNC_ERR) != 0) {
636                 /* RX frame truncated */
637                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
638                 flags |= EFX_DISCARD;
639                 goto deliver;
640         }
641         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
642                 /* Bad Ethernet frame CRC */
643                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
644                 flags |= EFX_DISCARD;
645                 goto deliver;
646         }
647         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {
648                 /*
649                  * Hardware parse failed, due to malformed headers
650                  * or headers that are too long for the parser.
651                  * Headers and checksums must be validated by the host.
652                  */
653                 EFX_EV_QSTAT_INCR(eep, EV_RX_PARSE_INCOMPLETE);
654                 goto deliver;
655         }
656
657         if ((eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN1) ||
658             (eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN2)) {
659                 flags |= EFX_PKT_VLAN_TAGGED;
660         }
661
662         switch (l3_class) {
663         case ESE_DZ_L3_CLASS_IP4:
664         case ESE_DZ_L3_CLASS_IP4_FRAG:
665                 flags |= EFX_PKT_IPV4;
666                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR)) {
667                         EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
668                 } else {
669                         flags |= EFX_CKSUM_IPV4;
670                 }
671
672                 /*
673                  * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is
674                  * only 2 bits wide on Medford2. Check it is safe to use the
675                  * Medford2 field and values for all EF10 controllers.
676                  */
677                 EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN ==
678                     ESF_DE_RX_L4_CLASS_LBN);
679                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
680                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
681                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN ==
682                     ESE_DE_L4_CLASS_UNKNOWN);
683
684                 if (l4_class == ESE_FZ_L4_CLASS_TCP) {
685                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
686                         flags |= EFX_PKT_TCP;
687                 } else if (l4_class == ESE_FZ_L4_CLASS_UDP) {
688                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
689                         flags |= EFX_PKT_UDP;
690                 } else {
691                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);
692                 }
693                 break;
694
695         case ESE_DZ_L3_CLASS_IP6:
696         case ESE_DZ_L3_CLASS_IP6_FRAG:
697                 flags |= EFX_PKT_IPV6;
698
699                 /*
700                  * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is
701                  * only 2 bits wide on Medford2. Check it is safe to use the
702                  * Medford2 field and values for all EF10 controllers.
703                  */
704                 EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN ==
705                     ESF_DE_RX_L4_CLASS_LBN);
706                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
707                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
708                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN ==
709                     ESE_DE_L4_CLASS_UNKNOWN);
710
711                 if (l4_class == ESE_FZ_L4_CLASS_TCP) {
712                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
713                         flags |= EFX_PKT_TCP;
714                 } else if (l4_class == ESE_FZ_L4_CLASS_UDP) {
715                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
716                         flags |= EFX_PKT_UDP;
717                 } else {
718                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);
719                 }
720                 break;
721
722         default:
723                 EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);
724                 break;
725         }
726
727         if (flags & (EFX_PKT_TCP | EFX_PKT_UDP)) {
728                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR)) {
729                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
730                 } else {
731                         flags |= EFX_CKSUM_TCPUDP;
732                 }
733         }
734
735 deliver:
736         /* If we're not discarding the packet then it is ok */
737         if (~flags & EFX_DISCARD)
738                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
739
740         EFSYS_ASSERT(eecp->eec_rx != NULL);
741         should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
742
743         return (should_abort);
744 }
745
746 static  __checkReturn   boolean_t
747 ef10_ev_tx(
748         __in            efx_evq_t *eep,
749         __in            efx_qword_t *eqp,
750         __in            const efx_ev_callbacks_t *eecp,
751         __in_opt        void *arg)
752 {
753         efx_nic_t *enp = eep->ee_enp;
754         uint32_t id;
755         uint32_t label;
756         boolean_t should_abort;
757
758         EFX_EV_QSTAT_INCR(eep, EV_TX);
759
760         /* Discard events after RXQ/TXQ errors, or hardware not available */
761         if (enp->en_reset_flags &
762             (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
763                 return (B_FALSE);
764
765         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
766                 /* Drop this event */
767                 return (B_FALSE);
768         }
769
770         /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
771         id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
772         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
773
774         EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
775
776         EFSYS_ASSERT(eecp->eec_tx != NULL);
777         should_abort = eecp->eec_tx(arg, label, id);
778
779         return (should_abort);
780 }
781
782 static  __checkReturn   boolean_t
783 ef10_ev_driver(
784         __in            efx_evq_t *eep,
785         __in            efx_qword_t *eqp,
786         __in            const efx_ev_callbacks_t *eecp,
787         __in_opt        void *arg)
788 {
789         unsigned int code;
790         boolean_t should_abort;
791
792         EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
793         should_abort = B_FALSE;
794
795         code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
796         switch (code) {
797         case ESE_DZ_DRV_TIMER_EV: {
798                 uint32_t id;
799
800                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
801
802                 EFSYS_ASSERT(eecp->eec_timer != NULL);
803                 should_abort = eecp->eec_timer(arg, id);
804                 break;
805         }
806
807         case ESE_DZ_DRV_WAKE_UP_EV: {
808                 uint32_t id;
809
810                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
811
812                 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
813                 should_abort = eecp->eec_wake_up(arg, id);
814                 break;
815         }
816
817         case ESE_DZ_DRV_START_UP_EV:
818                 EFSYS_ASSERT(eecp->eec_initialized != NULL);
819                 should_abort = eecp->eec_initialized(arg);
820                 break;
821
822         default:
823                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
824                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
825                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
826                 break;
827         }
828
829         return (should_abort);
830 }
831
832 static  __checkReturn   boolean_t
833 ef10_ev_drv_gen(
834         __in            efx_evq_t *eep,
835         __in            efx_qword_t *eqp,
836         __in            const efx_ev_callbacks_t *eecp,
837         __in_opt        void *arg)
838 {
839         uint32_t data;
840         boolean_t should_abort;
841
842         EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
843         should_abort = B_FALSE;
844
845         data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
846         if (data >= ((uint32_t)1 << 16)) {
847                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
848                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
849                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
850
851                 return (B_TRUE);
852         }
853
854         EFSYS_ASSERT(eecp->eec_software != NULL);
855         should_abort = eecp->eec_software(arg, (uint16_t)data);
856
857         return (should_abort);
858 }
859
860 static  __checkReturn   boolean_t
861 ef10_ev_mcdi(
862         __in            efx_evq_t *eep,
863         __in            efx_qword_t *eqp,
864         __in            const efx_ev_callbacks_t *eecp,
865         __in_opt        void *arg)
866 {
867         efx_nic_t *enp = eep->ee_enp;
868         unsigned int code;
869         boolean_t should_abort = B_FALSE;
870
871         EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
872
873         code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
874         switch (code) {
875         case MCDI_EVENT_CODE_BADSSERT:
876                 efx_mcdi_ev_death(enp, EINTR);
877                 break;
878
879         case MCDI_EVENT_CODE_CMDDONE:
880                 efx_mcdi_ev_cpl(enp,
881                     MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
882                     MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
883                     MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
884                 break;
885
886 #if EFSYS_OPT_MCDI_PROXY_AUTH
887         case MCDI_EVENT_CODE_PROXY_RESPONSE:
888                 /*
889                  * This event notifies a function that an authorization request
890                  * has been processed. If the request was authorized then the
891                  * function can now re-send the original MCDI request.
892                  * See SF-113652-SW "SR-IOV Proxied Network Access Control".
893                  */
894                 efx_mcdi_ev_proxy_response(enp,
895                     MCDI_EV_FIELD(eqp, PROXY_RESPONSE_HANDLE),
896                     MCDI_EV_FIELD(eqp, PROXY_RESPONSE_RC));
897                 break;
898 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
899
900 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
901         case MCDI_EVENT_CODE_PROXY_REQUEST:
902                 efx_mcdi_ev_proxy_request(enp,
903                         MCDI_EV_FIELD(eqp, PROXY_REQUEST_BUFF_INDEX));
904                 break;
905 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
906
907         case MCDI_EVENT_CODE_LINKCHANGE: {
908                 efx_link_mode_t link_mode;
909
910                 ef10_phy_link_ev(enp, eqp, &link_mode);
911                 should_abort = eecp->eec_link_change(arg, link_mode);
912                 break;
913         }
914
915         case MCDI_EVENT_CODE_SENSOREVT: {
916 #if EFSYS_OPT_MON_STATS
917                 efx_mon_stat_t id;
918                 efx_mon_stat_value_t value;
919                 efx_rc_t rc;
920
921                 /* Decode monitor stat for MCDI sensor (if supported) */
922                 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
923                         /* Report monitor stat change */
924                         should_abort = eecp->eec_monitor(arg, id, value);
925                 } else if (rc == ENOTSUP) {
926                         should_abort = eecp->eec_exception(arg,
927                                 EFX_EXCEPTION_UNKNOWN_SENSOREVT,
928                                 MCDI_EV_FIELD(eqp, DATA));
929                 } else {
930                         EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
931                 }
932 #endif
933                 break;
934         }
935
936         case MCDI_EVENT_CODE_SCHEDERR:
937                 /* Informational only */
938                 break;
939
940         case MCDI_EVENT_CODE_REBOOT:
941                 /* Falcon/Siena only (should not been seen with Huntington). */
942                 efx_mcdi_ev_death(enp, EIO);
943                 break;
944
945         case MCDI_EVENT_CODE_MC_REBOOT:
946                 /* MC_REBOOT event is used for Huntington (EF10) and later. */
947                 efx_mcdi_ev_death(enp, EIO);
948                 break;
949
950         case MCDI_EVENT_CODE_MAC_STATS_DMA:
951 #if EFSYS_OPT_MAC_STATS
952                 if (eecp->eec_mac_stats != NULL) {
953                         eecp->eec_mac_stats(arg,
954                             MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
955                 }
956 #endif
957                 break;
958
959         case MCDI_EVENT_CODE_FWALERT: {
960                 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
961
962                 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
963                         should_abort = eecp->eec_exception(arg,
964                                 EFX_EXCEPTION_FWALERT_SRAM,
965                                 MCDI_EV_FIELD(eqp, FWALERT_DATA));
966                 else
967                         should_abort = eecp->eec_exception(arg,
968                                 EFX_EXCEPTION_UNKNOWN_FWALERT,
969                                 MCDI_EV_FIELD(eqp, DATA));
970                 break;
971         }
972
973         case MCDI_EVENT_CODE_TX_ERR: {
974                 /*
975                  * After a TXQ error is detected, firmware sends a TX_ERR event.
976                  * This may be followed by TX completions (which we discard),
977                  * and then finally by a TX_FLUSH event. Firmware destroys the
978                  * TXQ automatically after sending the TX_FLUSH event.
979                  */
980                 enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
981
982                 EFSYS_PROBE2(tx_descq_err,
983                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
984                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
985
986                 /* Inform the driver that a reset is required. */
987                 eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
988                     MCDI_EV_FIELD(eqp, TX_ERR_DATA));
989                 break;
990         }
991
992         case MCDI_EVENT_CODE_TX_FLUSH: {
993                 uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
994
995                 /*
996                  * EF10 firmware sends two TX_FLUSH events: one to the txq's
997                  * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
998                  * We want to wait for all completions, so ignore the events
999                  * with TX_FLUSH_TO_DRIVER.
1000                  */
1001                 if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
1002                         should_abort = B_FALSE;
1003                         break;
1004                 }
1005
1006                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
1007
1008                 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
1009
1010                 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
1011                 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
1012                 break;
1013         }
1014
1015         case MCDI_EVENT_CODE_RX_ERR: {
1016                 /*
1017                  * After an RXQ error is detected, firmware sends an RX_ERR
1018                  * event. This may be followed by RX events (which we discard),
1019                  * and then finally by an RX_FLUSH event. Firmware destroys the
1020                  * RXQ automatically after sending the RX_FLUSH event.
1021                  */
1022                 enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
1023
1024                 EFSYS_PROBE2(rx_descq_err,
1025                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1026                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1027
1028                 /* Inform the driver that a reset is required. */
1029                 eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
1030                     MCDI_EV_FIELD(eqp, RX_ERR_DATA));
1031                 break;
1032         }
1033
1034         case MCDI_EVENT_CODE_RX_FLUSH: {
1035                 uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
1036
1037                 /*
1038                  * EF10 firmware sends two RX_FLUSH events: one to the rxq's
1039                  * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
1040                  * We want to wait for all completions, so ignore the events
1041                  * with RX_FLUSH_TO_DRIVER.
1042                  */
1043                 if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
1044                         should_abort = B_FALSE;
1045                         break;
1046                 }
1047
1048                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
1049
1050                 EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
1051
1052                 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
1053                 should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
1054                 break;
1055         }
1056
1057         default:
1058                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
1059                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
1060                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
1061                 break;
1062         }
1063
1064         return (should_abort);
1065 }
1066
1067                 void
1068 ef10_ev_rxlabel_init(
1069         __in            efx_evq_t *eep,
1070         __in            efx_rxq_t *erp,
1071         __in            unsigned int label,
1072         __in            efx_rxq_type_t type)
1073 {
1074         efx_evq_rxq_state_t *eersp;
1075 #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
1076         boolean_t packed_stream = (type == EFX_RXQ_TYPE_PACKED_STREAM);
1077         boolean_t es_super_buffer = (type == EFX_RXQ_TYPE_ES_SUPER_BUFFER);
1078 #endif
1079
1080         _NOTE(ARGUNUSED(type))
1081         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
1082         eersp = &eep->ee_rxq_state[label];
1083
1084         EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
1085
1086 #if EFSYS_OPT_RX_PACKED_STREAM
1087         /*
1088          * For packed stream modes, the very first event will
1089          * have a new buffer flag set, so it will be incremented,
1090          * yielding the correct pointer. That results in a simpler
1091          * code than trying to detect start-of-the-world condition
1092          * in the event handler.
1093          */
1094         eersp->eers_rx_read_ptr = packed_stream ? ~0 : 0;
1095 #else
1096         eersp->eers_rx_read_ptr = 0;
1097 #endif
1098         eersp->eers_rx_mask = erp->er_mask;
1099 #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
1100         eersp->eers_rx_stream_npackets = 0;
1101         eersp->eers_rx_packed_stream = packed_stream || es_super_buffer;
1102 #endif
1103 #if EFSYS_OPT_RX_PACKED_STREAM
1104         if (packed_stream) {
1105                 eersp->eers_rx_packed_stream_credits = (eep->ee_mask + 1) /
1106                     EFX_DIV_ROUND_UP(EFX_RX_PACKED_STREAM_MEM_PER_CREDIT,
1107                     EFX_RX_PACKED_STREAM_MIN_PACKET_SPACE);
1108                 EFSYS_ASSERT3U(eersp->eers_rx_packed_stream_credits, !=, 0);
1109                 /*
1110                  * A single credit is allocated to the queue when it is started.
1111                  * It is immediately spent by the first packet which has NEW
1112                  * BUFFER flag set, though, but still we shall take into
1113                  * account, as to not wrap around the maximum number of credits
1114                  * accidentally
1115                  */
1116                 eersp->eers_rx_packed_stream_credits--;
1117                 EFSYS_ASSERT3U(eersp->eers_rx_packed_stream_credits, <=,
1118                     EFX_RX_PACKED_STREAM_MAX_CREDITS);
1119         }
1120 #endif
1121 }
1122
1123                 void
1124 ef10_ev_rxlabel_fini(
1125         __in            efx_evq_t *eep,
1126         __in            unsigned int label)
1127 {
1128         efx_evq_rxq_state_t *eersp;
1129
1130         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
1131         eersp = &eep->ee_rxq_state[label];
1132
1133         EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
1134
1135         eersp->eers_rx_read_ptr = 0;
1136         eersp->eers_rx_mask = 0;
1137 #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
1138         eersp->eers_rx_stream_npackets = 0;
1139         eersp->eers_rx_packed_stream = B_FALSE;
1140 #endif
1141 #if EFSYS_OPT_RX_PACKED_STREAM
1142         eersp->eers_rx_packed_stream_credits = 0;
1143 #endif
1144 }
1145
1146 #endif  /* EFX_OPTS_EF10() */