public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump
@ 2025-07-03 13:05 Neeraj Sanjay Kale
  2025-07-03 13:05 ` [PATCH v1 2/2] Bluetooth: btnxpuart: Add uevents for FW dump and FW download complete Neeraj Sanjay Kale
  2025-07-03 14:08 ` [v1,1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump bluez.test.bot
  0 siblings, 2 replies; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2025-07-03 13:05 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, amitkumar.karwar,
	neeraj.sanjaykale, sherry.sun, manjeet.gupta, jean-yves.salaun

This adds proper handling for the independent reset command sent by the
driver after FW dump is complete.

In normal scenario, the independent reset vendor command gives a success
response before jumping to bootcode.

However, when FW goes in a bad state, and sends out FW dump packets, the
independent reset command does not get any response from the controller.

[  159.807732] Bluetooth: hci0: ==== Start FW dump ===
[  180.759060] Bluetooth: hci0: ==== FW dump complete ===
[  182.779208] Bluetooth: hci0: command 0xfcfc tx timeout
[  183.364974] Bluetooth: hci0: ChipID: 7601, Version: 0
[  183.368490] Bluetooth: hci0: Request Firmware: nxp/uartspi_n61x_v1.bin.se
[  184.679977] Bluetooth: hci0: FW Download Complete: 417064 bytes
[  187.963102] Bluetooth: hci0: Opcode 0x0c03 failed: -110

As a fix for such scenario, the independent reset vendor command is sent
using the __hci_cmd_send() API, which does not expect any response for
vendor commands.

__hci_cmd_send is non blocking, so before the tx_work is scheduled, it
sometimes gets canceled and 3F|FC command is never sent. Adding a small
delay after __hci_cmd_send allows the command to be sent to the
controller.

Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Tested-by: Jean-Yves Salaün <jean-yves.salaun@nxp.com>
---
 drivers/bluetooth/btnxpuart.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index c56b52bd8d98..f40794be2d89 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -367,17 +367,26 @@ static u8 crc8_table[CRC8_TABLE_SIZE];
 
 static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode,
 					u32 plen,
-					void *param)
+					void *param,
+					bool resp)
 {
 	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
 	struct ps_data *psdata = &nxpdev->psdata;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
 
 	/* set flag to prevent nxp_enqueue from parsing values from this command and
 	 * calling hci_cmd_sync_queue() again.
 	 */
 	psdata->driver_sent_cmd = true;
-	skb = __hci_cmd_sync(hdev, opcode, plen, param, HCI_CMD_TIMEOUT);
+	if (resp) {
+		skb = __hci_cmd_sync(hdev, opcode, plen, param, HCI_CMD_TIMEOUT);
+	} else {
+		__hci_cmd_send(hdev, opcode, plen, param);
+		/* Allow command to be sent before tx_work is cancelled
+		 * by btnxpuart_flush()
+		 */
+		msleep(20);
+	}
 	psdata->driver_sent_cmd = false;
 
 	return skb;
@@ -597,7 +606,7 @@ static int send_ps_cmd(struct hci_dev *hdev, void *data)
 		pcmd.ps_cmd = BT_PS_DISABLE;
 	pcmd.c2h_ps_interval = __cpu_to_le16(psdata->c2h_ps_interval);
 
-	skb = nxp_drv_send_cmd(hdev, HCI_NXP_AUTO_SLEEP_MODE, sizeof(pcmd), &pcmd);
+	skb = nxp_drv_send_cmd(hdev, HCI_NXP_AUTO_SLEEP_MODE, sizeof(pcmd), &pcmd, true);
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Setting Power Save mode failed (%ld)", PTR_ERR(skb));
 		return PTR_ERR(skb);
@@ -646,7 +655,7 @@ static int send_wakeup_method_cmd(struct hci_dev *hdev, void *data)
 		break;
 	}
 
-	skb = nxp_drv_send_cmd(hdev, HCI_NXP_WAKEUP_METHOD, sizeof(pcmd), &pcmd);
+	skb = nxp_drv_send_cmd(hdev, HCI_NXP_WAKEUP_METHOD, sizeof(pcmd), &pcmd, true);
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Setting wake-up method failed (%ld)", PTR_ERR(skb));
 		return PTR_ERR(skb);
