blob: 894b2cb11ea6caf808ff55b6c3135d42e9ad33b5 [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
Marcel Holtmann0372a662005-10-28 19:20:45 +020050#define VERSION "0.3"
51
Marcel Holtmann20dd6f52005-10-28 19:20:40 +020052static int txcrc = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070053static int hciextn = 1;
54
Marcel Holtmann0372a662005-10-28 19:20:45 +020055#define BCSP_TXWINSIZE 4
56
57#define BCSP_ACK_PKT 0x05
58#define BCSP_LE_PKT 0x06
59
60struct bcsp_struct {
61 struct sk_buff_head unack; /* Unack'ed packets queue */
62 struct sk_buff_head rel; /* Reliable packets queue */
63 struct sk_buff_head unrel; /* Unreliable packets queue */
64
65 unsigned long rx_count;
66 struct sk_buff *rx_skb;
67 u8 rxseq_txack; /* rxseq == txack. */
68 u8 rxack; /* Last packet sent by us that the peer ack'ed */
69 struct timer_list tbcsp;
70
71 enum {
72 BCSP_W4_PKT_DELIMITER,
73 BCSP_W4_PKT_START,
74 BCSP_W4_BCSP_HDR,
75 BCSP_W4_DATA,
76 BCSP_W4_CRC
77 } rx_state;
78
79 enum {
80 BCSP_ESCSTATE_NOESC,
81 BCSP_ESCSTATE_ESC
82 } rx_esc_state;
83
84 u8 use_crc;
85 u16 message_crc;
86 u8 txack_req; /* Do we need to send ack's to the peer? */
87
88 /* Reliable packet sequence number - used to assign seq to each rel pkt. */
89 u8 msgq_txseq;
90};
91
Linus Torvalds1da177e2005-04-16 15:20:36 -070092/* ---- BCSP CRC calculation ---- */
93
94/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
95initial value 0xffff, bits shifted in reverse order. */
96
97static const u16 crc_table[] = {
98 0x0000, 0x1081, 0x2102, 0x3183,
99 0x4204, 0x5285, 0x6306, 0x7387,
100 0x8408, 0x9489, 0xa50a, 0xb58b,
101 0xc60c, 0xd68d, 0xe70e, 0xf78f
102};
103
104/* Initialise the crc calculator */
105#define BCSP_CRC_INIT(x) x = 0xffff
106
107/*
108 Update crc with next data byte
109
110 Implementation note
111 The data byte is treated as two nibbles. The crc is generated
112 in reverse, i.e., bits are fed into the register from the top.
113*/
114static void bcsp_crc_update(u16 *crc, u8 d)
115{
116 u16 reg = *crc;
117
118 reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
119 reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
120
121 *crc = reg;
122}
123
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124/* ---- BCSP core ---- */
125
126static void bcsp_slip_msgdelim(struct sk_buff *skb)
127{
128 const char pkt_delim = 0xc0;
Marcel Holtmann0372a662005-10-28 19:20:45 +0200129
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 memcpy(skb_put(skb, 1), &pkt_delim, 1);
131}
132
133static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
134{
135 const char esc_c0[2] = { 0xdb, 0xdc };
136 const char esc_db[2] = { 0xdb, 0xdd };
137
138 switch (c) {
139 case 0xc0:
140 memcpy(skb_put(skb, 2), &esc_c0, 2);
141 break;
142 case 0xdb:
143 memcpy(skb_put(skb, 2), &esc_db, 2);
144 break;
145 default:
146 memcpy(skb_put(skb, 1), &c, 1);
147 }
148}
149
150static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
151{
152 struct bcsp_struct *bcsp = hu->priv;
153
154 if (skb->len > 0xFFF) {
155 BT_ERR("Packet too long");
156 kfree_skb(skb);
157 return 0;
158 }
159
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700160 switch (bt_cb(skb)->pkt_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 case HCI_ACLDATA_PKT:
162 case HCI_COMMAND_PKT:
163 skb_queue_tail(&bcsp->rel, skb);
164 break;
165
166 case HCI_SCODATA_PKT:
167 skb_queue_tail(&bcsp->unrel, skb);
168 break;
169
170 default:
171 BT_ERR("Unknown packet type");
172 kfree_skb(skb);
173 break;
174 }
175
176 return 0;
177}
178
179static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
180 int len, int pkt_type)
181{
182 struct sk_buff *nskb;
183 u8 hdr[4], chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200185 int rel, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
187 switch (pkt_type) {
188 case HCI_ACLDATA_PKT:
189 chan = 6; /* BCSP ACL channel */
190 rel = 1; /* reliable channel */
191 break;
192 case HCI_COMMAND_PKT:
193 chan = 5; /* BCSP cmd/evt channel */
194 rel = 1; /* reliable channel */
195 break;
196 case HCI_SCODATA_PKT:
197 chan = 7; /* BCSP SCO channel */
198 rel = 0; /* unreliable channel */
199 break;
200 case BCSP_LE_PKT:
201 chan = 1; /* BCSP LE channel */
202 rel = 0; /* unreliable channel */
203 break;
204 case BCSP_ACK_PKT:
205 chan = 0; /* BCSP internal channel */
206 rel = 0; /* unreliable channel */
207 break;
208 default:
209 BT_ERR("Unknown packet type");
210 return NULL;
211 }
212
213 if (hciextn && chan == 5) {
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700214 __le16 opcode = ((struct hci_command_hdr *)data)->opcode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200216 /* Vendor specific commands */
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700217 if (hci_opcode_ogf(__le16_to_cpu(opcode)) == 0x3f) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
219 if ((desc & 0xf0) == 0xc0) {
220 data += HCI_COMMAND_HDR_SIZE + 1;
221 len -= HCI_COMMAND_HDR_SIZE + 1;
222 chan = desc & 0x0f;
223 }
224 }
225 }
226
227 /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
228 (because bytes 0xc0 and 0xdb are escaped, worst case is
229 when the packet is all made of 0xc0 and 0xdb :) )
230 + 2 (0xc0 delimiters at start and end). */
231
232 nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
233 if (!nskb)
234 return NULL;
235
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700236 bt_cb(nskb)->pkt_type = pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
238 bcsp_slip_msgdelim(nskb);
239
240 hdr[0] = bcsp->rxseq_txack << 3;
241 bcsp->txack_req = 0;
242 BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
243
244 if (rel) {
245 hdr[0] |= 0x80 + bcsp->msgq_txseq;
246 BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
247 bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
248 }
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200249
250 if (bcsp->use_crc)
251 hdr[0] |= 0x40;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
253 hdr[1] = ((len << 4) & 0xff) | chan;
254 hdr[2] = len >> 4;
255 hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
256
257 /* Put BCSP header */
258 for (i = 0; i < 4; i++) {
259 bcsp_slip_one_byte(nskb, hdr[i]);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200260
261 if (bcsp->use_crc)
262 bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 }
264
265 /* Put payload */
266 for (i = 0; i < len; i++) {
267 bcsp_slip_one_byte(nskb, data[i]);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200268
269 if (bcsp->use_crc)
270 bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 }
272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 /* Put CRC */
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200274 if (bcsp->use_crc) {
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700275 bcsp_txmsg_crc = bitrev16(bcsp_txmsg_crc);
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200276 bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
277 bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
278 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
280 bcsp_slip_msgdelim(nskb);
281 return nskb;
282}
283
284/* This is a rewrite of pkt_avail in ABCSP */
285static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
286{
287 struct bcsp_struct *bcsp = hu->priv;
288 unsigned long flags;
289 struct sk_buff *skb;
290
291 /* First of all, check for unreliable messages in the queue,
292 since they have priority */
293
294 if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700295 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 if (nskb) {
297 kfree_skb(skb);
298 return nskb;
299 } else {
300 skb_queue_head(&bcsp->unrel, skb);
301 BT_ERR("Could not dequeue pkt because alloc_skb failed");
302 }
303 }
304
305 /* Now, try to send a reliable pkt. We can only send a
306 reliable packet if the number of packets sent but not yet ack'ed
307 is < than the winsize */
308
Peter Zijlstraf89d75f2006-12-06 20:36:59 -0800309 spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
311 if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700312 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 if (nskb) {
314 __skb_queue_tail(&bcsp->unack, skb);
315 mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
316 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
317 return nskb;
318 } else {
319 skb_queue_head(&bcsp->rel, skb);
320 BT_ERR("Could not dequeue pkt because alloc_skb failed");
321 }
322 }
323
324 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 /* We could not send a reliable packet, either because there are
327 none or because there are too many unack'ed pkts. Did we receive
328 any packets we have not acknowledged yet ? */
329
330 if (bcsp->txack_req) {
331 /* if so, craft an empty ACK pkt and send it on BCSP unreliable
332 channel 0 */
333 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
334 return nskb;
335 }
336
337 /* We have nothing to send */
338 return NULL;
339}
340
341static int bcsp_flush(struct hci_uart *hu)
342{
343 BT_DBG("hu %p", hu);
344 return 0;
345}
346
347/* Remove ack'ed packets */
348static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
349{
David S. Miller8fc53872008-09-21 22:44:08 -0700350 struct sk_buff *skb, *tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 int i, pkts_to_be_removed;
353 u8 seqno;
354
355 spin_lock_irqsave(&bcsp->unack.lock, flags);
356
David S. Miller8fc53872008-09-21 22:44:08 -0700357 pkts_to_be_removed = skb_queue_len(&bcsp->unack);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 seqno = bcsp->msgq_txseq;
359
360 while (pkts_to_be_removed) {
361 if (bcsp->rxack == seqno)
362 break;
363 pkts_to_be_removed--;
364 seqno = (seqno - 1) & 0x07;
365 }
366
367 if (bcsp->rxack != seqno)
368 BT_ERR("Peer acked invalid packet");
369
370 BT_DBG("Removing %u pkts out of %u, up to seqno %u",
David S. Miller8fc53872008-09-21 22:44:08 -0700371 pkts_to_be_removed, skb_queue_len(&bcsp->unack),
372 (seqno - 1) & 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
David S. Miller8fc53872008-09-21 22:44:08 -0700374 i = 0;
375 skb_queue_walk_safe(&bcsp->unack, skb, tmp) {
376 if (i++ >= pkts_to_be_removed)
377 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 __skb_unlink(skb, &bcsp->unack);
380 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200382
David S. Miller8fc53872008-09-21 22:44:08 -0700383 if (skb_queue_empty(&bcsp->unack))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 del_timer(&bcsp->tbcsp);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
387
388 if (i != pkts_to_be_removed)
389 BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
390}
391
392/* Handle BCSP link-establishment packets. When we
393 detect a "sync" packet, symptom that the BT module has reset,
394 we do nothing :) (yet) */
395static void bcsp_handle_le_pkt(struct hci_uart *hu)
396{
397 struct bcsp_struct *bcsp = hu->priv;
398 u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
399 u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
400 u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
401
402 /* spot "conf" pkts and reply with a "conf rsp" pkt */
403 if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
404 !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
405 struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
406
407 BT_DBG("Found a LE conf pkt");
408 if (!nskb)
409 return;
410 memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700411 bt_cb(nskb)->pkt_type = BCSP_LE_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
413 skb_queue_head(&bcsp->unrel, nskb);
414 hci_uart_tx_wakeup(hu);
415 }
416 /* Spot "sync" pkts. If we find one...disaster! */
417 else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
418 !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
419 BT_ERR("Found a LE sync pkt, card has reset");
420 }
421}
422
423static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
424{
425 const u8 c0 = 0xc0, db = 0xdb;
426
427 switch (bcsp->rx_esc_state) {
428 case BCSP_ESCSTATE_NOESC:
429 switch (byte) {
430 case 0xdb:
431 bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
432 break;
433 default:
434 memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
435 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
436 bcsp->rx_state != BCSP_W4_CRC)
437 bcsp_crc_update(&bcsp->message_crc, byte);
438 bcsp->rx_count--;
439 }
440 break;
441
442 case BCSP_ESCSTATE_ESC:
443 switch (byte) {
444 case 0xdc:
445 memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
446 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
447 bcsp->rx_state != BCSP_W4_CRC)
448 bcsp_crc_update(&bcsp-> message_crc, 0xc0);
449 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
450 bcsp->rx_count--;
451 break;
452
453 case 0xdd:
454 memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
455 if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
456 bcsp->rx_state != BCSP_W4_CRC)
457 bcsp_crc_update(&bcsp-> message_crc, 0xdb);
458 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
459 bcsp->rx_count--;
460 break;
461
462 default:
463 BT_ERR ("Invalid byte %02x after esc byte", byte);
464 kfree_skb(bcsp->rx_skb);
465 bcsp->rx_skb = NULL;
466 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
467 bcsp->rx_count = 0;
468 }
469 }
470}
471
Arjan van de Ven858119e2006-01-14 13:20:43 -0800472static void bcsp_complete_rx_pkt(struct hci_uart *hu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473{
474 struct bcsp_struct *bcsp = hu->priv;
475 int pass_up;
476
477 if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
478 BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
479 bcsp->rxseq_txack++;
480 bcsp->rxseq_txack %= 0x8;
481 bcsp->txack_req = 1;
482
483 /* If needed, transmit an ack pkt */
484 hci_uart_tx_wakeup(hu);
485 }
486
487 bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
488 BT_DBG("Request for pkt %u from card", bcsp->rxack);
489
490 bcsp_pkt_cull(bcsp);
491 if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
492 bcsp->rx_skb->data[0] & 0x80) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700493 bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 pass_up = 1;
495 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
496 bcsp->rx_skb->data[0] & 0x80) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700497 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 pass_up = 1;
499 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700500 bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 pass_up = 1;
502 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
503 !(bcsp->rx_skb->data[0] & 0x80)) {
504 bcsp_handle_le_pkt(hu);
505 pass_up = 0;
506 } else
507 pass_up = 0;
508
509 if (!pass_up) {
510 struct hci_event_hdr hdr;
511 u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
512
513 if (desc != 0 && desc != 1) {
514 if (hciextn) {
515 desc |= 0xc0;
516 skb_pull(bcsp->rx_skb, 4);
517 memcpy(skb_push(bcsp->rx_skb, 1), &desc, 1);
518
519 hdr.evt = 0xff;
520 hdr.plen = bcsp->rx_skb->len;
521 memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
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
524 hci_recv_frame(bcsp->rx_skb);
525 } else {
526 BT_ERR ("Packet for unknown channel (%u %s)",
527 bcsp->rx_skb->data[1] & 0x0f,
528 bcsp->rx_skb->data[0] & 0x80 ?
529 "reliable" : "unreliable");
530 kfree_skb(bcsp->rx_skb);
531 }
532 } else
533 kfree_skb(bcsp->rx_skb);
534 } else {
535 /* Pull out BCSP hdr */
536 skb_pull(bcsp->rx_skb, 4);
537
538 hci_recv_frame(bcsp->rx_skb);
539 }
Marcel Holtmann0372a662005-10-28 19:20:45 +0200540
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
542 bcsp->rx_skb = NULL;
543}
544
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700545static u16 bscp_get_crc(struct bcsp_struct *bcsp)
546{
547 return get_unaligned_be16(&bcsp->rx_skb->data[bcsp->rx_skb->len - 2]);
548}
549
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550/* Recv data */
551static int bcsp_recv(struct hci_uart *hu, void *data, int count)
552{
553 struct bcsp_struct *bcsp = hu->priv;
554 register unsigned char *ptr;
555
556 BT_DBG("hu %p count %d rx_state %d rx_count %ld",
557 hu, count, bcsp->rx_state, bcsp->rx_count);
558
559 ptr = data;
560 while (count) {
561 if (bcsp->rx_count) {
562 if (*ptr == 0xc0) {
563 BT_ERR("Short BCSP packet");
564 kfree_skb(bcsp->rx_skb);
565 bcsp->rx_state = BCSP_W4_PKT_START;
566 bcsp->rx_count = 0;
567 } else
568 bcsp_unslip_one_byte(bcsp, *ptr);
569
570 ptr++; count--;
571 continue;
572 }
573
574 switch (bcsp->rx_state) {
575 case BCSP_W4_BCSP_HDR:
576 if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
577 bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
578 BT_ERR("Error in BCSP hdr checksum");
579 kfree_skb(bcsp->rx_skb);
580 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
581 bcsp->rx_count = 0;
582 continue;
583 }
584 if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
585 && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
586 BT_ERR ("Out-of-order packet arrived, got %u expected %u",
587 bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
588
589 kfree_skb(bcsp->rx_skb);
590 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
591 bcsp->rx_count = 0;
592 continue;
593 }
594 bcsp->rx_state = BCSP_W4_DATA;
595 bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
596 (bcsp->rx_skb->data[2] << 4); /* May be 0 */
597 continue;
598
599 case BCSP_W4_DATA:
600 if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
601 bcsp->rx_state = BCSP_W4_CRC;
602 bcsp->rx_count = 2;
603 } else
604 bcsp_complete_rx_pkt(hu);
605 continue;
606
607 case BCSP_W4_CRC:
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700608 if (bitrev16(bcsp->message_crc) != bscp_get_crc(bcsp)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 BT_ERR ("Checksum failed: computed %04x received %04x",
Harvey Harrisonc5ec5142008-06-10 12:48:45 -0700610 bitrev16(bcsp->message_crc),
611 bscp_get_crc(bcsp));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613 kfree_skb(bcsp->rx_skb);
614 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
615 bcsp->rx_count = 0;
616 continue;
617 }
618 skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
619 bcsp_complete_rx_pkt(hu);
620 continue;
621
622 case BCSP_W4_PKT_DELIMITER:
623 switch (*ptr) {
624 case 0xc0:
625 bcsp->rx_state = BCSP_W4_PKT_START;
626 break;
627 default:
628 /*BT_ERR("Ignoring byte %02x", *ptr);*/
629 break;
630 }
631 ptr++; count--;
632 break;
633
634 case BCSP_W4_PKT_START:
635 switch (*ptr) {
636 case 0xc0:
637 ptr++; count--;
638 break;
639
640 default:
641 bcsp->rx_state = BCSP_W4_BCSP_HDR;
642 bcsp->rx_count = 4;
643 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
644 BCSP_CRC_INIT(bcsp->message_crc);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 /* Do not increment ptr or decrement count
647 * Allocate packet. Max len of a BCSP pkt=
648 * 0xFFF (payload) +4 (header) +2 (crc) */
649
650 bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
651 if (!bcsp->rx_skb) {
652 BT_ERR("Can't allocate mem for new packet");
653 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
654 bcsp->rx_count = 0;
655 return 0;
656 }
657 bcsp->rx_skb->dev = (void *) hu->hdev;
658 break;
659 }
660 break;
661 }
662 }
663 return count;
664}
665
666 /* Arrange to retransmit all messages in the relq. */
667static void bcsp_timed_event(unsigned long arg)
668{
669 struct hci_uart *hu = (struct hci_uart *) arg;
670 struct bcsp_struct *bcsp = hu->priv;
671 struct sk_buff *skb;
672 unsigned long flags;
673
674 BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
675
Peter Zijlstraf89d75f2006-12-06 20:36:59 -0800676 spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
678 while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
679 bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
680 skb_queue_head(&bcsp->rel, skb);
681 }
682
683 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
684
685 hci_uart_tx_wakeup(hu);
686}
687
688static int bcsp_open(struct hci_uart *hu)
689{
690 struct bcsp_struct *bcsp;
691
692 BT_DBG("hu %p", hu);
693
Deepak Saxena089b1db2005-11-07 01:01:26 -0800694 bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 if (!bcsp)
696 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697
698 hu->priv = bcsp;
699 skb_queue_head_init(&bcsp->unack);
700 skb_queue_head_init(&bcsp->rel);
701 skb_queue_head_init(&bcsp->unrel);
702
703 init_timer(&bcsp->tbcsp);
704 bcsp->tbcsp.function = bcsp_timed_event;
705 bcsp->tbcsp.data = (u_long) hu;
706
707 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
708
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200709 if (txcrc)
710 bcsp->use_crc = 1;
711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 return 0;
713}
714
715static int bcsp_close(struct hci_uart *hu)
716{
717 struct bcsp_struct *bcsp = hu->priv;
718 hu->priv = NULL;
719
720 BT_DBG("hu %p", hu);
721
722 skb_queue_purge(&bcsp->unack);
723 skb_queue_purge(&bcsp->rel);
724 skb_queue_purge(&bcsp->unrel);
725 del_timer(&bcsp->tbcsp);
726
727 kfree(bcsp);
728 return 0;
729}
730
731static struct hci_uart_proto bcsp = {
Marcel Holtmann0372a662005-10-28 19:20:45 +0200732 .id = HCI_UART_BCSP,
733 .open = bcsp_open,
734 .close = bcsp_close,
735 .enqueue = bcsp_enqueue,
736 .dequeue = bcsp_dequeue,
737 .recv = bcsp_recv,
738 .flush = bcsp_flush
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739};
740
741int bcsp_init(void)
742{
743 int err = hci_uart_register_proto(&bcsp);
Marcel Holtmann0372a662005-10-28 19:20:45 +0200744
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 if (!err)
746 BT_INFO("HCI BCSP protocol initialized");
747 else
748 BT_ERR("HCI BCSP protocol registration failed");
749
750 return err;
751}
752
753int bcsp_deinit(void)
754{
755 return hci_uart_unregister_proto(&bcsp);
756}
757
Marcel Holtmann20dd6f52005-10-28 19:20:40 +0200758module_param(txcrc, bool, 0644);
759MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
760
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761module_param(hciextn, bool, 0644);
762MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");