bcsp.c revision 1.7 1 1.7 plunky /* $NetBSD: bcsp.c,v 1.7 2007/11/11 12:54:23 plunky Exp $ */
2 1.1 kiyohara /*
3 1.1 kiyohara * Copyright (c) 2007 KIYOHARA Takashi
4 1.1 kiyohara * All rights reserved.
5 1.1 kiyohara *
6 1.1 kiyohara * Redistribution and use in source and binary forms, with or without
7 1.1 kiyohara * modification, are permitted provided that the following conditions
8 1.1 kiyohara * are met:
9 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright
10 1.1 kiyohara * notice, this list of conditions and the following disclaimer.
11 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the
13 1.1 kiyohara * documentation and/or other materials provided with the distribution.
14 1.1 kiyohara *
15 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 1.1 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 1.1 kiyohara * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 1.1 kiyohara * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 1.1 kiyohara * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 1.1 kiyohara * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 1.1 kiyohara * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.1 kiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 1.1 kiyohara * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 1.1 kiyohara * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 1.1 kiyohara * POSSIBILITY OF SUCH DAMAGE.
26 1.1 kiyohara */
27 1.1 kiyohara
28 1.1 kiyohara #include <sys/cdefs.h>
29 1.7 plunky __KERNEL_RCSID(0, "$NetBSD: bcsp.c,v 1.7 2007/11/11 12:54:23 plunky Exp $");
30 1.1 kiyohara
31 1.1 kiyohara #include <sys/types.h>
32 1.1 kiyohara #include <sys/param.h>
33 1.1 kiyohara #include <sys/callout.h>
34 1.1 kiyohara #include <sys/conf.h>
35 1.1 kiyohara #include <sys/device.h>
36 1.1 kiyohara #include <sys/errno.h>
37 1.1 kiyohara #include <sys/fcntl.h>
38 1.1 kiyohara #include <sys/kauth.h>
39 1.1 kiyohara #include <sys/kernel.h>
40 1.1 kiyohara #include <sys/malloc.h>
41 1.1 kiyohara #include <sys/mbuf.h>
42 1.1 kiyohara #include <sys/proc.h>
43 1.1 kiyohara #include <sys/sysctl.h>
44 1.1 kiyohara #include <sys/syslimits.h>
45 1.1 kiyohara #include <sys/systm.h>
46 1.1 kiyohara #include <sys/tty.h>
47 1.1 kiyohara
48 1.1 kiyohara #include <netbt/bluetooth.h>
49 1.1 kiyohara #include <netbt/hci.h>
50 1.1 kiyohara
51 1.1 kiyohara #include <dev/bluetooth/bcsp.h>
52 1.1 kiyohara #include <dev/bluetooth/btuart.h>
53 1.1 kiyohara
54 1.1 kiyohara #include "ioconf.h"
55 1.1 kiyohara
56 1.1 kiyohara #ifdef BCSP_DEBUG
57 1.3 kiyohara #ifdef DPRINTF
58 1.1 kiyohara #undef DPRINTF
59 1.3 kiyohara #endif
60 1.3 kiyohara #ifdef DPRINTFN
61 1.1 kiyohara #undef DPRINTFN
62 1.3 kiyohara #endif
63 1.1 kiyohara
64 1.1 kiyohara #define DPRINTF(x) printf x
65 1.1 kiyohara #define DPRINTFN(n, x) do { if (bcsp_debug > (n)) printf x; } while (0)
66 1.1 kiyohara int bcsp_debug = 3;
67 1.1 kiyohara #else
68 1.1 kiyohara #undef DPRINTF
69 1.1 kiyohara #undef DPRINTFN
70 1.1 kiyohara
71 1.1 kiyohara #define DPRINTF(x)
72 1.1 kiyohara #define DPRINTFN(n, x)
73 1.1 kiyohara #endif
74 1.1 kiyohara
75 1.1 kiyohara struct bcsp_softc {
76 1.4 plunky device_t sc_dev;
77 1.1 kiyohara
78 1.1 kiyohara struct tty *sc_tp;
79 1.1 kiyohara struct hci_unit sc_unit; /* Bluetooth HCI Unit */
80 1.1 kiyohara
81 1.1 kiyohara int sc_baud;
82 1.1 kiyohara int sc_init_baud;
83 1.1 kiyohara
84 1.1 kiyohara /* variables of SLIP Layer */
85 1.1 kiyohara struct mbuf *sc_txp; /* outgoing packet */
86 1.1 kiyohara struct mbuf *sc_rxp; /* incoming packet */
87 1.1 kiyohara int sc_slip_txrsv; /* reserved byte data */
88 1.1 kiyohara int sc_slip_rxexp; /* expected byte data */
89 1.1 kiyohara void (*sc_transmit_callback)(struct bcsp_softc *, struct mbuf *);
90 1.1 kiyohara
91 1.1 kiyohara /* variables of Packet Integrity Layer */
92 1.1 kiyohara int sc_pi_txcrc; /* use CRC, if true */
93 1.1 kiyohara
94 1.1 kiyohara /* variables of MUX Layer */
95 1.1 kiyohara bool sc_mux_send_ack; /* flag for send_ack */
96 1.1 kiyohara bool sc_mux_choke; /* Choke signal */
97 1.1 kiyohara struct timeval sc_mux_lastrx; /* Last Rx Pkt Time */
98 1.1 kiyohara
99 1.1 kiyohara /* variables of Sequencing Layer */
100 1.1 kiyohara MBUFQ_HEAD() sc_seqq; /* Sequencing Layer queue */
101 1.1 kiyohara MBUFQ_HEAD() sc_seq_retryq; /* retry queue */
102 1.1 kiyohara uint32_t sc_seq_txseq;
103 1.1 kiyohara uint32_t sc_seq_txack;
104 1.1 kiyohara uint32_t sc_seq_expected_rxseq;
105 1.1 kiyohara uint32_t sc_seq_winspace;
106 1.1 kiyohara uint32_t sc_seq_retries;
107 1.1 kiyohara callout_t sc_seq_timer;
108 1.1 kiyohara uint32_t sc_seq_timeout;
109 1.1 kiyohara uint32_t sc_seq_winsize;
110 1.1 kiyohara uint32_t sc_seq_retry_limit;
111 1.1 kiyohara
112 1.1 kiyohara /* variables of Datagram Queue Layer */
113 1.1 kiyohara MBUFQ_HEAD() sc_dgq; /* Datagram Queue Layer queue */
114 1.1 kiyohara
115 1.1 kiyohara /* variables of BCSP Link Establishment Protocol */
116 1.1 kiyohara bool sc_le_muzzled;
117 1.1 kiyohara bcsp_le_state_t sc_le_state;
118 1.1 kiyohara callout_t sc_le_timer;
119 1.1 kiyohara
120 1.1 kiyohara struct sysctllog *sc_log; /* sysctl log */
121 1.1 kiyohara };
122 1.1 kiyohara
123 1.1 kiyohara void bcspattach(int);
124 1.1 kiyohara static int bcsp_match(struct device *, struct cfdata *, void *);
125 1.1 kiyohara static void bcsp_attach(struct device *, struct device *, void *);
126 1.1 kiyohara static int bcsp_detach(struct device *, int);
127 1.1 kiyohara
128 1.1 kiyohara /* tty functions */
129 1.1 kiyohara static int bcspopen(dev_t, struct tty *);
130 1.1 kiyohara static int bcspclose(struct tty *, int);
131 1.1 kiyohara static int bcspioctl(struct tty *, u_long, void *, int, struct lwp *);
132 1.1 kiyohara
133 1.1 kiyohara static int bcsp_slip_transmit(struct tty *);
134 1.1 kiyohara static int bcsp_slip_receive(int, struct tty *);
135 1.1 kiyohara
136 1.1 kiyohara static void bcsp_pktintegrity_transmit(struct bcsp_softc *);
137 1.1 kiyohara static void bcsp_pktintegrity_receive(struct bcsp_softc *, struct mbuf *);
138 1.1 kiyohara static void bcsp_crc_update(uint16_t *, uint8_t);
139 1.1 kiyohara static uint16_t bcsp_crc_reverse(uint16_t);
140 1.1 kiyohara
141 1.1 kiyohara static void bcsp_mux_transmit(struct bcsp_softc *sc);
142 1.1 kiyohara static void bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m);
143 1.1 kiyohara static __inline void bcsp_send_ack_command(struct bcsp_softc *sc);
144 1.1 kiyohara static __inline struct mbuf *bcsp_create_ackpkt(void);
145 1.1 kiyohara static __inline void bcsp_set_choke(struct bcsp_softc *, bool);
146 1.1 kiyohara
147 1.1 kiyohara static void bcsp_sequencing_receive(struct bcsp_softc *, struct mbuf *);
148 1.1 kiyohara static bool bcsp_tx_reliable_pkt(struct bcsp_softc *, struct mbuf *, u_int);
149 1.1 kiyohara static __inline u_int bcsp_get_txack(struct bcsp_softc *);
150 1.1 kiyohara static void bcsp_signal_rxack(struct bcsp_softc *, uint32_t);
151 1.1 kiyohara static void bcsp_reliabletx_callback(struct bcsp_softc *, struct mbuf *);
152 1.1 kiyohara static void bcsp_timer_timeout(void *);
153 1.1 kiyohara static void bcsp_sequencing_reset(struct bcsp_softc *);
154 1.1 kiyohara
155 1.1 kiyohara static void bcsp_datagramq_receive(struct bcsp_softc *, struct mbuf *);
156 1.1 kiyohara static bool bcsp_tx_unreliable_pkt(struct bcsp_softc *, struct mbuf *, u_int);
157 1.1 kiyohara static void bcsp_unreliabletx_callback(struct bcsp_softc *, struct mbuf *);
158 1.1 kiyohara
159 1.1 kiyohara static int bcsp_start_le(struct hci_unit *);
160 1.1 kiyohara static void bcsp_terminate_le(struct hci_unit *);
161 1.1 kiyohara static void bcsp_input_le(struct hci_unit *, struct mbuf *);
162 1.1 kiyohara static void bcsp_le_timeout(void *);
163 1.1 kiyohara
164 1.1 kiyohara /* bluetooth hci functions */
165 1.7 plunky static int bcsp_enable(device_t);
166 1.7 plunky static void bcsp_disable(device_t);
167 1.7 plunky static void bcsp_start(device_t);
168 1.1 kiyohara
169 1.1 kiyohara #ifdef BCSP_DEBUG
170 1.1 kiyohara static void bcsp_packet_print(struct mbuf *m);
171 1.1 kiyohara #endif
172 1.1 kiyohara
173 1.1 kiyohara
174 1.1 kiyohara /*
175 1.1 kiyohara * It doesn't need to be exported, as only bcspattach() uses it,
176 1.1 kiyohara * but there's no "official" way to make it static.
177 1.1 kiyohara */
178 1.4 plunky CFATTACH_DECL_NEW(bcsp, sizeof(struct bcsp_softc),
179 1.1 kiyohara bcsp_match, bcsp_attach, bcsp_detach, NULL);
180 1.1 kiyohara
181 1.1 kiyohara static struct linesw bcsp_disc = {
182 1.1 kiyohara .l_name = "bcsp",
183 1.1 kiyohara .l_open = bcspopen,
184 1.1 kiyohara .l_close = bcspclose,
185 1.1 kiyohara .l_read = ttyerrio,
186 1.1 kiyohara .l_write = ttyerrio,
187 1.1 kiyohara .l_ioctl = bcspioctl,
188 1.1 kiyohara .l_rint = bcsp_slip_receive,
189 1.1 kiyohara .l_start = bcsp_slip_transmit,
190 1.1 kiyohara .l_modem = ttymodem,
191 1.1 kiyohara .l_poll = ttyerrpoll
192 1.1 kiyohara };
193 1.1 kiyohara
194 1.1 kiyohara
195 1.1 kiyohara /* ARGSUSED */
196 1.1 kiyohara void
197 1.1 kiyohara bcspattach(int num __unused)
198 1.1 kiyohara {
199 1.1 kiyohara int error;
200 1.1 kiyohara
201 1.1 kiyohara error = ttyldisc_attach(&bcsp_disc);
202 1.1 kiyohara if (error) {
203 1.1 kiyohara aprint_error("%s: unable to register line discipline, "
204 1.1 kiyohara "error = %d\n", bcsp_cd.cd_name, error);
205 1.1 kiyohara return;
206 1.1 kiyohara }
207 1.1 kiyohara
208 1.1 kiyohara error = config_cfattach_attach(bcsp_cd.cd_name, &bcsp_ca);
209 1.1 kiyohara if (error) {
210 1.1 kiyohara aprint_error("%s: unable to register cfattach, error = %d\n",
211 1.1 kiyohara bcsp_cd.cd_name, error);
212 1.1 kiyohara config_cfdriver_detach(&bcsp_cd);
213 1.1 kiyohara (void) ttyldisc_detach(&bcsp_disc);
214 1.1 kiyohara }
215 1.1 kiyohara }
216 1.1 kiyohara
217 1.1 kiyohara /*
218 1.1 kiyohara * Autoconf match routine.
219 1.1 kiyohara *
220 1.1 kiyohara * XXX: unused: config_attach_pseudo(9) does not call ca_match.
221 1.1 kiyohara */
222 1.1 kiyohara /* ARGSUSED */
223 1.1 kiyohara static int
224 1.1 kiyohara bcsp_match(struct device *self __unused, struct cfdata *cfdata __unused,
225 1.1 kiyohara void *arg __unused)
226 1.1 kiyohara {
227 1.1 kiyohara
228 1.1 kiyohara /* pseudo-device; always present */
229 1.1 kiyohara return 1;
230 1.1 kiyohara }
231 1.1 kiyohara
232 1.1 kiyohara /*
233 1.1 kiyohara * Autoconf attach routine. Called by config_attach_pseudo(9) when we
234 1.1 kiyohara * open the line discipline.
235 1.1 kiyohara */
236 1.1 kiyohara /* ARGSUSED */
237 1.1 kiyohara static void
238 1.1 kiyohara bcsp_attach(struct device *parent __unused, struct device *self,
239 1.1 kiyohara void *aux __unused)
240 1.1 kiyohara {
241 1.1 kiyohara struct bcsp_softc *sc = device_private(self);
242 1.1 kiyohara const struct sysctlnode *node;
243 1.1 kiyohara int rc, bcsp_node_num;
244 1.1 kiyohara
245 1.1 kiyohara aprint_normal("\n");
246 1.1 kiyohara aprint_naive("\n");
247 1.1 kiyohara
248 1.4 plunky sc->sc_dev = self;
249 1.1 kiyohara callout_init(&sc->sc_seq_timer, 0);
250 1.1 kiyohara callout_setfunc(&sc->sc_seq_timer, bcsp_timer_timeout, sc);
251 1.1 kiyohara callout_init(&sc->sc_le_timer, 0);
252 1.1 kiyohara callout_setfunc(&sc->sc_le_timer, bcsp_le_timeout, sc);
253 1.1 kiyohara sc->sc_seq_timeout = BCSP_SEQ_TX_TIMEOUT;
254 1.1 kiyohara sc->sc_seq_winsize = BCSP_SEQ_TX_WINSIZE;
255 1.1 kiyohara sc->sc_seq_retry_limit = BCSP_SEQ_TX_RETRY_LIMIT;
256 1.1 kiyohara MBUFQ_INIT(&sc->sc_seqq);
257 1.1 kiyohara MBUFQ_INIT(&sc->sc_seq_retryq);
258 1.1 kiyohara MBUFQ_INIT(&sc->sc_dgq);
259 1.1 kiyohara
260 1.1 kiyohara /* Attach Bluetooth unit */
261 1.7 plunky sc->sc_unit.hci_dev = self;
262 1.1 kiyohara sc->sc_unit.hci_enable = bcsp_enable;
263 1.1 kiyohara sc->sc_unit.hci_disable = bcsp_disable;
264 1.1 kiyohara sc->sc_unit.hci_start_cmd = bcsp_start;
265 1.1 kiyohara sc->sc_unit.hci_start_acl = bcsp_start;
266 1.1 kiyohara sc->sc_unit.hci_start_sco = bcsp_start;
267 1.1 kiyohara sc->sc_unit.hci_ipl = makeiplcookie(IPL_TTY);
268 1.1 kiyohara hci_attach(&sc->sc_unit);
269 1.1 kiyohara
270 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, NULL,
271 1.1 kiyohara CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
272 1.1 kiyohara NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
273 1.1 kiyohara goto err;
274 1.1 kiyohara }
275 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
276 1.4 plunky 0, CTLTYPE_NODE, device_xname(self),
277 1.1 kiyohara SYSCTL_DESCR("bcsp controls"),
278 1.1 kiyohara NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
279 1.1 kiyohara goto err;
280 1.1 kiyohara }
281 1.1 kiyohara bcsp_node_num = node->sysctl_num;
282 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
283 1.1 kiyohara CTLFLAG_READWRITE, CTLTYPE_INT,
284 1.1 kiyohara "muzzled", SYSCTL_DESCR("muzzled for Link-establishment Layer"),
285 1.1 kiyohara NULL, 0, &sc->sc_le_muzzled,
286 1.1 kiyohara 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
287 1.1 kiyohara goto err;
288 1.1 kiyohara }
289 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
290 1.1 kiyohara CTLFLAG_READWRITE, CTLTYPE_INT,
291 1.1 kiyohara "txcrc", SYSCTL_DESCR("txcrc for Packet Integrity Layer"),
292 1.1 kiyohara NULL, 0, &sc->sc_pi_txcrc,
293 1.1 kiyohara 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
294 1.1 kiyohara goto err;
295 1.1 kiyohara }
296 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
297 1.1 kiyohara CTLFLAG_READWRITE, CTLTYPE_INT,
298 1.1 kiyohara "timeout", SYSCTL_DESCR("timeout for Sequencing Layer"),
299 1.1 kiyohara NULL, 0, &sc->sc_seq_timeout,
300 1.1 kiyohara 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
301 1.1 kiyohara goto err;
302 1.1 kiyohara }
303 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
304 1.1 kiyohara CTLFLAG_READWRITE, CTLTYPE_INT,
305 1.1 kiyohara "winsize", SYSCTL_DESCR("winsize for Sequencing Layer"),
306 1.1 kiyohara NULL, 0, &sc->sc_seq_winsize,
307 1.1 kiyohara 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
308 1.1 kiyohara goto err;
309 1.1 kiyohara }
310 1.1 kiyohara if ((rc = sysctl_createv(&sc->sc_log, 0, NULL, &node,
311 1.1 kiyohara CTLFLAG_READWRITE, CTLTYPE_INT,
312 1.1 kiyohara "retry_limit", SYSCTL_DESCR("retry limit for Sequencing Layer"),
313 1.1 kiyohara NULL, 0, &sc->sc_seq_retry_limit,
314 1.1 kiyohara 0, CTL_HW, bcsp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
315 1.1 kiyohara goto err;
316 1.1 kiyohara }
317 1.1 kiyohara return;
318 1.1 kiyohara
319 1.1 kiyohara err:
320 1.1 kiyohara printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
321 1.1 kiyohara }
322 1.1 kiyohara
323 1.1 kiyohara /*
324 1.1 kiyohara * Autoconf detach routine. Called when we close the line discipline.
325 1.1 kiyohara */
326 1.1 kiyohara /* ARGSUSED */
327 1.1 kiyohara static int
328 1.1 kiyohara bcsp_detach(struct device *self, int flags __unused)
329 1.1 kiyohara {
330 1.1 kiyohara struct bcsp_softc *sc = device_private(self);
331 1.1 kiyohara
332 1.1 kiyohara hci_detach(&sc->sc_unit);
333 1.1 kiyohara
334 1.5 plunky callout_stop(&sc->sc_seq_timer);
335 1.5 plunky callout_destroy(&sc->sc_seq_timer);
336 1.5 plunky
337 1.5 plunky callout_stop(&sc->sc_le_timer);
338 1.5 plunky callout_destroy(&sc->sc_le_timer);
339 1.5 plunky
340 1.1 kiyohara return 0;
341 1.1 kiyohara }
342 1.1 kiyohara
343 1.1 kiyohara
344 1.1 kiyohara /*
345 1.1 kiyohara * Line discipline functions.
346 1.1 kiyohara */
347 1.1 kiyohara /* ARGSUSED */
348 1.1 kiyohara static int
349 1.1 kiyohara bcspopen(dev_t device __unused, struct tty *tp)
350 1.1 kiyohara {
351 1.1 kiyohara struct bcsp_softc *sc;
352 1.1 kiyohara struct cfdata *cfdata;
353 1.1 kiyohara struct lwp *l = curlwp; /* XXX */
354 1.1 kiyohara int error, unit, s;
355 1.1 kiyohara static char name[] = "bcsp";
356 1.1 kiyohara
357 1.1 kiyohara if ((error = kauth_authorize_device_tty(l->l_cred,
358 1.1 kiyohara KAUTH_GENERIC_ISSUSER, tp)) != 0)
359 1.1 kiyohara return error;
360 1.1 kiyohara
361 1.1 kiyohara s = spltty();
362 1.1 kiyohara
363 1.1 kiyohara if (tp->t_linesw == &bcsp_disc) {
364 1.4 plunky sc = tp->t_sc;
365 1.1 kiyohara if (sc != NULL) {
366 1.1 kiyohara splx(s);
367 1.1 kiyohara return EBUSY;
368 1.1 kiyohara }
369 1.1 kiyohara }
370 1.1 kiyohara
371 1.1 kiyohara KASSERT(tp->t_oproc != NULL);
372 1.1 kiyohara
373 1.1 kiyohara cfdata = malloc(sizeof(struct cfdata), M_DEVBUF, M_WAITOK);
374 1.1 kiyohara for (unit = 0; unit < bcsp_cd.cd_ndevs; unit++)
375 1.1 kiyohara if (bcsp_cd.cd_devs[unit] == NULL)
376 1.1 kiyohara break;
377 1.1 kiyohara cfdata->cf_name = name;
378 1.1 kiyohara cfdata->cf_atname = name;
379 1.1 kiyohara cfdata->cf_unit = unit;
380 1.1 kiyohara cfdata->cf_fstate = FSTATE_STAR;
381 1.1 kiyohara
382 1.1 kiyohara printf("%s%d at tty major %d minor %d",
383 1.1 kiyohara name, unit, major(tp->t_dev), minor(tp->t_dev));
384 1.1 kiyohara sc = (struct bcsp_softc *)config_attach_pseudo(cfdata);
385 1.1 kiyohara if (sc == NULL) {
386 1.1 kiyohara splx(s);
387 1.1 kiyohara return EIO;
388 1.1 kiyohara }
389 1.6 ad
390 1.6 ad mutex_spin_enter(&tty_lock);
391 1.1 kiyohara tp->t_sc = sc;
392 1.1 kiyohara sc->sc_tp = tp;
393 1.1 kiyohara ttyflush(tp, FREAD | FWRITE);
394 1.6 ad mutex_spin_exit(&tty_lock);
395 1.1 kiyohara
396 1.1 kiyohara splx(s);
397 1.1 kiyohara
398 1.1 kiyohara sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
399 1.1 kiyohara bcsp_sequencing_reset(sc);
400 1.1 kiyohara
401 1.1 kiyohara /* start link-establishment */
402 1.1 kiyohara bcsp_start_le(&sc->sc_unit);
403 1.1 kiyohara
404 1.1 kiyohara return 0;
405 1.1 kiyohara }
406 1.1 kiyohara
407 1.1 kiyohara /* ARGSUSED */
408 1.1 kiyohara static int
409 1.1 kiyohara bcspclose(struct tty *tp, int flag __unused)
410 1.1 kiyohara {
411 1.4 plunky struct bcsp_softc *sc = tp->t_sc;
412 1.1 kiyohara struct cfdata *cfdata;
413 1.1 kiyohara int s;
414 1.1 kiyohara
415 1.1 kiyohara /* terminate link-establishment */
416 1.1 kiyohara bcsp_terminate_le(&sc->sc_unit);
417 1.1 kiyohara
418 1.1 kiyohara s = spltty();
419 1.1 kiyohara
420 1.1 kiyohara MBUFQ_DRAIN(&sc->sc_dgq);
421 1.1 kiyohara bcsp_sequencing_reset(sc);
422 1.1 kiyohara
423 1.6 ad mutex_spin_enter(&tty_lock);
424 1.1 kiyohara ttyflush(tp, FREAD | FWRITE);
425 1.6 ad mutex_spin_exit(&tty_lock); /* XXX */
426 1.1 kiyohara ttyldisc_release(tp->t_linesw);
427 1.1 kiyohara tp->t_linesw = ttyldisc_default();
428 1.1 kiyohara if (sc != NULL) {
429 1.1 kiyohara tp->t_sc = NULL;
430 1.1 kiyohara if (sc->sc_tp == tp) {
431 1.4 plunky cfdata = device_cfdata(sc->sc_dev);
432 1.4 plunky config_detach(sc->sc_dev, 0);
433 1.1 kiyohara free(cfdata, M_DEVBUF);
434 1.1 kiyohara }
435 1.1 kiyohara
436 1.1 kiyohara }
437 1.1 kiyohara splx(s);
438 1.1 kiyohara return 0;
439 1.1 kiyohara }
440 1.1 kiyohara
441 1.1 kiyohara /* ARGSUSED */
442 1.1 kiyohara static int
443 1.1 kiyohara bcspioctl(struct tty *tp, u_long cmd, void *data, int flag __unused,
444 1.1 kiyohara struct lwp *l __unused)
445 1.1 kiyohara {
446 1.4 plunky struct bcsp_softc *sc = tp->t_sc;
447 1.1 kiyohara int error;
448 1.1 kiyohara
449 1.1 kiyohara if (sc == NULL || tp != sc->sc_tp)
450 1.1 kiyohara return EPASSTHROUGH;
451 1.1 kiyohara
452 1.1 kiyohara error = 0;
453 1.1 kiyohara switch (cmd) {
454 1.1 kiyohara default:
455 1.1 kiyohara error = EPASSTHROUGH;
456 1.1 kiyohara break;
457 1.1 kiyohara }
458 1.1 kiyohara
459 1.1 kiyohara return error;
460 1.1 kiyohara }
461 1.1 kiyohara
462 1.1 kiyohara
463 1.1 kiyohara /*
464 1.1 kiyohara * UART Driver Layer is supported by com-driver.
465 1.1 kiyohara */
466 1.1 kiyohara
467 1.1 kiyohara /*
468 1.1 kiyohara * BCSP SLIP Layer functions:
469 1.1 kiyohara * Supports to transmit/receive a byte stream.
470 1.1 kiyohara * SLIP protocol described in Internet standard RFC 1055.
471 1.1 kiyohara */
472 1.1 kiyohara static int
473 1.1 kiyohara bcsp_slip_transmit(struct tty *tp)
474 1.1 kiyohara {
475 1.4 plunky struct bcsp_softc *sc = tp->t_sc;
476 1.1 kiyohara struct mbuf *m;
477 1.1 kiyohara int count, rlen;
478 1.1 kiyohara uint8_t *rptr;
479 1.1 kiyohara
480 1.1 kiyohara m = sc->sc_txp;
481 1.1 kiyohara if (m == NULL) {
482 1.1 kiyohara sc->sc_unit.hci_flags &= ~BTF_XMIT;
483 1.1 kiyohara bcsp_mux_transmit(sc);
484 1.1 kiyohara return 0;
485 1.1 kiyohara }
486 1.1 kiyohara
487 1.1 kiyohara count = 0;
488 1.1 kiyohara rlen = 0;
489 1.1 kiyohara rptr = mtod(m, uint8_t *);
490 1.1 kiyohara
491 1.1 kiyohara if (sc->sc_slip_txrsv != 0) {
492 1.1 kiyohara #ifdef BCSP_DEBUG
493 1.1 kiyohara if (sc->sc_slip_txrsv == BCSP_SLIP_PKTSTART)
494 1.1 kiyohara DPRINTFN(4, ("%s: slip transmit start\n",
495 1.4 plunky device_xname(sc->sc_dev));
496 1.1 kiyohara else
497 1.1 kiyohara DPRINTFN(4, ("0x%02x ", sc->sc_slip_txrsv));
498 1.1 kiyohara #endif
499 1.1 kiyohara
500 1.1 kiyohara if (putc(sc->sc_slip_txrsv, &tp->t_outq) < 0)
501 1.1 kiyohara return 0;
502 1.1 kiyohara count++;
503 1.1 kiyohara
504 1.1 kiyohara if (sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_PKTEND ||
505 1.1 kiyohara sc->sc_slip_txrsv == BCSP_SLIP_ESCAPE_ESCAPE) {
506 1.1 kiyohara rlen++;
507 1.1 kiyohara rptr++;
508 1.1 kiyohara }
509 1.1 kiyohara sc->sc_slip_txrsv = 0;
510 1.1 kiyohara }
511 1.1 kiyohara
512 1.1 kiyohara for(;;) {
513 1.1 kiyohara if (rlen >= m->m_len) {
514 1.1 kiyohara m = m->m_next;
515 1.1 kiyohara if (m == NULL) {
516 1.1 kiyohara if (putc(BCSP_SLIP_PKTEND, &tp->t_outq) < 0)
517 1.1 kiyohara break;
518 1.1 kiyohara
519 1.1 kiyohara DPRINTFN(4, ("\n%s: slip transmit end\n",
520 1.7 plunky device_xname(sc->sc_dev)));
521 1.1 kiyohara
522 1.1 kiyohara m = sc->sc_txp;
523 1.1 kiyohara sc->sc_txp = NULL;
524 1.1 kiyohara sc->sc_slip_txrsv = BCSP_SLIP_PKTSTART;
525 1.1 kiyohara
526 1.1 kiyohara sc->sc_transmit_callback(sc, m);
527 1.1 kiyohara m = NULL;
528 1.1 kiyohara break;
529 1.1 kiyohara }
530 1.1 kiyohara
531 1.1 kiyohara rlen = 0;
532 1.1 kiyohara rptr = mtod(m, uint8_t *);
533 1.1 kiyohara continue;
534 1.1 kiyohara }
535 1.1 kiyohara
536 1.1 kiyohara if (*rptr == BCSP_SLIP_PKTEND) {
537 1.1 kiyohara if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
538 1.1 kiyohara break;
539 1.1 kiyohara count++;
540 1.1 kiyohara DPRINTFN(4, (" esc "));
541 1.1 kiyohara
542 1.1 kiyohara if (putc(BCSP_SLIP_ESCAPE_PKTEND, &tp->t_outq) < 0) {
543 1.1 kiyohara sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_PKTEND;
544 1.1 kiyohara break;
545 1.1 kiyohara }
546 1.1 kiyohara DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_PKTEND));
547 1.1 kiyohara } else if (*rptr == BCSP_SLIP_ESCAPE) {
548 1.1 kiyohara if (putc(BCSP_SLIP_ESCAPE, &tp->t_outq) < 0)
549 1.1 kiyohara break;
550 1.1 kiyohara count++;
551 1.1 kiyohara DPRINTFN(4, (" esc "));
552 1.1 kiyohara
553 1.1 kiyohara if (putc(BCSP_SLIP_ESCAPE_ESCAPE, &tp->t_outq) < 0) {
554 1.1 kiyohara sc->sc_slip_txrsv = BCSP_SLIP_ESCAPE_ESCAPE;
555 1.1 kiyohara break;
556 1.1 kiyohara }
557 1.1 kiyohara DPRINTFN(4, ("0x%02x ", BCSP_SLIP_ESCAPE_ESCAPE));
558 1.1 kiyohara } else {
559 1.1 kiyohara if (putc(*rptr++, &tp->t_outq) < 0)
560 1.1 kiyohara break;
561 1.1 kiyohara DPRINTFN(4, ("0x%02x ", *(rptr - 1)));
562 1.1 kiyohara }
563 1.1 kiyohara rlen++;
564 1.1 kiyohara count++;
565 1.1 kiyohara }
566 1.1 kiyohara if (m != NULL)
567 1.1 kiyohara m_adj(m, rlen);
568 1.1 kiyohara
569 1.1 kiyohara sc->sc_unit.hci_stats.byte_tx += count;
570 1.1 kiyohara
571 1.1 kiyohara if (tp->t_outq.c_cc != 0)
572 1.1 kiyohara (*tp->t_oproc)(tp);
573 1.1 kiyohara
574 1.1 kiyohara return 0;
575 1.1 kiyohara }
576 1.1 kiyohara
577 1.1 kiyohara static int
578 1.1 kiyohara bcsp_slip_receive(int c, struct tty *tp)
579 1.1 kiyohara {
580 1.4 plunky struct bcsp_softc *sc = tp->t_sc;
581 1.1 kiyohara struct mbuf *m = sc->sc_rxp;
582 1.1 kiyohara int discard = 0;
583 1.1 kiyohara const char *errstr;
584 1.1 kiyohara
585 1.1 kiyohara c &= TTY_CHARMASK;
586 1.1 kiyohara
587 1.1 kiyohara /* If we already started a packet, find the trailing end of it. */
588 1.1 kiyohara if (m) {
589 1.1 kiyohara while (m->m_next)
590 1.1 kiyohara m = m->m_next;
591 1.1 kiyohara
592 1.1 kiyohara if (M_TRAILINGSPACE(m) == 0) {
593 1.1 kiyohara /* extend mbuf */
594 1.1 kiyohara MGET(m->m_next, M_DONTWAIT, MT_DATA);
595 1.1 kiyohara if (m->m_next == NULL) {
596 1.1 kiyohara printf("%s: out of memory\n",
597 1.4 plunky device_xname(sc->sc_dev));
598 1.1 kiyohara ++sc->sc_unit.hci_stats.err_rx;
599 1.1 kiyohara return 0; /* (lost sync) */
600 1.1 kiyohara }
601 1.1 kiyohara
602 1.1 kiyohara m = m->m_next;
603 1.3 kiyohara m->m_pkthdr.len = m->m_len = 0;
604 1.1 kiyohara }
605 1.1 kiyohara } else
606 1.1 kiyohara if (c != BCSP_SLIP_PKTSTART) {
607 1.1 kiyohara discard = 1;
608 1.1 kiyohara errstr = "not sync";
609 1.1 kiyohara goto discarded;
610 1.1 kiyohara }
611 1.1 kiyohara
612 1.1 kiyohara switch (c) {
613 1.1 kiyohara case BCSP_SLIP_PKTSTART /* or _PKTEND */:
614 1.1 kiyohara if (m == NULL) {
615 1.1 kiyohara /* BCSP_SLIP_PKTSTART */
616 1.1 kiyohara
617 1.1 kiyohara DPRINTFN(4, ("%s: slip receive start\n",
618 1.4 plunky device_xname(sc->sc_dev)));
619 1.1 kiyohara
620 1.1 kiyohara /* new packet */
621 1.1 kiyohara MGETHDR(m, M_DONTWAIT, MT_DATA);
622 1.1 kiyohara if (m == NULL) {
623 1.1 kiyohara printf("%s: out of memory\n",
624 1.4 plunky device_xname(sc->sc_dev));
625 1.1 kiyohara ++sc->sc_unit.hci_stats.err_rx;
626 1.1 kiyohara return 0; /* (lost sync) */
627 1.1 kiyohara }
628 1.1 kiyohara
629 1.1 kiyohara sc->sc_rxp = m;
630 1.1 kiyohara m->m_pkthdr.len = m->m_len = 0;
631 1.1 kiyohara sc->sc_slip_rxexp = 0;
632 1.1 kiyohara } else {
633 1.1 kiyohara /* BCSP_SLIP_PKTEND */
634 1.1 kiyohara
635 1.1 kiyohara if (m == sc->sc_rxp && m->m_len == 0) {
636 1.1 kiyohara DPRINTFN(4, ("%s: resynchronises\n",
637 1.4 plunky device_xname(sc->sc_dev)));
638 1.1 kiyohara
639 1.1 kiyohara sc->sc_unit.hci_stats.byte_rx++;
640 1.1 kiyohara return 0;
641 1.1 kiyohara }
642 1.1 kiyohara
643 1.1 kiyohara DPRINTFN(4, ("%s%s: slip receive end\n",
644 1.1 kiyohara (m->m_len % 16 != 0) ? "\n" : "",
645 1.4 plunky device_xname(sc->sc_dev)));
646 1.1 kiyohara
647 1.1 kiyohara bcsp_pktintegrity_receive(sc, sc->sc_rxp);
648 1.1 kiyohara sc->sc_rxp = NULL;
649 1.1 kiyohara sc->sc_slip_rxexp = BCSP_SLIP_PKTSTART;
650 1.1 kiyohara }
651 1.1 kiyohara sc->sc_unit.hci_stats.byte_rx++;
652 1.1 kiyohara return 0;
653 1.1 kiyohara
654 1.1 kiyohara case BCSP_SLIP_ESCAPE:
655 1.1 kiyohara
656 1.1 kiyohara DPRINTFN(4, (" esc"));
657 1.1 kiyohara
658 1.1 kiyohara if (sc->sc_slip_rxexp == BCSP_SLIP_ESCAPE) {
659 1.1 kiyohara discard = 1;
660 1.1 kiyohara errstr = "waiting 0xdc or 0xdb";
661 1.1 kiyohara } else
662 1.1 kiyohara sc->sc_slip_rxexp = BCSP_SLIP_ESCAPE;
663 1.1 kiyohara break;
664 1.1 kiyohara
665 1.1 kiyohara default:
666 1.1 kiyohara DPRINTFN(4, (" 0x%02x%s",
667 1.1 kiyohara c, (m->m_len % 16 == 15) ? "\n" : ""));
668 1.1 kiyohara
669 1.1 kiyohara switch (sc->sc_slip_rxexp) {
670 1.1 kiyohara case BCSP_SLIP_PKTSTART:
671 1.1 kiyohara discard = 1;
672 1.1 kiyohara errstr = "waiting 0xc0";
673 1.1 kiyohara break;
674 1.1 kiyohara
675 1.1 kiyohara case BCSP_SLIP_ESCAPE:
676 1.1 kiyohara if (c == BCSP_SLIP_ESCAPE_PKTEND)
677 1.1 kiyohara mtod(m, uint8_t *)[m->m_len++] =
678 1.1 kiyohara BCSP_SLIP_PKTEND;
679 1.1 kiyohara else if (c == BCSP_SLIP_ESCAPE_ESCAPE)
680 1.1 kiyohara mtod(m, uint8_t *)[m->m_len++] =
681 1.1 kiyohara BCSP_SLIP_ESCAPE;
682 1.1 kiyohara else {
683 1.1 kiyohara discard = 1;
684 1.1 kiyohara errstr = "unknown escape";
685 1.1 kiyohara }
686 1.1 kiyohara sc->sc_slip_rxexp = 0;
687 1.1 kiyohara break;
688 1.1 kiyohara
689 1.1 kiyohara default:
690 1.1 kiyohara mtod(m, uint8_t *)[m->m_len++] = c;
691 1.1 kiyohara }
692 1.3 kiyohara sc->sc_rxp->m_pkthdr.len++;
693 1.1 kiyohara }
694 1.1 kiyohara if (discard) {
695 1.1 kiyohara discarded:
696 1.1 kiyohara DPRINTFN(4, ("%s: receives unexpected byte 0x%02x: %s\n",
697 1.4 plunky device_xname(sc->sc_dev), c, errstr));
698 1.3 kiyohara }
699 1.1 kiyohara sc->sc_unit.hci_stats.byte_rx++;
700 1.1 kiyohara
701 1.1 kiyohara return 0;
702 1.1 kiyohara }
703 1.1 kiyohara
704 1.1 kiyohara
705 1.1 kiyohara /*
706 1.1 kiyohara * BCSP Packet Integrity Layer functions:
707 1.1 kiyohara * handling Payload Length, Checksum, CRC.
708 1.1 kiyohara */
709 1.1 kiyohara static void
710 1.1 kiyohara bcsp_pktintegrity_transmit(struct bcsp_softc *sc)
711 1.1 kiyohara {
712 1.1 kiyohara struct mbuf *_m, *m = sc->sc_txp;
713 1.1 kiyohara bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
714 1.1 kiyohara int pktlen, pldlen;
715 1.1 kiyohara
716 1.4 plunky DPRINTFN(3, ("%s: pi transmit\n", device_xname(sc->sc_dev)));
717 1.1 kiyohara
718 1.1 kiyohara for (pktlen = 0, _m = m; _m != NULL; _m = _m->m_next)
719 1.1 kiyohara pktlen += _m->m_len;
720 1.1 kiyohara pldlen = pktlen - sizeof(bcsp_hdr_t);
721 1.1 kiyohara
722 1.1 kiyohara if (sc->sc_pi_txcrc)
723 1.1 kiyohara hdrp->flags |= BCSP_FLAGS_CRC_PRESENT;
724 1.1 kiyohara
725 1.1 kiyohara BCSP_SET_PLEN(hdrp, pldlen);
726 1.1 kiyohara BCSP_SET_CSUM(hdrp);
727 1.1 kiyohara
728 1.1 kiyohara if (sc->sc_pi_txcrc) {
729 1.1 kiyohara int n = 0;
730 1.1 kiyohara uint16_t crc = 0xffff;
731 1.1 kiyohara uint8_t *buf;
732 1.1 kiyohara
733 1.1 kiyohara for (_m = m; _m != NULL; _m = _m->m_next) {
734 1.1 kiyohara buf = mtod(_m, uint8_t *);
735 1.1 kiyohara for (n = 0; n < _m->m_len; n++)
736 1.1 kiyohara bcsp_crc_update(&crc, *(buf + n));
737 1.1 kiyohara }
738 1.1 kiyohara crc = htobe16(bcsp_crc_reverse(crc));
739 1.1 kiyohara m_copyback(m, pktlen, sizeof(crc), &crc);
740 1.1 kiyohara }
741 1.1 kiyohara
742 1.1 kiyohara #ifdef BCSP_DEBUG
743 1.1 kiyohara if (bcsp_debug == 4)
744 1.1 kiyohara bcsp_packet_print(m);
745 1.1 kiyohara #endif
746 1.1 kiyohara
747 1.1 kiyohara bcsp_slip_transmit(sc->sc_tp);
748 1.1 kiyohara }
749 1.1 kiyohara
750 1.1 kiyohara static void
751 1.1 kiyohara bcsp_pktintegrity_receive(struct bcsp_softc *sc, struct mbuf *m)
752 1.1 kiyohara {
753 1.1 kiyohara bcsp_hdr_t *hdrp;
754 1.1 kiyohara struct mbuf *_m;
755 1.1 kiyohara u_int pktlen, pldlen;
756 1.1 kiyohara int discard = 0;
757 1.1 kiyohara uint16_t crc = 0xffff;
758 1.1 kiyohara const char *errstr;
759 1.1 kiyohara
760 1.4 plunky DPRINTFN(3, ("%s: pi receive\n", device_xname(sc->sc_dev)));
761 1.1 kiyohara #ifdef BCSP_DEBUG
762 1.1 kiyohara if (bcsp_debug == 4)
763 1.1 kiyohara bcsp_packet_print(m);
764 1.1 kiyohara #endif
765 1.1 kiyohara
766 1.1 kiyohara KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
767 1.1 kiyohara
768 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
769 1.1 kiyohara for (pktlen = 0, _m = m; _m != NULL; _m = _m->m_next)
770 1.1 kiyohara pktlen += _m->m_len;
771 1.1 kiyohara pldlen = pktlen - sizeof(bcsp_hdr_t) -
772 1.1 kiyohara ((hdrp->flags & BCSP_FLAGS_CRC_PRESENT) ? sizeof(crc) : 0);
773 1.1 kiyohara if (pldlen > 0xfff) {
774 1.1 kiyohara discard = 1;
775 1.1 kiyohara errstr = "Payload Length";
776 1.1 kiyohara goto discarded;
777 1.1 kiyohara }
778 1.1 kiyohara if (hdrp->csum != BCSP_GET_CSUM(hdrp)) {
779 1.1 kiyohara discard = 1;
780 1.1 kiyohara errstr = "Checksum";
781 1.1 kiyohara goto discarded;
782 1.1 kiyohara }
783 1.1 kiyohara if (BCSP_GET_PLEN(hdrp) != pldlen) {
784 1.1 kiyohara discard = 1;
785 1.1 kiyohara errstr = "Payload Length";
786 1.1 kiyohara goto discarded;
787 1.1 kiyohara }
788 1.1 kiyohara if (hdrp->flags & BCSP_FLAGS_CRC_PRESENT) {
789 1.1 kiyohara int i, n;
790 1.1 kiyohara uint16_t crc0;
791 1.1 kiyohara uint8_t *buf;
792 1.1 kiyohara
793 1.1 kiyohara i = 0;
794 1.1 kiyohara n = 0;
795 1.1 kiyohara for (_m = m; _m != NULL; _m = _m->m_next) {
796 1.1 kiyohara buf = mtod(m, uint8_t *);
797 1.1 kiyohara for (n = 0;
798 1.1 kiyohara n < _m->m_len && i < sizeof(bcsp_hdr_t) + pldlen;
799 1.1 kiyohara n++, i++)
800 1.1 kiyohara bcsp_crc_update(&crc, *(buf + n));
801 1.1 kiyohara }
802 1.1 kiyohara
803 1.1 kiyohara m_copydata(_m, n, sizeof(crc0), &crc0);
804 1.1 kiyohara if (be16toh(crc0) != bcsp_crc_reverse(crc)) {
805 1.1 kiyohara discard = 1;
806 1.1 kiyohara errstr = "CRC";
807 1.1 kiyohara } else
808 1.1 kiyohara /* Shaves CRC */
809 1.2 kiyohara m_adj(m, (int)(0 - sizeof(crc)));
810 1.1 kiyohara }
811 1.1 kiyohara
812 1.1 kiyohara if (discard) {
813 1.1 kiyohara discarded:
814 1.1 kiyohara DPRINTFN(3, ("%s: receives unexpected packet: %s\n",
815 1.4 plunky device_xname(sc->sc_dev), errstr));
816 1.1 kiyohara m_freem(m);
817 1.1 kiyohara } else
818 1.1 kiyohara bcsp_mux_receive(sc, m);
819 1.1 kiyohara }
820 1.1 kiyohara
821 1.1 kiyohara static const uint16_t crctbl[] = {
822 1.1 kiyohara 0x0000, 0x1081, 0x2102, 0x3183,
823 1.1 kiyohara 0x4204, 0x5285, 0x6306, 0x7387,
824 1.1 kiyohara 0x8408, 0x9489, 0xa50a, 0xb58b,
825 1.1 kiyohara 0xc60c, 0xd68d, 0xe70e, 0xf78f,
826 1.1 kiyohara };
827 1.1 kiyohara
828 1.1 kiyohara static void
829 1.1 kiyohara bcsp_crc_update(uint16_t *crc, uint8_t d)
830 1.1 kiyohara {
831 1.1 kiyohara uint16_t reg = *crc;
832 1.1 kiyohara
833 1.1 kiyohara reg = (reg >> 4) ^ crctbl[(reg ^ d) & 0x000f];
834 1.1 kiyohara reg = (reg >> 4) ^ crctbl[(reg ^ (d >> 4)) & 0x000f];
835 1.1 kiyohara
836 1.1 kiyohara *crc = reg;
837 1.1 kiyohara }
838 1.1 kiyohara
839 1.1 kiyohara static uint16_t
840 1.1 kiyohara bcsp_crc_reverse(uint16_t crc)
841 1.1 kiyohara {
842 1.1 kiyohara uint16_t b, rev;
843 1.1 kiyohara
844 1.1 kiyohara for (b = 0, rev = 0; b < 16; b++) {
845 1.1 kiyohara rev = rev << 1;
846 1.1 kiyohara rev |= (crc & 1);
847 1.1 kiyohara crc = crc >> 1;
848 1.1 kiyohara }
849 1.1 kiyohara
850 1.1 kiyohara return rev;
851 1.1 kiyohara }
852 1.1 kiyohara
853 1.1 kiyohara
854 1.1 kiyohara /*
855 1.1 kiyohara * BCSP MUX Layer functions
856 1.1 kiyohara */
857 1.1 kiyohara static void
858 1.1 kiyohara bcsp_mux_transmit(struct bcsp_softc *sc)
859 1.1 kiyohara {
860 1.1 kiyohara struct hci_unit *unit = &sc->sc_unit;
861 1.1 kiyohara struct mbuf *m;
862 1.1 kiyohara bcsp_hdr_t *hdrp;
863 1.1 kiyohara
864 1.1 kiyohara DPRINTFN(2, ("%s: mux transmit: hci_flags=0x%x, choke=%d",
865 1.4 plunky device_xname(sc->sc_dev), unit->hci_flags, sc->sc_mux_choke));
866 1.1 kiyohara
867 1.1 kiyohara if (sc->sc_mux_choke) {
868 1.1 kiyohara struct mbuf *_m = NULL;
869 1.1 kiyohara
870 1.1 kiyohara /* In this case, send only Link Establishment packet */
871 1.1 kiyohara for (m = MBUFQ_FIRST(&sc->sc_dgq); m != NULL;
872 1.1 kiyohara _m = m, m = MBUFQ_NEXT(m)) {
873 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
874 1.1 kiyohara if (hdrp->ident == BCSP_CHANNEL_LE) {
875 1.1 kiyohara if (m == MBUFQ_FIRST(&sc->sc_dgq))
876 1.1 kiyohara MBUFQ_DEQUEUE(&sc->sc_dgq, m);
877 1.1 kiyohara else {
878 1.1 kiyohara if (m->m_nextpkt == NULL)
879 1.1 kiyohara sc->sc_dgq.mq_last =
880 1.1 kiyohara &_m->m_nextpkt;
881 1.1 kiyohara _m->m_nextpkt = m->m_nextpkt;
882 1.1 kiyohara m->m_nextpkt = NULL;
883 1.1 kiyohara }
884 1.1 kiyohara goto transmit;
885 1.1 kiyohara }
886 1.1 kiyohara }
887 1.1 kiyohara DPRINTFN(2, ("\n"));
888 1.1 kiyohara return;
889 1.1 kiyohara }
890 1.1 kiyohara
891 1.1 kiyohara /*
892 1.1 kiyohara * The MUX Layer always gives priority to packets from the Datagram
893 1.1 kiyohara * Queue Layer over the Sequencing Layer.
894 1.1 kiyohara */
895 1.1 kiyohara if (MBUFQ_FIRST(&sc->sc_dgq)) {
896 1.1 kiyohara MBUFQ_DEQUEUE(&sc->sc_dgq, m);
897 1.1 kiyohara goto transmit;
898 1.1 kiyohara }
899 1.1 kiyohara if (MBUFQ_FIRST(&sc->sc_seqq)) {
900 1.1 kiyohara MBUFQ_DEQUEUE(&sc->sc_seqq, m);
901 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
902 1.1 kiyohara hdrp->flags |= BCSP_FLAGS_PROTOCOL_REL; /* Reliable */
903 1.1 kiyohara goto transmit;
904 1.1 kiyohara }
905 1.7 plunky bcsp_start(sc->sc_dev);
906 1.1 kiyohara if (sc->sc_mux_send_ack == true) {
907 1.1 kiyohara m = bcsp_create_ackpkt();
908 1.1 kiyohara if (m != NULL)
909 1.1 kiyohara goto transmit;
910 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
911 1.2 kiyohara ++unit->hci_stats.err_tx;
912 1.1 kiyohara }
913 1.1 kiyohara
914 1.1 kiyohara /* Nothing to send */
915 1.1 kiyohara DPRINTFN(2, ("\n"));
916 1.1 kiyohara return;
917 1.1 kiyohara
918 1.1 kiyohara transmit:
919 1.1 kiyohara DPRINTFN(2, (", txack=%d, send_ack=%d\n",
920 1.1 kiyohara bcsp_get_txack(sc), sc->sc_mux_send_ack));
921 1.1 kiyohara
922 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
923 1.1 kiyohara hdrp->flags |=
924 1.1 kiyohara (bcsp_get_txack(sc) << BCSP_FLAGS_ACK_SHIFT) & BCSP_FLAGS_ACK_MASK;
925 1.1 kiyohara if (sc->sc_mux_send_ack == true)
926 1.1 kiyohara sc->sc_mux_send_ack = false;
927 1.1 kiyohara
928 1.1 kiyohara #ifdef BCSP_DEBUG
929 1.1 kiyohara if (bcsp_debug == 3)
930 1.1 kiyohara bcsp_packet_print(m);
931 1.1 kiyohara #endif
932 1.1 kiyohara
933 1.1 kiyohara sc->sc_txp = m;
934 1.1 kiyohara bcsp_pktintegrity_transmit(sc);
935 1.1 kiyohara }
936 1.1 kiyohara
937 1.1 kiyohara static void
938 1.1 kiyohara bcsp_mux_receive(struct bcsp_softc *sc, struct mbuf *m)
939 1.1 kiyohara {
940 1.1 kiyohara bcsp_hdr_t *hdrp = mtod(m, bcsp_hdr_t *);
941 1.1 kiyohara const u_int rxack = BCSP_FLAGS_ACK(hdrp->flags);
942 1.1 kiyohara
943 1.1 kiyohara DPRINTFN(2, ("%s: mux receive: flags=0x%x, ident=%d, rxack=%d\n",
944 1.4 plunky device_xname(sc->sc_dev), hdrp->flags, hdrp->ident, rxack));
945 1.1 kiyohara #ifdef BCSP_DEBUG
946 1.1 kiyohara if (bcsp_debug == 3)
947 1.1 kiyohara bcsp_packet_print(m);
948 1.1 kiyohara #endif
949 1.1 kiyohara
950 1.1 kiyohara bcsp_signal_rxack(sc, rxack);
951 1.1 kiyohara
952 1.1 kiyohara microtime(&sc->sc_mux_lastrx);
953 1.1 kiyohara
954 1.1 kiyohara /* if the Ack Packet received then discard */
955 1.1 kiyohara if (BCSP_FLAGS_SEQ(hdrp->flags) == 0 &&
956 1.1 kiyohara hdrp->ident == BCSP_IDENT_ACKPKT &&
957 1.1 kiyohara BCSP_GET_PLEN(hdrp) == 0) {
958 1.1 kiyohara m_freem(m);
959 1.1 kiyohara return;
960 1.1 kiyohara }
961 1.1 kiyohara
962 1.1 kiyohara if (hdrp->flags & BCSP_FLAGS_PROTOCOL_REL)
963 1.1 kiyohara bcsp_sequencing_receive(sc, m);
964 1.1 kiyohara else
965 1.1 kiyohara bcsp_datagramq_receive(sc, m);
966 1.1 kiyohara }
967 1.1 kiyohara
968 1.1 kiyohara static __inline void
969 1.1 kiyohara bcsp_send_ack_command(struct bcsp_softc *sc)
970 1.1 kiyohara {
971 1.1 kiyohara
972 1.4 plunky DPRINTFN(2, ("%s: mux send_ack_command\n", device_xname(sc->sc_dev)));
973 1.1 kiyohara
974 1.1 kiyohara sc->sc_mux_send_ack = true;
975 1.1 kiyohara }
976 1.1 kiyohara
977 1.1 kiyohara static __inline struct mbuf *
978 1.1 kiyohara bcsp_create_ackpkt()
979 1.1 kiyohara {
980 1.1 kiyohara struct mbuf *m;
981 1.1 kiyohara bcsp_hdr_t *hdrp;
982 1.1 kiyohara
983 1.1 kiyohara MGETHDR(m, M_DONTWAIT, MT_DATA);
984 1.1 kiyohara if (m != NULL) {
985 1.1 kiyohara m->m_pkthdr.len = m->m_len = sizeof(bcsp_hdr_t);
986 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
987 1.1 kiyohara /*
988 1.1 kiyohara * An Ack Packet has the following fields:
989 1.1 kiyohara * Ack Field: txack (not set yet)
990 1.1 kiyohara * Seq Field: 0
991 1.1 kiyohara * Protocol Identifier Field: 0
992 1.1 kiyohara * Protocol Type Field: Any value
993 1.1 kiyohara * Payload Length Field: 0
994 1.1 kiyohara */
995 1.1 kiyohara memset(hdrp, 0, sizeof(bcsp_hdr_t));
996 1.1 kiyohara }
997 1.1 kiyohara return m;
998 1.1 kiyohara }
999 1.1 kiyohara
1000 1.1 kiyohara static __inline void
1001 1.1 kiyohara bcsp_set_choke(struct bcsp_softc *sc, bool choke)
1002 1.1 kiyohara {
1003 1.1 kiyohara
1004 1.4 plunky DPRINTFN(2, ("%s: mux set choke=%d\n", device_xname(sc->sc_dev), choke));
1005 1.1 kiyohara
1006 1.1 kiyohara sc->sc_mux_choke = choke;
1007 1.1 kiyohara }
1008 1.1 kiyohara
1009 1.1 kiyohara
1010 1.1 kiyohara /*
1011 1.1 kiyohara * BCSP Sequencing Layer functions
1012 1.1 kiyohara */
1013 1.1 kiyohara static void
1014 1.1 kiyohara bcsp_sequencing_receive(struct bcsp_softc *sc, struct mbuf *m)
1015 1.1 kiyohara {
1016 1.1 kiyohara bcsp_hdr_t hdr;
1017 1.1 kiyohara uint32_t rxseq;
1018 1.1 kiyohara
1019 1.1 kiyohara m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
1020 1.1 kiyohara rxseq = BCSP_FLAGS_SEQ(hdr.flags);
1021 1.1 kiyohara
1022 1.1 kiyohara DPRINTFN(1, ("%s: seq receive: rxseq=%d, expected %d\n",
1023 1.4 plunky device_xname(sc->sc_dev), rxseq, sc->sc_seq_expected_rxseq));
1024 1.1 kiyohara #ifdef BCSP_DEBUG
1025 1.1 kiyohara if (bcsp_debug == 2)
1026 1.1 kiyohara bcsp_packet_print(m);
1027 1.1 kiyohara #endif
1028 1.1 kiyohara
1029 1.3 kiyohara /*
1030 1.3 kiyohara * We remove the header of BCSP and add the 'uint8_t type' of
1031 1.3 kiyohara * hci_*_hdr_t to the head.
1032 1.3 kiyohara */
1033 1.3 kiyohara m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
1034 1.3 kiyohara
1035 1.1 kiyohara if (rxseq != sc->sc_seq_expected_rxseq) {
1036 1.1 kiyohara m_freem(m);
1037 1.1 kiyohara
1038 1.1 kiyohara /* send ack packet, if needly */
1039 1.1 kiyohara bcsp_mux_transmit(sc);
1040 1.1 kiyohara
1041 1.1 kiyohara return;
1042 1.1 kiyohara }
1043 1.1 kiyohara
1044 1.1 kiyohara switch (hdr.ident) {
1045 1.1 kiyohara case BCSP_CHANNEL_HCI_CMDEVT:
1046 1.1 kiyohara *(mtod(m, uint8_t *)) = HCI_EVENT_PKT;
1047 1.1 kiyohara hci_input_event(&sc->sc_unit, m);
1048 1.1 kiyohara sc->sc_unit.hci_stats.evt_rx++;
1049 1.1 kiyohara break;
1050 1.1 kiyohara
1051 1.1 kiyohara case BCSP_CHANNEL_HCI_ACL:
1052 1.1 kiyohara *(mtod(m, uint8_t *)) = HCI_ACL_DATA_PKT;
1053 1.1 kiyohara hci_input_acl(&sc->sc_unit, m);
1054 1.1 kiyohara sc->sc_unit.hci_stats.acl_rx++;
1055 1.1 kiyohara break;
1056 1.1 kiyohara
1057 1.1 kiyohara case BCSP_CHANNEL_HCI_SCO:
1058 1.1 kiyohara *(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1059 1.1 kiyohara hci_input_sco(&sc->sc_unit, m);
1060 1.1 kiyohara sc->sc_unit.hci_stats.sco_rx++;
1061 1.1 kiyohara break;
1062 1.1 kiyohara
1063 1.1 kiyohara case BCSP_CHANNEL_HQ:
1064 1.1 kiyohara case BCSP_CHANNEL_DEVMGT:
1065 1.1 kiyohara case BCSP_CHANNEL_L2CAP:
1066 1.1 kiyohara case BCSP_CHANNEL_RFCOMM:
1067 1.1 kiyohara case BCSP_CHANNEL_SDP:
1068 1.1 kiyohara case BCSP_CHANNEL_DFU:
1069 1.1 kiyohara case BCSP_CHANNEL_VM:
1070 1.1 kiyohara default:
1071 1.1 kiyohara printf("%s:"
1072 1.1 kiyohara " received reliable packet with not support channel %d\n",
1073 1.4 plunky device_xname(sc->sc_dev), hdr.ident);
1074 1.1 kiyohara m_freem(m);
1075 1.1 kiyohara break;
1076 1.1 kiyohara }
1077 1.1 kiyohara
1078 1.1 kiyohara sc->sc_seq_expected_rxseq =
1079 1.1 kiyohara (sc->sc_seq_expected_rxseq + 1) & BCSP_FLAGS_SEQ_MASK;
1080 1.1 kiyohara sc->sc_seq_txack = sc->sc_seq_expected_rxseq;
1081 1.1 kiyohara bcsp_send_ack_command(sc);
1082 1.1 kiyohara }
1083 1.1 kiyohara
1084 1.1 kiyohara static bool
1085 1.1 kiyohara bcsp_tx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1086 1.1 kiyohara {
1087 1.1 kiyohara bcsp_hdr_t *hdrp;
1088 1.1 kiyohara struct mbuf *_m;
1089 1.1 kiyohara u_int pldlen;
1090 1.1 kiyohara int s;
1091 1.1 kiyohara
1092 1.1 kiyohara DPRINTFN(1, ("%s: seq transmit:"
1093 1.4 plunky "protocol_id=%d, winspace=%d, txseq=%d\n", device_xname(sc->sc_dev),
1094 1.1 kiyohara protocol_id, sc->sc_seq_winspace, sc->sc_seq_txseq));
1095 1.1 kiyohara
1096 1.1 kiyohara for (pldlen = 0, _m = m; _m != NULL; _m = _m->m_next) {
1097 1.1 kiyohara if (_m->m_len < 0)
1098 1.1 kiyohara return false;
1099 1.1 kiyohara pldlen += _m->m_len;
1100 1.1 kiyohara }
1101 1.1 kiyohara if (pldlen > 0xfff)
1102 1.1 kiyohara return false;
1103 1.1 kiyohara if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
1104 1.1 kiyohara return false;
1105 1.1 kiyohara
1106 1.1 kiyohara if (sc->sc_seq_winspace == 0)
1107 1.1 kiyohara return false;
1108 1.1 kiyohara
1109 1.1 kiyohara M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
1110 1.1 kiyohara if (m == NULL) {
1111 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1112 1.1 kiyohara return false;
1113 1.1 kiyohara }
1114 1.1 kiyohara KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
1115 1.1 kiyohara
1116 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
1117 1.1 kiyohara memset(hdrp, 0, sizeof(bcsp_hdr_t));
1118 1.1 kiyohara hdrp->flags |= sc->sc_seq_txseq;
1119 1.1 kiyohara hdrp->ident = protocol_id;
1120 1.1 kiyohara
1121 1.1 kiyohara callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1122 1.1 kiyohara
1123 1.1 kiyohara s = splserial();
1124 1.1 kiyohara MBUFQ_ENQUEUE(&sc->sc_seqq, m);
1125 1.1 kiyohara splx(s);
1126 1.1 kiyohara sc->sc_transmit_callback = bcsp_reliabletx_callback;
1127 1.1 kiyohara
1128 1.1 kiyohara #ifdef BCSP_DEBUG
1129 1.1 kiyohara if (bcsp_debug == 2)
1130 1.1 kiyohara bcsp_packet_print(m);
1131 1.1 kiyohara #endif
1132 1.1 kiyohara
1133 1.1 kiyohara sc->sc_seq_txseq = (sc->sc_seq_txseq + 1) & BCSP_FLAGS_SEQ_MASK;
1134 1.1 kiyohara sc->sc_seq_winspace--;
1135 1.1 kiyohara _m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1136 1.1 kiyohara if (_m == NULL) {
1137 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1138 1.1 kiyohara return false;
1139 1.1 kiyohara }
1140 1.1 kiyohara MBUFQ_ENQUEUE(&sc->sc_seq_retryq, _m);
1141 1.1 kiyohara bcsp_mux_transmit(sc);
1142 1.1 kiyohara
1143 1.1 kiyohara return true;
1144 1.1 kiyohara }
1145 1.1 kiyohara
1146 1.1 kiyohara #if 0
1147 1.1 kiyohara static bool
1148 1.1 kiyohara bcsp_rx_reliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1149 1.1 kiyohara {
1150 1.1 kiyohara
1151 1.1 kiyohara return false;
1152 1.1 kiyohara }
1153 1.1 kiyohara
1154 1.1 kiyohara /* XXXX: I can't understand meaning this function... */
1155 1.1 kiyohara static __inline void
1156 1.1 kiyohara bcsp_link_failed(struct bcsp_softc *sc)
1157 1.1 kiyohara {
1158 1.1 kiyohara
1159 1.1 kiyohara return (sc->sc_seq_retries >= sc->sc_seq_retry_limit);
1160 1.1 kiyohara }
1161 1.1 kiyohara #endif
1162 1.1 kiyohara
1163 1.1 kiyohara static __inline u_int
1164 1.1 kiyohara bcsp_get_txack(struct bcsp_softc *sc)
1165 1.1 kiyohara {
1166 1.1 kiyohara
1167 1.1 kiyohara return sc->sc_seq_txack;
1168 1.1 kiyohara }
1169 1.1 kiyohara
1170 1.1 kiyohara static void
1171 1.1 kiyohara bcsp_signal_rxack(struct bcsp_softc *sc, uint32_t rxack)
1172 1.1 kiyohara {
1173 1.1 kiyohara bcsp_hdr_t *hdrp;
1174 1.1 kiyohara struct mbuf *m;
1175 1.1 kiyohara uint32_t seqno = (rxack - 1) & BCSP_FLAGS_SEQ_MASK;
1176 1.1 kiyohara int s;
1177 1.1 kiyohara
1178 1.1 kiyohara DPRINTFN(1, ("%s: seq signal rxack: rxack=%d\n",
1179 1.4 plunky device_xname(sc->sc_dev), rxack));
1180 1.1 kiyohara
1181 1.1 kiyohara s = splserial();
1182 1.1 kiyohara m = MBUFQ_FIRST(&sc->sc_seq_retryq);
1183 1.1 kiyohara while (m != NULL) {
1184 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
1185 1.1 kiyohara if (BCSP_FLAGS_SEQ(hdrp->flags) == seqno) {
1186 1.1 kiyohara struct mbuf *m0;
1187 1.1 kiyohara
1188 1.1 kiyohara for (m0 = MBUFQ_FIRST(&sc->sc_seq_retryq);
1189 1.1 kiyohara m0 != MBUFQ_NEXT(m);
1190 1.1 kiyohara m0 = MBUFQ_FIRST(&sc->sc_seq_retryq)) {
1191 1.1 kiyohara MBUFQ_DEQUEUE(&sc->sc_seq_retryq, m0);
1192 1.1 kiyohara m_freem(m0);
1193 1.1 kiyohara sc->sc_seq_winspace++;
1194 1.1 kiyohara }
1195 1.1 kiyohara break;
1196 1.1 kiyohara }
1197 1.1 kiyohara m = MBUFQ_NEXT(m);
1198 1.1 kiyohara }
1199 1.1 kiyohara splx(s);
1200 1.1 kiyohara sc->sc_seq_retries = 0;
1201 1.1 kiyohara
1202 1.1 kiyohara if (sc->sc_seq_winspace == sc->sc_seq_winsize)
1203 1.1 kiyohara callout_stop(&sc->sc_seq_timer);
1204 1.1 kiyohara else
1205 1.1 kiyohara callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1206 1.1 kiyohara }
1207 1.1 kiyohara
1208 1.1 kiyohara static void
1209 1.1 kiyohara bcsp_reliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
1210 1.1 kiyohara {
1211 1.1 kiyohara
1212 1.1 kiyohara m_freem(m);
1213 1.1 kiyohara }
1214 1.1 kiyohara
1215 1.1 kiyohara static void
1216 1.1 kiyohara bcsp_timer_timeout(void *arg)
1217 1.1 kiyohara {
1218 1.1 kiyohara struct bcsp_softc *sc = arg;
1219 1.1 kiyohara struct mbuf *m, *_m;
1220 1.1 kiyohara int s, i = 0;
1221 1.1 kiyohara
1222 1.1 kiyohara DPRINTFN(1, ("%s: seq timeout: retries=%d\n",
1223 1.4 plunky device_xname(sc->sc_dev), sc->sc_seq_retries));
1224 1.1 kiyohara
1225 1.1 kiyohara s = splserial();
1226 1.1 kiyohara for (m = MBUFQ_FIRST(&sc->sc_seq_retryq); m != NULL;
1227 1.1 kiyohara m = MBUFQ_NEXT(m)) {
1228 1.1 kiyohara _m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1229 1.1 kiyohara if (_m == NULL) {
1230 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1231 1.1 kiyohara return;
1232 1.1 kiyohara }
1233 1.1 kiyohara MBUFQ_ENQUEUE(&sc->sc_seqq, _m);
1234 1.1 kiyohara i++;
1235 1.1 kiyohara }
1236 1.1 kiyohara splx(s);
1237 1.1 kiyohara
1238 1.1 kiyohara if (i != 0) {
1239 1.1 kiyohara if (++sc->sc_seq_retries < sc->sc_seq_retry_limit)
1240 1.1 kiyohara callout_schedule(&sc->sc_seq_timer, sc->sc_seq_timeout);
1241 1.1 kiyohara else {
1242 1.1 kiyohara printf("%s: reached the retry limit."
1243 1.1 kiyohara " restart the link-establishment\n",
1244 1.4 plunky device_xname(sc->sc_dev));
1245 1.3 kiyohara bcsp_sequencing_reset(sc);
1246 1.1 kiyohara bcsp_start_le(&sc->sc_unit);
1247 1.1 kiyohara return;
1248 1.1 kiyohara }
1249 1.1 kiyohara }
1250 1.1 kiyohara bcsp_mux_transmit(sc);
1251 1.1 kiyohara }
1252 1.1 kiyohara
1253 1.1 kiyohara static void
1254 1.1 kiyohara bcsp_sequencing_reset(struct bcsp_softc *sc)
1255 1.1 kiyohara {
1256 1.1 kiyohara int s;
1257 1.1 kiyohara
1258 1.1 kiyohara s = splserial();
1259 1.1 kiyohara MBUFQ_DRAIN(&sc->sc_seqq);
1260 1.1 kiyohara MBUFQ_DRAIN(&sc->sc_seq_retryq);
1261 1.1 kiyohara splx(s);
1262 1.1 kiyohara
1263 1.1 kiyohara
1264 1.1 kiyohara sc->sc_seq_txseq = 0;
1265 1.1 kiyohara sc->sc_seq_txack = 0;
1266 1.1 kiyohara sc->sc_seq_winspace = sc->sc_seq_winsize;
1267 1.1 kiyohara sc->sc_seq_retries = 0;
1268 1.1 kiyohara callout_stop(&sc->sc_seq_timer);
1269 1.1 kiyohara
1270 1.1 kiyohara sc->sc_mux_send_ack = false;
1271 1.1 kiyohara
1272 1.1 kiyohara /* XXXX: expected_rxseq should be set by MUX Layer */
1273 1.1 kiyohara sc->sc_seq_expected_rxseq = 0;
1274 1.1 kiyohara }
1275 1.1 kiyohara
1276 1.1 kiyohara
1277 1.1 kiyohara /*
1278 1.1 kiyohara * BCSP Datagram Queue Layer functions
1279 1.1 kiyohara */
1280 1.1 kiyohara static void
1281 1.1 kiyohara bcsp_datagramq_receive(struct bcsp_softc *sc, struct mbuf *m)
1282 1.1 kiyohara {
1283 1.1 kiyohara bcsp_hdr_t hdr;
1284 1.1 kiyohara
1285 1.4 plunky DPRINTFN(1, ("%s: dgq receive\n", device_xname(sc->sc_dev)));
1286 1.1 kiyohara #ifdef BCSP_DEBUG
1287 1.1 kiyohara if (bcsp_debug == 2)
1288 1.1 kiyohara bcsp_packet_print(m);
1289 1.1 kiyohara #endif
1290 1.1 kiyohara
1291 1.1 kiyohara m_copydata(m, 0, sizeof(bcsp_hdr_t), &hdr);
1292 1.1 kiyohara
1293 1.1 kiyohara switch (hdr.ident) {
1294 1.1 kiyohara case BCSP_CHANNEL_LE:
1295 1.1 kiyohara m_adj(m, sizeof(bcsp_hdr_t));
1296 1.1 kiyohara bcsp_input_le(&sc->sc_unit, m);
1297 1.1 kiyohara break;
1298 1.1 kiyohara
1299 1.1 kiyohara case BCSP_CHANNEL_HCI_SCO:
1300 1.1 kiyohara /*
1301 1.1 kiyohara * We remove the header of BCSP and add the 'uint8_t type' of
1302 1.1 kiyohara * hci_scodata_hdr_t to the head.
1303 1.1 kiyohara */
1304 1.1 kiyohara m_adj(m, sizeof(bcsp_hdr_t) - sizeof(uint8_t));
1305 1.1 kiyohara *(mtod(m, uint8_t *)) = HCI_SCO_DATA_PKT;
1306 1.1 kiyohara hci_input_sco(&sc->sc_unit, m);
1307 1.1 kiyohara sc->sc_unit.hci_stats.sco_rx++;
1308 1.1 kiyohara break;
1309 1.1 kiyohara
1310 1.1 kiyohara default:
1311 1.1 kiyohara printf("%s:"
1312 1.1 kiyohara " received unreliable packet with not support channel %d\n",
1313 1.4 plunky device_xname(sc->sc_dev), hdr.ident);
1314 1.1 kiyohara m_freem(m);
1315 1.1 kiyohara break;
1316 1.1 kiyohara }
1317 1.1 kiyohara }
1318 1.1 kiyohara
1319 1.1 kiyohara static bool
1320 1.1 kiyohara bcsp_tx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1321 1.1 kiyohara {
1322 1.1 kiyohara bcsp_hdr_t *hdrp;
1323 1.1 kiyohara struct mbuf *_m;
1324 1.1 kiyohara u_int pldlen;
1325 1.1 kiyohara int s;
1326 1.1 kiyohara
1327 1.1 kiyohara DPRINTFN(1, ("%s: dgq transmit: protocol_id=%d,",
1328 1.4 plunky device_xname(sc->sc_dev), protocol_id));
1329 1.1 kiyohara
1330 1.1 kiyohara for (pldlen = 0, _m = m; _m != NULL; _m = m->m_next) {
1331 1.1 kiyohara if (_m->m_len < 0)
1332 1.1 kiyohara return false;
1333 1.1 kiyohara pldlen += _m->m_len;
1334 1.1 kiyohara }
1335 1.1 kiyohara DPRINTFN(1, (" pldlen=%d\n", pldlen));
1336 1.1 kiyohara if (pldlen > 0xfff)
1337 1.1 kiyohara return false;
1338 1.1 kiyohara if (protocol_id == BCSP_IDENT_ACKPKT || protocol_id > 15)
1339 1.1 kiyohara return false;
1340 1.1 kiyohara
1341 1.1 kiyohara M_PREPEND(m, sizeof(bcsp_hdr_t), M_DONTWAIT);
1342 1.1 kiyohara if (m == NULL) {
1343 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1344 1.1 kiyohara return false;
1345 1.1 kiyohara }
1346 1.1 kiyohara KASSERT(m->m_len >= sizeof(bcsp_hdr_t));
1347 1.1 kiyohara
1348 1.1 kiyohara hdrp = mtod(m, bcsp_hdr_t *);
1349 1.1 kiyohara memset(hdrp, 0, sizeof(bcsp_hdr_t));
1350 1.1 kiyohara hdrp->ident = protocol_id;
1351 1.1 kiyohara
1352 1.1 kiyohara s = splserial();
1353 1.1 kiyohara MBUFQ_ENQUEUE(&sc->sc_dgq, m);
1354 1.1 kiyohara splx(s);
1355 1.1 kiyohara sc->sc_transmit_callback = bcsp_unreliabletx_callback;
1356 1.1 kiyohara
1357 1.1 kiyohara #ifdef BCSP_DEBUG
1358 1.1 kiyohara if (bcsp_debug == 2)
1359 1.1 kiyohara bcsp_packet_print(m);
1360 1.1 kiyohara #endif
1361 1.1 kiyohara
1362 1.1 kiyohara bcsp_mux_transmit(sc);
1363 1.1 kiyohara
1364 1.1 kiyohara return true;
1365 1.1 kiyohara }
1366 1.1 kiyohara
1367 1.1 kiyohara #if 0
1368 1.1 kiyohara static bool
1369 1.1 kiyohara bcsp_rx_unreliable_pkt(struct bcsp_softc *sc, struct mbuf *m, u_int protocol_id)
1370 1.1 kiyohara {
1371 1.1 kiyohara
1372 1.1 kiyohara return false;
1373 1.1 kiyohara }
1374 1.1 kiyohara #endif
1375 1.1 kiyohara
1376 1.1 kiyohara static void
1377 1.1 kiyohara bcsp_unreliabletx_callback(struct bcsp_softc *sc, struct mbuf *m)
1378 1.1 kiyohara {
1379 1.1 kiyohara
1380 1.1 kiyohara if (M_GETCTX(m, void *) == NULL)
1381 1.1 kiyohara m_freem(m);
1382 1.1 kiyohara else
1383 1.1 kiyohara hci_complete_sco(&sc->sc_unit, m);
1384 1.1 kiyohara }
1385 1.1 kiyohara
1386 1.1 kiyohara
1387 1.1 kiyohara /*
1388 1.1 kiyohara * BlueCore Link Establishment Protocol functions
1389 1.1 kiyohara */
1390 1.1 kiyohara static const uint8_t sync[] = BCSP_LE_SYNC;
1391 1.1 kiyohara static const uint8_t syncresp[] = BCSP_LE_SYNCRESP;
1392 1.1 kiyohara static const uint8_t conf[] = BCSP_LE_CONF;
1393 1.1 kiyohara static const uint8_t confresp[] = BCSP_LE_CONFRESP;
1394 1.1 kiyohara
1395 1.1 kiyohara static int
1396 1.1 kiyohara bcsp_start_le(struct hci_unit *unit)
1397 1.1 kiyohara {
1398 1.7 plunky struct bcsp_softc *sc = device_private(unit->hci_dev);
1399 1.1 kiyohara
1400 1.4 plunky DPRINTF(("%s: start link-establish\n", device_xname(sc->sc_dev)));
1401 1.1 kiyohara
1402 1.1 kiyohara bcsp_set_choke(sc, true);
1403 1.1 kiyohara
1404 1.1 kiyohara if (!sc->sc_le_muzzled) {
1405 1.1 kiyohara struct mbuf *m;
1406 1.1 kiyohara
1407 1.1 kiyohara m = m_gethdr(M_WAIT, MT_DATA);
1408 1.1 kiyohara m->m_pkthdr.len = m->m_len = 0;
1409 1.1 kiyohara m_copyback(m, 0, sizeof(sync), sync);
1410 1.1 kiyohara if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE)) {
1411 1.1 kiyohara printf("%s: le-packet transmit failed\n",
1412 1.4 plunky device_xname(sc->sc_dev));
1413 1.1 kiyohara return EINVAL;
1414 1.1 kiyohara }
1415 1.1 kiyohara }
1416 1.1 kiyohara callout_schedule(&sc->sc_le_timer, BCSP_LE_TSHY_TIMEOUT);
1417 1.1 kiyohara
1418 1.1 kiyohara sc->sc_le_state = le_state_shy;
1419 1.1 kiyohara return 0;
1420 1.1 kiyohara }
1421 1.1 kiyohara
1422 1.1 kiyohara static void
1423 1.1 kiyohara bcsp_terminate_le(struct hci_unit *unit)
1424 1.1 kiyohara {
1425 1.7 plunky struct bcsp_softc *sc = device_private(unit->hci_dev);
1426 1.1 kiyohara struct mbuf *m;
1427 1.1 kiyohara
1428 1.1 kiyohara /* terminate link-establishment */
1429 1.1 kiyohara callout_stop(&sc->sc_le_timer);
1430 1.1 kiyohara bcsp_set_choke(sc, true);
1431 1.1 kiyohara MGETHDR(m, M_DONTWAIT, MT_DATA);
1432 1.1 kiyohara if (m == NULL)
1433 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1434 1.1 kiyohara else {
1435 1.1 kiyohara /* length of le packets is 4 */
1436 1.1 kiyohara m->m_pkthdr.len = m->m_len = 0;
1437 1.1 kiyohara m_copyback(m, 0, sizeof(sync), sync);
1438 1.1 kiyohara if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1439 1.1 kiyohara printf("%s: link-establishment terminations failed\n",
1440 1.4 plunky device_xname(sc->sc_dev));
1441 1.1 kiyohara }
1442 1.1 kiyohara }
1443 1.1 kiyohara
1444 1.1 kiyohara static void
1445 1.1 kiyohara bcsp_input_le(struct hci_unit *unit, struct mbuf *m)
1446 1.1 kiyohara {
1447 1.7 plunky struct bcsp_softc *sc = device_private(unit->hci_dev);
1448 1.1 kiyohara uint32_t *rcvpkt;
1449 1.1 kiyohara int i;
1450 1.1 kiyohara const uint8_t *rplypkt;
1451 1.1 kiyohara static struct {
1452 1.1 kiyohara const char *type;
1453 1.1 kiyohara const uint8_t *datap;
1454 1.1 kiyohara } pkt[] = {
1455 1.1 kiyohara { "sync", sync },
1456 1.1 kiyohara { "sync-resp", syncresp },
1457 1.1 kiyohara { "conf", conf },
1458 1.1 kiyohara { "conf-resp", confresp },
1459 1.1 kiyohara
1460 1.2 kiyohara { NULL, 0 }
1461 1.1 kiyohara };
1462 1.1 kiyohara
1463 1.1 kiyohara DPRINTFN(0, ("%s: le input: state %d, muzzled %d\n",
1464 1.4 plunky device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1465 1.1 kiyohara #ifdef BCSP_DEBUG
1466 1.1 kiyohara if (bcsp_debug == 1)
1467 1.1 kiyohara bcsp_packet_print(m);
1468 1.1 kiyohara #endif
1469 1.1 kiyohara
1470 1.1 kiyohara rcvpkt = mtod(m, uint32_t *);
1471 1.1 kiyohara
1472 1.1 kiyohara /* length of le packets is 4 */
1473 1.1 kiyohara if (m->m_len == sizeof(uint32_t))
1474 1.1 kiyohara for (i = 0; pkt[i].type != NULL; i++)
1475 1.1 kiyohara if (*(const uint32_t *)pkt[i].datap == *rcvpkt)
1476 1.1 kiyohara break;
1477 1.1 kiyohara if (m->m_len != sizeof(uint32_t) || pkt[i].type == NULL) {
1478 1.4 plunky printf("%s: received unknown packet\n", device_xname(sc->sc_dev));
1479 1.1 kiyohara m_freem(m);
1480 1.1 kiyohara return;
1481 1.1 kiyohara }
1482 1.1 kiyohara
1483 1.1 kiyohara rplypkt = NULL;
1484 1.1 kiyohara switch (sc->sc_le_state) {
1485 1.1 kiyohara case le_state_shy:
1486 1.1 kiyohara if (*rcvpkt == *(const uint32_t *)sync) {
1487 1.1 kiyohara sc->sc_le_muzzled = false;
1488 1.1 kiyohara rplypkt = syncresp;
1489 1.1 kiyohara } else if (*rcvpkt == *(const uint32_t *)syncresp) {
1490 1.1 kiyohara DPRINTF(("%s: state change to curious\n",
1491 1.4 plunky device_xname(sc->sc_dev)));
1492 1.1 kiyohara
1493 1.1 kiyohara rplypkt = conf;
1494 1.1 kiyohara callout_schedule(&sc->sc_le_timer,
1495 1.1 kiyohara BCSP_LE_TCONF_TIMEOUT);
1496 1.1 kiyohara sc->sc_le_state = le_state_curious;
1497 1.1 kiyohara } else
1498 1.1 kiyohara printf("%s: received an unknown packet at shy\n",
1499 1.4 plunky device_xname(sc->sc_dev));
1500 1.1 kiyohara break;
1501 1.1 kiyohara
1502 1.1 kiyohara case le_state_curious:
1503 1.1 kiyohara if (*rcvpkt == *(const uint32_t *)sync)
1504 1.1 kiyohara rplypkt = syncresp;
1505 1.1 kiyohara else if (*rcvpkt == *(const uint32_t *)conf)
1506 1.1 kiyohara rplypkt = confresp;
1507 1.1 kiyohara else if (*rcvpkt == *(const uint32_t *)confresp) {
1508 1.1 kiyohara DPRINTF(("%s: state change to garrulous:\n",
1509 1.4 plunky device_xname(sc->sc_dev)));
1510 1.1 kiyohara
1511 1.1 kiyohara bcsp_set_choke(sc, false);
1512 1.1 kiyohara callout_stop(&sc->sc_le_timer);
1513 1.1 kiyohara sc->sc_le_state = le_state_garrulous;
1514 1.1 kiyohara } else
1515 1.1 kiyohara printf("%s: received unknown packet at curious\n",
1516 1.4 plunky device_xname(sc->sc_dev));
1517 1.1 kiyohara break;
1518 1.1 kiyohara
1519 1.1 kiyohara case le_state_garrulous:
1520 1.1 kiyohara if (*rcvpkt == *(const uint32_t *)conf)
1521 1.1 kiyohara rplypkt = confresp;
1522 1.1 kiyohara else if (*rcvpkt == *(const uint32_t *)sync) {
1523 1.1 kiyohara /* XXXXX */
1524 1.1 kiyohara printf("%s: received sync!! peer to reset?\n",
1525 1.4 plunky device_xname(sc->sc_dev));
1526 1.1 kiyohara
1527 1.3 kiyohara bcsp_sequencing_reset(sc);
1528 1.3 kiyohara rplypkt = sync;
1529 1.1 kiyohara sc->sc_le_state = le_state_shy;
1530 1.1 kiyohara } else
1531 1.1 kiyohara printf("%s: received unknown packet at garrulous\n",
1532 1.4 plunky device_xname(sc->sc_dev));
1533 1.1 kiyohara break;
1534 1.1 kiyohara }
1535 1.1 kiyohara
1536 1.1 kiyohara m_freem(m);
1537 1.1 kiyohara
1538 1.1 kiyohara if (rplypkt != NULL) {
1539 1.1 kiyohara MGETHDR(m, M_DONTWAIT, MT_DATA);
1540 1.1 kiyohara if (m == NULL)
1541 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1542 1.1 kiyohara else {
1543 1.1 kiyohara /* length of le packets is 4 */
1544 1.1 kiyohara m->m_pkthdr.len = m->m_len = 0;
1545 1.1 kiyohara m_copyback(m, 0, 4, rplypkt);
1546 1.1 kiyohara if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1547 1.1 kiyohara printf("%s: le-packet transmit failed\n",
1548 1.4 plunky device_xname(sc->sc_dev));
1549 1.1 kiyohara }
1550 1.1 kiyohara }
1551 1.1 kiyohara }
1552 1.1 kiyohara
1553 1.1 kiyohara static void
1554 1.1 kiyohara bcsp_le_timeout(void *arg)
1555 1.1 kiyohara {
1556 1.1 kiyohara struct bcsp_softc *sc = arg;
1557 1.1 kiyohara struct mbuf *m;
1558 1.1 kiyohara int timeout;
1559 1.1 kiyohara const uint8_t *sndpkt = NULL;
1560 1.1 kiyohara
1561 1.1 kiyohara DPRINTFN(0, ("%s: le timeout: state %d, muzzled %d\n",
1562 1.4 plunky device_xname(sc->sc_dev), sc->sc_le_state, sc->sc_le_muzzled));
1563 1.1 kiyohara
1564 1.1 kiyohara switch (sc->sc_le_state) {
1565 1.1 kiyohara case le_state_shy:
1566 1.1 kiyohara if (!sc->sc_le_muzzled)
1567 1.1 kiyohara sndpkt = sync;
1568 1.1 kiyohara timeout = BCSP_LE_TSHY_TIMEOUT;
1569 1.1 kiyohara break;
1570 1.1 kiyohara
1571 1.1 kiyohara case le_state_curious:
1572 1.1 kiyohara sndpkt = conf;
1573 1.1 kiyohara timeout = BCSP_LE_TCONF_TIMEOUT;
1574 1.1 kiyohara break;
1575 1.1 kiyohara
1576 1.1 kiyohara default:
1577 1.1 kiyohara printf("%s: timeout happen at unknown state %d\n",
1578 1.4 plunky device_xname(sc->sc_dev), sc->sc_le_state);
1579 1.1 kiyohara return;
1580 1.1 kiyohara }
1581 1.1 kiyohara
1582 1.1 kiyohara if (sndpkt != NULL) {
1583 1.1 kiyohara MGETHDR(m, M_DONTWAIT, MT_DATA);
1584 1.1 kiyohara if (m == NULL)
1585 1.4 plunky printf("%s: out of memory\n", device_xname(sc->sc_dev));
1586 1.1 kiyohara else {
1587 1.1 kiyohara /* length of le packets is 4 */
1588 1.1 kiyohara m->m_pkthdr.len = m->m_len = 0;
1589 1.1 kiyohara m_copyback(m, 0, 4, sndpkt);
1590 1.1 kiyohara if (!bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_LE))
1591 1.1 kiyohara printf("%s: le-packet transmit failed\n",
1592 1.4 plunky device_xname(sc->sc_dev));
1593 1.1 kiyohara }
1594 1.1 kiyohara }
1595 1.1 kiyohara
1596 1.1 kiyohara callout_schedule(&sc->sc_le_timer, timeout);
1597 1.1 kiyohara }
1598 1.1 kiyohara
1599 1.1 kiyohara
1600 1.1 kiyohara /*
1601 1.1 kiyohara * BlueCore Serial Protocol functions.
1602 1.1 kiyohara */
1603 1.1 kiyohara static int
1604 1.7 plunky bcsp_enable(device_t self)
1605 1.1 kiyohara {
1606 1.7 plunky struct bcsp_softc *sc = device_private(self);
1607 1.7 plunky struct hci_unit *unit = &sc->sc_unit;
1608 1.1 kiyohara
1609 1.1 kiyohara if (unit->hci_flags & BTF_RUNNING)
1610 1.1 kiyohara return 0;
1611 1.1 kiyohara
1612 1.1 kiyohara unit->hci_flags |= BTF_RUNNING;
1613 1.1 kiyohara unit->hci_flags &= ~BTF_XMIT;
1614 1.1 kiyohara
1615 1.1 kiyohara return 0;
1616 1.1 kiyohara }
1617 1.1 kiyohara
1618 1.1 kiyohara static void
1619 1.7 plunky bcsp_disable(device_t self)
1620 1.1 kiyohara {
1621 1.7 plunky struct bcsp_softc *sc = device_private(self);
1622 1.7 plunky struct hci_unit *unit = &sc->sc_unit;
1623 1.1 kiyohara
1624 1.1 kiyohara if ((unit->hci_flags & BTF_RUNNING) == 0)
1625 1.1 kiyohara return;
1626 1.1 kiyohara
1627 1.1 kiyohara if (sc->sc_rxp) {
1628 1.1 kiyohara m_freem(sc->sc_rxp);
1629 1.1 kiyohara sc->sc_rxp = NULL;
1630 1.1 kiyohara }
1631 1.1 kiyohara
1632 1.1 kiyohara if (sc->sc_txp) {
1633 1.1 kiyohara m_freem(sc->sc_txp);
1634 1.1 kiyohara sc->sc_txp = NULL;
1635 1.1 kiyohara }
1636 1.1 kiyohara
1637 1.1 kiyohara unit->hci_flags &= ~BTF_RUNNING;
1638 1.1 kiyohara }
1639 1.1 kiyohara
1640 1.1 kiyohara static void
1641 1.7 plunky bcsp_start(device_t self)
1642 1.1 kiyohara {
1643 1.7 plunky struct bcsp_softc *sc = device_private(self);
1644 1.7 plunky struct hci_unit *unit = &sc->sc_unit;
1645 1.1 kiyohara struct mbuf *m;
1646 1.1 kiyohara
1647 1.2 kiyohara KASSERT((unit->hci_flags & BTF_XMIT) == 0);
1648 1.2 kiyohara KASSERT(sc->sc_txp == NULL);
1649 1.2 kiyohara
1650 1.1 kiyohara if (MBUFQ_FIRST(&unit->hci_acltxq)) {
1651 1.1 kiyohara MBUFQ_DEQUEUE(&unit->hci_acltxq, m);
1652 1.1 kiyohara unit->hci_stats.acl_tx++;
1653 1.1 kiyohara M_SETCTX(m, NULL);
1654 1.1 kiyohara m_adj(m, sizeof(uint8_t));
1655 1.2 kiyohara unit->hci_flags |= BTF_XMIT;
1656 1.1 kiyohara bcsp_tx_reliable_pkt(sc, m, BCSP_CHANNEL_HCI_ACL);
1657 1.1 kiyohara }
1658 1.1 kiyohara
1659 1.1 kiyohara if (MBUFQ_FIRST(&unit->hci_cmdq)) {
1660 1.1 kiyohara MBUFQ_DEQUEUE(&unit->hci_cmdq, m);
1661 1.1 kiyohara unit->hci_stats.cmd_tx++;
1662 1.1 kiyohara M_SETCTX(m, NULL);
1663 1.1 kiyohara m_adj(m, sizeof(uint8_t));
1664 1.2 kiyohara unit->hci_flags |= BTF_XMIT;
1665 1.1 kiyohara bcsp_tx_reliable_pkt(sc, m, BCSP_CHANNEL_HCI_CMDEVT);
1666 1.1 kiyohara }
1667 1.1 kiyohara
1668 1.1 kiyohara if (MBUFQ_FIRST(&unit->hci_scotxq)) {
1669 1.1 kiyohara MBUFQ_DEQUEUE(&unit->hci_scotxq, m);
1670 1.1 kiyohara unit->hci_stats.sco_tx++;
1671 1.1 kiyohara /* XXXX: We can transmit with reliable */
1672 1.1 kiyohara m_adj(m, sizeof(uint8_t));
1673 1.2 kiyohara unit->hci_flags |= BTF_XMIT;
1674 1.1 kiyohara bcsp_tx_unreliable_pkt(sc, m, BCSP_CHANNEL_HCI_SCO);
1675 1.1 kiyohara }
1676 1.1 kiyohara
1677 1.1 kiyohara return;
1678 1.1 kiyohara }
1679 1.1 kiyohara
1680 1.1 kiyohara
1681 1.1 kiyohara #ifdef BCSP_DEBUG
1682 1.1 kiyohara static void
1683 1.1 kiyohara bcsp_packet_print(struct mbuf *m)
1684 1.1 kiyohara {
1685 1.1 kiyohara int i;
1686 1.1 kiyohara uint8_t *p;
1687 1.1 kiyohara
1688 1.1 kiyohara for ( ; m != NULL; m = m->m_next) {
1689 1.1 kiyohara p = mtod(m, uint8_t *);
1690 1.1 kiyohara for (i = 0; i < m->m_len; i++) {
1691 1.1 kiyohara if (i % 16 == 0)
1692 1.1 kiyohara printf(" ");
1693 1.1 kiyohara printf(" %02x", *(p + i));
1694 1.1 kiyohara if (i % 16 == 15)
1695 1.1 kiyohara printf("\n");
1696 1.1 kiyohara }
1697 1.1 kiyohara printf("\n");
1698 1.1 kiyohara }
1699 1.1 kiyohara }
1700 1.1 kiyohara #endif
1701