diff options
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r-- | drivers/bluetooth/btusb.c | 403 |
1 files changed, 401 insertions, 2 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index de7b236eeae7..d21f3b4176d3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
26 | #include <linux/firmware.h> | 26 | #include <linux/firmware.h> |
27 | #include <asm/unaligned.h> | ||
27 | 28 | ||
28 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
29 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
@@ -57,6 +58,7 @@ static struct usb_driver btusb_driver; | |||
57 | #define BTUSB_AMP 0x4000 | 58 | #define BTUSB_AMP 0x4000 |
58 | #define BTUSB_QCA_ROME 0x8000 | 59 | #define BTUSB_QCA_ROME 0x8000 |
59 | #define BTUSB_BCM_APPLE 0x10000 | 60 | #define BTUSB_BCM_APPLE 0x10000 |
61 | #define BTUSB_REALTEK 0x20000 | ||
60 | 62 | ||
61 | static const struct usb_device_id btusb_table[] = { | 63 | static const struct usb_device_id btusb_table[] = { |
62 | /* Generic Bluetooth USB device */ | 64 | /* Generic Bluetooth USB device */ |
@@ -288,6 +290,28 @@ static const struct usb_device_id blacklist_table[] = { | |||
288 | { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), | 290 | { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), |
289 | .driver_info = BTUSB_IGNORE }, | 291 | .driver_info = BTUSB_IGNORE }, |
290 | 292 | ||
293 | /* Realtek Bluetooth devices */ | ||
294 | { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), | ||
295 | .driver_info = BTUSB_REALTEK }, | ||
296 | |||
297 | /* Additional Realtek 8723AE Bluetooth devices */ | ||
298 | { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, | ||
299 | { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK }, | ||
300 | |||
301 | /* Additional Realtek 8723BE Bluetooth devices */ | ||
302 | { USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK }, | ||
303 | { USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_REALTEK }, | ||
304 | { USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK }, | ||
305 | { USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK }, | ||
306 | { USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK }, | ||
307 | |||
308 | /* Additional Realtek 8821AE Bluetooth devices */ | ||
309 | { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, | ||
310 | { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK }, | ||
311 | { USB_DEVICE(0x13d3, 0x3458), .driver_info = BTUSB_REALTEK }, | ||
312 | { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK }, | ||
313 | { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK }, | ||
314 | |||
291 | { } /* Terminating entry */ | 315 | { } /* Terminating entry */ |
292 | }; | 316 | }; |
293 | 317 | ||
@@ -892,7 +916,7 @@ static int btusb_open(struct hci_dev *hdev) | |||
892 | */ | 916 | */ |
893 | if (data->setup_on_usb) { | 917 | if (data->setup_on_usb) { |
894 | err = data->setup_on_usb(hdev); | 918 | err = data->setup_on_usb(hdev); |
895 | if (err <0) | 919 | if (err < 0) |
896 | return err; | 920 | return err; |
897 | } | 921 | } |
898 | 922 | ||
@@ -1345,6 +1369,378 @@ static int btusb_setup_csr(struct hci_dev *hdev) | |||
1345 | return ret; | 1369 | return ret; |
1346 | } | 1370 | } |
1347 | 1371 | ||
1372 | #define RTL_FRAG_LEN 252 | ||
1373 | |||
1374 | struct rtl_download_cmd { | ||
1375 | __u8 index; | ||
1376 | __u8 data[RTL_FRAG_LEN]; | ||
1377 | } __packed; | ||
1378 | |||
1379 | struct rtl_download_response { | ||
1380 | __u8 status; | ||
1381 | __u8 index; | ||
1382 | } __packed; | ||
1383 | |||
1384 | struct rtl_rom_version_evt { | ||
1385 | __u8 status; | ||
1386 | __u8 version; | ||
1387 | } __packed; | ||
1388 | |||
1389 | struct rtl_epatch_header { | ||
1390 | __u8 signature[8]; | ||
1391 | __le32 fw_version; | ||
1392 | __le16 num_patches; | ||
1393 | } __packed; | ||
1394 | |||
1395 | #define RTL_EPATCH_SIGNATURE "Realtech" | ||
1396 | #define RTL_ROM_LMP_3499 0x3499 | ||
1397 | #define RTL_ROM_LMP_8723A 0x1200 | ||
1398 | #define RTL_ROM_LMP_8723B 0x8723 | ||
1399 | #define RTL_ROM_LMP_8821A 0x8821 | ||
1400 | #define RTL_ROM_LMP_8761A 0x8761 | ||
1401 | |||
1402 | static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) | ||
1403 | { | ||
1404 | struct rtl_rom_version_evt *rom_version; | ||
1405 | struct sk_buff *skb; | ||
1406 | int ret; | ||
1407 | |||
1408 | /* Read RTL ROM version command */ | ||
1409 | skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT); | ||
1410 | if (IS_ERR(skb)) { | ||
1411 | BT_ERR("%s: Read ROM version failed (%ld)", | ||
1412 | hdev->name, PTR_ERR(skb)); | ||
1413 | return PTR_ERR(skb); | ||
1414 | } | ||
1415 | |||
1416 | if (skb->len != sizeof(*rom_version)) { | ||
1417 | BT_ERR("%s: RTL version event length mismatch", hdev->name); | ||
1418 | kfree_skb(skb); | ||
1419 | return -EIO; | ||
1420 | } | ||
1421 | |||
1422 | rom_version = (struct rtl_rom_version_evt *)skb->data; | ||
1423 | BT_INFO("%s: rom_version status=%x version=%x", | ||
1424 | hdev->name, rom_version->status, rom_version->version); | ||
1425 | |||
1426 | ret = rom_version->status; | ||
1427 | if (ret == 0) | ||
1428 | *version = rom_version->version; | ||
1429 | |||
1430 | kfree_skb(skb); | ||
1431 | return ret; | ||
1432 | } | ||
1433 | |||
1434 | static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver, | ||
1435 | const struct firmware *fw, | ||
1436 | unsigned char **_buf) | ||
1437 | { | ||
1438 | const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; | ||
1439 | struct rtl_epatch_header *epatch_info; | ||
1440 | unsigned char *buf; | ||
1441 | int i, ret, len; | ||
1442 | size_t min_size; | ||
1443 | u8 opcode, length, data, rom_version = 0; | ||
1444 | int project_id = -1; | ||
1445 | const unsigned char *fwptr, *chip_id_base; | ||
1446 | const unsigned char *patch_length_base, *patch_offset_base; | ||
1447 | u32 patch_offset = 0; | ||
1448 | u16 patch_length, num_patches; | ||
1449 | const u16 project_id_to_lmp_subver[] = { | ||
1450 | RTL_ROM_LMP_8723A, | ||
1451 | RTL_ROM_LMP_8723B, | ||
1452 | RTL_ROM_LMP_8821A, | ||
1453 | RTL_ROM_LMP_8761A | ||
1454 | }; | ||
1455 | |||
1456 | ret = rtl_read_rom_version(hdev, &rom_version); | ||
1457 | if (ret) | ||
1458 | return -bt_to_errno(ret); | ||
1459 | |||
1460 | min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; | ||
1461 | if (fw->size < min_size) | ||
1462 | return -EINVAL; | ||
1463 | |||
1464 | fwptr = fw->data + fw->size - sizeof(extension_sig); | ||
1465 | if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) { | ||
1466 | BT_ERR("%s: extension section signature mismatch", hdev->name); | ||
1467 | return -EINVAL; | ||
1468 | } | ||
1469 | |||
1470 | /* Loop from the end of the firmware parsing instructions, until | ||
1471 | * we find an instruction that identifies the "project ID" for the | ||
1472 | * hardware supported by this firwmare file. | ||
1473 | * Once we have that, we double-check that that project_id is suitable | ||
1474 | * for the hardware we are working with. | ||
1475 | */ | ||
1476 | while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) { | ||
1477 | opcode = *--fwptr; | ||
1478 | length = *--fwptr; | ||
1479 | data = *--fwptr; | ||
1480 | |||
1481 | BT_DBG("check op=%x len=%x data=%x", opcode, length, data); | ||
1482 | |||
1483 | if (opcode == 0xff) /* EOF */ | ||
1484 | break; | ||
1485 | |||
1486 | if (length == 0) { | ||
1487 | BT_ERR("%s: found instruction with length 0", | ||
1488 | hdev->name); | ||
1489 | return -EINVAL; | ||
1490 | } | ||
1491 | |||
1492 | if (opcode == 0 && length == 1) { | ||
1493 | project_id = data; | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | fwptr -= length; | ||
1498 | } | ||
1499 | |||
1500 | if (project_id < 0) { | ||
1501 | BT_ERR("%s: failed to find version instruction", hdev->name); | ||
1502 | return -EINVAL; | ||
1503 | } | ||
1504 | |||
1505 | if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) { | ||
1506 | BT_ERR("%s: unknown project id %d", hdev->name, project_id); | ||
1507 | return -EINVAL; | ||
1508 | } | ||
1509 | |||
1510 | if (lmp_subver != project_id_to_lmp_subver[project_id]) { | ||
1511 | BT_ERR("%s: firmware is for %x but this is a %x", hdev->name, | ||
1512 | project_id_to_lmp_subver[project_id], lmp_subver); | ||
1513 | return -EINVAL; | ||
1514 | } | ||
1515 | |||
1516 | epatch_info = (struct rtl_epatch_header *)fw->data; | ||
1517 | if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) { | ||
1518 | BT_ERR("%s: bad EPATCH signature", hdev->name); | ||
1519 | return -EINVAL; | ||
1520 | } | ||
1521 | |||
1522 | num_patches = le16_to_cpu(epatch_info->num_patches); | ||
1523 | BT_DBG("fw_version=%x, num_patches=%d", | ||
1524 | le32_to_cpu(epatch_info->fw_version), num_patches); | ||
1525 | |||
1526 | /* After the rtl_epatch_header there is a funky patch metadata section. | ||
1527 | * Assuming 2 patches, the layout is: | ||
1528 | * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2 | ||
1529 | * | ||
1530 | * Find the right patch for this chip. | ||
1531 | */ | ||
1532 | min_size += 8 * num_patches; | ||
1533 | if (fw->size < min_size) | ||
1534 | return -EINVAL; | ||
1535 | |||
1536 | chip_id_base = fw->data + sizeof(struct rtl_epatch_header); | ||
1537 | patch_length_base = chip_id_base + (sizeof(u16) * num_patches); | ||
1538 | patch_offset_base = patch_length_base + (sizeof(u16) * num_patches); | ||
1539 | for (i = 0; i < num_patches; i++) { | ||
1540 | u16 chip_id = get_unaligned_le16(chip_id_base + | ||
1541 | (i * sizeof(u16))); | ||
1542 | if (chip_id == rom_version + 1) { | ||
1543 | patch_length = get_unaligned_le16(patch_length_base + | ||
1544 | (i * sizeof(u16))); | ||
1545 | patch_offset = get_unaligned_le32(patch_offset_base + | ||
1546 | (i * sizeof(u32))); | ||
1547 | break; | ||
1548 | } | ||
1549 | } | ||
1550 | |||
1551 | if (!patch_offset) { | ||
1552 | BT_ERR("%s: didn't find patch for chip id %d", | ||
1553 | hdev->name, rom_version); | ||
1554 | return -EINVAL; | ||
1555 | } | ||
1556 | |||
1557 | BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i); | ||
1558 | min_size = patch_offset + patch_length; | ||
1559 | if (fw->size < min_size) | ||
1560 | return -EINVAL; | ||
1561 | |||
1562 | /* Copy the firmware into a new buffer and write the version at | ||
1563 | * the end. | ||
1564 | */ | ||
1565 | len = patch_length; | ||
1566 | buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL); | ||
1567 | if (!buf) | ||
1568 | return -ENOMEM; | ||
1569 | |||
1570 | memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); | ||
1571 | |||
1572 | *_buf = buf; | ||
1573 | return len; | ||
1574 | } | ||
1575 | |||
1576 | static int rtl_download_firmware(struct hci_dev *hdev, | ||
1577 | const unsigned char *data, int fw_len) | ||
1578 | { | ||
1579 | struct rtl_download_cmd *dl_cmd; | ||
1580 | int frag_num = fw_len / RTL_FRAG_LEN + 1; | ||
1581 | int frag_len = RTL_FRAG_LEN; | ||
1582 | int ret = 0; | ||
1583 | int i; | ||
1584 | |||
1585 | dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL); | ||
1586 | if (!dl_cmd) | ||
1587 | return -ENOMEM; | ||
1588 | |||
1589 | for (i = 0; i < frag_num; i++) { | ||
1590 | struct rtl_download_response *dl_resp; | ||
1591 | struct sk_buff *skb; | ||
1592 | |||
1593 | BT_DBG("download fw (%d/%d)", i, frag_num); | ||
1594 | |||
1595 | dl_cmd->index = i; | ||
1596 | if (i == (frag_num - 1)) { | ||
1597 | dl_cmd->index |= 0x80; /* data end */ | ||
1598 | frag_len = fw_len % RTL_FRAG_LEN; | ||
1599 | } | ||
1600 | memcpy(dl_cmd->data, data, frag_len); | ||
1601 | |||
1602 | /* Send download command */ | ||
1603 | skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd, | ||
1604 | HCI_INIT_TIMEOUT); | ||
1605 | if (IS_ERR(skb)) { | ||
1606 | BT_ERR("%s: download fw command failed (%ld)", | ||
1607 | hdev->name, PTR_ERR(skb)); | ||
1608 | ret = -PTR_ERR(skb); | ||
1609 | goto out; | ||
1610 | } | ||
1611 | |||
1612 | if (skb->len != sizeof(*dl_resp)) { | ||
1613 | BT_ERR("%s: download fw event length mismatch", | ||
1614 | hdev->name); | ||
1615 | kfree_skb(skb); | ||
1616 | ret = -EIO; | ||
1617 | goto out; | ||
1618 | } | ||
1619 | |||
1620 | dl_resp = (struct rtl_download_response *)skb->data; | ||
1621 | if (dl_resp->status != 0) { | ||
1622 | kfree_skb(skb); | ||
1623 | ret = bt_to_errno(dl_resp->status); | ||
1624 | goto out; | ||
1625 | } | ||
1626 | |||
1627 | kfree_skb(skb); | ||
1628 | data += RTL_FRAG_LEN; | ||
1629 | } | ||
1630 | |||
1631 | out: | ||
1632 | kfree(dl_cmd); | ||
1633 | return ret; | ||
1634 | } | ||
1635 | |||
1636 | static int btusb_setup_rtl8723a(struct hci_dev *hdev) | ||
1637 | { | ||
1638 | struct btusb_data *data = dev_get_drvdata(&hdev->dev); | ||
1639 | struct usb_device *udev = interface_to_usbdev(data->intf); | ||
1640 | const struct firmware *fw; | ||
1641 | int ret; | ||
1642 | |||
1643 | BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name); | ||
1644 | ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &udev->dev); | ||
1645 | if (ret < 0) { | ||
1646 | BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name); | ||
1647 | return ret; | ||
1648 | } | ||
1649 | |||
1650 | if (fw->size < 8) { | ||
1651 | ret = -EINVAL; | ||
1652 | goto out; | ||
1653 | } | ||
1654 | |||
1655 | /* Check that the firmware doesn't have the epatch signature | ||
1656 | * (which is only for RTL8723B and newer). | ||
1657 | */ | ||
1658 | if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) { | ||
1659 | BT_ERR("%s: unexpected EPATCH signature!", hdev->name); | ||
1660 | ret = -EINVAL; | ||
1661 | goto out; | ||
1662 | } | ||
1663 | |||
1664 | ret = rtl_download_firmware(hdev, fw->data, fw->size); | ||
1665 | |||
1666 | out: | ||
1667 | release_firmware(fw); | ||
1668 | return ret; | ||
1669 | } | ||
1670 | |||
1671 | static int btusb_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, | ||
1672 | const char *fw_name) | ||
1673 | { | ||
1674 | struct btusb_data *data = dev_get_drvdata(&hdev->dev); | ||
1675 | struct usb_device *udev = interface_to_usbdev(data->intf); | ||
1676 | unsigned char *fw_data = NULL; | ||
1677 | const struct firmware *fw; | ||
1678 | int ret; | ||
1679 | |||
1680 | BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); | ||
1681 | ret = request_firmware(&fw, fw_name, &udev->dev); | ||
1682 | if (ret < 0) { | ||
1683 | BT_ERR("%s: Failed to load %s", hdev->name, fw_name); | ||
1684 | return ret; | ||
1685 | } | ||
1686 | |||
1687 | ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); | ||
1688 | if (ret < 0) | ||
1689 | goto out; | ||
1690 | |||
1691 | ret = rtl_download_firmware(hdev, fw_data, ret); | ||
1692 | kfree(fw_data); | ||
1693 | if (ret < 0) | ||
1694 | goto out; | ||
1695 | |||
1696 | out: | ||
1697 | release_firmware(fw); | ||
1698 | return ret; | ||
1699 | } | ||
1700 | |||
1701 | static int btusb_setup_realtek(struct hci_dev *hdev) | ||
1702 | { | ||
1703 | struct sk_buff *skb; | ||
1704 | struct hci_rp_read_local_version *resp; | ||
1705 | u16 lmp_subver; | ||
1706 | |||
1707 | skb = btusb_read_local_version(hdev); | ||
1708 | if (IS_ERR(skb)) | ||
1709 | return -PTR_ERR(skb); | ||
1710 | |||
1711 | resp = (struct hci_rp_read_local_version *)skb->data; | ||
1712 | BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x " | ||
1713 | "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev, | ||
1714 | resp->lmp_ver, resp->lmp_subver); | ||
1715 | |||
1716 | lmp_subver = le16_to_cpu(resp->lmp_subver); | ||
1717 | kfree_skb(skb); | ||
1718 | |||
1719 | /* Match a set of subver values that correspond to stock firmware, | ||
1720 | * which is not compatible with standard btusb. | ||
1721 | * If matched, upload an alternative firmware that does conform to | ||
1722 | * standard btusb. Once that firmware is uploaded, the subver changes | ||
1723 | * to a different value. | ||
1724 | */ | ||
1725 | switch (lmp_subver) { | ||
1726 | case RTL_ROM_LMP_8723A: | ||
1727 | case RTL_ROM_LMP_3499: | ||
1728 | return btusb_setup_rtl8723a(hdev); | ||
1729 | case RTL_ROM_LMP_8723B: | ||
1730 | return btusb_setup_rtl8723b(hdev, lmp_subver, | ||
1731 | "rtl_bt/rtl8723b_fw.bin"); | ||
1732 | case RTL_ROM_LMP_8821A: | ||
1733 | return btusb_setup_rtl8723b(hdev, lmp_subver, | ||
1734 | "rtl_bt/rtl8821a_fw.bin"); | ||
1735 | case RTL_ROM_LMP_8761A: | ||
1736 | return btusb_setup_rtl8723b(hdev, lmp_subver, | ||
1737 | "rtl_bt/rtl8761a_fw.bin"); | ||
1738 | default: | ||
1739 | BT_INFO("rtl: assuming no firmware upload needed."); | ||
1740 | return 0; | ||
1741 | } | ||
1742 | } | ||
1743 | |||
1348 | static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, | 1744 | static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, |
1349 | struct intel_version *ver) | 1745 | struct intel_version *ver) |
1350 | { | 1746 | { |
@@ -2577,7 +2973,7 @@ static int btusb_setup_qca(struct hci_dev *hdev) | |||
2577 | int i, err; | 2973 | int i, err; |
2578 | 2974 | ||
2579 | err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver, | 2975 | err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver, |
2580 | sizeof(ver)); | 2976 | sizeof(ver)); |
2581 | if (err < 0) | 2977 | if (err < 0) |
2582 | return err; | 2978 | return err; |
2583 | 2979 | ||
@@ -2776,6 +3172,9 @@ static int btusb_probe(struct usb_interface *intf, | |||
2776 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; | 3172 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; |
2777 | } | 3173 | } |
2778 | 3174 | ||
3175 | if (id->driver_info & BTUSB_REALTEK) | ||
3176 | hdev->setup = btusb_setup_realtek; | ||
3177 | |||
2779 | if (id->driver_info & BTUSB_AMP) { | 3178 | if (id->driver_info & BTUSB_AMP) { |
2780 | /* AMP controllers do not support SCO packets */ | 3179 | /* AMP controllers do not support SCO packets */ |
2781 | data->isoc = NULL; | 3180 | data->isoc = NULL; |