Bluetooth: btintel: Refactoring setup routine for bootloader devices
authorTedd Ho-Jeong An <tedd.an@intel.com>
Thu, 5 Aug 2021 00:32:15 +0000 (17:32 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 5 Aug 2021 14:03:29 +0000 (16:03 +0200)
This patch refactors the setup routines for legacy and TLV based
bootloader devices to the combined setup, and move the related functions
from btusb to btintel.

Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
drivers/bluetooth/btintel.c
drivers/bluetooth/btintel.h
drivers/bluetooth/btusb.c

index 9e9fd22..8593b27 100644 (file)
@@ -631,90 +631,7 @@ int btintel_read_version_tlv(struct hci_dev *hdev, struct intel_version_tlv *ver
                return -EIO;
        }
 
-       /* Consume Command Complete Status field */
-       skb_pull(skb, 1);
-
-       /* Event parameters contatin multiple TLVs. Read each of them
-        * and only keep the required data. Also, it use existing legacy
-        * version field like hw_platform, hw_variant, and fw_variant
-        * to keep the existing setup flow
-        */
-       while (skb->len) {
-               struct intel_tlv *tlv;
-
-               tlv = (struct intel_tlv *)skb->data;
-               switch (tlv->type) {
-               case INTEL_TLV_CNVI_TOP:
-                       version->cnvi_top = get_unaligned_le32(tlv->val);
-                       break;
-               case INTEL_TLV_CNVR_TOP:
-                       version->cnvr_top = get_unaligned_le32(tlv->val);
-                       break;
-               case INTEL_TLV_CNVI_BT:
-                       version->cnvi_bt = get_unaligned_le32(tlv->val);
-                       break;
-               case INTEL_TLV_CNVR_BT:
-                       version->cnvr_bt = get_unaligned_le32(tlv->val);
-                       break;
-               case INTEL_TLV_DEV_REV_ID:
-                       version->dev_rev_id = get_unaligned_le16(tlv->val);
-                       break;
-               case INTEL_TLV_IMAGE_TYPE:
-                       version->img_type = tlv->val[0];
-                       break;
-               case INTEL_TLV_TIME_STAMP:
-                       /* If image type is Operational firmware (0x03), then
-                        * running FW Calendar Week and Year information can
-                        * be extracted from Timestamp information
-                        */
-                       version->min_fw_build_cw = tlv->val[0];
-                       version->min_fw_build_yy = tlv->val[1];
-                       version->timestamp = get_unaligned_le16(tlv->val);
-                       break;
-               case INTEL_TLV_BUILD_TYPE:
-                       version->build_type = tlv->val[0];
-                       break;
-               case INTEL_TLV_BUILD_NUM:
-                       /* If image type is Operational firmware (0x03), then
-                        * running FW build number can be extracted from the
-                        * Build information
-                        */
-                       version->min_fw_build_nn = tlv->val[0];
-                       version->build_num = get_unaligned_le32(tlv->val);
-                       break;
-               case INTEL_TLV_SECURE_BOOT:
-                       version->secure_boot = tlv->val[0];
-                       break;
-               case INTEL_TLV_OTP_LOCK:
-                       version->otp_lock = tlv->val[0];
-                       break;
-               case INTEL_TLV_API_LOCK:
-                       version->api_lock = tlv->val[0];
-                       break;
-               case INTEL_TLV_DEBUG_LOCK:
-                       version->debug_lock = tlv->val[0];
-                       break;
-               case INTEL_TLV_MIN_FW:
-                       version->min_fw_build_nn = tlv->val[0];
-                       version->min_fw_build_cw = tlv->val[1];
-                       version->min_fw_build_yy = tlv->val[2];
-                       break;
-               case INTEL_TLV_LIMITED_CCE:
-                       version->limited_cce = tlv->val[0];
-                       break;
-               case INTEL_TLV_SBE_TYPE:
-                       version->sbe_type = tlv->val[0];
-                       break;
-               case INTEL_TLV_OTP_BDADDR:
-                       memcpy(&version->otp_bd_addr, tlv->val, tlv->len);
-                       break;
-               default:
-                       /* Ignore rest of information */
-                       break;
-               }
-               /* consume the current tlv and move to next*/
-               skb_pull(skb, tlv->len + sizeof(*tlv));
-       }
+       btintel_parse_version_tlv(hdev, version, skb);
 
        kfree_skb(skb);
        return 0;
@@ -1192,10 +1109,10 @@ int btintel_download_firmware(struct hci_dev *hdev,
 }
 EXPORT_SYMBOL_GPL(btintel_download_firmware);
 
-int btintel_download_firmware_newgen(struct hci_dev *hdev,
-                                    struct intel_version_tlv *ver,
-                                    const struct firmware *fw, u32 *boot_param,
-                                    u8 hw_variant, u8 sbe_type)
+static int btintel_download_fw_tlv(struct hci_dev *hdev,
+                                  struct intel_version_tlv *ver,
+                                  const struct firmware *fw, u32 *boot_param,
+                                  u8 hw_variant, u8 sbe_type)
 {
        int err;
        u32 css_header_ver;
@@ -1292,7 +1209,6 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
        }
        return 0;
 }
-EXPORT_SYMBOL_GPL(btintel_download_firmware_newgen);
 
 void btintel_reset_to_bootloader(struct hci_dev *hdev)
 {
@@ -1683,6 +1599,579 @@ complete:
        return 0;
 }
 
