xref: /netbsd-src/sys/dev/bluetooth/bcsp.c (revision 481d3881954fd794ca5f2d880b68c53a5db8620e)
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