int btbcm_check_bdaddr(struct hci_dev *hdev) { struct hci_rp_read_bd_addr *bda; struct sk_buff *skb; skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { int err = PTR_ERR(skb); BT_ERR("%s: BCM: Reading device address failed (%d)", hdev->name, err); return err; } if (skb->len != sizeof(*bda)) { BT_ERR("%s: BCM: Device address length mismatch", hdev->name); kfree_skb(skb); return -EIO; } bda = (struct hci_rp_read_bd_addr *)skb->data; if (bda->status) { BT_ERR("%s: BCM: Device address result failed (%02x)", hdev->name, bda->status); kfree_skb(skb); return -bt_to_errno(bda->status); } /* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller * with no configured address. */ if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) { BT_INFO("%s: BCM: Using default device address (%pMR)", hdev->name, &bda->bdaddr); set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); } kfree_skb(skb); return 0; }
static int btusb_setup_csr(struct hci_dev *hdev) { struct hci_rp_read_local_version *rp; struct sk_buff *skb; int ret; BT_DBG("%s", hdev->name); skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("Reading local version failed (%ld)", -PTR_ERR(skb)); return -PTR_ERR(skb); } rp = (struct hci_rp_read_local_version *) skb->data; if (!rp->status) { if (le16_to_cpu(rp->manufacturer) != 10) { /* Clear the reset quirk since this is not an actual * early Bluetooth 1.1 device from CSR. */ clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); /* These fake CSR controllers have all a broken * stored link key handling and so just disable it. */ set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks); } } ret = -bt_to_errno(rp->status); kfree_skb(skb); return ret; }
static int btusb_setup_intel(struct hci_dev *hdev) { struct sk_buff *skb; const struct firmware *fw; const u8 *fw_ptr; int disable_patch; struct intel_version *ver; const u8 mfg_enable[] = { 0x01, 0x00 }; const u8 mfg_disable[] = { 0x00, 0x00 }; const u8 mfg_reset_deactivate[] = { 0x00, 0x01 }; const u8 mfg_reset_activate[] = { 0x00, 0x02 }; BT_DBG("%s", hdev->name); /* The controller has a bug with the first HCI command sent to it * returning number of completed commands as zero. This would stall the * command processing in the Bluetooth core. * * As a workaround, send HCI Reset command first which will reset the * number of completed commands and allow normal command processing * from now on. */ skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s sending initial HCI reset command failed (%ld)", hdev->name, PTR_ERR(skb)); return PTR_ERR(skb); } kfree_skb(skb); /* Read Intel specific controller version first to allow selection of * which firmware file to load. * * The returned information are hardware variant and revision plus * firmware variant, revision and build number. */ skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s reading Intel fw version command failed (%ld)", hdev->name, PTR_ERR(skb)); return PTR_ERR(skb); } if (skb->len != sizeof(*ver)) { BT_ERR("%s Intel version event length mismatch", hdev->name); kfree_skb(skb); return -EIO; } ver = (struct intel_version *)skb->data; if (ver->status) { BT_ERR("%s Intel fw version event failed (%02x)", hdev->name, ver->status); kfree_skb(skb); return -bt_to_errno(ver->status); } BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x", hdev->name, ver->hw_platform, ver->hw_variant, ver->hw_revision, ver->fw_variant, ver->fw_revision, ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy, ver->fw_patch_num); /* fw_patch_num indicates the version of patch the device currently * have. If there is no patch data in the device, it is always 0x00. * So, if it is other than 0x00, no need to patch the deivce again. */ if (ver->fw_patch_num) { BT_INFO("%s: Intel device is already patched. patch num: %02x", hdev->name, ver->fw_patch_num); kfree_skb(skb); return 0; } /* Opens the firmware patch file based on the firmware version read * from the controller. If it fails to open the matching firmware * patch file, it tries to open the default firmware patch file. * If no patch file is found, allow the device to operate without * a patch. */ fw = btusb_setup_intel_get_fw(hdev, ver); if (!fw) { kfree_skb(skb); return 0; } fw_ptr = fw->data; /* This Intel specific command enables the manufacturer mode of the * controller. * * Only while this mode is enabled, the driver can download the * firmware patch data and configuration parameters. */ skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s entering Intel manufacturer mode failed (%ld)", hdev->name, PTR_ERR(skb)); release_firmware(fw); return PTR_ERR(skb); } if (skb->data[0]) { u8 evt_status = skb->data[0]; BT_ERR("%s enable Intel manufacturer mode event failed (%02x)", hdev->name, evt_status); kfree_skb(skb); release_firmware(fw); return -bt_to_errno(evt_status); } kfree_skb(skb); disable_patch = 1; /* The firmware data file consists of list of Intel specific HCI * commands and its expected events. The first byte indicates the * type of the message, either HCI command or HCI event. * * It reads the command and its expected event from the firmware file, * and send to the controller. Once __hci_cmd_sync_ev() returns, * the returned event is compared with the event read from the firmware * file and it will continue until all the messages are downloaded to * the controller. * * Once the firmware patching is completed successfully, * the manufacturer mode is disabled with reset and activating the * downloaded patch. * * If the firmware patching fails, the manufacturer mode is * disabled with reset and deactivating the patch. * * If the default patch file is used, no reset is done when disabling * the manufacturer. */ while (fw->size > fw_ptr - fw->data) { int ret; ret = btusb_setup_intel_patching(hdev, fw, &fw_ptr, &disable_patch); if (ret < 0) goto exit_mfg_deactivate; } release_firmware(fw); if (disable_patch) goto exit_mfg_disable; /* Patching completed successfully and disable the manufacturer mode * with reset and activate the downloaded firmware patches. */ skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate), mfg_reset_activate, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", hdev->name, PTR_ERR(skb)); return PTR_ERR(skb); } kfree_skb(skb); BT_INFO("%s: Intel Bluetooth firmware patch completed and activated", hdev->name); return 0; exit_mfg_disable: /* Disable the manufacturer mode without reset */ skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", hdev->name, PTR_ERR(skb)); return PTR_ERR(skb); } kfree_skb(skb); BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name); return 0; exit_mfg_deactivate: release_firmware(fw); /* Patching failed. Disable the manufacturer mode with reset and * deactivate the downloaded firmware patches. */ skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate), mfg_reset_deactivate, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", hdev->name, PTR_ERR(skb)); return PTR_ERR(skb); } kfree_skb(skb); BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated", hdev->name); return 0; }