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