Message ID | 20210812171533.v7.3.I50ffa4cd0b3ab11669ff2541fc719fee00b4e244@changeid (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v7,1/4] Bluetooth: btusb: disable Intel link statistics telemetry events | expand |
Hi Joseph, On Thu, Aug 12, 2021 at 2:16 AM Joseph Hwang <josephsih@chromium.org> wrote: > > 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> > --- > > Changes in v7: > - Rebase on Tedd's patches that moved functionality from btusb to > btintel. > > Changes in v5: > - Removed CONFIG_BT_FEATURE_QUALITY_REPORT since there was no > large size impact. > > drivers/bluetooth/btintel.c | 81 ++++++++++++++++++++++++++++++++++++- > drivers/bluetooth/btintel.h | 6 +++ > 2 files changed, 86 insertions(+), 1 deletion(-) > > diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c > index 643e2194ca01..611c3ea5425f 100644 > --- 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,9 @@ static int btintel_bootloader_setup(struct hci_dev *hdev, > btintel_load_ddc_config(hdev, ddcname); > } > > + hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); > + bt_dev_dbg(hdev, "HCI_QUALITY_REPORT cleared"); I would remove such debugs since I don't think they have any value here, besides it doesn't seem HCI_QUALITY_REPORT is ever set anyway which perhaps should be done by the core itself after calling the callback. > /* Read the Intel version information after loading the FW */ > err = btintel_read_version(hdev, &new_ver); > if (err) > @@ -2132,6 +2205,9 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, > */ > btintel_load_ddc_config(hdev, ddcname); > > + hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); > + bt_dev_dbg(hdev, "HCI_QUALITY_REPORT cleared"); Ditto. > /* Read the Intel version information after loading the FW */ > err = btintel_read_version_tlv(hdev, &new_ver); > if (err) > @@ -2230,6 +2306,9 @@ static int btintel_setup_combined(struct hci_dev *hdev) > set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); > set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); > > + /* Set up the quality report callback for Intel devices */ > + hdev->set_quality_report = btintel_set_quality_report; > + > /* For Legacy device, check the HW platform value and size */ > if (skb->len == sizeof(ver) && skb->data[1] == 0x37) { > bt_dev_dbg(hdev, "Read the legacy Intel version information"); > diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h > index aa64072bbe68..fe02cb9ac96c 100644 > --- 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 > -- > 2.32.0.605.g8dce9f2422-goog >
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 643e2194ca01..611c3ea5425f 100644 --- 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,9 @@ static int btintel_bootloader_setup(struct hci_dev *hdev, btintel_load_ddc_config(hdev, ddcname); } + hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); + bt_dev_dbg(hdev, "HCI_QUALITY_REPORT cleared"); + /* Read the Intel version information after loading the FW */ err = btintel_read_version(hdev, &new_ver); if (err) @@ -2132,6 +2205,9 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, */ btintel_load_ddc_config(hdev, ddcname); + hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); + bt_dev_dbg(hdev, "HCI_QUALITY_REPORT cleared"); + /* Read the Intel version information after loading the FW */ err = btintel_read_version_tlv(hdev, &new_ver); if (err) @@ -2230,6 +2306,9 @@ static int btintel_setup_combined(struct hci_dev *hdev) set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); + /* Set up the quality report callback for Intel devices */ + hdev->set_quality_report = btintel_set_quality_report; + /* For Legacy device, check the HW platform value and size */ if (skb->len == sizeof(ver) && skb->data[1] == 0x37) { bt_dev_dbg(hdev, "Read the legacy Intel version information"); diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index aa64072bbe68..fe02cb9ac96c 100644 --- 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