Merge tag 'gcc-plugins-v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / bluetooth / btusb.c
index 3bbe8f4..03b83aa 100644 (file)
@@ -60,6 +60,7 @@ 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
 
 static const struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
@@ -365,7 +366,7 @@ static const struct usb_device_id blacklist_table[] = {
                                                     BTUSB_WIDEBAND_SPEECH },
        { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW |
                                                     BTUSB_WIDEBAND_SPEECH },
-       { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_NEW |
+       { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_NEWGEN |
                                                     BTUSB_WIDEBAND_SPEECH},
        { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
@@ -1788,9 +1789,12 @@ static int btusb_setup_bcm92035(struct hci_dev *hdev)
 
 static int btusb_setup_csr(struct hci_dev *hdev)
 {
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       u16 bcdDevice = le16_to_cpu(data->udev->descriptor.bcdDevice);
        struct hci_rp_read_local_version *rp;
        struct sk_buff *skb;
        bool is_fake = false;
+       int ret;
 
        BT_DBG("%s", hdev->name);
 
@@ -1857,6 +1861,12 @@ static int btusb_setup_csr(struct hci_dev *hdev)
                 le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_4_0)
                is_fake = true;
 
+       /* Other clones which beat all the above checks */
+       else if (bcdDevice == 0x0134 &&
+                le16_to_cpu(rp->lmp_subver) == 0x0c5c &&
+                le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_2_0)
+               is_fake = true;
+
        if (is_fake) {
                bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds...");
 
@@ -1873,6 +1883,43 @@ static int btusb_setup_csr(struct hci_dev *hdev)
                 */
                clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
                clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+
+               /*
+                * Special workaround for clones with a Barrot 8041a02 chip,
+                * these clones are really messed-up:
+                * 1. Their bulk rx endpoint will never report any data unless
+                * the device was suspended at least once (yes really).
+                * 2. They will not wakeup when autosuspended and receiving data
+                * on their bulk rx endpoint from e.g. a keyboard or mouse
+                * (IOW remote-wakeup support is broken for the bulk endpoint).
+                *
+                * To fix 1. enable runtime-suspend, force-suspend the
+                * hci and then wake-it up by disabling runtime-suspend.
+                *
+                * To fix 2. clear the hci's can_wake flag, this way the hci
+                * will still be autosuspended when it is not open.
+                */
+               if (bcdDevice == 0x8891 &&
+                   le16_to_cpu(rp->lmp_subver) == 0x1012 &&
+                   le16_to_cpu(rp->hci_rev) == 0x0810 &&
+                   le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_4_0) {
+                       bt_dev_warn(hdev, "CSR: detected a fake CSR dongle using a Barrot 8041a02 chip, this chip is very buggy and may have issues\n");
+
+                       pm_runtime_allow(&data->udev->dev);
+
+                       ret = pm_runtime_suspend(&data->udev->dev);
+                       if (ret >= 0)
+                               msleep(200);
+                       else
+                               bt_dev_err(hdev, "Failed to suspend the device for Barrot 8041a02 receive-issue workaround\n");
+
+                       pm_runtime_forbid(&data->udev->dev);
+
+                       device_set_wakeup_capable(&data->udev->dev, false);
+                       /* Re-enable autosuspend if this was requested */
+                       if (enable_autosuspend)
+                               usb_enable_autosuspend(data->udev);
+               }
        }
 
        kfree_skb(skb);
@@ -2384,6 +2431,182 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
        return true;
 }
 
+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_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);
+
+       if (!ver || !boot_param)
+               return -EINVAL;
+
+       /* The hardware platform number has a fixed value of 0x37 and
+        * for now only accept this single value.
+        */
+       if (INTEL_HW_PLATFORM(ver->cnvi_bt) != 0x37) {
+               bt_dev_err(hdev, "Unsupported Intel hardware platform (0x%2x)",
+                          INTEL_HW_PLATFORM(ver->cnvi_bt));
+               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);
+               return 0;
+       }
+
+       /* 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->cnvi_bt)) {
+       case 0x17:      /* TyP */
+       case 0x18:      /* Slr */
+       case 0x19:      /* Slr-F */
+               break;
+       default:
+               bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)",
+                          INTEL_HW_VARIANT(ver->cnvi_bt));
+               return -EINVAL;
+       }
+
+       /* 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->img_type != 0x01) {
+               bt_dev_err(hdev, "Unsupported Intel firmware variant (0x%x)",
+                          ver->img_type);
+               return -ENODEV;
+       }
+
+       /* 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 (ver->limited_cce != 0x00) {
+               bt_dev_err(hdev, "Unsupported Intel firmware loading method (0x%x)",
+                          ver->limited_cce);
+               return -EINVAL;
+       }
+
+       /* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */
+       if (ver->sbe_type > 0x01) {
+               bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)",
+                          ver->sbe_type);
+               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(&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 = request_firmware(&fw, fwname, &hdev->dev);
+       if (err < 0) {
+               bt_dev_err(hdev, "Failed to load Intel firmware file (%d)", 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;
+       }
+
+       set_bit(BTUSB_DOWNLOADING, &data->flags);
+
+       /* Start firmware downloading and get boot parameter */
+       err = btintel_download_firmware_newgen(hdev, fw, boot_param,
+                                              INTEL_HW_VARIANT(ver->cnvi_bt),
+                                              ver->sbe_type);
+       if (err < 0) {
+               /* When FW download fails, send Intel Reset to retry
+                * FW download.
+                */
+               btintel_reset_to_bootloader(hdev);
+               goto done;
+       }
+       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+
+       bt_dev_info(hdev, "Waiting for firmware download to complete");
+
+       /* 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 = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
+                                 TASK_INTERRUPTIBLE,
+                                 msecs_to_jiffies(5000));
+       if (err == -EINTR) {
+               bt_dev_err(hdev, "Firmware loading interrupted");
+               goto done;
+       }
+
+       if (err) {
+               bt_dev_err(hdev, "Firmware loading timeout");
+               err = -ETIMEDOUT;
+               btintel_reset_to_bootloader(hdev);
+               goto done;
+       }
+
+       if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
+               bt_dev_err(hdev, "Firmware loading failed");
+               err = -ENOEXEC;
+               goto done;
+       }
+
+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,
@@ -2718,6 +2941,134 @@ finish:
        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];
+       ktime_t calltime, delta, rettime;
+       unsigned long long duration;
+       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;
+
+       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_tlv(hdev, &version);
+       if (err) {
+               bt_dev_err(hdev, "Intel Read version failed (%d)", err);
+               btintel_reset_to_bootloader(hdev);
+               return err;
+       }
+
+       btintel_version_info_tlv(hdev, &version);
+
+       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;
+
+       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);
+
+       calltime = ktime_get();
+
+       set_bit(BTUSB_BOOTING, &data->flags);
+
+       err = btintel_send_intel_reset(hdev, boot_param);
+       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.
+        */
+       bt_dev_info(hdev, "Waiting for device to boot");
+
+       err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
+                                 TASK_INTERRUPTIBLE,
+                                 msecs_to_jiffies(1000));
+
+       if (err == -EINTR) {
+               bt_dev_err(hdev, "Device boot interrupted");
+               return -EINTR;
+       }
+
+       if (err) {
+               bt_dev_err(hdev, "Device boot timeout");
+               btintel_reset_to_bootloader(hdev);
+               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);
+
+       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.
+        */
+       btintel_read_debug_features(hdev, &features);
+
+       /* 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:
+       /* 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(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
@@ -3469,12 +3820,14 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,
 #define QCA_SYSCFG_UPDATED     0x40
 #define QCA_PATCH_UPDATED      0x80
 #define QCA_DFU_TIMEOUT                3000
+#define QCA_FLAG_MULTI_NVM      0x80
 
 struct qca_version {
        __le32  rom_version;
        __le32  patch_version;
        __le32  ram_version;
-       __le32  ref_clock;
+       __le16  board_id;
+       __le16  flag;
        __u8    reserved[4];
 } __packed;
 
@@ -3657,8 +4010,14 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
        char fwname[64];
        int err;
 
-       snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
-                le32_to_cpu(ver->rom_version));
+       if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
+               snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
+                        le32_to_cpu(ver->rom_version),
+                        le16_to_cpu(ver->board_id));
+       } else {
+               snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
+                        le32_to_cpu(ver->rom_version));
+       }
 
        err = request_firmware(&fw, fwname, &hdev->dev);
        if (err) {
@@ -3725,6 +4084,11 @@ static int btusb_setup_qca(struct hci_dev *hdev)
                        return err;
        }
 
+       err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
+                                       sizeof(ver));
+       if (err < 0)
+               return err;
+
        if (!(status & QCA_SYSCFG_UPDATED)) {
                err = btusb_setup_qca_load_nvm(hdev, &ver, info);
                if (err < 0)
@@ -4103,6 +4467,24 @@ static int btusb_probe(struct usb_interface *intf,
                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;