Skip to content

Commit 0eaecfb

Browse files
Swyterholtmann
authored andcommitted
Bluetooth: hci_sync: Add a new quirk to skip HCI_FLT_CLEAR_ALL
Some controllers have problems with being sent a command to clear all filtering. While the HCI code does not unconditionally send a clear-all anymore at BR/EDR setup (after the state machine refactor), there might be more ways of hitting these codepaths in the future as the kernel develops. Cc: [email protected] Cc: Hans de Goede <[email protected]> Signed-off-by: Ismael Ferreras Morezuelas <[email protected]> Reviewed-by: Hans de Goede <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 6ac034a commit 0eaecfb

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

include/net/bluetooth/hci.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,16 @@ enum {
255255
* during the hdev->setup vendor callback.
256256
*/
257257
HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
258+
259+
/* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with
260+
* HCI_FLT_CLEAR_ALL are ignored and event filtering is
261+
* completely avoided. A subset of the CSR controller
262+
* clones struggle with this and instantly lock up.
263+
*
264+
* Note that devices using this must (separately) disable
265+
* runtime suspend, because event filtering takes place there.
266+
*/
267+
HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
258268
};
259269

260270
/* HCI device flags */

net/bluetooth/hci_sync.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,9 @@ static int hci_set_event_filter_sync(struct hci_dev *hdev, u8 flt_type,
28092809
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
28102810
return 0;
28112811

2812+
if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
2813+
return 0;
2814+
28122815
memset(&cp, 0, sizeof(cp));
28132816
cp.flt_type = flt_type;
28142817

@@ -2829,6 +2832,13 @@ static int hci_clear_event_filter_sync(struct hci_dev *hdev)
28292832
if (!hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED))
28302833
return 0;
28312834

2835+
/* In theory the state machine should not reach here unless
2836+
* a hci_set_event_filter_sync() call succeeds, but we do
2837+
* the check both for parity and as a future reminder.
2838+
*/
2839+
if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
2840+
return 0;
2841+
28322842
return hci_set_event_filter_sync(hdev, HCI_FLT_CLEAR_ALL, 0x00,
28332843
BDADDR_ANY, 0x00);
28342844
}
@@ -4828,6 +4838,12 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)
48284838
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
48294839
return 0;
48304840

4841+
/* Some fake CSR controllers lock up after setting this type of
4842+
* filter, so avoid sending the request altogether.
4843+
*/
4844+
if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
4845+
return 0;
4846+
48314847
/* Always clear event filter when starting */
48324848
hci_clear_event_filter_sync(hdev);
48334849

0 commit comments

Comments
 (0)