| From 2222ea387559ee8f994e1c046983d047c5d642d1 Mon Sep 17 00:00:00 2001 |
| From: Joseph Hwang <josephsih@chromium.org> |
| Date: Sat, 8 May 2021 17:19:34 +0800 |
| Subject: [PATCH] CHROMIUM: Bluetooth: set quality report callback for Intel |
| |
| This patch sets up set_quality_report callback for Intel to |
| set and reset the debug features. |
| |
| (This CHROMIUM patch will be reverted by an UPSTREAM patch later.) |
| |
| BUG=b:170175384 |
| TEST=On a platform with Intel Belutooth controller, observe the |
| messages in the system logs. |
| when the quality report feature is enabled by a user process: |
| Bluetooth: set_exp_feature() quality report 1 changed 1 |
| Bluetooth: btintel_set_debug_features() hci0: trace_enable 2 mask 127 |
| |
| when the vs debug event is disalbed by a user process: |
| Bluetooth: set_exp_feature() quality report 0 changed 1 |
| Bluetooth: btintel_set_debug_features() hci0: trace_enable 0 mask 0 |
| |
| Change-Id: Icd1d1345b5970d3a2f8da23a10578e051e7e43e4 |
| Signed-off-by: Joseph Hwang <josephsih@chromium.org> |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2949309 |
| Reviewed-by: Yun-Hao Chung <howardchung@chromium.org> |
| --- |
| drivers/bluetooth/btintel.c | 75 ++++++++++++++++++++++++++++++++++++- |
| drivers/bluetooth/btintel.h | 13 +++++++ |
| drivers/bluetooth/btusb.c | 16 ++++++++ |
| 3 files changed, 103 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c |
| --- a/drivers/bluetooth/btintel.c |
| +++ b/drivers/bluetooth/btintel.c |
| @@ -1213,6 +1213,7 @@ void btintel_reset_to_bootloader(struct hci_dev *hdev) |
| } |
| EXPORT_SYMBOL_GPL(btintel_reset_to_bootloader); |
| |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| int btintel_read_debug_features(struct hci_dev *hdev, |
| struct intel_debug_features *features) |
| { |
| @@ -1254,8 +1255,10 @@ int btintel_set_debug_features(struct hci_dev *hdev, |
| u8 trace_enable = 0x02; |
| struct sk_buff *skb; |
| |
| - if (!features) |
| + if (!features) { |
| + bt_dev_warn(hdev, "Debug features not read"); |
| return -EINVAL; |
| + } |
| |
| if (!(features->page1[0] & 0x3f)) { |
| bt_dev_info(hdev, "Telemetry exception format not supported"); |
| @@ -1286,10 +1289,80 @@ int btintel_set_debug_features(struct hci_dev *hdev, |
| } |
| kfree_skb(skb); |
| |
| + bt_dev_info(hdev, "set debug features: trace_enable 0x%02x mask 0x%02x", |
| + trace_enable, mask[3]); |
| + |
| return 0; |
| } |
| EXPORT_SYMBOL_GPL(btintel_set_debug_features); |
| |
| +int btintel_reset_debug_features(struct hci_dev *hdev, |
| + const struct intel_debug_features *features) |
| +{ |
| + u8 mask[11] = { 0x0a, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, |
| + 0x00, 0x00, 0x00 }; |
| + u8 trace_enable = 0x00; |
| + struct sk_buff *skb; |
| + |
| + if (!features) { |
| + bt_dev_warn(hdev, "Debug features not read"); |
| + return -EINVAL; |
| + } |
| + |
| + if (!(features->page1[0] & 0x3f)) { |
| + bt_dev_info(hdev, "Telemetry exception format not supported"); |
| + return 0; |
| + } |
| + |
| + /* Should stop the trace before writing ddc event mask. */ |
| + skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT); |
| + if (IS_ERR(skb)) { |
| + bt_dev_err(hdev, "Stop tracing of link statistics events failed (%ld)", |
| + PTR_ERR(skb)); |
| + return PTR_ERR(skb); |
| + } |
| + kfree_skb(skb); |
| + |
| + skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT); |
| + if (IS_ERR(skb)) { |
| + bt_dev_err(hdev, "Setting Intel telemetry ddc write event mask failed (%ld)", |
| + PTR_ERR(skb)); |
| + return PTR_ERR(skb); |
| + } |
| + kfree_skb(skb); |
| + |
| + bt_dev_info(hdev, "reset debug features: trace_enable 0x%02x mask 0x%02x", |
| + trace_enable, mask[3]); |
| + |
| + return 0; |
| +} |
| +EXPORT_SYMBOL_GPL(btintel_reset_debug_features); |
| + |
| +int btintel_set_quality_report(struct hci_dev *hdev, bool enable) |
| +{ |
| + struct intel_debug_features features; |
| + int err; |
| + |
| + bt_dev_dbg(hdev, "enable %d", enable); |
| + |
| + /* Read the Intel supported features and if new exception formats |
| + * supported, need to load the additional DDC config to enable. |
| + */ |
| + err = btintel_read_debug_features(hdev, &features); |
| + if (err) |
| + return err; |
| + |
| + /* Set or reset the debug features. */ |
| + if (enable) |
| + err = btintel_set_debug_features(hdev, &features); |
| + else |
| + err = btintel_reset_debug_features(hdev, &features); |
| + |
| + return err; |
| +} |
| +EXPORT_SYMBOL_GPL(btintel_set_quality_report); |
| +#endif |
| + |
| MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
| MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION); |
| MODULE_VERSION(VERSION); |
| diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h |
| --- a/drivers/bluetooth/btintel.h |
| +++ b/drivers/bluetooth/btintel.h |
| @@ -171,10 +171,15 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev, |
| u32 *boot_param, u8 hw_variant, |
| u8 sbe_type); |
| void btintel_reset_to_bootloader(struct hci_dev *hdev); |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| int btintel_read_debug_features(struct hci_dev *hdev, |
| struct intel_debug_features *features); |
| int btintel_set_debug_features(struct hci_dev *hdev, |
| const struct intel_debug_features *features); |
| +int btintel_reset_debug_features(struct hci_dev *hdev, |
| + const struct intel_debug_features *features); |
| +int btintel_set_quality_report(struct hci_dev *hdev, bool enable); |
| +#endif |
| #else |
| |
| static inline int btintel_check_bdaddr(struct hci_dev *hdev) |
| @@ -301,10 +306,18 @@ static inline int btintel_read_debug_features(struct hci_dev *hdev, |
| return -EOPNOTSUPP; |
| } |
| |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| static inline int btintel_set_debug_features(struct hci_dev *hdev, |
| const struct intel_debug_features *features) |
| { |
| return -EOPNOTSUPP; |
| } |
| |
| +static inline int btintel_reset_debug_features(struct hci_dev *hdev, |
| + const struct intel_debug_features *features) |
| +{ |
| + return -EOPNOTSUPP; |
| +} |
| +#endif |
| + |
| #endif |
| diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c |
| --- a/drivers/bluetooth/btusb.c |
| +++ b/drivers/bluetooth/btusb.c |
| @@ -2937,6 +2937,11 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) |
| btintel_load_ddc_config(hdev, ddcname); |
| } |
| |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| + hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); |
| + bt_dev_dbg(hdev, "HCI_QUALITY_REPORT cleared"); |
| +#endif |
| + |
| /* Read the Intel version information after loading the FW */ |
| err = btintel_read_version(hdev, &ver); |
| if (err) |
| @@ -3024,6 +3029,11 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev) |
| */ |
| btintel_load_ddc_config(hdev, ddcname); |
| |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| + hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); |
| + bt_dev_dbg(hdev, "HCI_QUALITY_REPORT cleared"); |
| +#endif |
| + |
| /* Read the Intel version information after loading the FW */ |
| err = btintel_read_version_tlv(hdev, &version); |
| if (err) |
| @@ -4685,6 +4695,9 @@ static int btusb_probe(struct usb_interface *intf, |
| hdev->set_diag = btintel_set_diag; |
| hdev->set_bdaddr = btintel_set_bdaddr; |
| hdev->cmd_timeout = btusb_intel_cmd_timeout; |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| + hdev->set_quality_report = btintel_set_quality_report; |
| +#endif |
| 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); |
| @@ -4699,6 +4712,9 @@ static int btusb_probe(struct usb_interface *intf, |
| hdev->set_diag = btintel_set_diag; |
| hdev->set_bdaddr = btintel_set_bdaddr; |
| hdev->cmd_timeout = btusb_intel_cmd_timeout; |
| +#ifdef CONFIG_BT_FEATURE_QUALITY_REPORT |
| + hdev->set_quality_report = btintel_set_quality_report; |
| +#endif |
| 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); |
| -- |
| 2.33.0.rc2.250.ged5fa647cd-goog |
| |