+static int btintel_download_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
+{
+       ktime_t delta, rettime;
+       unsigned long long duration;
+       int err;
+
+       btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
+
+       bt_dev_info(hdev, "Waiting for firmware download to complete");
+
+       err = btintel_wait_on_flag_timeout(hdev, INTEL_DOWNLOADING,
+                                          TASK_INTERRUPTIBLE,
+                                          msecs_to_jiffies(msec));
+       if (err == -EINTR) {
+               bt_dev_err(hdev, "Firmware loading interrupted");
+               return err;
+       }
+
+       if (err) {
+               bt_dev_err(hdev, "Firmware loading timeout");
+               return -ETIMEDOUT;
+       }
+
+       if (btintel_test_flag(hdev, INTEL_FIRMWARE_FAILED)) {
+               bt_dev_err(hdev, "Firmware loading failed");
+               return -ENOEXEC;
+       }
+
+       rettime = ktime_get();
+       delta = ktime_sub(rettime, calltime);
+       duration = (unsigned long long)ktime_to_ns(delta) >> 10;
+
+       bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
+
+       return 0;
+}
+
+static int btintel_boot_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
+{
+       ktime_t delta, rettime;
+       unsigned long long duration;
+       int err;
+
+       bt_dev_info(hdev, "Waiting for device to boot");
+
+       err = btintel_wait_on_flag_timeout(hdev, INTEL_BOOTING,
+                                          TASK_INTERRUPTIBLE,
+                                          msecs_to_jiffies(msec));
+       if (err == -EINTR) {
+               bt_dev_err(hdev, "Device boot interrupted");
+               return -EINTR;
+       }
+
+       if (err) {
+               bt_dev_err(hdev, "Device boot timeout");
+               return -ETIMEDOUT;
+       }
+
+       rettime = ktime_get();
+       delta = ktime_sub(rettime, calltime);
+       duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+
+       bt_dev_info(hdev, "Device booted in %llu usecs", duration);
+
+       return 0;
+}
+
+static int btintel_boot(struct hci_dev *hdev, u32 boot_addr)
+{
+       ktime_t calltime;
+       int err;
+
+       calltime = ktime_get();
+
+       btintel_set_flag(hdev, INTEL_BOOTING);
+
+       err = btintel_send_intel_reset(hdev, boot_addr);
+       if (err) {
+               bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
+               btintel_reset_to_bootloader(hdev);
+               return err;
+       }
+
+       /* The bootloader will not indicate when the device is ready. This
+        * is done by the operational firmware sending bootup notification.
+        *
+        * Booting into operational firmware should not take longer than
+        * 1 second. However if that happens, then just fail the setup
+        * since something went wrong.
+        */
+       err = btintel_boot_wait(hdev, calltime, 1000);
+       if (err == -ETIMEDOUT)
+               btintel_reset_to_bootloader(hdev);
+
+       return err;
+}
+
+static int btintel_get_fw_name(struct intel_version *ver,
+                                            struct intel_boot_params *params,
+                                            char *fw_name, size_t len,
+                                            const char *suffix)
+{
+       switch (ver->hw_variant) {
+       case 0x0b:      /* SfP */
+       case 0x0c:      /* WsP */
+               snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
+                       le16_to_cpu(ver->hw_variant),
+                       le16_to_cpu(params->dev_revid),
+                       suffix);
+               break;
+       case 0x11:      /* JfP */
+       case 0x12:      /* ThP */
+       case 0x13:      /* HrP */
+       case 0x14:      /* CcP */
+               snprintf(fw_name, len, "intel/ibt-%u-%u-%u.%s",
+                       le16_to_cpu(ver->hw_variant),
+                       le16_to_cpu(ver->hw_revision),
+                       le16_to_cpu(ver->fw_revision),
+                       suffix);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int btintel_download_fw(struct hci_dev *hdev,
+                                        struct intel_version *ver,
+                                        struct intel_boot_params *params,
+                                        u32 *boot_param)
+{
+       const struct firmware *fw;
+       char fwname[64];
+       int err;
+       ktime_t calltime;
+
+       if (!ver || !params)
+               return -EINVAL;
+
+       /* The firmware variant determines if the device is in bootloader
+        * mode or is running operational firmware. The value 0x06 identifies
+        * the bootloader and the value 0x23 identifies the operational
+        * firmware.
+        *
+        * When the operational firmware is already present, then only
+        * the check for valid Bluetooth device address is needed. This
+        * determines if the device will be added as configured or
+        * unconfigured controller.
+        *
+        * 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) {
+               btintel_clear_flag(hdev, INTEL_BOOTLOADER);
+               btintel_check_bdaddr(hdev);
+
+               /* SfP and WsP don't seem to update the firmware version on file
+                * so version checking is currently possible.
+                */
+               switch (ver->hw_variant) {
+               case 0x0b:      /* SfP */
+               case 0x0c:      /* WsP */
+                       return 0;
+               }
+
+               /* Proceed to download to check if the version matches */
+               goto download;
+       }
+
+       /* Read the secure boot parameters to identify the operating
+        * details of the bootloader.
+        */
+       err = btintel_read_boot_params(hdev, params);
+       if (err)
+               return err;
+
+       /* It is required that every single firmware fragment is acknowledged
+        * 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) {
+               bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
+                          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(&params->otp_bdaddr, BDADDR_ANY)) {
+               bt_dev_info(hdev, "No device address configured");
+               set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+       }
+
+download:
+       /* With this Intel bootloader only the hardware variant and device
+        * revision information are used to select the right firmware for SfP
+        * and WsP.
+        *
+        * The firmware filename is ibt-<hw_variant>-<dev_revid>.sfi.
+        *
+        * Currently the supported hardware variants are:
+        *   11 (0x0b) for iBT3.0 (LnP/SfP)
+        *   12 (0x0c) for iBT3.5 (WsP)
+        *
+        * For ThP/JfP and for future SKU's, the FW name varies based on HW
+        * variant, HW revision and FW revision, as these are dependent on CNVi
+        * and RF Combination.
+        *
+        *   17 (0x11) for iBT3.5 (JfP)
+        *   18 (0x12) for iBT3.5 (ThP)
+        *
+        * The firmware file name for these will be
+        * ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
+        *
+        */
+       err = btintel_get_fw_name(ver, params, fwname, sizeof(fwname), "sfi");
+       if (err < 0) {
+               if (!btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
+                       /* Firmware has already been loaded */
+                       btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
+                       return 0;
+               }
+
+               bt_dev_err(hdev, "Unsupported Intel firmware naming");
+               return -EINVAL;
+       }
+
+       err = firmware_request_nowarn(&fw, fwname, &hdev->dev);
+       if (err < 0) {
+               if (!btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
+                       /* Firmware has already been loaded */
+                       btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
+                       return 0;
+               }
+
+               bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
+                          fwname, err);
+               return err;
+       }
+
+       bt_dev_info(hdev, "Found device firmware: %s", fwname);
+
+       if (fw->size < 644) {
+               bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
+                          fw->size);
+               err = -EBADF;
+               goto done;
+       }
+
+       calltime = ktime_get();
+
+       btintel_set_flag(hdev, INTEL_DOWNLOADING);
+
+       /* Start firmware downloading and get boot parameter */
+       err = btintel_download_firmware(hdev, ver, fw, boot_param);
+       if (err < 0) {
+               if (err == -EALREADY) {
+                       /* Firmware has already been loaded */
+                       btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
+                       err = 0;
+                       goto done;
+               }
+
+               /* When FW download fails, send Intel Reset to retry
+                * FW download.
+                */
+               btintel_reset_to_bootloader(hdev);
+               goto done;
+       }
+
+       /* Before switching the device into operational mode and with that
+        * booting the loaded firmware, wait for the bootloader notification
+        * that all fragments have been successfully received.
+        *
+        * When the event processing receives the notification, then the
+        * INTEL_DOWNLOADING flag will be cleared.
+        *
+        * The firmware loading should not take longer than 5 seconds
+        * and thus just timeout if that happens and fail the setup
+        * of this device.
+        */
+       err = btintel_download_wait(hdev, calltime, 5000);
+       if (err == -ETIMEDOUT)
+               btintel_reset_to_bootloader(hdev);
+
+done:
+       release_firmware(fw);
+       return err;
+}
+
+static int btintel_bootloader_setup(struct hci_dev *hdev,
+                                   struct intel_version *ver)
+{
+       struct intel_version new_ver;
+       struct intel_boot_params params;
+       u32 boot_param;
+       char ddcname[64];
+       int err;
+       struct intel_debug_features features;
+
+       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;
+
+       btintel_set_flag(hdev, INTEL_BOOTLOADER);
+
+       err = btintel_download_fw(hdev, ver, &params, &boot_param);
+       if (err)
+               return err;
+
+       /* controller is already having an operational firmware */
+       if (ver->fw_variant == 0x23)
+               goto finish;
+
+       err = btintel_boot(hdev, boot_param);
+       if (err)
+               return err;
+
+       btintel_clear_flag(hdev, INTEL_BOOTLOADER);
+
+       err = btintel_get_fw_name(ver, &params, ddcname,
+                                               sizeof(ddcname), "ddc");
+
+       if (err < 0) {
+               bt_dev_err(hdev, "Unsupported Intel firmware naming");
+       } else {
+               /* Once the device is running in operational mode, it needs to
+                * apply the device configuration (DDC) parameters.
+                *
+                * The device can work without DDC parameters, so even if it
+                * fails to load the file, no need to fail the setup.
+                */
+               btintel_load_ddc_config(hdev, ddcname);
+       }
+
+       /* Read the Intel supported features and if new exception formats
+        * supported, need to load the additional DDC config to enable.
+        */
+       err = btintel_read_debug_features(hdev, &features);
+       if (!err) {
+               /* Set DDC mask for available debug features */
+               btintel_set_debug_features(hdev, &features);
+       }
+
+       /* Read the Intel version information after loading the FW  */
+       err = btintel_read_version(hdev, &new_ver);
+       if (err)
+               return err;
+
+       btintel_version_info(hdev, &new_ver);
+
+finish:
+       /* All Intel controllers that support the Microsoft vendor
+        * extension are using 0xFC1E for VsMsftOpCode.
+        */
+       switch (ver->hw_variant) {
+       case 0x11:      /* JfP */
+       case 0x12:      /* ThP */
+       case 0x13:      /* HrP */
+       case 0x14:      /* CcP */
+               hci_set_msft_opcode(hdev, 0xFC1E);
+               break;
+       }
+
+       /* Set the event mask for Intel specific vendor events. This enables
+        * a few extra events that are useful during general operation. It
+        * does not enable any debugging related events.
+        *
+        * The device will function correctly without these events enabled
+        * and thus no need to fail the setup.
+        */
+       btintel_set_event_mask(hdev, false);
+
+       return 0;
+}
+
+static void btintel_get_fw_name_tlv(const struct intel_version_tlv *ver,
+                                   char *fw_name, size_t len,
+                                   const char *suffix)
+{
+       /* The firmware file name for new generation controllers will be
+        * ibt-<cnvi_top type+cnvi_top step>-<cnvr_top type+cnvr_top step>
+        */
+       snprintf(fw_name, len, "intel/ibt-%04x-%04x.%s",
+                INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver->cnvi_top),
+                                         INTEL_CNVX_TOP_STEP(ver->cnvi_top)),
+                INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver->cnvr_top),
+                                         INTEL_CNVX_TOP_STEP(ver->cnvr_top)),
+                suffix);
+}
+
+static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
+                                          struct intel_version_tlv *ver,
+                                          u32 *boot_param)
+{
+       const struct firmware *fw;
+       char fwname[64];
+       int err;
+       ktime_t calltime;
+
+       if (!ver || !boot_param)
+               return -EINVAL;
+
+       /* The firmware variant determines if the device is in bootloader
+        * mode or is running operational firmware. The value 0x03 identifies
+        * the bootloader and the value 0x23 identifies the operational
+        * firmware.
+        *
+        * When the operational firmware is already present, then only
+        * the check for valid Bluetooth device address is needed. This
+        * determines if the device will be added as configured or
+        * unconfigured controller.
+        *
+        * It is not possible to use the Secure Boot Parameters in this
+        * case since that command is only available in bootloader mode.
+        */
+       if (ver->img_type == 0x03) {
+               btintel_clear_flag(hdev, INTEL_BOOTLOADER);
+               btintel_check_bdaddr(hdev);
+       }
+
+       /* If the OTP has no valid Bluetooth device address, then there will
+        * also be no valid address for the operational firmware.
+        */
+       if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
+               bt_dev_info(hdev, "No device address configured");
+               set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+       }
+
+       btintel_get_fw_name_tlv(ver, fwname, sizeof(fwname), "sfi");
+       err = firmware_request_nowarn(&fw, fwname, &hdev->dev);
+       if (err < 0) {
+               if (!btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
+                       /* Firmware has already been loaded */
+                       btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
+                       return 0;
+               }
+
+               bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
+                          fwname, err);
+
+               return err;
+       }
+
+       bt_dev_info(hdev, "Found device firmware: %s", fwname);
+
+       if (fw->size < 644) {
+               bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
+                          fw->size);
+               err = -EBADF;
+               goto done;
+       }
+
+       calltime = ktime_get();
+
+       btintel_set_flag(hdev, INTEL_DOWNLOADING);
+
+       /* Start firmware downloading and get boot parameter */
+       err = btintel_download_fw_tlv(hdev, ver, fw, boot_param,
+                                              INTEL_HW_VARIANT(ver->cnvi_bt),
+                                              ver->sbe_type);
+       if (err < 0) {
+               if (err == -EALREADY) {
+                       /* Firmware has already been loaded */
+                       btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
+                       err = 0;
+                       goto done;
+               }
+
+               /* When FW download fails, send Intel Reset to retry
+                * FW download.
+                */
+               btintel_reset_to_bootloader(hdev);
+               goto done;
+       }
+
+       /* Before switching the device into operational mode and with that
+        * booting the loaded firmware, wait for the bootloader notification
+        * that all fragments have been successfully received.
+        *
+        * When the event processing receives the notification, then the
+        * BTUSB_DOWNLOADING flag will be cleared.
+        *
+        * The firmware loading should not take longer than 5 seconds
+        * and thus just timeout if that happens and fail the setup
+        * of this device.
+        */
+       err = btintel_download_wait(hdev, calltime, 5000);
+       if (err == -ETIMEDOUT)
+               btintel_reset_to_bootloader(hdev);
+
+done:
+       release_firmware(fw);
+       return err;
+}
+
+static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
+                                       struct intel_version_tlv *ver)
+{
+       u32 boot_param;
+       char ddcname[64];
+       int err;
+       struct intel_debug_features features;
+       struct intel_version_tlv new_ver;
+
+       bt_dev_dbg(hdev, "");
+
+       /* 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;
+
+       btintel_set_flag(hdev, INTEL_BOOTLOADER);
+
+       err = btintel_prepare_fw_download_tlv(hdev, ver, &boot_param);
+       if (err)
+               return err;
+
+       /* check if controller is already having an operational firmware */
+       if (ver->img_type == 0x03)
+               goto finish;
+
+       err = btintel_boot(hdev, boot_param);
+       if (err)
+               return err;
+
+       btintel_clear_flag(hdev, INTEL_BOOTLOADER);
+
+       btintel_get_fw_name_tlv(ver, ddcname, sizeof(ddcname), "ddc");
+       /* Once the device is running in operational mode, it needs to
+        * apply the device configuration (DDC) parameters.
+        *
+        * The device can work without DDC parameters, so even if it
+        * fails to load the file, no need to fail the setup.
+        */
+       btintel_load_ddc_config(hdev, ddcname);
+
+       /* Read the Intel supported features and if new exception formats
+        * supported, need to load the additional DDC config to enable.
+        */
+       err = btintel_read_debug_features(hdev, &features);
+       if (!err) {
+               /* Set DDC mask for available debug features */
+               btintel_set_debug_features(hdev, &features);
+       }
+
+       /* Read the Intel version information after loading the FW  */
+       err = btintel_read_version_tlv(hdev, &new_ver);
+       if (err)
+               return err;
+
+       btintel_version_info_tlv(hdev, &new_ver);
+
+finish:
+       /* Set the event mask for Intel specific vendor events. This enables
+        * a few extra events that are useful during general operation. It
+        * does not enable any debugging related events.
+        *
+        * The device will function correctly without these events enabled
+        * and thus no need to fail the setup.
+        */
+       btintel_set_event_mask(hdev, false);
+
+       return 0;
+}
+
 static int btintel_setup_combined(struct hci_dev *hdev)
 {
        const u8 param[1] = { 0xFF };
@@ -1770,7 +2259,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)
                case 0x12:      /* ThP */
                case 0x13:      /* HrP */
                case 0x14:      /* CcP */
-                       /* TODO: call setup routine for bootloader product */
+                       err = btintel_bootloader_setup(hdev, &ver);
                        break;
                default:
                        bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
@@ -1795,11 +2284,27 @@ static int btintel_setup_combined(struct hci_dev *hdev)
                goto exit_error;
        }
 
-       /* Display version information of TLV type */
-       btintel_version_info_tlv(hdev, &ver_tlv);
-
-       /* TODO: Need to filter the device for new generation */
-       /* TODO: call setup routine for tlv based bootloader product */
+       /* Check for supported iBT hardware variants of this firmware
+        * loading method.
+        *
+        * This check has been put in place to ensure correct forward
+        * compatibility options when newer hardware variants come
+        * along.
+        */
+       switch (INTEL_HW_VARIANT(ver_tlv.cnvi_bt)) {
+       case 0x17:
+       case 0x18:
+       case 0x19:
+               /* Display version information of TLV type */
+               btintel_version_info_tlv(hdev, &ver_tlv);
+
+               err = btintel_bootloader_setup_tlv(hdev, &ver_tlv);
+               break;
+       default:
+               bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
+                          INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
+               return -EINVAL;
+       }
 
 exit_error:
        kfree_skb(skb);
@@ -1846,6 +2351,7 @@ int btintel_configure_setup(struct hci_dev *hdev)
        hdev->manufacturer = 2;
        hdev->setup = btintel_setup_combined;
        hdev->shutdown = btintel_shutdown_combined;
+       hdev->hw_error = btintel_hw_error;
        hdev->set_diag = btintel_set_diag_combined;
        hdev->set_bdaddr = btintel_set_bdaddr;
 
@@ -1853,6 +2359,35 @@ int btintel_configure_setup(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL_GPL(btintel_configure_setup);
 
+void btintel_bootup(struct hci_dev *hdev, const void *ptr, unsigned int len)
+{
+       const struct intel_bootup *evt = ptr;
+
+       if (len != sizeof(*evt))
+               return;
+
+       if (btintel_test_and_clear_flag(hdev, INTEL_BOOTING))
+               btintel_wake_up_flag(hdev, INTEL_BOOTING);
+}
+EXPORT_SYMBOL_GPL(btintel_bootup);
+
+void btintel_secure_send_result(struct hci_dev *hdev,
+                               const void *ptr, unsigned int len)
+{
+       const struct intel_secure_send_result *evt = ptr;
+
+       if (len != sizeof(*evt))
+               return;
+
+       if (evt->result)
+               btintel_set_flag(hdev, INTEL_FIRMWARE_FAILED);
+
+       if (btintel_test_and_clear_flag(hdev, INTEL_DOWNLOADING) &&
+           btintel_test_flag(hdev, INTEL_FIRMWARE_LOADED))
+               btintel_wake_up_flag(hdev, INTEL_DOWNLOADING);
+}
+EXPORT_SYMBOL_GPL(btintel_secure_send_result);
+
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
 MODULE_VERSION(VERSION);
index 17cb62a..5a8a696 100644 (file)
@@ -207,17 +207,15 @@ int btintel_read_boot_params(struct hci_dev *hdev,
                             struct intel_boot_params *params);
 int btintel_download_firmware(struct hci_dev *dev, struct intel_version *ver,
                              const struct firmware *fw, u32 *boot_param);
-int btintel_download_firmware_newgen(struct hci_dev *hdev,
-                                    struct intel_version_tlv *ver,
-                                    const struct firmware *fw,
-                                    u32 *boot_param, u8 hw_variant,
-                                    u8 sbe_type);
 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);
 int btintel_configure_setup(struct hci_dev *hdev);
+void btintel_bootup(struct hci_dev *hdev, const void *ptr, unsigned int len);
+void btintel_secure_send_result(struct hci_dev *hdev,
+                               const void *ptr, unsigned int len);
 #else
 
 static inline int btintel_check_bdaddr(struct hci_dev *hdev)
@@ -321,14 +319,6 @@ static inline int btintel_download_firmware(struct hci_dev *dev,
        return -EOPNOTSUPP;
 }
 
