|
@@ -2502,11 +2502,9 @@ static const struct qca_device_info qca_devices_table[] = {
|
|
|
{ 0x00000302, 28, 4, 18 }, /* Rome 3.2 */
|
|
|
};
|
|
|
|
|
|
-static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
|
|
+static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
|
|
|
void *data, u16 size)
|
|
|
{
|
|
|
- struct btusb_data *btdata = hci_get_drvdata(hdev);
|
|
|
- struct usb_device *udev = btdata->udev;
|
|
|
int pipe, err;
|
|
|
u8 *buf;
|
|
|
|
|
@@ -2521,7 +2519,7 @@ static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
|
|
err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
|
|
|
0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
|
|
|
if (err < 0) {
|
|
|
- bt_dev_err(hdev, "Failed to access otp area (%d)", err);
|
|
|
+ dev_err(&udev->dev, "Failed to access otp area (%d)", err);
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
@@ -2671,20 +2669,38 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/* identify the ROM version and check whether patches are needed */
|
|
|
+static bool btusb_qca_need_patch(struct usb_device *udev)
|
|
|
+{
|
|
|
+ struct qca_version ver;
|
|
|
+
|
|
|
+ if (btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
|
|
+ sizeof(ver)) < 0)
|
|
|
+ return false;
|
|
|
+ /* only low ROM versions need patches */
|
|
|
+ return !(le32_to_cpu(ver.rom_version) & ~0xffffU);
|
|
|
+}
|
|
|
+
|
|
|
static int btusb_setup_qca(struct hci_dev *hdev)
|
|
|
{
|
|
|
+ struct btusb_data *btdata = hci_get_drvdata(hdev);
|
|
|
+ struct usb_device *udev = btdata->udev;
|
|
|
const struct qca_device_info *info = NULL;
|
|
|
struct qca_version ver;
|
|
|
u32 ver_rom;
|
|
|
u8 status;
|
|
|
int i, err;
|
|
|
|
|
|
- err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
|
|
|
+ err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
|
|
sizeof(ver));
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
|
ver_rom = le32_to_cpu(ver.rom_version);
|
|
|
+ /* Don't care about high ROM versions */
|
|
|
+ if (ver_rom & ~0xffffU)
|
|
|
+ return 0;
|
|
|
+
|
|
|
for (i = 0; i < ARRAY_SIZE(qca_devices_table); i++) {
|
|
|
if (ver_rom == qca_devices_table[i].rom_version)
|
|
|
info = &qca_devices_table[i];
|
|
@@ -2694,7 +2710,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- err = btusb_qca_send_vendor_req(hdev, QCA_CHECK_STATUS, &status,
|
|
|
+ err = btusb_qca_send_vendor_req(udev, QCA_CHECK_STATUS, &status,
|
|
|
sizeof(status));
|
|
|
if (err < 0)
|
|
|
return err;
|
|
@@ -2908,7 +2924,8 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
/* Old firmware would otherwise let ath3k driver load
|
|
|
* patch and sysconfig files
|
|
|
*/
|
|
|
- if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
|
|
|
+ if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001 &&
|
|
|
+ !btusb_qca_need_patch(udev))
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
@@ -3070,6 +3087,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
}
|
|
|
|
|
|
if (id->driver_info & BTUSB_ATH3012) {
|
|
|
+ data->setup_on_usb = btusb_setup_qca;
|
|
|
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
|
|
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
|
|
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
|