]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sfxge/sfxge_ev.c
Update nvi to 2.1.3 which fixes the data corruption when locale conversion
[FreeBSD/FreeBSD.git] / sys / dev / sfxge / sfxge_ev.c
1 /*-
2  * Copyright (c) 2010-2011 Solarflare Communications, Inc.
3  * All rights reserved.
4  *
5  * This software was developed in part by Philip Paeps under contract for
6  * Solarflare Communications, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/param.h>
37 #include <sys/queue.h>
38 #include <sys/systm.h>
39 #include <sys/taskqueue.h>
40
41 #include "common/efx.h"
42
43 #include "sfxge.h"
44
45 static void
46 sfxge_ev_qcomplete(struct sfxge_evq *evq, boolean_t eop)
47 {
48         struct sfxge_softc *sc;
49         unsigned int index;
50         struct sfxge_rxq *rxq;
51         struct sfxge_txq *txq;
52
53         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
54
55         sc = evq->sc;
56         index = evq->index;
57         rxq = sc->rxq[index];
58
59         if ((txq = evq->txq) != NULL) {
60                 evq->txq = NULL;
61                 evq->txqs = &(evq->txq);
62
63                 do {
64                         struct sfxge_txq *next;
65
66                         next = txq->next;
67                         txq->next = NULL;
68
69                         KASSERT(txq->evq_index == index,
70                             ("txq->evq_index != index"));
71
72                         if (txq->pending != txq->completed)
73                                 sfxge_tx_qcomplete(txq, evq);
74
75                         txq = next;
76                 } while (txq != NULL);
77         }
78
79         if (rxq->pending != rxq->completed)
80                 sfxge_rx_qcomplete(rxq, eop);
81 }
82
83 static boolean_t
84 sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
85     uint16_t flags)
86 {
87         struct sfxge_evq *evq;
88         struct sfxge_softc *sc;
89         struct sfxge_rxq *rxq;
90         unsigned int expected;
91         struct sfxge_rx_sw_desc *rx_desc;
92
93         evq = arg;
94         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
95
96         sc = evq->sc;
97
98         if (evq->exception)
99                 goto done;
100
101         rxq = sc->rxq[label];
102         KASSERT(rxq != NULL, ("rxq == NULL"));
103         KASSERT(evq->index == rxq->index,
104             ("evq->index != rxq->index"));
105
106         if (__predict_false(rxq->init_state != SFXGE_RXQ_STARTED))
107                 goto done;
108
109         expected = rxq->pending++ & rxq->ptr_mask;
110         if (id != expected) {
111                 evq->exception = B_TRUE;
112
113                 device_printf(sc->dev, "RX completion out of order"
114                               " (id=%#x expected=%#x flags=%#x); resetting\n",
115                               id, expected, flags);
116                 sfxge_schedule_reset(sc);
117
118                 goto done;
119         }
120
121         rx_desc = &rxq->queue[id];
122
123         KASSERT(rx_desc->flags == EFX_DISCARD,
124             ("rx_desc->flags != EFX_DISCARD"));
125         rx_desc->flags = flags;
126
127         KASSERT(size < (1 << 16), ("size > (1 << 16)"));
128         rx_desc->size = (uint16_t)size;
129         prefetch_read_many(rx_desc->mbuf);
130
131         evq->rx_done++;
132
133         if (rxq->pending - rxq->completed >= SFXGE_RX_BATCH)
134                 sfxge_ev_qcomplete(evq, B_FALSE);
135
136 done:
137         return (evq->rx_done >= SFXGE_EV_BATCH);
138 }
139
140 static boolean_t
141 sfxge_ev_exception(void *arg, uint32_t code, uint32_t data)
142 {
143         struct sfxge_evq *evq;
144         struct sfxge_softc *sc;
145
146         evq = (struct sfxge_evq *)arg;
147         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
148
149         sc = evq->sc;
150
151         evq->exception = B_TRUE;
152
153         if (code != EFX_EXCEPTION_UNKNOWN_SENSOREVT) {
154                 device_printf(sc->dev,
155                               "hardware exception (code=%u); resetting\n",
156                               code);
157                 sfxge_schedule_reset(sc);
158         }
159
160         return (B_FALSE);
161 }
162
163 static boolean_t
164 sfxge_ev_rxq_flush_done(void *arg, uint32_t rxq_index)
165 {
166         struct sfxge_evq *evq;
167         struct sfxge_softc *sc;
168         struct sfxge_rxq *rxq;
169         unsigned int index;
170         unsigned int label;
171         uint16_t magic;
172
173         evq = (struct sfxge_evq *)arg;
174         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
175
176         sc = evq->sc;
177         rxq = sc->rxq[rxq_index];
178
179         KASSERT(rxq != NULL, ("rxq == NULL"));
180
181         /* Resend a software event on the correct queue */
182         index = rxq->index;
183         evq = sc->evq[index];
184
185         label = rxq_index;
186         KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
187             ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != level"));
188         magic = SFXGE_MAGIC_RX_QFLUSH_DONE | label;
189
190         KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
191             ("evq not started"));
192         efx_ev_qpost(evq->common, magic);
193
194         return (B_FALSE);
195 }
196
197 static boolean_t
198 sfxge_ev_rxq_flush_failed(void *arg, uint32_t rxq_index)
199 {
200         struct sfxge_evq *evq;
201         struct sfxge_softc *sc;
202         struct sfxge_rxq *rxq;
203         unsigned int index;
204         unsigned int label;
205         uint16_t magic;
206
207         evq = (struct sfxge_evq *)arg;
208         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
209
210         sc = evq->sc;
211         rxq = sc->rxq[rxq_index];
212
213         KASSERT(rxq != NULL, ("rxq == NULL"));
214
215         /* Resend a software event on the correct queue */
216         index = rxq->index;
217         evq = sc->evq[index];
218
219         label = rxq_index;
220         KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
221             ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label"));
222         magic = SFXGE_MAGIC_RX_QFLUSH_FAILED | label;
223
224         KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
225             ("evq not started"));
226         efx_ev_qpost(evq->common, magic);
227
228         return (B_FALSE);
229 }
230
231 static struct sfxge_txq *
232 sfxge_get_txq_by_label(struct sfxge_evq *evq, enum sfxge_txq_type label)
233 {
234         unsigned int index;
235
236         KASSERT((evq->index == 0 && label < SFXGE_TXQ_NTYPES) ||
237             (label == SFXGE_TXQ_IP_TCP_UDP_CKSUM), ("unexpected txq label"));
238         index = (evq->index == 0) ? label : (evq->index - 1 + SFXGE_TXQ_NTYPES);
239         return (evq->sc->txq[index]);
240 }
241
242 static boolean_t
243 sfxge_ev_tx(void *arg, uint32_t label, uint32_t id)
244 {
245         struct sfxge_evq *evq;
246         struct sfxge_txq *txq;
247         unsigned int stop;
248         unsigned int delta;
249
250         evq = (struct sfxge_evq *)arg;
251         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
252
253         txq = sfxge_get_txq_by_label(evq, label);
254
255         KASSERT(txq != NULL, ("txq == NULL"));
256         KASSERT(evq->index == txq->evq_index,
257             ("evq->index != txq->evq_index"));
258
259         if (__predict_false(txq->init_state != SFXGE_TXQ_STARTED))
260                 goto done;
261
262         stop = (id + 1) & txq->ptr_mask;
263         id = txq->pending & txq->ptr_mask;
264
265         delta = (stop >= id) ? (stop - id) : (txq->entries - id + stop);
266         txq->pending += delta;
267
268         evq->tx_done++;
269
270         if (txq->next == NULL &&
271             evq->txqs != &(txq->next)) {
272                 *(evq->txqs) = txq;
273                 evq->txqs = &(txq->next);
274         }
275
276         if (txq->pending - txq->completed >= SFXGE_TX_BATCH)
277                 sfxge_tx_qcomplete(txq, evq);
278
279 done:
280         return (evq->tx_done >= SFXGE_EV_BATCH);
281 }
282
283 static boolean_t
284 sfxge_ev_txq_flush_done(void *arg, uint32_t txq_index)
285 {
286         struct sfxge_evq *evq;
287         struct sfxge_softc *sc;
288         struct sfxge_txq *txq;
289         unsigned int label;
290         uint16_t magic;
291
292         evq = (struct sfxge_evq *)arg;
293         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
294
295         sc = evq->sc;
296         txq = sc->txq[txq_index];
297
298         KASSERT(txq != NULL, ("txq == NULL"));
299         KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
300             ("txq not initialized"));
301
302         /* Resend a software event on the correct queue */
303         evq = sc->evq[txq->evq_index];
304
305         label = txq->type;
306         KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
307             ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label"));
308         magic = SFXGE_MAGIC_TX_QFLUSH_DONE | label;
309
310         KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
311             ("evq not started"));
312         efx_ev_qpost(evq->common, magic);
313
314         return (B_FALSE);
315 }
316
317 static boolean_t
318 sfxge_ev_software(void *arg, uint16_t magic)
319 {
320         struct sfxge_evq *evq;
321         struct sfxge_softc *sc;
322         unsigned int label;
323
324         evq = (struct sfxge_evq *)arg;
325         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
326
327         sc = evq->sc;
328
329         label = magic & SFXGE_MAGIC_DMAQ_LABEL_MASK;
330         magic &= ~SFXGE_MAGIC_DMAQ_LABEL_MASK;
331
332         switch (magic) {
333         case SFXGE_MAGIC_RX_QFLUSH_DONE: {
334                 struct sfxge_rxq *rxq = sc->rxq[label];
335
336                 KASSERT(rxq != NULL, ("rxq == NULL"));
337                 KASSERT(evq->index == rxq->index,
338                     ("evq->index != rxq->index"));
339
340                 sfxge_rx_qflush_done(rxq);
341                 break;
342         }
343         case SFXGE_MAGIC_RX_QFLUSH_FAILED: {
344                 struct sfxge_rxq *rxq = sc->rxq[label];
345
346                 KASSERT(rxq != NULL, ("rxq == NULL"));
347                 KASSERT(evq->index == rxq->index,
348                     ("evq->index != rxq->index"));
349
350                 sfxge_rx_qflush_failed(rxq);
351                 break;
352         }
353         case SFXGE_MAGIC_RX_QREFILL: {
354                 struct sfxge_rxq *rxq = sc->rxq[label];
355
356                 KASSERT(rxq != NULL, ("rxq == NULL"));
357                 KASSERT(evq->index == rxq->index,
358                     ("evq->index != rxq->index"));
359
360                 sfxge_rx_qrefill(rxq);
361                 break;
362         }
363         case SFXGE_MAGIC_TX_QFLUSH_DONE: {
364                 struct sfxge_txq *txq = sfxge_get_txq_by_label(evq, label);
365
366                 KASSERT(txq != NULL, ("txq == NULL"));
367                 KASSERT(evq->index == txq->evq_index,
368                     ("evq->index != txq->evq_index"));
369
370                 sfxge_tx_qflush_done(txq);
371                 break;
372         }
373         default:
374                 break;
375         }
376
377         return (B_FALSE);
378 }
379
380 static boolean_t
381 sfxge_ev_sram(void *arg, uint32_t code)
382 {
383         (void)arg;
384         (void)code;
385
386         switch (code) {
387         case EFX_SRAM_UPDATE:
388                 EFSYS_PROBE(sram_update);
389                 break;
390
391         case EFX_SRAM_CLEAR:
392                 EFSYS_PROBE(sram_clear);
393                 break;
394
395         case EFX_SRAM_ILLEGAL_CLEAR:
396                 EFSYS_PROBE(sram_illegal_clear);
397                 break;
398
399         default:
400                 KASSERT(B_FALSE, ("Impossible SRAM event"));
401                 break;
402         }
403
404         return (B_FALSE);
405 }
406
407 static boolean_t
408 sfxge_ev_timer(void *arg, uint32_t index)
409 {
410         (void)arg;
411         (void)index;
412
413         return (B_FALSE);
414 }
415
416 static boolean_t
417 sfxge_ev_wake_up(void *arg, uint32_t index)
418 {
419         (void)arg;
420         (void)index;
421
422         return (B_FALSE);
423 }
424
425 #if EFSYS_OPT_QSTATS
426
427 static void
428 sfxge_ev_stat_update(struct sfxge_softc *sc)
429 {
430         struct sfxge_evq *evq;
431         unsigned int index;
432         clock_t now;
433
434         SFXGE_ADAPTER_LOCK(sc);
435
436         if (__predict_false(sc->evq[0]->init_state != SFXGE_EVQ_STARTED))
437                 goto out;
438
439         now = ticks;
440         if (now - sc->ev_stats_update_time < hz)
441                 goto out;
442
443         sc->ev_stats_update_time = now;
444
445         /* Add event counts from each event queue in turn */
446         for (index = 0; index < sc->evq_count; index++) {
447                 evq = sc->evq[index];
448                 SFXGE_EVQ_LOCK(evq);
449                 efx_ev_qstats_update(evq->common, sc->ev_stats);
450                 SFXGE_EVQ_UNLOCK(evq);
451         }
452 out:
453         SFXGE_ADAPTER_UNLOCK(sc);
454 }
455
456 static int
457 sfxge_ev_stat_handler(SYSCTL_HANDLER_ARGS)
458 {
459         struct sfxge_softc *sc = arg1;
460         unsigned int id = arg2;
461
462         sfxge_ev_stat_update(sc);
463
464         return (SYSCTL_OUT(req, &sc->ev_stats[id], sizeof(sc->ev_stats[id])));
465 }
466
467 static void
468 sfxge_ev_stat_init(struct sfxge_softc *sc)
469 {
470         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
471         struct sysctl_oid_list *stat_list;
472         unsigned int id;
473         char name[40];
474
475         stat_list = SYSCTL_CHILDREN(sc->stats_node);
476
477         for (id = 0; id < EV_NQSTATS; id++) {
478                 snprintf(name, sizeof(name), "ev_%s",
479                          efx_ev_qstat_name(sc->enp, id));
480                 SYSCTL_ADD_PROC(
481                         ctx, stat_list,
482                         OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD,
483                         sc, id, sfxge_ev_stat_handler, "Q",
484                         "");
485         }
486 }
487
488 #endif /* EFSYS_OPT_QSTATS */
489
490 static void
491 sfxge_ev_qmoderate(struct sfxge_softc *sc, unsigned int idx, unsigned int us)
492 {
493         struct sfxge_evq *evq;
494         efx_evq_t *eep;
495
496         evq = sc->evq[idx];
497         eep = evq->common;
498
499         KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
500             ("evq->init_state != SFXGE_EVQ_STARTED"));
501
502         (void)efx_ev_qmoderate(eep, us);
503 }
504
505 static int
506 sfxge_int_mod_handler(SYSCTL_HANDLER_ARGS)
507 {
508         struct sfxge_softc *sc = arg1;
509         struct sfxge_intr *intr = &sc->intr;
510         unsigned int moderation;
511         int error;
512         unsigned int index;
513
514         SFXGE_ADAPTER_LOCK(sc);
515
516         if (req->newptr != NULL) {
517                 if ((error = SYSCTL_IN(req, &moderation, sizeof(moderation)))
518                     != 0)
519                         goto out;
520
521                 /* We may not be calling efx_ev_qmoderate() now,
522                  * so we have to range-check the value ourselves.
523                  */
524                 if (moderation >
525                     efx_nic_cfg_get(sc->enp)->enc_evq_timer_max_us) {
526                         error = EINVAL;
527                         goto out;
528                 }
529
530                 sc->ev_moderation = moderation;
531                 if (intr->state == SFXGE_INTR_STARTED) {
532                         for (index = 0; index < sc->evq_count; index++)
533                                 sfxge_ev_qmoderate(sc, index, moderation);
534                 }
535         } else {
536                 error = SYSCTL_OUT(req, &sc->ev_moderation,
537                                    sizeof(sc->ev_moderation));
538         }
539
540 out:
541         SFXGE_ADAPTER_UNLOCK(sc);
542
543         return (error);
544 }
545
546 static boolean_t
547 sfxge_ev_initialized(void *arg)
548 {
549         struct sfxge_evq *evq;
550
551         evq = (struct sfxge_evq *)arg;
552         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
553
554         KASSERT(evq->init_state == SFXGE_EVQ_STARTING,
555             ("evq not starting"));
556
557         evq->init_state = SFXGE_EVQ_STARTED;
558
559         return (0);
560 }
561
562 static boolean_t
563 sfxge_ev_link_change(void *arg, efx_link_mode_t link_mode)
564 {
565         struct sfxge_evq *evq;
566         struct sfxge_softc *sc;
567
568         evq = (struct sfxge_evq *)arg;
569         SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
570
571         sc = evq->sc;
572
573         sfxge_mac_link_update(sc, link_mode);
574
575         return (0);
576 }
577
578 static const efx_ev_callbacks_t sfxge_ev_callbacks = {
579         .eec_initialized        = sfxge_ev_initialized,
580         .eec_rx                 = sfxge_ev_rx,
581         .eec_tx                 = sfxge_ev_tx,
582         .eec_exception          = sfxge_ev_exception,
583         .eec_rxq_flush_done     = sfxge_ev_rxq_flush_done,
584         .eec_rxq_flush_failed   = sfxge_ev_rxq_flush_failed,
585         .eec_txq_flush_done     = sfxge_ev_txq_flush_done,
586         .eec_software           = sfxge_ev_software,
587         .eec_sram               = sfxge_ev_sram,
588         .eec_wake_up            = sfxge_ev_wake_up,
589         .eec_timer              = sfxge_ev_timer,
590         .eec_link_change        = sfxge_ev_link_change,
591 };
592
593
594 int
595 sfxge_ev_qpoll(struct sfxge_evq *evq)
596 {
597         int rc;
598
599         SFXGE_EVQ_LOCK(evq);
600
601         if (__predict_false(evq->init_state != SFXGE_EVQ_STARTING &&
602                             evq->init_state != SFXGE_EVQ_STARTED)) {
603                 rc = EINVAL;
604                 goto fail;
605         }
606
607         /* Synchronize the DMA memory for reading */
608         bus_dmamap_sync(evq->mem.esm_tag, evq->mem.esm_map,
609             BUS_DMASYNC_POSTREAD);
610
611         KASSERT(evq->rx_done == 0, ("evq->rx_done != 0"));
612         KASSERT(evq->tx_done == 0, ("evq->tx_done != 0"));
613         KASSERT(evq->txq == NULL, ("evq->txq != NULL"));
614         KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq"));
615
616         /* Poll the queue */
617         efx_ev_qpoll(evq->common, &evq->read_ptr, &sfxge_ev_callbacks, evq);
618
619         evq->rx_done = 0;
620         evq->tx_done = 0;
621
622         /* Perform any pending completion processing */
623         sfxge_ev_qcomplete(evq, B_TRUE);
624
625         /* Re-prime the event queue for interrupts */
626         if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0)
627                 goto fail;
628
629         SFXGE_EVQ_UNLOCK(evq);
630
631         return (0);
632
633 fail:
634         SFXGE_EVQ_UNLOCK(evq);
635         return (rc);
636 }
637
638 static void
639 sfxge_ev_qstop(struct sfxge_softc *sc, unsigned int index)
640 {
641         struct sfxge_evq *evq;
642
643         evq = sc->evq[index];
644
645         KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
646             ("evq->init_state != SFXGE_EVQ_STARTED"));
647
648         SFXGE_EVQ_LOCK(evq);
649         evq->init_state = SFXGE_EVQ_INITIALIZED;
650         evq->read_ptr = 0;
651         evq->exception = B_FALSE;
652
653 #if EFSYS_OPT_QSTATS
654         /* Add event counts before discarding the common evq state */
655         efx_ev_qstats_update(evq->common, sc->ev_stats);
656 #endif
657
658         efx_ev_qdestroy(evq->common);
659         efx_sram_buf_tbl_clear(sc->enp, evq->buf_base_id,
660             EFX_EVQ_NBUFS(evq->entries));
661         SFXGE_EVQ_UNLOCK(evq);
662 }
663
664 static int
665 sfxge_ev_qstart(struct sfxge_softc *sc, unsigned int index)
666 {
667         struct sfxge_evq *evq;
668         efsys_mem_t *esmp;
669         int count;
670         int rc;
671
672         evq = sc->evq[index];
673         esmp = &evq->mem;
674
675         KASSERT(evq->init_state == SFXGE_EVQ_INITIALIZED,
676             ("evq->init_state != SFXGE_EVQ_INITIALIZED"));
677
678         /* Clear all events. */
679         (void)memset(esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries));
680
681         /* Program the buffer table. */
682         if ((rc = efx_sram_buf_tbl_set(sc->enp, evq->buf_base_id, esmp,
683             EFX_EVQ_NBUFS(evq->entries))) != 0)
684                 return (rc);
685
686         /* Create the common code event queue. */
687         if ((rc = efx_ev_qcreate(sc->enp, index, esmp, evq->entries,
688             evq->buf_base_id, &evq->common)) != 0)
689                 goto fail;
690
691         SFXGE_EVQ_LOCK(evq);
692
693         /* Set the default moderation */
694         (void)efx_ev_qmoderate(evq->common, sc->ev_moderation);
695
696         /* Prime the event queue for interrupts */
697         if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0)
698                 goto fail2;
699
700         evq->init_state = SFXGE_EVQ_STARTING;
701
702         SFXGE_EVQ_UNLOCK(evq);
703
704         /* Wait for the initialization event */
705         count = 0;
706         do {
707                 /* Pause for 100 ms */
708                 pause("sfxge evq init", hz / 10);
709
710                 /* Check to see if the test event has been processed */
711                 if (evq->init_state == SFXGE_EVQ_STARTED)
712                         goto done;
713
714         } while (++count < 20);
715
716         rc = ETIMEDOUT;
717         goto fail3;
718
719 done:
720         return (0);
721
722 fail3:
723         SFXGE_EVQ_LOCK(evq);
724         evq->init_state = SFXGE_EVQ_INITIALIZED;
725 fail2:
726         SFXGE_EVQ_UNLOCK(evq);
727         efx_ev_qdestroy(evq->common);
728 fail:
729         efx_sram_buf_tbl_clear(sc->enp, evq->buf_base_id,
730             EFX_EVQ_NBUFS(evq->entries));
731
732         return (rc);
733 }
734
735 void
736 sfxge_ev_stop(struct sfxge_softc *sc)
737 {
738         struct sfxge_intr *intr;
739         efx_nic_t *enp;
740         int index;
741
742         intr = &sc->intr;
743         enp = sc->enp;
744
745         KASSERT(intr->state == SFXGE_INTR_STARTED,
746             ("Interrupts not started"));
747
748         /* Stop the event queue(s) */
749         index = sc->evq_count;
750         while (--index >= 0)
751                 sfxge_ev_qstop(sc, index);
752
753         /* Tear down the event module */
754         efx_ev_fini(enp);
755 }
756
757 int
758 sfxge_ev_start(struct sfxge_softc *sc)
759 {
760         struct sfxge_intr *intr;
761         int index;
762         int rc;
763
764         intr = &sc->intr;
765
766         KASSERT(intr->state == SFXGE_INTR_STARTED,
767             ("intr->state != SFXGE_INTR_STARTED"));
768
769         /* Initialize the event module */
770         if ((rc = efx_ev_init(sc->enp)) != 0)
771                 return (rc);
772
773         /* Start the event queues */
774         for (index = 0; index < sc->evq_count; index++) {
775                 if ((rc = sfxge_ev_qstart(sc, index)) != 0)
776                         goto fail;
777         }
778
779         return (0);
780
781 fail:
782         /* Stop the event queue(s) */
783         while (--index >= 0)
784                 sfxge_ev_qstop(sc, index);
785
786         /* Tear down the event module */
787         efx_ev_fini(sc->enp);
788
789         return (rc);
790 }
791
792 static void
793 sfxge_ev_qfini(struct sfxge_softc *sc, unsigned int index)
794 {
795         struct sfxge_evq *evq;
796
797         evq = sc->evq[index];
798
799         KASSERT(evq->init_state == SFXGE_EVQ_INITIALIZED,
800             ("evq->init_state != SFXGE_EVQ_INITIALIZED"));
801         KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq"));
802
803         sfxge_dma_free(&evq->mem);
804
805         sc->evq[index] = NULL;
806
807         SFXGE_EVQ_LOCK_DESTROY(evq);
808
809         free(evq, M_SFXGE);
810 }
811
812 static int
813 sfxge_ev_qinit(struct sfxge_softc *sc, unsigned int index)
814 {
815         struct sfxge_evq *evq;
816         efsys_mem_t *esmp;
817         int rc;
818
819         KASSERT(index < SFXGE_RX_SCALE_MAX, ("index >= SFXGE_RX_SCALE_MAX"));
820
821         evq = malloc(sizeof(struct sfxge_evq), M_SFXGE, M_ZERO | M_WAITOK);
822         evq->sc = sc;
823         evq->index = index;
824         sc->evq[index] = evq;
825         esmp = &evq->mem;
826
827         /* Build an event queue with room for one event per tx and rx buffer,
828          * plus some extra for link state events and MCDI completions.
829          * There are three tx queues in the first event queue and one in
830          * other.
831          */
832         if (index == 0)
833                 evq->entries =
834                         ROUNDUP_POW_OF_TWO(sc->rxq_entries +
835                                            3 * sc->txq_entries +
836                                            128);
837         else
838                 evq->entries =
839                         ROUNDUP_POW_OF_TWO(sc->rxq_entries +
840                                            sc->txq_entries +
841                                            128);
842
843         /* Initialise TX completion list */
844         evq->txqs = &evq->txq;
845
846         /* Allocate DMA space. */
847         if ((rc = sfxge_dma_alloc(sc, EFX_EVQ_SIZE(evq->entries), esmp)) != 0)
848                 return (rc);
849
850         /* Allocate buffer table entries. */
851         sfxge_sram_buf_tbl_alloc(sc, EFX_EVQ_NBUFS(evq->entries),
852                                  &evq->buf_base_id);
853
854         SFXGE_EVQ_LOCK_INIT(evq, device_get_nameunit(sc->dev), index);
855
856         evq->init_state = SFXGE_EVQ_INITIALIZED;
857
858         return (0);
859 }
860
861 void
862 sfxge_ev_fini(struct sfxge_softc *sc)
863 {
864         struct sfxge_intr *intr;
865         int index;
866
867         intr = &sc->intr;
868
869         KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
870             ("intr->state != SFXGE_INTR_INITIALIZED"));
871
872         sc->ev_moderation = 0;
873
874         /* Tear down the event queue(s). */
875         index = sc->evq_count;
876         while (--index >= 0)
877                 sfxge_ev_qfini(sc, index);
878
879         sc->evq_count = 0;
880 }
881
882 int
883 sfxge_ev_init(struct sfxge_softc *sc)
884 {
885         struct sysctl_ctx_list *sysctl_ctx = device_get_sysctl_ctx(sc->dev);
886         struct sysctl_oid *sysctl_tree = device_get_sysctl_tree(sc->dev);
887         struct sfxge_intr *intr;
888         int index;
889         int rc;
890
891         intr = &sc->intr;
892
893         sc->evq_count = intr->n_alloc;
894
895         KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
896             ("intr->state != SFXGE_INTR_INITIALIZED"));
897
898         /* Set default interrupt moderation; add a sysctl to
899          * read and change it.
900          */
901         sc->ev_moderation = SFXGE_MODERATION;
902         SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
903                         OID_AUTO, "int_mod", CTLTYPE_UINT|CTLFLAG_RW,
904                         sc, 0, sfxge_int_mod_handler, "IU",
905                         "sfxge interrupt moderation (us)");
906
907         /*
908          * Initialize the event queue(s) - one per interrupt.
909          */
910         for (index = 0; index < sc->evq_count; index++) {
911                 if ((rc = sfxge_ev_qinit(sc, index)) != 0)
912                         goto fail;
913         }
914
915 #if EFSYS_OPT_QSTATS
916         sfxge_ev_stat_init(sc);
917 #endif
918
919         return (0);
920
921 fail:
922         while (--index >= 0)
923                 sfxge_ev_qfini(sc, index);
924
925         sc->evq_count = 0;
926         return (rc);
927 }