Bluetooth: btusb: Fix quirks table naming
[platform/kernel/linux-rpi.git] / drivers / bluetooth / btusb.c
index 2122e86..e98f5fc 100644 (file)
@@ -175,7 +175,7 @@ static const struct usb_device_id btusb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, btusb_table);
 
-static const struct usb_device_id blacklist_table[] = {
+static const struct usb_device_id quirks_table[] = {
        /* CSR BlueCore devices */
        { USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
 
@@ -476,6 +476,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_COMBINED },
        { USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED },
        { USB_DEVICE(0x8087, 0x0035), .driver_info = BTUSB_INTEL_COMBINED },
+       { USB_DEVICE(0x8087, 0x0036), .driver_info = BTUSB_INTEL_COMBINED },
        { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED |
                                                     BTUSB_INTEL_NO_WBS_SUPPORT |
@@ -625,9 +626,24 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0489, 0xe0e4), .driver_info = BTUSB_MEDIATEK |
                                                     BTUSB_WIDEBAND_SPEECH |
                                                     BTUSB_VALID_LE_STATES },
+       { USB_DEVICE(0x0489, 0xe0f1), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
        { USB_DEVICE(0x0489, 0xe0f2), .driver_info = BTUSB_MEDIATEK |
                                                     BTUSB_WIDEBAND_SPEECH |
                                                     BTUSB_VALID_LE_STATES },
+       { USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
+       { USB_DEVICE(0x0489, 0xe0f6), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
+       { USB_DEVICE(0x0489, 0xe102), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
+       { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK |
+                                                    BTUSB_WIDEBAND_SPEECH |
+                                                    BTUSB_VALID_LE_STATES },
 
        /* Additional Realtek 8723AE Bluetooth devices */
        { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
@@ -2476,79 +2492,6 @@ static int btusb_recv_bulk_intel(struct btusb_data *data, void *buffer,
        return btusb_recv_bulk(data, buffer, count);
 }
 
-static int btusb_intel_diagnostics(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct intel_tlv *tlv = (void *)&skb->data[5];
-
-       /* The first event is always an event type TLV */
-       if (tlv->type != INTEL_TLV_TYPE_ID)
-               goto recv_frame;
-
-       switch (tlv->val[0]) {
-       case INTEL_TLV_SYSTEM_EXCEPTION:
-       case INTEL_TLV_FATAL_EXCEPTION:
-       case INTEL_TLV_DEBUG_EXCEPTION:
-       case INTEL_TLV_TEST_EXCEPTION:
-               /* Generate devcoredump from exception */
-               if (!hci_devcd_init(hdev, skb->len)) {
-                       hci_devcd_append(hdev, skb);
-                       hci_devcd_complete(hdev);
-               } else {
-                       bt_dev_err(hdev, "Failed to generate devcoredump");
-                       kfree_skb(skb);
-               }
-               return 0;
-       default:
-               bt_dev_err(hdev, "Invalid exception type %02X", tlv->val[0]);
-       }
-
-recv_frame:
-       return hci_recv_frame(hdev, skb);
-}
-
-static int btusb_recv_event_intel(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_event_hdr *hdr = (void *)skb->data;
-       const char diagnostics_hdr[] = { 0x87, 0x80, 0x03 };
-
-       if (skb->len > HCI_EVENT_HDR_SIZE && hdr->evt == 0xff &&
-           hdr->plen > 0) {
-               const void *ptr = skb->data + HCI_EVENT_HDR_SIZE + 1;
-               unsigned int len = skb->len - HCI_EVENT_HDR_SIZE - 1;
-
-               if (btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
-                       switch (skb->data[2]) {
-                       case 0x02:
-                               /* When switching to the operational firmware
-                                * the device sends a vendor specific event
-                                * indicating that the bootup completed.
-                                */
-                               btintel_bootup(hdev, ptr, len);
-                               break;
-                       case 0x06:
-                               /* When the firmware loading completes the
-                                * device sends out a vendor specific event
-                                * indicating the result of the firmware
-                                * loading.
-                                */
-                               btintel_secure_send_result(hdev, ptr, len);
-                               break;
-                       }
-               }
-
-               /* Handle all diagnostics events separately. May still call
-                * hci_recv_frame.
-                */
-               if (len >= sizeof(diagnostics_hdr) &&
-                   memcmp(&skb->data[2], diagnostics_hdr,
-                          sizeof(diagnostics_hdr)) == 0) {
-                       return btusb_intel_diagnostics(hdev, skb);
-               }
-       }
-
-       return hci_recv_frame(hdev, skb);
-}
-
 static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct urb *urb;
@@ -3040,6 +2983,78 @@ static u32 btusb_mtk_reset_done(struct hci_dev *hdev)
        return val & MTK_BT_RST_DONE;
 }
 
+static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       struct btmediatek_data *mediatek;
+       u32 val;
+       int err;
+
+       /* It's MediaTek specific bluetooth reset mechanism via USB */
+       if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
+               bt_dev_err(hdev, "last reset failed? Not resetting again");
+               return -EBUSY;
+       }
+
+       err = usb_autopm_get_interface(data->intf);
+       if (err < 0)
+               return err;
+
+       btusb_stop_traffic(data);
+       usb_kill_anchored_urbs(&data->tx_anchor);
+       mediatek = hci_get_priv(hdev);
+
+       if (mediatek->dev_id == 0x7925) {
+               btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+               val |= (1 << 5);
+               btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+               btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+               val &= 0xFFFF00FF;
+               val |= (1 << 13);
+               btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+               btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
+               btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+               val |= (1 << 0);
+               btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
+               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
+               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
+               msleep(100);
+       } else {
+               /* It's Device EndPoint Reset Option Register */
+               bt_dev_dbg(hdev, "Initiating reset mechanism via uhw");
+               btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
+               btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val);
+
+               /* Reset the bluetooth chip via USB interface. */
+               btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1);
+               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
+               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
+               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
+               /* MT7921 need to delay 20ms between toggle reset bit */
+               msleep(20);
+               btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
+               btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
+       }
+
+       err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
+                                val & MTK_BT_RST_DONE, 20000, 1000000);
+       if (err < 0)
+               bt_dev_err(hdev, "Reset timeout");
+
+       btusb_mtk_id_get(data, 0x70010200, &val);
+       if (!val)
+               bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
+
+       usb_queue_reset_device(data->intf);
+
+       clear_bit(BTUSB_HW_RESET_ACTIVE, &data->flags);
+
+       return err;
+}
+
 static int btusb_mtk_setup(struct hci_dev *hdev)
 {
        struct btusb_data *data = hci_get_drvdata(hdev);
@@ -3079,6 +3094,11 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
 
        mediatek = hci_get_priv(hdev);
        mediatek->dev_id = dev_id;
+       mediatek->reset_sync = btusb_mtk_reset;
+
+       err = btmtk_register_coredump(hdev, btusb_driver.name, fw_version);
+       if (err < 0)
+               bt_dev_err(hdev, "Failed to register coredump (%d)", err);
 
        switch (dev_id) {
        case 0x7663:
@@ -3236,80 +3256,11 @@ static int btusb_mtk_shutdown(struct hci_dev *hdev)
        return 0;
 }
 
-static void btusb_mtk_cmd_timeout(struct hci_dev *hdev)
-{
-       struct btusb_data *data = hci_get_drvdata(hdev);
-       u32 val;
-       int err;
-       struct btmediatek_data *mediatek;
-
-       /* It's MediaTek specific bluetooth reset mechanism via USB */
-       if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
-               bt_dev_err(hdev, "last reset failed? Not resetting again");
-               return;
-       }
-
-       err = usb_autopm_get_interface(data->intf);
-       if (err < 0)
-               return;
-
-       btusb_stop_traffic(data);
-       usb_kill_anchored_urbs(&data->tx_anchor);
-       mediatek = hci_get_priv(hdev);
-
-       if (mediatek->dev_id == 0x7925) {
-               btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
-               val |= (1 << 5);
-               btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
-               btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
-               val &= 0xFFFF00FF;
-               val |= (1 << 13);
-               btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
-               btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
-               btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
-               val |= (1 << 0);
-               btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
-               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
-               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
-               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
-               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
-               msleep(100);
-       } else {
-               /* It's Device EndPoint Reset Option Register */
-               bt_dev_dbg(hdev, "Initiating reset mechanism via uhw");
-               btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
-               btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val);
-
-               /* Reset the bluetooth chip via USB interface. */
-               btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1);
-               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
-               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
-               btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
-               btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
-               /* MT7921 need to delay 20ms between toggle reset bit */
-               msleep(20);
-               btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
-               btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
-       }
-
-       err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
-                                val & MTK_BT_RST_DONE, 20000, 1000000);
-       if (err < 0)
-               bt_dev_err(hdev, "Reset timeout");
-
-       btusb_mtk_id_get(data, 0x70010200, &val);
-       if (!val)
-               bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
-
-       usb_queue_reset_device(data->intf);
-
-       clear_bit(BTUSB_HW_RESET_ACTIVE, &data->flags);
-}
-
 static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct btusb_data *data = hci_get_drvdata(hdev);
        u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle);
