OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [bluetooth/] [hci_bcsp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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.1.1.1 2004-04-15 02:29:47 phoenix Exp $
29
 */
30
 
31
#define VERSION "0.1"
32
 
33
#include <linux/config.h>
34
#include <linux/module.h>
35
 
36
#include <linux/version.h>
37
#include <linux/config.h>
38
#include <linux/kernel.h>
39
#include <linux/init.h>
40
#include <linux/sched.h>
41
#include <linux/types.h>
42
#include <linux/fcntl.h>
43
#include <linux/interrupt.h>
44
#include <linux/ptrace.h>
45
#include <linux/poll.h>
46
 
47
#include <linux/slab.h>
48
#include <linux/tty.h>
49
#include <linux/errno.h>
50
#include <linux/string.h>
51
#include <linux/signal.h>
52
#include <linux/ioctl.h>
53
#include <linux/skbuff.h>
54
 
55
#include <net/bluetooth/bluetooth.h>
56
#include <net/bluetooth/hci_core.h>
57
#include "hci_uart.h"
58
#include "hci_bcsp.h"
59
 
60
#ifndef HCI_UART_DEBUG
61
#undef  BT_DBG
62
#define BT_DBG( A... )
63
#undef  BT_DMP
64
#define BT_DMP( A... )
65
#endif
66
 
67
/* ---- BCSP CRC calculation ---- */
68
 
69
/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
70
initial value 0xffff, bits shifted in reverse order. */
71
 
72
static 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
*/
89
static 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
*/
107
static 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
 
121
static 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
 
127
static 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
 
144
static 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
        return 0;
170
}
171
 
172
static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
173
                int len, int pkt_type)
174
{
175
        struct sk_buff *nskb;
176
        u8  hdr[4], chan;
177
        int rel, i;
178
 
179
#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
180
        u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
181
#endif
182
 
183
        switch (pkt_type) {
184
        case HCI_ACLDATA_PKT:
185
                chan = 6;       /* BCSP ACL channel */
186
                rel = 1;        /* reliable channel */
187
                break;
188
        case HCI_COMMAND_PKT:
189
                chan = 5;       /* BCSP cmd/evt channel */
190
                rel = 1;        /* reliable channel */
191
                break;
192
        case HCI_SCODATA_PKT:
193
                chan = 7;       /* BCSP SCO channel */
194
                rel = 0; /* unreliable channel */
195
                break;
196
        case BCSP_LE_PKT:
197
                chan = 1;       /* BCSP LE channel */
198
                rel = 0; /* unreliable channel */
199
                break;
200
        case BCSP_ACK_PKT:
201
                chan = 0;        /* BCSP internal channel */
202
                rel = 0; /* unreliable channel */
203
                break;
204
        default:
205
                BT_ERR("Unknown packet type");
206
                return NULL;
207
        }
208
 
209
        /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
210
           (because bytes 0xc0 and 0xdb are escaped, worst case is
211
           when the packet is all made of 0xc0 and 0xdb :) )
212
           + 2 (0xc0 delimiters at start and end). */
213
 
214
        nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
215
        if (!nskb)
216
                return NULL;
217
 
218
        nskb->pkt_type = pkt_type;
219
 
220
        bcsp_slip_msgdelim(nskb);
221
 
222
        hdr[0] = bcsp->rxseq_txack << 3;
223
        bcsp->txack_req = 0;
224
        BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
225
 
226
        if (rel) {
227
                hdr[0] |= 0x80 + bcsp->msgq_txseq;
228
                BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
229
                bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
230
        }
231
#ifdef  CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
232
        hdr[0] |= 0x40;
233
#endif
234
 
235
        hdr[1]  = (len << 4) & 0xFF;
236
        hdr[1] |= chan;
237
        hdr[2]  = len >> 4;
238
        hdr[3]  = ~(hdr[0] + hdr[1] + hdr[2]);
239
 
