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