linux/drivers/bluetooth/btbcm.c
<<
>>
Prefs
   1/*
   2 *
   3 *  Bluetooth support for Broadcom devices
   4 *
   5 *  Copyright (C) 2015  Intel Corporation
   6 *
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; either version 2 of the License, or
  11 *  (at your option) any later version.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to the Free Software
  20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 *
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/firmware.h>
  26#include <asm/unaligned.h>
  27
  28#include <net/bluetooth/bluetooth.h>
  29#include <net/bluetooth/hci_core.h>
  30
  31#include "btbcm.h"
  32
  33#define VERSION "0.1"
  34
  35#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
  36#define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}})
  37#define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}})
  38
  39int btbcm_check_bdaddr(struct hci_dev *hdev)
  40{
  41        struct hci_rp_read_bd_addr *bda;
  42        struct sk_buff *skb;
  43
  44        skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
  45                             HCI_INIT_TIMEOUT);
  46        if (IS_ERR(skb)) {
  47                int err = PTR_ERR(skb);
  48                BT_ERR("%s: BCM: Reading device address failed (%d)",
  49                       hdev->name, err);
  50                return err;
  51        }
  52
  53        if (skb->len != sizeof(*bda)) {
  54                BT_ERR("%s: BCM: Device address length mismatch", hdev->name);
  55                kfree_skb(skb);
  56                return -EIO;
  57        }
  58
  59        bda = (struct hci_rp_read_bd_addr *)skb->data;
  60
  61        /* Check if the address indicates a controller with either an
  62         * invalid or default address. In both cases the device needs
  63         * to be marked as not having a valid address.
  64         *
  65         * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
  66         * with no configured address.
  67         *
  68         * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller
  69         * with waiting for configuration state.
  70         *
  71         * The address 43:30:B1:00:00:00 indicates a BCM4330B1 controller
  72         * with waiting for configuration state.
  73         */
  74        if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) ||
  75            !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) ||
  76            !bacmp(&bda->bdaddr, BDADDR_BCM4330B1)) {
  77                BT_INFO("%s: BCM: Using default device address (%pMR)",
  78                        hdev->name, &bda->bdaddr);
  79                set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
  80        }
  81
  82        kfree_skb(skb);
  83
  84        return 0;
  85}
  86EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
  87
  88int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
  89{
  90        struct sk_buff *skb;
  91        int err;
  92
  93        skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
  94        if (IS_ERR(skb)) {
  95                err = PTR_ERR(skb);
  96                BT_ERR("%s: BCM: Change address command failed (%d)",
  97                       hdev->name, err);
  98                return err;
  99        }
 100        kfree_skb(skb);
 101
 102        return 0;
 103}
 104EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
 105
 106int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
 107{
 108        const struct hci_command_hdr *cmd;
 109        const u8 *fw_ptr;
 110        size_t fw_size;
 111        struct sk_buff *skb;
 112        u16 opcode;
 113        int err = 0;
 114
 115        /* Start Download */
 116        skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
 117        if (IS_ERR(skb)) {
 118                err = PTR_ERR(skb);
 119                BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
 120                       hdev->name, err);
 121                goto done;
 122        }
 123        kfree_skb(skb);
 124
 125        /* 50 msec delay after Download Minidrv completes */
 126        msleep(50);
 127
 128        fw_ptr = fw->data;
 129        fw_size = fw->size;
 130
 131        while (fw_size >= sizeof(*cmd)) {
 132                const u8 *cmd_param;
 133
 134                cmd = (struct hci_command_hdr *)fw_ptr;
 135                fw_ptr += sizeof(*cmd);
 136                fw_size -= sizeof(*cmd);
 137
 138                if (fw_size < cmd->plen) {
 139                        BT_ERR("%s: BCM: Patch is corrupted", hdev->name);
 140                        err = -EINVAL;
 141                        goto done;
 142                }
 143
 144                cmd_param = fw_ptr;
 145                fw_ptr += cmd->plen;
 146                fw_size -= cmd->plen;
 147
 148                opcode = le16_to_cpu(cmd->opcode);
 149
 150                skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
 151                                     HCI_INIT_TIMEOUT);
 152                if (IS_ERR(skb)) {
 153                        err = PTR_ERR(skb);
 154                        BT_ERR("%s: BCM: Patch command %04x failed (%d)",
 155                               hdev->name, opcode, err);
 156                        goto done;
 157                }
 158                kfree_skb(skb);
 159        }
 160
 161        /* 250 msec delay after Launch Ram completes */
 162        msleep(250);
 163
 164done:
 165        return err;
 166}
 167EXPORT_SYMBOL(btbcm_patchram);
 168
 169static int btbcm_reset(struct hci_dev *hdev)
 170{
 171        struct sk_buff *skb;
 172
 173        skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
 174        if (IS_ERR(skb)) {
 175                int err = PTR_ERR(skb);
 176                BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err);
 177                return err;
 178        }
 179        kfree_skb(skb);
 180
 181        return 0;
 182}
 183
 184static struct sk_buff *btbcm_read_local_name(struct hci_dev *hdev)
 185{
 186        struct sk_buff *skb;
 187
 188        skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL,
 189                             HCI_INIT_TIMEOUT);
 190        if (IS_ERR(skb)) {
 191                BT_ERR("%s: BCM: Reading local name failed (%ld)",
 192                       hdev->name, PTR_ERR(skb));
 193                return skb;
 194        }
 195
 196        if (skb->len != sizeof(struct hci_rp_read_local_name)) {
 197                BT_ERR("%s: BCM: Local name length mismatch", hdev->name);
 198                kfree_skb(skb);
 199                return ERR_PTR(-EIO);
 200        }
 201
 202        return skb;
 203}
 204
 205static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
 206{
 207        struct sk_buff *skb;
 208
 209        skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
 210                             HCI_INIT_TIMEOUT);
 211        if (IS_ERR(skb)) {
 212                BT_ERR("%s: BCM: Reading local version info failed (%ld)",
 213                       hdev->name, PTR_ERR(skb));
 214                return skb;
 215        }
 216
 217        if (skb->len != sizeof(struct hci_rp_read_local_version)) {
 218                BT_ERR("%s: BCM: Local version length mismatch", hdev->name);
 219                kfree_skb(skb);
 220                return ERR_PTR(-EIO);
 221        }
 222
 223        return skb;
 224}
 225
 226static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
 227{
 228        struct sk_buff *skb;
 229
 230        skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
 231        if (IS_ERR(skb)) {
 232                BT_ERR("%s: BCM: Read verbose config info failed (%ld)",
 233                       hdev->name, PTR_ERR(skb));
 234                return skb;
 235        }
 236
 237        if (skb->len != 7) {
 238                BT_ERR("%s: BCM: Verbose config length mismatch", hdev->name);
 239                kfree_skb(skb);
 240                return ERR_PTR(-EIO);
 241        }
 242
 243        return skb;
 244}
 245
 246static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
 247{
 248        struct sk_buff *skb;
 249
 250        skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
 251        if (IS_ERR(skb)) {
 252                BT_ERR("%s: BCM: Read USB product info failed (%ld)",
 253                       hdev->name, PTR_ERR(skb));
 254                return skb;
 255        }
 256
 257        if (skb->len != 5) {
 258                BT_ERR("%s: BCM: USB product length mismatch", hdev->name);
 259                kfree_skb(skb);
 260                return ERR_PTR(-EIO);
 261        }
 262
 263        return skb;
 264}
 265
 266static const struct {
 267        u16 subver;
 268        const char *name;
 269} bcm_uart_subver_table[] = {
 270        { 0x4103, "BCM4330B1"   },      /* 002.001.003 */
 271        { 0x410e, "BCM43341B0"  },      /* 002.001.014 */
 272        { 0x4406, "BCM4324B3"   },      /* 002.004.006 */
 273        { 0x610c, "BCM4354"     },      /* 003.001.012 */
 274        { }
 275};
 276
 277int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len)
 278{
 279        u16 subver, rev;
 280        const char *hw_name = NULL;
 281        struct sk_buff *skb;
 282        struct hci_rp_read_local_version *ver;
 283        int i, err;
 284
 285        /* Reset */
 286        err = btbcm_reset(hdev);
 287        if (err)
 288                return err;
 289
 290        /* Read Local Version Info */
 291        skb = btbcm_read_local_version(hdev);
 292        if (IS_ERR(skb))
 293                return PTR_ERR(skb);
 294
 295        ver = (struct hci_rp_read_local_version *)skb->data;
 296        rev = le16_to_cpu(ver->hci_rev);
 297        subver = le16_to_cpu(ver->lmp_subver);
 298        kfree_skb(skb);
 299
 300        /* Read Verbose Config Version Info */
 301        skb = btbcm_read_verbose_config(hdev);
 302        if (IS_ERR(skb))
 303                return PTR_ERR(skb);
 304
 305        BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
 306        kfree_skb(skb);
 307
 308        switch ((rev & 0xf000) >> 12) {
 309        case 0:
 310        case 1:
 311        case 3:
 312                for (i = 0; bcm_uart_subver_table[i].name; i++) {
 313                        if (subver == bcm_uart_subver_table[i].subver) {
 314                                hw_name = bcm_uart_subver_table[i].name;
 315                                break;
 316                        }
 317                }
 318
 319                snprintf(fw_name, len, "brcm/%s.hcd", hw_name ? : "BCM");
 320                break;
 321        default:
 322                return 0;
 323        }
 324
 325        BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
 326                hw_name ? : "BCM", (subver & 0xe000) >> 13,
 327                (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
 328
 329        return 0;
 330}
 331EXPORT_SYMBOL_GPL(btbcm_initialize);
 332
 333int btbcm_finalize(struct hci_dev *hdev)
 334{
 335        struct sk_buff *skb;
 336        struct hci_rp_read_local_version *ver;
 337        u16 subver, rev;
 338        int err;
 339
 340        /* Reset */
 341        err = btbcm_reset(hdev);
 342        if (err)
 343                return err;
 344
 345        /* Read Local Version Info */
 346        skb = btbcm_read_local_version(hdev);
 347        if (IS_ERR(skb))
 348                return PTR_ERR(skb);
 349
 350        ver = (struct hci_rp_read_local_version *)skb->data;
 351        rev = le16_to_cpu(ver->hci_rev);
 352        subver = le16_to_cpu(ver->lmp_subver);
 353        kfree_skb(skb);
 354
 355        BT_INFO("%s: BCM (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
 356                (subver & 0xe000) >> 13, (subver & 0x1f00) >> 8,
 357                (subver & 0x00ff), rev & 0x0fff);
 358
 359        btbcm_check_bdaddr(hdev);
 360
 361        set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 362
 363        return 0;
 364}
 365EXPORT_SYMBOL_GPL(btbcm_finalize);
 366
 367static const struct {
 368        u16 subver;
 369        const char *name;
 370} bcm_usb_subver_table[] = {
 371        { 0x210b, "BCM43142A0"  },      /* 001.001.011 */
 372        { 0x2112, "BCM4314A0"   },      /* 001.001.018 */
 373        { 0x2118, "BCM20702A0"  },      /* 001.001.024 */
 374        { 0x2126, "BCM4335A0"   },      /* 001.001.038 */
 375        { 0x220e, "BCM20702A1"  },      /* 001.002.014 */
 376        { 0x230f, "BCM4354A2"   },      /* 001.003.015 */
 377        { 0x4106, "BCM4335B0"   },      /* 002.001.006 */
 378        { 0x410e, "BCM20702B0"  },      /* 002.001.014 */
 379        { 0x6109, "BCM4335C0"   },      /* 003.001.009 */
 380        { 0x610c, "BCM4354"     },      /* 003.001.012 */
 381        { }
 382};
 383
 384int btbcm_setup_patchram(struct hci_dev *hdev)
 385{
 386        char fw_name[64];
 387        const struct firmware *fw;
 388        u16 subver, rev, pid, vid;
 389        const char *hw_name = NULL;
 390        struct sk_buff *skb;
 391        struct hci_rp_read_local_version *ver;
 392        int i, err;
 393
 394        /* Reset */
 395        err = btbcm_reset(hdev);
 396        if (err)
 397                return err;
 398
 399        /* Read Local Version Info */
 400        skb = btbcm_read_local_version(hdev);
 401        if (IS_ERR(skb))
 402                return PTR_ERR(skb);
 403
 404        ver = (struct hci_rp_read_local_version *)skb->data;
 405        rev = le16_to_cpu(ver->hci_rev);
 406        subver = le16_to_cpu(ver->lmp_subver);
 407        kfree_skb(skb);
 408
 409        /* Read Verbose Config Version Info */
 410        skb = btbcm_read_verbose_config(hdev);
 411        if (IS_ERR(skb))
 412                return PTR_ERR(skb);
 413
 414        BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
 415        kfree_skb(skb);
 416
 417        /* Read Local Name */
 418        skb = btbcm_read_local_name(hdev);
 419        if (IS_ERR(skb))
 420                return PTR_ERR(skb);
 421
 422        BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
 423        kfree_skb(skb);
 424
 425        switch ((rev & 0xf000) >> 12) {
 426        case 0:
 427        case 3:
 428                for (i = 0; bcm_uart_subver_table[i].name; i++) {
 429                        if (subver == bcm_uart_subver_table[i].subver) {
 430                                hw_name = bcm_uart_subver_table[i].name;
 431                                break;
 432                        }
 433                }
 434
 435                snprintf(fw_name, sizeof(fw_name), "brcm/%s.hcd",
 436                         hw_name ? : "BCM");
 437                break;
 438        case 1:
 439        case 2:
 440                /* Read USB Product Info */
 441                skb = btbcm_read_usb_product(hdev);
 442                if (IS_ERR(skb))
 443                        return PTR_ERR(skb);
 444
 445                vid = get_unaligned_le16(skb->data + 1);
 446                pid = get_unaligned_le16(skb->data + 3);
 447                kfree_skb(skb);
 448
 449                for (i = 0; bcm_usb_subver_table[i].name; i++) {
 450                        if (subver == bcm_usb_subver_table[i].subver) {
 451                                hw_name = bcm_usb_subver_table[i].name;
 452                                break;
 453                        }
 454                }
 455
 456                snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
 457                         hw_name ? : "BCM", vid, pid);
 458                break;
 459        default:
 460                return 0;
 461        }
 462
 463        BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
 464                hw_name ? : "BCM", (subver & 0xe000) >> 13,
 465                (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
 466
 467        err = request_firmware(&fw, fw_name, &hdev->dev);
 468        if (err < 0) {
 469                BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name);
 470                goto done;
 471        }
 472
 473        btbcm_patchram(hdev, fw);
 474
 475        release_firmware(fw);
 476
 477        /* Reset */
 478        err = btbcm_reset(hdev);
 479        if (err)
 480                return err;
 481
 482        /* Read Local Version Info */
 483        skb = btbcm_read_local_version(hdev);
 484        if (IS_ERR(skb))
 485                return PTR_ERR(skb);
 486
 487        ver = (struct hci_rp_read_local_version *)skb->data;
 488        rev = le16_to_cpu(ver->hci_rev);
 489        subver = le16_to_cpu(ver->lmp_subver);
 490        kfree_skb(skb);
 491
 492        BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
 493                hw_name ? : "BCM", (subver & 0xe000) >> 13,
 494                (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
 495
 496        /* Read Local Name */
 497        skb = btbcm_read_local_name(hdev);
 498        if (IS_ERR(skb))
 499                return PTR_ERR(skb);
 500
 501        BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
 502        kfree_skb(skb);
 503
 504done:
 505        btbcm_check_bdaddr(hdev);
 506
 507        set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 508
 509        return 0;
 510}
 511EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
 512
 513int btbcm_setup_apple(struct hci_dev *hdev)
 514{
 515        struct sk_buff *skb;
 516        int err;
 517
 518        /* Reset */
 519        err = btbcm_reset(hdev);
 520        if (err)
 521                return err;
 522
 523        /* Read Verbose Config Version Info */
 524        skb = btbcm_read_verbose_config(hdev);
 525        if (!IS_ERR(skb)) {
 526                BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name,
 527                        skb->data[1], get_unaligned_le16(skb->data + 5));
 528                kfree_skb(skb);
 529        }
 530
 531        /* Read USB Product Info */
 532        skb = btbcm_read_usb_product(hdev);
 533        if (!IS_ERR(skb)) {
 534                BT_INFO("%s: BCM: product %4.4x:%4.4x", hdev->name,
 535                        get_unaligned_le16(skb->data + 1),
 536                        get_unaligned_le16(skb->data + 3));
 537                kfree_skb(skb);
 538        }
 539
 540        /* Read Local Name */
 541        skb = btbcm_read_local_name(hdev);
 542        if (!IS_ERR(skb)) {
 543                BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
 544                kfree_skb(skb);
 545        }
 546
 547        set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 548
 549        return 0;
 550}
 551EXPORT_SYMBOL_GPL(btbcm_setup_apple);
 552
 553MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 554MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
 555MODULE_VERSION(VERSION);
 556MODULE_LICENSE("GPL");
 557