240
        /* Put BCSP header */
241
        for (i = 0; i < 4; i++) {
242
                bcsp_slip_one_byte(nskb, hdr[i]);
243
#ifdef  CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
244
                bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
245
#endif
246
        }
247
 
248
        /* Put payload */
249
        for (i = 0; i < len; i++) {
250
                bcsp_slip_one_byte(nskb, data[i]);
251
#ifdef  CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
252
                bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
253
#endif
254
        }
255
 
256
#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
257
        /* Put CRC */
258
        bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
259
        bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
260
        bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
261
#endif
262
 
263
        bcsp_slip_msgdelim(nskb);
264
        return nskb;
265
}
266
 
267
/* This is a rewrite of pkt_avail in ABCSP */
268
static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
269
{
270
        struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
271
        unsigned long flags;
272
        struct sk_buff *skb;
273
 
274
        /* First of all, check for unreliable messages in the queue,
275
           since they have priority */
276
 
277
        if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
278
                struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
279
                if (nskb) {
280
                        kfree_skb(skb);
281
                        return nskb;
282
                } else {
283
                        skb_queue_head(&bcsp->unrel, skb);
284
                        BT_ERR("Could not dequeue pkt because alloc_skb failed");
285
                }
286
        }
287
 
288
        /* Now, try to send a reliable pkt. We can only send a
289
           reliable packet if the number of packets sent but not yet ack'ed
290
           is < than the winsize */
291
 
292
        spin_lock_irqsave(&bcsp->unack.lock, flags);
293
 
294
        if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
295
                struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
296
                if (nskb) {
297
                        __skb_queue_tail(&bcsp->unack, skb);
298
                        mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
299
                        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
300
                        return nskb;
301
                } else {
302
                        skb_queue_head(&bcsp->rel, skb);
303
                        BT_ERR("Could not dequeue pkt because alloc_skb failed");
304
                }
305
        }
306
 
307
        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
308
 
309
 
310
        /* We could not send a reliable packet, either because there are
311
           none or because there are too many unack'ed pkts. Did we receive
312
           any packets we have not acknowledged yet ? */
313
 
314
        if (bcsp->txack_req) {
315
                /* if so, craft an empty ACK pkt and send it on BCSP unreliable
316
                   channel 0 */
317
                struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
318
                return nskb;
319
        }
320
 
321
        /* We have nothing to send */
322
        return NULL;
323
}
324
 
325
static int bcsp_flush(struct hci_uart *hu)
326
{
327
        BT_DBG("hu %p", hu);
328
        return 0;
329
}
330
 
331
/* Remove ack'ed packets */
332
static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
333
{
334
        unsigned long flags;
335
        struct sk_buff *skb;
336
        int i, pkts_to_be_removed;
337
        u8 seqno;
338
 
339
        spin_lock_irqsave(&bcsp->unack.lock, flags);
340
 
341
        pkts_to_be_removed = bcsp->unack.qlen;
342
        seqno = bcsp->msgq_txseq;
343
 
344
        while (pkts_to_be_removed) {
345
                if (bcsp->rxack == seqno)
346
                        break;
347
                pkts_to_be_removed--;
348
                seqno = (seqno - 1) & 0x07;
349
        }
350
 
351
        if (bcsp->rxack != seqno)
352
                BT_ERR("Peer acked invalid packet");
353
 
354
        BT_DBG("Removing %u pkts out of %u, up to seqno %u",
355
               pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
356
 
357
        for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
358
                        && skb != (struct sk_buff *) &bcsp->unack; i++) {
359
                struct sk_buff *nskb;
360
 
361
                nskb = skb->next;
362
                __skb_unlink(skb, &bcsp->unack);
363
                kfree_skb(skb);
364
                skb = nskb;
365
        }
366
        if (bcsp->unack.qlen == 0)
367
                del_timer(&bcsp->tbcsp);
368
        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
369
 
370
        if (i != pkts_to_be_removed)
371
                BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
372
}
373
 
