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