| From 717a2560ed519116293631e52d432245239b0c8e Mon Sep 17 00:00:00 2001 |
| From: Joseph Hwang <josephsih@chromium.org> |
| Date: Sun, 15 Aug 2021 20:17:17 +0800 |
| Subject: [PATCH] BACKPORT: FROMGIT: Bluetooth: set quality report callback for |
| Intel |
| |
| This patch sets up set_quality_report callback for Intel to |
| set and reset the debug features. |
| |
| Reviewed-by: Miao-chen Chou <mcchou@chromium.org> |
| Signed-off-by: Joseph Hwang <josephsih@chromium.org> |
| Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
| |
| (cherry picked from commit 927ac8da35db763fe22d338614777120fcfade70 |
| git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master) |
| |
| Conflicts: |
| drivers/bluetooth/btintel.c |
| drivers/bluetooth/btintel.h |
| drivers/bluetooth/btusb.c |
| |
| BUG=b:170175384 |
| TEST=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 quality report feature 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: I3703220a768ed7b164fe05ce4d3dac18a639649e |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3135125 |
| Reviewed-by: Miao-chen Chou <mcchou@chromium.org> |
| Commit-Queue: Michael Sun <michaelfsun@google.com> |
| Commit-Queue: Shyh-In Hwang <josephsih@chromium.org> |
| Tested-by: Shyh-In Hwang <josephsih@chromium.org> |
| --- |
| drivers/bluetooth/btintel.c | 76 ++++++++++++++++++++++++++++++++++++- |
| drivers/bluetooth/btintel.h | 6 +++ |
| drivers/bluetooth/btusb.c | 3 ++ |
| 3 files changed, 84 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 |
| @@ -1291,8 +1291,10 @@ static 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"); |
| @@ -1323,9 +1325,77 @@ static 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; |
| +} |
| + |
| +static 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; |
| } |
| |
| +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); |
| + |
| static const struct firmware *btintel_legacy_rom_get_fw(struct hci_dev *hdev, |
| struct intel_version *ver) |
| { |
| @@ -1951,6 +2021,8 @@ static int btintel_bootloader_setup(struct hci_dev *hdev, |
| btintel_load_ddc_config(hdev, ddcname); |
| } |
| |
| + btintel_clear_flag(hdev, HCI_QUALITY_REPORT); |
| + |
| /* Read the Intel version information after loading the FW */ |
| err = btintel_read_version(hdev, &new_ver); |
| if (err) |
| @@ -2132,6 +2204,8 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, |
| */ |
| btintel_load_ddc_config(hdev, ddcname); |
| |
| + btintel_clear_flag(hdev, HCI_QUALITY_REPORT); |
| + |
| /* Read the Intel version information after loading the FW */ |
| err = btintel_read_version_tlv(hdev, &new_ver); |
| if (err) |
| diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h |
| --- a/drivers/bluetooth/btintel.h |
| +++ b/drivers/bluetooth/btintel.h |
| @@ -204,6 +204,7 @@ int btintel_configure_setup(struct hci_dev *hdev); |
| void btintel_bootup(struct hci_dev *hdev, const void *ptr, unsigned int len); |
| void btintel_secure_send_result(struct hci_dev *hdev, |
| const void *ptr, unsigned int len); |
| +int btintel_set_quality_report(struct hci_dev *hdev, bool enable); |
| #else |
| |
| static inline int btintel_check_bdaddr(struct hci_dev *hdev) |
| @@ -294,4 +295,9 @@ static inline void btintel_secure_send_result(struct hci_dev *hdev, |
| const void *ptr, unsigned int len) |
| { |
| } |
| + |
| +static inline int btintel_set_quality_report(struct hci_dev *hdev, bool enable) |
| +{ |
| + return -ENODEV; |
| +} |
| #endif |
| diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c |
| --- a/drivers/bluetooth/btusb.c |
| +++ b/drivers/bluetooth/btusb.c |
| @@ -3870,6 +3870,9 @@ static int btusb_probe(struct usb_interface *intf, |
| hdev->send = btusb_send_frame_intel; |
| hdev->cmd_timeout = btusb_intel_cmd_timeout; |
| |
| + /* Set up the quality report callback for Intel devices */ |
| + hdev->set_quality_report = btintel_set_quality_report; |
| + |
| if (id->driver_info & BTUSB_INTEL_BROKEN_INITIAL_NCMD) |
| btintel_set_flag(hdev, INTEL_BROKEN_INITIAL_NCMD); |
| } |
| -- |
| 2.33.0.464.g1972c5931b-goog |
| |