2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2010-2016 Solarflare Communications Inc.
7 * This software was developed in part by Philip Paeps under contract for
8 * Solarflare Communications, Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
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>
47 #include "common/efx.h"
52 sfxge_ev_qcomplete(struct sfxge_evq *evq, boolean_t eop)
54 struct sfxge_softc *sc;
56 struct sfxge_rxq *rxq;
57 struct sfxge_txq *txq;
59 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
65 if ((txq = evq->txq) != NULL) {
67 evq->txqs = &(evq->txq);
70 struct sfxge_txq *next;
75 KASSERT(txq->evq_index == index,
76 ("txq->evq_index != index"));
78 if (txq->pending != txq->completed)
79 sfxge_tx_qcomplete(txq, evq);
82 } while (txq != NULL);
85 if (rxq->pending != rxq->completed)
86 sfxge_rx_qcomplete(rxq, eop);
89 static struct sfxge_rxq *
90 sfxge_get_rxq_by_label(struct sfxge_evq *evq, uint32_t label)
92 struct sfxge_rxq *rxq;
94 KASSERT(label == 0, ("unexpected rxq label != 0"));
96 rxq = evq->sc->rxq[evq->index];
98 KASSERT(rxq != NULL, ("rxq == NULL"));
99 KASSERT(evq->index == rxq->index, ("evq->index != rxq->index"));
105 sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
108 struct sfxge_evq *evq;
109 struct sfxge_softc *sc;
110 struct sfxge_rxq *rxq;
113 struct sfxge_rx_sw_desc *rx_desc;
116 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
123 rxq = sfxge_get_rxq_by_label(evq, label);
124 if (__predict_false(rxq->init_state != SFXGE_RXQ_STARTED))
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;
134 (delta > efx_nic_cfg_get(sc->enp)->enc_rx_batch_max)) {
135 evq->exception = B_TRUE;
137 device_printf(sc->dev, "RX completion out of order"
138 " (id=%#x delta=%u flags=%#x); resetting\n",
140 sfxge_schedule_reset(sc);
146 rx_desc = &rxq->queue[id];
148 prefetch_read_many(rx_desc->mbuf);
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;
156 KASSERT(size < (1 << 16), ("size > (1 << 16)"));
157 rx_desc->size = (uint16_t)size;
162 if (rxq->pending - rxq->completed >= SFXGE_RX_BATCH)
163 sfxge_ev_qcomplete(evq, B_FALSE);
166 return (evq->rx_done >= SFXGE_EV_BATCH);
170 sfxge_ev_exception(void *arg, uint32_t code, uint32_t data)
172 struct sfxge_evq *evq;
173 struct sfxge_softc *sc;
175 evq = (struct sfxge_evq *)arg;
176 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
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" :
192 evq->exception = B_TRUE;
194 if (code != EFX_EXCEPTION_UNKNOWN_SENSOREVT) {
195 device_printf(sc->dev,
196 "hardware exception (code=%u); resetting\n",
198 sfxge_schedule_reset(sc);
205 sfxge_ev_rxq_flush_done(void *arg, uint32_t rxq_index)
207 struct sfxge_evq *evq;
208 struct sfxge_softc *sc;
209 struct sfxge_rxq *rxq;
213 evq = (struct sfxge_evq *)arg;
214 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
217 rxq = sc->rxq[rxq_index];
219 KASSERT(rxq != NULL, ("rxq == NULL"));
221 /* Resend a software event on the correct queue */
223 if (index == evq->index) {
224 sfxge_rx_qflush_done(rxq);
228 evq = sc->evq[index];
229 magic = sfxge_sw_ev_rxq_magic(SFXGE_SW_EV_RX_QFLUSH_DONE, rxq);
231 KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
232 ("evq not started"));
233 efx_ev_qpost(evq->common, magic);
239 sfxge_ev_rxq_flush_failed(void *arg, uint32_t rxq_index)
241 struct sfxge_evq *evq;
242 struct sfxge_softc *sc;
243 struct sfxge_rxq *rxq;
247 evq = (struct sfxge_evq *)arg;
248 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
251 rxq = sc->rxq[rxq_index];
253 KASSERT(rxq != NULL, ("rxq == NULL"));
255 /* Resend a software event on the correct queue */
257 evq = sc->evq[index];
258 magic = sfxge_sw_ev_rxq_magic(SFXGE_SW_EV_RX_QFLUSH_FAILED, rxq);
260 KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
261 ("evq not started"));
262 efx_ev_qpost(evq->common, magic);
267 static struct sfxge_txq *
268 sfxge_get_txq_by_label(struct sfxge_evq *evq, enum sfxge_txq_type label)
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]);
280 sfxge_ev_tx(void *arg, uint32_t label, uint32_t id)
282 struct sfxge_evq *evq;
283 struct sfxge_txq *txq;
287 evq = (struct sfxge_evq *)arg;
288 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
290 txq = sfxge_get_txq_by_label(evq, label);
292 KASSERT(txq != NULL, ("txq == NULL"));
293 KASSERT(evq->index == txq->evq_index,
294 ("evq->index != txq->evq_index"));
296 if (__predict_false(txq->init_state != SFXGE_TXQ_STARTED))
299 stop = (id + 1) & txq->ptr_mask;
300 id = txq->pending & txq->ptr_mask;
302 delta = (stop >= id) ? (stop - id) : (txq->entries - id + stop);
303 txq->pending += delta;
307 if (txq->next == NULL &&
308 evq->txqs != &(txq->next)) {
310 evq->txqs = &(txq->next);
313 if (txq->pending - txq->completed >= SFXGE_TX_BATCH)
314 sfxge_tx_qcomplete(txq, evq);
317 return (evq->tx_done >= SFXGE_EV_BATCH);
321 sfxge_ev_txq_flush_done(void *arg, uint32_t txq_index)
323 struct sfxge_evq *evq;
324 struct sfxge_softc *sc;
325 struct sfxge_txq *txq;
328 evq = (struct sfxge_evq *)arg;
329 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
332 txq = sc->txq[txq_index];
334 KASSERT(txq != NULL, ("txq == NULL"));
335 KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
336 ("txq not initialized"));
338 if (txq->evq_index == evq->index) {
339 sfxge_tx_qflush_done(txq);
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);
347 KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
348 ("evq not started"));
349 efx_ev_qpost(evq->common, magic);
355 sfxge_ev_software(void *arg, uint16_t magic)
357 struct sfxge_evq *evq;
358 struct sfxge_softc *sc;
361 evq = (struct sfxge_evq *)arg;
362 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
366 label = magic & SFXGE_MAGIC_DMAQ_LABEL_MASK;
367 magic &= ~SFXGE_MAGIC_DMAQ_LABEL_MASK;
370 case SFXGE_SW_EV_MAGIC(SFXGE_SW_EV_RX_QFLUSH_DONE):
371 sfxge_rx_qflush_done(sfxge_get_rxq_by_label(evq, label));
374 case SFXGE_SW_EV_MAGIC(SFXGE_SW_EV_RX_QFLUSH_FAILED):
375 sfxge_rx_qflush_failed(sfxge_get_rxq_by_label(evq, label));
378 case SFXGE_SW_EV_MAGIC(SFXGE_SW_EV_RX_QREFILL):
379 sfxge_rx_qrefill(sfxge_get_rxq_by_label(evq, label));
382 case SFXGE_SW_EV_MAGIC(SFXGE_SW_EV_TX_QFLUSH_DONE): {
383 struct sfxge_txq *txq = sfxge_get_txq_by_label(evq, label);
385 KASSERT(txq != NULL, ("txq == NULL"));
386 KASSERT(evq->index == txq->evq_index,
387 ("evq->index != txq->evq_index"));
389 sfxge_tx_qflush_done(txq);
400 sfxge_ev_sram(void *arg, uint32_t code)
406 case EFX_SRAM_UPDATE:
407 EFSYS_PROBE(sram_update);
411 EFSYS_PROBE(sram_clear);
414 case EFX_SRAM_ILLEGAL_CLEAR:
415 EFSYS_PROBE(sram_illegal_clear);
419 KASSERT(B_FALSE, ("Impossible SRAM event"));
427 sfxge_ev_timer(void *arg, uint32_t index)
436 sfxge_ev_wake_up(void *arg, uint32_t index)
447 sfxge_evq_stat_update(struct sfxge_evq *evq)
453 if (__predict_false(evq->init_state != SFXGE_EVQ_STARTED))
457 if ((unsigned int)(now - evq->stats_update_time) < (unsigned int)hz)
460 evq->stats_update_time = now;
461 efx_ev_qstats_update(evq->common, evq->stats);
464 SFXGE_EVQ_UNLOCK(evq);
468 sfxge_evq_stat_handler(SYSCTL_HANDLER_ARGS)
470 struct sfxge_evq *evq = arg1;
471 struct sfxge_softc *sc = evq->sc;
472 unsigned int id = arg2;
474 SFXGE_ADAPTER_LOCK(sc);
476 sfxge_evq_stat_update(evq);
478 SFXGE_ADAPTER_UNLOCK(sc);
480 return (SYSCTL_OUT(req, &evq->stats[id], sizeof(evq->stats[id])));
484 sfxge_evq_stat_init(struct sfxge_evq *evq)
486 struct sfxge_softc *sc = evq->sc;
487 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
489 struct sysctl_oid *evq_stats_node;
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)
499 for (id = 0; id < EV_NQSTATS; id++) {
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",
512 sfxge_ev_stat_update(struct sfxge_softc *sc)
514 struct sfxge_evq *evq;
519 SFXGE_ADAPTER_LOCK(sc);
522 if ((unsigned int)(now - sc->ev_stats_update_time) < (unsigned int)hz)
525 sc->ev_stats_update_time = now;
527 memset(sc->ev_stats, 0, sizeof(sc->ev_stats));
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];
537 SFXGE_ADAPTER_UNLOCK(sc);
541 sfxge_ev_stat_handler(SYSCTL_HANDLER_ARGS)
543 struct sfxge_softc *sc = arg1;
544 unsigned int id = arg2;
546 sfxge_ev_stat_update(sc);
548 return (SYSCTL_OUT(req, &sc->ev_stats[id], sizeof(sc->ev_stats[id])));
552 sfxge_ev_stat_init(struct sfxge_softc *sc)
554 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
555 struct sysctl_oid_list *stat_list;
559 stat_list = SYSCTL_CHILDREN(sc->stats_node);
561 for (id = 0; id < EV_NQSTATS; id++) {
562 snprintf(name, sizeof(name), "ev_%s",
563 efx_ev_qstat_name(sc->enp, id));
566 OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD,
567 sc, id, sfxge_ev_stat_handler, "Q",
572 #endif /* EFSYS_OPT_QSTATS */
575 sfxge_ev_qmoderate(struct sfxge_softc *sc, unsigned int idx, unsigned int us)
577 struct sfxge_evq *evq;
583 KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
584 ("evq->init_state != SFXGE_EVQ_STARTED"));
586 (void)efx_ev_qmoderate(eep, us);
590 sfxge_int_mod_handler(SYSCTL_HANDLER_ARGS)
592 struct sfxge_softc *sc = arg1;
593 struct sfxge_intr *intr = &sc->intr;
594 unsigned int moderation;
598 SFXGE_ADAPTER_LOCK(sc);
600 if (req->newptr != NULL) {
601 if ((error = SYSCTL_IN(req, &moderation, sizeof(moderation)))
605 /* We may not be calling efx_ev_qmoderate() now,
606 * so we have to range-check the value ourselves.
609 efx_nic_cfg_get(sc->enp)->enc_evq_timer_max_us) {
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);
620 error = SYSCTL_OUT(req, &sc->ev_moderation,
621 sizeof(sc->ev_moderation));
625 SFXGE_ADAPTER_UNLOCK(sc);
631 sfxge_ev_initialized(void *arg)
633 struct sfxge_evq *evq;
635 evq = (struct sfxge_evq *)arg;
636 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
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"));
643 evq->init_state = SFXGE_EVQ_STARTED;
649 sfxge_ev_link_change(void *arg, efx_link_mode_t link_mode)
651 struct sfxge_evq *evq;
652 struct sfxge_softc *sc;
654 evq = (struct sfxge_evq *)arg;
655 SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
659 sfxge_mac_link_update(sc, link_mode);
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,
681 sfxge_ev_qpoll(struct sfxge_evq *evq)
687 if (__predict_false(evq->init_state != SFXGE_EVQ_STARTING &&
688 evq->init_state != SFXGE_EVQ_STARTED)) {
693 /* Synchronize the DMA memory for reading */
694 bus_dmamap_sync(evq->mem.esm_tag, evq->mem.esm_map,
695 BUS_DMASYNC_POSTREAD);
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"));
703 efx_ev_qpoll(evq->common, &evq->read_ptr, &sfxge_ev_callbacks, evq);
708 /* Perform any pending completion processing */
709 sfxge_ev_qcomplete(evq, B_TRUE);
711 /* Re-prime the event queue for interrupts */
712 if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0)
715 SFXGE_EVQ_UNLOCK(evq);
720 SFXGE_EVQ_UNLOCK(evq);
725 sfxge_ev_qstop(struct sfxge_softc *sc, unsigned int index)
727 struct sfxge_evq *evq;
729 evq = sc->evq[index];
731 KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
732 ("evq->init_state != SFXGE_EVQ_STARTED"));
735 evq->init_state = SFXGE_EVQ_INITIALIZED;
737 evq->exception = B_FALSE;
740 /* Add event counts before discarding the common evq state */
741 efx_ev_qstats_update(evq->common, evq->stats);
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);
751 sfxge_ev_qstart(struct sfxge_softc *sc, unsigned int index)
753 struct sfxge_evq *evq;
758 evq = sc->evq[index];
761 KASSERT(evq->init_state == SFXGE_EVQ_INITIALIZED,
762 ("evq->init_state != SFXGE_EVQ_INITIALIZED"));
764 /* Clear all events. */
765 (void)memset(esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries));
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)
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,
780 /* Prime the event queue for interrupts */
781 if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0)
784 evq->init_state = SFXGE_EVQ_STARTING;
786 SFXGE_EVQ_UNLOCK(evq);
788 /* Wait for the initialization event */
791 /* Pause for 100 ms */
792 pause("sfxge evq init", hz / 10);
794 /* Check to see if the test event has been processed */
795 if (evq->init_state == SFXGE_EVQ_STARTED)
798 } while (++count < 20);
808 evq->init_state = SFXGE_EVQ_INITIALIZED;
810 SFXGE_EVQ_UNLOCK(evq);
811 efx_ev_qdestroy(evq->common);
813 efx_sram_buf_tbl_clear(sc->enp, evq->buf_base_id,
814 EFX_EVQ_NBUFS(evq->entries));
820 sfxge_ev_stop(struct sfxge_softc *sc)
822 struct sfxge_intr *intr;
829 KASSERT(intr->state == SFXGE_INTR_STARTED,
830 ("Interrupts not started"));
832 /* Stop the event queue(s) */
833 index = sc->evq_count;
835 sfxge_ev_qstop(sc, index);
837 /* Tear down the event module */
842 sfxge_ev_start(struct sfxge_softc *sc)
844 struct sfxge_intr *intr;
850 KASSERT(intr->state == SFXGE_INTR_STARTED,
851 ("intr->state != SFXGE_INTR_STARTED"));
853 /* Initialize the event module */
854 if ((rc = efx_ev_init(sc->enp)) != 0)
857 /* Start the event queues */
858 for (index = 0; index < sc->evq_count; index++) {
859 if ((rc = sfxge_ev_qstart(sc, index)) != 0)
866 /* Stop the event queue(s) */
868 sfxge_ev_qstop(sc, index);
870 /* Tear down the event module */
871 efx_ev_fini(sc->enp);
877 sfxge_ev_qfini(struct sfxge_softc *sc, unsigned int index)
879 struct sfxge_evq *evq;
881 evq = sc->evq[index];
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"));
887 sfxge_dma_free(&evq->mem);
889 sc->evq[index] = NULL;
891 SFXGE_EVQ_LOCK_DESTROY(evq);
897 sfxge_ev_qinit(struct sfxge_softc *sc, unsigned int index)
899 struct sfxge_evq *evq;
903 KASSERT(index < SFXGE_RX_SCALE_MAX, ("index >= SFXGE_RX_SCALE_MAX"));
905 evq = malloc(sizeof(struct sfxge_evq), M_SFXGE, M_ZERO | M_WAITOK);
908 sc->evq[index] = evq;
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
918 ROUNDUP_POW_OF_TWO(sc->rxq_entries +
919 3 * sc->txq_entries +
923 ROUNDUP_POW_OF_TWO(sc->rxq_entries +
927 /* Initialise TX completion list */
928 evq->txqs = &evq->txq;
930 /* Allocate DMA space. */
931 if ((rc = sfxge_dma_alloc(sc, EFX_EVQ_SIZE(evq->entries), esmp)) != 0)
934 /* Allocate buffer table entries. */
935 sfxge_sram_buf_tbl_alloc(sc, EFX_EVQ_NBUFS(evq->entries),
938 SFXGE_EVQ_LOCK_INIT(evq, device_get_nameunit(sc->dev), index);
940 evq->init_state = SFXGE_EVQ_INITIALIZED;
943 rc = sfxge_evq_stat_init(evq);
945 goto 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;
963 sfxge_ev_fini(struct sfxge_softc *sc)
965 struct sfxge_intr *intr;
970 KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
971 ("intr->state != SFXGE_INTR_INITIALIZED"));
973 sc->ev_moderation = 0;
975 /* Tear down the event queue(s). */
976 index = sc->evq_count;
978 sfxge_ev_qfini(sc, index);
984 sfxge_ev_init(struct sfxge_softc *sc)
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;
994 sc->evq_count = intr->n_alloc;
996 KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
997 ("intr->state != SFXGE_INTR_INITIALIZED"));
999 /* Set default interrupt moderation; add a sysctl to
1000 * read and change it.
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)");
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) {
1014 goto fail_evqs_stats_node;
1019 * Initialize the event queue(s) - one per interrupt.
1021 for (index = 0; index < sc->evq_count; index++) {
1022 if ((rc = sfxge_ev_qinit(sc, index)) != 0)
1026 #if EFSYS_OPT_QSTATS
1027 sfxge_ev_stat_init(sc);
1033 while (--index >= 0)
1034 sfxge_ev_qfini(sc, index);
1036 #if EFSYS_OPT_QSTATS
1037 fail_evqs_stats_node: