xref: /freebsd/sys/dev/thunderbolt/nhi.c (revision b54dcb897a5fa66ff1013d0ea403ed8894e34b8a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2022 Scott Long
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Spec references are to the Universal Serial Bus 4 (USB4®) Specification
31  * version 2.0, September 2024:
32  * https://usb.org/document-library/usb4r-specification-v20
33  */
34 
35 #include "opt_thunderbolt.h"
36 
37 /* PCIe interface for Thunderbolt Native Host Interface (nhi) */
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/module.h>
43 #include <sys/bus.h>
44 #include <sys/conf.h>
45 #include <sys/malloc.h>
46 #include <sys/queue.h>
47 #include <sys/sysctl.h>
48 #include <sys/lock.h>
49 #include <sys/mutex.h>
50 #include <sys/taskqueue.h>
51 #include <sys/gsb_crc32.h>
52 #include <sys/endian.h>
53 #include <vm/vm.h>
54 #include <vm/pmap.h>
55 
56 #include <machine/bus.h>
57 #include <machine/stdarg.h>
58 
59 #include <dev/thunderbolt/nhi_reg.h>
60 #include <dev/thunderbolt/nhi_var.h>
61 #include <dev/thunderbolt/tb_reg.h>
62 #include <dev/thunderbolt/tb_var.h>
63 #include <dev/thunderbolt/tb_debug.h>
64 #include <dev/thunderbolt/hcm_var.h>
65 #include <dev/thunderbolt/tbcfg_reg.h>
66 #include <dev/thunderbolt/router_var.h>
67 #include <dev/thunderbolt/tb_dev.h>
68 #include "tb_if.h"
69 
70 static int nhi_alloc_ring(struct nhi_softc *, int, int, int,
71     struct nhi_ring_pair **);
72 static void nhi_free_ring(struct nhi_ring_pair *);
73 static void nhi_free_rings(struct nhi_softc *);
74 static int nhi_configure_ring(struct nhi_softc *, struct nhi_ring_pair *);
75 static int nhi_activate_ring(struct nhi_ring_pair *);
76 static int nhi_deactivate_ring(struct nhi_ring_pair *);
77 static int nhi_alloc_ring0(struct nhi_softc *);
78 static void nhi_free_ring0(struct nhi_softc *);
79 static void nhi_fill_rx_ring(struct nhi_softc *, struct nhi_ring_pair *);
80 static int nhi_init(struct nhi_softc *);
81 static void nhi_post_init(void *);
82 static int nhi_tx_enqueue(struct nhi_ring_pair *, struct nhi_cmd_frame *);
83 static int nhi_setup_sysctl(struct nhi_softc *);
84 
85 SYSCTL_NODE(_hw, OID_AUTO, nhi, CTLFLAG_RD, 0, "NHI Driver Parameters");
86 
87 MALLOC_DEFINE(M_NHI, "nhi", "nhi driver memory");
88 
89 #ifndef NHI_DEBUG_LEVEL
90 #define NHI_DEBUG_LEVEL 0
91 #endif
92 
93 void
94 nhi_get_tunables(struct nhi_softc *sc)
95 {
96 	devclass_t dc;
97 	device_t ufp;
98 	char	tmpstr[80], oid[80];
99 	u_int	val;
100 
101 	/* Set local defaults */
102 	sc->debug = NHI_DEBUG_LEVEL;
103 	sc->max_ring_count = NHI_DEFAULT_NUM_RINGS;
104 
105 	/* Inherit setting from the upstream thunderbolt switch node */
106 	val = TB_GET_DEBUG(sc->dev, &sc->debug);
107 	if (val != 0) {
108 		dc = devclass_find("tbolt");
109 		if (dc != NULL) {
110 			ufp = devclass_get_device(dc, device_get_unit(sc->dev));
111 			if (ufp != NULL)
112 				TB_GET_DEBUG(ufp, &sc->debug);
113 		} else {
114 			if (TUNABLE_STR_FETCH("hw.tbolt.debug_level", oid,
115 			    80) != 0)
116 				tb_parse_debug(&sc->debug, oid);
117 		}
118 	}
119 
120 	/*
121 	 * Grab global variables.  Allow nhi debug flags to override
122 	 * thunderbolt debug flags, if present.
123 	 */
124 	bzero(oid, 80);
125 	if (TUNABLE_STR_FETCH("hw.nhi.debug_level", oid, 80) != 0)
126 		tb_parse_debug(&sc->debug, oid);
127 	if (TUNABLE_INT_FETCH("hw.nhi.max_rings", &val) != 0) {
128 		val = min(val, NHI_MAX_NUM_RINGS);
129 		sc->max_ring_count = max(val, 1);
130 	}
131 
132 	/* Grab instance variables */
133 	bzero(oid, 80);
134 	snprintf(tmpstr, sizeof(tmpstr), "dev.nhi.%d.debug_level",
135 	    device_get_unit(sc->dev));
136 	if (TUNABLE_STR_FETCH(tmpstr, oid, 80) != 0)
137 		tb_parse_debug(&sc->debug, oid);
138 	snprintf(tmpstr, sizeof(tmpstr), "dev.nhi.%d.max_rings",
139 	    device_get_unit(sc->dev));
140 	if (TUNABLE_INT_FETCH(tmpstr, &val) != 0) {
141 		val = min(val, NHI_MAX_NUM_RINGS);
142 		sc->max_ring_count = max(val, 1);
143 	}
144 
145 	return;
146 }
147 
148 struct nhi_cmd_frame *
149 nhi_alloc_tx_frame(struct nhi_ring_pair *r)
150 {
151 	struct nhi_cmd_frame *cmd;
152 
153 	mtx_lock(&r->mtx);
154 	cmd = nhi_alloc_tx_frame_locked(r);
155 	mtx_unlock(&r->mtx);
156 
157 	return (cmd);
158 }
159 
160 void
161 nhi_free_tx_frame(struct nhi_ring_pair *r, struct nhi_cmd_frame *cmd)
162 {
163 	mtx_lock(&r->mtx);
164 	nhi_free_tx_frame_locked(r, cmd);
165 	mtx_unlock(&r->mtx);
166 }
167 
168 /*
169  * Push a command and data dword through the mailbox to the firmware.
170  * Response is either good, error, or timeout.  Commands that return data
171  * do so by reading OUTMAILDATA.
172  */
173 int
174 nhi_inmail_cmd(struct nhi_softc *sc, uint32_t cmd, uint32_t data)
175 {
176 	uint32_t val;
177 	u_int error, timeout;
178 
179 	mtx_lock(&sc->nhi_mtx);
180 	/*
181 	 * XXX Should a defer/reschedule happen here, or is it not worth
182 	 * worrying about?
183 	 */
184 	if (sc->hwflags & NHI_MBOX_BUSY) {
185 		mtx_unlock(&sc->nhi_mtx);
186 		tb_debug(sc, DBG_MBOX, "Driver busy with mailbox\n");
187 		return (EBUSY);
188 	}
189 	sc->hwflags |= NHI_MBOX_BUSY;
190 
191 	val = nhi_read_reg(sc, TBT_INMAILCMD);
192 	tb_debug(sc, DBG_MBOX|DBG_FULL, "Reading INMAILCMD= 0x%08x\n", val);
193 	if (val & INMAILCMD_ERROR)
194 		tb_debug(sc, DBG_MBOX, "Error already set in INMAILCMD\n");
195 	if (val & INMAILCMD_OPREQ) {
196 		mtx_unlock(&sc->nhi_mtx);
197 		tb_debug(sc, DBG_MBOX,
198 		    "INMAILCMD request already in progress\n");
199 		return (EBUSY);
200 	}
201 
202 	nhi_write_reg(sc, TBT_INMAILDATA, data);
203 	nhi_write_reg(sc, TBT_INMAILCMD, cmd | INMAILCMD_OPREQ);
204 
205 	/* Poll at 1s intervals */
206 	timeout = NHI_MAILBOX_TIMEOUT;
207 	while (timeout--) {
208 		DELAY(1000000);
209 		val = nhi_read_reg(sc, TBT_INMAILCMD);
210 		tb_debug(sc, DBG_MBOX|DBG_EXTRA,
211 		    "Polling INMAILCMD= 0x%08x\n", val);
212 		if ((val & INMAILCMD_OPREQ) == 0)
213 			break;
214 	}
215 	sc->hwflags &= ~NHI_MBOX_BUSY;
216 	mtx_unlock(&sc->nhi_mtx);
217 
218 	error = 0;
219 	if (val & INMAILCMD_OPREQ) {
220 		tb_printf(sc, "Timeout waiting for mailbox\n");
221 		error = ETIMEDOUT;
222 	}
223 	if (val & INMAILCMD_ERROR) {
224 		tb_printf(sc, "Firmware reports error in mailbox\n");
225 		error = EINVAL;
226 	}
227 
228 	return (error);
229 }
230 
231 /*
232  * Pull command status and data from the firmware mailbox.
233  */
234 int
235 nhi_outmail_cmd(struct nhi_softc *sc, uint32_t *val)
236 {
237 
238 	if (val == NULL)
239 		return (EINVAL);
240 	*val = nhi_read_reg(sc, TBT_OUTMAILCMD);
241 	return (0);
242 }
243 
244 static int
245 nhi_reset_v1(struct nhi_softc *sc)
246 {
247 
248 	/* See section 2.4 of HCM guide v2. */
249 	nhi_write_reg(sc, ROUTER_HIR, 1);
250 	pause_sbt("nhi", ustosbt(10 * 1000), 0, C_HARDCLOCK);
251 	return (0);
252 }
253 
254 static int
255 nhi_reset_v2(struct nhi_softc *sc)
256 {
257 	uint32_t reg;
258 
259 	/*
260 	 * TODO "The Connection Manager shall disable all Transmit Descriptor
261 	 * Rings and wait for at least 1 millisecond prior to setting the Host
262 	 * Router Reset bit to 1b. After the Connection Manager sets the Host
263 	 * Router Reset bit to 1b, it shall not access the Receive Descriptor
264 	 * Rings until the Host Router Reset bit is set to 0b."
265 	 */
266 	/* See section 3.5 of HCM guide v2. */
267 	nhi_write_reg(sc, ROUTER_HRR, 1);
268 	/*
269 	 * "The Host Router is required to complete its reset within 500ms
270 	 * after the Host Router Reset bit is set to 1b."
271 	 */
272 	for (size_t i = 0; i < 10 && reg; i++) {
273 		/*
274 		 * Wait at least 50 ms after writing before reading this
275 		 * register.  If this is 1, it means that we are still
276 		 * resetting.
277 		 */
278 		pause_sbt("nhi", ustosbt(50 * 1000), 0, 0);
279 		reg = nhi_read_reg(sc, ROUTER_HRR);
280 	}
281 	if (reg == 0) {
282 		tb_debug(sc, DBG_INIT|DBG_EXTRA,
283 		    "Succeeded in resetting host router\n");
284 		return (0);
285 	}
286 	tb_printf(sc, "Host router reset timed out\n");
287 	return (ETIMEDOUT);
288 }
289 
290 static int
291 nhi_reset(struct nhi_softc *sc)
292 {
293 
294 	tb_debug(sc, DBG_INIT, "Resetting host router\n");
295 
296 	switch (sc->ver) {
297 	case NHI_VER_1_0:
298 		return (nhi_reset_v1(sc));
299 	case NHI_VER_2_0:
300 		return (nhi_reset_v2(sc));
301 	}
302 	return (ENXIO);
303 }
304 
305 int
306 nhi_attach(struct nhi_softc *sc)
307 {
308 	uint32_t		val;
309 	struct nhi_host_caps	caps;
310 	int			error = 0;
311 
312 	if ((error = nhi_setup_sysctl(sc)) != 0)
313 		return (error);
314 
315 	mtx_init(&sc->nhi_mtx, "nhimtx", "NHI Control Mutex", MTX_DEF);
316 
317 	/*
318 	 * Get the host interface version and number of TX/RX paths.  This
319 	 * sizes some of the register arrays during allocation and
320 	 * initialization.  USB4 spec says that the max is 21.
321 	 */
322 	val = nhi_read_reg(sc, NHI_HOST_CAPS);
323 	caps = *(struct nhi_host_caps *)&val;
324 	if (caps.version_major == 0 && caps.version_minor == 0) {
325 		tb_printf(sc, "Host interface is version 1.0\n");
326 		sc->ver = NHI_VER_1_0;
327 	} else if (caps.version_major == 2 && caps.version_minor == 0) {
328 		tb_printf(sc, "Host interface is version 2.0\n");
329 		sc->ver = NHI_VER_2_0;
330 	} else {
331 		tb_printf(sc, "WARN: unexpected host interface version %d.%d -"
332 		    " assuming 1.0\n", caps.version_major, caps.version_minor);
333 		sc->ver = NHI_VER_1_0;
334 	}
335 	tb_debug(sc, DBG_INIT|DBG_NOISY, "Total Paths= %d\n", caps.total_paths);
336 	if (caps.total_paths == 0 || caps.total_paths > 21) {
337 		tb_printf(sc, "WARN: unexpected number of paths: %d\n", val);
338 		/* return (ENXIO); */
339 	}
340 	sc->path_count = val;
341 
342 	nhi_reset(sc);
343 
344 	SLIST_INIT(&sc->ring_list);
345 
346 	error = nhi_pci_configure_interrupts(sc);
347 	if (error == 0)
348 		error = nhi_alloc_ring0(sc);
349 	if (error == 0) {
350 		nhi_configure_ring(sc, sc->ring0);
351 		nhi_activate_ring(sc->ring0);
352 		nhi_fill_rx_ring(sc, sc->ring0);
353 	}
354 
355 	if (error == 0)
356 		error = tbdev_add_interface(sc);
357 
358 	error = hcm_attach(sc);
359 
360 	if (error == 0)
361 		error = nhi_init(sc);
362 
363 	return (error);
364 }
365 
366 int
367 nhi_detach(struct nhi_softc *sc)
368 {
369 	hcm_detach(sc);
370 
371 	if (sc->root_rsc != NULL)
372 		tb_router_detach(sc->root_rsc);
373 
374 	tbdev_remove_interface(sc);
375 
376 	nhi_pci_disable_interrupts(sc);
377 	nhi_pci_free_interrupts(sc);
378 
379 	nhi_free_ring0(sc);
380 
381 	/* XXX Should the rings be marked as !VALID in the descriptors? */
382 	nhi_free_rings(sc);
383 
384 	mtx_destroy(&sc->nhi_mtx);
385 
386 	return (0);
387 }
388 
389 static void
390 nhi_memaddr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
391 {
392 	bus_addr_t *addr;
393 
394 	addr = arg;
395 	if (error == 0 && nsegs == 1) {
396 		*addr = segs[0].ds_addr;
397 	} else
398 		*addr = 0;
399 }
400 
401 static int
402 nhi_alloc_ring(struct nhi_softc *sc, int ringnum, int tx_depth, int rx_depth,
403     struct nhi_ring_pair **rp)
404 {
405 	bus_dma_template_t t;
406 	bus_addr_t ring_busaddr;
407 	struct nhi_ring_pair *r;
408 	int ring_size, error;
409 	u_int rxring_len, txring_len;
410 	char *ring;
411 
412 	if (ringnum >= sc->max_ring_count) {
413 		tb_debug(sc, DBG_INIT, "Tried to allocate ring number %d\n",
414 		    ringnum);
415 		return (EINVAL);
416 	}
417 
418 	/* Allocate the ring structure and the RX ring tacker together. */
419 	rxring_len = rx_depth * sizeof(void *);
420 	txring_len = tx_depth * sizeof(void *);
421 	r = malloc(sizeof(struct nhi_ring_pair) + rxring_len + txring_len,
422 	    M_NHI, M_NOWAIT|M_ZERO);
423 	if (r == NULL) {
424 		tb_printf(sc, "ERROR: Cannot allocate ring memory\n");
425 		return (ENOMEM);
426 	}
427 
428 	r->sc = sc;
429 	TAILQ_INIT(&r->tx_head);
430 	TAILQ_INIT(&r->rx_head);
431 	r->ring_num = ringnum;
432 	r->tx_ring_depth = tx_depth;
433 	r->tx_ring_mask = tx_depth - 1;
434 	r->rx_ring_depth = rx_depth;
435 	r->rx_ring_mask = rx_depth - 1;
436 	r->rx_pici_reg = NHI_RX_RING_PICI + ringnum * 16;
437 	r->tx_pici_reg = NHI_TX_RING_PICI + ringnum * 16;
438 	r->rx_cmd_ring = (struct nhi_cmd_frame **)((uint8_t *)r + sizeof (*r));
439 	r->tx_cmd_ring = (struct nhi_cmd_frame **)((uint8_t *)r->rx_cmd_ring +
440 	    rxring_len);
441 
442 	snprintf(r->name, NHI_RING_NAMELEN, "nhiring%d\n", ringnum);
443 	mtx_init(&r->mtx, r->name, "NHI Ring Lock", MTX_DEF);
444 	tb_debug(sc, DBG_INIT | DBG_FULL, "Allocated ring context at %p, "
445 	    "mutex %p\n", r, &r->mtx);
446 
447 	/* Allocate the RX and TX buffer descriptor rings */
448 	ring_size = sizeof(struct nhi_tx_buffer_desc) * r->tx_ring_depth;
449 	ring_size += sizeof(struct nhi_rx_buffer_desc) * r->rx_ring_depth;
450 	tb_debug(sc, DBG_INIT | DBG_FULL, "Ring %d ring_size= %d\n",
451 	    ringnum, ring_size);
452 
453 	bus_dma_template_init(&t, sc->parent_dmat);
454 	t.alignment = 4;
455 	t.maxsize = t.maxsegsize = ring_size;
456 	t.nsegments = 1;
457 	if ((error = bus_dma_template_tag(&t, &r->ring_dmat)) != 0) {
458 		tb_printf(sc, "Cannot allocate ring %d DMA tag: %d\n",
459 		    ringnum, error);
460 		return (ENOMEM);
461 	}
462 	if (bus_dmamem_alloc(r->ring_dmat, (void **)&ring, BUS_DMA_NOWAIT,
463 	    &r->ring_map)) {
464 		tb_printf(sc, "Cannot allocate ring memory\n");
465 		return (ENOMEM);
466 	}
467 	bzero(ring, ring_size);
468 	bus_dmamap_load(r->ring_dmat, r->ring_map, ring, ring_size,
469 	    nhi_memaddr_cb, &ring_busaddr, 0);
470 
471 	r->ring = ring;
472 
473 	r->tx_ring = (union nhi_ring_desc *)(ring);
474 	r->tx_ring_busaddr = ring_busaddr;
475 	ring += sizeof(struct nhi_tx_buffer_desc) * r->tx_ring_depth;
476 	ring_busaddr += sizeof(struct nhi_tx_buffer_desc) * r->tx_ring_depth;
477 
478 	r->rx_ring = (union nhi_ring_desc *)(ring);
479 	r->rx_ring_busaddr = ring_busaddr;
480 
481 	tb_debug(sc, DBG_INIT | DBG_EXTRA, "Ring %d: RX %p [0x%jx] "
482 	    "TX %p [0x%jx]\n", ringnum, r->tx_ring, r->tx_ring_busaddr,
483 	    r->rx_ring, r->rx_ring_busaddr);
484 
485 	*rp = r;
486 	return (0);
487 }
488 
489 static void
490 nhi_free_ring(struct nhi_ring_pair *r)
491 {
492 
493 	tb_debug(r->sc, DBG_INIT, "Freeing ring %d resources\n", r->ring_num);
494 	nhi_deactivate_ring(r);
495 
496 	if (r->tx_ring_busaddr != 0) {
497 		bus_dmamap_unload(r->ring_dmat, r->ring_map);
498 		r->tx_ring_busaddr = 0;
499 	}
500 	if (r->ring != NULL) {
501 		bus_dmamem_free(r->ring_dmat, r->ring, r->ring_map);
502 		r->ring = NULL;
503 	}
504 	if (r->ring_dmat != NULL) {
505 		bus_dma_tag_destroy(r->ring_dmat);
506 		r->ring_dmat = NULL;
507 	}
508 	mtx_destroy(&r->mtx);
509 }
510 
511 static void
512 nhi_free_rings(struct nhi_softc *sc)
513 {
514 	struct nhi_ring_pair *r;
515 
516 	while ((r = SLIST_FIRST(&sc->ring_list)) != NULL) {
517 		nhi_free_ring(r);
518 		mtx_lock(&sc->nhi_mtx);
519 		SLIST_REMOVE_HEAD(&sc->ring_list, ring_link);
520 		mtx_unlock(&sc->nhi_mtx);
521 		free(r, M_NHI);
522 	}
523 
524 	return;
525 }
526 
527 static int
528 nhi_configure_ring(struct nhi_softc *sc, struct nhi_ring_pair *ring)
529 {
530 	bus_addr_t busaddr;
531 	uint32_t val;
532 	int idx;
533 
534 	idx = ring->ring_num * 16;
535 
536 	/* Program the TX ring address and size */
537 	busaddr = ring->tx_ring_busaddr;
538 	nhi_write_reg(sc, NHI_TX_RING_ADDR_LO + idx, busaddr & 0xffffffff);
539 	nhi_write_reg(sc, NHI_TX_RING_ADDR_HI + idx, busaddr >> 32);
540 	nhi_write_reg(sc, NHI_TX_RING_SIZE + idx, ring->tx_ring_depth);
541 	nhi_write_reg(sc, NHI_TX_RING_TABLE_TIMESTAMP + idx, 0x0);
542 	tb_debug(sc, DBG_INIT, "TX Ring %d TX_RING_SIZE= 0x%x\n",
543 	    ring->ring_num, ring->tx_ring_depth);
544 
545 	/* Program the RX ring address and size */
546 	busaddr = ring->rx_ring_busaddr;
547 	val = (ring->rx_buffer_size << 16) | ring->rx_ring_depth;
548 	nhi_write_reg(sc, NHI_RX_RING_ADDR_LO + idx, busaddr & 0xffffffff);
549 	nhi_write_reg(sc, NHI_RX_RING_ADDR_HI + idx, busaddr >> 32);
550 	nhi_write_reg(sc, NHI_RX_RING_SIZE + idx, val);
551 	nhi_write_reg(sc, NHI_RX_RING_TABLE_BASE1 + idx, 0xffffffff);
552 	tb_debug(sc, DBG_INIT, "RX Ring %d RX_RING_SIZE= 0x%x\n",
553 	    ring->ring_num, val);
554 
555 	return (0);
556 }
557 
558 static int
559 nhi_activate_ring(struct nhi_ring_pair *ring)
560 {
561 	struct nhi_softc *sc = ring->sc;
562 	int idx;
563 
564 	nhi_pci_enable_interrupt(ring);
565 
566 	idx = ring->ring_num * 32;
567 	tb_debug(sc, DBG_INIT, "Activating ring %d at idx %d\n",
568 	    ring->ring_num, idx);
569 	nhi_write_reg(sc, NHI_TX_RING_TABLE_BASE0 + idx,
570 	    TX_TABLE_RAW | TX_TABLE_VALID);
571 	nhi_write_reg(sc, NHI_RX_RING_TABLE_BASE0 + idx,
572 	    RX_TABLE_RAW | RX_TABLE_VALID);
573 
574 	return (0);
575 }
576 
577 static int
578 nhi_deactivate_ring(struct nhi_ring_pair *r)
579 {
580 	struct nhi_softc *sc = r->sc;
581 	int idx;
582 
583 	idx = r->ring_num * 32;
584 	tb_debug(sc, DBG_INIT, "Deactiving ring %d at idx %d\n",
585 	    r->ring_num, idx);
586 	nhi_write_reg(sc, NHI_TX_RING_TABLE_BASE0 + idx, 0);
587 	nhi_write_reg(sc, NHI_RX_RING_TABLE_BASE0 + idx, 0);
588 
589 	idx = r->ring_num * 16;
590 	tb_debug(sc, DBG_INIT, "Setting ring %d sizes to 0\n", r->ring_num);
591 	nhi_write_reg(sc, NHI_TX_RING_SIZE + idx, 0);
592 	nhi_write_reg(sc, NHI_RX_RING_SIZE + idx, 0);
593 
594 	return (0);
595 }
596 
597 static int
598 nhi_alloc_ring0(struct nhi_softc *sc)
599 {
600 	bus_addr_t frames_busaddr;
601 	bus_dma_template_t t;
602 	struct nhi_intr_tracker *trkr;
603 	struct nhi_ring_pair *r;
604 	struct nhi_cmd_frame *cmd;
605 	char *frames;
606 	int error, size, i;
607 
608 	if ((error = nhi_alloc_ring(sc, 0, NHI_RING0_TX_DEPTH,
609 	    NHI_RING0_RX_DEPTH, &r)) != 0) {
610 		tb_printf(sc, "Error allocating control ring\n");
611 		return (error);
612 	}
613 
614 	r->rx_buffer_size = NHI_RING0_FRAME_SIZE;/* Control packets are small */
615 
616 	/* Allocate the RX and TX buffers that are used for Ring0 comms */
617 	size = r->tx_ring_depth * NHI_RING0_FRAME_SIZE;
618 	size += r->rx_ring_depth * NHI_RING0_FRAME_SIZE;
619 
620 	bus_dma_template_init(&t, sc->parent_dmat);
621 	t.maxsize = t.maxsegsize = size;
622 	t.nsegments = 1;
623 	if (bus_dma_template_tag(&t, &sc->ring0_dmat)) {
624 		tb_printf(sc, "Error allocating control ring buffer tag\n");
625 		return (ENOMEM);
626 	}
627 
628 	if (bus_dmamem_alloc(sc->ring0_dmat, (void **)&frames, BUS_DMA_NOWAIT,
629 	    &sc->ring0_map) != 0) {
630 		tb_printf(sc, "Error allocating control ring memory\n");
631 		return (ENOMEM);
632 	}
633 	bzero(frames, size);
634 	bus_dmamap_load(sc->ring0_dmat, sc->ring0_map, frames, size,
635 	    nhi_memaddr_cb, &frames_busaddr, 0);
636 	sc->ring0_frames_busaddr = frames_busaddr;
637 	sc->ring0_frames = frames;
638 
639 	/* Allocate the driver command trackers */
640 	sc->ring0_cmds = malloc(sizeof(struct nhi_cmd_frame) *
641 	    (r->tx_ring_depth + r->rx_ring_depth), M_NHI, M_NOWAIT | M_ZERO);
642 	if (sc->ring0_cmds == NULL)
643 		return (ENOMEM);
644 
645 	/* Initialize the RX frames so they can be used */
646 	mtx_lock(&r->mtx);
647 	for (i = 0; i < r->rx_ring_depth; i++) {
648 		cmd = &sc->ring0_cmds[i];
649 		cmd->data = (uint32_t *)(frames + NHI_RING0_FRAME_SIZE * i);
650 		cmd->data_busaddr = frames_busaddr + NHI_RING0_FRAME_SIZE * i;
651 		cmd->flags = CMD_MAPPED;
652 		cmd->idx = i;
653 		TAILQ_INSERT_TAIL(&r->rx_head, cmd, cm_link);
654 	}
655 
656 	/* Initialize the TX frames */
657 	for ( ; i < r->tx_ring_depth + r->rx_ring_depth - 1; i++) {
658 		cmd = &sc->ring0_cmds[i];
659 		cmd->data = (uint32_t *)(frames + NHI_RING0_FRAME_SIZE * i);
660 		cmd->data_busaddr = frames_busaddr + NHI_RING0_FRAME_SIZE * i;
661 		cmd->flags = CMD_MAPPED;
662 		cmd->idx = i;
663 		nhi_free_tx_frame_locked(r, cmd);
664 	}
665 	mtx_unlock(&r->mtx);
666 
667 	/* Do a 1:1 mapping of rings to interrupt vectors. */
668 	/* XXX Should be abstracted */
669 	trkr = &sc->intr_trackers[0];
670 	trkr->ring = r;
671 	r->tracker = trkr;
672 
673 	/* XXX Should be an array */
674 	sc->ring0 = r;
675 	SLIST_INSERT_HEAD(&sc->ring_list, r, ring_link);
676 
677 	return (0);
678 }
679 
680 static void
681 nhi_free_ring0(struct nhi_softc *sc)
682 {
683 	if (sc->ring0_cmds != NULL) {
684 		free(sc->ring0_cmds, M_NHI);
685 		sc->ring0_cmds = NULL;
686 	}
687 
688 	if (sc->ring0_frames_busaddr != 0) {
689 		bus_dmamap_unload(sc->ring0_dmat, sc->ring0_map);
690 		sc->ring0_frames_busaddr = 0;
691 	}
692 
693 	if (sc->ring0_frames != NULL) {
694 		bus_dmamem_free(sc->ring0_dmat, sc->ring0_frames,
695 		    sc->ring0_map);
696 		sc->ring0_frames = NULL;
697 	}
698 
699 	if (sc->ring0_dmat != NULL)
700 		bus_dma_tag_destroy(sc->ring0_dmat);
701 
702 	return;
703 }
704 
705 static void
706 nhi_fill_rx_ring(struct nhi_softc *sc, struct nhi_ring_pair *rp)
707 {
708 	struct nhi_cmd_frame *cmd;
709 	struct nhi_rx_buffer_desc *desc;
710 	u_int ci;
711 
712 	/* Assume that we never grow or shrink the ring population */
713 	rp->rx_ci = ci = 0;
714 	rp->rx_pi = 0;
715 
716 	do {
717 		cmd = TAILQ_FIRST(&rp->rx_head);
718 		if (cmd == NULL)
719 			break;
720 		TAILQ_REMOVE(&rp->rx_head, cmd, cm_link);
721 		desc = &rp->rx_ring[ci].rx;
722 		if ((cmd->flags & CMD_MAPPED) == 0)
723 			panic("Need rx buffer mapping code");
724 
725 		desc->addr_lo = cmd->data_busaddr & 0xffffffff;
726 		desc->addr_hi = (cmd->data_busaddr >> 32) & 0xffffffff;
727 		desc->offset = 0;
728 		desc->flags = RX_BUFFER_DESC_RS | RX_BUFFER_DESC_IE;
729 		rp->rx_ci = ci;
730 		rp->rx_cmd_ring[ci] = cmd;
731 		tb_debug(sc, DBG_RXQ | DBG_FULL,
732 		    "Updating ring%d ci= %d cmd= %p, busaddr= 0x%jx\n",
733 		    rp->ring_num, ci, cmd, cmd->data_busaddr);
734 
735 		ci = (rp->rx_ci + 1) & rp->rx_ring_mask;
736 	} while (ci != rp->rx_pi);
737 
738 	/* Update the CI in one shot */
739 	tb_debug(sc, DBG_RXQ, "Writing RX CI= %d\n", rp->rx_ci);
740 	nhi_write_reg(sc, rp->rx_pici_reg, rp->rx_ci);
741 
742 	return;
743 }
744 
745 static int
746 nhi_init(struct nhi_softc *sc)
747 {
748 	tb_route_t root_route = {0x0, 0x0};
749 	uint32_t val;
750 	int error;
751 
752 	tb_debug(sc, DBG_INIT, "Initializing NHI\n");
753 
754 	/* Set interrupt Auto-ACK */
755 	val = nhi_read_reg(sc, NHI_DMA_MISC);
756 	tb_debug(sc, DBG_INIT|DBG_FULL, "Read NHI_DMA_MISC= 0x%08x\n", val);
757 	val |= DMA_MISC_INT_AUTOCLEAR;
758 	tb_debug(sc, DBG_INIT, "Setting interrupt auto-ACK, 0x%08x\n", val);
759 	nhi_write_reg(sc, NHI_DMA_MISC, val);
760 
761 	/*
762 	 * Attach the router to the root thunderbolt bridge now that the DMA
763 	 * channel is configured and ready.
764 	 * The root router always has a route of 0x0...0, so set it statically
765 	 * here.
766 	 */
767 	if ((error = tb_router_attach_root(sc, root_route)) != 0)
768 		tb_printf(sc, "tb_router_attach_root()  error."
769 		    "  The driver should be loaded at boot\n");
770 
771 	if (error == 0) {
772 		sc->ich.ich_func = nhi_post_init;
773 		sc->ich.ich_arg = sc;
774 		error = config_intrhook_establish(&sc->ich);
775 		if (error)
776 			tb_printf(sc, "Failed to establish config hook\n");
777 	}
778 
779 	return (error);
780 }
781 
782 static void
783 nhi_post_init(void *arg)
784 {
785 	struct nhi_softc *sc;
786 	uint8_t *u;
787 	int error;
788 
789 	sc = (struct nhi_softc *)arg;
790 	tb_debug(sc, DBG_INIT | DBG_EXTRA, "nhi_post_init\n");
791 
792 	bzero(sc->lc_uuid, 16);
793 	error = tb_config_get_lc_uuid(sc->root_rsc, sc->lc_uuid);
794 	if (error == 0) {
795 		u = sc->lc_uuid;
796 		tb_printf(sc, "Root Router LC UUID: %02x%02x%02x%02x-"
797 		    "%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
798 		    u[15], u[14], u[13], u[12], u[11], u[10], u[9], u[8], u[7],
799 		    u[6], u[5], u[4], u[3], u[2], u[1], u[0]);
800 	} else
801 		tb_printf(sc, "Error finding LC registers: %d\n", error);
802 
803 	u = sc->uuid;
804 	tb_printf(sc, "Root Router UUID: %02x%02x%02x%02x-"
805 	    "%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
806 	    u[15], u[14], u[13], u[12], u[11], u[10], u[9], u[8], u[7],
807 	    u[6], u[5], u[4], u[3], u[2], u[1], u[0]);
808 
809 	config_intrhook_disestablish(&sc->ich);
810 }
811 
812 static int
813 nhi_tx_enqueue(struct nhi_ring_pair *r, struct nhi_cmd_frame *cmd)
814 {
815 	struct nhi_softc *sc;
816 	struct nhi_tx_buffer_desc *desc;
817 	uint16_t pi;
818 
819 	sc = r->sc;
820 
821 	/* A length of 0 means 4096.  Can't have longer lengths */
822 	if (cmd->req_len > TX_BUFFER_DESC_LEN_MASK + 1) {
823 		tb_debug(sc, DBG_TXQ, "Error: TX frame too big\n");
824 		return (EINVAL);
825 	}
826 	cmd->req_len &= TX_BUFFER_DESC_LEN_MASK;
827 
828 	mtx_lock(&r->mtx);
829 	desc = &r->tx_ring[r->tx_pi].tx;
830 	pi = (r->tx_pi + 1) & r->tx_ring_mask;
831 	if (pi == r->tx_ci) {
832 		mtx_unlock(&r->mtx);
833 		return (EBUSY);
834 	}
835 	r->tx_cmd_ring[r->tx_pi] = cmd;
836 	r->tx_pi = pi;
837 
838 	desc->addr_lo = htole32(cmd->data_busaddr & 0xffffffff);
839 	desc->addr_hi = htole32(cmd->data_busaddr >> 32);
840 	desc->eof_len = htole16((cmd->pdf << TX_BUFFER_DESC_EOF_SHIFT) |
841 	    cmd->req_len);
842 	desc->flags_sof = cmd->pdf | TX_BUFFER_DESC_IE | TX_BUFFER_DESC_RS;
843 	desc->offset = 0;
844 	desc->payload_time = 0;
845 
846 	tb_debug(sc, DBG_TXQ, "enqueue TXdescIdx= %d cmdidx= %d len= %d, "
847 	    "busaddr= 0x%jx\n", r->tx_pi, cmd->idx, cmd->req_len,
848 	    cmd->data_busaddr);
849 
850 	nhi_write_reg(sc, r->tx_pici_reg, pi << TX_RING_PI_SHIFT | r->tx_ci);
851 	mtx_unlock(&r->mtx);
852 	return (0);
853 }
854 
855 /*
856  * No scheduling happens for now.  Ring0 scheduling is done in the TB
857  * layer.
858  */
859 int
860 nhi_tx_schedule(struct nhi_ring_pair *r, struct nhi_cmd_frame *cmd)
861 {
862 	int error;
863 
864 	error = nhi_tx_enqueue(r, cmd);
865 	if (error == EBUSY)
866 		nhi_write_reg(r->sc, r->tx_pici_reg, r->tx_pi << TX_RING_PI_SHIFT | r->tx_ci);
867 	return (error);
868 }
869 
870 int
871 nhi_tx_synchronous(struct nhi_ring_pair *r, struct nhi_cmd_frame *cmd)
872 {
873 	struct nhi_softc *sc __diagused;
874 	int error, count;
875 
876 	sc = r->sc;
877 
878 	if ((error = nhi_tx_schedule(r, cmd)) != 0)
879 		return (error);
880 
881 	if (cmd->flags & CMD_POLLED) {
882 		error = 0;
883 		count = cmd->timeout * 100;
884 
885 		/* Enter the loop at least once */
886 		while ((count-- > 0) && (cmd->flags & CMD_REQ_COMPLETE) == 0) {
887 			DELAY(10000);
888 			rmb();
889 			nhi_intr(r->tracker);
890 		}
891 	} else {
892 		error = msleep(cmd, &r->mtx, PCATCH, "nhi_tx", cmd->timeout);
893 		if ((error == 0) && (cmd->flags & CMD_REQ_COMPLETE) != 0)
894 			error = EWOULDBLOCK;
895 	}
896 
897 	if ((cmd->flags & CMD_REQ_COMPLETE) == 0)
898 		error = ETIMEDOUT;
899 
900 	tb_debug(sc, DBG_TXQ|DBG_FULL, "tx_synchronous done waiting, "
901 	    "err= %d, TX_COMPLETE= %d\n", error,
902 	    !!(cmd->flags & CMD_REQ_COMPLETE));
903 
904 	if (error == ERESTART) {
905 		tb_printf(sc, "TX command interrupted\n");
906 	} else if ((error == EWOULDBLOCK) || (error == ETIMEDOUT)) {
907 		tb_printf(sc, "TX command timed out\n");
908 	} else if (error != 0) {
909 		tb_printf(sc, "TX command failed error= %d\n", error);
910 	}
911 
912 	return (error);
913 }
914 
915 static int
916 nhi_tx_complete(struct nhi_ring_pair *r, struct nhi_tx_buffer_desc *desc,
917     struct nhi_cmd_frame *cmd)
918 {
919 	struct nhi_softc *sc __maybe_unused;
920 	struct nhi_pdf_dispatch *txpdf;
921 	u_int sof;
922 
923 	sc = r->sc;
924 	sof = desc->flags_sof & TX_BUFFER_DESC_SOF_MASK;
925 	tb_debug(sc, DBG_TXQ, "Recovered TX pdf= %s cmdidx= %d flags= 0x%x\n",
926 	    tb_get_string(sof, nhi_frame_pdf), cmd->idx, desc->flags_sof);
927 
928 	if ((desc->flags_sof & TX_BUFFER_DESC_DONE) == 0)
929 		tb_debug(sc, DBG_TXQ,
930 		    "warning, TX descriptor DONE flag not set\n");
931 
932 	/* XXX Atomics */
933 	cmd->flags |= CMD_REQ_COMPLETE;
934 
935 	txpdf = &r->tracker->txpdf[sof];
936 	if (txpdf->cb != NULL) {
937 		tb_debug(sc, DBG_INTR|DBG_TXQ, "Calling PDF TX callback\n");
938 		txpdf->cb(txpdf->context, (union nhi_ring_desc *)desc, cmd);
939 		return (0);
940 	}
941 
942 	tb_debug(sc, DBG_TXQ, "Unhandled TX complete %s\n",
943 	    tb_get_string(sof, nhi_frame_pdf));
944 	nhi_free_tx_frame(r, cmd);
945 
946 	return (0);
947 }
948 
949 static int
950 nhi_rx_complete(struct nhi_ring_pair *r, struct nhi_rx_post_desc *desc,
951     struct nhi_cmd_frame *cmd)
952 {
953 	struct nhi_softc *sc __maybe_unused;
954 	struct nhi_pdf_dispatch *rxpdf;
955 	u_int eof;
956 	u_int len __maybe_unused;
957 
958 	sc = r->sc;
959 	eof = desc->eof_len >> RX_BUFFER_DESC_EOF_SHIFT;
960 	len = desc->eof_len & RX_BUFFER_DESC_LEN_MASK;
961 	tb_debug(sc, DBG_INTR|DBG_RXQ,
962 	    "Recovered RX pdf= %s len= %d cmdidx= %d, busaddr= 0x%jx\n",
963 	    tb_get_string(eof, nhi_frame_pdf), len, cmd->idx,
964 	    cmd->data_busaddr);
965 
966 	rxpdf = &r->tracker->rxpdf[eof];
967 	if (rxpdf->cb != NULL) {
968 		tb_debug(sc, DBG_INTR|DBG_RXQ, "Calling PDF RX callback\n");
969 		rxpdf->cb(rxpdf->context, (union nhi_ring_desc *)desc, cmd);
970 		return (0);
971 	}
972 
973 	tb_debug(sc, DBG_INTR, "Unhandled RX frame %s\n",
974 	    tb_get_string(eof, nhi_frame_pdf));
975 
976 	return (0);
977 }
978 
979 int
980 nhi_register_pdf(struct nhi_ring_pair *rp, struct nhi_dispatch *tx,
981     struct nhi_dispatch *rx)
982 {
983 	struct nhi_intr_tracker *trkr;
984 	struct nhi_pdf_dispatch *slot;
985 
986 	KASSERT(rp != NULL, ("ring_pair is null\n"));
987 	tb_debug(rp->sc, DBG_INTR|DBG_EXTRA, "nhi_register_pdf called\n");
988 
989 	trkr = rp->tracker;
990 	if (trkr == NULL) {
991 		tb_debug(rp->sc, DBG_INTR, "Invalid tracker\n");
992 		return (EINVAL);
993 	}
994 
995 	tb_debug(rp->sc, DBG_INTR|DBG_EXTRA, "Registering TX interrupts\n");
996 	if (tx != NULL) {
997 		while (tx->cb != NULL) {
998 			if ((tx->pdf < 0) || (tx->pdf > 15))
999 				return (EINVAL);
1000 			slot = &trkr->txpdf[tx->pdf];
1001 			if (slot->cb != NULL) {
1002 				tb_debug(rp->sc, DBG_INTR,
1003 				    "Attempted to register busy callback\n");
1004 				return (EBUSY);
1005 			}
1006 			slot->cb = tx->cb;
1007 			slot->context = tx->context;
1008 			tb_debug(rp->sc, DBG_INTR,
1009 			    "Registered TX callback for PDF %d\n", tx->pdf);
1010 			tx++;
1011 		}
1012 	}
1013 
1014 	tb_debug(rp->sc, DBG_INTR|DBG_EXTRA, "Registering RX interrupts\n");
1015 	if (rx != NULL) {
1016 		while (rx->cb != NULL) {
1017 			if ((rx->pdf < 0) || (rx->pdf > 15))
1018 				return (EINVAL);
1019 			slot = &trkr->rxpdf[rx->pdf];
1020 			if (slot->cb != NULL) {
1021 				tb_debug(rp->sc, DBG_INTR,
1022 				    "Attempted to register busy callback\n");
1023 				return (EBUSY);
1024 			}
1025 			slot->cb = rx->cb;
1026 			slot->context = rx->context;
1027 			tb_debug(rp->sc, DBG_INTR,
1028 			    "Registered RX callback for PDF %d\n", rx->pdf);
1029 			rx++;
1030 		}
1031 	}
1032 
1033 	return (0);
1034 }
1035 
1036 int
1037 nhi_deregister_pdf(struct nhi_ring_pair *rp, struct nhi_dispatch *tx,
1038     struct nhi_dispatch *rx)
1039 {
1040 	struct nhi_intr_tracker *trkr;
1041 	struct nhi_pdf_dispatch *slot;
1042 
1043 	tb_debug(rp->sc, DBG_INTR|DBG_EXTRA, "nhi_register_pdf called\n");
1044 
1045 	trkr = rp->tracker;
1046 
1047 	if (tx != NULL) {
1048 		while (tx->cb != NULL) {
1049 			if ((tx->pdf < 0) || (tx->pdf > 15))
1050 				return (EINVAL);
1051 			slot = &trkr->txpdf[tx->pdf];
1052 			slot->cb = NULL;
1053 			slot->context = NULL;
1054 			tx++;
1055 		}
1056 	}
1057 
1058 	if (rx != NULL) {
1059 		while (rx->cb != NULL) {
1060 			if ((rx->pdf < 0) || (rx->pdf > 15))
1061 				return (EINVAL);
1062 			slot = &trkr->rxpdf[rx->pdf];
1063 			slot->cb = NULL;
1064 			slot->context = NULL;
1065 			rx++;
1066 		}
1067 	}
1068 
1069 	return (0);
1070 }
1071 
1072 /*
1073  * The CI and PI indexes are not read from the hardware.  We track them in
1074  * software, so we know where in the ring to start a scan on an interrupt.
1075  * All we have to do is check for the appropriate Done bit in the next
1076  * descriptor, and we know if we have reached the last descriptor that the
1077  * hardware touched.  This technique saves at least 2 MEMIO reads per
1078  * interrupt.
1079  */
1080 void
1081 nhi_intr(void *data)
1082 {
1083 	union nhi_ring_desc *rxd;
1084 	struct nhi_cmd_frame *cmd;
1085 	struct nhi_intr_tracker *trkr = data;
1086 	struct nhi_softc *sc;
1087 	struct nhi_ring_pair *r;
1088 	struct nhi_tx_buffer_desc *txd;
1089 	uint32_t val, old_ci;
1090 	u_int count;
1091 
1092 	sc = trkr->sc;
1093 
1094 	tb_debug(sc, DBG_INTR|DBG_FULL, "Interrupt @ vector %d\n",
1095 	    trkr->vector);
1096 	if ((r = trkr->ring) == NULL)
1097 		return;
1098 
1099 	/*
1100 	 * Need to read this necessarily to clear it; see 12.6.3.4.1.  Disable
1101 	 * ISR Auto-Clear must be set to 0.
1102 	 *
1103 	 * XXX This might not be necessary on all platforms.  It is on Pink
1104 	 * Sardine, but this was not being done previously so it might have
1105 	 * been working without this on whatever scottl@ was testing on.
1106 	 */
1107 	nhi_read_reg(sc, NHI_ISR0);
1108 
1109 	/*
1110 	 * Process TX completions from the adapter.  Only go through
1111 	 * the ring once to prevent unbounded looping.
1112 	 */
1113 	count = r->tx_ring_depth;
1114 	while (count-- > 0) {
1115 		txd = &r->tx_ring[r->tx_ci].tx;
1116 		if ((txd->flags_sof & TX_BUFFER_DESC_DONE) == 0)
1117 			break;
1118 		cmd = r->tx_cmd_ring[r->tx_ci];
1119 		tb_debug(sc, DBG_INTR|DBG_TXQ|DBG_FULL,
1120 		    "Found tx cmdidx= %d cmd= %p\n", r->tx_ci, cmd);
1121 
1122 		/* Pass the completion up the stack */
1123 		nhi_tx_complete(r, txd, cmd);
1124 
1125 		/*
1126 		 * Advance to the next item in the ring via the cached
1127 		 * copy of the CI.  Clear the flags so we can detect
1128 		 * a new done condition the next time the ring wraps
1129 		 * around.  Anything higher up the stack that needs this
1130 		 * field should have already copied it.
1131 		 *
1132 		 * XXX is a memory barrier needed?
1133 		 */
1134 		txd->flags_sof = 0;
1135 		r->tx_ci = (r->tx_ci + 1) & r->tx_ring_mask;
1136 	}
1137 
1138 	/* Process RX packets from the adapter */
1139 	count = r->rx_ring_depth;
1140 	old_ci = r->rx_ci;
1141 
1142 	while (count-- > 0) {
1143 		tb_debug(sc, DBG_INTR|DBG_RXQ|DBG_FULL,
1144 		    "Checking RX descriptor at %d\n", r->rx_pi);
1145 
1146 		/* Look up RX descriptor and cmd */
1147 		rxd = &r->rx_ring[r->rx_pi];
1148 		tb_debug(sc, DBG_INTR|DBG_RXQ|DBG_FULL,
1149 		    "rx desc len= 0x%04x flags= 0x%04x\n", rxd->rxpost.eof_len,
1150 		    rxd->rxpost.flags_sof);
1151 		if ((rxd->rxpost.flags_sof & RX_BUFFER_DESC_DONE) == 0)
1152 			break;
1153 		cmd = r->rx_cmd_ring[r->rx_pi];
1154 		tb_debug(sc, DBG_INTR|DBG_RXQ|DBG_FULL,
1155 		    "Found rx cmdidx= %d cmd= %p\n", r->rx_pi, cmd);
1156 
1157 		/*
1158 		 * Pass the RX frame up the stack.  RX frames are re-used
1159 		 * in-place, so their contents must be copied before this
1160 		 * function returns.
1161 		 *
1162 		 * XXX Rings other than Ring0 might want to have a different
1163 		 * re-use and re-populate policy
1164 		 */
1165 		nhi_rx_complete(r, &rxd->rxpost, cmd);
1166 
1167 		/*
1168 		 * Advance the CI and move forward to the next item in the
1169 		 * ring via our cached copy of the PI.  Clear out the
1170 		 * length field so we can detect a new RX frame when the
1171 		 * ring wraps around.  Reset the flags of the descriptor.
1172 		 */
1173 		rxd->rxpost.eof_len = 0;
1174 		rxd->rx.flags = RX_BUFFER_DESC_RS | RX_BUFFER_DESC_IE;
1175 		r->rx_ci = (r->rx_ci + 1) & r->rx_ring_mask;
1176 		r->rx_pi = (r->rx_pi + 1) & r->rx_ring_mask;
1177 	}
1178 
1179 	/*
1180 	 * Tell the firmware about the new RX CI
1181 	 *
1182 	 * XXX There's a chance this will overwrite an update to the PI.
1183 	 * Is that OK?  We keep our own copy of the PI and never read it from
1184 	 * hardware.  However, will overwriting it result in a missed
1185 	 * interrupt?
1186 	 */
1187 	if (r->rx_ci != old_ci) {
1188 		val = r->rx_pi << RX_RING_PI_SHIFT | r->rx_ci;
1189 		tb_debug(sc, DBG_INTR | DBG_RXQ,
1190 		    "Writing new RX PICI= 0x%08x\n", val);
1191 		nhi_write_reg(sc, r->rx_pici_reg, val);
1192 	}
1193 }
1194 
1195 static int
1196 nhi_setup_sysctl(struct nhi_softc *sc)
1197 {
1198 	struct sysctl_ctx_list	*ctx = NULL;
1199 	struct sysctl_oid	*tree = NULL;
1200 
1201 	ctx = device_get_sysctl_ctx(sc->dev);
1202 	if (ctx != NULL)
1203 		tree = device_get_sysctl_tree(sc->dev);
1204 
1205 	/*
1206 	 * Not being able to create sysctls is going to hamper other
1207 	 * parts of the driver.
1208 	 */
1209 	if (tree == NULL) {
1210 		tb_printf(sc, "Error: cannot create sysctl nodes\n");
1211 		return (EINVAL);
1212 	}
1213 	sc->sysctl_tree = tree;
1214 	sc->sysctl_ctx = ctx;
1215 
1216 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree),
1217 	    OID_AUTO, "debug_level", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE,
1218 	    &sc->debug, 0, tb_debug_sysctl, "A", "Thunderbolt debug level");
1219 	SYSCTL_ADD_U16(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1220 	    "max_rings", CTLFLAG_RD, &sc->max_ring_count, 0,
1221 	    "Max number of rings available");
1222 
1223 	return (0);
1224 }
1225