linux-old/drivers/bluetooth/hci_bcsp.c
<<
>>
Prefs
   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/*
  28 * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk 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/kernel.h>
  38#include <linux/init.h>
  39#include <linux/sched.h>
  40#include <linux/types.h>
  41#include <linux/fcntl.h>
  42#include <linux/interrupt.h>
  43#include <linux/ptrace.h>
  44#include <linux/poll.h>
  45
  46#include <linux/slab.h>
  47#include <linux/tty.h>
  48#include <linux/errno.h>
  49#include <linux/string.h>
  50#include <linux/signal.h>
  51#include <linux/ioctl.h>
  52#include <linux/skbuff.h>
  53
  54#include <net/bluetooth/bluetooth.h>
  55#include <net/bluetooth/hci_core.h>
  56#include "hci_uart.h"
  57#include "hci_bcsp.h"
  58
  59#ifndef HCI_UART_DEBUG
  60#undef  BT_DBG
  61#define BT_DBG( A... )
  62#undef  BT_DMP
  63#define BT_DMP( A... )
  64#endif
  65
  66/* ---- BCSP CRC calculation ---- */
  67
  68/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
  69initial value 0xffff, bits shifted in reverse order. */
  70
  71static const u16 crc_table[] = {
  72        0x0000, 0x1081, 0x2102, 0x3183,
  73        0x4204, 0x5285, 0x6306, 0x7387,
  74        0x8408, 0x9489, 0xa50a, 0xb58b,
  75        0xc60c, 0xd68d, 0xe70e, 0xf78f
  76};
  77
  78/* Initialise the crc calculator */
  79#define BCSP_CRC_INIT(x) x = 0xffff
  80
  81/*
  82   Update crc with next data byte
  83
  84   Implementation note
  85        The data byte is treated as two nibbles.  The crc is generated
  86        in reverse, i.e., bits are fed into the register from the top.
  87*/
  88static void bcsp_crc_update(u16 *crc, u8 d)
  89{
  90        u16 reg = *crc;
  91
  92        reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
  93        reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
  94
  95        *crc = reg;
  96}
  97
  98/*
  99   Get reverse of generated crc
 100
 101   Implementation note
 102        The crc generator (bcsp_crc_init() and bcsp_crc_update())
 103        creates a reversed crc, so it needs to be swapped back before
 104        being passed on.
 105*/
 106static u16 bcsp_crc_reverse(u16 crc)
 107{
 108        u16 b, rev;
 109
 110        for (b = 0, rev = 0; b < 16; b++) {
 111                rev = rev << 1;
 112                rev |= (crc & 1);
 113                crc = crc >> 1;
 114        }
 115        return (rev);
 116}
 117
 118/* ---- BCSP core ---- */
 119
 120static void bcsp_slip_msgdelim(struct sk_buff *skb)
 121{
 122        const char pkt_delim = 0xc0;
 123        memcpy(skb_put(skb, 1), &pkt_delim, 1);
 124}
 125
 126static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
 127{
 128        const char esc_c0[2] = { 0xdb, 0xdc };
 129        const char esc_db[2] = { 0xdb, 0xdd };
 130
 131        switch (c) {
 132        case 0xc0:
 133                memcpy(skb_put(skb, 2), &esc_c0, 2);
 134                break;
 135        case 0xdb:
 136                memcpy(skb_put(skb, 2), &esc_db, 2);
 137                break;
 138        default:
 139                memcpy(skb_put(skb, 1), &c, 1);
 140        }
 141}
 142
 143static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
 144{
 145        struct bcsp_struct *bcsp = hu->priv;
 146
 147        if (skb->len > 0xFFF) {
 148                BT_ERR("Packet too long");
 149                kfree_skb(skb);
 150                return 0;
 151        }
 152
 153        switch (skb->pkt_type) {
 154        case HCI_ACLDATA_PKT:
 155        case HCI_COMMAND_PKT:
 156                skb_queue_tail(&bcsp->rel, skb);
 157                break;
 158
 159        case HCI_SCODATA_PKT:
 160                skb_queue_tail(&bcsp->unrel, skb);
 161                break;
 162                
 163        default:
 164                BT_ERR("Unknown packet type");
 165                kfree_skb(skb);
 166                break;
 167        }
 168        return 0;
 169}
 170
 171static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
 172                int len, int pkt_type)
 173{
 174        struct sk_buff *nskb;
 175        u8  hdr[4], chan;
 176        int rel, i;
 177
 178#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
 179        u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
 180#endif
 181
 182        switch (pkt_type) {
 183        case HCI_ACLDATA_PKT:
 184                chan = 6;       /* BCSP ACL channel */
 185                rel = 1;        /* reliable channel */
 186                break;
 187        case HCI_COMMAND_PKT:
 188                chan = 5;       /* BCSP cmd/evt channel */
 189                rel = 1;        /* reliable channel */
 190                break;
 191        case HCI_SCODATA_PKT:
 192                chan = 7;       /* BCSP SCO channel */
 193                rel = 0;        /* unreliable channel */
 194                break;
 195        case BCSP_LE_PKT:
 196                chan = 1;       /* BCSP LE channel */
 197                rel = 0;        /* unreliable channel */
 198                break;
 199        case BCSP_ACK_PKT:
 200                chan = 0;       /* BCSP internal channel */
 201                rel = 0;        /* unreliable channel */
 202                break;
 203        default:
 204                BT_ERR("Unknown packet type");
 205                return NULL;
 206        }
 207
 208        /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
 209           (because bytes 0xc0 and 0xdb are escaped, worst case is
 210           when the packet is all made of 0xc0 and 0xdb :) )
 211           + 2 (0xc0 delimiters at start and end). */
 212
 213        nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
 214        if (!nskb)
 215                return NULL;
 216
 217        nskb->pkt_type = pkt_type;
 218
 219        bcsp_slip_msgdelim(nskb);
 220
 221        hdr[0] = bcsp->rxseq_txack << 3;
 222        bcsp->txack_req = 0;
 223        BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
 224
 225        if (rel) {
 226                hdr[0] |= 0x80 + bcsp->msgq_txseq;
 227                BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
 228                bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
 229        }
 230#ifdef  CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
 231        hdr[0] |= 0x40;
 232#endif
 233
 234        hdr[1]  = (len << 4) & 0xFF;
 235        hdr[1] |= chan;
 236        hdr[2]  = len >> 4;
 237        hdr[3]  = ~(hdr[0] + hdr[1] + hdr[2]);
 238
 239        /* Put BCSP header */
 240        for (i = 0; i < 4; i++) {
 241                bcsp_slip_one_byte(nskb, hdr[i]);
 242#ifdef  CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
 243                bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
 244#endif
 245        }
 246
 247        /* Put payload */
 248        for (i = 0; i < len; i++) {
 249                bcsp_slip_one_byte(nskb, data[i]);
 250#ifdef  CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
 251                bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
 252#endif
 253        }
 254
 255#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
 256        /* Put CRC */
 257        bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
 258        bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
 259        bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
 260#endif
 261
 262        bcsp_slip_msgdelim(nskb);
 263        return nskb;
 264}
 265
 266/* This is a rewrite of pkt_avail in ABCSP */
 267static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
 268{
 269        struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
 270        unsigned long flags;
 271        struct sk_buff *skb;
 272        
 273        /* First of all, check for unreliable messages in the queue,
 274           since they have priority */
 275
 276        if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
 277                struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
 278                if (nskb) {
 279                        kfree_skb(skb);
 280                        return nskb;
 281                } else {
 282                        skb_queue_head(&bcsp->unrel, skb);
 283                        BT_ERR("Could not dequeue pkt because alloc_skb failed");
 284                }
 285        }
 286
 287        /* Now, try to send a reliable pkt. We can only send a
 288           reliable packet if the number of packets sent but not yet ack'ed
 289           is < than the winsize */
 290
 291        spin_lock_irqsave(&bcsp->unack.lock, flags);
 292
 293        if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
 294                struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
 295                if (nskb) {
 296                        __skb_queue_tail(&bcsp->unack, skb);
 297                        mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
 298                        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
 299                        return nskb;
 300                } else {
 301                        skb_queue_head(&bcsp->rel, skb);
 302                        BT_ERR("Could not dequeue pkt because alloc_skb failed");
 303                }
 304        }
 305
 306        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
 307
 308
 309        /* We could not send a reliable packet, either because there are
 310           none or because there are too many unack'ed pkts. Did we receive
 311           any packets we have not acknowledged yet ? */
 312
 313        if (bcsp->txack_req) {
 314                /* if so, craft an empty ACK pkt and send it on BCSP unreliable
 315                   channel 0 */
 316                struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
 317                return nskb;
 318        }
 319
 320        /* We have nothing to send */
 321        return NULL;
 322}
 323
 324static int bcsp_flush(struct hci_uart *hu)
 325{
 326        BT_DBG("hu %p", hu);
 327        return 0;
 328}
 329
 330/* Remove ack'ed packets */
 331static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
 332{
 333        unsigned long flags;
 334        struct sk_buff *skb;
 335        int i, pkts_to_be_removed;
 336        u8 seqno;
 337
 338        spin_lock_irqsave(&bcsp->unack.lock, flags);
 339
 340        pkts_to_be_removed = bcsp->unack.qlen;
 341        seqno = bcsp->msgq_txseq;
 342
 343        while (pkts_to_be_removed) {
 344                if (bcsp->rxack == seqno)
 345                        break;
 346                pkts_to_be_removed--;
 347                seqno = (seqno - 1) & 0x07;
 348        }
 349
 350        if (bcsp->rxack != seqno)
 351                BT_ERR("Peer acked invalid packet");
 352
 353        BT_DBG("Removing %u pkts out of %u, up to seqno %u",
 354               pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
 355
 356        for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
 357                        && skb != (struct sk_buff *) &bcsp->unack; i++) {
 358                struct sk_buff *nskb;
 359
 360                nskb = skb->next;
 361                __skb_unlink(skb, &bcsp->unack);
 362                kfree_skb(skb);
 363                skb = nskb;
 364        }
 365        if (bcsp->unack.qlen == 0)
 366                del_timer(&bcsp->tbcsp);
 367        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
 368
 369        if (i != pkts_to_be_removed)
 370                BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
 371}
 372
 373/* Handle BCSP link-establishment packets. When we
 374   detect a "sync" packet, symptom that the BT module has reset,
 375   we do nothing :) (yet) */
 376static void bcsp_handle_le_pkt(struct hci_uart *hu)
 377{
 378        struct bcsp_struct *bcsp = hu->priv;
 379        u8 conf_pkt[4]     = { 0xad, 0xef, 0xac, 0xed };
 380        u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
 381        u8 sync_pkt[4]     = { 0xda, 0xdc, 0xed, 0xed };
 382
 383        /* spot "conf" pkts and reply with a "conf rsp" pkt */
 384        if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
 385                        !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
 386                struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
 387
 388                BT_DBG("Found a LE conf pkt");
 389                if (!nskb)
 390                        return;
 391                memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
 392                nskb->pkt_type = BCSP_LE_PKT;
 393
 394                skb_queue_head(&bcsp->unrel, nskb);
 395                hci_uart_tx_wakeup(hu);
 396        }
 397        /* Spot "sync" pkts. If we find one...disaster! */
 398        else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
 399                        !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
 400                BT_ERR("Found a LE sync pkt, card has reset");
 401        }
 402}
 403
 404static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
 405{
 406        const u8 c0 = 0xc0, db = 0xdb;
 407
 408        switch (bcsp->rx_esc_state) {
 409        case BCSP_ESCSTATE_NOESC:
 410                switch (byte) {
 411                case 0xdb:
 412                        bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
 413                        break;
 414                default:
 415                        memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
 416                        if ((bcsp->rx_skb-> data[0] & 0x40) != 0 && 
 417                                        bcsp->rx_state != BCSP_W4_CRC)
 418                                bcsp_crc_update(&bcsp->message_crc, byte);
 419                        bcsp->rx_count--;
 420                }
 421                break;
 422
 423        case BCSP_ESCSTATE_ESC:
 424                switch (byte) {
 425                case 0xdc:
 426                        memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
 427                        if ((bcsp->rx_skb-> data[0] & 0x40) != 0 && 
 428                                        bcsp->rx_state != BCSP_W4_CRC)
 429                                bcsp_crc_update(&bcsp-> message_crc, 0xc0);
 430                        bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
 431                        bcsp->rx_count--;
 432                        break;
 433
 434                case 0xdd:
 435                        memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
 436                        if ((bcsp->rx_skb-> data[0] & 0x40) != 0 && 
 437                                        bcsp->rx_state != BCSP_W4_CRC) 
 438                                bcsp_crc_update(&bcsp-> message_crc, 0xdb);
 439                        bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
 440                        bcsp->rx_count--;
 441                        break;
 442
 443                default:
 444                        BT_ERR ("Invalid byte %02x after esc byte", byte);
 445                        kfree_skb(bcsp->rx_skb);
 446                        bcsp->rx_skb = NULL;
 447                        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
 448                        bcsp->rx_count = 0;
 449                }
 450        }
 451}
 452
 453static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
 454{
 455        struct bcsp_struct *bcsp = hu->priv;
 456        int pass_up;
 457
 458        if (bcsp->rx_skb->data[0] & 0x80) {     /* reliable pkt */
 459                BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
 460                bcsp->rxseq_txack++;
 461                bcsp->rxseq_txack %= 0x8;
 462                bcsp->txack_req    = 1;
 463
 464                /* If needed, transmit an ack pkt */
 465                hci_uart_tx_wakeup(hu);
 466        }
 467
 468        bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
 469        BT_DBG("Request for pkt %u from card", bcsp->rxack);
 470
 471        bcsp_pkt_cull(bcsp);
 472        if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
 473                        bcsp->rx_skb->data[0] & 0x80) {
 474                bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
 475                pass_up = 1;
 476        } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
 477                        bcsp->rx_skb->data[0] & 0x80) {
 478                bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
 479                pass_up = 1;
 480        } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
 481                bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
 482                pass_up = 1;
 483        } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
 484                        !(bcsp->rx_skb->data[0] & 0x80)) {
 485                bcsp_handle_le_pkt(hu);
 486                pass_up = 0;
 487        } else
 488                pass_up = 0;
 489
 490        if (!pass_up) {
 491                if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
 492                        (bcsp->rx_skb->data[1] & 0x0f) != 1) {
 493                        BT_ERR ("Packet for unknown channel (%u %s)",
 494                                bcsp->rx_skb->data[1] & 0x0f,
 495                                bcsp->rx_skb->data[0] & 0x80 ? 
 496                                "reliable" : "unreliable");
 497                }
 498                kfree_skb(bcsp->rx_skb);
 499        } else {
 500                /* Pull out BCSP hdr */
 501                skb_pull(bcsp->rx_skb, 4);
 502
 503                hci_recv_frame(bcsp->rx_skb);
 504        }
 505        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
 506        bcsp->rx_skb = NULL;
 507}
 508
 509/* Recv data */
 510static int bcsp_recv(struct hci_uart *hu, void *data, int count)
 511{
 512        struct bcsp_struct *bcsp = hu->priv;
 513        register unsigned char *ptr;
 514
 515        BT_DBG("hu %p count %d rx_state %ld rx_count %ld", 
 516                hu, count, bcsp->rx_state, bcsp->rx_count);
 517
 518        ptr = data;
 519        while (count) {
 520                if (bcsp->rx_count) {
 521                        if (*ptr == 0xc0) {
 522                                BT_ERR("Short BCSP packet");
 523                                kfree_skb(bcsp->rx_skb);
 524                                bcsp->rx_state = BCSP_W4_PKT_START;
 525                                bcsp->rx_count = 0;
 526                        } else
 527                                bcsp_unslip_one_byte(bcsp, *ptr);
 528
 529                        ptr++; count--;
 530                        continue;
 531                }
 532
 533                switch (bcsp->rx_state) {
 534                case BCSP_W4_BCSP_HDR:
 535                        if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
 536                                        bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
 537                                BT_ERR("Error in BCSP hdr checksum");
 538                                kfree_skb(bcsp->rx_skb);
 539                                bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
 540                                bcsp->rx_count = 0;
 541                                continue;
 542                        }
 543                        if (bcsp->rx_skb->data[0] & 0x80        /* reliable pkt */
 544                                        && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
 545                                BT_ERR ("Out-of-order packet arrived, got %u expected %u",
 546                                        bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
 547
 548                                kfree_skb(bcsp->rx_skb);
 549                                bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
 550                                bcsp->rx_count = 0;
 551                                continue;
 552                        }
 553                        bcsp->rx_state = BCSP_W4_DATA;
 554                        bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) + 
 555                                        (bcsp->rx_skb->data[2] << 4);   /* May be 0 */
 556                        continue;
 557
 558                case BCSP_W4_DATA:
 559                        if (bcsp->rx_skb->data[0] & 0x40) {     /* pkt with crc */
 560                                bcsp->rx_state = BCSP_W4_CRC;
 561                                bcsp->rx_count = 2;
 562                        } else
 563                                bcsp_complete_rx_pkt(hu);
 564                        continue;
 565
 566                case BCSP_W4_CRC:
 567                        if (bcsp_crc_reverse(bcsp->message_crc) !=
 568                                        (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
 569                                        bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
 570
 571                                BT_ERR ("Checksum failed: computed %04x received %04x",
 572                                        bcsp_crc_reverse(bcsp->message_crc),
 573                                        (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
 574                                        bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
 575
 576                                kfree_skb(bcsp->rx_skb);
 577                                bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
 578                                bcsp->rx_count = 0;
 579                                continue;
 580                        }
 581                        skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
 582                        bcsp_complete_rx_pkt(hu);
 583                        continue;
 584
 585                case BCSP_W4_PKT_DELIMITER:
 586                        switch (*ptr) {
 587                        case 0xc0:
 588                                bcsp->rx_state = BCSP_W4_PKT_START;
 589                                break;
 590                        default:
 591                                /*BT_ERR("Ignoring byte %02x", *ptr);*/
 592                                break;
 593                        }
 594                        ptr++; count--;
 595                        break;
 596
 597                case BCSP_W4_PKT_START:
 598                        switch (*ptr) {
 599                        case 0xc0:
 600                                ptr++; count--;
 601                                break;
 602
 603                        default:
 604                                bcsp->rx_state = BCSP_W4_BCSP_HDR;
 605                                bcsp->rx_count = 4;
 606                                bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
 607                                BCSP_CRC_INIT(bcsp->message_crc);
 608                                
 609                                /* Do not increment ptr or decrement count
 610                                 * Allocate packet. Max len of a BCSP pkt= 
 611                                 * 0xFFF (payload) +4 (header) +2 (crc) */
 612
 613                                bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
 614                                if (!bcsp->rx_skb) {
 615                                        BT_ERR("Can't allocate mem for new packet");
 616                                        bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
 617                                        bcsp->rx_count = 0;
 618                                        return 0;
 619                                }
 620                                bcsp->rx_skb->dev = (void *) &hu->hdev;
 621                                break;
 622                        }
 623                        break;
 624                }
 625        }
 626        return count;
 627}
 628
 629        /* Arrange to retransmit all messages in the relq. */
 630static void bcsp_timed_event(unsigned long arg)
 631{
 632        struct hci_uart *hu = (struct hci_uart *) arg;
 633        struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
 634        struct sk_buff *skb;
 635        unsigned long flags;
 636
 637        BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
 638
 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
 651static 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
 676static 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
 692static 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
 702int bcsp_init(void)
 703{
 704        return hci_uart_register_proto(&bcsp);
 705}
 706
 707int bcsp_deinit(void)
 708{
 709        return hci_uart_unregister_proto(&bcsp);
 710}
 711
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.