@@ -1272,7 +1281,7 @@ static int nxp_set_baudrate_cmd(struct hci_dev *hdev, void *data)
 	if (!psdata)
 		return 0;
 
-	skb = nxp_drv_send_cmd(hdev, HCI_NXP_SET_OPER_SPEED, 4, (u8 *)&new_baudrate);
+	skb = nxp_drv_send_cmd(hdev, HCI_NXP_SET_OPER_SPEED, 4, (u8 *)&new_baudrate, true);
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Setting baudrate failed (%ld)", PTR_ERR(skb));
 		return PTR_ERR(skb);
@@ -1330,7 +1339,7 @@ static void nxp_coredump(struct hci_dev *hdev)
 	struct sk_buff *skb;
 	u8 pcmd = 2;
 
-	skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd);
+	skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd, true);
 	if (IS_ERR(skb))
 		bt_dev_err(hdev, "Failed to trigger FW Dump. (%ld)", PTR_ERR(skb));
 	else
@@ -1372,7 +1381,6 @@ static int nxp_process_fw_dump(struct hci_dev *hdev, struct sk_buff *skb)
 
 	if (buf_len == 0) {
 		bt_dev_warn(hdev, "==== FW dump complete ===");
-		clear_bit(BTNXPUART_FW_DUMP_IN_PROGRESS, &nxpdev->tx_state);
 		hci_devcd_complete(hdev);
 		nxp_set_ind_reset(hdev, NULL);
 	}