-static inline int btintel_download_firmware_newgen(struct hci_dev *hdev,
-                                                  const struct firmware *fw,
-                                                  u32 *boot_param,
-                                                  u8 hw_variant, u8 sbe_type)
-{
-       return -EOPNOTSUPP;
-}
-
 static inline void btintel_reset_to_bootloader(struct hci_dev *hdev)
 {
 }
@@ -350,4 +340,13 @@ static inline int btintel_configure_setup(struct hci_dev *hdev)
        return -ENODEV;
 }
 
+static inline void btintel_bootup(struct hci_dev *hdev,
+                                 const void *ptr, unsigned int len)
+{
+}
+
+static inline void btintel_secure_send_result(struct hci_dev *hdev,
+                               const void *ptr, unsigned int len)
+{
+}
 #endif
index 3ed552d..26863d8 100644 (file)
@@ -48,7 +48,6 @@ static struct usb_driver btusb_driver;
 #define BTUSB_BCM_PATCHRAM     0x400
 #define BTUSB_MARVELL          0x800
 #define BTUSB_SWAVE            0x1000
-#define BTUSB_INTEL_NEW                0x2000
 #define BTUSB_AMP              0x4000
 #define BTUSB_QCA_ROME         0x8000
 #define BTUSB_BCM_APPLE                0x10000
@@ -60,7 +59,6 @@ static struct usb_driver btusb_driver;
 #define BTUSB_WIDEBAND_SPEECH  0x400000
 #define BTUSB_VALID_LE_STATES   0x800000
 #define BTUSB_QCA_WCN6855      0x1000000
-#define BTUSB_INTEL_NEWGEN     0x2000000
 #define BTUSB_INTEL_BROKEN_INITIAL_NCMD 0x4000000
 
 static const struct usb_device_id btusb_table[] = {
@@ -360,27 +358,27 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL },
 
        /* Intel Bluetooth devices */
