1 /* $NetBSD: bcsp.c,v 1.17 2009/05/07 18:01:57 elad Exp $ */
3 * Copyright (c) 2007 KIYOHARA Takashi
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: bcsp.c,v 1.17 2009/05/07 18:01:57 elad Exp $");
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/callout.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>
43 #include <sys/sysctl.h>
44 #include <sys/syslimits.h>
45 #include <sys/systm.h>
48 #include <netbt/bluetooth.h>
49 #include <netbt/hci.h>
51 #include <dev/bluetooth/bcsp.h>
63 #define DPRINTF(x) printf x
64 #define DPRINTFN(n, x) do { if (bcsp_debug > (n)) printf x; } while (0)
71 #define DPRINTFN(n, x)
78 struct hci_unit
*sc_unit
; /* Bluetooth HCI Unit */
79 struct bt_stats sc_stats
;
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
*);
98 /* variables of Packet Integrity Layer */
99 int sc_pi_txcrc
; /* use CRC, if true */
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 */
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
;
119 /* variables of Datagram Queue Layer */
120 MBUFQ_HEAD() sc_dgq
; /* Datagram Queue Layer queue */
122 /* variables of BCSP Link Establishment Protocol */
124 bcsp_le_state_t sc_le_state
;
125 callout_t sc_le_timer
;
127 struct sysctllog
*sc_log
; /* sysctl log */
131 #define BCSP_XMIT (1 << 0) /* transmit active */
132 #define BCSP_ENABLED (1 << 1) /* is enabled */
134 void bcspattach(int);
135 static int bcsp_match(device_t
, cfdata_t
, void *);
136 static void bcsp_attach(device_t
, device_t
, void *);
137 static int bcsp_detach(device_t
, int);
140 static int bcspopen(dev_t
, struct tty
*);
141 static int bcspclose(struct tty
*, int);
142 static int bcspioctl(struct tty
*, u_long
, void *, int, struct lwp
*);
144 static int bcsp_slip_transmit(struct tty
*);
145 static int bcsp_slip_receive(int, struct tty
*);
147 static void bcsp_pktintegrity_transmit(struct bcsp_softc
*);
148 static void bcsp_pktintegrity_receive(struct bcsp_softc
*, struct mbuf
*);
149 static void bcsp_crc_update(uint16_t *, uint8_t);
150 static uint16_t bcsp_crc_reverse(uint16_t);
152 static void bcsp_mux_transmit(struct bcsp_softc
*sc
);
153 static void bcsp_mux_receive(struct bcsp_softc
*sc
, struct mbuf
*m
);
154 static __inline
void bcsp_send_ack_command(struct bcsp_softc
*sc
);
155 static __inline
struct mbuf
*bcsp_create_ackpkt(void);
156 static __inline
void bcsp_set_choke(struct bcsp_softc
*, bool);
158 static void bcsp_sequencing_receive(struct bcsp_softc
*, struct mbuf
*);
159 static bool bcsp_tx_reliable_pkt(struct bcsp_softc
*, struct mbuf
*, u_int
);
160 static __inline u_int
bcsp_get_txack(struct bcsp_softc
*);
161 static void bcsp_signal_rxack(struct bcsp_softc
*, uint32_t);
162 static void bcsp_reliabletx_callback(struct bcsp_softc
*, struct mbuf
*);
163 static void bcsp_timer_timeout(void *);
164 static void bcsp_sequencing_reset(struct bcsp_softc
*);
166 static void bcsp_datagramq_receive(struct bcsp_softc
*, struct mbuf
*);
167 static bool bcsp_tx_unreliable_pkt(struct bcsp_softc
*, struct mbuf
*, u_int
);
168 static void bcsp_unreliabletx_callback(struct bcsp_softc
*, struct mbuf
*);
170 static int bcsp_start_le(struct bcsp_softc
*);
171 static void bcsp_terminate_le(struct bcsp_softc
*);
172 static void bcsp_input_le(struct bcsp_softc
*, struct mbuf
*);
173 static void bcsp_le_timeout(void *);
175 static void bcsp_start(struct bcsp_softc
*);
177 /* bluetooth hci functions */
178 static int bcsp_enable(device_t
);
179 static void bcsp_disable(device_t
);
180 static void bcsp_output_cmd(device_t
, struct mbuf
*);
181 static void bcsp_output_acl(device_t
, struct mbuf
*);
182 static void bcsp_output_sco(device_t
, struct mbuf
*);
183 static void bcsp_stats(device_t
, struct bt_stats
*, int);
186 static void bcsp_packet_print(struct mbuf
*m
);
191 * It doesn't need to be exported, as only bcspattach() uses it,
192 * but there's no "official" way to make it static.
194 CFATTACH_DECL_NEW(bcsp
, sizeof(struct bcsp_softc
),
195 bcsp_match
, bcsp_attach
, bcsp_detach
, NULL
);
197 static struct linesw bcsp_disc
= {
200 .l_close
= bcspclose
,
203 .l_ioctl
= bcspioctl
,
204 .l_rint
= bcsp_slip_receive
,
205 .l_start
= bcsp_slip_transmit
,
210 static const struct hci_if bcsp_hci
= {
211 .enable
= bcsp_enable
,
212 .disable
= bcsp_disable
,
213 .output_cmd
= bcsp_output_cmd
,
214 .output_acl
= bcsp_output_acl
,
215 .output_sco
= bcsp_output_sco
,
216 .get_stats
= bcsp_stats
,
222 bcspattach(int num __unused
)
226 error
= ttyldisc_attach(&bcsp_disc
);
228 aprint_error("%s: unable to register line discipline, "
229 "error = %d\n", bcsp_cd
.cd_name
, error
);
233 error
= config_cfattach_attach(bcsp_cd
.cd_name
, &bcsp_ca
);
235 aprint_error("%s: unable to register cfattach, error = %d\n",
236 bcsp_cd
.cd_name
, error
);
237 config_cfdriver_detach(&bcsp_cd
);
238 (void) ttyldisc_detach(&bcsp_disc
);
243 * Autoconf match routine.
245 * XXX: unused: config_attach_pseudo(9) does not call ca_match.
249 bcsp_match(device_t self __unused
, cfdata_t cfdata __unused
,
253 /* pseudo-device; always present */
258 * Autoconf attach routine. Called by config_attach_pseudo(9) when we
259 * open the line discipline.
263 bcsp_attach(device_t parent __unused
, device_t self
, void *aux __unused
)
265 struct bcsp_softc
*sc
= device_private(self
);
266 const struct sysctlnode
*node
;
267 int rc
, bcsp_node_num
;
273 callout_init(&sc
->sc_seq_timer
, 0);
274 callout_setfunc(&sc
->sc_seq_timer
, bcsp_timer_timeout
, sc
);
275 callout_init(&sc
->sc_le_timer
, 0);
276 callout_setfunc(&sc
->sc_le_timer
, bcsp_le_timeout
, sc
);
277 sc
->sc_seq_timeout
= BCSP_SEQ_TX_TIMEOUT
;
278 sc
->sc_seq_winsize
= BCSP_SEQ_TX_WINSIZE
;
279 sc
->sc_seq_retry_limit
= BCSP_SEQ_TX_RETRY_LIMIT
;
280 MBUFQ_INIT(&sc
->sc_seqq
);
281 MBUFQ_INIT(&sc
->sc_seq_retryq
);
282 MBUFQ_INIT(&sc
->sc_dgq
);
283 MBUFQ_INIT(&sc
->sc_cmdq
);
284 MBUFQ_INIT(&sc
->sc_aclq
);
285 MBUFQ_INIT(&sc
->sc_scoq
);
287 /* Attach Bluetooth unit */
288 sc
->sc_unit
= hci_attach(&bcsp_hci
, self
, 0);
290 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, NULL
,
291 CTLFLAG_PERMANENT
, CTLTYPE_NODE
, "hw", NULL
,
292 NULL
, 0, NULL
, 0, CTL_HW
, CTL_EOL
)) != 0) {
295 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, &node
,
296 0, CTLTYPE_NODE
, device_xname(self
),
297 SYSCTL_DESCR("bcsp controls"),
298 NULL
, 0, NULL
, 0, CTL_HW
, CTL_CREATE
, CTL_EOL
)) != 0) {
301 bcsp_node_num
= node
->sysctl_num
;
302 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, &node
,
303 CTLFLAG_READWRITE
, CTLTYPE_INT
,
304 "muzzled", SYSCTL_DESCR("muzzled for Link-establishment Layer"),
305 NULL
, 0, &sc
->sc_le_muzzled
,
306 0, CTL_HW
, bcsp_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
309 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, &node
,
310 CTLFLAG_READWRITE
, CTLTYPE_INT
,
311 "txcrc", SYSCTL_DESCR("txcrc for Packet Integrity Layer"),
312 NULL
, 0, &sc
->sc_pi_txcrc
,
313 0, CTL_HW
, bcsp_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
316 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, &node
,
317 CTLFLAG_READWRITE
, CTLTYPE_INT
,
318 "timeout", SYSCTL_DESCR("timeout for Sequencing Layer"),
319 NULL
, 0, &sc
->sc_seq_timeout
,
320 0, CTL_HW
, bcsp_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
323 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, &node
,
324 CTLFLAG_READWRITE
, CTLTYPE_INT
,
325 "winsize", SYSCTL_DESCR("winsize for Sequencing Layer"),
326 NULL
, 0, &sc
->sc_seq_winsize
,
327 0, CTL_HW
, bcsp_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
330 if ((rc
= sysctl_createv(&sc
->sc_log
, 0, NULL
, &node
,
331 CTLFLAG_READWRITE
, CTLTYPE_INT
,
332 "retry_limit", SYSCTL_DESCR("retry limit for Sequencing Layer"),
333 NULL
, 0, &sc
->sc_seq_retry_limit
,
334 0, CTL_HW
, bcsp_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
340 aprint_error_dev(self
, "sysctl_createv failed (rc = %d)\n", rc
);
344 * Autoconf detach routine. Called when we close the line discipline.
348 bcsp_detach(device_t self
, int flags __unused
)
350 struct bcsp_softc
*sc
= device_private(self
);
352 if (sc
->sc_unit
!= NULL
) {
353 hci_detach(sc
->sc_unit
);
357 callout_stop(&sc
->sc_seq_timer
);
358 callout_destroy(&sc
->sc_seq_timer
);
360 callout_stop(&sc
->sc_le_timer
);
361 callout_destroy(&sc
->sc_le_timer
);
368 * Line discipline functions.
372 bcspopen(dev_t device __unused
, struct tty
*tp
)
374 struct bcsp_softc
*sc
;
377 struct lwp
*l
= curlwp
; /* XXX */
379 static char name
[] = "bcsp";
381 error
= kauth_authorize_device(l
->l_cred
, KAUTH_DEVICE_BLUETOOTH_BCSP
,
382 KAUTH_ARG(KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD
), NULL
, NULL
, NULL
);
388 if (tp
->t_linesw
== &bcsp_disc
) {
396 KASSERT(tp
->t_oproc
!= NULL
);
398 cfdata
= malloc(sizeof(struct cfdata
), M_DEVBUF
, M_WAITOK
);
399 for (unit
= 0; unit
< bcsp_cd
.cd_ndevs
; unit
++)
400 if (device_lookup(&bcsp_cd
, unit
) == NULL
)
402 cfdata
->cf_name
= name
;
403 cfdata
->cf_atname
= name
;
404 cfdata
->cf_unit
= unit
;
405 cfdata
->cf_fstate
= FSTATE_STAR
;
407 aprint_normal("%s%d at tty major %llu minor %llu",
408 name
, unit
, (unsigned long long)major(tp
->t_dev
),
409 (unsigned long long)minor(tp
->t_dev
));
410 dev
= config_attach_pseudo(cfdata
);
415 sc
= device_private(dev
);
417 mutex_spin_enter(&tty_lock
);
420 ttyflush(tp
, FREAD
| FWRITE
);
421 mutex_spin_exit(&tty_lock
);
425 sc
->sc_slip_txrsv
= BCSP_SLIP_PKTSTART
;
426 bcsp_sequencing_reset(sc
);
428 /* start link-establishment */
436 bcspclose(struct tty
*tp
, int flag __unused
)
438 struct bcsp_softc
*sc
= tp
->t_sc
;
442 /* terminate link-establishment */
443 bcsp_terminate_le(sc
);
447 MBUFQ_DRAIN(&sc
->sc_dgq
);
448 bcsp_sequencing_reset(sc
);
450 mutex_spin_enter(&tty_lock
);
451 ttyflush(tp
, FREAD
| FWRITE
);
452 mutex_spin_exit(&tty_lock
); /* XXX */
453 ttyldisc_release(tp
->t_linesw
);
454 tp
->t_linesw
= ttyldisc_default();
457 if (sc
->sc_tp
== tp
) {
458 cfdata
= device_cfdata(sc
->sc_dev
);
459 config_detach(sc
->sc_dev
, 0);
460 free(cfdata
, M_DEVBUF
);
470 bcspioctl(struct tty
*tp
, u_long cmd
, void *data
, int flag __unused
,
471 struct lwp
*l __unused
)
473 struct bcsp_softc
*sc
= tp
->t_sc
;
476 if (sc
== NULL
|| tp
!= sc
->sc_tp
)
482 error
= EPASSTHROUGH
;
491 * UART Driver Layer is supported by com-driver.
495 * BCSP SLIP Layer functions:
496 * Supports to transmit/receive a byte stream.
497 * SLIP protocol described in Internet standard RFC 1055.
500 bcsp_slip_transmit(struct tty
*tp
)
502 struct bcsp_softc
*sc
= tp
->t_sc
;
509 sc
->sc_flags
&= ~BCSP_XMIT
;
510 bcsp_mux_transmit(sc
);
516 rptr
= mtod(m
, uint8_t *);
518 if (sc
->sc_slip_txrsv
!= 0) {
520 if (sc
->sc_slip_txrsv
== BCSP_SLIP_PKTSTART
)
521 DPRINTFN(4, ("%s: slip transmit start\n",
522 device_xname(sc
->sc_dev
)));
524 DPRINTFN(4, ("0x%02x ", sc
->sc_slip_txrsv
));
527 if (putc(sc
->sc_slip_txrsv
, &tp
->t_outq
) < 0)
531 if (sc
->sc_slip_txrsv
== BCSP_SLIP_ESCAPE_PKTEND
||
532 sc
->sc_slip_txrsv
== BCSP_SLIP_ESCAPE_ESCAPE
) {
536 sc
->sc_slip_txrsv
= 0;
540 if (rlen
>= m
->m_len
) {
543 if (putc(BCSP_SLIP_PKTEND
, &tp
->t_outq
) < 0)
546 DPRINTFN(4, ("\n%s: slip transmit end\n",
547 device_xname(sc
->sc_dev
)));
551 sc
->sc_slip_txrsv
= BCSP_SLIP_PKTSTART
;
553 sc
->sc_transmit_callback(sc
, m
);
559 rptr
= mtod(m
, uint8_t *);
563 if (*rptr
== BCSP_SLIP_PKTEND
) {
564 if (putc(BCSP_SLIP_ESCAPE
, &tp
->t_outq
) < 0)
567 DPRINTFN(4, (" esc "));
569 if (putc(BCSP_SLIP_ESCAPE_PKTEND
, &tp
->t_outq
) < 0) {
570 sc
->sc_slip_txrsv
= BCSP_SLIP_ESCAPE_PKTEND
;
573 DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_PKTEND
));
575 } else if (*rptr
== BCSP_SLIP_ESCAPE
) {
576 if (putc(BCSP_SLIP_ESCAPE
, &tp
->t_outq
) < 0)
579 DPRINTFN(4, (" esc "));
581 if (putc(BCSP_SLIP_ESCAPE_ESCAPE
, &tp
->t_outq
) < 0) {
582 sc
->sc_slip_txrsv
= BCSP_SLIP_ESCAPE_ESCAPE
;
585 DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_ESCAPE
));
588 if (putc(*rptr
++, &tp
->t_outq
) < 0)
590 DPRINTFN(4, ("0x%02x ", *(rptr
- 1)));
598 sc
->sc_stats
.byte_tx
+= count
;
600 if (tp
->t_outq
.c_cc
!= 0)
607 bcsp_slip_receive(int c
, struct tty
*tp
)
609 struct bcsp_softc
*sc
= tp
->t_sc
;
610 struct mbuf
*m
= sc
->sc_rxp
;
616 /* If we already started a packet, find the trailing end of it. */
621 if (M_TRAILINGSPACE(m
) == 0) {
623 MGET(m
->m_next
, M_DONTWAIT
, MT_DATA
);
624 if (m
->m_next
== NULL
) {
625 aprint_error_dev(sc
->sc_dev
,
627 sc
->sc_stats
.err_rx
++;
628 return 0; /* (lost sync) */
635 if (c
!= BCSP_SLIP_PKTSTART
) {
642 case BCSP_SLIP_PKTSTART
/* or _PKTEND */:
644 /* BCSP_SLIP_PKTSTART */
646 DPRINTFN(4, ("%s: slip receive start\n",
647 device_xname(sc
->sc_dev
)));
650 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
652 aprint_error_dev(sc
->sc_dev
,
654 sc
->sc_stats
.err_rx
++;
655 return 0; /* (lost sync) */
659 m
->m_pkthdr
.len
= m
->m_len
= 0;
660 sc
->sc_slip_rxexp
= 0;
662 /* BCSP_SLIP_PKTEND */
664 if (m
== sc
->sc_rxp
&& m
->m_len
== 0) {
665 DPRINTFN(4, ("%s: resynchronises\n",
666 device_xname(sc
->sc_dev
)));
668 sc
->sc_stats
.byte_rx
++;
672 DPRINTFN(4, ("%s%s: slip receive end\n",
673 (m
->m_len
% 16 != 0) ? "\n" : "",
674 device_xname(sc
->sc_dev
)));
676 bcsp_pktintegrity_receive(sc
, sc
->sc_rxp
);
678 sc
->sc_slip_rxexp
= BCSP_SLIP_PKTSTART
;
680 sc
->sc_stats
.byte_rx
++;
683 case BCSP_SLIP_ESCAPE
:
685 DPRINTFN(4, (" esc"));
687 if (sc
->sc_slip_rxexp
== BCSP_SLIP_ESCAPE
) {
689 errstr
= "waiting 0xdc or 0xdb";
691 sc
->sc_slip_rxexp
= BCSP_SLIP_ESCAPE
;
695 DPRINTFN(4, (" 0x%02x%s",
696 c
, (m
->m_len
% 16 == 15) ? "\n" : ""));
698 switch (sc
->sc_slip_rxexp
) {
699 case BCSP_SLIP_PKTSTART
:
701 errstr
= "waiting 0xc0";
704 case BCSP_SLIP_ESCAPE
:
705 if (c
== BCSP_SLIP_ESCAPE_PKTEND
)
706 mtod(m
, uint8_t *)[m
->m_len
++] =
708 else if (c
== BCSP_SLIP_ESCAPE_ESCAPE
)
709 mtod(m
, uint8_t *)[m
->m_len
++] =
713 errstr
= "unknown escape";
715 sc
->sc_slip_rxexp
= 0;
719 mtod(m
, uint8_t *)[m
->m_len
++] = c
;
721 sc
->sc_rxp
->m_pkthdr
.len
++;
725 DPRINTFN(4, ("%s: receives unexpected byte 0x%02x: %s\n",
726 device_xname(sc
->sc_dev
), c
, errstr
));
728 sc
->sc_stats
.byte_rx
++;
735 * BCSP Packet Integrity Layer functions:
736 * handling Payload Length, Checksum, CRC.
739 bcsp_pktintegrity_transmit(struct bcsp_softc
*sc
)
741 struct mbuf
*m
= sc
->sc_txp
;
742 bcsp_hdr_t
*hdrp
= mtod(m
, bcsp_hdr_t
*);
745 DPRINTFN(3, ("%s: pi transmit\n", device_xname(sc
->sc_dev
)));
747 pldlen
= m
->m_pkthdr
.len
- sizeof(bcsp_hdr_t
);
750 hdrp
->flags
|= BCSP_FLAGS_CRC_PRESENT
;
752 BCSP_SET_PLEN(hdrp
, pldlen
);
755 if (sc
->sc_pi_txcrc
) {
758 uint16_t crc
= 0xffff;
761 for (_m
= m
; _m
!= NULL
; _m
= _m
->m_next
) {
762 buf
= mtod(_m
, uint8_t *);
763 for (n
= 0; n
< _m
->m_len
; n
++)
764 bcsp_crc_update(&crc
, *(buf
+ n
));
766 crc
= htobe16(bcsp_crc_reverse(crc
));
767 m_copyback(m
, m
->m_pkthdr
.len
, sizeof(crc
), &crc
);
772 bcsp_packet_print(m
);
775 bcsp_slip_transmit(sc
->sc_tp
);
779 bcsp_pktintegrity_receive(struct bcsp_softc
*sc
, struct mbuf
*m
)
781 bcsp_hdr_t
*hdrp
= mtod(m
, bcsp_hdr_t
*);
784 uint16_t crc
= 0xffff;
787 DPRINTFN(3, ("%s: pi receive\n", device_xname(sc
->sc_dev
)));
790 bcsp_packet_print(m
);
793 KASSERT(m
->m_len
>= sizeof(bcsp_hdr_t
));
795 pldlen
= m
->m_pkthdr
.len
- sizeof(bcsp_hdr_t
) -
796 ((hdrp
->flags
& BCSP_FLAGS_CRC_PRESENT
) ? sizeof(crc
) : 0);
797 if (pldlen
> 0xfff) {
799 errstr
= "Payload Length";
802 if (hdrp
->csum
!= BCSP_GET_CSUM(hdrp
)) {
807 if (BCSP_GET_PLEN(hdrp
) != pldlen
) {
809 errstr
= "Payload Length";
812 if (hdrp
->flags
& BCSP_FLAGS_CRC_PRESENT
) {
820 for (_m
= m
; _m
!= NULL
; _m
= _m
->m_next
) {
821 buf
= mtod(m
, uint8_t *);
823 n
< _m
->m_len
&& i
< sizeof(bcsp_hdr_t
) + pldlen
;
825 bcsp_crc_update(&crc
, *(buf
+ n
));
828 m_copydata(_m
, n
, sizeof(crc0
), &crc0
);
829 if (be16toh(crc0
) != bcsp_crc_reverse(crc
)) {
834 m_adj(m
, (int)(0 - sizeof(crc
)));
839 DPRINTFN(3, ("%s: receives unexpected packet: %s\n",
840 device_xname(sc
->sc_dev
), errstr
));
843 bcsp_mux_receive(sc
, m
);
846 static const uint16_t crctbl
[] = {
847 0x0000, 0x1081, 0x2102, 0x3183,
848 0x4204, 0x5285, 0x6306, 0x7387,
849 0x8408, 0x9489, 0xa50a, 0xb58b,
850 0xc60c, 0xd68d, 0xe70e, 0xf78f,
854 bcsp_crc_update(uint16_t *crc
, uint8_t d
)
858 reg
= (reg
>> 4) ^ crctbl
[(reg
^ d
) & 0x000f];
859 reg
= (reg
>> 4) ^ crctbl
[(reg
^ (d
>> 4)) & 0x000f];
865 bcsp_crc_reverse(uint16_t crc
)
869 for (b
= 0, rev
= 0; b
< 16; b
++) {
880 * BCSP MUX Layer functions
883 bcsp_mux_transmit(struct bcsp_softc
*sc
)
888 DPRINTFN(2, ("%s: mux transmit: sc_flags=0x%x, choke=%d",
889 device_xname(sc
->sc_dev
), sc
->sc_flags
, sc
->sc_mux_choke
));
891 if (sc
->sc_mux_choke
) {
892 struct mbuf
*_m
= NULL
;
894 /* In this case, send only Link Establishment packet */
895 for (m
= MBUFQ_FIRST(&sc
->sc_dgq
); m
!= NULL
;
896 _m
= m
, m
= MBUFQ_NEXT(m
)) {
897 hdrp
= mtod(m
, bcsp_hdr_t
*);
898 if (hdrp
->ident
== BCSP_CHANNEL_LE
) {
899 if (m
== MBUFQ_FIRST(&sc
->sc_dgq
))
900 MBUFQ_DEQUEUE(&sc
->sc_dgq
, m
);
902 if (m
->m_nextpkt
== NULL
)
905 _m
->m_nextpkt
= m
->m_nextpkt
;
916 * The MUX Layer always gives priority to packets from the Datagram
917 * Queue Layer over the Sequencing Layer.
919 if (MBUFQ_FIRST(&sc
->sc_dgq
)) {
920 MBUFQ_DEQUEUE(&sc
->sc_dgq
, m
);
923 if (MBUFQ_FIRST(&sc
->sc_seqq
)) {
924 MBUFQ_DEQUEUE(&sc
->sc_seqq
, m
);
925 hdrp
= mtod(m
, bcsp_hdr_t
*);
926 hdrp
->flags
|= BCSP_FLAGS_PROTOCOL_REL
; /* Reliable */
930 if (sc
->sc_mux_send_ack
== true) {
931 m
= bcsp_create_ackpkt();
934 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
935 sc
->sc_stats
.err_tx
++;
938 /* Nothing to send */
943 DPRINTFN(2, (", txack=%d, send_ack=%d\n",
944 bcsp_get_txack(sc
), sc
->sc_mux_send_ack
));
946 hdrp
= mtod(m
, bcsp_hdr_t
*);
948 (bcsp_get_txack(sc
) << BCSP_FLAGS_ACK_SHIFT
) & BCSP_FLAGS_ACK_MASK
;
949 if (sc
->sc_mux_send_ack
== true)
950 sc
->sc_mux_send_ack
= false;
954 bcsp_packet_print(m
);
958 bcsp_pktintegrity_transmit(sc
);
962 bcsp_mux_receive(struct bcsp_softc
*sc
, struct mbuf
*m
)
964 bcsp_hdr_t
*hdrp
= mtod(m
, bcsp_hdr_t
*);
965 const u_int rxack
= BCSP_FLAGS_ACK(hdrp
->flags
);
967 DPRINTFN(2, ("%s: mux receive: flags=0x%x, ident=%d, rxack=%d\n",
968 device_xname(sc
->sc_dev
), hdrp
->flags
, hdrp
->ident
, rxack
));
971 bcsp_packet_print(m
);
974 bcsp_signal_rxack(sc
, rxack
);
976 microtime(&sc
->sc_mux_lastrx
);
978 /* if the Ack Packet received then discard */
979 if (BCSP_FLAGS_SEQ(hdrp
->flags
) == 0 &&
980 hdrp
->ident
== BCSP_IDENT_ACKPKT
&&
981 BCSP_GET_PLEN(hdrp
) == 0) {
986 if (hdrp
->flags
& BCSP_FLAGS_PROTOCOL_REL
)
987 bcsp_sequencing_receive(sc
, m
);
989 bcsp_datagramq_receive(sc
, m
);
993 bcsp_send_ack_command(struct bcsp_softc
*sc
)
996 DPRINTFN(2, ("%s: mux send_ack_command\n", device_xname(sc
->sc_dev
)));
998 sc
->sc_mux_send_ack
= true;
1001 static __inline
struct mbuf
*
1002 bcsp_create_ackpkt(void)
1007 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1009 m
->m_pkthdr
.len
= m
->m_len
= sizeof(bcsp_hdr_t
);
1010 hdrp
= mtod(m
, bcsp_hdr_t
*);
1012 * An Ack Packet has the following fields:
1013 * Ack Field: txack (not set yet)
1015 * Protocol Identifier Field: 0
1016 * Protocol Type Field: Any value
1017 * Payload Length Field: 0
1019 memset(hdrp
, 0, sizeof(bcsp_hdr_t
));
1024 static __inline
void
1025 bcsp_set_choke(struct bcsp_softc
*sc
, bool choke
)
1028 DPRINTFN(2, ("%s: mux set choke=%d\n", device_xname(sc
->sc_dev
), choke
));
1030 sc
->sc_mux_choke
= choke
;
1035 * BCSP Sequencing Layer functions
1038 bcsp_sequencing_receive(struct bcsp_softc
*sc
, struct mbuf
*m
)
1043 m_copydata(m
, 0, sizeof(bcsp_hdr_t
), &hdr
);
1044 rxseq
= BCSP_FLAGS_SEQ(hdr
.flags
);
1046 DPRINTFN(1, ("%s: seq receive: rxseq=%d, expected %d\n",
1047 device_xname(sc
->sc_dev
), rxseq
, sc
->sc_seq_expected_rxseq
));
1049 if (bcsp_debug
== 2)
1050 bcsp_packet_print(m
);
1054 * We remove the header of BCSP and add the 'uint8_t type' of
1055 * hci_*_hdr_t to the head.
1057 m_adj(m
, sizeof(bcsp_hdr_t
) - sizeof(uint8_t));
1059 if (rxseq
!= sc
->sc_seq_expected_rxseq
) {
1062 /* send ack packet, if needly */
1063 bcsp_mux_transmit(sc
);
1068 switch (hdr
.ident
) {
1069 case BCSP_CHANNEL_HCI_CMDEVT
:
1070 *(mtod(m
, uint8_t *)) = HCI_EVENT_PKT
;
1071 if (!hci_input_event(sc
->sc_unit
, m
))
1072 sc
->sc_stats
.err_rx
++;
1074 sc
->sc_stats
.evt_rx
++;
1077 case BCSP_CHANNEL_HCI_ACL
:
1078 *(mtod(m
, uint8_t *)) = HCI_ACL_DATA_PKT
;
1079 if (!hci_input_acl(sc
->sc_unit
, m
))
1080 sc
->sc_stats
.err_rx
++;
1082 sc
->sc_stats
.acl_rx
++;
1085 case BCSP_CHANNEL_HCI_SCO
:
1086 *(mtod(m
, uint8_t *)) = HCI_SCO_DATA_PKT
;
1087 if (!hci_input_sco(sc
->sc_unit
, m
))
1088 sc
->sc_stats
.err_rx
++;
1090 sc
->sc_stats
.sco_rx
++;
1093 case BCSP_CHANNEL_HQ
:
1094 case BCSP_CHANNEL_DEVMGT
:
1095 case BCSP_CHANNEL_L2CAP
:
1096 case BCSP_CHANNEL_RFCOMM
:
1097 case BCSP_CHANNEL_SDP
:
1098 case BCSP_CHANNEL_DFU
:
1099 case BCSP_CHANNEL_VM
:
1101 aprint_error_dev(sc
->sc_dev
,
1102 "received reliable packet with not support channel %d\n",
1108 sc
->sc_seq_expected_rxseq
=
1109 (sc
->sc_seq_expected_rxseq
+ 1) & BCSP_FLAGS_SEQ_MASK
;
1110 sc
->sc_seq_txack
= sc
->sc_seq_expected_rxseq
;
1111 bcsp_send_ack_command(sc
);
1115 bcsp_tx_reliable_pkt(struct bcsp_softc
*sc
, struct mbuf
*m
, u_int protocol_id
)
1122 DPRINTFN(1, ("%s: seq transmit:"
1123 "protocol_id=%d, winspace=%d, txseq=%d\n", device_xname(sc
->sc_dev
),
1124 protocol_id
, sc
->sc_seq_winspace
, sc
->sc_seq_txseq
));
1126 for (pldlen
= 0, _m
= m
; _m
!= NULL
; _m
= _m
->m_next
) {
1129 pldlen
+= _m
->m_len
;
1133 if (protocol_id
== BCSP_IDENT_ACKPKT
|| protocol_id
> 15)
1136 if (sc
->sc_seq_winspace
== 0)
1139 M_PREPEND(m
, sizeof(bcsp_hdr_t
), M_DONTWAIT
);
1141 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1144 KASSERT(m
->m_len
>= sizeof(bcsp_hdr_t
));
1146 hdrp
= mtod(m
, bcsp_hdr_t
*);
1147 memset(hdrp
, 0, sizeof(bcsp_hdr_t
));
1148 hdrp
->flags
|= sc
->sc_seq_txseq
;
1149 hdrp
->ident
= protocol_id
;
1151 callout_schedule(&sc
->sc_seq_timer
, sc
->sc_seq_timeout
);
1154 MBUFQ_ENQUEUE(&sc
->sc_seqq
, m
);
1156 sc
->sc_transmit_callback
= bcsp_reliabletx_callback
;
1159 if (bcsp_debug
== 2)
1160 bcsp_packet_print(m
);
1163 sc
->sc_seq_txseq
= (sc
->sc_seq_txseq
+ 1) & BCSP_FLAGS_SEQ_MASK
;
1164 sc
->sc_seq_winspace
--;
1165 _m
= m_copym(m
, 0, M_COPYALL
, M_DONTWAIT
);
1167 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1170 MBUFQ_ENQUEUE(&sc
->sc_seq_retryq
, _m
);
1171 bcsp_mux_transmit(sc
);
1178 bcsp_rx_reliable_pkt(struct bcsp_softc
*sc
, struct mbuf
*m
, u_int protocol_id
)
1184 /* XXXX: I can't understand meaning this function... */
1185 static __inline
void
1186 bcsp_link_failed(struct bcsp_softc
*sc
)
1189 return (sc
->sc_seq_retries
>= sc
->sc_seq_retry_limit
);
1193 static __inline u_int
1194 bcsp_get_txack(struct bcsp_softc
*sc
)
1197 return sc
->sc_seq_txack
;
1201 bcsp_signal_rxack(struct bcsp_softc
*sc
, uint32_t rxack
)
1205 uint32_t seqno
= (rxack
- 1) & BCSP_FLAGS_SEQ_MASK
;
1208 DPRINTFN(1, ("%s: seq signal rxack: rxack=%d\n",
1209 device_xname(sc
->sc_dev
), rxack
));
1212 m
= MBUFQ_FIRST(&sc
->sc_seq_retryq
);
1214 hdrp
= mtod(m
, bcsp_hdr_t
*);
1215 if (BCSP_FLAGS_SEQ(hdrp
->flags
) == seqno
) {
1218 for (m0
= MBUFQ_FIRST(&sc
->sc_seq_retryq
);
1219 m0
!= MBUFQ_NEXT(m
);
1220 m0
= MBUFQ_FIRST(&sc
->sc_seq_retryq
)) {
1221 MBUFQ_DEQUEUE(&sc
->sc_seq_retryq
, m0
);
1223 sc
->sc_seq_winspace
++;
1230 sc
->sc_seq_retries
= 0;
1232 if (sc
->sc_seq_winspace
== sc
->sc_seq_winsize
)
1233 callout_stop(&sc
->sc_seq_timer
);
1235 callout_schedule(&sc
->sc_seq_timer
, sc
->sc_seq_timeout
);
1239 bcsp_reliabletx_callback(struct bcsp_softc
*sc
, struct mbuf
*m
)
1246 bcsp_timer_timeout(void *arg
)
1248 struct bcsp_softc
*sc
= arg
;
1249 struct mbuf
*m
, *_m
;
1252 DPRINTFN(1, ("%s: seq timeout: retries=%d\n",
1253 device_xname(sc
->sc_dev
), sc
->sc_seq_retries
));
1256 for (m
= MBUFQ_FIRST(&sc
->sc_seq_retryq
); m
!= NULL
;
1257 m
= MBUFQ_NEXT(m
)) {
1258 _m
= m_copym(m
, 0, M_COPYALL
, M_DONTWAIT
);
1260 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1263 MBUFQ_ENQUEUE(&sc
->sc_seqq
, _m
);
1269 if (++sc
->sc_seq_retries
< sc
->sc_seq_retry_limit
)
1270 callout_schedule(&sc
->sc_seq_timer
, sc
->sc_seq_timeout
);
1272 aprint_error_dev(sc
->sc_dev
,
1273 "reached the retry limit."
1274 " restart the link-establishment\n");
1275 bcsp_sequencing_reset(sc
);
1280 bcsp_mux_transmit(sc
);
1284 bcsp_sequencing_reset(struct bcsp_softc
*sc
)
1289 MBUFQ_DRAIN(&sc
->sc_seqq
);
1290 MBUFQ_DRAIN(&sc
->sc_seq_retryq
);
1294 sc
->sc_seq_txseq
= 0;
1295 sc
->sc_seq_txack
= 0;
1296 sc
->sc_seq_winspace
= sc
->sc_seq_winsize
;
1297 sc
->sc_seq_retries
= 0;
1298 callout_stop(&sc
->sc_seq_timer
);
1300 sc
->sc_mux_send_ack
= false;
1302 /* XXXX: expected_rxseq should be set by MUX Layer */
1303 sc
->sc_seq_expected_rxseq
= 0;
1308 * BCSP Datagram Queue Layer functions
1311 bcsp_datagramq_receive(struct bcsp_softc
*sc
, struct mbuf
*m
)
1315 DPRINTFN(1, ("%s: dgq receive\n", device_xname(sc
->sc_dev
)));
1317 if (bcsp_debug
== 2)
1318 bcsp_packet_print(m
);
1321 m_copydata(m
, 0, sizeof(bcsp_hdr_t
), &hdr
);
1323 switch (hdr
.ident
) {
1324 case BCSP_CHANNEL_LE
:
1325 m_adj(m
, sizeof(bcsp_hdr_t
));
1326 bcsp_input_le(sc
, m
);
1329 case BCSP_CHANNEL_HCI_SCO
:
1331 * We remove the header of BCSP and add the 'uint8_t type' of
1332 * hci_scodata_hdr_t to the head.
1334 m_adj(m
, sizeof(bcsp_hdr_t
) - sizeof(uint8_t));
1335 *(mtod(m
, uint8_t *)) = HCI_SCO_DATA_PKT
;
1336 if (!hci_input_sco(sc
->sc_unit
, m
))
1337 sc
->sc_stats
.err_rx
++;
1339 sc
->sc_stats
.sco_rx
++;
1343 aprint_error_dev(sc
->sc_dev
,
1344 "received unreliable packet with not support channel %d\n",
1352 bcsp_tx_unreliable_pkt(struct bcsp_softc
*sc
, struct mbuf
*m
, u_int protocol_id
)
1359 DPRINTFN(1, ("%s: dgq transmit: protocol_id=%d,",
1360 device_xname(sc
->sc_dev
), protocol_id
));
1362 for (pldlen
= 0, _m
= m
; _m
!= NULL
; _m
= m
->m_next
) {
1365 pldlen
+= _m
->m_len
;
1367 DPRINTFN(1, (" pldlen=%d\n", pldlen
));
1370 if (protocol_id
== BCSP_IDENT_ACKPKT
|| protocol_id
> 15)
1373 M_PREPEND(m
, sizeof(bcsp_hdr_t
), M_DONTWAIT
);
1375 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1378 KASSERT(m
->m_len
>= sizeof(bcsp_hdr_t
));
1380 hdrp
= mtod(m
, bcsp_hdr_t
*);
1381 memset(hdrp
, 0, sizeof(bcsp_hdr_t
));
1382 hdrp
->ident
= protocol_id
;
1385 MBUFQ_ENQUEUE(&sc
->sc_dgq
, m
);
1387 sc
->sc_transmit_callback
= bcsp_unreliabletx_callback
;
1390 if (bcsp_debug
== 2)
1391 bcsp_packet_print(m
);
1394 bcsp_mux_transmit(sc
);
1401 bcsp_rx_unreliable_pkt(struct bcsp_softc
*sc
, struct mbuf
*m
, u_int protocol_id
)
1409 bcsp_unreliabletx_callback(struct bcsp_softc
*sc
, struct mbuf
*m
)
1412 if (M_GETCTX(m
, void *) == NULL
)
1414 else if (!hci_complete_sco(sc
->sc_unit
, m
))
1415 sc
->sc_stats
.err_tx
++;
1420 * BlueCore Link Establishment Protocol functions
1422 static const uint8_t sync
[] = BCSP_LE_SYNC
;
1423 static const uint8_t syncresp
[] = BCSP_LE_SYNCRESP
;
1424 static const uint8_t conf
[] = BCSP_LE_CONF
;
1425 static const uint8_t confresp
[] = BCSP_LE_CONFRESP
;
1428 bcsp_start_le(struct bcsp_softc
*sc
)
1431 DPRINTF(("%s: start link-establish\n", device_xname(sc
->sc_dev
)));
1433 bcsp_set_choke(sc
, true);
1435 if (!sc
->sc_le_muzzled
) {
1438 m
= m_gethdr(M_WAIT
, MT_DATA
);
1439 m
->m_pkthdr
.len
= m
->m_len
= 0;
1440 m_copyback(m
, 0, sizeof(sync
), sync
);
1441 if (!bcsp_tx_unreliable_pkt(sc
, m
, BCSP_CHANNEL_LE
)) {
1442 aprint_error_dev(sc
->sc_dev
,
1443 "le-packet transmit failed\n");
1447 callout_schedule(&sc
->sc_le_timer
, BCSP_LE_TSHY_TIMEOUT
);
1449 sc
->sc_le_state
= le_state_shy
;
1454 bcsp_terminate_le(struct bcsp_softc
*sc
)
1458 /* terminate link-establishment */
1459 callout_stop(&sc
->sc_le_timer
);
1460 bcsp_set_choke(sc
, true);
1461 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1463 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1465 /* length of le packets is 4 */
1466 m
->m_pkthdr
.len
= m
->m_len
= 0;
1467 m_copyback(m
, 0, sizeof(sync
), sync
);
1468 if (!bcsp_tx_unreliable_pkt(sc
, m
, BCSP_CHANNEL_LE
))
1469 aprint_error_dev(sc
->sc_dev
,
1470 "link-establishment terminations failed\n");
1475 bcsp_input_le(struct bcsp_softc
*sc
, struct mbuf
*m
)
1479 const uint8_t *rplypkt
;
1482 const uint8_t *datap
;
1485 { "sync-resp", syncresp
},
1487 { "conf-resp", confresp
},
1492 DPRINTFN(0, ("%s: le input: state %d, muzzled %d\n",
1493 device_xname(sc
->sc_dev
), sc
->sc_le_state
, sc
->sc_le_muzzled
));
1495 if (bcsp_debug
== 1)
1496 bcsp_packet_print(m
);
1499 rcvpkt
= mtod(m
, uint32_t *);
1502 /* length of le packets is 4 */
1503 if (m
->m_len
== sizeof(uint32_t))
1504 for (i
= 0; pkt
[i
].type
!= NULL
; i
++)
1505 if (*(const uint32_t *)pkt
[i
].datap
== *rcvpkt
)
1507 if (m
->m_len
!= sizeof(uint32_t) || pkt
[i
].type
== NULL
) {
1508 aprint_error_dev(sc
->sc_dev
, "received unknown packet\n");
1514 switch (sc
->sc_le_state
) {
1516 if (*rcvpkt
== *(const uint32_t *)sync
) {
1517 sc
->sc_le_muzzled
= false;
1519 } else if (*rcvpkt
== *(const uint32_t *)syncresp
) {
1520 DPRINTF(("%s: state change to curious\n",
1521 device_xname(sc
->sc_dev
)));
1524 callout_schedule(&sc
->sc_le_timer
,
1525 BCSP_LE_TCONF_TIMEOUT
);
1526 sc
->sc_le_state
= le_state_curious
;
1528 aprint_error_dev(sc
->sc_dev
,
1529 "received an unknown packet at shy\n");
1532 case le_state_curious
:
1533 if (*rcvpkt
== *(const uint32_t *)sync
)
1535 else if (*rcvpkt
== *(const uint32_t *)conf
)
1537 else if (*rcvpkt
== *(const uint32_t *)confresp
) {
1538 DPRINTF(("%s: state change to garrulous:\n",
1539 device_xname(sc
->sc_dev
)));
1541 bcsp_set_choke(sc
, false);
1542 callout_stop(&sc
->sc_le_timer
);
1543 sc
->sc_le_state
= le_state_garrulous
;
1545 aprint_error_dev(sc
->sc_dev
,
1546 "received unknown packet at curious\n");
1549 case le_state_garrulous
:
1550 if (*rcvpkt
== *(const uint32_t *)conf
)
1552 else if (*rcvpkt
== *(const uint32_t *)sync
) {
1554 aprint_error_dev(sc
->sc_dev
,
1555 "received sync! peer to reset?\n");
1557 bcsp_sequencing_reset(sc
);
1559 sc
->sc_le_state
= le_state_shy
;
1561 aprint_error_dev(sc
->sc_dev
,
1562 "received unknown packet at garrulous\n");
1568 if (rplypkt
!= NULL
) {
1569 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1571 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1573 /* length of le packets is 4 */
1574 m
->m_pkthdr
.len
= m
->m_len
= 0;
1575 m_copyback(m
, 0, 4, rplypkt
);
1576 if (!bcsp_tx_unreliable_pkt(sc
, m
, BCSP_CHANNEL_LE
))
1577 aprint_error_dev(sc
->sc_dev
,
1578 "le-packet transmit failed\n");
1584 bcsp_le_timeout(void *arg
)
1586 struct bcsp_softc
*sc
= arg
;
1589 const uint8_t *sndpkt
= NULL
;
1591 DPRINTFN(0, ("%s: le timeout: state %d, muzzled %d\n",
1592 device_xname(sc
->sc_dev
), sc
->sc_le_state
, sc
->sc_le_muzzled
));
1594 switch (sc
->sc_le_state
) {
1596 if (!sc
->sc_le_muzzled
)
1598 timeout
= BCSP_LE_TSHY_TIMEOUT
;
1601 case le_state_curious
:
1603 timeout
= BCSP_LE_TCONF_TIMEOUT
;
1607 aprint_error_dev(sc
->sc_dev
,
1608 "timeout happen at unknown state %d\n", sc
->sc_le_state
);
1612 if (sndpkt
!= NULL
) {
1613 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1615 aprint_error_dev(sc
->sc_dev
, "out of memory\n");
1617 /* length of le packets is 4 */
1618 m
->m_pkthdr
.len
= m
->m_len
= 0;
1619 m_copyback(m
, 0, 4, sndpkt
);
1620 if (!bcsp_tx_unreliable_pkt(sc
, m
, BCSP_CHANNEL_LE
))
1621 aprint_error_dev(sc
->sc_dev
,
1622 "le-packet transmit failed\n");
1626 callout_schedule(&sc
->sc_le_timer
, timeout
);
1631 * BlueCore Serial Protocol functions.
1634 bcsp_enable(device_t self
)
1636 struct bcsp_softc
*sc
= device_private(self
);
1639 if (sc
->sc_flags
& BCSP_ENABLED
)
1644 sc
->sc_flags
|= BCSP_ENABLED
;
1645 sc
->sc_flags
&= ~BCSP_XMIT
;
1653 bcsp_disable(device_t self
)
1655 struct bcsp_softc
*sc
= device_private(self
);
1658 if ((sc
->sc_flags
& BCSP_ENABLED
) == 0)
1664 m_freem(sc
->sc_rxp
);
1669 m_freem(sc
->sc_txp
);
1673 MBUFQ_DRAIN(&sc
->sc_cmdq
);
1674 MBUFQ_DRAIN(&sc
->sc_aclq
);
1675 MBUFQ_DRAIN(&sc
->sc_scoq
);
1677 sc
->sc_flags
&= ~BCSP_ENABLED
;
1682 bcsp_start(struct bcsp_softc
*sc
)
1686 KASSERT((sc
->sc_flags
& BCSP_XMIT
) == 0);
1687 KASSERT(sc
->sc_txp
== NULL
);
1689 if (MBUFQ_FIRST(&sc
->sc_aclq
)) {
1690 MBUFQ_DEQUEUE(&sc
->sc_aclq
, m
);
1691 sc
->sc_stats
.acl_tx
++;
1692 sc
->sc_flags
|= BCSP_XMIT
;
1693 bcsp_tx_reliable_pkt(sc
, m
, BCSP_CHANNEL_HCI_ACL
);
1696 if (MBUFQ_FIRST(&sc
->sc_cmdq
)) {
1697 MBUFQ_DEQUEUE(&sc
->sc_cmdq
, m
);
1698 sc
->sc_stats
.cmd_tx
++;
1699 sc
->sc_flags
|= BCSP_XMIT
;
1700 bcsp_tx_reliable_pkt(sc
, m
, BCSP_CHANNEL_HCI_CMDEVT
);
1703 if (MBUFQ_FIRST(&sc
->sc_scoq
)) {
1704 MBUFQ_DEQUEUE(&sc
->sc_scoq
, m
);
1705 sc
->sc_stats
.sco_tx
++;
1706 /* XXXX: We can transmit with reliable */
1707 sc
->sc_flags
|= BCSP_XMIT
;
1708 bcsp_tx_unreliable_pkt(sc
, m
, BCSP_CHANNEL_HCI_SCO
);
1715 bcsp_output_cmd(device_t self
, struct mbuf
*m
)
1717 struct bcsp_softc
*sc
= device_private(self
);
1720 KASSERT(sc
->sc_flags
& BCSP_ENABLED
);
1722 m_adj(m
, sizeof(uint8_t));
1726 MBUFQ_ENQUEUE(&sc
->sc_cmdq
, m
);
1727 if ((sc
->sc_flags
& BCSP_XMIT
) == 0)
1734 bcsp_output_acl(device_t self
, struct mbuf
*m
)
1736 struct bcsp_softc
*sc
= device_private(self
);
1739 KASSERT(sc
->sc_flags
& BCSP_ENABLED
);
1741 m_adj(m
, sizeof(uint8_t));
1745 MBUFQ_ENQUEUE(&sc
->sc_aclq
, m
);
1746 if ((sc
->sc_flags
& BCSP_XMIT
) == 0)
1753 bcsp_output_sco(device_t self
, struct mbuf
*m
)
1755 struct bcsp_softc
*sc
= device_private(self
);
1758 KASSERT(sc
->sc_flags
& BCSP_ENABLED
);
1760 m_adj(m
, sizeof(uint8_t));
1763 MBUFQ_ENQUEUE(&sc
->sc_scoq
, m
);
1764 if ((sc
->sc_flags
& BCSP_XMIT
) == 0)
1771 bcsp_stats(device_t self
, struct bt_stats
*dest
, int flush
)
1773 struct bcsp_softc
*sc
= device_private(self
);
1777 memcpy(dest
, &sc
->sc_stats
, sizeof(struct bt_stats
));
1780 memset(&sc
->sc_stats
, 0, sizeof(struct bt_stats
));
1788 bcsp_packet_print(struct mbuf
*m
)
1793 for ( ; m
!= NULL
; m
= m
->m_next
) {
1794 p
= mtod(m
, uint8_t *);
1795 for (i
= 0; i
< m
->m_len
; i
++) {
1798 printf(" %02x", *(p
+ i
));