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