374
/* Handle BCSP link-establishment packets. When we
375
   detect a "sync" packet, symptom that the BT module has reset,
376
   we do nothing :) (yet) */
377
static void bcsp_handle_le_pkt(struct hci_uart *hu)
378
{
379
        struct bcsp_struct *bcsp = hu->priv;
380
        u8 conf_pkt[4]     = { 0xad, 0xef, 0xac, 0xed };
381
        u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
382
        u8 sync_pkt[4]     = { 0xda, 0xdc, 0xed, 0xed };
383
 
384
        /* spot "conf" pkts and reply with a "conf rsp" pkt */
385
        if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
386
                        !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
387
                struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
388
 
389
                BT_DBG("Found a LE conf pkt");
390
                if (!nskb)
391
                        return;
392
                memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
393
                nskb->pkt_type = BCSP_LE_PKT;
394
 
395
                skb_queue_head(&bcsp->unrel, nskb);
396
                hci_uart_tx_wakeup(hu);
397
        }
398
        /* Spot "sync" pkts. If we find one...disaster! */
399
        else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
400
                        !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
401
                BT_ERR("Found a LE sync pkt, card has reset");
402
        }
403
}
404
 
405
static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
406
{
407
        const u8 c0 = 0xc0, db = 0xdb;
408
 
409
        switch (bcsp->rx_esc_state) {
410
        case BCSP_ESCSTATE_NOESC:
411
                switch (byte) {
412
                case 0xdb:
413
                        bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
414
                        break;
415
                default:
416
                        memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
417
                        if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
418
                                        bcsp->rx_state != BCSP_W4_CRC)
419
                                bcsp_crc_update(&bcsp->message_crc, byte);
420
                        bcsp->rx_count--;
421
                }
422
                break;
423
 
424
        case BCSP_ESCSTATE_ESC:
425
                switch (byte) {
426
                case 0xdc:
427
                        memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
428
                        if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
429
                                        bcsp->rx_state != BCSP_W4_CRC)
430
                                bcsp_crc_update(&bcsp-> message_crc, 0xc0);
431
                        bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
432
                        bcsp->rx_count--;
433
                        break;
434
 
435
                case 0xdd:
436
                        memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
437
                        if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
438
                                        bcsp->rx_state != BCSP_W4_CRC)
439
                                bcsp_crc_update(&bcsp-> message_crc, 0xdb);
440
                        bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
441
                        bcsp->rx_count--;
442
                        break;
443
 
444
                default:
445
                        BT_ERR ("Invalid byte %02x after esc byte", byte);
446
                        kfree_skb(bcsp->rx_skb);
447
                        bcsp->rx_skb = NULL;
448
                        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
449
                        bcsp->rx_count = 0;
450
                }
451
        }
452
}
453
 
454
static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
455
{
456
        struct bcsp_struct *bcsp = hu->priv;
457
        int pass_up;
458
 
459
        if (bcsp->rx_skb->data[0] & 0x80) {      /* reliable pkt */
460
                BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
461
                bcsp->rxseq_txack++;
462
                bcsp->rxseq_txack %= 0x8;
463
                bcsp->txack_req    = 1;
464
 
465
                /* If needed, transmit an ack pkt */
466
                hci_uart_tx_wakeup(hu);
467
        }
468
 
469
        bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
470
        BT_DBG("Request for pkt %u from card", bcsp->rxack);
471
 
472
        bcsp_pkt_cull(bcsp);
473
        if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
474
                        bcsp->rx_skb->data[0] & 0x80) {
475
                bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
476
                pass_up = 1;
477
        } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
478
                        bcsp->rx_skb->data[0] & 0x80) {
479
                bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
480
                pass_up = 1;
481
        } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
482
                bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
483
                pass_up = 1;
484
        } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
485
                        !(bcsp->rx_skb->data[0] & 0x80)) {
486
                bcsp_handle_le_pkt(hu);
487
                pass_up = 0;
488
        } else
489
                pass_up = 0;
490
 
491
        if (!pass_up) {
492
                if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
493
                        (bcsp->rx_skb->data[1] & 0x0f) != 1) {
494
                        BT_ERR ("Packet for unknown channel (%u %s)",
495
                                bcsp->rx_skb->data[1] & 0x0f,
496
                                bcsp->rx_skb->data[0] & 0x80 ?
497
                                "reliable" : "unreliable");
498
                }
499
                kfree_skb(bcsp->rx_skb);
500
        } else {
501
                /* Pull out BCSP hdr */
502
                skb_pull(bcsp->rx_skb, 4);
503
 
504
                hci_recv_frame(bcsp->rx_skb);
505
        }
506
        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
507
        bcsp->rx_skb = NULL;
508
}
509
 
510
/* Recv data */
511
static int bcsp_recv(struct hci_uart *hu, void *data, int count)
512
{
513
        struct bcsp_struct *bcsp = hu->priv;
514
        register unsigned char *ptr;
515
 
516
        BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
517
                hu, count, bcsp->rx_state, bcsp->rx_count);
518
 
519
        ptr = data;
520
        while (count) {
521
                if (bcsp->rx_count) {
522
                        if (*ptr == 0xc0) {
523
                                BT_ERR("Short BCSP packet");
524
                                kfree_skb(bcsp->rx_skb);
525
                                bcsp->rx_state = BCSP_W4_PKT_START;
526
                                bcsp->rx_count = 0;
527
                        } else
528
                                bcsp_unslip_one_byte(bcsp, *ptr);
529
 
530
                        ptr++; count--;
531
                        continue;
532
                }
533
 
534
                switch (bcsp->rx_state) {
535
                case BCSP_W4_BCSP_HDR:
536
                        if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
537
                                        bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
538
                                BT_ERR("Error in BCSP hdr checksum");
539
                                kfree_skb(bcsp->rx_skb);
540
                                bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
541
                                bcsp->rx_count = 0;
542
                                continue;
543
                        }
544
                        if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
545
                                        && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
546
                                BT_ERR ("Out-of-order packet arrived, got %u expected %u",
547
                                        bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
548
 
549
                                kfree_skb(bcsp->rx_skb);
550
                                bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
551
                                bcsp->rx_count = 0;
552
                                continue;
553
                        }
554
                        bcsp->rx_state = BCSP_W4_DATA;
555
                        bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
556
                                        (bcsp->rx_skb->data[2] << 4);   /* May be 0 */
557
                        continue;
558
 
559
                case BCSP_W4_DATA:
560
                        if (bcsp->rx_skb->data[0] & 0x40) {      /* pkt with crc */
561
                                bcsp->rx_state = BCSP_W4_CRC;
562
                                bcsp->rx_count = 2;
563
                        } else
564
                                bcsp_complete_rx_pkt(hu);
565
                        continue;
566
 
567
                case BCSP_W4_CRC:
568
                        if (bcsp_crc_reverse(bcsp->message_crc) !=
569
                                        (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
570
                                        bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
571
 
572
                                BT_ERR ("Checksum failed: computed %04x received %04x",
573
                                        bcsp_crc_reverse(bcsp->message_crc),
574
                                        (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
575
                                        bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
576
 
577
                                kfree_skb(bcsp->rx_skb);
578
                                bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
579
                                bcsp->rx_count = 0;
580
                                continue;
581
                        }
582
                        skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
583
                        bcsp_complete_rx_pkt(hu);
584
                        continue;
585
 
586
                case BCSP_W4_PKT_DELIMITER:
587
                        switch (*ptr) {
588
                        case 0xc0:
589
                                bcsp->rx_state = BCSP_W4_PKT_START;
590
                                break;
591
                        default:
592
                                /*BT_ERR("Ignoring byte %02x", *ptr);*/
593
                                break;
594
                        }
595
                        ptr++; count--;
596
                        break;
597
 
598
                case BCSP_W4_PKT_START:
599
                        switch (*ptr) {
600
                        case 0xc0:
601
                                ptr++; count--;
602
                                break;
603
 
604
                        default:
605
                                bcsp->rx_state = BCSP_W4_BCSP_HDR;
606
                                bcsp->rx_count = 4;
607
                                bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
608
                                BCSP_CRC_INIT(bcsp->message_crc);
609
 
610
                                /* Do not increment ptr or decrement count
611
                                 * Allocate packet. Max len of a BCSP pkt=
612
                                 * 0xFFF (payload) +4 (header) +2 (crc) */
613
 
614
                                bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
615
                                if (!bcsp->rx_skb) {
616
                                        BT_ERR("Can't allocate mem for new packet");
617
                                        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
618
                                        bcsp->rx_count = 0;
619
                                        return 0;
620
                                }
621
                                bcsp->rx_skb->dev = (void *) &hu->hdev;
622
                                break;
623
                        }
624
                        break;
625
                }
626
        }
627
        return count;
628
}
629
 
630
        /* Arrange to retransmit all messages in the relq. */
631
static void bcsp_timed_event(unsigned long arg)
632
{
633
        struct hci_uart *hu = (struct hci_uart *) arg;
634
        struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
635
        struct sk_buff *skb;
636
        unsigned long flags;
637
 
638
        BT_ERR("Timeout, retransmitting %u pkts", bcsp->unack.qlen);
639
        spin_lock_irqsave(&bcsp->unack.lock, flags);
640
 
641
        while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
642
                bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
643
                skb_queue_head(&bcsp->rel, skb);
644
        }
645
 
646
        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
647
 
648
        hci_uart_tx_wakeup(hu);
649
}
650
 
651
static int bcsp_open(struct hci_uart *hu)
652
{
653
        struct bcsp_struct *bcsp;
654
 
655
        BT_DBG("hu %p", hu);
656
 
657
        bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
658
        if (!bcsp)
659
                return -ENOMEM;
660
        memset(bcsp, 0, sizeof(*bcsp));
661
 
662
        hu->priv = bcsp;
663
        skb_queue_head_init(&bcsp->unack);
664
        skb_queue_head_init(&bcsp->rel);
665
        skb_queue_head_init(&bcsp->unrel);
666
 
667
        init_timer(&bcsp->tbcsp);
668
        bcsp->tbcsp.function = bcsp_timed_event;
669
        bcsp->tbcsp.data     = (u_long) hu;
670
 
671
        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
672
 
673
        return 0;
674
}
675
 
676
static int bcsp_close(struct hci_uart *hu)
677
{
678
        struct bcsp_struct *bcsp = hu->priv;
679
        hu->priv = NULL;
680
 
681
        BT_DBG("hu %p", hu);
682
 
683
        skb_queue_purge(&bcsp->unack);
684
        skb_queue_purge(&bcsp->rel);
685
        skb_queue_purge(&bcsp->unrel);
686
        del_timer(&bcsp->tbcsp);
687
 
688
        kfree(bcsp);
689
        return 0;
690
}
691
 
692
static struct hci_uart_proto bcsp = {
693
        id:      HCI_UART_BCSP,
694
        open:    bcsp_open,
695
        close:   bcsp_close,
696
        enqueue: bcsp_enqueue,
697
        dequeue: bcsp_dequeue,
698
        recv:    bcsp_recv,
699
        flush:   bcsp_flush
700
};
701
 
702
int bcsp_init(void)
703
{
704
        return hci_uart_register_proto(&bcsp);
705
}
706
 
707
int bcsp_deinit(void)
708
{
709
        return hci_uart_unregister_proto(&bcsp);
710
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.