@@ -1486,7 +1494,13 @@ static int nxp_shutdown(struct hci_dev *hdev)
 	u8 pcmd = 0;
 
 	if (ind_reset_in_progress(nxpdev)) {
-		skb = nxp_drv_send_cmd(hdev, HCI_NXP_IND_RESET, 1, &pcmd);
+		if (test_and_clear_bit(BTNXPUART_FW_DUMP_IN_PROGRESS,
+				       &nxpdev->tx_state))
+			skb = nxp_drv_send_cmd(hdev, HCI_NXP_IND_RESET, 1,
+					       &pcmd, false);
+		else
+			skb = nxp_drv_send_cmd(hdev, HCI_NXP_IND_RESET, 1,
+					       &pcmd, true);
 		serdev_device_set_flow_control(nxpdev->serdev, false);
 		set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
 		/* HCI_NXP_IND_RESET command may not returns any response */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v1 2/2] Bluetooth: btnxpuart: Add uevents for FW dump and FW download complete
  2025-07-03 13:05 [PATCH v1 1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump Neeraj Sanjay Kale
@ 2025-07-03 13:05 ` Neeraj Sanjay Kale
  2025-07-03 14:08 ` [v1,1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump bluez.test.bot
  1 sibling, 0 replies; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2025-07-03 13:05 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, amitkumar.karwar,
	neeraj.sanjaykale, sherry.sun, manjeet.gupta, jean-yves.salaun

This adds uevents which will be generated whenever FW dump is triggered,
FW dump is complete and FW (re)download is done.

This feature is needed for IW612 chipset, which is a tri-radio chipset,
where WLAN runs on CPU1 and BT and Zigbee runs on CPU2.

Currently, whenever BT FW crashes, and FW dump is in progress, there is
no way for 15.4 application to know that CPU2 is in bad state, and when
it will be recovered.

With the help of these uevents and udev rules, the 15.4 app, or any
userspace application can be alerted whenever CPU2 goes in bad state and
recoveres after BTNXPUART reloads the firmware.

[  334.255154] Bluetooth: hci0: ==== Start FW dump ===
[  334.261003] Bluetooth: hci0: ==== Send uevent: BTNXPUART_DEV=serial0-0:BTNXPUART_STATE=FW_DUMP_ACTIVE ===
[  351.486048] Bluetooth: hci0: ==== FW dump complete ===
[  351.491356] Bluetooth: hci0: ==== Send uevent: BTNXPUART_DEV=serial0-0:BTNXPUART_STATE=FW_DUMP_DONE ===
[  352.028974] Bluetooth: hci0: ChipID: 7601, Version: 0
[  352.034490] Bluetooth: hci0: Request Firmware: nxp/uartspi_n61x_v1.bin.se
[  353.979977] Bluetooth: hci0: FW Download Complete: 417064 bytes
[  355.197222] Bluetooth: hci0: ==== Send uevent: BTNXPUART_DEV=serial0-0:BTNXPUART_STATE=FW_READY ===

Tested this change by creating a simple udev rule to store the
BTNXPUART_STATE value in a ~/<BTNXPUART_DEV>/state file, and running
15.4 traffic.

The 15.4 packets were sent over SPI only when BTNXPUART_STATE was
FW_READY.

Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Tested-by: Jean-Yves Salaün <jean-yves.salaun@nxp.com>
---
 drivers/bluetooth/btnxpuart.c | 38 ++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index f40794be2d89..c16ff72c9948 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1434,6 +1434,10 @@ static int nxp_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 static int nxp_setup(struct hci_dev *hdev)
 {
 	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+	struct serdev_device *serdev = nxpdev->serdev;
+	char device_string[30];
+	char event_string[50];
+	char *envp[] = {device_string, event_string, NULL};
 	int err = 0;
 
 	if (nxp_check_boot_sign(nxpdev)) {
@@ -1446,6 +1450,11 @@ static int nxp_setup(struct hci_dev *hdev)
 		clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
 	}
 
+	snprintf(device_string, 30, "BTNXPUART_DEV=%s", dev_name(&serdev->dev));
+	snprintf(event_string, 50, "BTNXPUART_STATE=FW_READY");
+	bt_dev_dbg(hdev, "==== Send uevent: %s:%s ===", device_string, event_string);
+	kobject_uevent_env(&serdev->dev.kobj, KOBJ_CHANGE, envp);
+
 	serdev_device_set_baudrate(nxpdev->serdev, nxpdev->fw_init_baudrate);
 	nxpdev->current_baudrate = nxpdev->fw_init_baudrate;
 
@@ -1766,6 +1775,33 @@ static const struct serdev_device_ops btnxpuart_client_ops = {
 	.write_wakeup = btnxpuart_write_wakeup,
 };
 
+static void nxp_coredump_notify(struct hci_dev *hdev, int state)
+{
+	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+	struct serdev_device *serdev = nxpdev->serdev;
+	char device_string[30];
+	char event_string[50];
+	char *envp[] = {device_string, event_string, NULL};
+
+	snprintf(device_string, 30, "BTNXPUART_DEV=%s", dev_name(&serdev->dev));
+	switch (state) {
+	case HCI_DEVCOREDUMP_ACTIVE:
+		snprintf(event_string, 50, "BTNXPUART_STATE=FW_DUMP_ACTIVE");
+		break;
+	case HCI_DEVCOREDUMP_DONE:
+		snprintf(event_string, 50, "BTNXPUART_STATE=FW_DUMP_DONE");
+		break;
+	case HCI_DEVCOREDUMP_TIMEOUT:
+		snprintf(event_string, 50, "BTNXPUART_STATE=FW_DUMP_TIMEOUT");
+		break;
+	default:
+		snprintf(event_string, 50, "BTNXPUART_STATE=FW_DUMP_STATE_%d", state);
+		break;
+	}
+	bt_dev_dbg(hdev, "==== Send uevent: %s:%s ===", device_string, event_string);
+	kobject_uevent_env(&serdev->dev.kobj, KOBJ_CHANGE, envp);
+}
+
 static int nxp_serdev_probe(struct serdev_device *serdev)
 {
 	struct hci_dev *hdev;
@@ -1849,7 +1885,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 	if (ps_setup(hdev))
 		goto probe_fail;
 
-	hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr, NULL);
+	hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr, nxp_coredump_notify);
 
 	return 0;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [v1,1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump
  2025-07-03 13:05 [PATCH v1 1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump Neeraj Sanjay Kale
  2025-07-03 13:05 ` [PATCH v1 2/2] Bluetooth: btnxpuart: Add uevents for FW dump and FW download complete Neeraj Sanjay Kale
@ 2025-07-03 14:08 ` bluez.test.bot
  1 sibling, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2025-07-03 14:08 UTC (permalink / raw)
  To: linux-bluetooth, neeraj.sanjaykale

[-- Attachment #1: Type: text/plain, Size: 2376 bytes --]

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=978644

---Test result---

Test Summary:
CheckPatch                    PENDING   0.42 seconds
GitLint                       PENDING   0.35 seconds
SubjectPrefix                 PASS      0.32 seconds
BuildKernel                   PASS      24.10 seconds
CheckAllWarning               PASS      26.48 seconds
CheckSparse                   PASS      30.12 seconds
BuildKernel32                 PASS      24.28 seconds
TestRunnerSetup               PASS      473.91 seconds
TestRunner_l2cap-tester       PASS      25.40 seconds
TestRunner_iso-tester         PASS      42.42 seconds
TestRunner_bnep-tester        PASS      6.08 seconds
TestRunner_mgmt-tester        FAIL      134.34 seconds
TestRunner_rfcomm-tester      PASS      9.42 seconds
TestRunner_sco-tester         PASS      14.80 seconds
TestRunner_ioctl-tester       PASS      10.10 seconds
TestRunner_mesh-tester        FAIL      11.42 seconds
TestRunner_smp-tester         PASS      8.56 seconds
TestRunner_userchan-tester    PASS      6.27 seconds
IncrementalBuild              PENDING   0.99 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 490, Passed: 484 (98.8%), Failed: 2, Not Run: 4

Failed Test Cases
LL Privacy - Add Device 3 (AL is full)               Failed       0.228 seconds
LL Privacy - Set Device Flag 1 (Device Privacy)      Failed       0.163 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    2.071 seconds
Mesh - Send cancel - 2                               Timed out    1.997 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [v1,1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump
  2025-07-14  7:30 [PATCH v1 1/2] " Neeraj Sanjay Kale
@ 2025-07-14  8:43 ` bluez.test.bot
  0 siblings, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2025-07-14  8:43 UTC (permalink / raw)
  To: linux-bluetooth, neeraj.sanjaykale

[-- Attachment #1: Type: text/plain, Size: 2377 bytes --]

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=981936

---Test result---

Test Summary:
CheckPatch                    PENDING   0.30 seconds
GitLint                       PENDING   0.20 seconds
SubjectPrefix                 PASS      0.25 seconds
BuildKernel                   PASS      24.85 seconds
CheckAllWarning               PASS      27.26 seconds
CheckSparse                   PASS      30.76 seconds
BuildKernel32                 PASS      23.97 seconds
TestRunnerSetup               PASS      482.23 seconds
TestRunner_l2cap-tester       PASS      25.55 seconds
TestRunner_iso-tester         PASS      50.31 seconds
TestRunner_bnep-tester        PASS      6.11 seconds
TestRunner_mgmt-tester        FAIL      136.49 seconds
TestRunner_rfcomm-tester      PASS      9.60 seconds
TestRunner_sco-tester         PASS      15.07 seconds
TestRunner_ioctl-tester       PASS      10.49 seconds
TestRunner_mesh-tester        FAIL      14.84 seconds
TestRunner_smp-tester         PASS      10.01 seconds
TestRunner_userchan-tester    PASS      6.41 seconds
IncrementalBuild              PENDING   0.57 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 490, Passed: 484 (98.8%), Failed: 2, Not Run: 4

Failed Test Cases
LL Privacy - Set Flags 3 (2 Devices to RL)           Failed       0.221 seconds
LL Privacy - Start Discovery 1 (Disable RL)          Failed       0.208 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    2.096 seconds
Mesh - Send cancel - 2                               Timed out    2.004 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-07-14  8:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-03 13:05 [PATCH v1 1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump Neeraj Sanjay Kale
2025-07-03 13:05 ` [PATCH v1 2/2] Bluetooth: btnxpuart: Add uevents for FW dump and FW download complete Neeraj Sanjay Kale
2025-07-03 14:08 ` [v1,1/2] Bluetooth: btnxpuart: Correct the Independent Reset handling after FW dump bluez.test.bot
  -- strict thread matches above, loose matches on Subject: below --
2025-07-14  7:30 [PATCH v1 1/2] " Neeraj Sanjay Kale
2025-07-14  8:43 ` [v1,1/2] " bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox