Re: [PATCH v1 1/2] Bluetooth: btnxpuart: Add msleep() after changing the baudrate

From: Neeraj Sanjay Kale
Date: Fri Mar 28 2025 - 15:09:23 EST


Hi Paul,

Thank you for reviewing the patch.

>
> Dear Neeraj,
>
>
> Thank you for your patch. For the summary/title, I suggest:
>
> Sleep 100 ms after baud rate change
I will update this in V2 patch.

>
> Am 27.03.25 um 19:25 schrieb Neeraj Sanjay Kale:
> > This adds a 100 millisec sleep after change baudrate vendor command.
> >
> > It is observed that when the baudrate change command changes the
> > baudrate from 3000000 to 115200, any immediate HCI command returns an
> > error -22 (Device Busy).
Correction. It returns error -110 (Command Timeout)

>
> Really 3 million?
NXP chips mainly use these 2 baudrates:
#define HCI_NXP_PRI_BAUDRATE 115200
#define HCI_NXP_SEC_BAUDRATE 3000000

>
> Is this happening with every change, or only decreasing the baud rate with
> the values you listed?

Let me share some background first:
After FW download, the FW initializes at 115200 baudrate.

Initial implementation of BTNXPUART changed the baudrate from 115200 to 3000000 in nxp_setup() after modprobe.
During rmmod, driver reverted the baudrate back to 115200.

However, since after modprobe hci0 is DOWN, the change baudrate command failed during rmmod.
It succeeded if hci0 is already UP and RUNNING, thus next modprobe command would also succeed.

This logic made sure BTNXPUART and controller are in sync even if FW is already present in the controller, but rmmod when hci0 is down failed, leaving the controller running at 3000000 baudrate. In next iteration modprobe command would eventually fail.

This problem was fixed in:
https://github.com/bluez/bluetooth-next/commit/6fca6781d19dfadbc3d96b3c10daf1f2e1239092 (Merged)
Which had a change in nxp_shutdown() function picked up from:
https://patchwork.kernel.org/project/bluetooth/patch/20250226151340.1017790-1-loic.poulain@xxxxxxxxxx/ (Not merged, dropped)

With this change, the driver changed the baudrate from 115200 to 3000000 on modprobe in nxp_post_init().

After the initialization, when hci0 became DOWN, nxp_shutdown() changed the baudrate back to 115200.

Later, when hci0 becomes UP, nxp_post_init() changed it back to 3000000. It fixed the rmmod problem when hci0 is DOWN.

However, this logic introduced a new issue with "hciconfig hci0 reset" command, which makes hci0 DOWN and UP immediately.

So,
1) modprobe btnxpuart (FW download, change baudrate from 115200 to 3000000)
2) After HCI init done, hci0 interface is down (Baudrate switches back to 115200)
3) hciconfig hci0 up (Baudrate switches back to 3000000)
4) hciconfig hci0 reset (hci0 down sets baudrate to 115200, first reset command in hci0 UP times out)

On Logic Analyzer, we see 3 millisec gap between the *change baudrate command complete event* from controller, and *HCI_RESET* command from host at 115200 baudrate.
This HCI_RESET command is missed by the controller as it is not completely switched to 115200 baudrate.

This is a completely new scenario, which never occurred before above-mentioned commit was merged.
With some trial and error, I was able to get the hciconfig reset command working if the gap between *change baudrate command complete event* and first *HCI_RESET* command was increased to 50 millisec.

The reason for choosing 100 millisec was to provide sufficient buffer time. Now that I'm thinking, yes it seems reasonably high.
And yes, the chip should not take such a long time to change baudrate.

Also, this issue is not observed with "hciconfig hci0 up" or "bluetoothctl power on" commands.

>
> > Adding a small delay after the change baudrate command complete event
> > is received helps fix the issue.
>
> 100 ms is not small to me. Is this issue documented in the hardware
> documentation? Are there other ways like polling, if the command
> succeeded?
I could not find such a reference but looks like this issue is specific to *hciconfig hci0 reset* command only.
Today I ran these 2 commands in a loop without delay, and did not see any timeout errors:
1) hcitool -i hci0 cmd 3f 09 00 c2 01 00 // where 0x00012c00 => 115200
2) hcitool -i hci0 cmd 3f 09 c0 c6 2d 00 // where 0x002dc6c0 => 3000000

Although hciconfig and hcitool commands are deprecated, we'd want these commands to work fine.

Thank you for bearing with my extensive response. Any alternatives/suggestion are welcome.

Regards,
Neeraj