xref: /netbsd-src/sys/dev/bluetooth/bth5.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /*	$NetBSD: bth5.c,v 1.6 2019/11/16 22:06:49 mlelstv Exp $	*/
2 /*
3  * Copyright (c) 2017 Nathanial Sloss <nathanialsloss@yahoo.com.au>
4  * All rights reserved.
5  *
6  * Copyright (c) 2007 KIYOHARA Takashi
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: bth5.c,v 1.6 2019/11/16 22:06:49 mlelstv Exp $");
33 
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/callout.h>
37 #include <sys/conf.h>
38 #include <sys/device.h>
39 #include <sys/errno.h>
40 #include <sys/fcntl.h>
41 #include <sys/kauth.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/proc.h>
46 #include <sys/sysctl.h>
47 #include <sys/syslimits.h>
48 #include <sys/systm.h>
49 #include <sys/tty.h>
50 
51 #include <netbt/bluetooth.h>
52 #include <netbt/hci.h>
53 
54 #include <dev/bluetooth/bth5.h>
55 
56 #include "ioconf.h"
57 
58 #ifdef BTH5_DEBUG
59 #ifdef DPRINTF
60 #undef DPRINTF
61 #endif
62 #ifdef DPRINTFN
63 #undef DPRINTFN
64 #endif
65 
66 #define DPRINTF(x)	printf x
67 #define DPRINTFN(n, x)	do { if (bth5_debug > (n)) printf x; } while (0)
68 int bth5_debug = 3;
69 #else
70 #undef DPRINTF
71 #undef DPRINTFN
72 
73 #define DPRINTF(x)
74 #define DPRINTFN(n, x)
75 #endif
76 
77 struct bth5_softc {
78 	device_t sc_dev;
79 
80 	struct tty *sc_tp;
81 	struct hci_unit *sc_unit;		/* Bluetooth HCI Unit */
82 	struct bt_stats sc_stats;
83 
84 	int sc_flags;
85 
86 	/* output queues */
87 	MBUFQ_HEAD()	sc_cmdq;
88 	MBUFQ_HEAD()	sc_aclq;
89 	MBUFQ_HEAD()	sc_scoq;
90 
91 	int sc_baud;
92 	int sc_init_baud;
93 
94 	/* variables of SLIP Layer */
95 	struct mbuf *sc_txp;			/* outgoing packet */
96 	struct mbuf *sc_rxp;			/* incoming packet */
97 	int sc_slip_txrsv;			/* reserved byte data */
98 	int sc_slip_rxexp;			/* expected byte data */
99 	void (*sc_transmit_callback)(struct bth5_softc *, struct mbuf *);
100 
101 	/* variables of Packet Integrity Layer */
102 	int sc_pi_txcrc;			/* use CRC, if true */
103 
104 	/* variables of MUX Layer */
105 	bool sc_mux_send_ack;			/* flag for send_ack */
106 	bool sc_mux_choke;			/* Choke signal */
107 	struct timeval sc_mux_lastrx;		/* Last Rx Pkt Time */
108 
109 	/* variables of Sequencing Layer */
110 	MBUFQ_HEAD() sc_seqq;			/* Sequencing Layer queue */
111 	MBUFQ_HEAD() sc_seq_retryq;		/* retry queue */
112 	uint32_t sc_seq_txseq;
113 	uint32_t sc_seq_expected_rxseq;
114 	uint32_t sc_seq_total_rxpkts;
115 	uint32_t sc_seq_winack;
116 	uint32_t sc_seq_winspace;
117 	uint32_t sc_seq_retries;
118 	callout_t sc_seq_timer;
119 	uint32_t sc_seq_timeout;
120 	uint32_t sc_seq_winsize;
121 	uint32_t sc_seq_retry_limit;
122 	bool	 sc_oof_flow_control;
123 
124 	/* variables of Datagram Queue Layer */
125 	MBUFQ_HEAD() sc_dgq;			/* Datagram Queue Layer queue */
126 
127 	/* variables of BTH5 Link Establishment Protocol */
128 	bool sc_le_muzzled;
129 	bth5_le_state_t sc_le_state;
130 	callout_t sc_le_timer;
131 
132 	struct sysctllog *sc_log;		/* sysctl log */
133 };
134 
135 /* sc_flags */
136 #define	BTH5_XMIT	(1 << 0)	/* transmit active */
137 #define	BTH5_ENABLED	(1 << 1)	/* is enabled */
138 
139 static int bthfive_match(device_t, cfdata_t, void *);
140 static void bthfive_attach(device_t, device_t, void *);
141 static int bthfive_detach(device_t, int);
142 
143 /* tty functions */
144 static int bth5open(dev_t, struct tty *);
145 static int bth5close(struct tty *, int);
146 static int bth5ioctl(struct tty *, u_long, void *, int, struct lwp *);
147 
148 static int bth5_slip_transmit(struct tty *);
149 static int bth5_slip_receive(int, struct tty *);
150 
151 static void bth5_pktintegrity_transmit(struct bth5_softc *);
152 static void bth5_pktintegrity_receive(struct bth5_softc *, struct mbuf *);
153 static void bth5_crc_update(uint16_t *, uint8_t);
154 static uint16_t bth5_crc_reverse(uint16_t);
155 
156 static void bth5_mux_transmit(struct bth5_softc *sc);
157 static void bth5_mux_receive(struct bth5_softc *sc, struct mbuf *m);
158 static __inline void bth5_send_ack_command(struct bth5_softc *sc);
159 static __inline struct mbuf *bth5_create_ackpkt(void);
160 static __inline void bth5_set_choke(struct bth5_softc *, bool);
161 
162 static void bth5_sequencing_receive(struct bth5_softc *, struct mbuf *);
163 static bool bth5_tx_reliable_pkt(struct bth5_softc *, struct mbuf *, u_int);
164 static __inline u_int bth5_get_txack(struct bth5_softc *);
165 static void bth5_signal_rxack(struct bth5_softc *, uint32_t);
166 static void bth5_reliabletx_callback(struct bth5_softc *, struct mbuf *);
167 static void bth5_timer_timeout(void *);
168 static void bth5_sequencing_reset(struct bth5_softc *);
169 
170 static void bth5_datagramq_receive(struct bth5_softc *, struct mbuf *);
171 static bool bth5_tx_unreliable_pkt(struct bth5_softc *, struct mbuf *, u_int);
172 static void bth5_unreliabletx_callback(struct bth5_softc *, struct mbuf *);
173 
174 static int bth5_start_le(struct bth5_softc *);
175 static void bth5_terminate_le(struct bth5_softc *);
176 static void bth5_input_le(struct bth5_softc *, struct mbuf *);
177 static void bth5_le_timeout(void *);
178 
179 static void bth5_start(struct bth5_softc *);
180 
181 /* bluetooth hci functions */
182 static int bth5_enable(device_t);
183 static void bth5_disable(device_t);
184 static void bth5_output_cmd(device_t, struct mbuf *);
185 static void bth5_output_acl(device_t, struct mbuf *);
186 static void bth5_output_sco(device_t, struct mbuf *);
187 static void bth5_stats(device_t, struct bt_stats *, int);
188 
189 #ifdef BTH5_DEBUG
190 static void bth5_packet_print(struct mbuf *m);
191 #endif
192 
193 
194 /*
195  * It doesn't need to be exported, as only bth5attach() uses it,
196  * but there's no "official" way to make it static.
197  */
198 CFATTACH_DECL_NEW(bthfive, sizeof(struct bth5_softc),
199     bthfive_match, bthfive_attach, bthfive_detach, NULL);
200 
201 static struct linesw bth5_disc = {
202 	.l_name = "bth5",
203 	.l_open = bth5open,
204 	.l_close = bth5close,
205 	.l_read = ttyerrio,
206 	.l_write = ttyerrio,
207 	.l_ioctl = bth5ioctl,
208 	.l_rint = bth5_slip_receive,
209 	.l_start = bth5_slip_transmit,
210 	.l_modem = ttymodem,
211 	.l_poll = ttyerrpoll
212 };
213 
214 static const struct hci_if bth5_hci = {
215 	.enable = bth5_enable,
216 	.disable = bth5_disable,
217 	.output_cmd = bth5_output_cmd,
218 	.output_acl = bth5_output_acl,
219 	.output_sco = bth5_output_sco,
220 	.get_stats = bth5_stats,
221 	.ipl = IPL_TTY,
222 };
223 
224 /* ARGSUSED */
225 void
226 bthfiveattach(int num __unused)
227 {
228 	int error;
229 
230 	error = ttyldisc_attach(&bth5_disc);
231 	if (error) {
232 		aprint_error("%s: unable to register line discipline, "
233 		    "error = %d\n", bthfive_cd.cd_name, error);
234 		return;
235 	}
236 
237 	error = config_cfattach_attach(bthfive_cd.cd_name, &bthfive_ca);
238 	if (error) {
239 		aprint_error("%s: unable to register cfattach, error = %d\n",
240 		    bthfive_cd.cd_name, error);
241 		config_cfdriver_detach(&bthfive_cd);
242 		(void) ttyldisc_detach(&bth5_disc);
243 	}
244 }
245 
246 /*
247  * Autoconf match routine.
248  *
249  * XXX: unused: config_attach_pseudo(9) does not call ca_match.
250  */
251 /* ARGSUSED */
252 static int
253 bthfive_match(device_t self __unused, cfdata_t cfdata __unused,
254 	   void *arg __unused)
255 {
256 
257 	/* pseudo-device; always present */
258 	return 1;
259 }
260 
261 /*
262  * Autoconf attach routine.  Called by config_attach_pseudo(9) when we
263  * open the line discipline.
264  */
265 /* ARGSUSED */
266 static void
267 bthfive_attach(device_t parent __unused, device_t self, void *aux __unused)
268 {
269 	struct bth5_softc *sc = device_private(self);
270 	const struct sysctlnode *node;
271 	int rc, bth5_node_num;
272 
273 	aprint_normal("\n");
274 	aprint_naive("\n");
275 
276 	sc->sc_dev = self;
277 	callout_init(&sc->sc_seq_timer, 0);
278 	callout_setfunc(&sc->sc_seq_timer, bth5_timer_timeout, sc);
279 	callout_init(&sc->sc_le_timer, 0);
280 	callout_setfunc(&sc->sc_le_timer, bth5_le_timeout, sc);
281 	sc->sc_seq_timeout = BTH5_SEQ_TX_TIMEOUT;
282 	sc->sc_seq_winsize = BTH5_SEQ_TX_WINSIZE;
283 	sc->sc_seq_retry_limit = BTH5_SEQ_TX_RETRY_LIMIT;
284 	MBUFQ_INIT(&sc->sc_seqq);
285 	MBUFQ_INIT(&sc->sc_seq_retryq);
286 	MBUFQ_INIT(&sc->sc_dgq);
287 	MBUFQ_INIT(&sc->sc_cmdq);
288 	MBUFQ_INIT(&sc->sc_aclq);
289 	MBUFQ_INIT(&sc->sc_scoq);
290 
291 	/* Attach Bluetooth unit */
292 	sc->sc_unit = hci_attach_pcb(&bth5_hci, self, 0);
293 
294 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
295 	    0, CTLTYPE_NODE, device_xname(self),
296 	    SYSCTL_DESCR("bth5 controls"),
297 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
298 		goto err;
299 	}
300 	bth5_node_num = node->sysctl_num;
301 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
302 	    CTLFLAG_READWRITE, CTLTYPE_BOOL,
303 	    "muzzled", SYSCTL_DESCR("muzzled for Link-establishment Layer"),
304 	    NULL, 0, &sc->sc_le_muzzled,
305 	    0, CTL_HW, bth5_node_num, CTL_CREATE, CTL_EOL)) != 0) {
306 		goto err;
307 	}
308 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
309 	    CTLFLAG_READWRITE, CTLTYPE_INT,
310 	    "txcrc", SYSCTL_DESCR("txcrc for Packet Integrity Layer"),
311 	    NULL, 0, &sc->sc_pi_txcrc,
312 	    0, CTL_HW, bth5_node_num, CTL_CREATE, CTL_EOL)) != 0) {
313 		goto err;
314 	}
315 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
316 	    CTLFLAG_READWRITE, CTLTYPE_INT,
317 	    "timeout", SYSCTL_DESCR("timeout for Sequencing Layer"),
318 	    NULL, 0, &sc->sc_seq_timeout,
319 	    0, CTL_HW, bth5_node_num, CTL_CREATE, CTL_EOL)) != 0) {
320 		goto err;
321 	}
322 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
323 	    CTLFLAG_READWRITE, CTLTYPE_INT,
324 	    "winsize", SYSCTL_DESCR("winsize for Sequencing Layer"),
325 	    NULL, 0, &sc->sc_seq_winsize,
326 	    0, CTL_HW, bth5_node_num, CTL_CREATE, CTL_EOL)) != 0) {
327 		goto err;
328 	}
329 	if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
330 	    CTLFLAG_READWRITE, CTLTYPE_INT,
331 	    "retry_limit", SYSCTL_DESCR("retry limit for Sequencing Layer"),
332 	    NULL, 0, &sc->sc_seq_retry_limit,
333 	    0, CTL_HW, bth5_node_num, CTL_CREATE, CTL_EOL)) != 0) {
334 		goto err;
335 	}
336 	return;
337 
338 err:
339 	aprint_error_dev(self, "sysctl_createv failed (rc = %d)\n", rc);
340 }
341 
342 /*
343  * Autoconf detach routine.  Called when we close the line discipline.
344  */
345 /* ARGSUSED */
346 static int
347 bthfive_detach(device_t self, int flags __unused)
348 {
349 	struct bth5_softc *sc = device_private(self);
350 
351 	if (sc->sc_unit != NULL) {
352 		hci_detach_pcb(sc->sc_unit);
353 		sc->sc_unit = NULL;
354 	}
355 
356 	callout_halt(&sc->sc_seq_timer, NULL);
357 	callout_destroy(&sc->sc_seq_timer);
358 
359 	callout_halt(&sc->sc_le_timer, NULL);
360 	callout_destroy(&sc->sc_le_timer);
361 
362 	return 0;
363 }
364 
365 
366 /*
367  * Line discipline functions.
368  */
369 /* ARGSUSED */
370 static int
371 bth5open(dev_t device __unused, struct tty *tp)
372 {
373 	struct bth5_softc *sc;
374 	device_t dev;
375 	cfdata_t cfdata;
376 	struct lwp *l = curlwp;		/* XXX */
377 	int error, unit, s;
378 	static char name[] = "bthfive";
379 
380 	error = kauth_authorize_device(l->l_cred, KAUTH_DEVICE_BLUETOOTH_BCSP,
381 	    KAUTH_ARG(KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD), NULL, NULL, NULL);
382 	if (error)
383 		return (error);
384 
385 	s = spltty();
386 
387 	if (tp->t_linesw == &bth5_disc) {
388 		sc = tp->t_sc;
389 		if (sc != NULL) {
390 			splx(s);
391 			return EBUSY;
392 		}
393 	}
394 
395 	KASSERT(tp->t_oproc != NULL);
396 
397 	cfdata = malloc(sizeof(struct cfdata), M_DEVBUF, M_WAITOK);
398 	for (unit = 0; unit < bthfive_cd.cd_ndevs; unit++)
399 		if (device_lookup(&bthfive_cd, unit) == NULL)
400 			break;
401 	cfdata->cf_name = name;
402 	cfdata->cf_atname = name;
403 	cfdata->cf_unit = unit;
404 	cfdata->cf_fstate = FSTATE_STAR;
405 
406 	aprint_normal("%s%d at tty major %llu minor %llu",
407 	    name, unit, (unsigned long long)major(tp->t_dev),
408 	    (unsigned long long)minor(tp->t_dev));
409 	dev = config_attach_pseudo(cfdata);
410 	if (dev == NULL) {
411 		splx(s);
412 		return EIO;
413 	}
414 	sc = device_private(dev);
415 
416 	mutex_spin_enter(&tty_lock);
417 	tp->t_sc = sc;
418 	sc->sc_tp = tp;
419 	ttyflush(tp, FREAD | FWRITE);
420 	mutex_spin_exit(&tty_lock);
421 
422 	splx(s);
423 
424 	sc->sc_slip_txrsv = BTH5_SLIP_PKTSTART;
425 	bth5_sequencing_reset(sc);
426 
427 	/* start link-establishment */
428 	bth5_start_le(sc);
429 
430 	return 0;
431 }
432 
433 /* ARGSUSED */
434 static int
435 bth5close(struct tty *tp, int flag __unused)
436 {
437 	struct bth5_softc *sc = tp->t_sc;
438 	cfdata_t cfdata;
439 	int s;
440 
441 	/* terminate link-establishment */
442 	bth5_terminate_le(sc);
443 
444 	s = spltty();
445 
446 	MBUFQ_DRAIN(&sc->sc_dgq);
447 	bth5_sequencing_reset(sc);
448 
449 	mutex_spin_enter(&tty_lock);
450 	ttyflush(tp, FREAD | FWRITE);
451 	mutex_spin_exit(&tty_lock);	/* XXX */
452 	ttyldisc_release(tp->t_linesw);
453 	tp->t_linesw = ttyldisc_default();
454 	if (sc != NULL) {
455 		tp->t_sc = NULL;
456 		if (sc->sc_tp == tp) {
457 			cfdata = device_cfdata(sc->sc_dev);
458 			config_detach(sc->sc_dev, 0);
459 			free(cfdata, M_DEVBUF);
460 		}
461 
462 	}
463 	splx(s);
464 	return 0;
465 }
466 
467 /* ARGSUSED */
468 static int
469 bth5ioctl(struct tty *tp, u_long cmd, void *data, int flag __unused,
470 	  struct lwp *l __unused)
471 {
472 	struct bth5_softc *sc = tp->t_sc;
473 	int error;
474 
475 	if (sc == NULL || tp != sc->sc_tp)
476 		return EPASSTHROUGH;
477 
478 	error = 0;
479 	switch (cmd) {
480 	default:
481 		error = EPASSTHROUGH;
482 		break;
483 	}
484 
485 	return error;
486 }
487 
488 
489 /*
490  * UART Driver Layer is supported by com-driver.
491  */
492 
493 /*
494  * BTH5 SLIP Layer functions:
495  *   Supports to transmit/receive a byte stream.
496  *   SLIP protocol described in Internet standard RFC 1055.
497  */
498 static int
499 bth5_slip_transmit(struct tty *tp)
500 {
501 	struct bth5_softc *sc = tp->t_sc;
502 	struct mbuf *m;
503 	int count, rlen;
504 	uint8_t *rptr;
505 	int s;
506 
507 	m = sc->sc_txp;
508 	if (m == NULL) {
509 		s = spltty();
510 		sc->sc_flags &= ~BTH5_XMIT;
511 		splx(s);
512 		bth5_mux_transmit(sc);
513 		return 0;
514 	}
515 
516 	count = 0;
517 	rlen = 0;
518 	rptr = mtod(m, uint8_t *);
519 
520 	if (sc->sc_slip_txrsv != 0) {
521 #ifdef BTH5_DEBUG
522 		if (sc->sc_slip_txrsv == BTH5_SLIP_PKTSTART)
523 			DPRINTFN(4, ("%s: slip transmit start\n",
524 			    device_xname(sc->sc_dev)));
525 		else
526 			DPRINTFN(4, ("0x%02x ", sc->sc_slip_txrsv));
527 #endif
528 
529 		if (putc(sc->sc_slip_txrsv, &tp->t_outq) < 0)
530 			return 0;
531 		count++;
532 
533 		if (sc->sc_slip_txrsv == BTH5_SLIP_ESCAPE_PKTEND ||
534 		    sc->sc_slip_txrsv == BTH5_SLIP_ESCAPE_ESCAPE) {
535 			rlen++;
536 			rptr++;
537 		}
538 		if (sc->sc_oof_flow_control == true) {
539 			if (sc->sc_slip_txrsv == BTH5_SLIP_ESCAPE_XON ||
540 			    sc->sc_slip_txrsv == BTH5_SLIP_ESCAPE_XOFF) {
541 				rlen++;
542 				rptr++;
543 			}
544 		}
545 
546 		sc->sc_slip_txrsv = 0;
547 	}
548 
549 	for(;;) {
550 		if (rlen >= m->m_len) {
551 			m = m->m_next;
552 			if (m == NULL) {
553 				if (putc(BTH5_SLIP_PKTEND, &tp->t_outq) < 0)
554 					break;
555 
556 				DPRINTFN(4, ("\n%s: slip transmit end\n",
557 				    device_xname(sc->sc_dev)));
558 
559 				m = sc->sc_txp;
560 				sc->sc_txp = NULL;
561 				sc->sc_slip_txrsv = BTH5_SLIP_PKTSTART;
562 
563 				sc->sc_transmit_callback(sc, m);
564 				m = NULL;
565 				break;
566 			}
567 
568 			rlen = 0;
569 			rptr = mtod(m, uint8_t *);
570 			continue;
571 		}
572 
573 		if (*rptr == BTH5_SLIP_PKTEND) {
574 			if (putc(BTH5_SLIP_ESCAPE, &tp->t_outq) < 0)
575 				break;
576 			count++;
577 			DPRINTFN(4, (" esc "));
578 
579 			if (putc(BTH5_SLIP_ESCAPE_PKTEND, &tp->t_outq) < 0) {
580 				sc->sc_slip_txrsv = BTH5_SLIP_ESCAPE_PKTEND;
581 				break;
582 			}
583 			DPRINTFN(4, ("0x%02x ", BTH5_SLIP_ESCAPE_PKTEND));
584 			rptr++;
585 		} else if (sc->sc_oof_flow_control == true && *rptr ==
586 							 BTH5_SLIP_XON) {
587 			if (putc(BTH5_SLIP_ESCAPE, &tp->t_outq) < 0)
588 				break;
589 			count++;
590 			DPRINTFN(4, (" esc "));
591 
592 			if (putc(BTH5_SLIP_ESCAPE_XON, &tp->t_outq) < 0) {
593 				sc->sc_slip_txrsv = BTH5_SLIP_ESCAPE_XON;
594 				break;
595 			}
596 			DPRINTFN(4, ("0x%02x ", BTH5_SLIP_ESCAPE_XON));
597 			rptr++;
598 		} else if (sc->sc_oof_flow_control == true && *rptr ==
599 							 BTH5_SLIP_XOFF) {
600 			if (putc(BTH5_SLIP_ESCAPE, &tp->t_outq) < 0)
601 				break;
602 			count++;
603 			DPRINTFN(4, (" esc "));
604 
605 			if (putc(BTH5_SLIP_ESCAPE_XOFF, &tp->t_outq) < 0) {
606 				sc->sc_slip_txrsv = BTH5_SLIP_ESCAPE_XOFF;
607 				break;
608 			}
609 			DPRINTFN(4, ("0x%02x ", BTH5_SLIP_ESCAPE_XOFF));
610 			rptr++;
611 		} else if (*rptr == BTH5_SLIP_ESCAPE) {
612 			if (putc(BTH5_SLIP_ESCAPE, &tp->t_outq) < 0)
613 				break;
614 			count++;
615 			DPRINTFN(4, (" esc "));
616 
617 			if (putc(BTH5_SLIP_ESCAPE_ESCAPE, &tp->t_outq) < 0) {
618 				sc->sc_slip_txrsv = BTH5_SLIP_ESCAPE_ESCAPE;
619 				break;
620 			}
621 			DPRINTFN(4, ("0x%02x ", BTH5_SLIP_ESCAPE_ESCAPE));
622 			rptr++;
623 		} else {
624 			if (putc(*rptr++, &tp->t_outq) < 0)
625 				break;
626 			DPRINTFN(4, ("0x%02x ", *(rptr - 1)));
627 		}
628 		rlen++;
629 		count++;
630 	}
631 	if (m != NULL)
632 		m_adj(m, rlen);
633 
634 	sc->sc_stats.byte_tx += count;
635 
636 	if (tp->t_outq.c_cc != 0)
637 		(*tp->t_oproc)(tp);
638 
639 	return 0;
640 }
641 
642 static int
643 bth5_slip_receive(int c, struct tty *tp)
644 {
645 	struct bth5_softc *sc = tp->t_sc;
646 	struct mbuf *m = sc->sc_rxp;
647 	int discard = 0;
648 	const char *errstr;
649 
650 	c &= TTY_CHARMASK;
651 
652 	/* If we already started a packet, find the trailing end of it. */
653 	if (m) {
654 		while (m->m_next)
655 			m = m->m_next;
656 
657 		if (M_TRAILINGSPACE(m) == 0) {
658 			/* extend mbuf */
659 			MGET(m->m_next, M_DONTWAIT, MT_DATA);
660 			if (m->m_next == NULL) {
661 				aprint_error_dev(sc->sc_dev,
662 				    "out of memory\n");
663 				sc->sc_stats.err_rx++;
664 				return 0;	/* (lost sync) */
665 			}
666 
667 			m = m->m_next;
668 			m->m_len = 0;
669 		}
670 	} else
671 		if (c != BTH5_SLIP_PKTSTART) {
672 			discard = 1;
673 			errstr = "not sync";
674 			goto discarded;
675 		}
676 
677 	switch (c) {
678 	case BTH5_SLIP_PKTSTART /* or _PKTEND */:
679 		if (m == NULL) {
680 			/* BTH5_SLIP_PKTSTART */
681 
682 			DPRINTFN(4, ("%s: slip receive start\n",
683 			    device_xname(sc->sc_dev)));
684 
685 			/* new packet */
686 			MGETHDR(m, M_DONTWAIT, MT_DATA);
687 			if (m == NULL) {
688 				aprint_error_dev(sc->sc_dev,
689 				    "out of memory\n");
690 				sc->sc_stats.err_rx++;
691 				return 0;	/* (lost sync) */
692 			}
693 
694 			sc->sc_rxp = m;
695 			m->m_pkthdr.len = m->m_len = 0;
696 			sc->sc_slip_rxexp = 0;
697 		} else {
698 			/* BTH5_SLIP_PKTEND */
699 
700 			if (m == sc->sc_rxp && m->m_len == 0) {
701 				DPRINTFN(4, ("%s: resynchronises\n",
702 				    device_xname(sc->sc_dev)));
703 
704 				sc->sc_stats.byte_rx++;
705 				return 0;
706 			}
707 
708 			DPRINTFN(4, ("%s%s: slip receive end\n",
709 			    (m->m_len % 16 != 0) ? "\n" :  "",
710 			    device_xname(sc->sc_dev)));
711 
712 			bth5_pktintegrity_receive(sc, sc->sc_rxp);
713 			sc->sc_rxp = NULL;
714 			sc->sc_slip_rxexp = BTH5_SLIP_PKTSTART;
715 		}
716 		sc->sc_stats.byte_rx++;
717 		return 0;
718 
719 	case BTH5_SLIP_ESCAPE:
720 
721 		DPRINTFN(4, ("  esc"));
722 
723 		if (sc->sc_slip_rxexp == BTH5_SLIP_ESCAPE) {
724 			discard = 1;
725 			errstr = "waiting 0xdc or 0xdb or 0xde of 0xdf";
726 		} else
727 			sc->sc_slip_rxexp = BTH5_SLIP_ESCAPE;
728 		break;
729 
730 	default:
731 		DPRINTFN(4, (" 0x%02x%s",
732 		    c, (m->m_len % 16 == 15) ? "\n" :  ""));
733 
734 		switch (sc->sc_slip_rxexp) {
735 		case BTH5_SLIP_PKTSTART:
736 			discard = 1;
737 			errstr = "waiting 0xc0";
738 			break;
739 
740 		case BTH5_SLIP_ESCAPE:
741 			if (c == BTH5_SLIP_ESCAPE_PKTEND)
742 				mtod(m, uint8_t *)[m->m_len++] =
743 				    BTH5_SLIP_PKTEND;
744 			else if (sc->sc_oof_flow_control == true &&
745 						c == BTH5_SLIP_ESCAPE_XON)
746 				mtod(m, uint8_t *)[m->m_len++] =
747 				    BTH5_SLIP_XON;
748 			else if (sc->sc_oof_flow_control == true &&
749 						c == BTH5_SLIP_ESCAPE_XOFF)
750 				mtod(m, uint8_t *)[m->m_len++] =
751 				    BTH5_SLIP_XOFF;
752 			else if (c == BTH5_SLIP_ESCAPE_ESCAPE)
753 				mtod(m, uint8_t *)[m->m_len++] =
754 				    BTH5_SLIP_ESCAPE;
755 			else {
756 				discard = 1;
757 				errstr = "unknown escape";
758 			}
759 			sc->sc_slip_rxexp = 0;
760 			break;
761 
762 		default:
763 			mtod(m, uint8_t *)[m->m_len++] = c;
764 		}
765 		sc->sc_rxp->m_pkthdr.len++;
766 	}
767 	if (discard) {
768 discarded:
769 #ifdef BTH5_DEBUG
770 		DPRINTFN(4, ("%s: receives unexpected byte 0x%02x: %s\n",
771 		    device_xname(sc->sc_dev), c, errstr));
772 #else
773 		__USE(errstr);
774 #endif
775 	}
776 	sc->sc_stats.byte_rx++;
777 
778 	return 0;
779 }
780 
781 
782 /*
783  * BTH5 Packet Integrity Layer functions:
784  *   handling Payload Length, Checksum, CRC.
785  */
786 static void
787 bth5_pktintegrity_transmit(struct bth5_softc *sc)
788 {
789 	struct mbuf *m = sc->sc_txp;
790 	bth5_hdr_t *hdrp = mtod(m, bth5_hdr_t *);
791 	int pldlen;
792 
793 	DPRINTFN(3, ("%s: pi transmit\n", device_xname(sc->sc_dev)));
794 
795 	pldlen = m->m_pkthdr.len - sizeof(bth5_hdr_t);
796 
797 	if (sc->sc_pi_txcrc)
798 		hdrp->flags |= BTH5_FLAGS_CRC_PRESENT;
799 
800 	BTH5_SET_PLEN(hdrp, pldlen);
801 	BTH5_SET_CSUM(hdrp);
802 
803 	if (sc->sc_pi_txcrc) {
804 		struct mbuf *_m;
805 		int n = 0;
806 		uint16_t crc = 0xffff;
807 		uint8_t *buf;
808 
809 		for (_m = m; _m != NULL; _m = _m->m_next) {
810 			buf = mtod(_m, uint8_t *);
811 			for (n = 0; n < _m->m_len; n++)
812 				bth5_crc_update(&crc, *(buf + n));
813 		}
814 		crc = htobe16(bth5_crc_reverse(crc));
815 		m_copyback(m, m->m_pkthdr.len, sizeof(crc), &crc);
816 	}
817 
818 #ifdef BTH5_DEBUG
819 	if (bth5_debug == 3)
820 		bth5_packet_print(m);
821 #endif
822 
823 	bth5_slip_transmit(sc->sc_tp);
824 }
825 
826 static void
827 bth5_pktintegrity_receive(struct bth5_softc *sc, struct mbuf *m)
828 {
829 	bth5_hdr_t *hdrp = mtod(m, bth5_hdr_t *);
830 	u_int pldlen;
831 	int discard = 0;
832 	uint16_t crc = 0xffff;
833 	const char *errstr;
834 
835 	DPRINTFN(3, ("%s: pi receive\n", device_xname(sc->sc_dev)));
836 #ifdef BTH5_DEBUG
837 	if (bth5_debug == 4)
838 		bth5_packet_print(m);
839 #endif
840 
841 	KASSERT(m->m_len >= sizeof(bth5_hdr_t));
842 
843 	pldlen = m->m_pkthdr.len - sizeof(bth5_hdr_t) -
844 	    ((hdrp->flags & BTH5_FLAGS_CRC_PRESENT) ? sizeof(crc) : 0);
845 	if (pldlen > 0xfff) {
846 		discard = 1;
847 		errstr = "Payload Length";
848 		goto discarded;
849 	}
850 	if (hdrp->csum != BTH5_GET_CSUM(hdrp)) {
851 		discard = 1;
852 		errstr = "Checksum";
853 		goto discarded;
854 	}
855 	if (BTH5_GET_PLEN(hdrp) != pldlen) {
856 		discard = 1;
857 		errstr = "Payload Length";
858 		goto discarded;
859 	}
860 	if (hdrp->flags & BTH5_FLAGS_CRC_PRESENT) {
861 		struct mbuf *_m;
862 		int i, n;
863 		uint16_t crc0;
864 		uint8_t *buf;
865 
866 		i = 0;
867 		n = 0;
868 		for (_m = m; _m != NULL; _m = _m->m_next) {
869 			buf = mtod(m, uint8_t *);
870 			for (n = 0;
871 			    n < _m->m_len && i < sizeof(bth5_hdr_t) + pldlen;
872 			    n++, i++)
873 				bth5_crc_update(&crc, *(buf + n));
874 		}
875 
876 		m_copydata(_m, n, sizeof(crc0), &crc0);
877 		if (be16toh(crc0) != bth5_crc_reverse(crc)) {
878 			discard = 1;
879 			errstr = "CRC";
880 		} else
881 			/* Shaves CRC */
882 			m_adj(m, (int)(0 - sizeof(crc)));
883 	}
884 
885 	if (discard) {
886 discarded:
887 #ifdef BTH5_DEBUG
888 		DPRINTFN(3, ("%s: receives unexpected packet: %s\n",
889 		    device_xname(sc->sc_dev), errstr));
890 #else
891 		__USE(errstr);
892 #endif
893 		m_freem(m);
894 	} else
895 		bth5_mux_receive(sc, m);
896 }
897 
898 static const uint16_t crctbl[] = {
899 	0x0000, 0x1081, 0x2102, 0x3183,
900 	0x4204, 0x5285, 0x6306, 0x7387,
901 	0x8408, 0x9489, 0xa50a, 0xb58b,
902 	0xc60c, 0xd68d, 0xe70e, 0xf78f,
903 };
904 
905 static void
906 bth5_crc_update(uint16_t *crc, uint8_t d)
907 {
908 	uint16_t reg = *crc;
909 
910 	reg = (reg >> 4) ^ crctbl[(reg ^ d) & 0x000f];
911 	reg = (reg >> 4) ^ crctbl[(reg ^ (d >> 4)) & 0x000f];
912 
913 	*crc = reg;
914 }
915 
916 static uint16_t
917 bth5_crc_reverse(uint16_t crc)
918 {
919 	uint16_t b, rev;
920 
921 	for (b = 0, rev = 0; b < 16; b++) {
922 		rev = rev << 1;
923 		rev |= (crc & 1);
924 		crc = crc >> 1;
925 	}
926 
927 	return rev;
928 }
929 
930 
931 /*
932  * BTH5 MUX Layer functions
933  */
934 static void
935 bth5_mux_transmit(struct bth5_softc *sc)
936 {
937 	struct mbuf *m;
938 	bth5_hdr_t *hdrp;
939 	int s;
940 
941 	DPRINTFN(2, ("%s: mux transmit: sc_flags=0x%x, choke=%d",
942 	    device_xname(sc->sc_dev), sc->sc_flags, sc->sc_mux_choke));
943 
944 	if (sc->sc_mux_choke) {
945 		struct mbuf *_m = NULL;
946 
947 		/* In this case, send only Link Establishment packet */
948 		for (m = MBUFQ_FIRST(&sc->sc_dgq); m != NULL;
949 		    _m = m, m = MBUFQ_NEXT(m)) {
950 			hdrp = mtod(m, bth5_hdr_t *);
951 			if (hdrp->ident == BTH5_CHANNEL_LE) {
952 				if (m == MBUFQ_FIRST(&sc->sc_dgq))
953 					MBUFQ_DEQUEUE(&sc->sc_dgq, m);
954 				else {
955 					if (m->m_nextpkt == NULL)
956 						sc->sc_dgq.mq_last =
957 						    &_m->m_nextpkt;
958 					_m->m_nextpkt = m->m_nextpkt;
959 					m->m_nextpkt = NULL;
960 				}
961 				goto transmit;
962 			}
963 		}
964 		DPRINTFN(2, ("\n"));
965 		return;
966 	}
967 
968 	/*
969 	 * The MUX Layer always gives priority to packets from the Datagram
970 	 * Queue Layer over the Sequencing Layer.
971 	 */
972 	if (MBUFQ_FIRST(&sc->sc_dgq)) {
973 		MBUFQ_DEQUEUE(&sc->sc_dgq, m);
974 		goto transmit;
975 	}
976 	if (MBUFQ_FIRST(&sc->sc_seqq)) {
977 		MBUFQ_DEQUEUE(&sc->sc_seqq, m);
978 		hdrp = mtod(m, bth5_hdr_t *);
979 		hdrp->flags |= BTH5_FLAGS_PROTOCOL_REL;		/* Reliable */
980 		goto transmit;
981 	}
982 
983 	s = spltty();
984 	if ((sc->sc_flags & BTH5_XMIT) == 0)
985 		bth5_start(sc);
986 	splx(s);
987 
988 	if (sc->sc_mux_send_ack == true) {
989 		m = bth5_create_ackpkt();
990 		if (m != NULL)
991 			goto transmit;
992 		aprint_error_dev(sc->sc_dev, "out of memory\n");
993 		sc->sc_stats.err_tx++;
994 	}
995 
996 	/* Nothing to send */
997 	DPRINTFN(2, ("\n"));
998 
999 	return;
1000 
1001 transmit:
1002 	DPRINTFN(2, (", txack=%d, send_ack=%d\n",
1003 	    bth5_get_txack(sc), sc->sc_mux_send_ack));
1004 
1005 	hdrp = mtod(m, bth5_hdr_t *);
1006 	hdrp->flags |=
1007 	    (bth5_get_txack(sc) << BTH5_FLAGS_ACK_SHIFT) & BTH5_FLAGS_ACK_MASK;
1008 	if (sc->sc_mux_send_ack == true)
1009 		sc->sc_mux_send_ack = false;
1010 
1011 #ifdef BTH5_DEBUG
1012 	if (bth5_debug == 3)
1013 		bth5_packet_print(m);
1014 #endif
1015 
1016 	sc->sc_txp = m;
1017 	bth5_pktintegrity_transmit(sc);
1018 }
1019 
1020 static void
1021 bth5_mux_receive(struct bth5_softc *sc, struct mbuf *m)
1022 {
1023 	bth5_hdr_t *hdrp = mtod(m, bth5_hdr_t *);
1024 	const u_int rxack = BTH5_FLAGS_ACK(hdrp->flags);
1025 
1026 	DPRINTFN(2, ("%s: mux receive: flags=0x%x, ident=%d, rxack=%d\n",
1027 	    device_xname(sc->sc_dev), hdrp->flags, hdrp->ident, rxack));
1028 #ifdef BTH5_DEBUG
1029 	if (bth5_debug == 3)
1030 		bth5_packet_print(m);
1031 #endif
1032 
1033 	bth5_signal_rxack(sc, rxack);
1034 
1035 	microtime(&sc->sc_mux_lastrx);
1036 
1037 	/* if the Ack Packet received then discard */
1038 	if (BTH5_FLAGS_SEQ(hdrp->flags) == 0 &&
1039 	    hdrp->ident == BTH5_IDENT_ACKPKT &&
1040 	    BTH5_GET_PLEN(hdrp) == 0) {
1041 		sc->sc_seq_txseq = BTH5_FLAGS_ACK(hdrp->flags);
1042 		bth5_send_ack_command(sc);
1043 		bth5_mux_transmit(sc);
1044 		m_freem(m);
1045 		return;
1046 	}
1047 
1048 	if (hdrp->flags & BTH5_FLAGS_PROTOCOL_REL)
1049 		bth5_sequencing_receive(sc, m);
1050 	else
1051 		bth5_datagramq_receive(sc, m);
1052 }
1053 
1054 static __inline void
1055 bth5_send_ack_command(struct bth5_softc *sc)
1056 {
1057 
1058 	DPRINTFN(2, ("%s: mux send_ack_command\n", device_xname(sc->sc_dev)));
1059 
1060 	sc->sc_mux_send_ack = true;
1061 }
1062 
1063 static __inline struct mbuf *
1064 bth5_create_ackpkt(void)
1065 {
1066 	struct mbuf *m;
1067 	bth5_hdr_t *hdrp;
1068 
1069 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1070 	if (m != NULL) {
1071 		m->m_pkthdr.len = m->m_len = sizeof(bth5_hdr_t);
1072 		hdrp = mtod(m, bth5_hdr_t *);
1073 		/*
1074 		 * An Ack Packet has the following fields:
1075 		 *	Ack Field:			txack (not set yet)
1076 		 *	Seq Field:			0
1077 		 *	Protocol Identifier Field:	0
1078 		 *	Protocol Type Field:		Any value
1079 		 *	Payload Length Field:		0
1080 		 */
1081 		memset(hdrp, 0, sizeof(bth5_hdr_t));
1082 	}
1083 	return m;
1084 }
1085 
1086 static __inline void
1087 bth5_set_choke(struct bth5_softc *sc, bool choke)
1088 {
1089 
1090 	DPRINTFN(2, ("%s: mux set choke=%d\n", device_xname(sc->sc_dev), choke));
1091 
1092 	sc->sc_mux_choke = choke;
1093 }
1094 
1095 
1096 /*
1097  * BTH5 Sequencing Layer functions
1098  */
1099 static void
1100 bth5_sequencing_receive(struct bth5_softc *sc, struct mbuf *m)
1101 {
1102 	bth5_hdr_t hdr;
1103 	uint32_t exp_rxseq, rxack, rxseq;
1104 
1105 	exp_rxseq = sc->sc_seq_expected_rxseq & BTH5_FLAGS_SEQ_MASK;
1106 	m_copydata(m, 0, sizeof(bth5_hdr_t), &hdr);
1107 	rxseq = BTH5_FLAGS_SEQ(hdr.flags);
1108 	rxack = BTH5_FLAGS_ACK(hdr.flags);
1109 
1110 	DPRINTFN(1, ("%s: seq receive: rxseq=%d, expected %d\n",
1111 	    device_xname(sc->sc_dev), rxseq, exp_rxseq));
1112 #ifdef BTH5_DEBUG
1113 	if (bth5_debug == 2)
1114 		bth5_packet_print(m);
1115 #endif
1116 
1117 	/*
1118 	 * We remove the header of BTH5 and add the 'uint8_t type' of
1119 	 * hci_*_hdr_t to the head.
1120 	 */
1121 	m_adj(m, sizeof(bth5_hdr_t) - sizeof(uint8_t));
1122 
1123 	if (rxseq != exp_rxseq) {
1124 		m_freem(m);
1125 
1126 		bth5_send_ack_command(sc);
1127 		/* send ack packet, if needly */
1128 		bth5_mux_transmit(sc);
1129 
1130 		return;
1131 	}
1132 
1133 	switch (hdr.ident) {
1134 	case BTH5_CHANNEL_HCI_CMD:
1135 		*(mtod(m, uint8_t *)) = HCI_CMD_PKT;
1136 		if (!hci_input_event(sc->sc_unit, m))
1137 			sc->sc_stats.err_rx++;
1138 
1139 		sc->sc_stats.evt_rx++;
1140 		break;
1141 
1142 	case BTH5_CHANNEL_HCI_EVT:
1143 		*(mtod(m, uint8_t *)) = HCI_EVENT_PKT;
1144 		if (!hci_input_event(sc->sc_unit, m))
1145 			sc->sc_stats.err_rx++;
1146 
1147 		sc->sc_stats.evt_rx++;
1148 		break;
1149 
1150 	case BTH5_CHANNEL_HCI_ACL:
1151 		*(mtod(m, uint8_t *)) = HCI_ACL_DATA_PKT;
1152 		if (!hci_input_acl(sc->sc_unit, m))
1153 			sc->sc_stats.err_rx++;
1154 
1155 		sc->sc_stats.acl_rx++;
1156 		break;
1157 
1158 	case BTH5_CHANNEL_HCI_SCO:
1159 		*(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1160 		if (!hci_input_sco(sc->sc_unit, m))
1161 			sc->sc_stats.err_rx++;
1162 
1163 		sc->sc_stats.sco_rx++;
1164 		break;
1165 
1166 	default:
1167 		aprint_error_dev(sc->sc_dev,
1168 		    "received reliable packet with not support channel %d\n",
1169 		    hdr.ident);
1170 		m_freem(m);
1171 		break;
1172 	}
1173 	bth5_send_ack_command(sc);
1174 	sc->sc_seq_txseq = rxack;
1175 	sc->sc_seq_expected_rxseq = (rxseq + 1) & BTH5_FLAGS_SEQ_MASK;
1176 	sc->sc_seq_total_rxpkts++;
1177 
1178 	if (sc->sc_seq_total_rxpkts % sc->sc_seq_winack == 0)
1179 		bth5_mux_transmit(sc);
1180 }
1181 
1182 static bool
1183 bth5_tx_reliable_pkt(struct bth5_softc *sc, struct mbuf *m, u_int protocol_id)
1184 {
1185 	bth5_hdr_t *hdrp;
1186 	struct mbuf *_m;
1187 	struct mbuf *_retrans;
1188 	u_int pldlen;
1189 	int s;
1190 
1191 	DPRINTFN(1, ("%s: seq transmit:"
1192 	    "protocol_id=%d, winspace=%d, txseq=%d\n", device_xname(sc->sc_dev),
1193 	    protocol_id, sc->sc_seq_winspace, sc->sc_seq_txseq));
1194 
1195 	for (pldlen = 0, _m = m; _m != NULL; _m = _m->m_next) {
1196 		if (_m->m_len < 0)
1197 			goto out;
1198 		pldlen += _m->m_len;
1199 	}
1200 	if (pldlen > 0xfff)
1201 		goto out;
1202 	if (protocol_id == BTH5_IDENT_ACKPKT || protocol_id > 15)
1203 		goto out;
1204 
1205 	if (sc->sc_seq_winspace == 0)
1206 		goto out;
1207 
1208 	M_PREPEND(m, sizeof(bth5_hdr_t), M_DONTWAIT);
1209 	if (m == NULL) {
1210 		aprint_error_dev(sc->sc_dev, "out of memory\n");
1211 		return false;
1212 	}
1213 	KASSERT(m->m_len >= sizeof(bth5_hdr_t));
1214 
1215 	hdrp = mtod(m, bth5_hdr_t *);
1216 	memset(hdrp, 0, sizeof(bth5_hdr_t));
1217 	hdrp->flags |= sc->sc_seq_txseq;
1218 	hdrp->ident = protocol_id;
1219 
1220 	callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1221 
1222 	s = splserial();
1223 	MBUFQ_ENQUEUE(&sc->sc_seqq, m);
1224 	splx(s);
1225 	sc->sc_transmit_callback = bth5_reliabletx_callback;
1226 
1227 #ifdef BTH5_DEBUG
1228 	if (bth5_debug == 2)
1229 		bth5_packet_print(m);
1230 #endif
1231 
1232 	sc->sc_seq_winspace--;
1233 	_retrans = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1234 	if (_retrans == NULL) {
1235 		aprint_error_dev(sc->sc_dev, "out of memory\n");
1236 		goto out;
1237 	}
1238 	MBUFQ_ENQUEUE(&sc->sc_seq_retryq, _retrans);
1239 	bth5_mux_transmit(sc);
1240 	sc->sc_seq_txseq = (sc->sc_seq_txseq + 1) & BTH5_FLAGS_SEQ_MASK;
1241 
1242 	return true;
1243 out:
1244 	m_freem(m);
1245 	return false;
1246 }
1247 
1248 static __inline u_int
1249 bth5_get_txack(struct bth5_softc *sc)
1250 {
1251 
1252 	return sc->sc_seq_expected_rxseq;
1253 }
1254 
1255 static void
1256 bth5_signal_rxack(struct bth5_softc *sc, uint32_t rxack)
1257 {
1258 	bth5_hdr_t *hdrp;
1259 	struct mbuf *m;
1260 	uint32_t seqno = (rxack - 1) & BTH5_FLAGS_SEQ_MASK;
1261 	int s;
1262 
1263 	DPRINTFN(1, ("%s: seq signal rxack: rxack=%d\n",
1264 	    device_xname(sc->sc_dev), rxack));
1265 
1266 	s = splserial();
1267 	m = MBUFQ_FIRST(&sc->sc_seq_retryq);
1268 	while (m != NULL) {
1269 		hdrp = mtod(m, bth5_hdr_t *);
1270 		if (BTH5_FLAGS_SEQ(hdrp->flags) == seqno) {
1271 			struct mbuf *m0;
1272 
1273 			for (m0 = MBUFQ_FIRST(&sc->sc_seq_retryq);
1274 			    m0 != MBUFQ_NEXT(m);
1275 			    m0 = MBUFQ_FIRST(&sc->sc_seq_retryq)) {
1276 				MBUFQ_DEQUEUE(&sc->sc_seq_retryq, m0);
1277 				m_freem(m0);
1278 				sc->sc_seq_winspace++;
1279 				if (sc->sc_seq_winspace > sc->sc_seq_winsize)
1280 					sc->sc_seq_winspace = sc->sc_seq_winsize;
1281 			}
1282 			break;
1283 		}
1284 		m = MBUFQ_NEXT(m);
1285 	}
1286 	splx(s);
1287 	sc->sc_seq_retries = 0;
1288 
1289 	if (sc->sc_seq_winspace == sc->sc_seq_winsize)
1290 		callout_stop(&sc->sc_seq_timer);
1291 	else
1292 		callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1293 }
1294 
1295 static void
1296 bth5_reliabletx_callback(struct bth5_softc *sc, struct mbuf *m)
1297 {
1298 
1299 	m_freem(m);
1300 }
1301 
1302 static void
1303 bth5_timer_timeout(void *arg)
1304 {
1305 	struct bth5_softc *sc = arg;
1306 	struct mbuf *m, *_m;
1307 	int s, i = 0;
1308 
1309 	DPRINTFN(1, ("%s: seq timeout: retries=%d\n",
1310 	    device_xname(sc->sc_dev), sc->sc_seq_retries));
1311 
1312 	bth5_send_ack_command(sc);
1313 	bth5_mux_transmit(sc);
1314 	s = splserial();
1315 	for (m = MBUFQ_FIRST(&sc->sc_seq_retryq); m != NULL;
1316 	    m = MBUFQ_NEXT(m)) {
1317 		_m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1318 		if (_m == NULL) {
1319 			aprint_error_dev(sc->sc_dev, "out of memory\n");
1320 			return;
1321 		}
1322 		MBUFQ_ENQUEUE(&sc->sc_seqq, _m);
1323 		i++;
1324 	}
1325 	splx(s);
1326 
1327 	if (i != 0) {
1328 		if (++sc->sc_seq_retries < sc->sc_seq_retry_limit)
1329 			callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1330 		else {
1331 			aprint_error_dev(sc->sc_dev,
1332 			    "reached the retry limit."
1333 			    " restart the link-establishment\n");
1334 			bth5_sequencing_reset(sc);
1335 			bth5_start_le(sc);
1336 			return;
1337 		}
1338 	}
1339 	bth5_mux_transmit(sc);
1340 }
1341 
1342 static void
1343 bth5_sequencing_reset(struct bth5_softc *sc)
1344 {
1345 	int s;
1346 
1347 	s = splserial();
1348 	MBUFQ_DRAIN(&sc->sc_seqq);
1349 	MBUFQ_DRAIN(&sc->sc_seq_retryq);
1350 	splx(s);
1351 
1352 
1353 	sc->sc_seq_txseq = 0;
1354 	sc->sc_seq_winspace = sc->sc_seq_winsize;
1355 	sc->sc_seq_retries = 0;
1356 	callout_stop(&sc->sc_seq_timer);
1357 
1358 	sc->sc_mux_send_ack = false;
1359 
1360 	/* XXXX: expected_rxseq should be set by MUX Layer */
1361 	sc->sc_seq_expected_rxseq = 0;
1362 	sc->sc_seq_total_rxpkts = 0;
1363 }
1364 
1365 
1366 /*
1367  * BTH5 Datagram Queue Layer functions
1368  */
1369 static void
1370 bth5_datagramq_receive(struct bth5_softc *sc, struct mbuf *m)
1371 {
1372 	bth5_hdr_t hdr;
1373 
1374 	DPRINTFN(1, ("%s: dgq receive\n", device_xname(sc->sc_dev)));
1375 #ifdef BTH5_DEBUG
1376 	if (bth5_debug == 2)
1377 		bth5_packet_print(m);
1378 #endif
1379 
1380 	m_copydata(m, 0, sizeof(bth5_hdr_t), &hdr);
1381 
1382 	switch (hdr.ident) {
1383 	case BTH5_CHANNEL_LE:
1384 		m_adj(m, sizeof(bth5_hdr_t));
1385 		bth5_input_le(sc, m);
1386 		break;
1387 
1388 	case BTH5_CHANNEL_HCI_SCO:
1389 		/*
1390 		 * We remove the header of BTH5 and add the 'uint8_t type' of
1391 		 * hci_scodata_hdr_t to the head.
1392 		 */
1393 		m_adj(m, sizeof(bth5_hdr_t) - sizeof(uint8_t));
1394 		*(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1395 		if (!hci_input_sco(sc->sc_unit, m))
1396 			sc->sc_stats.err_rx++;
1397 
1398 		sc->sc_stats.sco_rx++;
1399 		break;
1400 
1401 	default:
1402 		aprint_error_dev(sc->sc_dev,
1403 		    "received unreliable packet with not support channel %d\n",
1404 		    hdr.ident);
1405 		m_freem(m);
1406 		break;
1407 	}
1408 }
1409 
1410 static bool
1411 bth5_tx_unreliable_pkt(struct bth5_softc *sc, struct mbuf *m, u_int protocol_id)
1412 {
1413 	bth5_hdr_t *hdrp;
1414 	struct mbuf *_m;
1415 	u_int pldlen;
1416 	int s;
1417 
1418 	DPRINTFN(1, ("%s: dgq transmit: protocol_id=%d,",
1419 	    device_xname(sc->sc_dev), protocol_id));
1420 
1421 	for (pldlen = 0, _m = m; _m != NULL; _m = m->m_next) {
1422 		if (_m->m_len < 0)
1423 			goto out;
1424 		pldlen += _m->m_len;
1425 	}
1426 	DPRINTFN(1, (" pldlen=%d\n", pldlen));
1427 	if (pldlen > 0xfff)
1428 		goto out;
1429 	if (protocol_id == BTH5_IDENT_ACKPKT || protocol_id > 15)
1430 		goto out;
1431 
1432 	M_PREPEND(m, sizeof(bth5_hdr_t), M_DONTWAIT);
1433 	if (m == NULL) {
1434 		aprint_error_dev(sc->sc_dev, "out of memory\n");
1435 		return false;
1436 	}
1437 	KASSERT(m->m_len >= sizeof(bth5_hdr_t));
1438 
1439 	hdrp = mtod(m, bth5_hdr_t *);
1440 	memset(hdrp, 0, sizeof(bth5_hdr_t));
1441 	hdrp->ident = protocol_id;
1442 
1443 	s = splserial();
1444 	MBUFQ_ENQUEUE(&sc->sc_dgq, m);
1445 	splx(s);
1446 	sc->sc_transmit_callback = bth5_unreliabletx_callback;
1447 
1448 #ifdef BTH5_DEBUG
1449 	if (bth5_debug == 2)
1450 		bth5_packet_print(m);
1451 #endif
1452 
1453 	bth5_mux_transmit(sc);
1454 
1455 	return true;
1456 out:
1457 	m_freem(m);
1458 	return false;
1459 }
1460 
1461 static void
1462 bth5_unreliabletx_callback(struct bth5_softc *sc, struct mbuf *m)
1463 {
1464 
1465 	if (M_GETCTX(m, void *) == NULL)
1466 		m_freem(m);
1467 	else if (!hci_complete_sco(sc->sc_unit, m))
1468 		sc->sc_stats.err_tx++;
1469 }
1470 
1471 
1472 /*
1473  * BTUART H5 Link Establishment Protocol functions
1474  */
1475 static const uint8_t sync[] = BTH5_LE_SYNC;
1476 static const uint8_t syncresp[] = BTH5_LE_SYNCRESP;
1477 static const uint8_t conf[] = BTH5_LE_CONF;
1478 static const uint8_t confresp[] = BTH5_LE_CONFRESP;
1479 
1480 static int
1481 bth5_start_le(struct bth5_softc *sc)
1482 {
1483 
1484 	DPRINTF(("%s: start link-establish\n", device_xname(sc->sc_dev)));
1485 
1486 	bth5_set_choke(sc, true);
1487 
1488 	if (!sc->sc_le_muzzled) {
1489 		struct mbuf *m;
1490 
1491 		m = m_gethdr(M_DONTWAIT, MT_DATA);
1492 		if (m == NULL) {
1493 			aprint_error_dev(sc->sc_dev,
1494 			    "le-packet transmit out of memory\n");
1495 			return ENOMEM;
1496 		}
1497 		m->m_pkthdr.len = m->m_len = 0;
1498 		m_copyback(m, 0, sizeof(sync), sync);
1499 		if (!bth5_tx_unreliable_pkt(sc, m, BTH5_CHANNEL_LE)) {
1500 			aprint_error_dev(sc->sc_dev,
1501 			    "le-packet transmit failed\n");
1502 			return EINVAL;
1503 		}
1504 	}
1505 	callout_schedule(&sc->sc_le_timer, BTH5_LE_TSHY_TIMEOUT);
1506 
1507 	sc->sc_le_state = le_state_shy;
1508 	return 0;
1509 }
1510 
1511 static void
1512 bth5_terminate_le(struct bth5_softc *sc)
1513 {
1514 	struct mbuf *m;
1515 
1516 	/* terminate link-establishment */
1517 	callout_stop(&sc->sc_le_timer);
1518 	bth5_set_choke(sc, true);
1519 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1520 	if (m == NULL)
1521 		aprint_error_dev(sc->sc_dev, "out of memory\n");
1522 	else {
1523 		/* length of le packets is 4 */
1524 		m->m_pkthdr.len = m->m_len = 0;
1525 		m_copyback(m, 0, sizeof(sync), sync);
1526 		if (!bth5_tx_unreliable_pkt(sc, m, BTH5_CHANNEL_LE))
1527 			aprint_error_dev(sc->sc_dev,
1528 			    "link-establishment terminations failed\n");
1529 	}
1530 }
1531 
1532 static void
1533 bth5_input_le(struct bth5_softc *sc, struct mbuf *m)
1534 {
1535 	uint16_t *rcvpkt;
1536 	int i, len;
1537 	uint8_t config[3];
1538 	const uint8_t *rplypkt;
1539 	static struct {
1540 		const char *type;
1541 		const uint8_t *datap;
1542 	} pkt[] = {
1543 		{ "sync",	sync },
1544 		{ "sync-resp",	syncresp },
1545 		{ "conf",	conf },
1546 		{ "conf-resp",	confresp },
1547 
1548 		{ NULL, 0 }
1549 	};
1550 
1551 	DPRINTFN(0, ("%s: le input: state %d, muzzled %d\n",
1552 	    device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1553 #ifdef BTH5_DEBUG
1554 	if (bth5_debug == 1)
1555 		bth5_packet_print(m);
1556 #endif
1557 
1558 	rcvpkt = mtod(m, uint16_t *);
1559 	i = 0;
1560 
1561 	/* length of le packets is 2 */
1562 	if (m->m_len >= sizeof(uint16_t))
1563 		for (i = 0; pkt[i].type != NULL; i++)
1564 			if (*(const uint16_t *)pkt[i].datap == *rcvpkt)
1565 				break;
1566 	if (m->m_len < sizeof(uint16_t) || pkt[i].type == NULL) {
1567 		aprint_error_dev(sc->sc_dev, "received unknown packet\n");
1568 		m_freem(m);
1569 		return;
1570 	}
1571 
1572 	len = m->m_len;
1573 
1574 	rplypkt = NULL;
1575 	switch (sc->sc_le_state) {
1576 	case le_state_shy:
1577 		if (*rcvpkt == *(const uint16_t *)sync) {
1578 			sc->sc_le_muzzled = false;
1579 			rplypkt = syncresp;
1580 		} else if (*rcvpkt == *(const uint16_t *)syncresp) {
1581 			DPRINTF(("%s: state change to curious\n",
1582 			    device_xname(sc->sc_dev)));
1583 			rplypkt = conf;
1584 			callout_schedule(&sc->sc_le_timer,
1585 			    BTH5_LE_TCONF_TIMEOUT);
1586 			sc->sc_le_state = le_state_curious;
1587 		} else
1588 			aprint_error_dev(sc->sc_dev,
1589 			    "received an unknown packet at shy\n");
1590 		break;
1591 
1592 	case le_state_curious:
1593 		if (*rcvpkt == *(const uint16_t *)sync)
1594 			rplypkt = syncresp;
1595 		else if (*rcvpkt == *(const uint16_t *)syncresp) {
1596 			rplypkt = conf;
1597 			len = 3;
1598 		}
1599 		else if (*rcvpkt == *(const uint16_t *)conf)
1600 			rplypkt = confresp;
1601 		else if (*rcvpkt == *(const uint16_t *)confresp &&
1602 				m->m_len == 3) {
1603 			DPRINTF(("%s: state change to garrulous:\n",
1604 			    device_xname(sc->sc_dev)));
1605 
1606 			memcpy(config, conf, sizeof(uint16_t));
1607 			config[2] = (uint8_t)rcvpkt[1];
1608 			sc->sc_seq_winack = config[2] & BTH5_CONFIG_ACK_MASK;
1609 			if (config[2] & BTH5_CONFIG_FLOW_MASK)
1610 				sc->sc_oof_flow_control = true;
1611 			else
1612 				sc->sc_oof_flow_control = false;
1613 
1614 			bth5_sequencing_reset(sc);
1615 			bth5_set_choke(sc, false);
1616 			callout_stop(&sc->sc_le_timer);
1617 			sc->sc_le_state = le_state_garrulous;
1618 		} else
1619 			aprint_error_dev(sc->sc_dev,
1620 			    "received unknown packet at curious\n");
1621 		break;
1622 
1623 	case le_state_garrulous:
1624 		if (*rcvpkt == *(const uint16_t *)conf)
1625 			rplypkt = confresp;
1626 		else if (*rcvpkt == *(const uint16_t *)sync) {
1627 			/* XXXXX */
1628 			aprint_error_dev(sc->sc_dev,
1629 			    "received sync! peer to reset?\n");
1630 
1631 			bth5_sequencing_reset(sc);
1632 			rplypkt = syncresp;
1633 			sc->sc_le_state = le_state_shy;
1634 		} else
1635 			aprint_error_dev(sc->sc_dev,
1636 			    "received unknown packet at garrulous\n");
1637 		break;
1638 	}
1639 
1640 	m_freem(m);
1641 
1642 	if (rplypkt != NULL) {
1643 		MGETHDR(m, M_DONTWAIT, MT_DATA);
1644 		if (m == NULL)
1645 			aprint_error_dev(sc->sc_dev, "out of memory\n");
1646 		else {
1647 			/* length of le packets is 2 */
1648 			m->m_pkthdr.len = m->m_len = 0;
1649 			if (rplypkt == (const uint8_t *)&config
1650 			    || rplypkt == confresp || rplypkt == conf)
1651 				m_copyback(m, 0, len, rplypkt);
1652 			else
1653 				m_copyback(m, 0, 2, rplypkt);
1654 			if (!bth5_tx_unreliable_pkt(sc, m, BTH5_CHANNEL_LE))
1655 				aprint_error_dev(sc->sc_dev,
1656 				    "le-packet transmit failed\n");
1657 		}
1658 	}
1659 }
1660 
1661 static void
1662 bth5_le_timeout(void *arg)
1663 {
1664 	struct bth5_softc *sc = arg;
1665 	struct mbuf *m;
1666 	int timeout;
1667 	const uint8_t *sndpkt = NULL;
1668 
1669 	DPRINTFN(0, ("%s: le timeout: state %d, muzzled %d\n",
1670 	    device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1671 
1672 	switch (sc->sc_le_state) {
1673 	case le_state_shy:
1674 		if (!sc->sc_le_muzzled)
1675 			sndpkt = sync;
1676 		timeout = BTH5_LE_TSHY_TIMEOUT;
1677 		break;
1678 
1679 	case le_state_curious:
1680 		sndpkt = conf;
1681 		timeout = BTH5_LE_TCONF_TIMEOUT;
1682 		break;
1683 
1684 	default:
1685 		aprint_error_dev(sc->sc_dev,
1686 		    "timeout happen at unknown state %d\n", sc->sc_le_state);
1687 		return;
1688 	}
1689 
1690 	if (sndpkt != NULL) {
1691 		MGETHDR(m, M_DONTWAIT, MT_DATA);
1692 		if (m == NULL)
1693 			aprint_error_dev(sc->sc_dev, "out of memory\n");
1694 		else {
1695 			/* length of le packets is 4 */
1696 			m->m_pkthdr.len = m->m_len = 0;
1697 			if (sndpkt == conf || sndpkt == confresp)
1698 				m_copyback(m, 0, 3, sndpkt);
1699 			else
1700 				m_copyback(m, 0, 2, sndpkt);
1701 			if (!bth5_tx_unreliable_pkt(sc, m, BTH5_CHANNEL_LE))
1702 				aprint_error_dev(sc->sc_dev,
1703 				    "le-packet transmit failed\n");
1704 		}
1705 	}
1706 
1707 	callout_schedule(&sc->sc_le_timer, timeout);
1708 }
1709 
1710 
1711 /*
1712  * BTUART H5 Serial Protocol functions.
1713  */
1714 static int
1715 bth5_enable(device_t self)
1716 {
1717 	struct bth5_softc *sc = device_private(self);
1718 	int s;
1719 
1720 	if (sc->sc_flags & BTH5_ENABLED)
1721 		return 0;
1722 
1723 	s = spltty();
1724 
1725 	sc->sc_flags |= BTH5_ENABLED;
1726 	sc->sc_flags &= ~BTH5_XMIT;
1727 
1728 	splx(s);
1729 
1730 	return 0;
1731 }
1732 
1733 static void
1734 bth5_disable(device_t self)
1735 {
1736 	struct bth5_softc *sc = device_private(self);
1737 	int s;
1738 
1739 	if ((sc->sc_flags & BTH5_ENABLED) == 0)
1740 		return;
1741 
1742 	s = spltty();
1743 
1744 	if (sc->sc_rxp) {
1745 		m_freem(sc->sc_rxp);
1746 		sc->sc_rxp = NULL;
1747 	}
1748 
1749 	if (sc->sc_txp) {
1750 		m_freem(sc->sc_txp);
1751 		sc->sc_txp = NULL;
1752 	}
1753 
1754 	MBUFQ_DRAIN(&sc->sc_cmdq);
1755 	MBUFQ_DRAIN(&sc->sc_aclq);
1756 	MBUFQ_DRAIN(&sc->sc_scoq);
1757 
1758 	sc->sc_flags &= ~BTH5_ENABLED;
1759 	splx(s);
1760 }
1761 
1762 static void
1763 bth5_start(struct bth5_softc *sc)
1764 {
1765 	struct mbuf *m;
1766 
1767 	KASSERT((sc->sc_flags & BTH5_XMIT) == 0);
1768 	KASSERT(sc->sc_txp == NULL);
1769 
1770 	if (MBUFQ_FIRST(&sc->sc_aclq)) {
1771 		MBUFQ_DEQUEUE(&sc->sc_aclq, m);
1772 		sc->sc_stats.acl_tx++;
1773 		sc->sc_flags |= BTH5_XMIT;
1774 		bth5_tx_reliable_pkt(sc, m, BTH5_CHANNEL_HCI_ACL);
1775 	}
1776 
1777 	if (MBUFQ_FIRST(&sc->sc_cmdq)) {
1778 		MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
1779 		sc->sc_stats.cmd_tx++;
1780 		sc->sc_flags |= BTH5_XMIT;
1781 		bth5_tx_reliable_pkt(sc, m, BTH5_CHANNEL_HCI_CMD);
1782 	}
1783 
1784 	if (MBUFQ_FIRST(&sc->sc_scoq)) {
1785 		MBUFQ_DEQUEUE(&sc->sc_scoq, m);
1786 		sc->sc_stats.sco_tx++;
1787 		/* XXXX: We can transmit with reliable */
1788 		sc->sc_flags |= BTH5_XMIT;
1789 		bth5_tx_unreliable_pkt(sc, m, BTH5_CHANNEL_HCI_SCO);
1790 	}
1791 
1792 	return;
1793 }
1794 
1795 static void
1796 bth5_output_cmd(device_t self, struct mbuf *m)
1797 {
1798 	struct bth5_softc *sc = device_private(self);
1799 	int s;
1800 
1801 	KASSERT(sc->sc_flags & BTH5_ENABLED);
1802 
1803 	m_adj(m, sizeof(uint8_t));
1804 	M_SETCTX(m, NULL);
1805 
1806 	s = spltty();
1807 	MBUFQ_ENQUEUE(&sc->sc_cmdq, m);
1808 	if ((sc->sc_flags & BTH5_XMIT) == 0)
1809 		bth5_start(sc);
1810 
1811 	splx(s);
1812 }
1813 
1814 static void
1815 bth5_output_acl(device_t self, struct mbuf *m)
1816 {
1817 	struct bth5_softc *sc = device_private(self);
1818 	int s;
1819 
1820 	KASSERT(sc->sc_flags & BTH5_ENABLED);
1821 
1822 	m_adj(m, sizeof(uint8_t));
1823 	M_SETCTX(m, NULL);
1824 
1825 	s = spltty();
1826 	MBUFQ_ENQUEUE(&sc->sc_aclq, m);
1827 	if ((sc->sc_flags & BTH5_XMIT) == 0)
1828 		bth5_start(sc);
1829 
1830 	splx(s);
1831 }
1832 
1833 static void
1834 bth5_output_sco(device_t self, struct mbuf *m)
1835 {
1836 	struct bth5_softc *sc = device_private(self);
1837 	int s;
1838 
1839 	KASSERT(sc->sc_flags & BTH5_ENABLED);
1840 
1841 	m_adj(m, sizeof(uint8_t));
1842 
1843 	s = spltty();
1844 	MBUFQ_ENQUEUE(&sc->sc_scoq, m);
1845 	if ((sc->sc_flags & BTH5_XMIT) == 0)
1846 		bth5_start(sc);
1847 
1848 	splx(s);
1849 }
1850 
1851 static void
1852 bth5_stats(device_t self, struct bt_stats *dest, int flush)
1853 {
1854 	struct bth5_softc *sc = device_private(self);
1855 	int s;
1856 
1857 	s = spltty();
1858 	memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
1859 
1860 	if (flush)
1861 		memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
1862 
1863 	splx(s);
1864 }
1865 
1866 
1867 #ifdef BTH5_DEBUG
1868 static void
1869 bth5_packet_print(struct mbuf *m)
1870 {
1871 	int i;
1872 	uint8_t *p;
1873 
1874 	for ( ; m != NULL; m = m->m_next) {
1875 		p = mtod(m, uint8_t *);
1876 		for (i = 0; i < m->m_len; i++) {
1877 			if (i % 16 == 0)
1878 				printf(" ");
1879 			printf(" %02x", *(p + i));
1880 			if (i % 16 == 15)
1881 				printf("\n");
1882 		}
1883 		printf("\n");
1884 	}
1885 }
1886 #endif
1887