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