From be587c070716d820eceee2377f966874ae51eb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Thu, 2 Dec 2021 13:54:10 -0300 Subject: [PATCH] linux5.15: add patch to fix bluetooth dongle The patch is taken verbatim from this particular comment: https://gist.github.com/nevack/6b36b82d715dc025163d9e9124840a07#gistcomment-3818325 Note that there are several fake variants of this CSR dongle (usb id 0a12:0001) that need different workarounds. The gist itself mentions a workaround (force-suspend) that is already included in 5.15 and fixes some dongles but not mine. The issue is also mentioned in kernel bugzilla at https://bugzilla.kernel.org/show_bug.cgi?id=60824#c187 Starting at comment 187 there are several reports of dongles fixed by that patch (or a variation / rediscovery of the workaround). --- .../btusb-quirk-HCI_FLT_CLEAR_ALL.patch | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 srcpkgs/linux5.15/patches/btusb-quirk-HCI_FLT_CLEAR_ALL.patch diff --git a/srcpkgs/linux5.15/patches/btusb-quirk-HCI_FLT_CLEAR_ALL.patch b/srcpkgs/linux5.15/patches/btusb-quirk-HCI_FLT_CLEAR_ALL.patch new file mode 100644 index 00000000000000..5c04e5158217de --- /dev/null +++ b/srcpkgs/linux5.15/patches/btusb-quirk-HCI_FLT_CLEAR_ALL.patch @@ -0,0 +1,96 @@ +From 4d5b0262d30dd6227d9bef96c2a2259bf1162350 Mon Sep 17 00:00:00 2001 +From: Ismael Ferreras Morezuelas +Date: Mon, 19 Jul 2021 12:39:11 +0200 +Subject: [PATCH] Bluetooth: Add a new quirk to skip HCI_FLT_CLEAR_ALL + +Signed-off-by: Ismael Ferreras Morezuelas +--- + drivers/bluetooth/btusb.c | 1 + + include/net/bluetooth/hci.h | 6 ++++++ + net/bluetooth/hci_core.c | 12 +++++++++--- + net/bluetooth/hci_request.c | 8 ++++++-- + 4 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 197cafe75..8fa07f9e3 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -1899,6 +1899,7 @@ static int btusb_setup_csr(struct hci_dev *hdev) + */ + set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks); + set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks); ++ set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks); + + /* Clear the reset quirk since this is not an actual + * early Bluetooth 1.1 device from CSR. +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index b80415011..a12178387 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -246,6 +246,12 @@ enum { + * HCI after resume. + */ + HCI_QUIRK_NO_SUSPEND_NOTIFIER, ++ ++ /* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with ++ * HCI_FLT_CLEAR_ALL are ignored. A subset of the CSR controller ++ * clones struggle with this and instantly lock up. ++ */ ++ HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, + }; + + /* HCI device flags */ +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 2560ed2f1..7ed355c3e 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -273,6 +273,7 @@ static void bredr_setup(struct hci_request *req) + { + __le16 param; + __u8 flt_type; ++ struct hci_dev *hdev = req->hdev; + + /* Read Buffer Size (ACL mtu, max pkt, etc.) */ + hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); +@@ -292,9 +293,14 @@ static void bredr_setup(struct hci_request *req) + /* Read Current IAC LAP */ + hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); + +- /* Clear Event Filters */ +- flt_type = HCI_FLT_CLEAR_ALL; +- hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); ++ /* Clear Event Filters; some fake CSR controllers lock up after setting ++ * this type of filter, so avoid sending the request altogether. ++ */ ++ if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) ++ { ++ flt_type = HCI_FLT_CLEAR_ALL; ++ hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); ++ } + + /* Connection accept timeout ~20 secs */ + param = cpu_to_le16(0x7d00); +diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c +index 1d14adc02..90a88539b 100644 +--- a/net/bluetooth/hci_request.c ++++ b/net/bluetooth/hci_request.c +@@ -1156,11 +1156,15 @@ static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance) + static void hci_req_clear_event_filter(struct hci_request *req) + { + struct hci_cp_set_event_filter f; ++ struct hci_dev *hdev = req->hdev; ++ ++ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) ++ return; + +- if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED)) ++ if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) + return; + +- if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) { ++ if (hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) { + memset(&f, 0, sizeof(f)); + f.flt_type = HCI_FLT_CLEAR_ALL; + hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f); +-- +2.32.0