-       { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW |
+       { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH |
                                                     BTUSB_VALID_LE_STATES },
-       { USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW |
+       { USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH },
-       { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW |
+       { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH },
-       { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_NEWGEN |
+       { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH},
-       { USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_NEWGEN |
+       { USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH |
                                                     BTUSB_VALID_LE_STATES },
        { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_INTEL_BROKEN_INITIAL_NCMD },
        { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL_COMBINED },
-       { USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_NEW |
+       { USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH },
        { USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH },
-       { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_NEW |
+       { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_WIDEBAND_SPEECH |
                                                     BTUSB_VALID_LE_STATES },
 
@@ -1999,49 +1997,21 @@ static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
 static int btusb_recv_bulk_intel(struct btusb_data *data, void *buffer,
                                 int count)
 {
+       struct hci_dev *hdev = data->hdev;
+
        /* When the device is in bootloader mode, then it can send
         * events via the bulk endpoint. These events are treated the
         * same way as the ones received from the interrupt endpoint.
         */
-       if (test_bit(BTUSB_BOOTLOADER, &data->flags))
+       if (btintel_test_flag(hdev, INTEL_BOOTLOADER))
                return btusb_recv_intr(data, buffer, count);
 
        return btusb_recv_bulk(data, buffer, count);
 }
 
-static void btusb_intel_bootup(struct btusb_data *data, const void *ptr,
-                              unsigned int len)
-{
-       const struct intel_bootup *evt = ptr;
-
-       if (len != sizeof(*evt))
-               return;
-
-       if (test_and_clear_bit(BTUSB_BOOTING, &data->flags))
-               wake_up_bit(&data->flags, BTUSB_BOOTING);
-}
-
-static void btusb_intel_secure_send_result(struct btusb_data *data,
-                                          const void *ptr, unsigned int len)
-{
-       const struct intel_secure_send_result *evt = ptr;
-
-       if (len != sizeof(*evt))
-               return;
-
-       if (evt->result)
-               set_bit(BTUSB_FIRMWARE_FAILED, &data->flags);
-
-       if (test_and_clear_bit(BTUSB_DOWNLOADING, &data->flags) &&
-           test_bit(BTUSB_FIRMWARE_LOADED, &data->flags))
-               wake_up_bit(&data->flags, BTUSB_DOWNLOADING);
-}
-
 static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct btusb_data *data = hci_get_drvdata(hdev);
-
-       if (test_bit(BTUSB_BOOTLOADER, &data->flags)) {
+       if (btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
                struct hci_event_hdr *hdr = (void *)skb->data;
 
                if (skb->len > HCI_EVENT_HDR_SIZE && hdr->evt == 0xff &&
@@ -2055,7 +2025,7 @@ static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb)
                                 * the device sends a vendor specific event
                                 * indicating that the bootup completed.
                                 */
-                               btusb_intel_bootup(data, ptr, len);
+                               btintel_bootup(hdev, ptr, len);
                                break;
                        case 0x06:
                                /* When the firmware loading completes the
@@ -2063,7 +2033,7 @@ static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb)
                                 * indicating the result of the firmware
                                 * loading.
                                 */
-                               btusb_intel_secure_send_result(data, ptr, len);
+                               btintel_secure_send_result(hdev, ptr, len);
                                break;
                        }
                }
@@ -2074,14 +2044,13 @@ static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb)
 
 static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct btusb_data *data = hci_get_drvdata(hdev);
        struct urb *urb;
 
        BT_DBG("%s", hdev->name);
 
        switch (hci_skb_pkt_type(skb)) {
        case HCI_COMMAND_PKT:
-               if (test_bit(BTUSB_BOOTLOADER, &data->flags)) {
+               if (btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
                        struct hci_command_hdr *cmd = (void *)skb->data;
                        __u16 opcode = le16_to_cpu(cmd->opcode);
 
@@ -2133,641 +2102,6 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
        return -EILSEQ;
 }
 
-static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
-                                            struct intel_boot_params *params,
-                                            char *fw_name, size_t len,
-                                            const char *suffix)
-{
-       switch (ver->hw_variant) {
-       case 0x0b:      /* SfP */
-       case 0x0c:      /* WsP */
-               snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
-                       le16_to_cpu(ver->hw_variant),
-                       le16_to_cpu(params->dev_revid),
-                       suffix);
-               break;
-       case 0x11:      /* JfP */
-       case 0x12:      /* ThP */
-       case 0x13:      /* HrP */
-       case 0x14:      /* CcP */
-               snprintf(fw_name, len, "intel/ibt-%u-%u-%u.%s",
-                       le16_to_cpu(ver->hw_variant),
-                       le16_to_cpu(ver->hw_revision),
-                       le16_to_cpu(ver->fw_revision),
-                       suffix);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv *ver_tlv,
-                                                char *fw_name, size_t len,
-                                                const char *suffix)
-{
-       /* The firmware file name for new generation controllers will be
-        * ibt-<cnvi_top type+cnvi_top step>-<cnvr_top type+cnvr_top step>
-        */
-       snprintf(fw_name, len, "intel/ibt-%04x-%04x.%s",
-                INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver_tlv->cnvi_top),
-                                         INTEL_CNVX_TOP_STEP(ver_tlv->cnvi_top)),
-                INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver_tlv->cnvr_top),
-                                         INTEL_CNVX_TOP_STEP(ver_tlv->cnvr_top)),
-                suffix);
-}
-
-static int btusb_download_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
-{
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       ktime_t delta, rettime;
-       unsigned long long duration;
-       int err;
-
-       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-
-       bt_dev_info(hdev, "Waiting for firmware download to complete");
-
-       err = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
-                                 TASK_INTERRUPTIBLE,
-                                 msecs_to_jiffies(msec));
-       if (err == -EINTR) {
-               bt_dev_err(hdev, "Firmware loading interrupted");
-               return err;
-       }
-
-       if (err) {
-               bt_dev_err(hdev, "Firmware loading timeout");
-               return -ETIMEDOUT;
-       }
-
-       if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
-               bt_dev_err(hdev, "Firmware loading failed");
-               return -ENOEXEC;
-       }
-
-       rettime = ktime_get();
-       delta = ktime_sub(rettime, calltime);
-       duration = (unsigned long long)ktime_to_ns(delta) >> 10;
-
-       bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
-
-       return 0;
-}
-
-static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
-                                               struct intel_version_tlv *ver,
-                                               u32 *boot_param)
-{
-       const struct firmware *fw;
-       char fwname[64];
-       int err;
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       ktime_t calltime;
-
-       if (!ver || !boot_param)
-               return -EINVAL;
-
-       /* The firmware variant determines if the device is in bootloader
-        * mode or is running operational firmware. The value 0x03 identifies
-        * the bootloader and the value 0x23 identifies the operational
-        * firmware.
-        *
-        * When the operational firmware is already present, then only
-        * the check for valid Bluetooth device address is needed. This
-        * determines if the device will be added as configured or
-        * unconfigured controller.
-        *
-        * It is not possible to use the Secure Boot Parameters in this
-        * case since that command is only available in bootloader mode.
-        */
-       if (ver->img_type == 0x03) {
-               clear_bit(BTUSB_BOOTLOADER, &data->flags);
-               btintel_check_bdaddr(hdev);
-       }
-
-       /* If the OTP has no valid Bluetooth device address, then there will
-        * also be no valid address for the operational firmware.
-        */
-       if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
-               bt_dev_info(hdev, "No device address configured");
-               set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
-       }
-
-       btusb_setup_intel_newgen_get_fw_name(ver, fwname, sizeof(fwname), "sfi");
-       err = firmware_request_nowarn(&fw, fwname, &hdev->dev);
-       if (err < 0) {
-               if (!test_bit(BTUSB_BOOTLOADER, &data->flags)) {
-                       /* Firmware has already been loaded */
-                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-                       return 0;
-               }
-
-               bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
-                          fwname, err);
-
-               return err;
-       }
-
-       bt_dev_info(hdev, "Found device firmware: %s", fwname);
-
-       if (fw->size < 644) {
-               bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
-                          fw->size);
-               err = -EBADF;
-               goto done;
-       }
-
-       calltime = ktime_get();
-
-       set_bit(BTUSB_DOWNLOADING, &data->flags);
-
-       /* Start firmware downloading and get boot parameter */
-       err = btintel_download_firmware_newgen(hdev, ver, fw, boot_param,
-                                              INTEL_HW_VARIANT(ver->cnvi_bt),
-                                              ver->sbe_type);
-       if (err < 0) {
-               if (err == -EALREADY) {
-                       /* Firmware has already been loaded */
-                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-                       err = 0;
-                       goto done;
-               }
-
-               /* When FW download fails, send Intel Reset to retry
-                * FW download.
-                */
-               btintel_reset_to_bootloader(hdev);
-               goto done;
-       }
-
-       /* Before switching the device into operational mode and with that
-        * booting the loaded firmware, wait for the bootloader notification
-        * that all fragments have been successfully received.
-        *
-        * When the event processing receives the notification, then the
-        * BTUSB_DOWNLOADING flag will be cleared.
-        *
-        * The firmware loading should not take longer than 5 seconds
-        * and thus just timeout if that happens and fail the setup
-        * of this device.
-        */
-       err = btusb_download_wait(hdev, calltime, 5000);
-       if (err == -ETIMEDOUT)
-               btintel_reset_to_bootloader(hdev);
-
-done:
-       release_firmware(fw);
-       return err;
-}
-
-static int btusb_intel_download_firmware(struct hci_dev *hdev,
-                                        struct intel_version *ver,
-                                        struct intel_boot_params *params,
-                                        u32 *boot_param)
-{
-       const struct firmware *fw;
-       char fwname[64];
-       int err;
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       ktime_t calltime;
-
-       if (!ver || !params)
-               return -EINVAL;
-
-       /* The firmware variant determines if the device is in bootloader
-        * mode or is running operational firmware. The value 0x06 identifies
-        * the bootloader and the value 0x23 identifies the operational
-        * firmware.
-        *
-        * When the operational firmware is already present, then only
-        * the check for valid Bluetooth device address is needed. This
-        * determines if the device will be added as configured or
-        * unconfigured controller.
-        *
-        * 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) {
-               clear_bit(BTUSB_BOOTLOADER, &data->flags);
-               btintel_check_bdaddr(hdev);
-
-               /* SfP and WsP don't seem to update the firmware version on file
-                * so version checking is currently possible.
-                */
-               switch (ver->hw_variant) {
-               case 0x0b:      /* SfP */
-               case 0x0c:      /* WsP */
-                       return 0;
-               }
-
-               /* Proceed to download to check if the version matches */
-               goto download;
-       }
-
-       /* Read the secure boot parameters to identify the operating
-        * details of the bootloader.
-        */
-       err = btintel_read_boot_params(hdev, params);
-       if (err)
-               return err;
-
-       /* It is required that every single firmware fragment is acknowledged
-        * 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) {
-               bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
-                          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(&params->otp_bdaddr, BDADDR_ANY)) {
-               bt_dev_info(hdev, "No device address configured");
-               set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
-       }
-
-download:
-       /* With this Intel bootloader only the hardware variant and device
-        * revision information are used to select the right firmware for SfP
-        * and WsP.
-        *
-        * The firmware filename is ibt-<hw_variant>-<dev_revid>.sfi.
-        *
-        * Currently the supported hardware variants are:
-        *   11 (0x0b) for iBT3.0 (LnP/SfP)
-        *   12 (0x0c) for iBT3.5 (WsP)
-        *
-        * For ThP/JfP and for future SKU's, the FW name varies based on HW
-        * variant, HW revision and FW revision, as these are dependent on CNVi
-        * and RF Combination.
-        *
-        *   17 (0x11) for iBT3.5 (JfP)
-        *   18 (0x12) for iBT3.5 (ThP)
-        *
-        * The firmware file name for these will be
-        * ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
-        *
-        */
-       err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
-                                               sizeof(fwname), "sfi");
-       if (err < 0) {
-               if (!test_bit(BTUSB_BOOTLOADER, &data->flags)) {
-                       /* Firmware has already been loaded */
-                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-                       return 0;
-               }
-
-               bt_dev_err(hdev, "Unsupported Intel firmware naming");
-               return -EINVAL;
-       }
-
-       err = firmware_request_nowarn(&fw, fwname, &hdev->dev);
-       if (err < 0) {
-               if (!test_bit(BTUSB_BOOTLOADER, &data->flags)) {
-                       /* Firmware has already been loaded */
-                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-                       return 0;
-               }
-
-               bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
-                          fwname, err);
-               return err;
-       }
-
-       bt_dev_info(hdev, "Found device firmware: %s", fwname);
-
-       if (fw->size < 644) {
-               bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
-                          fw->size);
-               err = -EBADF;
-               goto done;
-       }
-
-       calltime = ktime_get();
-
-       set_bit(BTUSB_DOWNLOADING, &data->flags);
-
-       /* Start firmware downloading and get boot parameter */
-       err = btintel_download_firmware(hdev, ver, fw, boot_param);
-       if (err < 0) {
-               if (err == -EALREADY) {
-                       /* Firmware has already been loaded */
-                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-                       err = 0;
-                       goto done;
-               }
-
-               /* When FW download fails, send Intel Reset to retry
-                * FW download.
-                */
-               btintel_reset_to_bootloader(hdev);
-               goto done;
-       }
-
-       /* Before switching the device into operational mode and with that
-        * booting the loaded firmware, wait for the bootloader notification
-        * that all fragments have been successfully received.
-        *
-        * When the event processing receives the notification, then the
-        * BTUSB_DOWNLOADING flag will be cleared.
-        *
-        * The firmware loading should not take longer than 5 seconds
-        * and thus just timeout if that happens and fail the setup
-        * of this device.
-        */
-       err = btusb_download_wait(hdev, calltime, 5000);
-       if (err == -ETIMEDOUT)
-               btintel_reset_to_bootloader(hdev);
-
-done:
-       release_firmware(fw);
-       return err;
-}
-
-static int btusb_boot_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
-{
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       ktime_t delta, rettime;
-       unsigned long long duration;
-       int err;
-
-       bt_dev_info(hdev, "Waiting for device to boot");
-
-       err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
-                                 TASK_INTERRUPTIBLE,
-                                 msecs_to_jiffies(msec));
-       if (err == -EINTR) {
-               bt_dev_err(hdev, "Device boot interrupted");
-               return -EINTR;
-       }
-
-       if (err) {
-               bt_dev_err(hdev, "Device boot timeout");
-               return -ETIMEDOUT;
-       }
-
-       rettime = ktime_get();
-       delta = ktime_sub(rettime, calltime);
-       duration = (unsigned long long) ktime_to_ns(delta) >> 10;
-
-       bt_dev_info(hdev, "Device booted in %llu usecs", duration);
-
-       return 0;
-}
-
-static int btusb_intel_boot(struct hci_dev *hdev, u32 boot_addr)
-{
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       ktime_t calltime;
-       int err;
-
-       calltime = ktime_get();
-
-       set_bit(BTUSB_BOOTING, &data->flags);
-
-       err = btintel_send_intel_reset(hdev, boot_addr);
-       if (err) {
-               bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
-               btintel_reset_to_bootloader(hdev);
-               return err;
-       }
-
-       /* The bootloader will not indicate when the device is ready. This
-        * is done by the operational firmware sending bootup notification.
-        *
-        * Booting into operational firmware should not take longer than
-        * 1 second. However if that happens, then just fail the setup
-        * since something went wrong.
-        */
-       err = btusb_boot_wait(hdev, calltime, 1000);
-       if (err == -ETIMEDOUT)
-               btintel_reset_to_bootloader(hdev);
-
-       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];
-       int err;
-       struct intel_debug_features features;
-
-       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;
-
-       /* 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;
-       }
-
-       err = btintel_version_info(hdev, &ver);
-       if (err)
-               return err;
-
-       err = btusb_intel_download_firmware(hdev, &ver, &params, &boot_param);
-       if (err)
-               return err;
-
-       /* controller is already having an operational firmware */
-       if (ver.fw_variant == 0x23)
-               goto finish;
-
-       err = btusb_intel_boot(hdev, boot_param);
-       if (err)
-               return err;
-
-       clear_bit(BTUSB_BOOTLOADER, &data->flags);
-
-       err = btusb_setup_intel_new_get_fw_name(&ver, &params, ddcname,
-                                               sizeof(ddcname), "ddc");
-
-       if (err < 0) {
-               bt_dev_err(hdev, "Unsupported Intel firmware naming");
-       } else {
-               /* Once the device is running in operational mode, it needs to
-                * apply the device configuration (DDC) parameters.
-                *
-                * The device can work without DDC parameters, so even if it
-                * fails to load the file, no need to fail the setup.
-                */
-               btintel_load_ddc_config(hdev, ddcname);
-       }
-
-       /* Read the Intel supported features and if new exception formats
-        * supported, need to load the additional DDC config to enable.
-        */
-       err = btintel_read_debug_features(hdev, &features);
-       if (!err) {
-               /* Set DDC mask for available debug features */
-               btintel_set_debug_features(hdev, &features);
-       }
-
-       /* Read the Intel version information after loading the FW  */
-       err = btintel_read_version(hdev, &ver);
-       if (err)
-               return err;
-
-       btintel_version_info(hdev, &ver);
-
-finish:
-       /* All Intel controllers that support the Microsoft vendor
-        * extension are using 0xFC1E for VsMsftOpCode.
-        */
-       switch (ver.hw_variant) {
-       case 0x11:      /* JfP */
-       case 0x12:      /* ThP */
-       case 0x13:      /* HrP */
-       case 0x14:      /* CcP */
-               hci_set_msft_opcode(hdev, 0xFC1E);
-               break;
-       }
-
-       /* Set the event mask for Intel specific vendor events. This enables
-        * a few extra events that are useful during general operation. It
-        * does not enable any debugging related events.
-        *
-        * The device will function correctly without these events enabled
-        * and thus no need to fail the setup.
-        */
-       btintel_set_event_mask(hdev, false);
-
-       return 0;
-}
-
-static int btusb_setup_intel_newgen(struct hci_dev *hdev)
-{
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       u32 boot_param;
-       char ddcname[64];
-       int err;
-       struct intel_debug_features features;
-       struct intel_version_tlv version;
-
-       bt_dev_dbg(hdev, "");
-
-       /* 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;
-
-       /* 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_tlv(hdev, &version);
-       if (err) {
-               bt_dev_err(hdev, "Intel Read version failed (%d)", err);
-               btintel_reset_to_bootloader(hdev);
-               return err;
-       }
-
-       err = btintel_version_info_tlv(hdev, &version);
-       if (err)
-               return err;
-
-       err = btusb_intel_download_firmware_newgen(hdev, &version, &boot_param);
-       if (err)
-               return err;
-
-       /* check if controller is already having an operational firmware */
-       if (version.img_type == 0x03)
-               goto finish;
-
-       err = btusb_intel_boot(hdev, boot_param);
-       if (err)
-               return err;
-
-       clear_bit(BTUSB_BOOTLOADER, &data->flags);
-
-       btusb_setup_intel_newgen_get_fw_name(&version, ddcname, sizeof(ddcname),
-                                            "ddc");
-       /* Once the device is running in operational mode, it needs to
-        * apply the device configuration (DDC) parameters.
-        *
-        * The device can work without DDC parameters, so even if it
-        * fails to load the file, no need to fail the setup.
-        */
-       btintel_load_ddc_config(hdev, ddcname);
-
-       /* Read the Intel supported features and if new exception formats
-        * supported, need to load the additional DDC config to enable.
-        */
-       err = btintel_read_debug_features(hdev, &features);
-       if (!err) {
-               /* Set DDC mask for available debug features */
-               btintel_set_debug_features(hdev, &features);
-       }
-
-       /* Read the Intel version information after loading the FW  */
-       err = btintel_read_version_tlv(hdev, &version);
-       if (err)
-               return err;
-
-       btintel_version_info_tlv(hdev, &version);
-
-finish:
-       /* All Intel new genration controllers support the Microsoft vendor
-        * extension are using 0xFC1E for VsMsftOpCode.
-        */
-       switch (INTEL_HW_VARIANT(version.cnvi_bt)) {
-       case 0x17:
-       case 0x18:
-       case 0x19:
-               hci_set_msft_opcode(hdev, 0xFC1E);
-               break;
-       }
-
-       /* Set the event mask for Intel specific vendor events. This enables
-        * a few extra events that are useful during general operation. It
-        * does not enable any debugging related events.
-        *
-        * The device will function correctly without these events enabled
-        * and thus no need to fail the setup.
-        */
-       btintel_set_event_mask(hdev, false);
-
-       return 0;
-}
-
-static int btusb_shutdown_intel_new(struct hci_dev *hdev)
-{
-       struct sk_buff *skb;
-
-       /* Send HCI Reset to the controller to stop any BT activity which
-        * were triggered. This will help to save power and maintain the
-        * sync b/w Host and controller
-        */
-       skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
-       if (IS_ERR(skb)) {
-               bt_dev_err(hdev, "HCI reset during shutdown failed");
-               return PTR_ERR(skb);
-       }
-       kfree_skb(skb);
-
-       return 0;
-}
-
 /* UHW CR mapping */
 #define MTK_BT_MISC            0x70002510
 #define MTK_BT_SUBSYS_RST      0x70002610
