diff options
-rw-r--r-- | drivers/bluetooth/btintel.c | 62 | ||||
-rw-r--r-- | drivers/bluetooth/btintel.h | 12 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 27 |
3 files changed, 92 insertions, 9 deletions
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index e4496faf8cf5..1f13e617bf56 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -111,13 +111,15 @@ int btintel_set_diag(struct hci_dev *hdev, bool enable) if (IS_ERR(skb)) { err = PTR_ERR(skb); if (err == -ENODATA) - return 0; + goto done; BT_ERR("%s: Changing Intel diagnostic mode failed (%d)", hdev->name, err); return err; } kfree_skb(skb); +done: + btintel_set_event_mask(hdev, enable); return 0; } EXPORT_SYMBOL_GPL(btintel_set_diag); @@ -283,6 +285,64 @@ int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name) } EXPORT_SYMBOL_GPL(btintel_load_ddc_config); +int btintel_set_event_mask(struct hci_dev *hdev, bool debug) +{ + u8 mask[8] = { 0x87, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + struct sk_buff *skb; + int err; + + if (debug) + mask[1] |= 0x62; + + skb = __hci_cmd_sync(hdev, 0xfc52, 8, mask, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: Setting Intel event mask failed (%d)", + hdev->name, err); + return err; + } + kfree_skb(skb); + + return 0; +} +EXPORT_SYMBOL_GPL(btintel_set_event_mask); + +int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug) +{ + struct sk_buff *skb; + u8 param[2]; + int err; + + param[0] = 0x01; + param[1] = 0x00; + + skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: Entering Intel manufacturer mode failed (%d)", + hdev->name, err); + return PTR_ERR(skb); + } + kfree_skb(skb); + + err = btintel_set_event_mask(hdev, debug); + + param[0] = 0x00; + param[1] = 0x00; + + skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: Leaving Intel manufacturer mode failed (%d)", + hdev->name, err); + return PTR_ERR(skb); + } + kfree_skb(skb); + + return err; +} +EXPORT_SYMBOL_GPL(btintel_set_event_mask_mfg); + /* ------- REGMAP IBT SUPPORT ------- */ #define IBT_REG_MODE_8BIT 0x00 diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index 702a276b3c60..07e58e05a7fa 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -81,6 +81,8 @@ void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver); int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen, const void *param); int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name); +int btintel_set_event_mask(struct hci_dev *hdev, bool debug); +int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug); struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read, u16 opcode_write); @@ -128,6 +130,16 @@ static inline int btintel_load_ddc_config(struct hci_dev *hdev, return -EOPNOTSUPP; } +static inline int btintel_set_event_mask(struct hci_dev *hdev, bool debug) +{ + return -EOPNOTSUPP; +} + +static inline int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug) +{ + return -EOPNOTSUPP; +} + static inline struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read, u16 opcode_write) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 19961763015a..e33dacf5bd98 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1701,8 +1701,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) BT_INFO("%s: Intel device is already patched. patch num: %02x", hdev->name, ver->fw_patch_num); kfree_skb(skb); - btintel_check_bdaddr(hdev); - return 0; + goto complete; } /* Opens the firmware patch file based on the firmware version read @@ -1714,8 +1713,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) fw = btusb_setup_intel_get_fw(hdev, ver); if (!fw) { kfree_skb(skb); - btintel_check_bdaddr(hdev); - return 0; + goto complete; } fw_ptr = fw->data; @@ -1788,8 +1786,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) BT_INFO("%s: Intel Bluetooth firmware patch completed and activated", hdev->name); - btintel_check_bdaddr(hdev); - return 0; + goto complete; exit_mfg_disable: /* Disable the manufacturer mode without reset */ @@ -1804,8 +1801,7 @@ exit_mfg_disable: BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name); - btintel_check_bdaddr(hdev); - return 0; + goto complete; exit_mfg_deactivate: release_firmware(fw); @@ -1825,6 +1821,12 @@ exit_mfg_deactivate: BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated", hdev->name); +complete: + /* Set the event mask for Intel specific vendor events. This enables + * a few extra events that are useful during general operation. + */ + btintel_set_event_mask_mfg(hdev, false); + btintel_check_bdaddr(hdev); return 0; } @@ -2339,6 +2341,15 @@ done: */ btintel_load_ddc_config(hdev, fwname); + /* 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; } |