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