1 /* $NetBSD: bcsp.c,v 1.34 2024/07/05 04:31:50 rin 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.34 2024/07/05 04:31:50 rin Exp $");
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/callout.h>
34 #include <sys/conf.h>
35 #include <sys/device.h>
36 #include <sys/errno.h>
37 #include <sys/fcntl.h>
38 #include <sys/kauth.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/mbuf.h>
42 #include <sys/proc.h>
43 #include <sys/sysctl.h>
44 #include <sys/syslimits.h>
45 #include <sys/systm.h>
46 #include <sys/tty.h>
47
48 #include <netbt/bluetooth.h>
49 #include <netbt/hci.h>
50
51 #include <dev/bluetooth/bcsp.h>
52
53 #include "ioconf.h"
54
55 #ifdef BCSP_DEBUG
56 #ifdef DPRINTF
57 #undef DPRINTF
58 #endif
59 #ifdef DPRINTFN
60 #undef DPRINTFN
61 #endif
62
63 #define DPRINTF(x) printf x
64 #define DPRINTFN(n, x) do { if (bcsp_debug > (n)) printf x; } while (0)
65 int bcsp_debug = 3;
66 #else
67 #undef DPRINTF
68 #undef DPRINTFN
69
70 #define DPRINTF(x)
71 #define DPRINTFN(n, x)
72 #endif
73
74 struct bcsp_softc {
75 device_t sc_dev;
76
77 struct tty *sc_tp;
78 struct hci_unit *sc_unit; /* Bluetooth HCI Unit */
79 struct bt_stats sc_stats;
80
81 int sc_flags;
82
83 /* output queues */
84 MBUFQ_HEAD() sc_cmdq;
85 MBUFQ_HEAD() sc_aclq;
86 MBUFQ_HEAD() sc_scoq;
87
88 int sc_baud;
89 int sc_init_baud;
90
91 /* variables of SLIP Layer */
92 struct mbuf *sc_txp; /* outgoing packet */
93 struct mbuf *sc_rxp; /* incoming packet */
94 int sc_slip_txrsv; /* reserved byte data */
95 int sc_slip_rxexp; /* expected byte data */
96 void (*sc_transmit_callback)(struct bcsp_softc *, struct mbuf *);
97
98 /* variables of Packet Integrity Layer */
99 int sc_pi_txcrc; /* use CRC, if true */
100
101 /* variables of MUX Layer */
102 bool sc_mux_send_ack; /* flag for send_ack */
103 bool sc_mux_choke; /* Choke signal */
104 struct timeval sc_mux_lastrx; /* Last Rx Pkt Time */
105
106 /* variables of Sequencing Layer */
107 MBUFQ_HEAD() sc_seqq; /* Sequencing Layer queue */
108 MBUFQ_HEAD() sc_seq_retryq; /* retry queue */
109 uint32_t sc_seq_txseq;
110 uint32_t sc_seq_txack;
111 uint32_t sc_seq_expected_rxseq;
112 uint32_t sc_seq_winspace;
113 uint32_t sc_seq_retries;
114 callout_t sc_seq_timer;
115 uint32_t sc_seq_timeout;
116 uint32_t sc_seq_winsize;
117 uint32_t sc_seq_retry_limit;
118
119 /* variables of Datagram Queue Layer */
120 MBUFQ_HEAD() sc_dgq; /* Datagram Queue Layer queue */
121
122 /* variables of BCSP Link Establishment Protocol */
123 bool sc_le_muzzled;
124 bcsp_le_state_t sc_le_state;
125 callout_t sc_le_timer;
126
127 struct sysctllog *sc_log; /* sysctl log */
128 };
129
130 /* sc_flags */
131 #define BCSP_XMIT (1 << 0) /* transmit active */
132 #define BCSP_ENABLED (1 << 1) /* is enabled */
133
134 static int bcsp_match(device_t, cfdata_t, void *);
135 static void bcsp_attach(device_t, device_t, void *);
136 static int bcsp_detach(device_t, int);
137
138 /* tty functions */
139 static int bcspopen(dev_t, struct tty *);
140 static int bcspclose(struct tty *, int);
141 static int bcspioctl(struct tty *, u_long, void *, int, struct lwp *);
142
143 static int bcsp_slip_transmit(struct tty *);
144 static int bcsp_slip_receive(int, struct tty *);
145
146 static void bcsp_pktintegrity_transmit(struct bcsp_softc *);
147 static void bcsp_pktintegrity_receive(struct bcsp_softc *, struct mbuf *);
148 static void bcsp_crc_update(uint16_t *, uint8_t);
149 static uint16_t bcsp_crc_reverse(uint16_t);
150
151 static void bcsp_mux_transmit(struct bcsp_softc *sc);
152 static void bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m);
153 static __inline void bcsp_send_ack_command(struct bcsp_softc *sc);
154 static __inline struct mbuf *bcsp_create_ackpkt(void);
155 static __inline void bcsp_set_choke(struct bcsp_softc *, bool);
156
157 static void bcsp_sequencing_receive(struct bcsp_softc *, struct mbuf *);
158 static bool bcsp_tx_reliable_pkt(struct bcsp_softc *, struct mbuf *, u_int);
159 static __inline u_int bcsp_get_txack(struct bcsp_softc *);
160 static void bcsp_signal_rxack(struct bcsp_softc *, uint32_t);
161 static void bcsp_reliabletx_callback(struct bcsp_softc *, struct mbuf *);
162 static void bcsp_timer_timeout(void *);
163 static void bcsp_sequencing_reset(struct bcsp_softc *);
164
165 static void bcsp_datagramq_receive(struct bcsp_softc *, struct mbuf *);
166 static bool bcsp_tx_unreliable_pkt(struct bcsp_softc *, struct mbuf *, u_int);
167 static void bcsp_unreliabletx_callback(struct bcsp_softc *, struct mbuf *);
168
169 static int bcsp_start_le(struct bcsp_softc *);
170 static void bcsp_terminate_le(struct bcsp_softc *);
171 static void bcsp_input_le(struct bcsp_softc *, struct mbuf *);
172 static void bcsp_le_timeout(void *);
173
174 static void bcsp_start(struct bcsp_softc *);
175
176 /* bluetooth hci functions */
177 static int bcsp_enable(device_t);
178 static void bcsp_disable(device_t);
179 static void bcsp_output_cmd(device_t, struct mbuf *);
180 static void bcsp_output_acl(device_t, struct mbuf *);
181 static void bcsp_output_sco(device_t, struct mbuf *);
182 static void bcsp_stats(device_t, struct bt_stats *, int);
183
184 #ifdef BCSP_DEBUG
185 static 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 */
193 CFATTACH_DECL_NEW(bcsp, sizeof(struct bcsp_softc),
194 bcsp_match, bcsp_attach, bcsp_detach, NULL);
195
196 static 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
209 static 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 */
220 void
bcspattach(int num __unused)221 bcspattach(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 */
247 static int
bcsp_match(device_t self __unused,cfdata_t cfdata __unused,void * arg __unused)248 bcsp_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 */
261 static void
bcsp_attach(device_t parent __unused,device_t self,void * aux __unused)262 bcsp_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
333 err:
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 */
341 static int
bcsp_detach(device_t self,int flags __unused)342 bcsp_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 */
365 static int
bcspopen(dev_t device __unused,struct tty * tp)366 bcspopen(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 cfdata = malloc(sizeof(struct cfdata), M_DEVBUF, M_WAITOK);
391 for (unit = 0; unit < bcsp_cd.cd_ndevs; unit++)
392 if (device_lookup(&bcsp_cd, unit) == NULL)
393 break;
394 cfdata->cf_name = name;
395 cfdata->cf_atname = name;
396 cfdata->cf_unit = unit;
397 cfdata->cf_fstate = FSTATE_STAR;
398
399 aprint_normal("%s%d at tty major %llu minor %llu",
400 name, unit, (unsigned long long)major(tp->t_dev),
401 (unsigned long long)minor(tp->t_dev));
402 dev = config_attach_pseudo(cfdata);
403 if (dev == NULL) {
404 splx(s);
405 return EIO;
406 }
407 sc = device_private(dev);
408
409 ttylock(tp);
410 tp->t_sc = sc;
411 sc->sc_tp = tp;
412 ttyflush(tp, FREAD | FWRITE);
413 ttyunlock(tp);
414
415 splx(s);
416
417 sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
418 bcsp_sequencing_reset(sc);
419
420 /* start link-establishment */
421 bcsp_start_le(sc);
422
423 return 0;
424 }
425
426 /* ARGSUSED */
427 static int
bcspclose(struct tty * tp,int flag __unused)428 bcspclose(struct tty *tp, int flag __unused)
429 {
430 struct bcsp_softc *sc = tp->t_sc;
431 cfdata_t cfdata;
432 int s;
433
434 /* terminate link-establishment */
435 bcsp_terminate_le(sc);
436
437 s = spltty();
438
439 MBUFQ_DRAIN(&sc->sc_dgq);
440 bcsp_sequencing_reset(sc);
441
442 ttylock(tp);
443 ttyflush(tp, FREAD | FWRITE);
444 ttyunlock(tp); /* XXX */
445 ttyldisc_release(tp->t_linesw);
446 tp->t_linesw = ttyldisc_default();
447 if (sc != NULL) {
448 tp->t_sc = NULL;
449 if (sc->sc_tp == tp) {
450 cfdata = device_cfdata(sc->sc_dev);
451 config_detach(sc->sc_dev, 0);
452 free(cfdata, M_DEVBUF);
453 }
454
455 }
456 splx(s);
457 return 0;
458 }
459
460 /* ARGSUSED */
461 static int
bcspioctl(struct tty * tp,u_long cmd,void * data,int flag __unused,struct lwp * l __unused)462 bcspioctl(struct tty *tp, u_long cmd, void *data, int flag __unused,
463 struct lwp *l __unused)
464 {
465 struct bcsp_softc *sc = tp->t_sc;
466 int error;
467
468 /*
469 * XXX
470 * This function can be called without KERNEL_LOCK when caller's
471 * struct cdevsw is set D_MPSAFE. Is KERNEL_LOCK required?
472 */
473
474 if (sc == NULL || tp != sc->sc_tp)
475 return EPASSTHROUGH;
476
477 error = 0;
478 switch (cmd) {
479 default:
480 error = EPASSTHROUGH;
481 break;
482 }
483
484 return error;
485 }
486
487
488 /*
489 * UART Driver Layer is supported by com-driver.
490 */
491
492 /*
493 * BCSP SLIP Layer functions:
494 * Supports to transmit/receive a byte stream.
495 * SLIP protocol described in Internet standard RFC 1055.
496 */
497 static int
bcsp_slip_transmit(struct tty * tp)498 bcsp_slip_transmit(struct tty *tp)
499 {
500 struct bcsp_softc *sc = tp->t_sc;
501 struct mbuf *m;
502 int count, rlen;
503 uint8_t *rptr;
504
505 m = sc->sc_txp;
506 if (m == NULL) {
507 sc->sc_flags &= ~BCSP_XMIT;
508 bcsp_mux_transmit(sc);
509 return 0;
510 }
511
512 count = 0;
513 rlen = 0;
514 rptr = mtod(m, uint8_t *);
515
516 if (sc->sc_slip_txrsv != 0) {
517 #ifdef BCSP_DEBUG
518 if (sc->sc_slip_txrsv == BCSP_SLIP_PKTSTART)
519 DPRINTFN(4, ("%s: slip transmit start\n",
520 device_xname(sc->sc_dev)));
521 else
522 DPRINTFN(4, ("0x%02x ", sc->sc_slip_txrsv));
523 #endif
524
525 if (putc(sc->sc_slip_txrsv, &tp->t_outq) < 0)
526 return 0;
527 count++;
528
529 if (sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_PKTEND ||
530 sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_ESCAPE) {
531 rlen++;
532 rptr++;
533 }
534 sc->sc_slip_txrsv = 0;
535 }
536
537 for(;;) {
538 if (rlen >= m->m_len) {
539 m = m->m_next;
540 if (m == NULL) {
541 if (putc(BCSP_SLIP_PKTEND, &tp->t_outq) < 0)
542 break;
543
544 DPRINTFN(4, ("\n%s: slip transmit end\n",
545 device_xname(sc->sc_dev)));
546
547 m = sc->sc_txp;
548 sc->sc_txp = NULL;
549 sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
550
551 sc->sc_transmit_callback(sc, m);
552 m = NULL;
553 break;
554 }
555
556 rlen = 0;
557 rptr = mtod(m, uint8_t *);
558 continue;
559 }
560
561 if (*rptr == BCSP_SLIP_PKTEND) {
562 if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
563 break;
564 count++;
565 DPRINTFN(4, (" esc "));
566
567 if (putc(BCSP_SLIP_ESCAPE_PKTEND, &tp->t_outq) < 0) {
568 sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_PKTEND;
569 break;
570 }
571 DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_PKTEND));
572 rptr++;
573 } else if (*rptr == BCSP_SLIP_ESCAPE) {
574 if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
575 break;
576 count++;
577 DPRINTFN(4, (" esc "));
578
579 if (putc(BCSP_SLIP_ESCAPE_ESCAPE, &tp->t_outq) < 0) {
580 sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_ESCAPE;
581 break;
582 }
583 DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_ESCAPE));
584 rptr++;
585 } else {
586 if (putc(*rptr++, &tp->t_outq) < 0)
587 break;
588 DPRINTFN(4, ("0x%02x ", *(rptr - 1)));
589 }
590 rlen++;
591 count++;
592 }
593 if (m != NULL)
594 m_adj(m, rlen);
595
596 sc->sc_stats.byte_tx += count;
597
598 if (tp->t_outq.c_cc != 0 && tp->t_oproc != NULL)
599 (*tp->t_oproc)(tp);
600
601 return 0;
602 }
603
604 static int
bcsp_slip_receive(int c,struct tty * tp)605 bcsp_slip_receive(int c, struct tty *tp)
606 {
607 struct bcsp_softc *sc = tp->t_sc;
608 struct mbuf *m = sc->sc_rxp;
609 int discard = 0;
610 const char *errstr;
611
612 c &= TTY_CHARMASK;
613
614 /* If we already started a packet, find the trailing end of it. */
615 if (m) {
616 while (m->m_next)
617 m = m->m_next;
618
619 if (M_TRAILINGSPACE(m) == 0) {
620 /* extend mbuf */
621 MGET(m->m_next, M_DONTWAIT, MT_DATA);
622 if (m->m_next == NULL) {
623 aprint_error_dev(sc->sc_dev,
624 "out of memory\n");
625 sc->sc_stats.err_rx++;
626 return 0; /* (lost sync) */
627 }
628
629 m = m->m_next;
630 m->m_len = 0;
631 }
632 } else
633 if (c != BCSP_SLIP_PKTSTART) {
634 discard = 1;
635 errstr = "not sync";
636 goto discarded;
637 }
638
639 switch (c) {
640 case BCSP_SLIP_PKTSTART /* or _PKTEND */:
641 if (m == NULL) {
642 /* BCSP_SLIP_PKTSTART */
643
644 DPRINTFN(4, ("%s: slip receive start\n",
645 device_xname(sc->sc_dev)));
646
647 /* new packet */
648 MGETHDR(m, M_DONTWAIT, MT_DATA);
649 if (m == NULL) {
650 aprint_error_dev(sc->sc_dev,
651 "out of memory\n");
652 sc->sc_stats.err_rx++;
653 return 0; /* (lost sync) */
654 }
655
656 sc->sc_rxp = m;
657 m->m_pkthdr.len = m->m_len = 0;
658 sc->sc_slip_rxexp = 0;
659 } else {
660 /* BCSP_SLIP_PKTEND */
661
662 if (m == sc->sc_rxp && m->m_len == 0) {
663 DPRINTFN(4, ("%s: resynchronises\n",
664 device_xname(sc->sc_dev)));
665
666 sc->sc_stats.byte_rx++;
667 return 0;
668 }
669
670 DPRINTFN(4, ("%s%s: slip receive end\n",
671 (m->m_len % 16 != 0) ? "\n" : "",
672 device_xname(sc->sc_dev)));
673
674 bcsp_pktintegrity_receive(sc, sc->sc_rxp);
675 sc->sc_rxp = NULL;
676 sc->sc_slip_rxexp = BCSP_SLIP_PKTSTART;
677 }
678 sc->sc_stats.byte_rx++;
679 return 0;
680
681 case BCSP_SLIP_ESCAPE:
682
683 DPRINTFN(4, (" esc"));
684
685 if (sc->sc_slip_rxexp == BCSP_SLIP_ESCAPE) {
686 discard = 1;
687 errstr = "waiting 0xdc or 0xdb";
688 } else
689 sc->sc_slip_rxexp = BCSP_SLIP_ESCAPE;
690 break;
691
692 default:
693 DPRINTFN(4, (" 0x%02x%s",
694 c, (m->m_len % 16 == 15) ? "\n" : ""));
695
696 switch (sc->sc_slip_rxexp) {
697 case BCSP_SLIP_PKTSTART:
698 discard = 1;
699 errstr = "waiting 0xc0";
700 break;
701
702 case BCSP_SLIP_ESCAPE:
703 if (c == BCSP_SLIP_ESCAPE_PKTEND)
704 mtod(m, uint8_t *)[m->m_len++] =
705 BCSP_SLIP_PKTEND;
706 else if (c == BCSP_SLIP_ESCAPE_ESCAPE)
707 mtod(m, uint8_t *)[m->m_len++] =
708 BCSP_SLIP_ESCAPE;
709 else {
710 discard = 1;
711 errstr = "unknown escape";
712 }
713 sc->sc_slip_rxexp = 0;
714 break;
715
716 default:
717 mtod(m, uint8_t *)[m->m_len++] = c;
718 }
719 sc->sc_rxp->m_pkthdr.len++;
720 }
721 if (discard) {
722 discarded:
723 #ifdef BCSP_DEBUG
724 DPRINTFN(4, ("%s: receives unexpected byte 0x%02x: %s\n",
725 device_xname(sc->sc_dev), c, errstr));
726 #else
727 __USE(errstr);
728 #endif
729 }
730 sc->sc_stats.byte_rx++;
731
732 return 0;
733 }
734
735
736 /*
737 * BCSP Packet Integrity Layer functions:
738 * handling Payload Length, Checksum, CRC.
739 */
740 static void
bcsp_pktintegrity_transmit(struct bcsp_softc * sc)741 bcsp_pktintegrity_transmit(struct bcsp_softc *sc)
742 {
743 struct mbuf *m = sc->sc_txp;
744 bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
745 int pldlen;
746
747 DPRINTFN(3, ("%s: pi transmit\n", device_xname(sc->sc_dev)));
748
749 pldlen = m->m_pkthdr.len - sizeof(bcsp_hdr_t);
750
751 if (sc->sc_pi_txcrc)
752 hdrp->flags |= BCSP_FLAGS_CRC_PRESENT;
753
754 BCSP_SET_PLEN(hdrp, pldlen);
755 BCSP_SET_CSUM(hdrp);
756
757 if (sc->sc_pi_txcrc) {
758 struct mbuf *_m;
759 int n = 0;
760 uint16_t crc = 0xffff;
761 uint8_t *buf;
762
763 for (_m = m; _m != NULL; _m = _m->m_next) {
764 buf = mtod(_m, uint8_t *);
765 for (n = 0; n < _m->m_len; n++)
766 bcsp_crc_update(&crc, *(buf + n));
767 }
768 crc = htobe16(bcsp_crc_reverse(crc));
769 m_copyback(m, m->m_pkthdr.len, sizeof(crc), &crc);
770 }
771
772 #ifdef BCSP_DEBUG
773 if (bcsp_debug == 4)
774 bcsp_packet_print(m);
775 #endif
776
777 bcsp_slip_transmit(sc->sc_tp);
778 }
779
780 static void
bcsp_pktintegrity_receive(struct bcsp_softc * sc,struct mbuf * m)781 bcsp_pktintegrity_receive(struct bcsp_softc *sc, struct mbuf *m)
782 {
783 bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
784 u_int pldlen;
785 int discard = 0;
786 uint16_t crc = 0xffff;
787 const char *errstr;
788
789 DPRINTFN(3, ("%s: pi receive\n", device_xname(sc->sc_dev)));
790 #ifdef BCSP_DEBUG
791 if (bcsp_debug == 4)
792 bcsp_packet_print(m);
793 #endif
794
795 KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
796
797 pldlen = m->m_pkthdr.len - sizeof(bcsp_hdr_t) -
798 ((hdrp->flags & BCSP_FLAGS_CRC_PRESENT) ? sizeof(crc) : 0);
799 if (pldlen > 0xfff) {
800 discard = 1;
801 errstr = "Payload Length";
802 goto discarded;
803 }
804 if (hdrp->csum != BCSP_GET_CSUM(hdrp)) {
805 discard = 1;
806 errstr = "Checksum";
807 goto discarded;
808 }
809 if (BCSP_GET_PLEN(hdrp) != pldlen) {
810 discard = 1;
811 errstr = "Payload Length";
812 goto discarded;
813 }
814 if (hdrp->flags & BCSP_FLAGS_CRC_PRESENT) {
815 struct mbuf *_m;
816 int i, n;
817 uint16_t crc0;
818 uint8_t *buf;
819
820 i = 0;
821 n = 0;
822 for (_m = m; _m != NULL; _m = _m->m_next) {
823 buf = mtod(m, uint8_t *);
824 for (n = 0;
825 n < _m->m_len && i < sizeof(bcsp_hdr_t) + pldlen;
826 n++, i++)
827 bcsp_crc_update(&crc, *(buf + n));
828 }
829
830 m_copydata(_m, n, sizeof(crc0), &crc0);
831 if (be16toh(crc0) != bcsp_crc_reverse(crc)) {
832 discard = 1;
833 errstr = "CRC";
834 } else
835 /* Shaves CRC */
836 m_adj(m, (int)(0 - sizeof(crc)));
837 }
838
839 if (discard) {
840 discarded:
841 #ifdef BCSP_DEBUG
842 DPRINTFN(3, ("%s: receives unexpected packet: %s\n",
843 device_xname(sc->sc_dev), errstr));
844 #else
845 __USE(errstr);
846 #endif
847 m_freem(m);
848 } else
849 bcsp_mux_receive(sc, m);
850 }
851
852 static const uint16_t crctbl[] = {
853 0x0000, 0x1081, 0x2102, 0x3183,
854 0x4204, 0x5285, 0x6306, 0x7387,
855 0x8408, 0x9489, 0xa50a, 0xb58b,
856 0xc60c, 0xd68d, 0xe70e, 0xf78f,
857 };
858
859 static void
bcsp_crc_update(uint16_t * crc,uint8_t d)860 bcsp_crc_update(uint16_t *crc, uint8_t d)
861 {
862 uint16_t reg = *crc;
863
864 reg = (reg >> 4) ^ crctbl[(reg ^ d) & 0x000f];
865 reg = (reg >> 4) ^ crctbl[(reg ^ (d >> 4)) & 0x000f];
866
867 *crc = reg;
868 }
869
870 static uint16_t
bcsp_crc_reverse(uint16_t crc)871 bcsp_crc_reverse(uint16_t crc)
872 {
873 uint16_t b, rev;
874
875 for (b = 0, rev = 0; b < 16; b++) {
876 rev = rev << 1;
877 rev |= (crc & 1);
878 crc = crc >> 1;
879 }
880
881 return rev;
882 }
883
884
885 /*
886 * BCSP MUX Layer functions
887 */
888 static void
bcsp_mux_transmit(struct bcsp_softc * sc)889 bcsp_mux_transmit(struct bcsp_softc *sc)
890 {
891 struct mbuf *m;
892 bcsp_hdr_t *hdrp;
893
894 DPRINTFN(2, ("%s: mux transmit: sc_flags=0x%x, choke=%d",
895 device_xname(sc->sc_dev), sc->sc_flags, sc->sc_mux_choke));
896
897 if (sc->sc_mux_choke) {
898 struct mbuf *_m = NULL;
899
900 /* In this case, send only Link Establishment packet */
901 for (m = MBUFQ_FIRST(&sc->sc_dgq); m != NULL;
902 _m = m, m = MBUFQ_NEXT(m)) {
903 hdrp = mtod(m, bcsp_hdr_t *);
904 if (hdrp->ident == BCSP_CHANNEL_LE) {
905 if (m == MBUFQ_FIRST(&sc->sc_dgq))
906 MBUFQ_DEQUEUE(&sc->sc_dgq, m);
907 else {
908 if (m->m_nextpkt == NULL)
909 sc->sc_dgq.mq_last =
910 &_m->m_nextpkt;
911 _m->m_nextpkt = m->m_nextpkt;
912 m->m_nextpkt = NULL;
913 }
914 goto transmit;
915 }
916 }
917 DPRINTFN(2, ("\n"));
918 return;
919 }
920
921 /*
922 * The MUX Layer always gives priority to packets from the Datagram
923 * Queue Layer over the Sequencing Layer.
924 */
925 if (MBUFQ_FIRST(&sc->sc_dgq)) {
926 MBUFQ_DEQUEUE(&sc->sc_dgq, m);
927 goto transmit;
928 }
929 if (MBUFQ_FIRST(&sc->sc_seqq)) {
930 MBUFQ_DEQUEUE(&sc->sc_seqq, m);
931 hdrp = mtod(m, bcsp_hdr_t *);
932 hdrp->flags |= BCSP_FLAGS_PROTOCOL_REL; /* Reliable */
933 goto transmit;
934 }
935 bcsp_start(sc);
936 if (sc->sc_mux_send_ack == true) {
937 m = bcsp_create_ackpkt();
938 if (m != NULL)
939 goto transmit;
940 aprint_error_dev(sc->sc_dev, "out of memory\n");
941 sc->sc_stats.err_tx++;
942 }
943
944 /* Nothing to send */
945 DPRINTFN(2, ("\n"));
946 return;
947
948 transmit:
949 DPRINTFN(2, (", txack=%d, send_ack=%d\n",
950 bcsp_get_txack(sc), sc->sc_mux_send_ack));
951
952 hdrp = mtod(m, bcsp_hdr_t *);
953 hdrp->flags |=
954 (bcsp_get_txack(sc) << BCSP_FLAGS_ACK_SHIFT) & BCSP_FLAGS_ACK_MASK;
955 if (sc->sc_mux_send_ack == true)
956 sc->sc_mux_send_ack = false;
957
958 #ifdef BCSP_DEBUG
959 if (bcsp_debug == 3)
960 bcsp_packet_print(m);
961 #endif
962
963 sc->sc_txp = m;
964 bcsp_pktintegrity_transmit(sc);
965 }
966
967 static void
bcsp_mux_receive(struct bcsp_softc * sc,struct mbuf * m)968 bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m)
969 {
970 bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
971 const u_int rxack = BCSP_FLAGS_ACK(hdrp->flags);
972
973 DPRINTFN(2, ("%s: mux receive: flags=0x%x, ident=%d, rxack=%d\n",
974 device_xname(sc->sc_dev), hdrp->flags, hdrp->ident, rxack));
975 #ifdef BCSP_DEBUG
976 if (bcsp_debug == 3)
977 bcsp_packet_print(m);
978 #endif
979
980 bcsp_signal_rxack(sc, rxack);
981
982 microtime(&sc->sc_mux_lastrx);
983
984 /* if the Ack Packet received then discard */
985 if (BCSP_FLAGS_SEQ(hdrp->flags) == 0 &&
986 hdrp->ident == BCSP_IDENT_ACKPKT &&
987 BCSP_GET_PLEN(hdrp) == 0) {
988 m_freem(m);
989 return;
990 }
991
992 if (hdrp->flags & BCSP_FLAGS_PROTOCOL_REL)
993 bcsp_sequencing_receive(sc, m);
994 else
995 bcsp_datagramq_receive(sc, m);
996 }
997
998 static __inline void
bcsp_send_ack_command(struct bcsp_softc * sc)999 bcsp_send_ack_command(struct bcsp_softc *sc)
1000 {
1001
1002 DPRINTFN(2, ("%s: mux send_ack_command\n", device_xname(sc->sc_dev)));
1003
1004 sc->sc_mux_send_ack = true;
1005 }
1006
1007 static __inline struct mbuf *
bcsp_create_ackpkt(void)1008 bcsp_create_ackpkt(void)
1009 {
1010 struct mbuf *m;
1011 bcsp_hdr_t *hdrp;
1012
1013 MGETHDR(m, M_DONTWAIT, MT_DATA);
1014 if (m != NULL) {
1015 m->m_pkthdr.len = m->m_len = sizeof(bcsp_hdr_t);
1016 hdrp = mtod(m, bcsp_hdr_t *);
1017 /*
1018 * An Ack Packet has the following fields:
1019 * Ack Field: txack (not set yet)
1020 * Seq Field: 0
1021 * Protocol Identifier Field: 0
1022 * Protocol Type Field: Any value
1023 * Payload Length Field: 0
1024 */
1025 memset(hdrp, 0, sizeof(bcsp_hdr_t));
1026 }
1027 return m;
1028 }
1029
1030 static __inline void
bcsp_set_choke(struct bcsp_softc * sc,bool choke)1031 bcsp_set_choke(struct bcsp_softc *sc, bool choke)
1032 {
1033
1034 DPRINTFN(2, ("%s: mux set choke=%d\n", device_xname(sc->sc_dev), choke));
1035
1036 sc->sc_mux_choke = choke;
1037 }
1038
1039
1040 /*
1041 * BCSP Sequencing Layer functions
1042 */
1043 static void
bcsp_sequencing_receive(struct bcsp_softc * sc,struct mbuf * m)1044 bcsp_sequencing_receive(struct bcsp_softc *sc, struct mbuf *m)
1045 {
1046 bcsp_hdr_t hdr;
1047 uint32_t rxseq;
1048
1049 m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
1050 rxseq = BCSP_FLAGS_SEQ(hdr.flags);
1051
1052 DPRINTFN(1, ("%s: seq receive: rxseq=%d, expected %d\n",
1053 device_xname(sc->sc_dev), rxseq, sc->sc_seq_expected_rxseq));
1054 #ifdef BCSP_DEBUG
1055 if (bcsp_debug == 2)
1056 bcsp_packet_print(m);
1057 #endif
1058
1059 /*
1060 * We remove the header of BCSP and add the 'uint8_t type' of
1061 * hci_*_hdr_t to the head.
1062 */
1063 m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
1064
1065 if (rxseq != sc->sc_seq_expected_rxseq) {
1066 m_freem(m);
1067
1068 /* send ack packet, if needly */
1069 bcsp_mux_transmit(sc);
1070
1071 return;
1072 }
1073
1074 switch (hdr.ident) {
1075 case BCSP_CHANNEL_HCI_CMDEVT:
1076 *(mtod(m, uint8_t *)) = HCI_EVENT_PKT;
1077 if (!hci_input_event(sc->sc_unit, m))
1078 sc->sc_stats.err_rx++;
1079
1080 sc->sc_stats.evt_rx++;
1081 break;
1082
1083 case BCSP_CHANNEL_HCI_ACL:
1084 *(mtod(m, uint8_t *)) = HCI_ACL_DATA_PKT;
1085 if (!hci_input_acl(sc->sc_unit, m))
1086 sc->sc_stats.err_rx++;
1087
1088 sc->sc_stats.acl_rx++;
1089 break;
1090
1091 case BCSP_CHANNEL_HCI_SCO:
1092 *(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1093 if (!hci_input_sco(sc->sc_unit, m))
1094 sc->sc_stats.err_rx++;
1095
1096 sc->sc_stats.sco_rx++;
1097 break;
1098
1099 case BCSP_CHANNEL_HQ:
1100 case BCSP_CHANNEL_DEVMGT:
1101 case BCSP_CHANNEL_L2CAP:
1102 case BCSP_CHANNEL_RFCOMM:
1103 case BCSP_CHANNEL_SDP:
1104 case BCSP_CHANNEL_DFU:
1105 case BCSP_CHANNEL_VM:
1106 default:
1107 aprint_error_dev(sc->sc_dev,
1108 "received reliable packet with not support channel %d\n",
1109 hdr.ident);
1110 m_freem(m);
1111 break;
1112 }
1113
1114 sc->sc_seq_expected_rxseq =
1115 (sc->sc_seq_expected_rxseq + 1) & BCSP_FLAGS_SEQ_MASK;
1116 sc->sc_seq_txack = sc->sc_seq_expected_rxseq;
1117 bcsp_send_ack_command(sc);
1118 }
1119
1120 static bool
bcsp_tx_reliable_pkt(struct bcsp_softc * sc,struct mbuf * m,u_int protocol_id)1121 bcsp_tx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1122 {
1123 bcsp_hdr_t *hdrp;
1124 struct mbuf *_m;
1125 u_int pldlen;
1126 int s;
1127
1128 DPRINTFN(1, ("%s: seq transmit:"
1129 "protocol_id=%d, winspace=%d, txseq=%d\n", device_xname(sc->sc_dev),
1130 protocol_id, sc->sc_seq_winspace, sc->sc_seq_txseq));
1131
1132 for (pldlen = 0, _m = m; _m != NULL; _m = _m->m_next) {
1133 if (_m->m_len < 0)
1134 goto out;
1135 pldlen += _m->m_len;
1136 }
1137 if (pldlen > 0xfff)
1138 goto out;
1139 if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
1140 goto out;
1141
1142 if (sc->sc_seq_winspace == 0)
1143 goto out;
1144
1145 M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
1146 if (m == NULL) {
1147 aprint_error_dev(sc->sc_dev, "out of memory\n");
1148 return false;
1149 }
1150 KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
1151
1152 hdrp = mtod(m, bcsp_hdr_t *);
1153 memset(hdrp, 0, sizeof(bcsp_hdr_t));
1154 hdrp->flags |= sc->sc_seq_txseq;
1155 hdrp->ident = protocol_id;
1156
1157 callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1158
1159 s = splserial();
1160 MBUFQ_ENQUEUE(&sc->sc_seqq, m);
1161 splx(s);
1162 sc->sc_transmit_callback = bcsp_reliabletx_callback;
1163
1164 #ifdef BCSP_DEBUG
1165 if (bcsp_debug == 2)
1166 bcsp_packet_print(m);
1167 #endif
1168
1169 sc->sc_seq_txseq = (sc->sc_seq_txseq + 1) & BCSP_FLAGS_SEQ_MASK;
1170 sc->sc_seq_winspace--;
1171 _m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1172 if (_m == NULL) {
1173 aprint_error_dev(sc->sc_dev, "out of memory\n");
1174 goto out;
1175 }
1176 MBUFQ_ENQUEUE(&sc->sc_seq_retryq, _m);
1177 bcsp_mux_transmit(sc);
1178
1179 return true;
1180 out:
1181 m_freem(m);
1182 return false;
1183 }
1184
1185 #if 0
1186 static bool
1187 bcsp_rx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1188 {
1189
1190 return false;
1191 }
1192
1193 /* XXXX: I can't understand meaning this function... */
1194 static __inline void
1195 bcsp_link_failed(struct bcsp_softc *sc)
1196 {
1197
1198 return (sc->sc_seq_retries >= sc->sc_seq_retry_limit);
1199 }
1200 #endif
1201
1202 static __inline u_int
bcsp_get_txack(struct bcsp_softc * sc)1203 bcsp_get_txack(struct bcsp_softc *sc)
1204 {
1205
1206 return sc->sc_seq_txack;
1207 }
1208
1209 static void
bcsp_signal_rxack(struct bcsp_softc * sc,uint32_t rxack)1210 bcsp_signal_rxack(struct bcsp_softc *sc, uint32_t rxack)
1211 {
1212 bcsp_hdr_t *hdrp;
1213 struct mbuf *m;
1214 uint32_t seqno = (rxack - 1) & BCSP_FLAGS_SEQ_MASK;
1215 int s;
1216
1217 DPRINTFN(1, ("%s: seq signal rxack: rxack=%d\n",
1218 device_xname(sc->sc_dev), rxack));
1219
1220 s = splserial();
1221 m = MBUFQ_FIRST(&sc->sc_seq_retryq);
1222 while (m != NULL) {
1223 hdrp = mtod(m, bcsp_hdr_t *);
1224 if (BCSP_FLAGS_SEQ(hdrp->flags) == seqno) {
1225 struct mbuf *m0;
1226
1227 for (m0 = MBUFQ_FIRST(&sc->sc_seq_retryq);
1228 m0 != MBUFQ_NEXT(m);
1229 m0 = MBUFQ_FIRST(&sc->sc_seq_retryq)) {
1230 MBUFQ_DEQUEUE(&sc->sc_seq_retryq, m0);
1231 m_freem(m0);
1232 sc->sc_seq_winspace++;
1233 }
1234 break;
1235 }
1236 m = MBUFQ_NEXT(m);
1237 }
1238 splx(s);
1239 sc->sc_seq_retries = 0;
1240
1241 if (sc->sc_seq_winspace == sc->sc_seq_winsize)
1242 callout_stop(&sc->sc_seq_timer);
1243 else
1244 callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1245 }
1246
1247 static void
bcsp_reliabletx_callback(struct bcsp_softc * sc,struct mbuf * m)1248 bcsp_reliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
1249 {
1250
1251 m_freem(m);
1252 }
1253
1254 static void
bcsp_timer_timeout(void * arg)1255 bcsp_timer_timeout(void *arg)
1256 {
1257 struct bcsp_softc *sc = arg;
1258 struct mbuf *m, *_m;
1259 int s, i = 0;
1260
1261 DPRINTFN(1, ("%s: seq timeout: retries=%d\n",
1262 device_xname(sc->sc_dev), sc->sc_seq_retries));
1263
1264 s = splserial();
1265 for (m = MBUFQ_FIRST(&sc->sc_seq_retryq); m != NULL;
1266 m = MBUFQ_NEXT(m)) {
1267 _m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1268 if (_m == NULL) {
1269 aprint_error_dev(sc->sc_dev, "out of memory\n");
1270 return;
1271 }
1272 MBUFQ_ENQUEUE(&sc->sc_seqq, _m);
1273 i++;
1274 }
1275 splx(s);
1276
1277 if (i != 0) {
1278 if (++sc->sc_seq_retries < sc->sc_seq_retry_limit)
1279 callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1280 else {
1281 aprint_error_dev(sc->sc_dev,
1282 "reached the retry limit."
1283 " restart the link-establishment\n");
1284 bcsp_sequencing_reset(sc);
1285 bcsp_start_le(sc);
1286 return;
1287 }
1288 }
1289 bcsp_mux_transmit(sc);
1290 }
1291
1292 static void
bcsp_sequencing_reset(struct bcsp_softc * sc)1293 bcsp_sequencing_reset(struct bcsp_softc *sc)
1294 {
1295 int s;
1296
1297 s = splserial();
1298 MBUFQ_DRAIN(&sc->sc_seqq);
1299 MBUFQ_DRAIN(&sc->sc_seq_retryq);
1300 splx(s);
1301
1302
1303 sc->sc_seq_txseq = 0;
1304 sc->sc_seq_txack = 0;
1305 sc->sc_seq_winspace = sc->sc_seq_winsize;
1306 sc->sc_seq_retries = 0;
1307 callout_stop(&sc->sc_seq_timer);
1308
1309 sc->sc_mux_send_ack = false;
1310
1311 /* XXXX: expected_rxseq should be set by MUX Layer */
1312 sc->sc_seq_expected_rxseq = 0;
1313 }
1314
1315
1316 /*
1317 * BCSP Datagram Queue Layer functions
1318 */
1319 static void
bcsp_datagramq_receive(struct bcsp_softc * sc,struct mbuf * m)1320 bcsp_datagramq_receive(struct bcsp_softc *sc, struct mbuf *m)
1321 {
1322 bcsp_hdr_t hdr;
1323
1324 DPRINTFN(1, ("%s: dgq receive\n", device_xname(sc->sc_dev)));
1325 #ifdef BCSP_DEBUG
1326 if (bcsp_debug == 2)
1327 bcsp_packet_print(m);
1328 #endif
1329
1330 m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
1331
1332 switch (hdr.ident) {
1333 case BCSP_CHANNEL_LE:
1334 m_adj(m, sizeof(bcsp_hdr_t));
1335 bcsp_input_le(sc, m);
1336 break;
1337
1338 case BCSP_CHANNEL_HCI_SCO:
1339 /*
1340 * We remove the header of BCSP and add the 'uint8_t type' of
1341 * hci_scodata_hdr_t to the head.
1342 */
1343 m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
1344 *(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1345 if (!hci_input_sco(sc->sc_unit, m))
1346 sc->sc_stats.err_rx++;
1347
1348 sc->sc_stats.sco_rx++;
1349 break;
1350
1351 default:
1352 aprint_error_dev(sc->sc_dev,
1353 "received unreliable packet with not support channel %d\n",
1354 hdr.ident);
1355 m_freem(m);
1356 break;
1357 }
1358 }
1359
1360 static bool
bcsp_tx_unreliable_pkt(struct bcsp_softc * sc,struct mbuf * m,u_int protocol_id)1361 bcsp_tx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1362 {
1363 bcsp_hdr_t *hdrp;
1364 struct mbuf *_m;
1365 u_int pldlen;
1366 int s;
1367
1368 DPRINTFN(1, ("%s: dgq transmit: protocol_id=%d,",
1369 device_xname(sc->sc_dev), protocol_id));
1370
1371 for (pldlen = 0, _m = m; _m != NULL; _m = m->m_next) {
1372 if (_m->m_len < 0)
1373 goto out;
1374 pldlen += _m->m_len;
1375 }
1376 DPRINTFN(1, (" pldlen=%d\n", pldlen));
1377 if (pldlen > 0xfff)
1378 goto out;
1379 if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
1380 goto out;
1381
1382 M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
1383 if (m == NULL) {
1384 aprint_error_dev(sc->sc_dev, "out of memory\n");
1385 return false;
1386 }
1387 KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
1388
1389 hdrp = mtod(m, bcsp_hdr_t *);
1390 memset(hdrp, 0, sizeof(bcsp_hdr_t));
1391 hdrp->ident = protocol_id;
1392
1393 s = splserial();
1394 MBUFQ_ENQUEUE(&sc->sc_dgq, m);
1395 splx(s);
1396 sc->sc_transmit_callback = bcsp_unreliabletx_callback;
1397
1398 #ifdef BCSP_DEBUG
1399 if (bcsp_debug == 2)
1400 bcsp_packet_print(m);
1401 #endif
1402
1403 bcsp_mux_transmit(sc);
1404
1405 return true;
1406 out:
1407 m_freem(m);
1408 return false;
1409 }
1410
1411 #if 0
1412 static bool
1413 bcsp_rx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1414 {
1415
1416 return false;
1417 }
1418 #endif
1419
1420 static void
bcsp_unreliabletx_callback(struct bcsp_softc * sc,struct mbuf * m)1421 bcsp_unreliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
1422 {
1423
1424 if (M_GETCTX(m, void *) == NULL)
1425 m_freem(m);
1426 else if (!hci_complete_sco(sc->sc_unit, m))
1427 sc->sc_stats.err_tx++;
1428 }
1429
1430
1431 /*
1432 * BlueCore Link Establishment Protocol functions
1433 */
1434 static const uint8_t sync[] = BCSP_LE_SYNC;
1435 static const uint8_t syncresp[] = BCSP_LE_SYNCRESP;
1436 static const uint8_t conf[] = BCSP_LE_CONF;
1437 static const uint8_t confresp[] = BCSP_LE_CONFRESP;
1438
1439 static int
bcsp_start_le(struct bcsp_softc * sc)1440 bcsp_start_le(struct bcsp_softc *sc)
1441 {
1442
1443 DPRINTF(("%s: start link-establish\n", device_xname(sc->sc_dev)));
1444
1445 bcsp_set_choke(sc, true);
1446
1447 if (!sc->sc_le_muzzled) {
1448 struct mbuf *m;
1449
1450 m = m_gethdr(M_WAIT, MT_DATA);
1451 m->m_pkthdr.len = m->m_len = 0;
1452 m_copyback(m, 0, sizeof(sync), sync);
1453 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE)) {
1454 aprint_error_dev(sc->sc_dev,
1455 "le-packet transmit failed\n");
1456 return EINVAL;
1457 }
1458 }
1459 callout_schedule(&sc->sc_le_timer, BCSP_LE_TSHY_TIMEOUT);
1460
1461 sc->sc_le_state = le_state_shy;
1462 return 0;
1463 }
1464
1465 static void
bcsp_terminate_le(struct bcsp_softc * sc)1466 bcsp_terminate_le(struct bcsp_softc *sc)
1467 {
1468 struct mbuf *m;
1469
1470 /* terminate link-establishment */
1471 callout_stop(&sc->sc_le_timer);
1472 bcsp_set_choke(sc, true);
1473 MGETHDR(m, M_DONTWAIT, MT_DATA);
1474 if (m == NULL)
1475 aprint_error_dev(sc->sc_dev, "out of memory\n");
1476 else {
1477 /* length of le packets is 4 */
1478 m->m_pkthdr.len = m->m_len = 0;
1479 m_copyback(m, 0, sizeof(sync), sync);
1480 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1481 aprint_error_dev(sc->sc_dev,
1482 "link-establishment terminations failed\n");
1483 }
1484 }
1485
1486 static void
bcsp_input_le(struct bcsp_softc * sc,struct mbuf * m)1487 bcsp_input_le(struct bcsp_softc *sc, struct mbuf *m)
1488 {
1489 uint32_t *rcvpkt;
1490 int i;
1491 const uint8_t *rplypkt;
1492 static struct {
1493 const char *type;
1494 const uint8_t *datap;
1495 } pkt[] = {
1496 { "sync", sync },
1497 { "sync-resp", syncresp },
1498 { "conf", conf },
1499 { "conf-resp", confresp },
1500
1501 { NULL, 0 }
1502 };
1503
1504 DPRINTFN(0, ("%s: le input: state %d, muzzled %d\n",
1505 device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1506 #ifdef BCSP_DEBUG
1507 if (bcsp_debug == 1)
1508 bcsp_packet_print(m);
1509 #endif
1510
1511 rcvpkt = mtod(m, uint32_t *);
1512 i = 0;
1513
1514 /* length of le packets is 4 */
1515 if (m->m_len == sizeof(uint32_t))
1516 for (i = 0; pkt[i].type != NULL; i++)
1517 if (*(const uint32_t *)pkt[i].datap == *rcvpkt)
1518 break;
1519 if (m->m_len != sizeof(uint32_t) || pkt[i].type == NULL) {
1520 aprint_error_dev(sc->sc_dev, "received unknown packet\n");
1521 m_freem(m);
1522 return;
1523 }
1524
1525 rplypkt = NULL;
1526 switch (sc->sc_le_state) {
1527 case le_state_shy:
1528 if (*rcvpkt == *(const uint32_t *)sync) {
1529 sc->sc_le_muzzled = false;
1530 rplypkt = syncresp;
1531 } else if (*rcvpkt == *(const uint32_t *)syncresp) {
1532 DPRINTF(("%s: state change to curious\n",
1533 device_xname(sc->sc_dev)));
1534
1535 rplypkt = conf;
1536 callout_schedule(&sc->sc_le_timer,
1537 BCSP_LE_TCONF_TIMEOUT);
1538 sc->sc_le_state = le_state_curious;
1539 } else
1540 aprint_error_dev(sc->sc_dev,
1541 "received an unknown packet at shy\n");
1542 break;
1543
1544 case le_state_curious:
1545 if (*rcvpkt == *(const uint32_t *)sync)
1546 rplypkt = syncresp;
1547 else if (*rcvpkt == *(const uint32_t *)conf)
1548 rplypkt = confresp;
1549 else if (*rcvpkt == *(const uint32_t *)confresp) {
1550 DPRINTF(("%s: state change to garrulous:\n",
1551 device_xname(sc->sc_dev)));
1552
1553 bcsp_set_choke(sc, false);
1554 callout_stop(&sc->sc_le_timer);
1555 sc->sc_le_state = le_state_garrulous;
1556 } else
1557 aprint_error_dev(sc->sc_dev,
1558 "received unknown packet at curious\n");
1559 break;
1560
1561 case le_state_garrulous:
1562 if (*rcvpkt == *(const uint32_t *)conf)
1563 rplypkt = confresp;
1564 else if (*rcvpkt == *(const uint32_t *)sync) {
1565 /* XXXXX */
1566 aprint_error_dev(sc->sc_dev,
1567 "received sync! peer to reset?\n");
1568
1569 bcsp_sequencing_reset(sc);
1570 rplypkt = sync;
1571 sc->sc_le_state = le_state_shy;
1572 } else
1573 aprint_error_dev(sc->sc_dev,
1574 "received unknown packet at garrulous\n");
1575 break;
1576 }
1577
1578 m_freem(m);
1579
1580 if (rplypkt != NULL) {
1581 MGETHDR(m, M_DONTWAIT, MT_DATA);
1582 if (m == NULL)
1583 aprint_error_dev(sc->sc_dev, "out of memory\n");
1584 else {
1585 /* length of le packets is 4 */
1586 m->m_pkthdr.len = m->m_len = 0;
1587 m_copyback(m, 0, 4, rplypkt);
1588 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1589 aprint_error_dev(sc->sc_dev,
1590 "le-packet transmit failed\n");
1591 }
1592 }
1593 }
1594
1595 static void
bcsp_le_timeout(void * arg)1596 bcsp_le_timeout(void *arg)
1597 {
1598 struct bcsp_softc *sc = arg;
1599 struct mbuf *m;
1600 int timeout;
1601 const uint8_t *sndpkt = NULL;
1602
1603 DPRINTFN(0, ("%s: le timeout: state %d, muzzled %d\n",
1604 device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1605
1606 switch (sc->sc_le_state) {
1607 case le_state_shy:
1608 if (!sc->sc_le_muzzled)
1609 sndpkt = sync;
1610 timeout = BCSP_LE_TSHY_TIMEOUT;
1611 break;
1612
1613 case le_state_curious:
1614 sndpkt = conf;
1615 timeout = BCSP_LE_TCONF_TIMEOUT;
1616 break;
1617
1618 default:
1619 aprint_error_dev(sc->sc_dev,
1620 "timeout happen at unknown state %d\n", sc->sc_le_state);
1621 return;
1622 }
1623
1624 if (sndpkt != NULL) {
1625 MGETHDR(m, M_DONTWAIT, MT_DATA);
1626 if (m == NULL)
1627 aprint_error_dev(sc->sc_dev, "out of memory\n");
1628 else {
1629 /* length of le packets is 4 */
1630 m->m_pkthdr.len = m->m_len = 0;
1631 m_copyback(m, 0, 4, sndpkt);
1632 if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1633 aprint_error_dev(sc->sc_dev,
1634 "le-packet transmit failed\n");
1635 }
1636 }
1637
1638 callout_schedule(&sc->sc_le_timer, timeout);
1639 }
1640
1641
1642 /*
1643 * BlueCore Serial Protocol functions.
1644 */
1645 static int
bcsp_enable(device_t self)1646 bcsp_enable(device_t self)
1647 {
1648 struct bcsp_softc *sc = device_private(self);
1649 int s;
1650
1651 if (sc->sc_flags & BCSP_ENABLED)
1652 return 0;
1653
1654 s = spltty();
1655
1656 sc->sc_flags |= BCSP_ENABLED;
1657 sc->sc_flags &= ~BCSP_XMIT;
1658
1659 splx(s);
1660
1661 return 0;
1662 }
1663
1664 static void
bcsp_disable(device_t self)1665 bcsp_disable(device_t self)
1666 {
1667 struct bcsp_softc *sc = device_private(self);
1668 int s;
1669
1670 if ((sc->sc_flags & BCSP_ENABLED) == 0)
1671 return;
1672
1673 s = spltty();
1674
1675 m_freem(sc->sc_rxp);
1676 sc->sc_rxp = NULL;
1677
1678 m_freem(sc->sc_txp);
1679 sc->sc_txp = NULL;
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
1689 static void
bcsp_start(struct bcsp_softc * sc)1690 bcsp_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
1722 static void
bcsp_output_cmd(device_t self,struct mbuf * m)1723 bcsp_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
1741 static void
bcsp_output_acl(device_t self,struct mbuf * m)1742 bcsp_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
1760 static void
bcsp_output_sco(device_t self,struct mbuf * m)1761 bcsp_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
1778 static void
bcsp_stats(device_t self,struct bt_stats * dest,int flush)1779 bcsp_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
1795 static void
bcsp_packet_print(struct mbuf * m)1796 bcsp_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