diff options
44 files changed, 2149 insertions, 324 deletions
diff --git a/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml b/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml index f15a5e5e4859..c488f24ed38f 100644 --- a/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml +++ b/Documentation/devicetree/bindings/net/realtek-bluetooth.yaml @@ -44,7 +44,7 @@ examples: uart1 { pinctrl-names = "default"; pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; - uart-has-rtscts = <1>; + uart-has-rtscts; bluetooth { compatible = "realtek,rtl8723bs-bt"; diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 3b176257b993..e667933c3d70 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c @@ -106,7 +106,7 @@ static void bcm203x_complete(struct urb *urb) } data->state = BCM203X_LOAD_FIRMWARE; - /* fall through */ + fallthrough; case BCM203X_LOAD_FIRMWARE: if (data->fw_sent == data->fw_size) { usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index cc6e56223656..36eabf61717f 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -295,7 +295,6 @@ static void bluecard_write_wakeup(struct bluecard_info *info) baud_reg = REG_CONTROL_BAUD_RATE_115200; break; case PKT_BAUD_RATE_57600: - /* Fall through... */ default: baud_reg = REG_CONTROL_BAUD_RATE_57600; break; @@ -585,7 +584,6 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) hci_skb_pkt_type(skb) = PKT_BAUD_RATE_115200; break; case 57600: - /* Fall through... */ default: cmd[4] = 0x03; hci_skb_pkt_type(skb) = PKT_BAUD_RATE_57600; diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 6a0e2c5a8beb..5fa5be3c5598 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -754,6 +754,65 @@ void btintel_reset_to_bootloader(struct hci_dev *hdev) } EXPORT_SYMBOL_GPL(btintel_reset_to_bootloader); +int btintel_read_debug_features(struct hci_dev *hdev, + struct intel_debug_features *features) +{ + struct sk_buff *skb; + u8 page_no = 1; + + /* Intel controller supports two pages, each page is of 128-bit + * feature bit mask. And each bit defines specific feature support + */ + skb = __hci_cmd_sync(hdev, 0xfca6, sizeof(page_no), &page_no, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + bt_dev_err(hdev, "Reading supported features failed (%ld)", + PTR_ERR(skb)); + return PTR_ERR(skb); + } + + if (skb->len != (sizeof(features->page1) + 3)) { + bt_dev_err(hdev, "Supported features event size mismatch"); + kfree_skb(skb); + return -EILSEQ; + } + + memcpy(features->page1, skb->data + 3, sizeof(features->page1)); + + /* Read the supported features page2 if required in future. + */ + kfree_skb(skb); + return 0; +} +EXPORT_SYMBOL_GPL(btintel_read_debug_features); + +int btintel_set_debug_features(struct hci_dev *hdev, + const struct intel_debug_features *features) +{ + u8 mask[11] = { 0x0a, 0x92, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 }; + struct sk_buff *skb; + + if (!features) + return -EINVAL; + + if (!(features->page1[0] & 0x3f)) { + bt_dev_info(hdev, "Telemetry exception format not supported"); + return 0; + } + + skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + bt_dev_err(hdev, "Setting Intel telemetry ddc write event mask failed (%ld)", + PTR_ERR(skb)); + return PTR_ERR(skb); + } + + kfree_skb(skb); + return 0; +} +EXPORT_SYMBOL_GPL(btintel_set_debug_features); + MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION); MODULE_VERSION(VERSION); diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index a69ea8a87b9b..08e20606fb58 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -62,6 +62,10 @@ struct intel_reset { __le32 boot_param; } __packed; +struct intel_debug_features { + __u8 page1[16]; +} __packed; + #if IS_ENABLED(CONFIG_BT_INTEL) int btintel_check_bdaddr(struct hci_dev *hdev); @@ -88,6 +92,10 @@ int btintel_read_boot_params(struct hci_dev *hdev, int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw, u32 *boot_param); void btintel_reset_to_bootloader(struct hci_dev *hdev); +int btintel_read_debug_features(struct hci_dev *hdev, + struct intel_debug_features *features); +int btintel_set_debug_features(struct hci_dev *hdev, + const struct intel_debug_features *features); #else static inline int btintel_check_bdaddr(struct hci_dev *hdev) @@ -186,4 +194,17 @@ static inline int btintel_download_firmware(struct hci_dev *dev, static inline void btintel_reset_to_bootloader(struct hci_dev *hdev) { } + +static inline int btintel_read_debug_features(struct hci_dev *hdev, + struct intel_debug_features *features) +{ + return -EOPNOTSUPP; +} + +static inline int btintel_set_debug_features(struct hci_dev *hdev, + const struct intel_debug_features *features) +{ + return -EOPNOTSUPP; +} + #endif diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 708ad21683eb..8b9d78ce6bb2 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -587,6 +587,14 @@ static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) return 0; } +static bool btmrvl_prevent_wake(struct hci_dev *hdev) +{ + struct btmrvl_private *priv = hci_get_drvdata(hdev); + struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; + + return !device_may_wakeup(&card->func->dev); +} + /* * This function handles the event generated by firmware, rx data * received from firmware, and tx data sent from kernel. @@ -669,6 +677,7 @@ static int btmrvl_service_main_thread(void *data) int btmrvl_register_hdev(struct btmrvl_private *priv) { struct hci_dev *hdev = NULL; + struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; int ret; hdev = hci_alloc_dev(); @@ -687,6 +696,8 @@ int btmrvl_register_hdev(struct btmrvl_private *priv) hdev->send = btmrvl_send_frame; hdev->setup = btmrvl_setup; hdev->set_bdaddr = btmrvl_set_bdaddr; + hdev->prevent_wake = btmrvl_prevent_wake; + SET_HCIDEV_DEV(hdev, &card->func->dev); hdev->dev_type = priv->btmrvl_dev.dev_type; diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index a296f8526433..d15fd5be0216 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -111,6 +111,9 @@ static int btmrvl_sdio_probe_of(struct device *dev, "Failed to request irq_bt %d (%d)\n", cfg->irq_bt, ret); } + + /* Configure wakeup (enabled by default) */ + device_init_wakeup(dev, true); disable_irq(cfg->irq_bt); } } @@ -328,7 +331,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8977 = { .helper = NULL, - .firmware = "mrvl/sd8977_uapsta.bin", + .firmware = "mrvl/sdsd8977_combo_v2.bin", .reg = &btmrvl_reg_8977, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, @@ -346,7 +349,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8987 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = { .helper = NULL, - .firmware = "mrvl/sd8997_uapsta.bin", + .firmware = "mrvl/sdsd8997_combo_v4.bin", .reg = &btmrvl_reg_8997, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, @@ -1654,6 +1657,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func) MODULE_SHUTDOWN_REQ); btmrvl_sdio_disable_host_int(card); } + BT_DBG("unregister dev"); card->priv->surprise_removed = true; btmrvl_sdio_unregister_dev(card); @@ -1690,7 +1694,8 @@ static int btmrvl_sdio_suspend(struct device *dev) } /* Enable platform specific wakeup interrupt */ - if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { + if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 && + device_may_wakeup(dev)) { card->plt_wake_cfg->wake_by_bt = false; enable_irq(card->plt_wake_cfg->irq_bt); enable_irq_wake(card->plt_wake_cfg->irq_bt); @@ -1707,7 +1712,8 @@ static int btmrvl_sdio_suspend(struct device *dev) BT_ERR("HS not activated, suspend failed!"); /* Disable platform specific wakeup interrupt */ if (card->plt_wake_cfg && - card->plt_wake_cfg->irq_bt >= 0) { + card->plt_wake_cfg->irq_bt >= 0 && + device_may_wakeup(dev)) { disable_irq_wake(card->plt_wake_cfg->irq_bt); disable_irq(card->plt_wake_cfg->irq_bt); } @@ -1767,7 +1773,8 @@ static int btmrvl_sdio_resume(struct device *dev) hci_resume_dev(hcidev); /* Disable platform specific wakeup interrupt */ - if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { + if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 && + device_may_wakeup(dev)) { disable_irq_wake(card->plt_wake_cfg->irq_bt); disable_irq(card->plt_wake_cfg->irq_bt); if (card->plt_wake_cfg->wake_by_bt) @@ -1831,6 +1838,6 @@ MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); -MODULE_FIRMWARE("mrvl/sd8977_uapsta.bin"); +MODULE_FIRMWARE("mrvl/sdsd8977_combo_v2.bin"); MODULE_FIRMWARE("mrvl/sd8987_uapsta.bin"); -MODULE_FIRMWARE("mrvl/sd8997_uapsta.bin"); +MODULE_FIRMWARE("mrvl/sdsd8997_combo_v4.bin"); diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index bff095be2f97..c7ab7a23bd67 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -685,7 +685,7 @@ static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) const u8 *fw_ptr; size_t fw_size; int err, dlen; - u8 flag; + u8 flag, param; err = request_firmware(&fw, fwname, &hdev->dev); if (err < 0) { @@ -693,6 +693,20 @@ static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) return err; } + /* Power on data RAM the firmware relies on. */ + param = 1; + wmt_params.op = MTK_WMT_FUNC_CTRL; + wmt_params.flag = 3; + wmt_params.dlen = sizeof(param); + wmt_params.data = ¶m; + wmt_params.status = NULL; + + err = mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to power on data RAM (%d)", err); + return err; + } + fw_ptr = fw->data; fw_size = fw->size; diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index c5984966f315..ce9dcffdc5bf 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -400,6 +400,27 @@ out: return ret; } +static int qca_disable_soc_logging(struct hci_dev *hdev) +{ + struct sk_buff *skb; + u8 cmd[2]; + int err; + + cmd[0] = QCA_DISABLE_LOGGING_SUB_OP; + cmd[1] = 0x00; + skb = __hci_cmd_sync_ev(hdev, QCA_DISABLE_LOGGING, sizeof(cmd), cmd, + HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "QCA Failed to disable soc logging(%d)", err); + return err; + } + + kfree_skb(skb); + + return 0; +} + int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) { struct sk_buff *skb; @@ -486,6 +507,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, return err; } + if (soc_type >= QCA_WCN3991) { + err = qca_disable_soc_logging(hdev); + if (err < 0) + return err; + } + /* Perform HCI reset */ err = qca_send_reset(hdev); if (err < 0) { diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 6e1e62dd4b95..d81b74c408a5 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -14,6 +14,7 @@ #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) #define MAX_SIZE_PER_TLV_SEGMENT (243) #define QCA_PRE_SHUTDOWN_CMD (0xFC08) +#define QCA_DISABLE_LOGGING (0xFC17) #define EDL_CMD_REQ_RES_EVT (0x00) #define EDL_PATCH_VER_RES_EVT (0x19) @@ -22,6 +23,7 @@ #define EDL_CMD_EXE_STATUS_EVT (0x00) #define EDL_SET_BAUDRATE_RSP_EVT (0x92) #define EDL_NVM_ACCESS_CODE_EVT (0x0B) +#define QCA_DISABLE_LOGGING_SUB_OP (0x14) #define EDL_TAG_ID_HCI (17) #define EDL_TAG_ID_DEEP_SLEEP (27) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 5f022e9cf667..8d2608ddfd08 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -359,6 +359,10 @@ static const struct usb_device_id blacklist_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), .driver_info = BTUSB_IGNORE }, + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + /* Realtek Bluetooth devices */ { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), .driver_info = BTUSB_REALTEK }, @@ -453,6 +457,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = { #define BTUSB_HW_RESET_ACTIVE 12 #define BTUSB_TX_WAIT_VND_EVT 13 #define BTUSB_WAKEUP_DISABLE 14 +#define BTUSB_USE_ALT1_FOR_WBS 15 struct btusb_data { struct hci_dev *hdev; @@ -511,7 +516,6 @@ struct btusb_data { unsigned cmd_timeout_cnt; }; - static void btusb_intel_cmd_timeout(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -573,6 +577,23 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev) gpiod_set_value_cansleep(reset_gpio, 0); } +static void btusb_qca_cmd_timeout(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + int err; + + if (++data->cmd_timeout_cnt < 5) + return; + + bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device."); + /* This is not an unbalanced PM reference since the device will reset */ + err = usb_autopm_get_interface(data->intf); + if (!err) + usb_queue_reset_device(data->intf); + else + bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err); +} + static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; @@ -1666,14 +1687,15 @@ static void btusb_work(struct work_struct *work) new_alts = data->sco_num; } } else if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_TRANSP) { - - data->usb_alt6_packet_flow = true; - /* Check if Alt 6 is supported for Transparent audio */ - if (btusb_find_altsetting(data, 6)) + if (btusb_find_altsetting(data, 6)) { + data->usb_alt6_packet_flow = true; new_alts = 6; - else + } else if (test_bit(BTUSB_USE_ALT1_FOR_WBS, &data->flags)) { + new_alts = 1; + } else { bt_dev_err(hdev, "Device does not support ALT setting 6"); + } } if (btusb_switch_alt_setting(hdev, new_alts) < 0) @@ -1720,6 +1742,7 @@ static int btusb_setup_csr(struct hci_dev *hdev) { struct hci_rp_read_local_version *rp; struct sk_buff *skb; + bool is_fake = false; BT_DBG("%s", hdev->name); @@ -1739,18 +1762,69 @@ static int btusb_setup_csr(struct hci_dev *hdev) rp = (struct hci_rp_read_local_version *)skb->data; - /* Detect controllers which aren't real CSR ones. */ + /* Detect a wide host of Chinese controllers that aren't CSR. + * + * Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891 + * + * The main thing they have in common is that these are really popular low-cost + * options that support newer Bluetooth versions but rely on heavy VID/PID + * squatting of this poor old Bluetooth 1.1 device. Even sold as such. + * + * We detect actual CSR devices by checking that the HCI manufacturer code + * is Cambridge Silicon Radio (10) and ensuring that LMP sub-version and + * HCI rev values always match. As they both store the firmware number. + */ if (le16_to_cpu(rp->manufacturer) != 10 || - le16_to_cpu(rp->lmp_subver) == 0x0c5c) { + le16_to_cpu(rp->hci_rev) != le16_to_cpu(rp->lmp_subver)) + is_fake = true; + + /* Known legit CSR firmware build numbers and their supported BT versions: + * - 1.1 (0x1) -> 0x0073, 0x020d, 0x033c, 0x034e + * - 1.2 (0x2) -> 0x04d9, 0x0529 + * - 2.0 (0x3) -> 0x07a6, 0x07ad, 0x0c5c + * - 2.1 (0x4) -> 0x149c, 0x1735, 0x1899 (0x1899 is a BlueCore4-External) + * - 4.0 (0x6) -> 0x1d86, 0x2031, 0x22bb + * + * e.g. Real CSR dongles with LMP subversion 0x73 are old enough that + * support BT 1.1 only; so it's a dead giveaway when some + * third-party BT 4.0 dongle reuses it. + */ + else if (le16_to_cpu(rp->lmp_subver) <= 0x034e && + le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_1) + is_fake = true; + + else if (le16_to_cpu(rp->lmp_subver) <= 0x0529 && + le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_2) + is_fake = true; + + else if (le16_to_cpu(rp->lmp_subver) <= 0x0c5c && + le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_0) + is_fake = true; + + else if (le16_to_cpu(rp->lmp_subver) <= 0x1899 && + le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_1) + is_fake = true; + + else if (le16_to_cpu(rp->lmp_subver) <= 0x22bb && + le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_4_0) + is_fake = true; + + if (is_fake) { + bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds..."); + + /* Generally these clones have big discrepancies between + * advertised features and what's actually supported. + * Probably will need to be expanded in the future; + * without these the controller will lock up. + */ + set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks); + set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks); + /* 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); + clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); } kfree_skb(skb); @@ -2262,45 +2336,25 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver, return true; } -static int btusb_setup_intel_new(struct hci_dev *hdev) +static int btusb_intel_download_firmware(struct hci_dev *hdev, + struct intel_version *ver, + struct intel_boot_params *params) { - struct btusb_data *data = hci_get_drvdata(hdev); - struct intel_version ver; - struct intel_boot_params params; const struct firmware *fw; u32 boot_param; char fwname[64]; - ktime_t calltime, delta, rettime; - unsigned long long duration; int err; + struct btusb_data *data = hci_get_drvdata(hdev); - BT_DBG("%s", hdev->name); - - /* Set the default boot parameter to 0x0 and it is updated to - * SKU specific boot parameter after reading Intel_Write_Boot_Params - * command while downloading the firmware. - */ - boot_param = 0x00000000; - - calltime = ktime_get(); - - /* Read the Intel version information to determine if the device - * is in bootloader mode or if it already has operational firmware - * loaded. - */ - err = btintel_read_version(hdev, &ver); - if (err) { - bt_dev_err(hdev, "Intel Read version failed (%d)", err); - btintel_reset_to_bootloader(hdev); - return err; - } + if (!ver || !params) + return -EINVAL; /* The hardware platform number has a fixed value of 0x37 and * for now only accept this single value. */ - if (ver.hw_platform != 0x37) { + if (ver->hw_platform != 0x37) { bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)", - ver.hw_platform); + ver->hw_platform); return -EINVAL; } @@ -2310,7 +2364,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * This check has been put in place to ensure correct forward * compatibility options when newer hardware variants come along. */ - switch (ver.hw_variant) { + switch (ver->hw_variant) { case 0x0b: /* SfP */ case 0x0c: /* WsP */ case 0x11: /* JfP */ @@ -2320,11 +2374,11 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) break; default: bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)", - ver.hw_variant); + ver->hw_variant); return -EINVAL; } - btintel_version_info(hdev, &ver); + btintel_version_info(hdev, ver); /* The firmware variant determines if the device is in bootloader * mode or is running operational firmware. The value 0x06 identifies @@ -2339,25 +2393,25 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * It is not possible to use the Secure Boot Parameters in this * case since that command is only available in bootloader mode. */ - if (ver.fw_variant == 0x23) { + if (ver->fw_variant == 0x23) { clear_bit(BTUSB_BOOTLOADER, &data->flags); btintel_check_bdaddr(hdev); - goto finish; + return 0; } /* If the device is not in bootloader mode, then the only possible * choice is to return an error and abort the device initialization. */ - if (ver.fw_variant != 0x06) { + if (ver->fw_variant != 0x06) { bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)", - ver.fw_variant); + ver->fw_variant); return -ENODEV; } /* Read the secure boot parameters to identify the operating * details of the bootloader. */ - err = btintel_read_boot_params(hdev, ¶ms); + err = btintel_read_boot_params(hdev, params); if (err) return err; @@ -2365,16 +2419,16 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * with a command complete event. If the boot parameters indicate * that this bootloader does not send them, then abort the setup. */ - if (params.limited_cce != 0x00) { + if (params->limited_cce != 0x00) { bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)", - params.limited_cce); + params->limited_cce); return -EINVAL; } /* If the OTP has no valid Bluetooth device address, then there will * also be no valid address for the operational firmware. */ - if (!bacmp(¶ms.otp_bdaddr, BDADDR_ANY)) { + if (!bacmp(¶ms->otp_bdaddr, BDADDR_ANY)) { bt_dev_info(hdev, "No device address configured"); set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); } @@ -2400,7 +2454,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi. * */ - err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, fwname, + err = btusb_setup_intel_new_get_fw_name(ver, params, fwname, sizeof(fwname), "sfi"); if (!err) { bt_dev_err(hdev, "Unsupported Intel firmware naming"); @@ -2415,16 +2469,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) bt_dev_info(hdev, "Found device firmware: %s", fwname); - /* Save the DDC file name for later use to apply once the firmware - * downloading is done. - */ - err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, fwname, - sizeof(fwname), "ddc"); - if (!err) { - bt_dev_err(hdev, "Unsupported Intel firmware naming"); - return -EINVAL; - } - if (fw->size < 644) { bt_dev_err(hdev, "Invalid size of firmware file (%zu)", fw->size); @@ -2479,18 +2523,58 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) goto done; } +done: + release_firmware(fw); + return err; +} + +static int btusb_setup_intel_new(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct intel_version ver; + struct intel_boot_params params; + u32 boot_param; + char ddcname[64]; + ktime_t calltime, delta, rettime; + unsigned long long duration; + int err; + struct intel_debug_features features; |