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