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