net/sfc/base: import SFN7xxx family support
[dpdk.git] / drivers / net / sfc / base / efx_ev.c
1 /*
2  * Copyright (c) 2007-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 "efx.h"
32 #include "efx_impl.h"
33
34 #define EFX_EV_QSTAT_INCR(_eep, _stat)
35
36 #define EFX_EV_PRESENT(_qword)                                          \
37         (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff &&        \
38         EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
39
40
41
42 #if EFSYS_OPT_SIENA
43
44 static  __checkReturn   efx_rc_t
45 siena_ev_init(
46         __in            efx_nic_t *enp);
47
48 static                  void
49 siena_ev_fini(
50         __in            efx_nic_t *enp);
51
52 static  __checkReturn   efx_rc_t
53 siena_ev_qcreate(
54         __in            efx_nic_t *enp,
55         __in            unsigned int index,
56         __in            efsys_mem_t *esmp,
57         __in            size_t n,
58         __in            uint32_t id,
59         __in            uint32_t us,
60         __in            uint32_t flags,
61         __in            efx_evq_t *eep);
62
63 static                  void
64 siena_ev_qdestroy(
65         __in            efx_evq_t *eep);
66
67 static  __checkReturn   efx_rc_t
68 siena_ev_qprime(
69         __in            efx_evq_t *eep,
70         __in            unsigned int count);
71
72 static                  void
73 siena_ev_qpost(
74         __in    efx_evq_t *eep,
75         __in    uint16_t data);
76
77 static  __checkReturn   efx_rc_t
78 siena_ev_qmoderate(
79         __in            efx_evq_t *eep,
80         __in            unsigned int us);
81
82 #endif /* EFSYS_OPT_SIENA */
83
84 #if EFSYS_OPT_SIENA
85 static const efx_ev_ops_t       __efx_ev_siena_ops = {
86         siena_ev_init,                          /* eevo_init */
87         siena_ev_fini,                          /* eevo_fini */
88         siena_ev_qcreate,                       /* eevo_qcreate */
89         siena_ev_qdestroy,                      /* eevo_qdestroy */
90         siena_ev_qprime,                        /* eevo_qprime */
91         siena_ev_qpost,                         /* eevo_qpost */
92         siena_ev_qmoderate,                     /* eevo_qmoderate */
93 };
94 #endif /* EFSYS_OPT_SIENA */
95
96 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
97 static const efx_ev_ops_t       __efx_ev_ef10_ops = {
98         ef10_ev_init,                           /* eevo_init */
99         ef10_ev_fini,                           /* eevo_fini */
100         ef10_ev_qcreate,                        /* eevo_qcreate */
101         ef10_ev_qdestroy,                       /* eevo_qdestroy */
102         ef10_ev_qprime,                         /* eevo_qprime */
103         ef10_ev_qpost,                          /* eevo_qpost */
104         ef10_ev_qmoderate,                      /* eevo_qmoderate */
105 };
106 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
107
108
109         __checkReturn   efx_rc_t
110 efx_ev_init(
111         __in            efx_nic_t *enp)
112 {
113         const efx_ev_ops_t *eevop;
114         efx_rc_t rc;
115
116         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
117         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
118
119         if (enp->en_mod_flags & EFX_MOD_EV) {
120                 rc = EINVAL;
121                 goto fail1;
122         }
123
124         switch (enp->en_family) {
125 #if EFSYS_OPT_SIENA
126         case EFX_FAMILY_SIENA:
127                 eevop = &__efx_ev_siena_ops;
128                 break;
129 #endif /* EFSYS_OPT_SIENA */
130
131 #if EFSYS_OPT_HUNTINGTON
132         case EFX_FAMILY_HUNTINGTON:
133                 eevop = &__efx_ev_ef10_ops;
134                 break;
135 #endif /* EFSYS_OPT_HUNTINGTON */
136
137         default:
138                 EFSYS_ASSERT(0);
139                 rc = ENOTSUP;
140                 goto fail1;
141         }
142
143         EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
144
145         if ((rc = eevop->eevo_init(enp)) != 0)
146                 goto fail2;
147
148         enp->en_eevop = eevop;
149         enp->en_mod_flags |= EFX_MOD_EV;
150         return (0);
151
152 fail2:
153         EFSYS_PROBE(fail2);
154
155 fail1:
156         EFSYS_PROBE1(fail1, efx_rc_t, rc);
157
158         enp->en_eevop = NULL;
159         enp->en_mod_flags &= ~EFX_MOD_EV;
160         return (rc);
161 }
162
163                 void
164 efx_ev_fini(
165         __in    efx_nic_t *enp)
166 {
167         const efx_ev_ops_t *eevop = enp->en_eevop;
168
169         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
170         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
171         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
172         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
173         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
174         EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
175
176         eevop->eevo_fini(enp);
177
178         enp->en_eevop = NULL;
179         enp->en_mod_flags &= ~EFX_MOD_EV;
180 }
181
182
183         __checkReturn   efx_rc_t
184 efx_ev_qcreate(
185         __in            efx_nic_t *enp,
186         __in            unsigned int index,
187         __in            efsys_mem_t *esmp,
188         __in            size_t n,
189         __in            uint32_t id,
190         __in            uint32_t us,
191         __in            uint32_t flags,
192         __deref_out     efx_evq_t **eepp)
193 {
194         const efx_ev_ops_t *eevop = enp->en_eevop;
195         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
196         efx_evq_t *eep;
197         efx_rc_t rc;
198
199         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
200         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
201
202         EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit);
203
204         switch (flags & EFX_EVQ_FLAGS_NOTIFY_MASK) {
205         case EFX_EVQ_FLAGS_NOTIFY_INTERRUPT:
206                 break;
207         case EFX_EVQ_FLAGS_NOTIFY_DISABLED:
208                 if (us != 0) {
209                         rc = EINVAL;
210                         goto fail1;
211                 }
212                 break;
213         default:
214                 rc = EINVAL;
215                 goto fail2;
216         }
217
218         /* Allocate an EVQ object */
219         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
220         if (eep == NULL) {
221                 rc = ENOMEM;
222                 goto fail3;
223         }
224
225         eep->ee_magic = EFX_EVQ_MAGIC;
226         eep->ee_enp = enp;
227         eep->ee_index = index;
228         eep->ee_mask = n - 1;
229         eep->ee_flags = flags;
230         eep->ee_esmp = esmp;
231
232         /*
233          * Set outputs before the queue is created because interrupts may be
234          * raised for events immediately after the queue is created, before the
235          * function call below returns. See bug58606.
236          *
237          * The eepp pointer passed in by the client must therefore point to data
238          * shared with the client's event processing context.
239          */
240         enp->en_ev_qcount++;
241         *eepp = eep;
242
243         if ((rc = eevop->eevo_qcreate(enp, index, esmp, n, id, us, flags,
244             eep)) != 0)
245                 goto fail4;
246
247         return (0);
248
249 fail4:
250         EFSYS_PROBE(fail4);
251
252         *eepp = NULL;
253         enp->en_ev_qcount--;
254         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
255 fail3:
256         EFSYS_PROBE(fail3);
257 fail2:
258         EFSYS_PROBE(fail2);
259 fail1:
260         EFSYS_PROBE1(fail1, efx_rc_t, rc);
261         return (rc);
262 }
263
264                 void
265 efx_ev_qdestroy(
266         __in    efx_evq_t *eep)
267 {
268         efx_nic_t *enp = eep->ee_enp;
269         const efx_ev_ops_t *eevop = enp->en_eevop;
270
271         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
272
273         EFSYS_ASSERT(enp->en_ev_qcount != 0);
274         --enp->en_ev_qcount;
275
276         eevop->eevo_qdestroy(eep);
277
278         /* Free the EVQ object */
279         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
280 }
281
282         __checkReturn   efx_rc_t
283 efx_ev_qprime(
284         __in            efx_evq_t *eep,
285         __in            unsigned int count)
286 {
287         efx_nic_t *enp = eep->ee_enp;
288         const efx_ev_ops_t *eevop = enp->en_eevop;
289         efx_rc_t rc;
290
291         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
292
293         if (!(enp->en_mod_flags & EFX_MOD_INTR)) {
294                 rc = EINVAL;
295                 goto fail1;
296         }
297
298         if ((rc = eevop->eevo_qprime(eep, count)) != 0)
299                 goto fail2;
300
301         return (0);
302
303 fail2:
304         EFSYS_PROBE(fail2);
305 fail1:
306         EFSYS_PROBE1(fail1, efx_rc_t, rc);
307         return (rc);
308 }
309
310         __checkReturn   boolean_t
311 efx_ev_qpending(
312         __in            efx_evq_t *eep,
313         __in            unsigned int count)
314 {
315         size_t offset;
316         efx_qword_t qword;
317
318         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
319
320         offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
321         EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword);
322
323         return (EFX_EV_PRESENT(qword));
324 }
325
326 #define EFX_EV_BATCH    8
327
328                         void
329 efx_ev_qpoll(
330         __in            efx_evq_t *eep,
331         __inout         unsigned int *countp,
332         __in            const efx_ev_callbacks_t *eecp,
333         __in_opt        void *arg)
334 {
335         efx_qword_t ev[EFX_EV_BATCH];
336         unsigned int batch;
337         unsigned int total;
338         unsigned int count;
339         unsigned int index;
340         size_t offset;
341
342         /* Ensure events codes match for EF10 (Huntington/Medford) and Siena */
343         EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_LBN == FSF_AZ_EV_CODE_LBN);
344         EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_WIDTH == FSF_AZ_EV_CODE_WIDTH);
345
346         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_RX_EV == FSE_AZ_EV_CODE_RX_EV);
347         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_TX_EV == FSE_AZ_EV_CODE_TX_EV);
348         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRIVER_EV == FSE_AZ_EV_CODE_DRIVER_EV);
349         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRV_GEN_EV ==
350             FSE_AZ_EV_CODE_DRV_GEN_EV);
351 #if EFSYS_OPT_MCDI
352         EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_MCDI_EV ==
353             FSE_AZ_EV_CODE_MCDI_EVRESPONSE);
354 #endif
355
356         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
357         EFSYS_ASSERT(countp != NULL);
358         EFSYS_ASSERT(eecp != NULL);
359
360         count = *countp;
361         do {
362                 /* Read up until the end of the batch period */
363                 batch = EFX_EV_BATCH - (count & (EFX_EV_BATCH - 1));
364                 offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
365                 for (total = 0; total < batch; ++total) {
366                         EFSYS_MEM_READQ(eep->ee_esmp, offset, &(ev[total]));
367
368                         if (!EFX_EV_PRESENT(ev[total]))
369                                 break;
370
371                         EFSYS_PROBE3(event, unsigned int, eep->ee_index,
372                             uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_1),
373                             uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_0));
374
375                         offset += sizeof (efx_qword_t);
376                 }
377
378                 /* Process the batch of events */
379                 for (index = 0; index < total; ++index) {
380                         boolean_t should_abort;
381                         uint32_t code;
382
383                         EFX_EV_QSTAT_INCR(eep, EV_ALL);
384
385                         code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE);
386                         switch (code) {
387                         case FSE_AZ_EV_CODE_RX_EV:
388                                 should_abort = eep->ee_rx(eep,
389                                     &(ev[index]), eecp, arg);
390                                 break;
391                         case FSE_AZ_EV_CODE_TX_EV:
392                                 should_abort = eep->ee_tx(eep,
393                                     &(ev[index]), eecp, arg);
394                                 break;
395                         case FSE_AZ_EV_CODE_DRIVER_EV:
396                                 should_abort = eep->ee_driver(eep,
397                                     &(ev[index]), eecp, arg);
398                                 break;
399                         case FSE_AZ_EV_CODE_DRV_GEN_EV:
400                                 should_abort = eep->ee_drv_gen(eep,
401                                     &(ev[index]), eecp, arg);
402                                 break;
403 #if EFSYS_OPT_MCDI
404                         case FSE_AZ_EV_CODE_MCDI_EVRESPONSE:
405                                 should_abort = eep->ee_mcdi(eep,
406                                     &(ev[index]), eecp, arg);
407                                 break;
408 #endif
409                         case FSE_AZ_EV_CODE_GLOBAL_EV:
410                                 if (eep->ee_global) {
411                                         should_abort = eep->ee_global(eep,
412                                             &(ev[index]), eecp, arg);
413                                         break;
414                                 }
415                                 /* else fallthrough */
416                         default:
417                                 EFSYS_PROBE3(bad_event,
418                                     unsigned int, eep->ee_index,
419                                     uint32_t,
420                                     EFX_QWORD_FIELD(ev[index], EFX_DWORD_1),
421                                     uint32_t,
422                                     EFX_QWORD_FIELD(ev[index], EFX_DWORD_0));
423
424                                 EFSYS_ASSERT(eecp->eec_exception != NULL);
425                                 (void) eecp->eec_exception(arg,
426                                         EFX_EXCEPTION_EV_ERROR, code);
427                                 should_abort = B_TRUE;
428                         }
429                         if (should_abort) {
430                                 /* Ignore subsequent events */
431                                 total = index + 1;
432                                 break;
433                         }
434                 }
435
436                 /*
437                  * Now that the hardware has most likely moved onto dma'ing
438                  * into the next cache line, clear the processed events. Take
439                  * care to only clear out events that we've processed
440                  */
441                 EFX_SET_QWORD(ev[0]);
442                 offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
443                 for (index = 0; index < total; ++index) {
444                         EFSYS_MEM_WRITEQ(eep->ee_esmp, offset, &(ev[0]));
445                         offset += sizeof (efx_qword_t);
446                 }
447
448                 count += total;
449
450         } while (total == batch);
451
452         *countp = count;
453 }
454
455                         void
456 efx_ev_qpost(
457         __in    efx_evq_t *eep,
458         __in    uint16_t data)
459 {
460         efx_nic_t *enp = eep->ee_enp;
461         const efx_ev_ops_t *eevop = enp->en_eevop;
462
463         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
464
465         EFSYS_ASSERT(eevop != NULL &&
466             eevop->eevo_qpost != NULL);
467
468         eevop->eevo_qpost(eep, data);
469 }
470
471         __checkReturn   efx_rc_t
472 efx_ev_usecs_to_ticks(
473         __in            efx_nic_t *enp,
474         __in            unsigned int us,
475         __out           unsigned int *ticksp)
476 {
477         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
478         unsigned int ticks;
479
480         /* Convert microseconds to a timer tick count */
481         if (us == 0)
482                 ticks = 0;
483         else if (us * 1000 < encp->enc_evq_timer_quantum_ns)
484                 ticks = 1;      /* Never round down to zero */
485         else
486                 ticks = us * 1000 / encp->enc_evq_timer_quantum_ns;
487
488         *ticksp = ticks;
489         return (0);
490 }
491
492         __checkReturn   efx_rc_t
493 efx_ev_qmoderate(
494         __in            efx_evq_t *eep,
495         __in            unsigned int us)
496 {
497         efx_nic_t *enp = eep->ee_enp;
498         const efx_ev_ops_t *eevop = enp->en_eevop;
499         efx_rc_t rc;
500
501         EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
502
503         if ((eep->ee_flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
504             EFX_EVQ_FLAGS_NOTIFY_DISABLED) {
505                 rc = EINVAL;
506                 goto fail1;
507         }
508
509         if ((rc = eevop->eevo_qmoderate(eep, us)) != 0)
510                 goto fail2;
511
512         return (0);
513
514 fail2:
515         EFSYS_PROBE(fail2);
516 fail1:
517         EFSYS_PROBE1(fail1, efx_rc_t, rc);
518         return (rc);
519 }
520
521 #if EFSYS_OPT_SIENA
522
523 static  __checkReturn   efx_rc_t
524 siena_ev_init(
525         __in            efx_nic_t *enp)
526 {
527         efx_oword_t oword;
528
529         /*
530          * Program the event queue for receive and transmit queue
531          * flush events.
532          */
533         EFX_BAR_READO(enp, FR_AZ_DP_CTRL_REG, &oword);
534         EFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0);
535         EFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword);
536
537         return (0);
538
539 }
540
541 static  __checkReturn   boolean_t
542 siena_ev_rx_not_ok(
543         __in            efx_evq_t *eep,
544         __in            efx_qword_t *eqp,
545         __in            uint32_t label,
546         __in            uint32_t id,
547         __inout         uint16_t *flagsp)
548 {
549         boolean_t ignore = B_FALSE;
550
551         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TOBE_DISC) != 0) {
552                 EFX_EV_QSTAT_INCR(eep, EV_RX_TOBE_DISC);
553                 EFSYS_PROBE(tobe_disc);
554                 /*
555                  * Assume this is a unicast address mismatch, unless below
556                  * we find either FSF_AZ_RX_EV_ETH_CRC_ERR or
557                  * EV_RX_PAUSE_FRM_ERR is set.
558                  */
559                 (*flagsp) |= EFX_ADDR_MISMATCH;
560         }
561
562         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_FRM_TRUNC) != 0) {
563                 EFSYS_PROBE2(frm_trunc, uint32_t, label, uint32_t, id);
564                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
565                 (*flagsp) |= EFX_DISCARD;
566
567         }
568
569         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_ETH_CRC_ERR) != 0) {
570                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
571                 EFSYS_PROBE(crc_err);
572                 (*flagsp) &= ~EFX_ADDR_MISMATCH;
573                 (*flagsp) |= EFX_DISCARD;
574         }
575
576         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PAUSE_FRM_ERR) != 0) {
577                 EFX_EV_QSTAT_INCR(eep, EV_RX_PAUSE_FRM_ERR);
578                 EFSYS_PROBE(pause_frm_err);
579                 (*flagsp) &= ~EFX_ADDR_MISMATCH;
580                 (*flagsp) |= EFX_DISCARD;
581         }
582
583         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR) != 0) {
584                 EFX_EV_QSTAT_INCR(eep, EV_RX_BUF_OWNER_ID_ERR);
585                 EFSYS_PROBE(owner_id_err);
586                 (*flagsp) |= EFX_DISCARD;
587         }
588
589         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR) != 0) {
590                 EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
591                 EFSYS_PROBE(ipv4_err);
592                 (*flagsp) &= ~EFX_CKSUM_IPV4;
593         }
594
595         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR) != 0) {
596                 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
597                 EFSYS_PROBE(udp_chk_err);
598                 (*flagsp) &= ~EFX_CKSUM_TCPUDP;
599         }
600
601         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_FRAG_ERR) != 0) {
602                 EFX_EV_QSTAT_INCR(eep, EV_RX_IP_FRAG_ERR);
603
604                 /*
605                  * If IP is fragmented FSF_AZ_RX_EV_IP_FRAG_ERR is set. This
606                  * causes FSF_AZ_RX_EV_PKT_OK to be clear. This is not an error
607                  * condition.
608                  */
609                 (*flagsp) &= ~(EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP);
610         }
611
612         return (ignore);
613 }
614
615 static  __checkReturn   boolean_t
616 siena_ev_rx(
617         __in            efx_evq_t *eep,
618         __in            efx_qword_t *eqp,
619         __in            const efx_ev_callbacks_t *eecp,
620         __in_opt        void *arg)
621 {
622         uint32_t id;
623         uint32_t size;
624         uint32_t label;
625         boolean_t ok;
626         uint32_t hdr_type;
627         boolean_t is_v6;
628         uint16_t flags;
629         boolean_t ignore;
630         boolean_t should_abort;
631
632         EFX_EV_QSTAT_INCR(eep, EV_RX);
633
634         /* Basic packet information */
635         id = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_DESC_PTR);
636         size = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT);
637         label = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_Q_LABEL);
638         ok = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_OK) != 0);
639
640         hdr_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_HDR_TYPE);
641
642         is_v6 = (EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_IPV6_PKT) != 0);
643
644         /*
645          * If packet is marked as OK and packet type is TCP/IP or
646          * UDP/IP or other IP, then we can rely on the hardware checksums.
647          */
648         switch (hdr_type) {
649         case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_TCP:
650                 flags = EFX_PKT_TCP | EFX_CKSUM_TCPUDP;
651                 if (is_v6) {
652                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
653                         flags |= EFX_PKT_IPV6;
654                 } else {
655                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
656                         flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4;
657                 }
658                 break;
659
660         case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_UDP:
661                 flags = EFX_PKT_UDP | EFX_CKSUM_TCPUDP;
662                 if (is_v6) {
663                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
664                         flags |= EFX_PKT_IPV6;
665                 } else {
666                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
667                         flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4;
668                 }
669                 break;
670
671         case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_OTHER:
672                 if (is_v6) {
673                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);
674                         flags = EFX_PKT_IPV6;
675                 } else {
676                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);
677                         flags = EFX_PKT_IPV4 | EFX_CKSUM_IPV4;
678                 }
679                 break;
680
681         case FSE_AZ_RX_EV_HDR_TYPE_OTHER:
682                 EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);
683                 flags = 0;
684                 break;
685
686         default:
687                 EFSYS_ASSERT(B_FALSE);
688                 flags = 0;
689                 break;
690         }
691
692         /* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */
693         if (!ok) {
694                 ignore = siena_ev_rx_not_ok(eep, eqp, label, id, &flags);
695                 if (ignore) {
696                         EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,
697                             uint32_t, size, uint16_t, flags);
698
699                         return (B_FALSE);
700                 }
701         }
702
703         /* If we're not discarding the packet then it is ok */
704         if (~flags & EFX_DISCARD)
705                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
706
707         /* Detect multicast packets that didn't match the filter */
708         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_PKT) != 0) {
709                 EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_PKT);
710
711                 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_HASH_MATCH) != 0) {
712                         EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_HASH_MATCH);
713                 } else {
714                         EFSYS_PROBE(mcast_mismatch);
715                         flags |= EFX_ADDR_MISMATCH;
716                 }
717         } else {
718                 flags |= EFX_PKT_UNICAST;
719         }
720
721         /*
722          * The packet parser in Siena can abort parsing packets under
723          * certain error conditions, setting the PKT_NOT_PARSED bit
724          * (which clears PKT_OK). If this is set, then don't trust
725          * the PKT_TYPE field.
726          */
727         if (!ok) {
728                 uint32_t parse_err;
729
730                 parse_err = EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_PKT_NOT_PARSED);
731                 if (parse_err != 0)
732                         flags |= EFX_CHECK_VLAN;
733         }
734
735         if (~flags & EFX_CHECK_VLAN) {
736                 uint32_t pkt_type;
737
738                 pkt_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_TYPE);
739                 if (pkt_type >= FSE_AZ_RX_EV_PKT_TYPE_VLAN)
740                         flags |= EFX_PKT_VLAN_TAGGED;
741         }
742
743         EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,
744             uint32_t, size, uint16_t, flags);
745
746         EFSYS_ASSERT(eecp->eec_rx != NULL);
747         should_abort = eecp->eec_rx(arg, label, id, size, flags);
748
749         return (should_abort);
750 }
751
752 static  __checkReturn   boolean_t
753 siena_ev_tx(
754         __in            efx_evq_t *eep,
755         __in            efx_qword_t *eqp,
756         __in            const efx_ev_callbacks_t *eecp,
757         __in_opt        void *arg)
758 {
759         uint32_t id;
760         uint32_t label;
761         boolean_t should_abort;
762
763         EFX_EV_QSTAT_INCR(eep, EV_TX);
764
765         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0 &&
766             EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) == 0 &&
767             EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) == 0 &&
768             EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) == 0) {
769
770                 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_DESC_PTR);
771                 label = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_Q_LABEL);
772
773                 EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
774
775                 EFSYS_ASSERT(eecp->eec_tx != NULL);
776                 should_abort = eecp->eec_tx(arg, label, id);
777
778                 return (should_abort);
779         }
780
781         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0)
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         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) != 0)
787                 EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_ERR);
788
789         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) != 0)
790                 EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_TOO_BIG);
791
792         if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) != 0)
793                 EFX_EV_QSTAT_INCR(eep, EV_TX_WQ_FF_FULL);
794
795         EFX_EV_QSTAT_INCR(eep, EV_TX_UNEXPECTED);
796         return (B_FALSE);
797 }
798
799 static  __checkReturn   boolean_t
800 siena_ev_global(
801         __in            efx_evq_t *eep,
802         __in            efx_qword_t *eqp,
803         __in            const efx_ev_callbacks_t *eecp,
804         __in_opt        void *arg)
805 {
806         _NOTE(ARGUNUSED(eqp, eecp, arg))
807
808         EFX_EV_QSTAT_INCR(eep, EV_GLOBAL);
809
810         return (B_FALSE);
811 }
812
813 static  __checkReturn   boolean_t
814 siena_ev_driver(
815         __in            efx_evq_t *eep,
816         __in            efx_qword_t *eqp,
817         __in            const efx_ev_callbacks_t *eecp,
818         __in_opt        void *arg)
819 {
820         boolean_t should_abort;
821
822         EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
823         should_abort = B_FALSE;
824
825         switch (EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBCODE)) {
826         case FSE_AZ_TX_DESCQ_FLS_DONE_EV: {
827                 uint32_t txq_index;
828
829                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
830
831                 txq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
832
833                 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
834
835                 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
836                 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
837
838                 break;
839         }
840         case FSE_AZ_RX_DESCQ_FLS_DONE_EV: {
841                 uint32_t rxq_index;
842                 uint32_t failed;
843
844                 rxq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
845                 failed = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
846
847                 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
848                 EFSYS_ASSERT(eecp->eec_rxq_flush_failed != NULL);
849
850                 if (failed) {
851                         EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_FAILED);
852
853                         EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index);
854
855                         should_abort = eecp->eec_rxq_flush_failed(arg,
856                                                                     rxq_index);
857                 } else {
858                         EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
859
860                         EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
861
862                         should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
863                 }
864
865                 break;
866         }
867         case FSE_AZ_EVQ_INIT_DONE_EV:
868                 EFSYS_ASSERT(eecp->eec_initialized != NULL);
869                 should_abort = eecp->eec_initialized(arg);
870
871                 break;
872
873         case FSE_AZ_EVQ_NOT_EN_EV:
874                 EFSYS_PROBE(evq_not_en);
875                 break;
876
877         case FSE_AZ_SRM_UPD_DONE_EV: {
878                 uint32_t code;
879
880                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_SRM_UPD_DONE);
881
882                 code = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
883
884                 EFSYS_ASSERT(eecp->eec_sram != NULL);
885                 should_abort = eecp->eec_sram(arg, code);
886
887                 break;
888         }
889         case FSE_AZ_WAKE_UP_EV: {
890                 uint32_t id;
891
892                 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
893
894                 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
895                 should_abort = eecp->eec_wake_up(arg, id);
896
897                 break;
898         }
899         case FSE_AZ_TX_PKT_NON_TCP_UDP:
900                 EFSYS_PROBE(tx_pkt_non_tcp_udp);
901                 break;
902
903         case FSE_AZ_TIMER_EV: {
904                 uint32_t id;
905
906                 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA);
907
908                 EFSYS_ASSERT(eecp->eec_timer != NULL);
909                 should_abort = eecp->eec_timer(arg, id);
910
911                 break;
912         }
913         case FSE_AZ_RX_DSC_ERROR_EV:
914                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DSC_ERROR);
915
916                 EFSYS_PROBE(rx_dsc_error);
917
918                 EFSYS_ASSERT(eecp->eec_exception != NULL);
919                 should_abort = eecp->eec_exception(arg,
920                         EFX_EXCEPTION_RX_DSC_ERROR, 0);
921
922                 break;
923
924         case FSE_AZ_TX_DSC_ERROR_EV:
925                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DSC_ERROR);
926
927                 EFSYS_PROBE(tx_dsc_error);
928
929                 EFSYS_ASSERT(eecp->eec_exception != NULL);
930                 should_abort = eecp->eec_exception(arg,
931                         EFX_EXCEPTION_TX_DSC_ERROR, 0);
932
933                 break;
934
935         default:
936                 break;
937         }
938
939         return (should_abort);
940 }
941
942 static  __checkReturn   boolean_t
943 siena_ev_drv_gen(
944         __in            efx_evq_t *eep,
945         __in            efx_qword_t *eqp,
946         __in            const efx_ev_callbacks_t *eecp,
947         __in_opt        void *arg)
948 {
949         uint32_t data;
950         boolean_t should_abort;
951
952         EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
953
954         data = EFX_QWORD_FIELD(*eqp, FSF_AZ_EV_DATA_DW0);
955         if (data >= ((uint32_t)1 << 16)) {
956                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
957                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
958                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
959                 return (B_TRUE);
960         }
961
962         EFSYS_ASSERT(eecp->eec_software != NULL);
963         should_abort = eecp->eec_software(arg, (uint16_t)data);
964
965         return (should_abort);
966 }
967
968 #if EFSYS_OPT_MCDI
969
970 static  __checkReturn   boolean_t
971 siena_ev_mcdi(
972         __in            efx_evq_t *eep,
973         __in            efx_qword_t *eqp,
974         __in            const efx_ev_callbacks_t *eecp,
975         __in_opt        void *arg)
976 {
977         efx_nic_t *enp = eep->ee_enp;
978         unsigned int code;
979         boolean_t should_abort = B_FALSE;
980
981         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
982
983         if (enp->en_family != EFX_FAMILY_SIENA)
984                 goto out;
985
986         EFSYS_ASSERT(eecp->eec_link_change != NULL);
987         EFSYS_ASSERT(eecp->eec_exception != NULL);
988
989         EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
990
991         code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
992         switch (code) {
993         case MCDI_EVENT_CODE_BADSSERT:
994                 efx_mcdi_ev_death(enp, EINTR);
995                 break;
996
997         case MCDI_EVENT_CODE_CMDDONE:
998                 efx_mcdi_ev_cpl(enp,
999                     MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
1000                     MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
1001                     MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
1002                 break;
1003
1004         case MCDI_EVENT_CODE_LINKCHANGE: {
1005                 efx_link_mode_t link_mode;
1006
1007                 siena_phy_link_ev(enp, eqp, &link_mode);
1008                 should_abort = eecp->eec_link_change(arg, link_mode);
1009                 break;
1010         }
1011         case MCDI_EVENT_CODE_SENSOREVT: {
1012                 should_abort = B_FALSE;
1013                 break;
1014         }
1015         case MCDI_EVENT_CODE_SCHEDERR:
1016                 /* Informational only */
1017                 break;
1018
1019         case MCDI_EVENT_CODE_REBOOT:
1020                 efx_mcdi_ev_death(enp, EIO);
1021                 break;
1022
1023         case MCDI_EVENT_CODE_MAC_STATS_DMA:
1024                 break;
1025
1026         case MCDI_EVENT_CODE_FWALERT: {
1027                 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
1028
1029                 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
1030                         should_abort = eecp->eec_exception(arg,
1031                                 EFX_EXCEPTION_FWALERT_SRAM,
1032                                 MCDI_EV_FIELD(eqp, FWALERT_DATA));
1033                 else
1034                         should_abort = eecp->eec_exception(arg,
1035                                 EFX_EXCEPTION_UNKNOWN_FWALERT,
1036                                 MCDI_EV_FIELD(eqp, DATA));
1037                 break;
1038         }
1039
1040         default:
1041                 EFSYS_PROBE1(mc_pcol_error, int, code);
1042                 break;
1043         }
1044
1045 out:
1046         return (should_abort);
1047 }
1048
1049 #endif  /* EFSYS_OPT_MCDI */
1050
1051 static  __checkReturn   efx_rc_t
1052 siena_ev_qprime(
1053         __in            efx_evq_t *eep,
1054         __in            unsigned int count)
1055 {
1056         efx_nic_t *enp = eep->ee_enp;
1057         uint32_t rptr;
1058         efx_dword_t dword;
1059
1060         rptr = count & eep->ee_mask;
1061
1062         EFX_POPULATE_DWORD_1(dword, FRF_AZ_EVQ_RPTR, rptr);
1063
1064         EFX_BAR_TBL_WRITED(enp, FR_AZ_EVQ_RPTR_REG, eep->ee_index,
1065                             &dword, B_FALSE);
1066
1067         return (0);
1068 }
1069
1070 static          void
1071 siena_ev_qpost(
1072         __in    efx_evq_t *eep,
1073         __in    uint16_t data)
1074 {
1075         efx_nic_t *enp = eep->ee_enp;
1076         efx_qword_t ev;
1077         efx_oword_t oword;
1078
1079         EFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV,
1080             FSF_AZ_EV_DATA_DW0, (uint32_t)data);
1081
1082         EFX_POPULATE_OWORD_3(oword, FRF_AZ_DRV_EV_QID, eep->ee_index,
1083             EFX_DWORD_0, EFX_QWORD_FIELD(ev, EFX_DWORD_0),
1084             EFX_DWORD_1, EFX_QWORD_FIELD(ev, EFX_DWORD_1));
1085
1086         EFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword);
1087 }
1088
1089 static  __checkReturn   efx_rc_t
1090 siena_ev_qmoderate(
1091         __in            efx_evq_t *eep,
1092         __in            unsigned int us)
1093 {
1094         efx_nic_t *enp = eep->ee_enp;
1095         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1096         unsigned int locked;
1097         efx_dword_t dword;
1098         efx_rc_t rc;
1099
1100         if (us > encp->enc_evq_timer_max_us) {
1101                 rc = EINVAL;
1102                 goto fail1;
1103         }
1104
1105         /* If the value is zero then disable the timer */
1106         if (us == 0) {
1107                 EFX_POPULATE_DWORD_2(dword,
1108                     FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS,
1109                     FRF_CZ_TC_TIMER_VAL, 0);
1110         } else {
1111                 unsigned int ticks;
1112
1113                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
1114                         goto fail2;
1115
1116                 EFSYS_ASSERT(ticks > 0);
1117                 EFX_POPULATE_DWORD_2(dword,
1118                     FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_INT_HLDOFF,
1119                     FRF_CZ_TC_TIMER_VAL, ticks - 1);
1120         }
1121
1122         locked = (eep->ee_index == 0) ? 1 : 0;
1123
1124         EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
1125             eep->ee_index, &dword, locked);
1126
1127         return (0);
1128
1129 fail2:
1130         EFSYS_PROBE(fail2);
1131 fail1:
1132         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1133
1134         return (rc);
1135 }
1136
1137 static  __checkReturn   efx_rc_t
1138 siena_ev_qcreate(
1139         __in            efx_nic_t *enp,
1140         __in            unsigned int index,
1141         __in            efsys_mem_t *esmp,
1142         __in            size_t n,
1143         __in            uint32_t id,
1144         __in            uint32_t us,
1145         __in            uint32_t flags,
1146         __in            efx_evq_t *eep)
1147 {
1148         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1149         uint32_t size;
1150         efx_oword_t oword;
1151         efx_rc_t rc;
1152         boolean_t notify_mode;
1153
1154         _NOTE(ARGUNUSED(esmp))
1155
1156         EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
1157         EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
1158
1159         if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
1160                 rc = EINVAL;
1161                 goto fail1;
1162         }
1163         if (index >= encp->enc_evq_limit) {
1164                 rc = EINVAL;
1165                 goto fail2;
1166         }
1167         for (size = 0; (1 << size) <= (EFX_EVQ_MAXNEVS / EFX_EVQ_MINNEVS);
1168             size++)
1169                 if ((1 << size) == (int)(n / EFX_EVQ_MINNEVS))
1170                         break;
1171         if (id + (1 << size) >= encp->enc_buftbl_limit) {
1172                 rc = EINVAL;
1173                 goto fail4;
1174         }
1175
1176         /* Set up the handler table */
1177         eep->ee_rx      = siena_ev_rx;
1178         eep->ee_tx      = siena_ev_tx;
1179         eep->ee_driver  = siena_ev_driver;
1180         eep->ee_global  = siena_ev_global;
1181         eep->ee_drv_gen = siena_ev_drv_gen;
1182 #if EFSYS_OPT_MCDI
1183         eep->ee_mcdi    = siena_ev_mcdi;
1184 #endif  /* EFSYS_OPT_MCDI */
1185
1186         notify_mode = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) !=
1187             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT);
1188
1189         /* Set up the new event queue */
1190         EFX_POPULATE_OWORD_3(oword, FRF_CZ_TIMER_Q_EN, 1,
1191             FRF_CZ_HOST_NOTIFY_MODE, notify_mode,
1192             FRF_CZ_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS);
1193         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword, B_TRUE);
1194
1195         EFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size,
1196             FRF_AZ_EVQ_BUF_BASE_ID, id);
1197
1198         EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword, B_TRUE);
1199
1200         /* Set initial interrupt moderation */
1201         siena_ev_qmoderate(eep, us);
1202
1203         return (0);
1204
1205 fail4:
1206         EFSYS_PROBE(fail4);
1207 fail2:
1208         EFSYS_PROBE(fail2);
1209 fail1:
1210         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1211
1212         return (rc);
1213 }
1214
1215 #endif /* EFSYS_OPT_SIENA */
1216
1217 #if EFSYS_OPT_SIENA
1218
1219 static          void
1220 siena_ev_qdestroy(
1221         __in    efx_evq_t *eep)
1222 {
1223         efx_nic_t *enp = eep->ee_enp;
1224         efx_oword_t oword;
1225
1226         /* Purge event queue */
1227         EFX_ZERO_OWORD(oword);
1228
1229         EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL,
1230             eep->ee_index, &oword, B_TRUE);
1231
1232         EFX_ZERO_OWORD(oword);
1233         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, eep->ee_index, &oword, B_TRUE);
1234 }
1235
1236 static          void
1237 siena_ev_fini(
1238         __in    efx_nic_t *enp)
1239 {
1240         _NOTE(ARGUNUSED(enp))
1241 }
1242
1243 #endif /* EFSYS_OPT_SIENA */