@@ -4389,18 +3723,16 @@ static int btusb_probe(struct usb_interface *intf,
 
        priv_size = 0;
 
+       data->recv_event = hci_recv_frame;
+       data->recv_bulk = btusb_recv_bulk;
+
        if (id->driver_info & BTUSB_INTEL_COMBINED) {
                /* Allocate extra space for Intel device */
                priv_size += sizeof(struct btintel_data);
-       }
 
-       if (id->driver_info & BTUSB_INTEL_NEW) {
+               /* Override the rx handlers */
                data->recv_event = btusb_recv_event_intel;
                data->recv_bulk = btusb_recv_bulk_intel;
-               set_bit(BTUSB_BOOTLOADER, &data->flags);
-       } else {
-               data->recv_event = hci_recv_frame;
-               data->recv_bulk = btusb_recv_bulk;
        }
 
        data->recv_acl = hci_recv_frame;
@@ -4486,6 +3818,7 @@ static int btusb_probe(struct usb_interface *intf,
                        goto out_free_dev;
 
                /* Transport specific configuration */
+               hdev->send = btusb_send_frame_intel;
                hdev->cmd_timeout = btusb_intel_cmd_timeout;
 
                set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
@@ -4496,38 +3829,6 @@ static int btusb_probe(struct usb_interface *intf,
                        btintel_set_flag(hdev, INTEL_BROKEN_INITIAL_NCMD);
        }
 
-       if (id->driver_info & BTUSB_INTEL_NEW) {
-               hdev->manufacturer = 2;
-               hdev->send = btusb_send_frame_intel;
-               hdev->setup = btusb_setup_intel_new;
-               hdev->shutdown = btusb_shutdown_intel_new;
-               hdev->hw_error = btintel_hw_error;
-               hdev->set_diag = btintel_set_diag;
-               hdev->set_bdaddr = btintel_set_bdaddr;
-               hdev->cmd_timeout = btusb_intel_cmd_timeout;
-               set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
-               set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
-               set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
-       }
-
-       if (id->driver_info & BTUSB_INTEL_NEWGEN) {
-               hdev->manufacturer = 2;
-               hdev->send = btusb_send_frame_intel;
-               hdev->setup = btusb_setup_intel_newgen;
-               hdev->shutdown = btusb_shutdown_intel_new;
-               hdev->hw_error = btintel_hw_error;
-               hdev->set_diag = btintel_set_diag;
-               hdev->set_bdaddr = btintel_set_bdaddr;
-               hdev->cmd_timeout = btusb_intel_cmd_timeout;
-               set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
-               set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
-               set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
-
-               data->recv_event = btusb_recv_event_intel;
-               data->recv_bulk = btusb_recv_bulk_intel;
-               set_bit(BTUSB_BOOTLOADER, &data->flags);
-       }
-
        if (id->driver_info & BTUSB_MARVELL)
                hdev->set_bdaddr = btusb_set_bdaddr_marvell;