Home | History | Annotate | Line # | Download | only in bluetooth
bth5.c revision 1.5.6.1
      1 /*	$NetBSD: bth5.c,v 1.5.6.1 2020/04/13 08:04:19 martin Exp $	*/
      2 /*
      3  * Copyright (c) 2017 Nathanial Sloss <nathanialsloss (at) 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.5.6.1 2020/04/13 08:04:19 martin 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