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: releng/11.2/sys/dev/sfxge/sfxge_ev.c 331722 2018-03-29 02:50:57Z eadler $");
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, EFX_EVQ_FLAGS_TYPE_AUTO,
707 &evq->common)) != 0)
708 goto fail;
709
710 SFXGE_EVQ_LOCK(evq);
711
712 /* Prime the event queue for interrupts */
713 if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0)
714 goto fail2;
715
716 evq->init_state = SFXGE_EVQ_STARTING;
717
718 SFXGE_EVQ_UNLOCK(evq);
719
720 /* Wait for the initialization event */
721 count = 0;
722 do {
723 /* Pause for 100 ms */
724 pause("sfxge evq init", hz / 10);
725
726 /* Check to see if the test event has been processed */
727 if (evq->init_state == SFXGE_EVQ_STARTED)
728 goto done;
729
730 } while (++count < 20);
731
732 rc = ETIMEDOUT;
733 goto fail3;
734
735 done:
736 return (0);
737
738 fail3:
739 SFXGE_EVQ_LOCK(evq);
740 evq->init_state = SFXGE_EVQ_INITIALIZED;
741 fail2:
742 SFXGE_EVQ_UNLOCK(evq);
743 efx_ev_qdestroy(evq->common);
744 fail:
745 efx_sram_buf_tbl_clear(sc->enp, evq->buf_base_id,
746 EFX_EVQ_NBUFS(evq->entries));
747
748 return (rc);
749 }
750
751 void
752 sfxge_ev_stop(struct sfxge_softc *sc)
753 {
754 struct sfxge_intr *intr;
755 efx_nic_t *enp;
756 int index;
757
758 intr = &sc->intr;
759 enp = sc->enp;
760
761 KASSERT(intr->state == SFXGE_INTR_STARTED,
762 ("Interrupts not started"));
763
764 /* Stop the event queue(s) */
765 index = sc->evq_count;
766 while (--index >= 0)
767 sfxge_ev_qstop(sc, index);
768
769 /* Tear down the event module */
770 efx_ev_fini(enp);
771 }
772
773 int
774 sfxge_ev_start(struct sfxge_softc *sc)
775 {
776 struct sfxge_intr *intr;
777 int index;
778 int rc;
779
780 intr = &sc->intr;
781
782 KASSERT(intr->state == SFXGE_INTR_STARTED,
783 ("intr->state != SFXGE_INTR_STARTED"));
784
785 /* Initialize the event module */
786 if ((rc = efx_ev_init(sc->enp)) != 0)
787 return (rc);
788
789 /* Start the event queues */
790 for (index = 0; index < sc->evq_count; index++) {
791 if ((rc = sfxge_ev_qstart(sc, index)) != 0)
792 goto fail;
793 }
794
795 return (0);
796
797 fail:
798 /* Stop the event queue(s) */
799 while (--index >= 0)
800 sfxge_ev_qstop(sc, index);
801
802 /* Tear down the event module */
803 efx_ev_fini(sc->enp);
804
805 return (rc);
806 }
807
808 static void
809 sfxge_ev_qfini(struct sfxge_softc *sc, unsigned int index)
810 {
811 struct sfxge_evq *evq;
812
813 evq = sc->evq[index];
814
815 KASSERT(evq->init_state == SFXGE_EVQ_INITIALIZED,
816 ("evq->init_state != SFXGE_EVQ_INITIALIZED"));
817 KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq"));
818
819 sfxge_dma_free(&evq->mem);
820
821 sc->evq[index] = NULL;
822
823 SFXGE_EVQ_LOCK_DESTROY(evq);
824
825 free(evq, M_SFXGE);
826 }
827
828 static int
829 sfxge_ev_qinit(struct sfxge_softc *sc, unsigned int index)
830 {
831 struct sfxge_evq *evq;
832 efsys_mem_t *esmp;
833 int rc;
834
835 KASSERT(index < SFXGE_RX_SCALE_MAX, ("index >= SFXGE_RX_SCALE_MAX"));
836
837 evq = malloc(sizeof(struct sfxge_evq), M_SFXGE, M_ZERO | M_WAITOK);
838 evq->sc = sc;
839 evq->index = index;
840 sc->evq[index] = evq;
841 esmp = &evq->mem;
842
843 /* Build an event queue with room for one event per tx and rx buffer,
844 * plus some extra for link state events and MCDI completions.
845 * There are three tx queues in the first event queue and one in
846 * other.
847 */
848 if (index == 0)
849 evq->entries =
850 ROUNDUP_POW_OF_TWO(sc->rxq_entries +
851 3 * sc->txq_entries +
852 128);
853 else
854 evq->entries =
855 ROUNDUP_POW_OF_TWO(sc->rxq_entries +
856 sc->txq_entries +
857 128);
858
859 /* Initialise TX completion list */
860 evq->txqs = &evq->txq;
861
862 /* Allocate DMA space. */
863 if ((rc = sfxge_dma_alloc(sc, EFX_EVQ_SIZE(evq->entries), esmp)) != 0)
864 return (rc);
865
866 /* Allocate buffer table entries. */
867 sfxge_sram_buf_tbl_alloc(sc, EFX_EVQ_NBUFS(evq->entries),
868 &evq->buf_base_id);
869
870 SFXGE_EVQ_LOCK_INIT(evq, device_get_nameunit(sc->dev), index);
871
872 evq->init_state = SFXGE_EVQ_INITIALIZED;
873
874 return (0);
875 }
876
877 void
878 sfxge_ev_fini(struct sfxge_softc *sc)
879 {
880 struct sfxge_intr *intr;
881 int index;
882
883 intr = &sc->intr;
884
885 KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
886 ("intr->state != SFXGE_INTR_INITIALIZED"));
887
888 sc->ev_moderation = 0;
889
890 /* Tear down the event queue(s). */
891 index = sc->evq_count;
892 while (--index >= 0)
893 sfxge_ev_qfini(sc, index);
894
895 sc->evq_count = 0;
896 }
897
898 int
899 sfxge_ev_init(struct sfxge_softc *sc)
900 {
901 struct sysctl_ctx_list *sysctl_ctx = device_get_sysctl_ctx(sc->dev);
902 struct sysctl_oid *sysctl_tree = device_get_sysctl_tree(sc->dev);
903 struct sfxge_intr *intr;
904 int index;
905 int rc;
906
907 intr = &sc->intr;
908
909 sc->evq_count = intr->n_alloc;
910
911 KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
912 ("intr->state != SFXGE_INTR_INITIALIZED"));
913
914 /* Set default interrupt moderation; add a sysctl to
915 * read and change it.
916 */
917 sc->ev_moderation = SFXGE_MODERATION;
918 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
919 OID_AUTO, "int_mod", CTLTYPE_UINT|CTLFLAG_RW,
920 sc, 0, sfxge_int_mod_handler, "IU",
921 "sfxge interrupt moderation (us)");
922
923 /*
924 * Initialize the event queue(s) - one per interrupt.
925 */
926 for (index = 0; index < sc->evq_count; index++) {
927 if ((rc = sfxge_ev_qinit(sc, index)) != 0)
928 goto fail;
929 }
930
931 #if EFSYS_OPT_QSTATS
932 sfxge_ev_stat_init(sc);
933 #endif
934
935 return (0);
936
937 fail:
938 while (--index >= 0)
939 sfxge_ev_qfini(sc, index);
940
941 sc->evq_count = 0;
942 return (rc);
943 }
Cache object: 5ea1df4b541bc497136249b7ca692663
|