diff mbox series

Bluetooth: btqcomsmd: Fix command timeout after setting BD address

Message ID 20220613110745.3778356-1-stephan.gerhold@kernkonzept.com
State Superseded
Headers show
Series Bluetooth: btqcomsmd: Fix command timeout after setting BD address | expand

Commit Message

Stephan Gerhold June 13, 2022, 11:07 a.m. UTC
The Bluetooth firmware seems to become unresponsive for a while after
setting the BD address. At least on recent kernel versions this often
causes timeouts for subsequent commands, e.g. the HCI reset sent by
the Bluetooth core during initialization:

	Bluetooth: hci0: Opcode 0x c03 failed: -110

Unfortunately this behavior does not seem to be documented anywhere.
Experimentation suggests that the minimum necessary delay to avoid
the problem is ~150us. However, to be sure add a sleep for > 1ms
in case it is a bit longer on other firmware versions.

Fixes: 1511cc750c3d ("Bluetooth: Introduce Qualcomm WCNSS SMD based HCI driver")
Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
---
I tested this using a script that reboots repeatedly and checks for the
error. With this patch, BT shows up successfully for 100+ consecutive
boots. Without this patch it usually fails after 1-5 boots (or even
always on some boards).
---
 drivers/bluetooth/btqcomsmd.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

Comments

bluez.test.bot@gmail.com June 13, 2022, 4:14 p.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=649852

---Test result---

Test Summary:
CheckPatch                    PASS      1.62 seconds
GitLint                       FAIL      1.00 seconds
SubjectPrefix                 PASS      0.92 seconds
BuildKernel                   PASS      32.35 seconds
BuildKernel32                 PASS      28.92 seconds
Incremental Build with patchesPASS      39.04 seconds
TestRunner: Setup             PASS      476.76 seconds
TestRunner: l2cap-tester      PASS      17.37 seconds
TestRunner: bnep-tester       PASS      6.07 seconds
TestRunner: mgmt-tester       FAIL      105.82 seconds
TestRunner: rfcomm-tester     PASS      9.67 seconds
TestRunner: sco-tester        PASS      9.39 seconds
TestRunner: smp-tester        PASS      9.40 seconds
TestRunner: userchan-tester   PASS      6.37 seconds

Details
##############################
Test: GitLint - FAIL - 1.00 seconds
Run gitlint with rule in .gitlint
Bluetooth: btqcomsmd: Fix command timeout after setting BD address
8: B3 Line contains hard tab characters (\t): "	Bluetooth: hci0: Opcode 0x c03 failed: -110"


##############################
Test: TestRunner: mgmt-tester - FAIL - 105.82 seconds
Run test-runner with mgmt-tester
Total: 493, Passed: 491 (99.6%), Failed: 2, Not Run: 0

Failed Test Cases
Add Advertising - Success (Name+data+appear)         Timed out    2.630 seconds
Add Ext Advertising - Success (Name+data+appear)     Timed out    2.489 seconds



---
Regards,
Linux Bluetooth
Stephan Gerhold June 14, 2022, 8:02 a.m. UTC | #2
Hi Paul,

On Mon, Jun 13, 2022 at 06:09:33PM +0200, Paul Menzel wrote:
> Am 13.06.22 um 13:07 schrieb Stephan Gerhold:
> > The Bluetooth firmware seems to become unresponsive for a while after
> 
> Please mention the device with the problematic firmware.
> 

Will add a comment in v2. It seems to affect pretty much all devices
that make use of the "btqcomsmd" driver.

> > setting the BD address. At least on recent kernel versions this often
> 
> The commit referenced in the Fixes tag is in Linux 4.9. Can you please name
> the oldest Linux kernel version you experienced the problem with.
> 

This is quite hard to say. It definitely became more apparent in the
last few months (so at least 5.17+). But since it's a timing problem
it's influenced by various side effects. For example, it is less likely
to happen the more hardware functionality you enable on a board (because
other interrupts come in and might cause the necessary delay).

I believe that the problem also exists in some form on Linux 4.9,
even though it might be harder to trigger it there.

Thanks,
Stephan
diff mbox series

Patch

diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
index 2acb719e596f..11c7e04bf394 100644
--- a/drivers/bluetooth/btqcomsmd.c
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -122,6 +122,21 @@  static int btqcomsmd_setup(struct hci_dev *hdev)
 	return 0;
 }
 
+static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	int ret;
+
+	ret = qca_set_bdaddr_rome(hdev, bdaddr);
+	if (ret)
+		return ret;
+
+	/* The firmware stops responding for a while after setting the bdaddr,
+	 * causing timeouts for subsequent commands. Sleep a bit to avoid this.
+	 */
+	usleep_range(1000, 10000);
+	return 0;
+}
+
 static int btqcomsmd_probe(struct platform_device *pdev)
 {
 	struct btqcomsmd *btq;
@@ -162,7 +177,7 @@  static int btqcomsmd_probe(struct platform_device *pdev)
 	hdev->close = btqcomsmd_close;
 	hdev->send = btqcomsmd_send;
 	hdev->setup = btqcomsmd_setup;
-	hdev->set_bdaddr = qca_set_bdaddr_rome;
+	hdev->set_bdaddr = btqcomsmd_set_bdaddr;
 
 	ret = hci_register_dev(hdev);
 	if (ret < 0)