linux/drivers/bluetooth/btmrvl_main.c
<<
>>
Prefs
   1/**
   2 * Marvell Bluetooth driver
   3 *
   4 * Copyright (C) 2009, Marvell International Ltd.
   5 *
   6 * This software file (the "File") is distributed by Marvell International
   7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
   8 * (the "License").  You may use, redistribute and/or modify this File in
   9 * accordance with the terms and conditions of the License, a copy of which
  10 * is available by writing to the Free Software Foundation, Inc.,
  11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13 *
  14 *
  15 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  16 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  17 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
  18 * this warranty disclaimer.
  19 **/
  20
  21#include <linux/module.h>
  22#include <linux/of.h>
  23#include <net/bluetooth/bluetooth.h>
  24#include <net/bluetooth/hci_core.h>
  25#include <linux/mmc/sdio_func.h>
  26
  27#include "btmrvl_drv.h"
  28#include "btmrvl_sdio.h"
  29
  30#define VERSION "1.0"
  31
  32/*
  33 * This function is called by interface specific interrupt handler.
  34 * It updates Power Save & Host Sleep states, and wakes up the main
  35 * thread.
  36 */
  37void btmrvl_interrupt(struct btmrvl_private *priv)
  38{
  39        priv->adapter->ps_state = PS_AWAKE;
  40
  41        priv->adapter->wakeup_tries = 0;
  42
  43        priv->adapter->int_count++;
  44
  45        if (priv->adapter->hs_state == HS_ACTIVATED) {
  46                BT_DBG("BT: HS DEACTIVATED in ISR!");
  47                priv->adapter->hs_state = HS_DEACTIVATED;
  48        }
  49
  50        wake_up_interruptible(&priv->main_thread.wait_q);
  51}
  52EXPORT_SYMBOL_GPL(btmrvl_interrupt);
  53
  54bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
  55{
  56        struct hci_event_hdr *hdr = (void *) skb->data;
  57
  58        if (hdr->evt == HCI_EV_CMD_COMPLETE) {
  59                struct hci_ev_cmd_complete *ec;
  60                u16 opcode;
  61
  62                ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
  63                opcode = __le16_to_cpu(ec->opcode);
  64
  65                if (priv->btmrvl_dev.sendcmdflag) {
  66                        priv->btmrvl_dev.sendcmdflag = false;
  67                        priv->adapter->cmd_complete = true;
  68                        wake_up_interruptible(&priv->adapter->cmd_wait_q);
  69
  70                        if (hci_opcode_ogf(opcode) == 0x3F) {
  71                                BT_DBG("vendor event skipped: opcode=%#4.4x",
  72                                       opcode);
  73                                kfree_skb(skb);
  74                                return false;
  75                        }
  76                }
  77        }
  78
  79        return true;
  80}
  81EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt);
  82
  83int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
  84{
  85        struct btmrvl_adapter *adapter = priv->adapter;
  86        struct btmrvl_event *event;
  87        int ret = 0;
  88
  89        event = (struct btmrvl_event *) skb->data;
  90        if (event->ec != 0xff) {
  91                BT_DBG("Not Marvell Event=%x", event->ec);
  92                ret = -EINVAL;
  93                goto exit;
  94        }
  95
  96        switch (event->data[0]) {
  97        case BT_EVENT_AUTO_SLEEP_MODE:
  98                if (!event->data[2]) {
  99                        if (event->data[1] == BT_PS_ENABLE)
 100                                adapter->psmode = 1;
 101                        else
 102                                adapter->psmode = 0;
 103                        BT_DBG("PS Mode:%s",
 104                                (adapter->psmode) ? "Enable" : "Disable");
 105                } else {
 106                        BT_DBG("PS Mode command failed");
 107                }
 108                break;
 109
 110        case BT_EVENT_HOST_SLEEP_CONFIG:
 111                if (!event->data[3])
 112                        BT_DBG("gpio=%x, gap=%x", event->data[1],
 113                                                        event->data[2]);
 114                else
 115                        BT_DBG("HSCFG command failed");
 116                break;
 117
 118        case BT_EVENT_HOST_SLEEP_ENABLE:
 119                if (!event->data[1]) {
 120                        adapter->hs_state = HS_ACTIVATED;
 121                        if (adapter->psmode)
 122                                adapter->ps_state = PS_SLEEP;
 123                        wake_up_interruptible(&adapter->event_hs_wait_q);
 124                        BT_DBG("HS ACTIVATED!");
 125                } else {
 126                        BT_DBG("HS Enable failed");
 127                }
 128                break;
 129
 130        case BT_EVENT_MODULE_CFG_REQ:
 131                if (priv->btmrvl_dev.sendcmdflag &&
 132                                event->data[1] == MODULE_BRINGUP_REQ) {
 133                        BT_DBG("EVENT:%s",
 134                                ((event->data[2] == MODULE_BROUGHT_UP) ||
 135                                (event->data[2] == MODULE_ALREADY_UP)) ?
 136                                "Bring-up succeed" : "Bring-up failed");
 137
 138                        if (event->length > 3 && event->data[3])
 139                                priv->btmrvl_dev.dev_type = HCI_AMP;
 140                        else
 141                                priv->btmrvl_dev.dev_type = HCI_PRIMARY;
 142
 143                        BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type);
 144                } else if (priv->btmrvl_dev.sendcmdflag &&
 145                                event->data[1] == MODULE_SHUTDOWN_REQ) {
 146                        BT_DBG("EVENT:%s", (event->data[2]) ?
 147                                "Shutdown failed" : "Shutdown succeed");
 148                } else {
 149                        BT_DBG("BT_CMD_MODULE_CFG_REQ resp for APP");
 150                        ret = -EINVAL;
 151                }
 152                break;
 153
 154        case BT_EVENT_POWER_STATE:
 155                if (event->data[1] == BT_PS_SLEEP)
 156                        adapter->ps_state = PS_SLEEP;
 157                BT_DBG("EVENT:%s",
 158                        (adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE");
 159                break;
 160
 161        default:
 162                BT_DBG("Unknown Event=%d", event->data[0]);
 163                ret = -EINVAL;
 164                break;
 165        }
 166
 167exit:
 168        if (!ret)
 169                kfree_skb(skb);
 170
 171        return ret;
 172}
 173EXPORT_SYMBOL_GPL(btmrvl_process_event);
 174
 175static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
 176                                const void *param, u8 len)
 177{
 178        struct sk_buff *skb;
 179        struct hci_command_hdr *hdr;
 180
 181        if (priv->surprise_removed) {
 182                BT_ERR("Card is removed");
 183                return -EFAULT;
 184        }
 185
 186        skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC);
 187        if (!skb) {
 188                BT_ERR("No free skb");
 189                return -ENOMEM;
 190        }
 191
 192        hdr = skb_put(skb, HCI_COMMAND_HDR_SIZE);
 193        hdr->opcode = cpu_to_le16(opcode);
 194        hdr->plen = len;
 195
 196        if (len)
 197                skb_put_data(skb, param, len);
 198
 199        hci_skb_pkt_type(skb) = MRVL_VENDOR_PKT;
 200
 201        skb_queue_head(&priv->adapter->tx_queue, skb);
 202
 203        priv->btmrvl_dev.sendcmdflag = true;
 204
 205        priv->adapter->cmd_complete = false;
 206
 207        wake_up_interruptible(&priv->main_thread.wait_q);
 208
 209        if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
 210                                              priv->adapter->cmd_complete ||
 211                                              priv->surprise_removed,
 212                                              WAIT_UNTIL_CMD_RESP))
 213                return -ETIMEDOUT;
 214
 215        if (priv->surprise_removed)
 216                return -EFAULT;
 217
 218        return 0;
 219}
 220
 221int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
 222{
 223        int ret;
 224
 225        ret = btmrvl_send_sync_cmd(priv, BT_CMD_MODULE_CFG_REQ, &subcmd, 1);
 226        if (ret)
 227                BT_ERR("module_cfg_cmd(%x) failed", subcmd);
 228
 229        return ret;
 230}
 231EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
 232
 233static int btmrvl_enable_sco_routing_to_host(struct btmrvl_private *priv)
 234{
 235        int ret;
 236        u8 subcmd = 0;
 237
 238        ret = btmrvl_send_sync_cmd(priv, BT_CMD_ROUTE_SCO_TO_HOST, &subcmd, 1);
 239        if (ret)
 240                BT_ERR("BT_CMD_ROUTE_SCO_TO_HOST command failed: %#x", ret);
 241
 242        return ret;
 243}
 244
 245int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd)
 246{
 247        struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
 248        int ret;
 249
 250        if (!card->support_pscan_win_report)
 251                return 0;
 252
 253        ret = btmrvl_send_sync_cmd(priv, BT_CMD_PSCAN_WIN_REPORT_ENABLE,
 254                                   &subcmd, 1);
 255        if (ret)
 256                BT_ERR("PSCAN_WIN_REPORT_ENABLE command failed: %#x", ret);
 257
 258        return ret;
 259}
 260EXPORT_SYMBOL_GPL(btmrvl_pscan_window_reporting);
 261
 262int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
 263{
 264        int ret;
 265        u8 param[2];
 266
 267        param[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
 268        param[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
 269
 270        BT_DBG("Sending HSCFG Command, gpio=0x%x, gap=0x%x",
 271               param[0], param[1]);
 272
 273        ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_CONFIG, param, 2);
 274        if (ret)
 275                BT_ERR("HSCFG command failed");
 276
 277        return ret;
 278}
 279EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);
 280
 281int btmrvl_enable_ps(struct btmrvl_private *priv)
 282{
 283        int ret;
 284        u8 param;
 285
 286        if (priv->btmrvl_dev.psmode)
 287                param = BT_PS_ENABLE;
 288        else
 289                param = BT_PS_DISABLE;
 290
 291        ret = btmrvl_send_sync_cmd(priv, BT_CMD_AUTO_SLEEP_MODE, &param, 1);
 292        if (ret)
 293                BT_ERR("PSMODE command failed");
 294
 295        return 0;
 296}
 297EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
 298
 299int btmrvl_enable_hs(struct btmrvl_private *priv)
 300{
 301        struct btmrvl_adapter *adapter = priv->adapter;
 302        int ret;
 303
 304        ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
 305        if (ret) {
 306                BT_ERR("Host sleep enable command failed");
 307                return ret;
 308        }
 309
 310        ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q,
 311                                               adapter->hs_state ||
 312                                               priv->surprise_removed,
 313                                               WAIT_UNTIL_HS_STATE_CHANGED);
 314        if (ret < 0 || priv->surprise_removed) {
 315                BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d",
 316                       ret, adapter->hs_state, adapter->ps_state,
 317                       adapter->wakeup_tries);
 318        } else if (!ret) {
 319                BT_ERR("hs_enable timeout: %d,%d,%d", adapter->hs_state,
 320                       adapter->ps_state, adapter->wakeup_tries);
 321                ret = -ETIMEDOUT;
 322        } else {
 323                BT_DBG("host sleep enabled: %d,%d,%d", adapter->hs_state,
 324                       adapter->ps_state, adapter->wakeup_tries);
 325                ret = 0;
 326        }
 327
 328        return ret;
 329}
 330EXPORT_SYMBOL_GPL(btmrvl_enable_hs);
 331
 332int btmrvl_prepare_command(struct btmrvl_private *priv)
 333{
 334        int ret = 0;
 335
 336        if (priv->btmrvl_dev.hscfgcmd) {
 337                priv->btmrvl_dev.hscfgcmd = 0;
 338                btmrvl_send_hscfg_cmd(priv);
 339        }
 340
 341        if (priv->btmrvl_dev.pscmd) {
 342                priv->btmrvl_dev.pscmd = 0;
 343                btmrvl_enable_ps(priv);
 344        }
 345
 346        if (priv->btmrvl_dev.hscmd) {
 347                priv->btmrvl_dev.hscmd = 0;
 348
 349                if (priv->btmrvl_dev.hsmode) {
 350                        ret = btmrvl_enable_hs(priv);
 351                } else {
 352                        ret = priv->hw_wakeup_firmware(priv);
 353                        priv->adapter->hs_state = HS_DEACTIVATED;
 354                        BT_DBG("BT: HS DEACTIVATED due to host activity!");
 355                }
 356        }
 357
 358        return ret;
 359}
 360
 361void btmrvl_firmware_dump(struct btmrvl_private *priv)
 362{
 363        if (priv->firmware_dump)
 364                priv->firmware_dump(priv);
 365}
 366
 367static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
 368{
 369        int ret = 0;
 370
 371        if (!skb || !skb->data)
 372                return -EINVAL;
 373
 374        if (!skb->len || ((skb->len + BTM_HEADER_LEN) > BTM_UPLD_SIZE)) {
 375                BT_ERR("Tx Error: Bad skb length %d : %d",
 376                                                skb->len, BTM_UPLD_SIZE);
 377                return -EINVAL;
 378        }
 379
 380        skb_push(skb, BTM_HEADER_LEN);
 381
 382        /* header type: byte[3]
 383         * HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor
 384         * header length: byte[2][1][0]
 385         */
 386
 387        skb->data[0] = (skb->len & 0x0000ff);
 388        skb->data[1] = (skb->len & 0x00ff00) >> 8;
 389        skb->data[2] = (skb->len & 0xff0000) >> 16;
 390        skb->data[3] = hci_skb_pkt_type(skb);
 391
 392        if (priv->hw_host_to_card)
 393                ret = priv->hw_host_to_card(priv, skb->data, skb->len);
 394
 395        return ret;
 396}
 397
 398static void btmrvl_init_adapter(struct btmrvl_private *priv)
 399{
 400        int buf_size;
 401
 402        skb_queue_head_init(&priv->adapter->tx_queue);
 403
 404        priv->adapter->ps_state = PS_AWAKE;
 405
 406        buf_size = ALIGN_SZ(SDIO_BLOCK_SIZE, BTSDIO_DMA_ALIGN);
 407        priv->adapter->hw_regs_buf = kzalloc(buf_size, GFP_KERNEL);
 408        if (!priv->adapter->hw_regs_buf) {
 409                priv->adapter->hw_regs = NULL;
 410                BT_ERR("Unable to allocate buffer for hw_regs.");
 411        } else {
 412                priv->adapter->hw_regs =
 413                        (u8 *)ALIGN_ADDR(priv->adapter->hw_regs_buf,
 414                                         BTSDIO_DMA_ALIGN);
 415                BT_DBG("hw_regs_buf=%p hw_regs=%p",
 416                       priv->adapter->hw_regs_buf, priv->adapter->hw_regs);
 417        }
 418
 419        init_waitqueue_head(&priv->adapter->cmd_wait_q);
 420        init_waitqueue_head(&priv->adapter->event_hs_wait_q);
 421}
 422
 423static void btmrvl_free_adapter(struct btmrvl_private *priv)
 424{
 425        skb_queue_purge(&priv->adapter->tx_queue);
 426
 427        kfree(priv->adapter->hw_regs_buf);
 428        kfree(priv->adapter);
 429
 430        priv->adapter = NULL;
 431}
 432
 433static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 434{
 435        struct btmrvl_private *priv = hci_get_drvdata(hdev);
 436
 437        BT_DBG("type=%d, len=%d", hci_skb_pkt_type(skb), skb->len);
 438
 439        if (priv->adapter->is_suspending || priv->adapter->is_suspended) {
 440                BT_ERR("%s: Device is suspending or suspended", __func__);
 441                return -EBUSY;
 442        }
 443
 444        switch (hci_skb_pkt_type(skb)) {
 445        case HCI_COMMAND_PKT:
 446                hdev->stat.cmd_tx++;
 447                break;
 448
 449        case HCI_ACLDATA_PKT:
 450                hdev->stat.acl_tx++;
 451                break;
 452
 453        case HCI_SCODATA_PKT:
 454                hdev->stat.sco_tx++;
 455                break;
 456        }
 457
 458        skb_queue_tail(&priv->adapter->tx_queue, skb);
 459
 460        if (!priv->adapter->is_suspended)
 461                wake_up_interruptible(&priv->main_thread.wait_q);
 462
 463        return 0;
 464}
 465
 466static int btmrvl_flush(struct hci_dev *hdev)
 467{
 468        struct btmrvl_private *priv = hci_get_drvdata(hdev);
 469
 470        skb_queue_purge(&priv->adapter->tx_queue);
 471
 472        return 0;
 473}
 474
 475static int btmrvl_close(struct hci_dev *hdev)
 476{
 477        struct btmrvl_private *priv = hci_get_drvdata(hdev);
 478
 479        skb_queue_purge(&priv->adapter->tx_queue);
 480
 481        return 0;
 482}
 483
 484static int btmrvl_open(struct hci_dev *hdev)
 485{
 486        return 0;
 487}
 488
 489static int btmrvl_download_cal_data(struct btmrvl_private *priv,
 490                                    u8 *data, int len)
 491{
 492        int ret;
 493
 494        data[0] = 0x00;
 495        data[1] = 0x00;
 496        data[2] = 0x00;
 497        data[3] = len;
 498
 499        print_hex_dump_bytes("Calibration data: ",
 500                             DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len);
 501
 502        ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
 503                                   BT_CAL_HDR_LEN + len);
 504        if (ret)
 505                BT_ERR("Failed to download calibration data");
 506
 507        return 0;
 508}
 509
 510static int btmrvl_check_device_tree(struct btmrvl_private *priv)
 511{
 512        struct device_node *dt_node;
 513        struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
 514        u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
 515        int ret = 0;
 516        u16 gpio, gap;
 517
 518        if (card->plt_of_node) {
 519                dt_node = card->plt_of_node;
 520                ret = of_property_read_u16(dt_node, "marvell,wakeup-pin",
 521                                           &gpio);
 522                if (ret)
 523                        gpio = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
 524
 525                ret = of_property_read_u16(dt_node, "marvell,wakeup-gap-ms",
 526                                           &gap);
 527                if (ret)
 528                        gap = (u8)(priv->btmrvl_dev.gpio_gap & 0x00ff);
 529
 530                priv->btmrvl_dev.gpio_gap = (gpio << 8) + gap;
 531
 532                ret = of_property_read_u8_array(dt_node, "marvell,cal-data",
 533                                                cal_data + BT_CAL_HDR_LEN,
 534                                                BT_CAL_DATA_SIZE);
 535                if (ret)
 536                        return ret;
 537
 538                BT_DBG("Use cal data from device tree");
 539                ret = btmrvl_download_cal_data(priv, cal_data,
 540                                               BT_CAL_DATA_SIZE);
 541                if (ret)
 542                        BT_ERR("Fail to download calibrate data");
 543        }
 544
 545        return ret;
 546}
 547
 548static int btmrvl_setup(struct hci_dev *hdev)
 549{
 550        struct btmrvl_private *priv = hci_get_drvdata(hdev);
 551        int ret;
 552
 553        ret = btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
 554        if (ret)
 555                return ret;
 556
 557        priv->btmrvl_dev.gpio_gap = 0xfffe;
 558
 559        btmrvl_check_device_tree(priv);
 560
 561        btmrvl_enable_sco_routing_to_host(priv);
 562
 563        btmrvl_pscan_window_reporting(priv, 0x01);
 564
 565        priv->btmrvl_dev.psmode = 1;
 566        btmrvl_enable_ps(priv);
 567
 568        btmrvl_send_hscfg_cmd(priv);
 569
 570        return 0;
 571}
 572
 573static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 574{
 575        struct sk_buff *skb;
 576        long ret;
 577        u8 buf[8];
 578
 579        buf[0] = MRVL_VENDOR_PKT;
 580        buf[1] = sizeof(bdaddr_t);
 581        memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
 582
 583        skb = __hci_cmd_sync(hdev, BT_CMD_SET_BDADDR, sizeof(buf), buf,
 584                             HCI_INIT_TIMEOUT);
 585        if (IS_ERR(skb)) {
 586                ret = PTR_ERR(skb);
 587                BT_ERR("%s: changing btmrvl device address failed (%ld)",
 588                       hdev->name, ret);
 589                return ret;
 590        }
 591        kfree_skb(skb);
 592
 593        return 0;
 594}
 595
 596/*
 597 * This function handles the event generated by firmware, rx data
 598 * received from firmware, and tx data sent from kernel.
 599 */
 600static int btmrvl_service_main_thread(void *data)
 601{
 602        struct btmrvl_thread *thread = data;
 603        struct btmrvl_private *priv = thread->priv;
 604        struct btmrvl_adapter *adapter = priv->adapter;
 605        wait_queue_entry_t wait;
 606        struct sk_buff *skb;
 607        ulong flags;
 608
 609        init_waitqueue_entry(&wait, current);
 610
 611        for (;;) {
 612                add_wait_queue(&thread->wait_q, &wait);
 613
 614                set_current_state(TASK_INTERRUPTIBLE);
 615                if (kthread_should_stop() || priv->surprise_removed) {
 616                        BT_DBG("main_thread: break from main thread");
 617                        break;
 618                }
 619
 620                if (adapter->wakeup_tries ||
 621                                ((!adapter->int_count) &&
 622                                (!priv->btmrvl_dev.tx_dnld_rdy ||
 623                                skb_queue_empty(&adapter->tx_queue)))) {
 624                        BT_DBG("main_thread is sleeping...");
 625                        schedule();
 626                }
 627
 628                set_current_state(TASK_RUNNING);
 629
 630                remove_wait_queue(&thread->wait_q, &wait);
 631
 632                BT_DBG("main_thread woke up");
 633
 634                if (kthread_should_stop() || priv->surprise_removed) {
 635                        BT_DBG("main_thread: break from main thread");
 636                        break;
 637                }
 638
 639                spin_lock_irqsave(&priv->driver_lock, flags);
 640                if (adapter->int_count) {
 641                        adapter->int_count = 0;
 642                        spin_unlock_irqrestore(&priv->driver_lock, flags);
 643                        priv->hw_process_int_status(priv);
 644                } else if (adapter->ps_state == PS_SLEEP &&
 645                                        !skb_queue_empty(&adapter->tx_queue)) {
 646                        spin_unlock_irqrestore(&priv->driver_lock, flags);
 647                        adapter->wakeup_tries++;
 648                        priv->hw_wakeup_firmware(priv);
 649                        continue;
 650                } else {
 651                        spin_unlock_irqrestore(&priv->driver_lock, flags);
 652                }
 653
 654                if (adapter->ps_state == PS_SLEEP)
 655                        continue;
 656
 657                if (!priv->btmrvl_dev.tx_dnld_rdy ||
 658                    priv->adapter->is_suspended)
 659                        continue;
 660
 661                skb = skb_dequeue(&adapter->tx_queue);
 662                if (skb) {
 663                        if (btmrvl_tx_pkt(priv, skb))
 664                                priv->btmrvl_dev.hcidev->stat.err_tx++;
 665                        else
 666                                priv->btmrvl_dev.hcidev->stat.byte_tx += skb->len;
 667
 668                        kfree_skb(skb);
 669                }
 670        }
 671
 672        return 0;
 673}
 674
 675int btmrvl_register_hdev(struct btmrvl_private *priv)
 676{
 677        struct hci_dev *hdev = NULL;
 678        int ret;
 679
 680        hdev = hci_alloc_dev();
 681        if (!hdev) {
 682                BT_ERR("Can not allocate HCI device");
 683                goto err_hdev;
 684        }
 685
 686        priv->btmrvl_dev.hcidev = hdev;
 687        hci_set_drvdata(hdev, priv);
 688
 689        hdev->bus   = HCI_SDIO;
 690        hdev->open  = btmrvl_open;
 691        hdev->close = btmrvl_close;
 692        hdev->flush = btmrvl_flush;
 693        hdev->send  = btmrvl_send_frame;
 694        hdev->setup = btmrvl_setup;
 695        hdev->set_bdaddr = btmrvl_set_bdaddr;
 696
 697        hdev->dev_type = priv->btmrvl_dev.dev_type;
 698
 699        ret = hci_register_dev(hdev);
 700        if (ret < 0) {
 701                BT_ERR("Can not register HCI device");
 702                goto err_hci_register_dev;
 703        }
 704
 705#ifdef CONFIG_DEBUG_FS
 706        btmrvl_debugfs_init(hdev);
 707#endif
 708
 709        return 0;
 710
 711err_hci_register_dev:
 712        hci_free_dev(hdev);
 713
 714err_hdev:
 715        /* Stop the thread servicing the interrupts */
 716        kthread_stop(priv->main_thread.task);
 717
 718        btmrvl_free_adapter(priv);
 719        kfree(priv);
 720
 721        return -ENOMEM;
 722}
 723EXPORT_SYMBOL_GPL(btmrvl_register_hdev);
 724
 725struct btmrvl_private *btmrvl_add_card(void *card)
 726{
 727        struct btmrvl_private *priv;
 728
 729        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 730        if (!priv) {
 731                BT_ERR("Can not allocate priv");
 732                goto err_priv;
 733        }
 734
 735        priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL);
 736        if (!priv->adapter) {
 737                BT_ERR("Allocate buffer for btmrvl_adapter failed!");
 738                goto err_adapter;
 739        }
 740
 741        btmrvl_init_adapter(priv);
 742
 743        BT_DBG("Starting kthread...");
 744        priv->main_thread.priv = priv;
 745        spin_lock_init(&priv->driver_lock);
 746
 747        init_waitqueue_head(&priv->main_thread.wait_q);
 748        priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
 749                                &priv->main_thread, "btmrvl_main_service");
 750        if (IS_ERR(priv->main_thread.task))
 751                goto err_thread;
 752
 753        priv->btmrvl_dev.card = card;
 754        priv->btmrvl_dev.tx_dnld_rdy = true;
 755
 756        return priv;
 757
 758err_thread:
 759        btmrvl_free_adapter(priv);
 760
 761err_adapter:
 762        kfree(priv);
 763
 764err_priv:
 765        return NULL;
 766}
 767EXPORT_SYMBOL_GPL(btmrvl_add_card);
 768
 769int btmrvl_remove_card(struct btmrvl_private *priv)
 770{
 771        struct hci_dev *hdev;
 772
 773        hdev = priv->btmrvl_dev.hcidev;
 774
 775        wake_up_interruptible(&priv->adapter->cmd_wait_q);
 776        wake_up_interruptible(&priv->adapter->event_hs_wait_q);
 777
 778        kthread_stop(priv->main_thread.task);
 779
 780#ifdef CONFIG_DEBUG_FS
 781        btmrvl_debugfs_remove(hdev);
 782#endif
 783
 784        hci_unregister_dev(hdev);
 785
 786        hci_free_dev(hdev);
 787
 788        priv->btmrvl_dev.hcidev = NULL;
 789
 790        btmrvl_free_adapter(priv);
 791
 792        kfree(priv);
 793
 794        return 0;
 795}
 796EXPORT_SYMBOL_GPL(btmrvl_remove_card);
 797
 798MODULE_AUTHOR("Marvell International Ltd.");
 799MODULE_DESCRIPTION("Marvell Bluetooth driver ver " VERSION);
 800MODULE_VERSION(VERSION);
 801MODULE_LICENSE("GPL v2");
 802