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