blob: 7bd4ef90411542f6996596ae0f36d9a0880d22de [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Marcel Holtmann0372a662005-10-28 19:20:45 +02002 *
3 * Bluetooth HCI UART driver
4 *
5 * Copyright (C) 2002-2003 Fabrizio Gennari <fabrizio.gennari@philips.com>
6 * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
7 *
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 */
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/config.h>
26#include <linux/module.h>
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/sched.h>
31#include <linux/types.h>
32#include <linux/fcntl.h>
33#include <linux/interrupt.h>
34#include <linux/ptrace.h>
35#include <linux/poll.h>
36
37#include <linux/slab.h>
38#include <linux/tty.h>
39#include <linux/errno.h>
40#include <linux/string.h>
41#include <linux/signal.h>
42#include <linux/ioctl.h>
43#include <linux/skbuff.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
Marcel Holtmann0372a662005-10-28 19:20:45 +020047
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include "hci_uart.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50#ifndef CONFIG_BT_HCIUART_DEBUG
51#undef BT_DBG
52#define BT_DBG( A... )
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#endif
54
Marcel Holtmann0372a662005-10-28 19:20:45 +020055#define VERSION "0.3"
56
Marcel Holtmann20dd6f52005-10-28 19:20:40 +020057static int txcrc = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058static int hciextn = 1;
59
Marcel Holtmann0372a662005-10-28 19:20:45 +020060#define BCSP_TXWINSIZE 4
61
62#define BCSP_ACK_PKT 0x05
63#define BCSP_LE_PKT 0x06
64
65struct bcsp_struct {
66 struct sk_buff_head unack; /* Unack'ed packets queue */
67 struct sk_buff_head rel; /* Reliable packets queue */
68 struct sk_buff_head unrel; /* Unreliable packets queue */
69
70 unsigned long rx_count;
71 struct sk_buff *rx_skb;
72 u8 rxseq_txack; /* rxseq == txack. */
73 u8 rxack; /* Last packet sent by us that the peer ack'ed */
74 struct timer_list tbcsp;
75
76 enum {
77 BCSP_W4_PKT_DELIMITER,
78 BCSP_W4_PKT_START,
79 BCSP_W4_BCSP_HDR,
80 BCSP_W4_DATA,
81 BCSP_W4_CRC
82 } rx_state;
83
84 enum {
85 BCSP_ESCSTATE_NOESC,
86 BCSP_ESCSTATE_ESC
87 } rx_esc_state;
88
89 u8 use_crc;
90 u16 message_crc;
91 u8 txack_req; /* Do we need to send ack's to the peer? */
92
93 /* Reliable packet sequence number - used to assign seq to each rel pkt. */
94 u8 msgq_txseq;
95};
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097/* ---- BCSP CRC calculation ---- */
98
99/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
100initial value 0xffff, bits shifted in reverse order. */
101
102static const u16 crc_table[] = {
103 0x0000, 0x1081, 0x2102, 0x3183,
104 0x4204, 0x5285, 0x6306, 0x7387,
105 0x8408, 0x9489, 0xa50a, 0xb58b,
106 0xc60c, 0xd68d, 0xe70e, 0xf78f
107};
108
109/* Initialise the crc calculator */
110#define BCSP_CRC_INIT(x) x = 0xffff
111
112/*
113 Update crc with next data byte
114
115 Implementation note
116 The data byte is treated as two nibbles. The crc is generated
117 in reverse, i.e., bits are fed into the register from the top.
118*/
119static void bcsp_crc_update(u16 *crc, u8 d)
120{
121 u16 reg = *crc;
122
123 reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
124 reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
125
126 *crc = reg;
127}
128
129/*
130 Get reverse of generated crc
131
132 Implementation note
133 The crc generator (bcsp_crc_init() and bcsp_crc_update())
134 creates a reversed crc, so it needs to be swapped back before
135 being passed on.
136*/
137static u16 bcsp_crc_reverse(u16 crc)
138{
139 u16 b, rev;
140
141 for (b = 0, rev = 0; b < 16; b++) {
142 rev = rev << 1;
143 rev |= (crc & 1);
144 crc = crc >> 1;
145 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200146
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 return (rev);
148}
149
150/* ---- BCSP core ---- */
151
152static void bcsp_slip_msgdelim(struct sk_buff *skb)
153{
154 const char pkt_delim = 0xc0;
Marcel Holtmann0372a662005-10-28 19:20:45 +0200155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 memcpy(skb_put(skb, 1), &pkt_delim, 1);
157}
158
159static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
160{
161 const char esc_c0[2] = { 0xdb, 0xdc };
162 const char esc_db[2] = { 0xdb, 0xdd };
163
164 switch (c) {
165 case 0xc0:
166 memcpy(skb_put(skb, 2), &esc_c0, 2);
167 break;
168 case 0xdb:
169 memcpy(skb_put(skb, 2), &esc_db, 2);
170 break;
171 default:
172 memcpy(skb_put(skb, 1), &c, 1);
173 }
174}
175
176static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
177{
178 struct bcsp_struct *bcsp = hu->priv;
179
180 if (skb->len > 0xFFF) {
181 BT_ERR("Packet too long");
182 kfree_skb(skb);
183 return 0;
184 }
185
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700186 switch (bt_cb(skb)->pkt_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 case HCI_ACLDATA_PKT:
188 case HCI_COMMAND_PKT:
189 skb_queue_tail(&bcsp->rel, skb);
190 break;
191
192 case HCI_SCODATA_PKT:
193 skb_queue_tail(&bcsp->unrel, skb);
194 break;
195
196 default:
197 BT_ERR("Unknown packet type");
198 kfree_skb(skb);
199 break;
200 }
201
202 return 0;
203}
204
205static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
206 int len, int pkt_type)
207{
208 struct sk_buff *nskb;
209 u8 hdr[4], chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200211 int rel, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
213 switch (pkt_type) {
214 case HCI_ACLDATA_PKT:
215 chan = 6; /* BCSP ACL channel */
216 rel = 1; /* reliable channel */
217 break;
218 case HCI_COMMAND_PKT:
219 chan = 5; /* BCSP cmd/evt channel */
220 rel = 1; /* reliable channel */
221 break;
222 case HCI_SCODATA_PKT:
223 chan = 7; /* BCSP SCO channel */
224 rel = 0; /* unreliable channel */
225 break;
226 case BCSP_LE_PKT:
227 chan = 1; /* BCSP LE channel */
228 rel = 0; /* unreliable channel */
229 break;
230 case BCSP_ACK_PKT:
231 chan = 0; /* BCSP internal channel */
232 rel = 0; /* unreliable channel */
233 break;
234 default:
235 BT_ERR("Unknown packet type");
236 return NULL;
237 }
238
239 if (hciextn && chan == 5) {
240 struct hci_command_hdr *hdr = (struct hci_command_hdr *) data;
241
242 if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == OGF_VENDOR_CMD) {
243 u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
244 if ((desc & 0xf0) == 0xc0) {
245 data += HCI_COMMAND_HDR_SIZE + 1;
246 len -= HCI_COMMAND_HDR_SIZE + 1;
247 chan = desc & 0x0f;
248 }
249 }
250 }
251
252 /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
253 (because bytes 0xc0 and 0xdb are escaped, worst case is
254 when the packet is all made of 0xc0 and 0xdb :) )
255 + 2 (0xc0 delimiters at start and end). */
256
257 nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
258 if (!nskb)
259 return NULL;
260
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700261 bt_cb(nskb)->pkt_type = pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262
263 bcsp_slip_msgdelim(nskb);
264
265 hdr[0] = bcsp->rxseq_txack << 3;
266 bcsp->txack_req = 0;
267 BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
268
269 if (rel) {
270 hdr[0] |= 0x80 + bcsp->msgq_txseq;
271 BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
272 bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
273 }
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200274
275 if (bcsp->use_crc)
276 hdr[0] |= 0x40;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
278 hdr[1] = ((len << 4) & 0xff) | chan;
279 hdr[2] = len >> 4;
280 hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
281
282 /* Put BCSP header */
283 for (i = 0; i < 4; i++) {
284 bcsp_slip_one_byte(nskb, hdr[i]);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200285
286 if (bcsp->use_crc)
287 bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 }
289
290 /* Put payload */
291 for (i = 0; i < len; i++) {
292 bcsp_slip_one_byte(nskb, data[i]);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200293
294 if (bcsp->use_crc)
295 bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 }
297
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 /* Put CRC */
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200299 if (bcsp->use_crc) {
300 bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
301 bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
302 bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
303 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304
305 bcsp_slip_msgdelim(nskb);
306 return nskb;
307}
308
309/* This is a rewrite of pkt_avail in ABCSP */
310static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
311{
312 struct bcsp_struct *bcsp = hu->priv;
313 unsigned long flags;
314 struct sk_buff *skb;
315
316 /* First of all, check for unreliable messages in the queue,
317 since they have priority */
318
319 if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700320 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 if (nskb) {
322 kfree_skb(skb);
323 return nskb;
324 } else {
325 skb_queue_head(&bcsp->unrel, skb);
326 BT_ERR("Could not dequeue pkt because alloc_skb failed");
327 }
328 }
329
330 /* Now, try to send a reliable pkt. We can only send a
331 reliable packet if the number of packets sent but not yet ack'ed
332 is < than the winsize */
333
334 spin_lock_irqsave(&bcsp->unack.lock, flags);
335
336 if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700337 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 if (nskb) {
339 __skb_queue_tail(&bcsp->unack, skb);
340 mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
341 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
342 return nskb;
343 } else {
344 skb_queue_head(&bcsp->rel, skb);
345 BT_ERR("Could not dequeue pkt because alloc_skb failed");
346 }
347 }
348
349 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
350
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 /* We could not send a reliable packet, either because there are
352 none or because there are too many unack'ed pkts. Did we receive
353 any packets we have not acknowledged yet ? */
354
355 if (bcsp->txack_req) {
356 /* if so, craft an empty ACK pkt and send it on BCSP unreliable
357 channel 0 */
358 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
359 return nskb;
360 }
361
362 /* We have nothing to send */
363 return NULL;
364}
365
366static int bcsp_flush(struct hci_uart *hu)
367{
368 BT_DBG("hu %p", hu);
369 return 0;
370}
371
372/* Remove ack'ed packets */
373static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
374{
375 unsigned long flags;
376 struct sk_buff *skb;
377 int i, pkts_to_be_removed;
378 u8 seqno;
379
380 spin_lock_irqsave(&bcsp->unack.lock, flags);
381
382 pkts_to_be_removed = bcsp->unack.qlen;
383 seqno = bcsp->msgq_txseq;
384
385 while (pkts_to_be_removed) {
386 if (bcsp->rxack == seqno)
387 break;
388 pkts_to_be_removed--;
389 seqno = (seqno - 1) & 0x07;
390 }
391
392 if (bcsp->rxack != seqno)
393 BT_ERR("Peer acked invalid packet");
394
395 BT_DBG("Removing %u pkts out of %u, up to seqno %u",
Marcel Holtmann0372a662005-10-28 19:20:45 +0200396 pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
398 for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
399 && skb != (struct sk_buff *) &bcsp->unack; i++) {
400 struct sk_buff *nskb;
401
402 nskb = skb->next;
403 __skb_unlink(skb, &bcsp->unack);
404 kfree_skb(skb);
405 skb = nskb;
406 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 if (bcsp->unack.qlen == 0)
409 del_timer(&bcsp->tbcsp);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200410
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
412
413 if (i != pkts_to_be_removed)
414 BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
415}
416
417/* Handle BCSP link-establishment packets. When we
418 detect a "sync" packet, symptom that the BT module has reset,
419 we do nothing :) (yet) */
420static void bcsp_handle_le_pkt(struct hci_uart *hu)
421{
422 struct bcsp_struct *bcsp = hu->priv;
423 u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
424 u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
425 u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
426
427 /* spot "conf" pkts and reply with a "conf rsp" pkt */
428 if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
429 !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
430 struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
431
432 BT_DBG("Found a LE conf pkt");
433 if (!nskb)
434 return;
435 memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700436 bt_cb(nskb)->pkt_type = BCSP_LE_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437
438 skb_queue_head(&bcsp->unrel, nskb);
439 hci_uart_tx_wakeup(hu);
440 }
441 /* Spot "sync" pkts. If we find one...disaster! */
442 else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
443 !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
444 BT_ERR("Found a LE sync pkt, card has reset");
445 }
446}
447
448static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
449{
450 const u8 c0 = 0xc0, db = 0xdb;
451
452 switch (bcsp->rx_esc_state) {
453 case BCSP_ESCSTATE_NOESC:
454 switch (byte) {
455 case 0xdb:
456 bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
457 break;
458 default:
459 memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
460 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
461 bcsp->rx_state != BCSP_W4_CRC)
462 bcsp_crc_update(&bcsp->message_crc, byte);
463 bcsp->rx_count--;
464 }
465 break;
466
467 case BCSP_ESCSTATE_ESC:
468 switch (byte) {
469 case 0xdc:
470 memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
471 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
472 bcsp->rx_state != BCSP_W4_CRC)
473 bcsp_crc_update(&bcsp-> message_crc, 0xc0);
474 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
475 bcsp->rx_count--;
476 break;
477
478 case 0xdd:
479 memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
480 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
481 bcsp->rx_state != BCSP_W4_CRC)
482 bcsp_crc_update(&bcsp-> message_crc, 0xdb);
483 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
484 bcsp->rx_count--;
485 break;
486
487 default:
488 BT_ERR ("Invalid byte %02x after esc byte", byte);
489 kfree_skb(bcsp->rx_skb);
490 bcsp->rx_skb = NULL;
491 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
492 bcsp->rx_count = 0;
493 }
494 }
495}
496
Arjan van de Ven858119e2006-01-14 13:20:43 -0800497static void bcsp_complete_rx_pkt(struct hci_uart *hu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498{
499 struct bcsp_struct *bcsp = hu->priv;
500 int pass_up;
501
502 if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
503 BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
504 bcsp->rxseq_txack++;
505 bcsp->rxseq_txack %= 0x8;
506 bcsp->txack_req = 1;
507
508 /* If needed, transmit an ack pkt */
509 hci_uart_tx_wakeup(hu);
510 }
511
512 bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
513 BT_DBG("Request for pkt %u from card", bcsp->rxack);
514
515 bcsp_pkt_cull(bcsp);
516 if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
517 bcsp->rx_skb->data[0] & 0x80) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700518 bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 pass_up = 1;
520 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
521 bcsp->rx_skb->data[0] & 0x80) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700522 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 pass_up = 1;
524 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700525 bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 pass_up = 1;
527 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
528 !(bcsp->rx_skb->data[0] & 0x80)) {
529 bcsp_handle_le_pkt(hu);
530 pass_up = 0;
531 } else
532 pass_up = 0;
533
534 if (!pass_up) {
535 struct hci_event_hdr hdr;
536 u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
537
538 if (desc != 0 && desc != 1) {
539 if (hciextn) {
540 desc |= 0xc0;
541 skb_pull(bcsp->rx_skb, 4);
542 memcpy(skb_push(bcsp->rx_skb, 1), &desc, 1);
543
544 hdr.evt = 0xff;
545 hdr.plen = bcsp->rx_skb->len;
546 memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700547 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549 hci_recv_frame(bcsp->rx_skb);
550 } else {
551 BT_ERR ("Packet for unknown channel (%u %s)",
552 bcsp->rx_skb->data[1] & 0x0f,
553 bcsp->rx_skb->data[0] & 0x80 ?
554 "reliable" : "unreliable");
555 kfree_skb(bcsp->rx_skb);
556 }
557 } else
558 kfree_skb(bcsp->rx_skb);
559 } else {
560 /* Pull out BCSP hdr */
561 skb_pull(bcsp->rx_skb, 4);
562
563 hci_recv_frame(bcsp->rx_skb);
564 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
567 bcsp->rx_skb = NULL;
568}
569
570/* Recv data */
571static int bcsp_recv(struct hci_uart *hu, void *data, int count)
572{
573 struct bcsp_struct *bcsp = hu->priv;
574 register unsigned char *ptr;
575
576 BT_DBG("hu %p count %d rx_state %d rx_count %ld",
577 hu, count, bcsp->rx_state, bcsp->rx_count);
578
579 ptr = data;
580 while (count) {
581 if (bcsp->rx_count) {
582 if (*ptr == 0xc0) {
583 BT_ERR("Short BCSP packet");
584 kfree_skb(bcsp->rx_skb);
585 bcsp->rx_state = BCSP_W4_PKT_START;
586 bcsp->rx_count = 0;
587 } else
588 bcsp_unslip_one_byte(bcsp, *ptr);
589
590 ptr++; count--;
591 continue;
592 }
593
594 switch (bcsp->rx_state) {
595 case BCSP_W4_BCSP_HDR:
596 if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
597 bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
598 BT_ERR("Error in BCSP hdr checksum");
599 kfree_skb(bcsp->rx_skb);
600 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
601 bcsp->rx_count = 0;
602 continue;
603 }
604 if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
605 && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
606 BT_ERR ("Out-of-order packet arrived, got %u expected %u",
607 bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
608
609 kfree_skb(bcsp->rx_skb);
610 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
611 bcsp->rx_count = 0;
612 continue;
613 }
614 bcsp->rx_state = BCSP_W4_DATA;
615 bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
616 (bcsp->rx_skb->data[2] << 4); /* May be 0 */
617 continue;
618
619 case BCSP_W4_DATA:
620 if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
621 bcsp->rx_state = BCSP_W4_CRC;
622 bcsp->rx_count = 2;
623 } else
624 bcsp_complete_rx_pkt(hu);
625 continue;
626
627 case BCSP_W4_CRC:
628 if (bcsp_crc_reverse(bcsp->message_crc) !=
629 (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
630 bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
631
632 BT_ERR ("Checksum failed: computed %04x received %04x",
633 bcsp_crc_reverse(bcsp->message_crc),
Marcel Holtmann0372a662005-10-28 19:20:45 +0200634 (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
635 bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
637 kfree_skb(bcsp->rx_skb);
638 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
639 bcsp->rx_count = 0;
640 continue;
641 }
642 skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
643 bcsp_complete_rx_pkt(hu);
644 continue;
645
646 case BCSP_W4_PKT_DELIMITER:
647 switch (*ptr) {
648 case 0xc0:
649 bcsp->rx_state = BCSP_W4_PKT_START;
650 break;
651 default:
652 /*BT_ERR("Ignoring byte %02x", *ptr);*/
653 break;
654 }
655 ptr++; count--;
656 break;
657
658 case BCSP_W4_PKT_START:
659 switch (*ptr) {
660 case 0xc0:
661 ptr++; count--;
662 break;
663
664 default:
665 bcsp->rx_state = BCSP_W4_BCSP_HDR;
666 bcsp->rx_count = 4;
667 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
668 BCSP_CRC_INIT(bcsp->message_crc);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 /* Do not increment ptr or decrement count
671 * Allocate packet. Max len of a BCSP pkt=
672 * 0xFFF (payload) +4 (header) +2 (crc) */
673
674 bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
675 if (!bcsp->rx_skb) {
676 BT_ERR("Can't allocate mem for new packet");
677 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
678 bcsp->rx_count = 0;
679 return 0;
680 }
681 bcsp->rx_skb->dev = (void *) hu->hdev;
682 break;
683 }
684 break;
685 }
686 }
687 return count;
688}
689
690 /* Arrange to retransmit all messages in the relq. */
691static void bcsp_timed_event(unsigned long arg)
692{
693 struct hci_uart *hu = (struct hci_uart *) arg;
694 struct bcsp_struct *bcsp = hu->priv;
695 struct sk_buff *skb;
696 unsigned long flags;
697
698 BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
699
700 spin_lock_irqsave(&bcsp->unack.lock, flags);
701
702 while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
703 bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
704 skb_queue_head(&bcsp->rel, skb);
705 }
706
707 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
708
709 hci_uart_tx_wakeup(hu);
710}
711
712static int bcsp_open(struct hci_uart *hu)
713{
714 struct bcsp_struct *bcsp;
715
716 BT_DBG("hu %p", hu);
717
Deepak Saxena089b1db2005-11-07 01:01:26 -0800718 bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 if (!bcsp)
720 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 hu->priv = bcsp;
723 skb_queue_head_init(&bcsp->unack);
724 skb_queue_head_init(&bcsp->rel);
725 skb_queue_head_init(&bcsp->unrel);
726
727 init_timer(&bcsp->tbcsp);
728 bcsp->tbcsp.function = bcsp_timed_event;
729 bcsp->tbcsp.data = (u_long) hu;
730
731 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
732
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200733 if (txcrc)
734 bcsp->use_crc = 1;
735
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 return 0;
737}
738
739static int bcsp_close(struct hci_uart *hu)
740{
741 struct bcsp_struct *bcsp = hu->priv;
742 hu->priv = NULL;
743
744 BT_DBG("hu %p", hu);
745
746 skb_queue_purge(&bcsp->unack);
747 skb_queue_purge(&bcsp->rel);
748 skb_queue_purge(&bcsp->unrel);
749 del_timer(&bcsp->tbcsp);
750
751 kfree(bcsp);
752 return 0;
753}
754
755static struct hci_uart_proto bcsp = {
Marcel Holtmann0372a662005-10-28 19:20:45 +0200756 .id = HCI_UART_BCSP,
757 .open = bcsp_open,
758 .close = bcsp_close,
759 .enqueue = bcsp_enqueue,
760 .dequeue = bcsp_dequeue,
761 .recv = bcsp_recv,
762 .flush = bcsp_flush
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763};
764
765int bcsp_init(void)
766{
767 int err = hci_uart_register_proto(&bcsp);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200768
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 if (!err)
770 BT_INFO("HCI BCSP protocol initialized");
771 else
772 BT_ERR("HCI BCSP protocol registration failed");
773
774 return err;
775}
776
777int bcsp_deinit(void)
778{
779 return hci_uart_unregister_proto(&bcsp);
780}
781
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200782module_param(txcrc, bool, 0644);
783MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
784
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785module_param(hciextn, bool, 0644);
786MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");