aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_bcsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/hci_bcsp.c')
-rw-r--r--drivers/bluetooth/hci_bcsp.c160
1 files changed, 100 insertions, 60 deletions
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0ee324e1265d..0a4761415ac3 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -1,35 +1,27 @@
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/* 1/*
28 * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $ 2 *
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 *
29 */ 23 */
30 24
31#define VERSION "0.2"
32
33#include <linux/config.h> 25#include <linux/config.h>
34#include <linux/module.h> 26#include <linux/module.h>
35 27
@@ -52,16 +44,56 @@
52 44
53#include <net/bluetooth/bluetooth.h> 45#include <net/bluetooth/bluetooth.h>
54#include <net/bluetooth/hci_core.h> 46#include <net/bluetooth/hci_core.h>
47
55#include "hci_uart.h" 48#include "hci_uart.h"
56#include "hci_bcsp.h"
57 49
58#ifndef CONFIG_BT_HCIUART_DEBUG 50#ifndef CONFIG_BT_HCIUART_DEBUG
59#undef BT_DBG 51#undef BT_DBG
60#define BT_DBG( A... ) 52#define BT_DBG( A... )
61#endif 53#endif
62 54
55#define VERSION "0.3"
56
57static int txcrc = 1;
63static int hciextn = 1; 58static int hciextn = 1;
64 59
60#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
65/* ---- BCSP CRC calculation ---- */ 97/* ---- BCSP CRC calculation ---- */
66 98
67/* Table for calculating CRC for polynomial 0x1021, LSB processed first, 99/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
@@ -111,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc)
111 rev |= (crc & 1); 143 rev |= (crc & 1);
112 crc = crc >> 1; 144 crc = crc >> 1;
113 } 145 }
146
114 return (rev); 147 return (rev);
115} 148}
116 149
@@ -119,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc)
119static void bcsp_slip_msgdelim(struct sk_buff *skb) 152static void bcsp_slip_msgdelim(struct sk_buff *skb)
120{ 153{
121 const char pkt_delim = 0xc0; 154 const char pkt_delim = 0xc0;
155
122 memcpy(skb_put(skb, 1), &pkt_delim, 1); 156 memcpy(skb_put(skb, 1), &pkt_delim, 1);
123} 157}
124 158
@@ -173,11 +207,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
173{ 207{
174 struct sk_buff *nskb; 208 struct sk_buff *nskb;
175 u8 hdr[4], chan; 209 u8 hdr[4], chan;
176 int rel, i;
177
178#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
179 u16 BCSP_CRC_INIT(bcsp_txmsg_crc); 210 u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
180#endif 211 int rel, i;
181 212
182 switch (pkt_type) { 213 switch (pkt_type) {
183 case HCI_ACLDATA_PKT: 214 case HCI_ACLDATA_PKT:
@@ -240,9 +271,9 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
240 BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq); 271 BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
241 bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07; 272 bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
242 } 273 }
243#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC 274
244 hdr[0] |= 0x40; 275 if (bcsp->use_crc)
245#endif 276 hdr[0] |= 0x40;
246 277
247 hdr[1] = ((len << 4) & 0xff) | chan; 278 hdr[1] = ((len << 4) & 0xff) | chan;
248 hdr[2] = len >> 4; 279 hdr[2] = len >> 4;
@@ -251,25 +282,25 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
251 /* Put BCSP header */ 282 /* Put BCSP header */
252 for (i = 0; i < 4; i++) { 283 for (i = 0; i < 4; i++) {
253 bcsp_slip_one_byte(nskb, hdr[i]); 284 bcsp_slip_one_byte(nskb, hdr[i]);
254#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC 285
255 bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]); 286 if (bcsp->use_crc)
256#endif 287 bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
257 } 288 }
258 289
259 /* Put payload */ 290 /* Put payload */
260 for (i = 0; i < len; i++) { 291 for (i = 0; i < len; i++) {
261 bcsp_slip_one_byte(nskb, data[i]); 292 bcsp_slip_one_byte(nskb, data[i]);
262#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC 293
263 bcsp_crc_update(&bcsp_txmsg_crc, data[i]); 294 if (bcsp->use_crc)
264#endif 295 bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
265 } 296 }
266 297
267#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
268 /* Put CRC */ 298 /* Put CRC */
269 bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc); 299 if (bcsp->use_crc) {
270 bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff)); 300 bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
271 bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff)); 301 bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
272#endif 302 bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
303 }
273 304
274 bcsp_slip_msgdelim(nskb); 305 bcsp_slip_msgdelim(nskb);
275 return nskb; 306 return nskb;
@@ -317,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
317 348
318 spin_unlock_irqrestore(&bcsp->unack.lock, flags); 349 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
319 350
320
321 /* We could not send a reliable packet, either because there are 351 /* We could not send a reliable packet, either because there are
322 none or because there are too many unack'ed pkts. Did we receive 352 none or because there are too many unack'ed pkts. Did we receive
323 any packets we have not acknowledged yet ? */ 353 any packets we have not acknowledged yet ? */
@@ -363,7 +393,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
363 BT_ERR("Peer acked invalid packet"); 393 BT_ERR("Peer acked invalid packet");
364 394
365 BT_DBG("Removing %u pkts out of %u, up to seqno %u", 395 BT_DBG("Removing %u pkts out of %u, up to seqno %u",
366 pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); 396 pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
367 397
368 for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed 398 for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
369 && skb != (struct sk_buff *) &bcsp->unack; i++) { 399 && skb != (struct sk_buff *) &bcsp->unack; i++) {
@@ -374,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
374 kfree_skb(skb); 404 kfree_skb(skb);
375 skb = nskb; 405 skb = nskb;
376 } 406 }
407
377 if (bcsp->unack.qlen == 0) 408 if (bcsp->unack.qlen == 0)
378 del_timer(&bcsp->tbcsp); 409 del_timer(&bcsp->tbcsp);
410
379 spin_unlock_irqrestore(&bcsp->unack.lock, flags); 411 spin_unlock_irqrestore(&bcsp->unack.lock, flags);
380 412
381 if (i != pkts_to_be_removed) 413 if (i != pkts_to_be_removed)
@@ -530,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
530 562
531 hci_recv_frame(bcsp->rx_skb); 563 hci_recv_frame(bcsp->rx_skb);
532 } 564 }
565
533 bcsp->rx_state = BCSP_W4_PKT_DELIMITER; 566 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
534 bcsp->rx_skb = NULL; 567 bcsp->rx_skb = NULL;
535} 568}
@@ -598,8 +631,8 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
598 631
599 BT_ERR ("Checksum failed: computed %04x received %04x", 632 BT_ERR ("Checksum failed: computed %04x received %04x",
600 bcsp_crc_reverse(bcsp->message_crc), 633 bcsp_crc_reverse(bcsp->message_crc),
601 (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) + 634 (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
602 bcsp->rx_skb->data[bcsp->rx_skb->len - 1]); 635 bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
603 636
604 kfree_skb(bcsp->rx_skb); 637 kfree_skb(bcsp->rx_skb);
605 bcsp->rx_state = BCSP_W4_PKT_DELIMITER; 638 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
@@ -633,7 +666,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
633 bcsp->rx_count = 4; 666 bcsp->rx_count = 4;
634 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; 667 bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
635 BCSP_CRC_INIT(bcsp->message_crc); 668 BCSP_CRC_INIT(bcsp->message_crc);
636 669
637 /* Do not increment ptr or decrement count 670 /* Do not increment ptr or decrement count
638 * Allocate packet. Max len of a BCSP pkt= 671 * Allocate packet. Max len of a BCSP pkt=
639 * 0xFFF (payload) +4 (header) +2 (crc) */ 672 * 0xFFF (payload) +4 (header) +2 (crc) */
@@ -698,6 +731,9 @@ static int bcsp_open(struct hci_uart *hu)
698 731
699 bcsp->rx_state = BCSP_W4_PKT_DELIMITER; 732 bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
700 733
734 if (txcrc)
735 bcsp->use_crc = 1;
736
701 return 0; 737 return 0;
702} 738}
703 739
@@ -718,18 +754,19 @@ static int bcsp_close(struct hci_uart *hu)
718} 754}
719 755
720static struct hci_uart_proto bcsp = { 756static struct hci_uart_proto bcsp = {
721 .id = HCI_UART_BCSP, 757 .id = HCI_UART_BCSP,
722 .open = bcsp_open, 758 .open = bcsp_open,
723 .close = bcsp_close, 759 .close = bcsp_close,
724 .enqueue = bcsp_enqueue, 760 .enqueue = bcsp_enqueue,
725 .dequeue = bcsp_dequeue, 761 .dequeue = bcsp_dequeue,
726 .recv = bcsp_recv, 762 .recv = bcsp_recv,
727 .flush = bcsp_flush 763 .flush = bcsp_flush
728}; 764};
729 765
730int bcsp_init(void) 766int bcsp_init(void)
731{ 767{
732 int err = hci_uart_register_proto(&bcsp); 768 int err = hci_uart_register_proto(&bcsp);
769
733 if (!err) 770 if (!err)
734 BT_INFO("HCI BCSP protocol initialized"); 771 BT_INFO("HCI BCSP protocol initialized");
735 else 772 else
@@ -743,5 +780,8 @@ int bcsp_deinit(void)
743 return hci_uart_unregister_proto(&bcsp); 780 return hci_uart_unregister_proto(&bcsp);
744} 781}
745 782
783module_param(txcrc, bool, 0644);
784MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
785
746module_param(hciextn, bool, 0644); 786module_param(hciextn, bool, 0644);
747MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets"); 787MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");