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 return 0; 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 504 btbcm_check_bdaddr(hdev); 505 506 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); 507 508 return 0; 509} 510EXPORT_SYMBOL_GPL(btbcm_setup_patchram); 511 512int btbcm_setup_apple(struct hci_dev *hdev) 513{ 514 struct sk_buff *skb; 515 int err; 516 517 /* Reset */ 518 err = btbcm_reset(hdev); 519 if (err) 520 return err; 521 522 /* Read Verbose Config Version Info */ 523 skb = btbcm_read_verbose_config(hdev); 524 if (!IS_ERR(skb)) { 525 BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, 526 skb->data[1], get_unaligned_le16(skb->data + 5)); 527 kfree_skb(skb); 528 } 529 530 /* Read USB Product Info */ 531 skb = btbcm_read_usb_product(hdev); 532 if (!IS_ERR(skb)) { 533 BT_INFO("%s: BCM: product %4.4x:%4.4x", hdev->name, 534 get_unaligned_le16(skb->data + 1), 535 get_unaligned_le16(skb->data + 3)); 536 kfree_skb(skb); 537 } 538 539 /* Read Local Name */ 540 skb = btbcm_read_local_name(hdev); 541 if (!IS_ERR(skb)) { 542 BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1)); 543 kfree_skb(skb); 544 } 545 546 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); 547 548 return 0; 549} 550EXPORT_SYMBOL_GPL(btbcm_setup_apple); 551 552MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 553MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION); 554MODULE_VERSION(VERSION); 555MODULE_LICENSE("GPL"); 556