aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_bcsp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/bluetooth/hci_bcsp.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/bluetooth/hci_bcsp.c')
-rw-r--r--drivers/bluetooth/hci_bcsp.c749
1 files changed, 749 insertions, 0 deletions
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
new file mode 100644
index 000000000000..c0ed213fc857
--- /dev/null
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -0,0 +1,749 @@
1/*
2 BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
3 Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
4
5 Based on
6 hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
7 ABCSP by Carl Orsborn <cjo@csr.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
17 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
22 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
24 SOFTWARE IS DISCLAIMED.
25*/
26
27/*
28 * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $
29 */
30
31#define VERSION "0.2"
32
33#include <linux/config.h>
34#include <linux/module.h>
35
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/sched.h>
39#include <linux/types.h>
40#include <linux/fcntl.h>
41#include <linux/interrupt.h>
42#include <linux/ptrace.h>
43#include <linux/poll.h>
44
45#include <linux/slab.h>
46#include <linux/tty.h>
47#include <linux/errno.h>
48#include <linux/string.h>
49#include <linux/signal.h>
50#include <linux/ioctl.h>
51#include <linux/skbuff.h>
52
53#include <net/bluetooth/bluetooth.h>
54#include <net/bluetooth/hci_core.h>
55#include "hci_uart.h"
56#include "hci_bcsp.h"
57
58#ifndef CONFIG_BT_HCIUART_DEBUG
59#undef BT_DBG
60#define BT_DBG( A... )
61#undef BT_DMP
62#define BT_DMP( A... )
63#endif
64
65static int hciextn = 1;
66
67/* ---- BCSP CRC calculation ---- */
68
69/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
70initial value 0xffff, bits shifted in reverse order. */
71
72static const u16 crc_table[] = {
73 0x0000, 0x1081, 0x2102, 0x3183,
74 0x4204, 0x5285, 0x6306, 0x7387,
75 0x8408, 0x9489, 0xa50a, 0xb58b,
76 0xc60c, 0xd68d, 0xe70e, 0xf78f
77};
78
79/* Initialise the crc calculator */
80#define BCSP_CRC_INIT(x) x = 0xffff
81
82/*
83 Update crc with next data byte
84
85 Implementation note
86 The data byte is treated as two nibbles. The crc is generated
87 in reverse, i.e., bits are fed into the register from the top.
88*/
89static void bcsp_crc_update(u16 *crc, u8 d)
90{
91 u16 reg = *crc;
92
93 reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
94 reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
95
96 *crc = reg;
97}
98
99/*
100 Get reverse of generated crc
101
102 Implementation note
103 The crc generator (bcsp_crc_init() and bcsp_crc_update())
104 creates a reversed crc, so it needs to be swapped back before
105 being passed on.
106*/
107static u16 bcsp_crc_reverse(u16 crc)
108{
109 u16 b, rev;
110
111 for (b = 0, rev = 0; b < 16; b++) {
112 rev = rev << 1;
113 rev |= (crc & 1);
114 crc = crc >> 1;
115 }
116 return (rev);
117}
118
119/* ---- BCSP core ---- */
120
121static void bcsp_slip_msgdelim(struct sk_buff *skb)
122{
123 const char pkt_delim = 0xc0;
124 memcpy(skb_put(skb, 1), &pkt_delim, 1);
125}
126
127static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
128{
129 const char esc_c0[2] = { 0xdb, 0xdc };
130 const char esc_db[2] = { 0xdb, 0xdd };
131
132 switch (c) {
133 case 0xc0:
134 memcpy(skb_put(skb, 2), &esc_c0, 2);
135 break;
136 case 0xdb:
137 memcpy(skb_put(skb, 2), &esc_db, 2);
138 break;
139 default:
140 memcpy(skb_put(skb, 1), &c, 1);
141 }
142}
143
144static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
145{
146 struct bcsp_struct *bcsp = hu->priv;
147
148 if (skb->len > 0xFFF) {
149 BT_ERR("Packet too long");
150 kfree_skb(skb);
151 return 0;
152 }
153
154 switch (skb->pkt_type) {
155 case HCI_ACLDATA_PKT:
156 case HCI_COMMAND_PKT:
157 skb_queue_tail(&bcsp->rel, skb);
158 break;
159
160 case HCI_SCODATA_PKT:
161 skb_queue_tail(&bcsp->unrel, skb);
162 break;
163
164 default:
165 BT_ERR("Unknown packet type");
166 kfree_skb(skb);
167 break;
168 }
169
170 return 0;
171}
172
173static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
174 int len, int pkt_type)
175{
176 struct sk_buff *nskb;
177 u8 hdr[4], chan;
178 int rel, i;
179
180#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
181 u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
182#endif
183
184 switch (pkt_type) {
185 case HCI_ACLDATA_PKT:
186 chan = 6; /* BCSP ACL channel */
187 rel = 1; /* reliable channel */
188 break;
189 case HCI_COMMAND_PKT:
190 chan = 5; /* BCSP cmd/evt channel */
191 rel = 1; /* reliable channel */
192 break;
193 case HCI_SCODATA_PKT:
194 chan = 7; /* BCSP SCO channel */
195 rel = 0; /* unreliable channel */
196 break;
197 case BCSP_LE_PKT:
198 chan = 1; /* BCSP LE channel */
199 rel = 0; /* unreliable channel */
200 break;
201 case BCSP_ACK_PKT:
202 chan = 0; /* BCSP internal channel */
203 rel = 0; /* unreliable channel */
204 break;
205 default:
206 BT_ERR("Unknown packet type");
207 return NULL;
208 }
209
210 if (hciextn && chan == 5) {
211 struct hci_command_hdr *hdr = (struct hci_command_hdr *) data;
212
213 if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == OGF_VENDOR_CMD) {
214 u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
215 if ((desc & 0xf0) == 0xc0) {
216 data += HCI_COMMAND_HDR_SIZE + 1;
217 len -= HCI_COMMAND_HDR_SIZE + 1;
218 chan = desc & 0x0f;
219 }
220 }
221 }
222
223 /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
224 (because bytes 0xc0 and 0xdb are escaped, worst case is
225 when the packet is all made of 0xc0 and 0xdb :) )
226 + 2 (0xc0 delimiters at start and end). */
227
228 nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
229 if (!nskb)
230 return NULL;
231
232 nskb->pkt_type = pkt_type;
233
234 bcsp_slip_msgdelim(nskb);
235
236 hdr[0] = bcsp->rxseq_txack << 3;
237 bcsp->txack_req = 0;
238 BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
239
240 if (rel) {
241 hdr[0] |= 0x80 + bcsp->msgq_txseq;
242 BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
243 bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
244 }
245#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
246 hdr[0] |= 0x40;
247#endif
248
249 hdr[1] = ((len << 4) & 0xff) | chan;
250 hdr[2] = len >> 4;
251 hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
252
253 /* Put BCSP header */
254 for (i = 0; i < 4; i++) {
255 bcsp_slip_one_byte(nskb, hdr[i]);
256#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
257 bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
258#endif
259 }
260
261 /* Put payload */
262 for (i = 0; i < len; i++) {
263 bcsp_slip_one_byte(nskb, data[i]);
264#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
265 bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
266#endif
267 }
268
269#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
270 /* Put CRC */
271 bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
272 bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
273 bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
274#endif
275
276 bcsp_slip_msgdelim(nskb);
277 return nskb;
278}
279
280/* This is a rewrite of pkt_avail in ABCSP */
281static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
282{
283 struct bcsp_struct *bcsp = hu->priv;
284 unsigned long flags;
285 struct sk_buff *skb;
286
287 /* First of all, check for unreliable messages in the queue,
288 since they have priority */
289
290 if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
291 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
292 if (nskb) {
293 kfree_skb(skb);
294 return nskb;
295 } else {
296 skb_queue_head(&bcsp->unrel, skb);
297 BT_ERR("Could not dequeue pkt because alloc_skb failed");
298 }
299 }
300
301 /* Now, try to send a reliable pkt. We can only send a
302 reliable packet if the number of packets sent but not yet ack'ed
303 is < than the winsize */
304
305 spin_lock_irqsave(&bcsp->unack.lock, flags);
306
307 if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
308 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
309 if (nskb) {
310 __skb_queue_tail(&bcsp->unack, skb);
311 mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
312 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
313 return nskb;
314 } else {
315 skb_queue_head(&bcsp->rel, skb);
316 BT_ERR("Could not dequeue pkt because alloc_skb failed");
317 }
318 }
319
320 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
321
322
323 /* We could not send a reliable packet, either because there are
324 none or because there are too many unack'ed pkts. Did we receive
325 any packets we have not acknowledged yet ? */
326
327 if (bcsp->txack_req) {
328 /* if so, craft an empty ACK pkt and send it on BCSP unreliable
329 channel 0 */
330 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
331 return nskb;
332 }
333
334 /* We have nothing to send */
335 return NULL;
336}
337
338static int bcsp_flush(struct hci_uart *hu)
339{
340 BT_DBG("hu %p", hu);
341 return 0;
342}
343
344/* Remove ack'ed packets */
345static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
346{
347 unsigned long flags;
348 struct sk_buff *skb;
349 int i, pkts_to_be_removed;
350 u8 seqno;
351
352 spin_lock_irqsave(&bcsp->unack.lock, flags);
353
354 pkts_to_be_removed = bcsp->unack.qlen;
355 seqno = bcsp->msgq_txseq;
356
357 while (pkts_to_be_removed) {
358 if (bcsp->rxack == seqno)
359 break;
360 pkts_to_be_removed--;
361 seqno = (seqno - 1) & 0x07;
362 }
363
364 if (bcsp->rxack != seqno)
365 BT_ERR("Peer acked invalid packet");
366
367 BT_DBG("Removing %u pkts out of %u, up to seqno %u",
368 pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
369
370 for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
371 && skb != (struct sk_buff *) &bcsp->unack; i++) {
372 struct sk_buff *nskb;
373
374 nskb = skb->next;
375 __skb_unlink(skb, &bcsp->unack);
376 kfree_skb(skb);
377 skb = nskb;
378 }
379 if (bcsp->unack.qlen == 0)
380 del_timer(&bcsp->tbcsp);
381 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
382
383 if (i != pkts_to_be_removed)
384 BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
385}
386
387/* Handle BCSP link-establishment packets. When we
388 detect a "sync" packet, symptom that the BT module has reset,
389 we do nothing :) (yet) */
390static void bcsp_handle_le_pkt(struct hci_uart *hu)
391{
392 struct bcsp_struct *bcsp = hu->priv;
393 u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
394 u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
395 u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
396
397 /* spot "conf" pkts and reply with a "conf rsp" pkt */
398 if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
399 !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
400 struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
401
402 BT_DBG("Found a LE conf pkt");
403 if (!nskb)
404 return;
405 memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
406 nskb->pkt_type = BCSP_LE_PKT;
407
408 skb_queue_head(&bcsp->unrel, nskb);
409 hci_uart_tx_wakeup(hu);
410 }
411 /* Spot "sync" pkts. If we find one...disaster! */
412 else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
413 !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
414 BT_ERR("Found a LE sync pkt, card has reset");
415 }
416}
417
418static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
419{
420 const u8 c0 = 0xc0, db = 0xdb;
421
422 switch (bcsp->rx_esc_state) {
423 case BCSP_ESCSTATE_NOESC:
424 switch (byte) {
425 case 0xdb:
426 bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
427 break;
428 default:
429 memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
430 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
431 bcsp->rx_state != BCSP_W4_CRC)
432 bcsp_crc_update(&bcsp->message_crc, byte);
433 bcsp->rx_count--;
434 }
435 break;
436
437 case BCSP_ESCSTATE_ESC:
438 switch (byte) {
439 case 0xdc:
440 memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
441 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
442 bcsp->rx_state != BCSP_W4_CRC)
443 bcsp_crc_update(&bcsp-> message_crc, 0xc0);
444 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
445 bcsp->rx_count--;
446 break;
447
448 case 0xdd:
449 memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
450 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
451 bcsp->rx_state != BCSP_W4_CRC)
452 bcsp_crc_update(&bcsp-> message_crc, 0xdb);
453 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
454 bcsp->rx_count--;
455 break;
456
457 default:
458 BT_ERR ("Invalid byte %02x after esc byte", byte);
459 kfree_skb(bcsp->rx_skb);
460 bcsp->rx_skb = NULL;
461 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
462 bcsp->rx_count = 0;
463 }
464 }
465}
466
467static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
468{
469 struct bcsp_struct *bcsp = hu->priv;
470 int pass_up;
471
472 if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
473 BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
474 bcsp->rxseq_txack++;
475 bcsp->rxseq_txack %= 0x8;
476 bcsp->txack_req = 1;
477
478 /* If needed, transmit an ack pkt */
479 hci_uart_tx_wakeup(hu);
480 }
481
482 bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
483 BT_DBG("Request for pkt %u from card", bcsp->rxack);
484
485 bcsp_pkt_cull(bcsp);
486 if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
487 bcsp->rx_skb->data[0] & 0x80) {
488 bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
489 pass_up = 1;
490 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
491 bcsp->rx_skb->data[0] & 0x80) {
492 bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
493 pass_up = 1;
494 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
495 bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
496 pass_up = 1;
497 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
498 !(bcsp->rx_skb->data[0] & 0x80)) {
499 bcsp_handle_le_pkt(hu);
500 pass_up = 0;
501 } else
502 pass_up = 0;
503
504 if (!pass_up) {
505 struct hci_event_hdr hdr;
506 u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
507
508 if (desc != 0 && desc != 1) {
509 if (hciextn) {
510 desc |= 0xc0;
511 skb_pull(bcsp->rx_skb, 4);
512 memcpy(skb_push(bcsp->rx_skb, 1), &desc, 1);
513
514 hdr.evt = 0xff;
515 hdr.plen = bcsp->rx_skb->len;
516 memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
517 bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
518
519 hci_recv_frame(bcsp->rx_skb);
520 } else {
521 BT_ERR ("Packet for unknown channel (%u %s)",
522 bcsp->rx_skb->data[1] & 0x0f,
523 bcsp->rx_skb->data[0] & 0x80 ?
524 "reliable" : "unreliable");
525 kfree_skb(bcsp->rx_skb);
526 }
527 } else
528 kfree_skb(bcsp->rx_skb);
529 } else {
530 /* Pull out BCSP hdr */
531 skb_pull(bcsp->rx_skb, 4);
532
533 hci_recv_frame(bcsp->rx_skb);
534 }
535 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
536 bcsp->rx_skb = NULL;
537}
538
539/* Recv data */
540static int bcsp_recv(struct hci_uart *hu, void *data, int count)
541{
542 struct bcsp_struct *bcsp = hu->priv;
543 register unsigned char *ptr;
544
545 BT_DBG("hu %p count %d rx_state %d rx_count %ld",
546 hu, count, bcsp->rx_state, bcsp->rx_count);
547
548 ptr = data;
549 while (count) {
550 if (bcsp->rx_count) {
551 if (*ptr == 0xc0) {
552 BT_ERR("Short BCSP packet");
553 kfree_skb(bcsp->rx_skb);
554 bcsp->rx_state = BCSP_W4_PKT_START;
555 bcsp->rx_count = 0;
556 } else
557 bcsp_unslip_one_byte(bcsp, *ptr);
558
559 ptr++; count--;
560 continue;
561 }
562
563 switch (bcsp->rx_state) {
564 case BCSP_W4_BCSP_HDR:
565 if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
566 bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
567 BT_ERR("Error in BCSP hdr checksum");
568 kfree_skb(bcsp->rx_skb);
569 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
570 bcsp->rx_count = 0;
571 continue;
572 }
573 if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
574 && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
575 BT_ERR ("Out-of-order packet arrived, got %u expected %u",
576 bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
577
578 kfree_skb(bcsp->rx_skb);
579 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
580 bcsp->rx_count = 0;
581 continue;
582 }
583 bcsp->rx_state = BCSP_W4_DATA;
584 bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
585 (bcsp->rx_skb->data[2] << 4); /* May be 0 */
586 continue;
587
588 case BCSP_W4_DATA:
589 if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
590 bcsp->rx_state = BCSP_W4_CRC;
591 bcsp->rx_count = 2;
592 } else
593 bcsp_complete_rx_pkt(hu);
594 continue;
595
596 case BCSP_W4_CRC:
597 if (bcsp_crc_reverse(bcsp->message_crc) !=
598 (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
599 bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
600
601 BT_ERR ("Checksum failed: computed %04x received %04x",
602 bcsp_crc_reverse(bcsp->message_crc),
603 (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
604 bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
605
606 kfree_skb(bcsp->rx_skb);
607 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
608 bcsp->rx_count = 0;
609 continue;
610 }
611 skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
612 bcsp_complete_rx_pkt(hu);
613 continue;
614
615 case BCSP_W4_PKT_DELIMITER:
616 switch (*ptr) {
617 case 0xc0:
618 bcsp->rx_state = BCSP_W4_PKT_START;
619 break;
620 default:
621 /*BT_ERR("Ignoring byte %02x", *ptr);*/
622 break;
623 }
624 ptr++; count--;
625 break;
626
627 case BCSP_W4_PKT_START:
628 switch (*ptr) {
629 case 0xc0:
630 ptr++; count--;
631 break;
632
633 default:
634 bcsp->rx_state = BCSP_W4_BCSP_HDR;
635 bcsp->rx_count = 4;
636 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
637 BCSP_CRC_INIT(bcsp->message_crc);
638
639 /* Do not increment ptr or decrement count
640 * Allocate packet. Max len of a BCSP pkt=
641 * 0xFFF (payload) +4 (header) +2 (crc) */
642
643 bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
644 if (!bcsp->rx_skb) {
645 BT_ERR("Can't allocate mem for new packet");
646 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
647 bcsp->rx_count = 0;
648 return 0;
649 }
650 bcsp->rx_skb->dev = (void *) hu->hdev;
651 break;
652 }
653 break;
654 }
655 }
656 return count;
657}
658
659 /* Arrange to retransmit all messages in the relq. */
660static void bcsp_timed_event(unsigned long arg)
661{
662 struct hci_uart *hu = (struct hci_uart *) arg;
663 struct bcsp_struct *bcsp = hu->priv;
664 struct sk_buff *skb;
665 unsigned long flags;
666
667 BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
668
669 spin_lock_irqsave(&bcsp->unack.lock, flags);
670
671 while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
672 bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
673 skb_queue_head(&bcsp->rel, skb);
674 }
675
676 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
677
678 hci_uart_tx_wakeup(hu);
679}
680
681static int bcsp_open(struct hci_uart *hu)
682{
683 struct bcsp_struct *bcsp;
684
685 BT_DBG("hu %p", hu);
686
687 bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
688 if (!bcsp)
689 return -ENOMEM;
690 memset(bcsp, 0, sizeof(*bcsp));
691
692 hu->priv = bcsp;
693 skb_queue_head_init(&bcsp->unack);
694 skb_queue_head_init(&bcsp->rel);
695 skb_queue_head_init(&bcsp->unrel);
696
697 init_timer(&bcsp->tbcsp);
698 bcsp->tbcsp.function = bcsp_timed_event;
699 bcsp->tbcsp.data = (u_long) hu;
700
701 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
702
703 return 0;
704}
705
706static int bcsp_close(struct hci_uart *hu)
707{
708 struct bcsp_struct *bcsp = hu->priv;
709 hu->priv = NULL;
710
711 BT_DBG("hu %p", hu);
712
713 skb_queue_purge(&bcsp->unack);
714 skb_queue_purge(&bcsp->rel);
715 skb_queue_purge(&bcsp->unrel);
716 del_timer(&bcsp->tbcsp);
717
718 kfree(bcsp);
719 return 0;
720}
721
722static struct hci_uart_proto bcsp = {
723 .id = HCI_UART_BCSP,
724 .open = bcsp_open,
725 .close = bcsp_close,
726 .enqueue = bcsp_enqueue,
727 .dequeue = bcsp_dequeue,
728 .recv = bcsp_recv,
729 .flush = bcsp_flush
730};
731
732int bcsp_init(void)
733{
734 int err = hci_uart_register_proto(&bcsp);
735 if (!err)
736 BT_INFO("HCI BCSP protocol initialized");
737 else
738 BT_ERR("HCI BCSP protocol registration failed");
739
740 return err;
741}
742
743int bcsp_deinit(void)
744{
745 return hci_uart_unregister_proto(&bcsp);
746}
747
748module_param(hciextn, bool, 0644);
749MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");