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