+       struct sk_buff *skb_cd;
 
        switch (handle) {
        case 0xfc6f:            /* Firmware dump from device */
@@ -3317,6 +3268,15 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb)
                 * suspend and thus disable auto-suspend.
                 */
                usb_disable_autosuspend(data->udev);
+
+               /* We need to forward the diagnostic packet to userspace daemon
+                * for backward compatibility, so we have to clone the packet
+                * extraly for the in-kernel coredump support.
+                */
+               skb_cd = skb_clone(skb, GFP_ATOMIC);
+               if (skb_cd)
+                       btmtk_process_coredump(hdev, skb_cd);
+
                fallthrough;
        case 0x05ff:            /* Firmware debug logging 1 */
        case 0x05fe:            /* Firmware debug logging 2 */
@@ -4234,7 +4194,7 @@ static int btusb_probe(struct usb_interface *intf,
        if (!id->driver_info) {
                const struct usb_device_id *match;
 
-               match = usb_match_id(intf, blacklist_table);
+               match = usb_match_id(intf, quirks_table);
                if (match)
                        id = match;
        }
@@ -4317,7 +4277,7 @@ static int btusb_probe(struct usb_interface *intf,
                priv_size += sizeof(struct btintel_data);
 
                /* Override the rx handlers */
-               data->recv_event = btusb_recv_event_intel;
+               data->recv_event = btintel_recv_event;
                data->recv_bulk = btusb_recv_bulk_intel;
        } else if (id->driver_info & BTUSB_REALTEK) {
                /* Allocate extra space for Realtek device */
@@ -4433,7 +4393,7 @@ static int btusb_probe(struct usb_interface *intf,
                hdev->setup = btusb_mtk_setup;
                hdev->shutdown = btusb_mtk_shutdown;
                hdev->manufacturer = 70;
-               hdev->cmd_timeout = btusb_mtk_cmd_timeout;
+               hdev->cmd_timeout = btmtk_reset_sync;
                hdev->set_bdaddr = btmtk_set_bdaddr;
                set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks);
                set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);