Fix unexpected SMP 0x08 and 0x09 command errors when connecting and pairing devices using ATS2851 based controllers. The errors are a result of a race condition in which the host receives the commands (without prior authorization by SMP functions) in the moment host is sending WRITE_AUTH_PAYLOAD_TIMEOUT command. In such a situation, a disconnect event occurs, and the device cannot connect or pair. To address this issue, we add a condition that skips the WRITE_AUTH_PAYLOAD_TIMEOUT command for ATS2851, enabling the SMP functions to prepare for commands 0x08 and 0x09 in a timely manner. Signed-off-by: Raul Cheleguini <raul.cheleguini@xxxxxxxxx> --- V1 -> V2: Fix typo in commit message. - Note that this patch depends on the broken extended create connection quirk sent in [1]. [1]. https://marc.info/?l=linux-bluetooth&m=168244024503639&w=2 drivers/bluetooth/btusb.c | 1 + include/net/bluetooth/hci.h | 7 +++++++ net/bluetooth/hci_event.c | 7 +++++++ net/bluetooth/hci_sync.c | 5 ++++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1cf104feaf85..972ca94de6de 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -4374,6 +4374,7 @@ static int btusb_probe(struct usb_interface *intf, set_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, &hdev->quirks); + set_bit(HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT, &hdev->quirks); } if (!reset) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index d5d0e44bf0b6..625c100a74ad 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -316,6 +316,13 @@ enum { * based controllers, which erroneously claims to support it. */ HCI_QUIRK_BROKEN_EXT_CREATE_CONN, + + /* + * When this quirk is set, the command WRITE_AUTH_PAYLOAD_TIMEOUT is + * skipped. This is required for the Actions Semiconductor ATS2851 + * based controllers, due to a race condition in pairing process. + */ + HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT, }; /* HCI device flags */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d00ef6e3fc45..2077a7c921f1 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3655,6 +3655,13 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data, goto unlock; } + /* We skip the WRITE_AUTH_PAYLOAD_TIMEOUT for ATS2851 based controllers + * to avoid unexpected SMP command errors when pairing. + */ + if (test_bit(HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT, + &hdev->quirks)) + goto notify; + /* Set the default Authenticated Payload Timeout after * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 26ab4deb6d52..ecd18c611122 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -4581,7 +4581,10 @@ static const struct { "advertised, but not supported."), HCI_QUIRK_BROKEN(EXT_CREATE_CONN, "HCI LE Extended Create Connection command is " - "advertised, but not supported.") + "advertised, but not supported."), + HCI_QUIRK_BROKEN(WRITE_AUTH_PAYLOAD_TIMEOUT, + "HCI WRITE AUTH PAYLOAD TIMEOUT command leads " + "to unexpected SMP errors when pairing.") }; /* This function handles hdev setup stage: -- 2.39.2