Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / bluetooth / bcsp.c
blob8334823ca6849be5e2f5da479e296396769b8660
1 /* $NetBSD: bcsp.c,v 1.17 2009/05/07 18:01:57 elad Exp $ */
2 /*
3 * Copyright (c) 2007 KIYOHARA Takashi
4 * All rights reserved.
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.
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.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: bcsp.c,v 1.17 2009/05/07 18:01:57 elad Exp $");
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>
48 #include <netbt/bluetooth.h>
49 #include <netbt/hci.h>
51 #include <dev/bluetooth/bcsp.h>
53 #include "ioconf.h"
55 #ifdef BCSP_DEBUG
56 #ifdef DPRINTF
57 #undef DPRINTF
58 #endif
59 #ifdef DPRINTFN
60 #undef DPRINTFN
61 #endif
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
70 #define DPRINTF(x)
71 #define DPRINTFN(n, x)
72 #endif
74 struct bcsp_softc {
75 device_t sc_dev;
77 struct tty *sc_tp;
78 struct hci_unit *sc_unit; /* Bluetooth HCI Unit */
79 struct bt_stats sc_stats;
81 int sc_flags;
83 /* output queues */
84 MBUFQ_HEAD() sc_cmdq;
85 MBUFQ_HEAD() sc_aclq;
86 MBUFQ_HEAD() sc_scoq;
88 int sc_baud;
89 int sc_init_baud;
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 *);
98 /* variables of Packet Integrity Layer */
99 int sc_pi_txcrc; /* use CRC, if true */
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 */
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;
119 /* variables of Datagram Queue Layer */
120 MBUFQ_HEAD() sc_dgq; /* Datagram Queue Layer queue */
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;
127 struct sysctllog *sc_log; /* sysctl log */
130 /* sc_flags */
131 #define BCSP_XMIT (1 << 0) /* transmit active */
132 #define BCSP_ENABLED (1 << 1) /* is enabled */
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);
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 *);
144 static int bcsp_slip_transmit(struct tty *);
145 static int bcsp_slip_receive(int, struct tty *);
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);
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);
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 *);
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 *);
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 *);
175 static void bcsp_start(struct bcsp_softc *);
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);
185 #ifdef BCSP_DEBUG
186 static void bcsp_packet_print(struct mbuf *m);
187 #endif
191 * It doesn't need to be exported, as only bcspattach() uses it,
192 * but there's no "official" way to make it static.
194 CFATTACH_DECL_NEW(bcsp, sizeof(struct bcsp_softc),
195 bcsp_match, bcsp_attach, bcsp_detach, NULL);
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
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,
220 /* ARGSUSED */
221 void
222 bcspattach(int num __unused)
224 int error;
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;
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);
243 * Autoconf match routine.
245 * XXX: unused: config_attach_pseudo(9) does not call ca_match.
247 /* ARGSUSED */
248 static int
249 bcsp_match(device_t self __unused, cfdata_t cfdata __unused,
250 void *arg __unused)
253 /* pseudo-device; always present */
254 return 1;
258 * Autoconf attach routine. Called by config_attach_pseudo(9) when we
259 * open the line discipline.
261 /* ARGSUSED */
262 static void
263 bcsp_attach(device_t parent __unused, device_t self, void *aux __unused)
265 struct bcsp_softc *sc = device_private(self);
266 const struct sysctlnode *node;
267 int rc, bcsp_node_num;
269 aprint_normal("\n");
270 aprint_naive("\n");
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);
287 /* Attach Bluetooth unit */
288 sc->sc_unit = hci_attach(&bcsp_hci, self, 0);
290 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, NULL,
291 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
292 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
293 goto err;
295 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
296 0, CTLTYPE_NODE, device_xname(self),
297 SYSCTL_DESCR("bcsp controls"),
298 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
299 goto err;
301 bcsp_node_num = node->sysctl_num;
302 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
303 CTLFLAG_READWRITE, CTLTYPE_INT,
304 "muzzled", SYSCTL_DESCR("muzzled for Link-establishment Layer"),
305 NULL, 0, &sc->sc_le_muzzled,
306 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
307 goto err;
309 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
310 CTLFLAG_READWRITE, CTLTYPE_INT,
311 "txcrc", SYSCTL_DESCR("txcrc for Packet Integrity Layer"),
312 NULL, 0, &sc->sc_pi_txcrc,
313 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
314 goto err;
316 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
317 CTLFLAG_READWRITE, CTLTYPE_INT,
318 "timeout", SYSCTL_DESCR("timeout for Sequencing Layer"),
319 NULL, 0, &sc->sc_seq_timeout,
320 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
321 goto err;
323 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
324 CTLFLAG_READWRITE, CTLTYPE_INT,
325 "winsize", SYSCTL_DESCR("winsize for Sequencing Layer"),
326 NULL, 0, &sc->sc_seq_winsize,
327 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
328 goto err;
330 if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
331 CTLFLAG_READWRITE, CTLTYPE_INT,
332 "retry_limit", SYSCTL_DESCR("retry limit for Sequencing Layer"),
333 NULL, 0, &sc->sc_seq_retry_limit,
334 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
335 goto err;
337 return;
339 err:
340 aprint_error_dev(self, "sysctl_createv failed (rc = %d)\n", rc);
344 * Autoconf detach routine. Called when we close the line discipline.
346 /* ARGSUSED */
347 static int
348 bcsp_detach(device_t self, int flags __unused)
350 struct bcsp_softc *sc = device_private(self);
352 if (sc->sc_unit != NULL) {
353 hci_detach(sc->sc_unit);
354 sc->sc_unit = NULL;
357 callout_stop(&sc->sc_seq_timer);
358 callout_destroy(&sc->sc_seq_timer);
360 callout_stop(&sc->sc_le_timer);
361 callout_destroy(&sc->sc_le_timer);
363 return 0;
368 * Line discipline functions.
370 /* ARGSUSED */
371 static int
372 bcspopen(dev_t device __unused, struct tty *tp)
374 struct bcsp_softc *sc;
375 device_t dev;
376 cfdata_t cfdata;
377 struct lwp *l = curlwp; /* XXX */
378 int error, unit, s;
379 static char name[] = "bcsp";
381 error = kauth_authorize_device(l->l_cred, KAUTH_DEVICE_BLUETOOTH_BCSP,
382 KAUTH_ARG(KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD), NULL, NULL, NULL);
383 if (error)
384 return (error);
386 s = spltty();
388 if (tp->t_linesw == &bcsp_disc) {
389 sc = tp->t_sc;
390 if (sc != NULL) {
391 splx(s);
392 return EBUSY;
396 KASSERT(tp->t_oproc != NULL);
398 cfdata = malloc(sizeof(struct cfdata), M_DEVBUF, M_WAITOK);
399 for (unit = 0; unit < bcsp_cd.cd_ndevs; unit++)
400 if (device_lookup(&bcsp_cd, unit) == NULL)
401 break;
402 cfdata->cf_name = name;
403 cfdata->cf_atname = name;
404 cfdata->cf_unit = unit;
405 cfdata->cf_fstate = FSTATE_STAR;
407 aprint_normal("%s%d at tty major %llu minor %llu",
408 name, unit, (unsigned long long)major(tp->t_dev),
409 (unsigned long long)minor(tp->t_dev));
410 dev = config_attach_pseudo(cfdata);
411 if (dev == NULL) {
412 splx(s);
413 return EIO;
415 sc = device_private(dev);
417 mutex_spin_enter(&tty_lock);
418 tp->t_sc = sc;
419 sc->sc_tp = tp;
420 ttyflush(tp, FREAD | FWRITE);
421 mutex_spin_exit(&tty_lock);
423 splx(s);
425 sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
426 bcsp_sequencing_reset(sc);
428 /* start link-establishment */
429 bcsp_start_le(sc);
431 return 0;
434 /* ARGSUSED */
435 static int
436 bcspclose(struct tty *tp, int flag __unused)
438 struct bcsp_softc *sc = tp->t_sc;
439 cfdata_t cfdata;
440 int s;
442 /* terminate link-establishment */
443 bcsp_terminate_le(sc);
445 s = spltty();
447 MBUFQ_DRAIN(&sc->sc_dgq);
448 bcsp_sequencing_reset(sc);
450 mutex_spin_enter(&tty_lock);
451 ttyflush(tp, FREAD | FWRITE);
452 mutex_spin_exit(&tty_lock); /* XXX */
453 ttyldisc_release(tp->t_linesw);
454 tp->t_linesw = ttyldisc_default();
455 if (sc != NULL) {
456 tp->t_sc = NULL;
457 if (sc->sc_tp == tp) {
458 cfdata = device_cfdata(sc->sc_dev);
459 config_detach(sc->sc_dev, 0);
460 free(cfdata, M_DEVBUF);
464 splx(s);
465 return 0;
468 /* ARGSUSED */
469 static int
470 bcspioctl(struct tty *tp, u_long cmd, void *data, int flag __unused,
471 struct lwp *l __unused)
473 struct bcsp_softc *sc = tp->t_sc;
474 int error;
476 if (sc == NULL || tp != sc->sc_tp)
477 return EPASSTHROUGH;
479 error = 0;
480 switch (cmd) {
481 default:
482 error = EPASSTHROUGH;
483 break;
486 return error;
491 * UART Driver Layer is supported by com-driver.
495 * BCSP SLIP Layer functions:
496 * Supports to transmit/receive a byte stream.
497 * SLIP protocol described in Internet standard RFC 1055.
499 static int
500 bcsp_slip_transmit(struct tty *tp)
502 struct bcsp_softc *sc = tp->t_sc;
503 struct mbuf *m;
504 int count, rlen;
505 uint8_t *rptr;
507 m = sc->sc_txp;
508 if (m == NULL) {
509 sc->sc_flags &= ~BCSP_XMIT;
510 bcsp_mux_transmit(sc);
511 return 0;
514 count = 0;
515 rlen = 0;
516 rptr = mtod(m, uint8_t *);
518 if (sc->sc_slip_txrsv != 0) {
519 #ifdef BCSP_DEBUG
520 if (sc->sc_slip_txrsv == BCSP_SLIP_PKTSTART)
521 DPRINTFN(4, ("%s: slip transmit start\n",
522 device_xname(sc->sc_dev)));
523 else
524 DPRINTFN(4, ("0x%02x ", sc->sc_slip_txrsv));
525 #endif
527 if (putc(sc->sc_slip_txrsv, &tp->t_outq) < 0)
528 return 0;
529 count++;
531 if (sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_PKTEND ||
532 sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_ESCAPE) {
533 rlen++;
534 rptr++;
536 sc->sc_slip_txrsv = 0;
539 for(;;) {
540 if (rlen >= m->m_len) {
541 m = m->m_next;
542 if (m == NULL) {
543 if (putc(BCSP_SLIP_PKTEND, &tp->t_outq) < 0)
544 break;
546 DPRINTFN(4, ("\n%s: slip transmit end\n",
547 device_xname(sc->sc_dev)));
549 m = sc->sc_txp;
550 sc->sc_txp = NULL;
551 sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
553 sc->sc_transmit_callback(sc, m);
554 m = NULL;
555 break;
558 rlen = 0;
559 rptr = mtod(m, uint8_t *);
560 continue;
563 if (*rptr == BCSP_SLIP_PKTEND) {
564 if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
565 break;
566 count++;
567 DPRINTFN(4, (" esc "));
569 if (putc(BCSP_SLIP_ESCAPE_PKTEND, &tp->t_outq) < 0) {
570 sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_PKTEND;
571 break;
573 DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_PKTEND));
574 rptr++;
575 } else if (*rptr == BCSP_SLIP_ESCAPE) {
576 if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
577 break;
578 count++;
579 DPRINTFN(4, (" esc "));
581 if (putc(BCSP_SLIP_ESCAPE_ESCAPE, &tp->t_outq) < 0) {
582 sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_ESCAPE;
583 break;
585 DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_ESCAPE));
586 rptr++;
587 } else {
588 if (putc(*rptr++, &tp->t_outq) < 0)
589 break;
590 DPRINTFN(4, ("0x%02x ", *(rptr - 1)));
592 rlen++;
593 count++;
595 if (m != NULL)
596 m_adj(m, rlen);
598 sc->sc_stats.byte_tx += count;
600 if (tp->t_outq.c_cc != 0)
601 (*tp->t_oproc)(tp);
603 return 0;
606 static int
607 bcsp_slip_receive(int c, struct tty *tp)
609 struct bcsp_softc *sc = tp->t_sc;
610 struct mbuf *m = sc->sc_rxp;
611 int discard = 0;
612 const char *errstr;
614 c &= TTY_CHARMASK;
616 /* If we already started a packet, find the trailing end of it. */
617 if (m) {
618 while (m->m_next)
619 m = m->m_next;
621 if (M_TRAILINGSPACE(m) == 0) {
622 /* extend mbuf */
623 MGET(m->m_next, M_DONTWAIT, MT_DATA);
624 if (m->m_next == NULL) {
625 aprint_error_dev(sc->sc_dev,
626 "out of memory\n");
627 sc->sc_stats.err_rx++;
628 return 0; /* (lost sync) */
631 m = m->m_next;
632 m->m_len = 0;
634 } else
635 if (c != BCSP_SLIP_PKTSTART) {
636 discard = 1;
637 errstr = "not sync";
638 goto discarded;
641 switch (c) {
642 case BCSP_SLIP_PKTSTART /* or _PKTEND */:
643 if (m == NULL) {
644 /* BCSP_SLIP_PKTSTART */
646 DPRINTFN(4, ("%s: slip receive start\n",
647 device_xname(sc->sc_dev)));
649 /* new packet */
650 MGETHDR(m, M_DONTWAIT, MT_DATA);
651 if (m == NULL) {
652 aprint_error_dev(sc->sc_dev,
653 "out of memory\n");
654 sc->sc_stats.err_rx++;
655 return 0; /* (lost sync) */
658 sc->sc_rxp = m;
659 m->m_pkthdr.len = m->m_len = 0;
660 sc->sc_slip_rxexp = 0;
661 } else {
662 /* BCSP_SLIP_PKTEND */
664 if (m == sc->sc_rxp && m->m_len == 0) {
665 DPRINTFN(4, ("%s: resynchronises\n",
666 device_xname(sc->sc_dev)));
668 sc->sc_stats.byte_rx++;
669 return 0;
672 DPRINTFN(4, ("%s%s: slip receive end\n",
673 (m->m_len % 16 != 0) ? "\n" : "",
674 device_xname(sc->sc_dev)));
676 bcsp_pktintegrity_receive(sc, sc->sc_rxp);
677 sc->sc_rxp = NULL;
678 sc->sc_slip_rxexp = BCSP_SLIP_PKTSTART;
680 sc->sc_stats.byte_rx++;
681 return 0;
683 case BCSP_SLIP_ESCAPE:
685 DPRINTFN(4, (" esc"));
687 if (sc->sc_slip_rxexp == BCSP_SLIP_ESCAPE) {
688 discard = 1;
689 errstr = "waiting 0xdc or 0xdb";
690 } else
691 sc->sc_slip_rxexp = BCSP_SLIP_ESCAPE;
692 break;
694 default:
695 DPRINTFN(4, (" 0x%02x%s",
696 c, (m->m_len % 16 == 15) ? "\n" : ""));
698 switch (sc->sc_slip_rxexp) {
699 case BCSP_SLIP_PKTSTART:
700 discard = 1;
701 errstr = "waiting 0xc0";
702 break;
704 case BCSP_SLIP_ESCAPE:
705 if (c == BCSP_SLIP_ESCAPE_PKTEND)
706 mtod(m, uint8_t *)[m->m_len++] =
707 BCSP_SLIP_PKTEND;
708 else if (c == BCSP_SLIP_ESCAPE_ESCAPE)
709 mtod(m, uint8_t *)[m->m_len++] =
710 BCSP_SLIP_ESCAPE;
711 else {
712 discard = 1;
713 errstr = "unknown escape";
715 sc->sc_slip_rxexp = 0;
716 break;
718 default:
719 mtod(m, uint8_t *)[m->m_len++] = c;
721 sc->sc_rxp->m_pkthdr.len++;
723 if (discard) {
724 discarded:
725 DPRINTFN(4, ("%s: receives unexpected byte 0x%02x: %s\n",
726 device_xname(sc->sc_dev), c, errstr));
728 sc->sc_stats.byte_rx++;
730 return 0;
735 * BCSP Packet Integrity Layer functions:
736 * handling Payload Length, Checksum, CRC.
738 static void
739 bcsp_pktintegrity_transmit(struct bcsp_softc *sc)
741 struct mbuf *m = sc->sc_txp;
742 bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
743 int pldlen;
745 DPRINTFN(3, ("%s: pi transmit\n", device_xname(sc->sc_dev)));
747 pldlen = m->m_pkthdr.len - sizeof(bcsp_hdr_t);
749 if (sc->sc_pi_txcrc)
750 hdrp->flags |= BCSP_FLAGS_CRC_PRESENT;
752 BCSP_SET_PLEN(hdrp, pldlen);
753 BCSP_SET_CSUM(hdrp);
755 if (sc->sc_pi_txcrc) {
756 struct mbuf *_m;
757 int n = 0;
758 uint16_t crc = 0xffff;
759 uint8_t *buf;
761 for (_m = m; _m != NULL; _m = _m->m_next) {
762 buf = mtod(_m, uint8_t *);
763 for (n = 0; n < _m->m_len; n++)
764 bcsp_crc_update(&crc, *(buf + n));
766 crc = htobe16(bcsp_crc_reverse(crc));
767 m_copyback(m, m->m_pkthdr.len, sizeof(crc), &crc);
770 #ifdef BCSP_DEBUG
771 if (bcsp_debug == 4)
772 bcsp_packet_print(m);
773 #endif
775 bcsp_slip_transmit(sc->sc_tp);
778 static void
779 bcsp_pktintegrity_receive(struct bcsp_softc *sc, struct mbuf *m)
781 bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
782 u_int pldlen;
783 int discard = 0;
784 uint16_t crc = 0xffff;
785 const char *errstr;
787 DPRINTFN(3, ("%s: pi receive\n", device_xname(sc->sc_dev)));
788 #ifdef BCSP_DEBUG
789 if (bcsp_debug == 4)
790 bcsp_packet_print(m);
791 #endif
793 KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
795 pldlen = m->m_pkthdr.len - sizeof(bcsp_hdr_t) -
796 ((hdrp->flags & BCSP_FLAGS_CRC_PRESENT) ? sizeof(crc) : 0);
797 if (pldlen > 0xfff) {
798 discard = 1;
799 errstr = "Payload Length";
800 goto discarded;
802 if (hdrp->csum != BCSP_GET_CSUM(hdrp)) {
803 discard = 1;
804 errstr = "Checksum";
805 goto discarded;
807 if (BCSP_GET_PLEN(hdrp) != pldlen) {
808 discard = 1;
809 errstr = "Payload Length";
810 goto discarded;
812 if (hdrp->flags & BCSP_FLAGS_CRC_PRESENT) {
813 struct mbuf *_m;
814 int i, n;
815 uint16_t crc0;
816 uint8_t *buf;
818 i = 0;
819 n = 0;
820 for (_m = m; _m != NULL; _m = _m->m_next) {
821 buf = mtod(m, uint8_t *);
822 for (n = 0;
823 n < _m->m_len && i < sizeof(bcsp_hdr_t) + pldlen;
824 n++, i++)
825 bcsp_crc_update(&crc, *(buf + n));
828 m_copydata(_m, n, sizeof(crc0), &crc0);
829 if (be16toh(crc0) != bcsp_crc_reverse(crc)) {
830 discard = 1;
831 errstr = "CRC";
832 } else
833 /* Shaves CRC */
834 m_adj(m, (int)(0 - sizeof(crc)));
837 if (discard) {
838 discarded:
839 DPRINTFN(3, ("%s: receives unexpected packet: %s\n",
840 device_xname(sc->sc_dev), errstr));
841 m_freem(m);
842 } else
843 bcsp_mux_receive(sc, m);
846 static const uint16_t crctbl[] = {
847 0x0000, 0x1081, 0x2102, 0x3183,
848 0x4204, 0x5285, 0x6306, 0x7387,
849 0x8408, 0x9489, 0xa50a, 0xb58b,
850 0xc60c, 0xd68d, 0xe70e, 0xf78f,
853 static void
854 bcsp_crc_update(uint16_t *crc, uint8_t d)
856 uint16_t reg = *crc;
858 reg = (reg >> 4) ^ crctbl[(reg ^ d) & 0x000f];
859 reg = (reg >> 4) ^ crctbl[(reg ^ (d >> 4)) & 0x000f];
861 *crc = reg;
864 static uint16_t
865 bcsp_crc_reverse(uint16_t crc)
867 uint16_t b, rev;
869 for (b = 0, rev = 0; b < 16; b++) {
870 rev = rev << 1;
871 rev |= (crc & 1);
872 crc = crc >> 1;
875 return rev;
880 * BCSP MUX Layer functions
882 static void
883 bcsp_mux_transmit(struct bcsp_softc *sc)
885 struct mbuf *m;
886 bcsp_hdr_t *hdrp;
888 DPRINTFN(2, ("%s: mux transmit: sc_flags=0x%x, choke=%d",
889 device_xname(sc->sc_dev), sc->sc_flags, sc->sc_mux_choke));
891 if (sc->sc_mux_choke) {
892 struct mbuf *_m = NULL;
894 /* In this case, send only Link Establishment packet */
895 for (m = MBUFQ_FIRST(&sc->sc_dgq); m != NULL;
896 _m = m, m = MBUFQ_NEXT(m)) {
897 hdrp = mtod(m, bcsp_hdr_t *);
898 if (hdrp->ident == BCSP_CHANNEL_LE) {
899 if (m == MBUFQ_FIRST(&sc->sc_dgq))
900 MBUFQ_DEQUEUE(&sc->sc_dgq, m);
901 else {
902 if (m->m_nextpkt == NULL)
903 sc->sc_dgq.mq_last =
904 &_m->m_nextpkt;
905 _m->m_nextpkt = m->m_nextpkt;
906 m->m_nextpkt = NULL;
908 goto transmit;
911 DPRINTFN(2, ("\n"));
912 return;
916 * The MUX Layer always gives priority to packets from the Datagram
917 * Queue Layer over the Sequencing Layer.
919 if (MBUFQ_FIRST(&sc->sc_dgq)) {
920 MBUFQ_DEQUEUE(&sc->sc_dgq, m);
921 goto transmit;
923 if (MBUFQ_FIRST(&sc->sc_seqq)) {
924 MBUFQ_DEQUEUE(&sc->sc_seqq, m);
925 hdrp = mtod(m, bcsp_hdr_t *);
926 hdrp->flags |= BCSP_FLAGS_PROTOCOL_REL; /* Reliable */
927 goto transmit;
929 bcsp_start(sc);
930 if (sc->sc_mux_send_ack == true) {
931 m = bcsp_create_ackpkt();
932 if (m != NULL)
933 goto transmit;
934 aprint_error_dev(sc->sc_dev, "out of memory\n");
935 sc->sc_stats.err_tx++;
938 /* Nothing to send */
939 DPRINTFN(2, ("\n"));
940 return;
942 transmit:
943 DPRINTFN(2, (", txack=%d, send_ack=%d\n",
944 bcsp_get_txack(sc), sc->sc_mux_send_ack));
946 hdrp = mtod(m, bcsp_hdr_t *);
947 hdrp->flags |=
948 (bcsp_get_txack(sc) << BCSP_FLAGS_ACK_SHIFT) & BCSP_FLAGS_ACK_MASK;
949 if (sc->sc_mux_send_ack == true)
950 sc->sc_mux_send_ack = false;
952 #ifdef BCSP_DEBUG
953 if (bcsp_debug == 3)
954 bcsp_packet_print(m);
955 #endif
957 sc->sc_txp = m;
958 bcsp_pktintegrity_transmit(sc);
961 static void
962 bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m)
964 bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
965 const u_int rxack = BCSP_FLAGS_ACK(hdrp->flags);
967 DPRINTFN(2, ("%s: mux receive: flags=0x%x, ident=%d, rxack=%d\n",
968 device_xname(sc->sc_dev), hdrp->flags, hdrp->ident, rxack));
969 #ifdef BCSP_DEBUG
970 if (bcsp_debug == 3)
971 bcsp_packet_print(m);
972 #endif
974 bcsp_signal_rxack(sc, rxack);
976 microtime(&sc->sc_mux_lastrx);
978 /* if the Ack Packet received then discard */
979 if (BCSP_FLAGS_SEQ(hdrp->flags) == 0 &&
980 hdrp->ident == BCSP_IDENT_ACKPKT &&
981 BCSP_GET_PLEN(hdrp) == 0) {
982 m_freem(m);
983 return;
986 if (hdrp->flags & BCSP_FLAGS_PROTOCOL_REL)
987 bcsp_sequencing_receive(sc, m);
988 else
989 bcsp_datagramq_receive(sc, m);
992 static __inline void
993 bcsp_send_ack_command(struct bcsp_softc *sc)
996 DPRINTFN(2, ("%s: mux send_ack_command\n", device_xname(sc->sc_dev)));
998 sc->sc_mux_send_ack = true;
1001 static __inline struct mbuf *
1002 bcsp_create_ackpkt(void)
1004 struct mbuf *m;
1005 bcsp_hdr_t *hdrp;
1007 MGETHDR(m, M_DONTWAIT, MT_DATA);
1008 if (m != NULL) {
1009 m->m_pkthdr.len = m->m_len = sizeof(bcsp_hdr_t);
1010 hdrp = mtod(m, bcsp_hdr_t *);
1012 * An Ack Packet has the following fields:
1013 * Ack Field: txack (not set yet)
1014 * Seq Field: 0
1015 * Protocol Identifier Field: 0
1016 * Protocol Type Field: Any value
1017 * Payload Length Field: 0
1019 memset(hdrp, 0, sizeof(bcsp_hdr_t));
1021 return m;
1024 static __inline void
1025 bcsp_set_choke(struct bcsp_softc *sc, bool choke)
1028 DPRINTFN(2, ("%s: mux set choke=%d\n", device_xname(sc->sc_dev), choke));
1030 sc->sc_mux_choke = choke;
1035 * BCSP Sequencing Layer functions
1037 static void
1038 bcsp_sequencing_receive(struct bcsp_softc *sc, struct mbuf *m)
1040 bcsp_hdr_t hdr;
1041 uint32_t rxseq;
1043 m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
1044 rxseq = BCSP_FLAGS_SEQ(hdr.flags);
1046 DPRINTFN(1, ("%s: seq receive: rxseq=%d, expected %d\n",
1047 device_xname(sc->sc_dev), rxseq, sc->sc_seq_expected_rxseq));
1048 #ifdef BCSP_DEBUG
1049 if (bcsp_debug == 2)
1050 bcsp_packet_print(m);
1051 #endif
1054 * We remove the header of BCSP and add the 'uint8_t type' of
1055 * hci_*_hdr_t to the head.
1057 m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
1059 if (rxseq != sc->sc_seq_expected_rxseq) {
1060 m_freem(m);
1062 /* send ack packet, if needly */
1063 bcsp_mux_transmit(sc);
1065 return;
1068 switch (hdr.ident) {
1069 case BCSP_CHANNEL_HCI_CMDEVT:
1070 *(mtod(m, uint8_t *)) = HCI_EVENT_PKT;
1071 if (!hci_input_event(sc->sc_unit, m))
1072 sc->sc_stats.err_rx++;
1074 sc->sc_stats.evt_rx++;
1075 break;
1077 case BCSP_CHANNEL_HCI_ACL:
1078 *(mtod(m, uint8_t *)) = HCI_ACL_DATA_PKT;
1079 if (!hci_input_acl(sc->sc_unit, m))
1080 sc->sc_stats.err_rx++;
1082 sc->sc_stats.acl_rx++;
1083 break;
1085 case BCSP_CHANNEL_HCI_SCO:
1086 *(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1087 if (!hci_input_sco(sc->sc_unit, m))
1088 sc->sc_stats.err_rx++;
1090 sc->sc_stats.sco_rx++;
1091 break;
1093 case BCSP_CHANNEL_HQ:
1094 case BCSP_CHANNEL_DEVMGT:
1095 case BCSP_CHANNEL_L2CAP:
1096 case BCSP_CHANNEL_RFCOMM:
1097 case BCSP_CHANNEL_SDP:
1098 case BCSP_CHANNEL_DFU:
1099 case BCSP_CHANNEL_VM:
1100 default:
1101 aprint_error_dev(sc->sc_dev,
1102 "received reliable packet with not support channel %d\n",
1103 hdr.ident);
1104 m_freem(m);
1105 break;
1108 sc->sc_seq_expected_rxseq =
1109 (sc->sc_seq_expected_rxseq + 1) & BCSP_FLAGS_SEQ_MASK;
1110 sc->sc_seq_txack = sc->sc_seq_expected_rxseq;
1111 bcsp_send_ack_command(sc);
1114 static bool
1115 bcsp_tx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1117 bcsp_hdr_t *hdrp;
1118 struct mbuf *_m;
1119 u_int pldlen;
1120 int s;
1122 DPRINTFN(1, ("%s: seq transmit:"
1123 "protocol_id=%d, winspace=%d, txseq=%d\n", device_xname(sc->sc_dev),
1124 protocol_id, sc->sc_seq_winspace, sc->sc_seq_txseq));
1126 for (pldlen = 0, _m = m; _m != NULL; _m = _m->m_next) {
1127 if (_m->m_len < 0)
1128 return false;
1129 pldlen += _m->m_len;
1131 if (pldlen > 0xfff)
1132 return false;
1133 if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
1134 return false;
1136 if (sc->sc_seq_winspace == 0)
1137 return false;
1139 M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
1140 if (m == NULL) {
1141 aprint_error_dev(sc->sc_dev, "out of memory\n");
1142 return false;
1144 KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
1146 hdrp = mtod(m, bcsp_hdr_t *);
1147 memset(hdrp, 0, sizeof(bcsp_hdr_t));
1148 hdrp->flags |= sc->sc_seq_txseq;
1149 hdrp->ident = protocol_id;
1151 callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1153 s = splserial();
1154 MBUFQ_ENQUEUE(&sc->sc_seqq, m);
1155 splx(s);
1156 sc->sc_transmit_callback = bcsp_reliabletx_callback;
1158 #ifdef BCSP_DEBUG
1159 if (bcsp_debug == 2)
1160 bcsp_packet_print(m);
1161 #endif
1163 sc->sc_seq_txseq = (sc->sc_seq_txseq + 1) & BCSP_FLAGS_SEQ_MASK;
1164 sc->sc_seq_winspace--;
1165 _m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1166 if (_m == NULL) {
1167 aprint_error_dev(sc->sc_dev, "out of memory\n");
1168 return false;
1170 MBUFQ_ENQUEUE(&sc->sc_seq_retryq, _m);
1171 bcsp_mux_transmit(sc);
1173 return true;
1176 #if 0
1177 static bool
1178 bcsp_rx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1181 return false;
1184 /* XXXX: I can't understand meaning this function... */
1185 static __inline void
1186 bcsp_link_failed(struct bcsp_softc *sc)
1189 return (sc->sc_seq_retries >= sc->sc_seq_retry_limit);
1191 #endif
1193 static __inline u_int
1194 bcsp_get_txack(struct bcsp_softc *sc)
1197 return sc->sc_seq_txack;
1200 static void
1201 bcsp_signal_rxack(struct bcsp_softc *sc, uint32_t rxack)
1203 bcsp_hdr_t *hdrp;
1204 struct mbuf *m;
1205 uint32_t seqno = (rxack - 1) & BCSP_FLAGS_SEQ_MASK;
1206 int s;
1208 DPRINTFN(1, ("%s: seq signal rxack: rxack=%d\n",
1209 device_xname(sc->sc_dev), rxack));
1211 s = splserial();
1212 m = MBUFQ_FIRST(&sc->sc_seq_retryq);
1213 while (m != NULL) {
1214 hdrp = mtod(m, bcsp_hdr_t *);
1215 if (BCSP_FLAGS_SEQ(hdrp->flags) == seqno) {
1216 struct mbuf *m0;
1218 for (m0 = MBUFQ_FIRST(&sc->sc_seq_retryq);
1219 m0 != MBUFQ_NEXT(m);
1220 m0 = MBUFQ_FIRST(&sc->sc_seq_retryq)) {
1221 MBUFQ_DEQUEUE(&sc->sc_seq_retryq, m0);
1222 m_freem(m0);
1223 sc->sc_seq_winspace++;
1225 break;
1227 m = MBUFQ_NEXT(m);
1229 splx(s);
1230 sc->sc_seq_retries = 0;
1232 if (sc->sc_seq_winspace == sc->sc_seq_winsize)
1233 callout_stop(&sc->sc_seq_timer);
1234 else
1235 callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1238 static void
1239 bcsp_reliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
1242 m_freem(m);
1245 static void
1246 bcsp_timer_timeout(void *arg)
1248 struct bcsp_softc *sc = arg;
1249 struct mbuf *m, *_m;
1250 int s, i = 0;
1252 DPRINTFN(1, ("%s: seq timeout: retries=%d\n",
1253 device_xname(sc->sc_dev), sc->sc_seq_retries));
1255 s = splserial();
1256 for (m = MBUFQ_FIRST(&sc->sc_seq_retryq); m != NULL;
1257 m = MBUFQ_NEXT(m)) {
1258 _m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1259 if (_m == NULL) {
1260 aprint_error_dev(sc->sc_dev, "out of memory\n");
1261 return;
1263 MBUFQ_ENQUEUE(&sc->sc_seqq, _m);
1264 i++;
1266 splx(s);
1268 if (i != 0) {
1269 if (++sc->sc_seq_retries < sc->sc_seq_retry_limit)
1270 callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1271 else {
1272 aprint_error_dev(sc->sc_dev,
1273 "reached the retry limit."
1274 " restart the link-establishment\n");
1275 bcsp_sequencing_reset(sc);
1276 bcsp_start_le(sc);
1277 return;
1280 bcsp_mux_transmit(sc);
1283 static void
1284 bcsp_sequencing_reset(struct bcsp_softc *sc)
1286 int s;
1288 s = splserial();
1289 MBUFQ_DRAIN(&sc->sc_seqq);
1290 MBUFQ_DRAIN(&sc->sc_seq_retryq);
1291 splx(s);
1294 sc->sc_seq_txseq = 0;
1295 sc->sc_seq_txack = 0;
1296 sc->sc_seq_winspace = sc->sc_seq_winsize;
1297 sc->sc_seq_retries = 0;
1298 callout_stop(&sc->sc_seq_timer);
1300 sc->sc_mux_send_ack = false;
1302 /* XXXX: expected_rxseq should be set by MUX Layer */
1303 sc->sc_seq_expected_rxseq = 0;
1308 * BCSP Datagram Queue Layer functions
1310 static void
1311 bcsp_datagramq_receive(struct bcsp_softc *sc, struct mbuf *m)
1313 bcsp_hdr_t hdr;
1315 DPRINTFN(1, ("%s: dgq receive\n", device_xname(sc->sc_dev)));
1316 #ifdef BCSP_DEBUG
1317 if (bcsp_debug == 2)
1318 bcsp_packet_print(m);
1319 #endif
1321 m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
1323 switch (hdr.ident) {
1324 case BCSP_CHANNEL_LE:
1325 m_adj(m, sizeof(bcsp_hdr_t));
1326 bcsp_input_le(sc, m);
1327 break;
1329 case BCSP_CHANNEL_HCI_SCO:
1331 * We remove the header of BCSP and add the 'uint8_t type' of
1332 * hci_scodata_hdr_t to the head.
1334 m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
1335 *(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1336 if (!hci_input_sco(sc->sc_unit, m))
1337 sc->sc_stats.err_rx++;
1339 sc->sc_stats.sco_rx++;
1340 break;
1342 default:
1343 aprint_error_dev(sc->sc_dev,
1344 "received unreliable packet with not support channel %d\n",
1345 hdr.ident);
1346 m_freem(m);
1347 break;
1351 static bool
1352 bcsp_tx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1354 bcsp_hdr_t *hdrp;
1355 struct mbuf *_m;
1356 u_int pldlen;
1357 int s;
1359 DPRINTFN(1, ("%s: dgq transmit: protocol_id=%d,",
1360 device_xname(sc->sc_dev), protocol_id));
1362 for (pldlen = 0, _m = m; _m != NULL; _m = m->m_next) {
1363 if (_m->m_len < 0)
1364 return false;
1365 pldlen += _m->m_len;
1367 DPRINTFN(1, (" pldlen=%d\n", pldlen));
1368 if (pldlen > 0xfff)
1369 return false;
1370 if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
1371 return false;
1373 M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
1374 if (m == NULL) {
1375 aprint_error_dev(sc->sc_dev, "out of memory\n");
1376 return false;
1378 KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
1380 hdrp = mtod(m, bcsp_hdr_t *);
1381 memset(hdrp, 0, sizeof(bcsp_hdr_t));
1382 hdrp->ident = protocol_id;
1384 s = splserial();
1385 MBUFQ_ENQUEUE(&sc->sc_dgq, m);
1386 splx(s);
1387 sc->sc_transmit_callback = bcsp_unreliabletx_callback;
1389 #ifdef BCSP_DEBUG
1390 if (bcsp_debug == 2)
1391 bcsp_packet_print(m);
1392 #endif
1394 bcsp_mux_transmit(sc);
1396 return true;
1399 #if 0
1400 static bool
1401 bcsp_rx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1404 return false;
1406 #endif
1408 static void
1409 bcsp_unreliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
1412 if (M_GETCTX(m, void *) == NULL)
1413 m_freem(m);
1414 else if (!hci_complete_sco(sc->sc_unit, m))
1415 sc->sc_stats.err_tx++;
1420 * BlueCore Link Establishment Protocol functions
1422 static const uint8_t sync[] = BCSP_LE_SYNC;
1423 static const uint8_t syncresp[] = BCSP_LE_SYNCRESP;
1424 static const uint8_t conf[] = BCSP_LE_CONF;
1425 static const uint8_t confresp[] = BCSP_LE_CONFRESP;
1427 static int
1428 bcsp_start_le(struct bcsp_softc *sc)
1431 DPRINTF(("%s: start link-establish\n", device_xname(sc->sc_dev)));
1433 bcsp_set_choke(sc, true);
1435 if (!sc->sc_le_muzzled) {
1436 struct mbuf *m;
1438 m = m_gethdr(M_WAIT, MT_DATA);
1439 m->m_pkthdr.len = m->m_len = 0;
1440 m_copyback(m, 0, sizeof(sync), sync);
1441 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE)) {
1442 aprint_error_dev(sc->sc_dev,
1443 "le-packet transmit failed\n");
1444 return EINVAL;
1447 callout_schedule(&sc->sc_le_timer, BCSP_LE_TSHY_TIMEOUT);
1449 sc->sc_le_state = le_state_shy;
1450 return 0;
1453 static void
1454 bcsp_terminate_le(struct bcsp_softc *sc)
1456 struct mbuf *m;
1458 /* terminate link-establishment */
1459 callout_stop(&sc->sc_le_timer);
1460 bcsp_set_choke(sc, true);
1461 MGETHDR(m, M_DONTWAIT, MT_DATA);
1462 if (m == NULL)
1463 aprint_error_dev(sc->sc_dev, "out of memory\n");
1464 else {
1465 /* length of le packets is 4 */
1466 m->m_pkthdr.len = m->m_len = 0;
1467 m_copyback(m, 0, sizeof(sync), sync);
1468 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1469 aprint_error_dev(sc->sc_dev,
1470 "link-establishment terminations failed\n");
1474 static void
1475 bcsp_input_le(struct bcsp_softc *sc, struct mbuf *m)
1477 uint32_t *rcvpkt;
1478 int i;
1479 const uint8_t *rplypkt;
1480 static struct {
1481 const char *type;
1482 const uint8_t *datap;
1483 } pkt[] = {
1484 { "sync", sync },
1485 { "sync-resp", syncresp },
1486 { "conf", conf },
1487 { "conf-resp", confresp },
1489 { NULL, 0 }
1492 DPRINTFN(0, ("%s: le input: state %d, muzzled %d\n",
1493 device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1494 #ifdef BCSP_DEBUG
1495 if (bcsp_debug == 1)
1496 bcsp_packet_print(m);
1497 #endif
1499 rcvpkt = mtod(m, uint32_t *);
1500 i = 0;
1502 /* length of le packets is 4 */
1503 if (m->m_len == sizeof(uint32_t))
1504 for (i = 0; pkt[i].type != NULL; i++)
1505 if (*(const uint32_t *)pkt[i].datap == *rcvpkt)
1506 break;
1507 if (m->m_len != sizeof(uint32_t) || pkt[i].type == NULL) {
1508 aprint_error_dev(sc->sc_dev, "received unknown packet\n");
1509 m_freem(m);
1510 return;
1513 rplypkt = NULL;
1514 switch (sc->sc_le_state) {
1515 case le_state_shy:
1516 if (*rcvpkt == *(const uint32_t *)sync) {
1517 sc->sc_le_muzzled = false;
1518 rplypkt = syncresp;
1519 } else if (*rcvpkt == *(const uint32_t *)syncresp) {
1520 DPRINTF(("%s: state change to curious\n",
1521 device_xname(sc->sc_dev)));
1523 rplypkt = conf;
1524 callout_schedule(&sc->sc_le_timer,
1525 BCSP_LE_TCONF_TIMEOUT);
1526 sc->sc_le_state = le_state_curious;
1527 } else
1528 aprint_error_dev(sc->sc_dev,
1529 "received an unknown packet at shy\n");
1530 break;
1532 case le_state_curious:
1533 if (*rcvpkt == *(const uint32_t *)sync)
1534 rplypkt = syncresp;
1535 else if (*rcvpkt == *(const uint32_t *)conf)
1536 rplypkt = confresp;
1537 else if (*rcvpkt == *(const uint32_t *)confresp) {
1538 DPRINTF(("%s: state change to garrulous:\n",
1539 device_xname(sc->sc_dev)));
1541 bcsp_set_choke(sc, false);
1542 callout_stop(&sc->sc_le_timer);
1543 sc->sc_le_state = le_state_garrulous;
1544 } else
1545 aprint_error_dev(sc->sc_dev,
1546 "received unknown packet at curious\n");
1547 break;
1549 case le_state_garrulous:
1550 if (*rcvpkt == *(const uint32_t *)conf)
1551 rplypkt = confresp;
1552 else if (*rcvpkt == *(const uint32_t *)sync) {
1553 /* XXXXX */
1554 aprint_error_dev(sc->sc_dev,
1555 "received sync! peer to reset?\n");
1557 bcsp_sequencing_reset(sc);
1558 rplypkt = sync;
1559 sc->sc_le_state = le_state_shy;
1560 } else
1561 aprint_error_dev(sc->sc_dev,
1562 "received unknown packet at garrulous\n");
1563 break;
1566 m_freem(m);
1568 if (rplypkt != NULL) {
1569 MGETHDR(m, M_DONTWAIT, MT_DATA);
1570 if (m == NULL)
1571 aprint_error_dev(sc->sc_dev, "out of memory\n");
1572 else {
1573 /* length of le packets is 4 */
1574 m->m_pkthdr.len = m->m_len = 0;
1575 m_copyback(m, 0, 4, rplypkt);
1576 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1577 aprint_error_dev(sc->sc_dev,
1578 "le-packet transmit failed\n");
1583 static void
1584 bcsp_le_timeout(void *arg)
1586 struct bcsp_softc *sc = arg;
1587 struct mbuf *m;
1588 int timeout;
1589 const uint8_t *sndpkt = NULL;
1591 DPRINTFN(0, ("%s: le timeout: state %d, muzzled %d\n",
1592 device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1594 switch (sc->sc_le_state) {
1595 case le_state_shy:
1596 if (!sc->sc_le_muzzled)
1597 sndpkt = sync;
1598 timeout = BCSP_LE_TSHY_TIMEOUT;
1599 break;
1601 case le_state_curious:
1602 sndpkt = conf;
1603 timeout = BCSP_LE_TCONF_TIMEOUT;
1604 break;
1606 default:
1607 aprint_error_dev(sc->sc_dev,
1608 "timeout happen at unknown state %d\n", sc->sc_le_state);
1609 return;
1612 if (sndpkt != NULL) {
1613 MGETHDR(m, M_DONTWAIT, MT_DATA);
1614 if (m == NULL)
1615 aprint_error_dev(sc->sc_dev, "out of memory\n");
1616 else {
1617 /* length of le packets is 4 */
1618 m->m_pkthdr.len = m->m_len = 0;
1619 m_copyback(m, 0, 4, sndpkt);
1620 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1621 aprint_error_dev(sc->sc_dev,
1622 "le-packet transmit failed\n");
1626 callout_schedule(&sc->sc_le_timer, timeout);
1631 * BlueCore Serial Protocol functions.
1633 static int
1634 bcsp_enable(device_t self)
1636 struct bcsp_softc *sc = device_private(self);
1637 int s;
1639 if (sc->sc_flags & BCSP_ENABLED)
1640 return 0;
1642 s = spltty();
1644 sc->sc_flags |= BCSP_ENABLED;
1645 sc->sc_flags &= ~BCSP_XMIT;
1647 splx(s);
1649 return 0;
1652 static void
1653 bcsp_disable(device_t self)
1655 struct bcsp_softc *sc = device_private(self);
1656 int s;
1658 if ((sc->sc_flags & BCSP_ENABLED) == 0)
1659 return;
1661 s = spltty();
1663 if (sc->sc_rxp) {
1664 m_freem(sc->sc_rxp);
1665 sc->sc_rxp = NULL;
1668 if (sc->sc_txp) {
1669 m_freem(sc->sc_txp);
1670 sc->sc_txp = NULL;
1673 MBUFQ_DRAIN(&sc->sc_cmdq);
1674 MBUFQ_DRAIN(&sc->sc_aclq);
1675 MBUFQ_DRAIN(&sc->sc_scoq);
1677 sc->sc_flags &= ~BCSP_ENABLED;
1678 splx(s);
1681 static void
1682 bcsp_start(struct bcsp_softc *sc)
1684 struct mbuf *m;
1686 KASSERT((sc->sc_flags & BCSP_XMIT) == 0);
1687 KASSERT(sc->sc_txp == NULL);
1689 if (MBUFQ_FIRST(&sc->sc_aclq)) {
1690 MBUFQ_DEQUEUE(&sc->sc_aclq, m);
1691 sc->sc_stats.acl_tx++;
1692 sc->sc_flags |= BCSP_XMIT;
1693 bcsp_tx_reliable_pkt(sc, m, BCSP_CHANNEL_HCI_ACL);
1696 if (MBUFQ_FIRST(&sc->sc_cmdq)) {
1697 MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
1698 sc->sc_stats.cmd_tx++;
1699 sc->sc_flags |= BCSP_XMIT;
1700 bcsp_tx_reliable_pkt(sc, m, BCSP_CHANNEL_HCI_CMDEVT);
1703 if (MBUFQ_FIRST(&sc->sc_scoq)) {
1704 MBUFQ_DEQUEUE(&sc->sc_scoq, m);
1705 sc->sc_stats.sco_tx++;
1706 /* XXXX: We can transmit with reliable */
1707 sc->sc_flags |= BCSP_XMIT;
1708 bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_HCI_SCO);
1711 return;
1714 static void
1715 bcsp_output_cmd(device_t self, struct mbuf *m)
1717 struct bcsp_softc *sc = device_private(self);
1718 int s;
1720 KASSERT(sc->sc_flags & BCSP_ENABLED);
1722 m_adj(m, sizeof(uint8_t));
1723 M_SETCTX(m, NULL);
1725 s = spltty();
1726 MBUFQ_ENQUEUE(&sc->sc_cmdq, m);
1727 if ((sc->sc_flags & BCSP_XMIT) == 0)
1728 bcsp_start(sc);
1730 splx(s);
1733 static void
1734 bcsp_output_acl(device_t self, struct mbuf *m)
1736 struct bcsp_softc *sc = device_private(self);
1737 int s;
1739 KASSERT(sc->sc_flags & BCSP_ENABLED);
1741 m_adj(m, sizeof(uint8_t));
1742 M_SETCTX(m, NULL);
1744 s = spltty();
1745 MBUFQ_ENQUEUE(&sc->sc_aclq, m);
1746 if ((sc->sc_flags & BCSP_XMIT) == 0)
1747 bcsp_start(sc);
1749 splx(s);
1752 static void
1753 bcsp_output_sco(device_t self, struct mbuf *m)
1755 struct bcsp_softc *sc = device_private(self);
1756 int s;
1758 KASSERT(sc->sc_flags & BCSP_ENABLED);
1760 m_adj(m, sizeof(uint8_t));
1762 s = spltty();
1763 MBUFQ_ENQUEUE(&sc->sc_scoq, m);
1764 if ((sc->sc_flags & BCSP_XMIT) == 0)
1765 bcsp_start(sc);
1767 splx(s);
1770 static void
1771 bcsp_stats(device_t self, struct bt_stats *dest, int flush)
1773 struct bcsp_softc *sc = device_private(self);
1774 int s;
1776 s = spltty();
1777 memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
1779 if (flush)
1780 memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
1782 splx(s);
1786 #ifdef BCSP_DEBUG
1787 static void
1788 bcsp_packet_print(struct mbuf *m)
1790 int i;
1791 uint8_t *p;
1793 for ( ; m != NULL; m = m->m_next) {
1794 p = mtod(m, uint8_t *);
1795 for (i = 0; i < m->m_len; i++) {
1796 if (i % 16 == 0)
1797 printf(" ");
1798 printf(" %02x", *(p + i));
1799 if (i % 16 == 15)
1800 printf("\n");
1802 printf("\n");
1805 #endif