#define VERSION "0.6"
-static bool ignore_dga;
-static bool ignore_csr;
-static bool ignore_sniffer;
static bool disable_scofix;
static bool force_scofix;
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
#define BTUSB_INTEL 0x100
-#define BTUSB_BCM_PATCHRAM 0x200
+#define BTUSB_INTEL_BOOT 0x200
+#define BTUSB_BCM_PATCHRAM 0x400
+#define BTUSB_MARVELL 0x800
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM },
+ /* ASUSTek Computer - Broadcom based */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0b05, 0xff, 0x01, 0x01) },
+
/* Belkin F8065bf - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
/* IMC Networks - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
+ /* Intel Bluetooth USB Bootloader (RAM module) */
+ { USB_DEVICE(0x8087, 0x0a5a),
+ .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
+
{ } /* Terminating entry */
};
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
/* CSR BlueCore Bluetooth Sniffer */
- { USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
+ { USB_DEVICE(0x0a12, 0x0002),
+ .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
/* Frontline ComProbe Bluetooth Sniffer */
- { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
+ { USB_DEVICE(0x16d3, 0x0002),
+ .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
/* Intel Bluetooth device */
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
+ /* Marvell device */
+ { USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
+ { USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
+
{ } /* Terminating entry */
};
* fully operational, but have the danger of duplicate addresses
* and that in turn can cause problems with Bluetooth operation.
*/
- if (!bacmp(&rp->bdaddr, BDADDR_INTEL))
+ if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) {
BT_ERR("%s found Intel default device address (%pMR)",
hdev->name, &rp->bdaddr);
+ set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+ }
kfree_skb(skb);
return 0;
}
+static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
+ const bdaddr_t *bdaddr)
+{
+ struct sk_buff *skb;
+ u8 buf[8];
+ long ret;
+
+ buf[0] = 0xfe;
+ buf[1] = sizeof(bdaddr_t);
+ memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
+
+ skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ BT_ERR("%s: changing Marvell device address failed (%ld)",
+ hdev->name, ret);
+ return ret;
+ }
+ kfree_skb(skb);
+
+ return 0;
+}
+
#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
/* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
* with no configured address.
*/
- if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0))
+ if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
BT_INFO("%s: BCM: using default device address (%pMR)",
hdev->name, &bda->bdaddr);
+ set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+ }
kfree_skb(skb);
if (id->driver_info == BTUSB_IGNORE)
return -ENODEV;
- if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
- return -ENODEV;
-
- if (ignore_csr && id->driver_info & BTUSB_CSR)
- return -ENODEV;
-
- if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
- return -ENODEV;
-
if (id->driver_info & BTUSB_ATH3012) {
struct usb_device *udev = interface_to_usbdev(intf);
hdev->set_bdaddr = btusb_set_bdaddr_intel;
}
+ if (id->driver_info & BTUSB_MARVELL)
+ hdev->set_bdaddr = btusb_set_bdaddr_marvell;
+
+ if (id->driver_info & BTUSB_INTEL_BOOT)
+ set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
/* New sniffer firmware has crippled HCI interface */
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+ }
- data->isoc = NULL;
+ if (id->driver_info & BTUSB_INTEL_BOOT) {
+ /* A bug in the bootloader causes that interrupt interface is
+ * only enabled after receiving SetInterface(0, AltSetting=0).
+ */
+ err = usb_set_interface(data->udev, 0, 0);
+ if (err < 0) {
+ BT_ERR("failed to set interface 0, alt 0 %d", err);
+ hci_free_dev(hdev);
+ return err;
+ }
}
if (data->isoc) {
module_usb_driver(btusb_driver);
-module_param(ignore_dga, bool, 0644);
-MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
-
-module_param(ignore_csr, bool, 0644);
-MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
-
-module_param(ignore_sniffer, bool, 0644);
-MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
-
module_param(disable_scofix, bool, 0644);
MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");