blob: 7938062c1cc7a13daf1306baa659c6cf477782be [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/module.h>
26
27#include <linux/kernel.h>
28#include <linux/init.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/types.h>
30#include <linux/fcntl.h>
31#include <linux/interrupt.h>
32#include <linux/ptrace.h>
33#include <linux/poll.h>
34
35#include <linux/slab.h>
36#include <linux/tty.h>
37#include <linux/errno.h>
38#include <linux/string.h>
39#include <linux/signal.h>
40#include <linux/ioctl.h>
41#include <linux/skbuff.h>
Harvey Harrisonc5ec5142008-06-10 12:48:45 -070042#include <linux/bitrev.h>
43#include <asm/unaligned.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129/* ---- BCSP core ---- */
130
131static void bcsp_slip_msgdelim(struct sk_buff *skb)
132{
133 const char pkt_delim = 0xc0;
Marcel Holtmann0372a662005-10-28 19:20:45 +0200134
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 memcpy(skb_put(skb, 1), &pkt_delim, 1);
136}
137
138static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
139{
140 const char esc_c0[2] = { 0xdb, 0xdc };
141 const char esc_db[2] = { 0xdb, 0xdd };
142
143 switch (c) {
144 case 0xc0:
145 memcpy(skb_put(skb, 2), &esc_c0, 2);
146 break;
147 case 0xdb:
148 memcpy(skb_put(skb, 2), &esc_db, 2);
149 break;
150 default:
151 memcpy(skb_put(skb, 1), &c, 1);
152 }
153}
154
155static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
156{
157 struct bcsp_struct *bcsp = hu->priv;
158
159 if (skb->len > 0xFFF) {
160 BT_ERR("Packet too long");
161 kfree_skb(skb);
162 return 0;
163 }
164
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700165 switch (bt_cb(skb)->pkt_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 case HCI_ACLDATA_PKT:
167 case HCI_COMMAND_PKT:
168 skb_queue_tail(&bcsp->rel, skb);
169 break;
170
171 case HCI_SCODATA_PKT:
172 skb_queue_tail(&bcsp->unrel, skb);
173 break;
174
175 default:
176 BT_ERR("Unknown packet type");
177 kfree_skb(skb);
178 break;
179 }
180
181 return 0;
182}
183
184static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
185 int len, int pkt_type)
186{
187 struct sk_buff *nskb;
188 u8 hdr[4], chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200190 int rel, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
192 switch (pkt_type) {
193 case HCI_ACLDATA_PKT:
194 chan = 6; /* BCSP ACL channel */
195 rel = 1; /* reliable channel */
196 break;
197 case HCI_COMMAND_PKT:
198 chan = 5; /* BCSP cmd/evt channel */
199 rel = 1; /* reliable channel */
200 break;
201 case HCI_SCODATA_PKT:
202 chan = 7; /* BCSP SCO channel */
203 rel = 0; /* unreliable channel */
204 break;
205 case BCSP_LE_PKT:
206 chan = 1; /* BCSP LE channel */
207 rel = 0; /* unreliable channel */
208 break;
209 case BCSP_ACK_PKT:
210 chan = 0; /* BCSP internal channel */
211 rel = 0; /* unreliable channel */
212 break;
213 default:
214 BT_ERR("Unknown packet type");
215 return NULL;
216 }
217
218 if (hciextn && chan == 5) {
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700219 __le16 opcode = ((struct hci_command_hdr *)data)->opcode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200221 /* Vendor specific commands */
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700222 if (hci_opcode_ogf(__le16_to_cpu(opcode)) == 0x3f) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
224 if ((desc & 0xf0) == 0xc0) {
225 data += HCI_COMMAND_HDR_SIZE + 1;
226 len -= HCI_COMMAND_HDR_SIZE + 1;
227 chan = desc & 0x0f;
228 }
229 }
230 }
231
232 /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
233 (because bytes 0xc0 and 0xdb are escaped, worst case is
234 when the packet is all made of 0xc0 and 0xdb :) )
235 + 2 (0xc0 delimiters at start and end). */
236
237 nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
238 if (!nskb)
239 return NULL;
240
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700241 bt_cb(nskb)->pkt_type = pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
243 bcsp_slip_msgdelim(nskb);
244
245 hdr[0] = bcsp->rxseq_txack << 3;
246 bcsp->txack_req = 0;
247 BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
248
249 if (rel) {
250 hdr[0] |= 0x80 + bcsp->msgq_txseq;
251 BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
252 bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
253 }
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200254
255 if (bcsp->use_crc)
256 hdr[0] |= 0x40;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
258 hdr[1] = ((len << 4) & 0xff) | chan;
259 hdr[2] = len >> 4;
260 hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
261
262 /* Put BCSP header */
263 for (i = 0; i < 4; i++) {
264 bcsp_slip_one_byte(nskb, hdr[i]);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200265
266 if (bcsp->use_crc)
267 bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 }
269
270 /* Put payload */
271 for (i = 0; i < len; i++) {
272 bcsp_slip_one_byte(nskb, data[i]);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200273
274 if (bcsp->use_crc)
275 bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 }
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 /* Put CRC */
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200279 if (bcsp->use_crc) {
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700280 bcsp_txmsg_crc = bitrev16(bcsp_txmsg_crc);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200281 bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
282 bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
283 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284
285 bcsp_slip_msgdelim(nskb);
286 return nskb;
287}
288
289/* This is a rewrite of pkt_avail in ABCSP */
290static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
291{
292 struct bcsp_struct *bcsp = hu->priv;
293 unsigned long flags;
294 struct sk_buff *skb;
295
296 /* First of all, check for unreliable messages in the queue,
297 since they have priority */
298
299 if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700300 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 if (nskb) {
302 kfree_skb(skb);
303 return nskb;
304 } else {
305 skb_queue_head(&bcsp->unrel, skb);
306 BT_ERR("Could not dequeue pkt because alloc_skb failed");
307 }
308 }
309
310 /* Now, try to send a reliable pkt. We can only send a
311 reliable packet if the number of packets sent but not yet ack'ed
312 is < than the winsize */
313
Peter Zijlstraf89d75f2006-12-06 20:36:59 -0800314 spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315
316 if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700317 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 if (nskb) {
319 __skb_queue_tail(&bcsp->unack, skb);
320 mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
321 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
322 return nskb;
323 } else {
324 skb_queue_head(&bcsp->rel, skb);
325 BT_ERR("Could not dequeue pkt because alloc_skb failed");
326 }
327 }
328
329 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
330
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 /* We could not send a reliable packet, either because there are
332 none or because there are too many unack'ed pkts. Did we receive
333 any packets we have not acknowledged yet ? */
334
335 if (bcsp->txack_req) {
336 /* if so, craft an empty ACK pkt and send it on BCSP unreliable
337 channel 0 */
338 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
339 return nskb;
340 }
341
342 /* We have nothing to send */
343 return NULL;
344}
345
346static int bcsp_flush(struct hci_uart *hu)
347{
348 BT_DBG("hu %p", hu);
349 return 0;
350}
351
352/* Remove ack'ed packets */
353static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
354{
David S. Miller8fc53872008-09-21 22:44:08 -0700355 struct sk_buff *skb, *tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 int i, pkts_to_be_removed;
358 u8 seqno;
359
360 spin_lock_irqsave(&bcsp->unack.lock, flags);
361
David S. Miller8fc53872008-09-21 22:44:08 -0700362 pkts_to_be_removed = skb_queue_len(&bcsp->unack);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 seqno = bcsp->msgq_txseq;
364
365 while (pkts_to_be_removed) {
366 if (bcsp->rxack == seqno)
367 break;
368 pkts_to_be_removed--;
369 seqno = (seqno - 1) & 0x07;
370 }
371
372 if (bcsp->rxack != seqno)
373 BT_ERR("Peer acked invalid packet");
374
375 BT_DBG("Removing %u pkts out of %u, up to seqno %u",
David S. Miller8fc53872008-09-21 22:44:08 -0700376 pkts_to_be_removed, skb_queue_len(&bcsp->unack),
377 (seqno - 1) & 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
David S. Miller8fc53872008-09-21 22:44:08 -0700379 i = 0;
380 skb_queue_walk_safe(&bcsp->unack, skb, tmp) {
381 if (i++ >= pkts_to_be_removed)
382 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 __skb_unlink(skb, &bcsp->unack);
385 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200387
David S. Miller8fc53872008-09-21 22:44:08 -0700388 if (skb_queue_empty(&bcsp->unack))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 del_timer(&bcsp->tbcsp);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
392
393 if (i != pkts_to_be_removed)
394 BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
395}
396
397/* Handle BCSP link-establishment packets. When we
398 detect a "sync" packet, symptom that the BT module has reset,
399 we do nothing :) (yet) */
400static void bcsp_handle_le_pkt(struct hci_uart *hu)
401{
402 struct bcsp_struct *bcsp = hu->priv;
403 u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
404 u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
405 u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
406
407 /* spot "conf" pkts and reply with a "conf rsp" pkt */
408 if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
409 !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
410 struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
411
412 BT_DBG("Found a LE conf pkt");
413 if (!nskb)
414 return;
415 memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700416 bt_cb(nskb)->pkt_type = BCSP_LE_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418 skb_queue_head(&bcsp->unrel, nskb);
419 hci_uart_tx_wakeup(hu);
420 }
421 /* Spot "sync" pkts. If we find one...disaster! */
422 else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
423 !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
424 BT_ERR("Found a LE sync pkt, card has reset");
425 }
426}
427
428static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
429{
430 const u8 c0 = 0xc0, db = 0xdb;
431
432 switch (bcsp->rx_esc_state) {
433 case BCSP_ESCSTATE_NOESC:
434 switch (byte) {
435 case 0xdb:
436 bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
437 break;
438 default:
439 memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
440 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
441 bcsp->rx_state != BCSP_W4_CRC)
442 bcsp_crc_update(&bcsp->message_crc, byte);
443 bcsp->rx_count--;
444 }
445 break;
446
447 case BCSP_ESCSTATE_ESC:
448 switch (byte) {
449 case 0xdc:
450 memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
451 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
452 bcsp->rx_state != BCSP_W4_CRC)
453 bcsp_crc_update(&bcsp-> message_crc, 0xc0);
454 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
455 bcsp->rx_count--;
456 break;
457
458 case 0xdd:
459 memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
460 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
461 bcsp->rx_state != BCSP_W4_CRC)
462 bcsp_crc_update(&bcsp-> message_crc, 0xdb);
463 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
464 bcsp->rx_count--;
465 break;
466
467 default:
468 BT_ERR ("Invalid byte %02x after esc byte", byte);
469 kfree_skb(bcsp->rx_skb);
470 bcsp->rx_skb = NULL;
471 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
472 bcsp->rx_count = 0;
473 }
474 }
475}
476
Arjan van de Ven858119e2006-01-14 13:20:43 -0800477static void bcsp_complete_rx_pkt(struct hci_uart *hu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478{
479 struct bcsp_struct *bcsp = hu->priv;
480 int pass_up;
481
482 if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
483 BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
484 bcsp->rxseq_txack++;
485 bcsp->rxseq_txack %= 0x8;
486 bcsp->txack_req = 1;
487
488 /* If needed, transmit an ack pkt */
489 hci_uart_tx_wakeup(hu);
490 }
491
492 bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
493 BT_DBG("Request for pkt %u from card", bcsp->rxack);
494
495 bcsp_pkt_cull(bcsp);
496 if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
497 bcsp->rx_skb->data[0] & 0x80) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700498 bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 pass_up = 1;
500 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
501 bcsp->rx_skb->data[0] & 0x80) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700502 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 pass_up = 1;
504 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700505 bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 pass_up = 1;
507 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
508 !(bcsp->rx_skb->data[0] & 0x80)) {
509 bcsp_handle_le_pkt(hu);
510 pass_up = 0;
511 } else
512 pass_up = 0;
513
514 if (!pass_up) {
515 struct hci_event_hdr hdr;
516 u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
517
518 if (desc != 0 && desc != 1) {
519 if (hciextn) {
520 desc |= 0xc0;
521 skb_pull(bcsp->rx_skb, 4);
522 memcpy(skb_push(bcsp->rx_skb, 1), &desc, 1);
523
524 hdr.evt = 0xff;
525 hdr.plen = bcsp->rx_skb->len;
526 memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700527 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
529 hci_recv_frame(bcsp->rx_skb);
530 } else {
531 BT_ERR ("Packet for unknown channel (%u %s)",
532 bcsp->rx_skb->data[1] & 0x0f,
533 bcsp->rx_skb->data[0] & 0x80 ?
534 "reliable" : "unreliable");
535 kfree_skb(bcsp->rx_skb);
536 }
537 } else
538 kfree_skb(bcsp->rx_skb);
539 } else {
540 /* Pull out BCSP hdr */
541 skb_pull(bcsp->rx_skb, 4);
542
543 hci_recv_frame(bcsp->rx_skb);
544 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
547 bcsp->rx_skb = NULL;
548}
549
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700550static u16 bscp_get_crc(struct bcsp_struct *bcsp)
551{
552 return get_unaligned_be16(&bcsp->rx_skb->data[bcsp->rx_skb->len - 2]);
553}
554
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555/* Recv data */
556static int bcsp_recv(struct hci_uart *hu, void *data, int count)
557{
558 struct bcsp_struct *bcsp = hu->priv;
559 register unsigned char *ptr;
560
561 BT_DBG("hu %p count %d rx_state %d rx_count %ld",
562 hu, count, bcsp->rx_state, bcsp->rx_count);
563
564 ptr = data;
565 while (count) {
566 if (bcsp->rx_count) {
567 if (*ptr == 0xc0) {
568 BT_ERR("Short BCSP packet");
569 kfree_skb(bcsp->rx_skb);
570 bcsp->rx_state = BCSP_W4_PKT_START;
571 bcsp->rx_count = 0;
572 } else
573 bcsp_unslip_one_byte(bcsp, *ptr);
574
575 ptr++; count--;
576 continue;
577 }
578
579 switch (bcsp->rx_state) {
580 case BCSP_W4_BCSP_HDR:
581 if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
582 bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
583 BT_ERR("Error in BCSP hdr checksum");
584 kfree_skb(bcsp->rx_skb);
585 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
586 bcsp->rx_count = 0;
587 continue;
588 }
589 if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
590 && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
591 BT_ERR ("Out-of-order packet arrived, got %u expected %u",
592 bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
593
594 kfree_skb(bcsp->rx_skb);
595 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
596 bcsp->rx_count = 0;
597 continue;
598 }
599 bcsp->rx_state = BCSP_W4_DATA;
600 bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
601 (bcsp->rx_skb->data[2] << 4); /* May be 0 */
602 continue;
603
604 case BCSP_W4_DATA:
605 if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
606 bcsp->rx_state = BCSP_W4_CRC;
607 bcsp->rx_count = 2;
608 } else
609 bcsp_complete_rx_pkt(hu);
610 continue;
611
612 case BCSP_W4_CRC:
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700613 if (bitrev16(bcsp->message_crc) != bscp_get_crc(bcsp)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 BT_ERR ("Checksum failed: computed %04x received %04x",
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700615 bitrev16(bcsp->message_crc),
616 bscp_get_crc(bcsp));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
618 kfree_skb(bcsp->rx_skb);
619 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
620 bcsp->rx_count = 0;
621 continue;
622 }
623 skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
624 bcsp_complete_rx_pkt(hu);
625 continue;
626
627 case BCSP_W4_PKT_DELIMITER:
628 switch (*ptr) {
629 case 0xc0:
630 bcsp->rx_state = BCSP_W4_PKT_START;
631 break;
632 default:
633 /*BT_ERR("Ignoring byte %02x", *ptr);*/
634 break;
635 }
636 ptr++; count--;
637 break;
638
639 case BCSP_W4_PKT_START:
640 switch (*ptr) {
641 case 0xc0:
642 ptr++; count--;
643 break;
644
645 default:
646 bcsp->rx_state = BCSP_W4_BCSP_HDR;
647 bcsp->rx_count = 4;
648 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
649 BCSP_CRC_INIT(bcsp->message_crc);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 /* Do not increment ptr or decrement count
652 * Allocate packet. Max len of a BCSP pkt=
653 * 0xFFF (payload) +4 (header) +2 (crc) */
654
655 bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
656 if (!bcsp->rx_skb) {
657 BT_ERR("Can't allocate mem for new packet");
658 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
659 bcsp->rx_count = 0;
660 return 0;
661 }
662 bcsp->rx_skb->dev = (void *) hu->hdev;
663 break;
664 }
665 break;
666 }
667 }
668 return count;
669}
670
671 /* Arrange to retransmit all messages in the relq. */
672static void bcsp_timed_event(unsigned long arg)
673{
674 struct hci_uart *hu = (struct hci_uart *) arg;
675 struct bcsp_struct *bcsp = hu->priv;
676 struct sk_buff *skb;
677 unsigned long flags;
678
679 BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
680
Peter Zijlstraf89d75f2006-12-06 20:36:59 -0800681 spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682
683 while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
684 bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
685 skb_queue_head(&bcsp->rel, skb);
686 }
687
688 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
689
690 hci_uart_tx_wakeup(hu);
691}
692
693static int bcsp_open(struct hci_uart *hu)
694{
695 struct bcsp_struct *bcsp;
696
697 BT_DBG("hu %p", hu);
698
Deepak Saxena089b1db2005-11-07 01:01:26 -0800699 bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 if (!bcsp)
701 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702
703 hu->priv = bcsp;
704 skb_queue_head_init(&bcsp->unack);
705 skb_queue_head_init(&bcsp->rel);
706 skb_queue_head_init(&bcsp->unrel);
707
708 init_timer(&bcsp->tbcsp);
709 bcsp->tbcsp.function = bcsp_timed_event;
710 bcsp->tbcsp.data = (u_long) hu;
711
712 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
713
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200714 if (txcrc)
715 bcsp->use_crc = 1;
716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 return 0;
718}
719
720static int bcsp_close(struct hci_uart *hu)
721{
722 struct bcsp_struct *bcsp = hu->priv;
723 hu->priv = NULL;
724
725 BT_DBG("hu %p", hu);
726
727 skb_queue_purge(&bcsp->unack);
728 skb_queue_purge(&bcsp->rel);
729 skb_queue_purge(&bcsp->unrel);
730 del_timer(&bcsp->tbcsp);
731
732 kfree(bcsp);
733 return 0;
734}
735
736static struct hci_uart_proto bcsp = {
Marcel Holtmann0372a662005-10-28 19:20:45 +0200737 .id = HCI_UART_BCSP,
738 .open = bcsp_open,
739 .close = bcsp_close,
740 .enqueue = bcsp_enqueue,
741 .dequeue = bcsp_dequeue,
742 .recv = bcsp_recv,
743 .flush = bcsp_flush
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744};
745
746int bcsp_init(void)
747{
748 int err = hci_uart_register_proto(&bcsp);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200749
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 if (!err)
751 BT_INFO("HCI BCSP protocol initialized");
752 else
753 BT_ERR("HCI BCSP protocol registration failed");
754
755 return err;
756}
757
758int bcsp_deinit(void)
759{
760 return hci_uart_unregister_proto(&bcsp);
761}
762
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200763module_param(txcrc, bool, 0644);
764MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766module_param(hciextn, bool, 0644);
767MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");