From: Ravindra <ravindra@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: chethan.tumkur.narayan@intel.com, kiran.k@intel.com,
Ravindra <ravindra@intel.com>,
Paul Menzel <pmenzel@molgen.mpg.de>
Subject: [PATCH v3] Bluetooth: btintel: read ROM debug registers on FW download failure
Date: Mon, 21 Sep 2026 18:40:47 +0530 [thread overview]
Message-ID: <20260921131047.2780402-1-ravindra@intel.com> (raw)
The bootloader records init sequence progress and debug info in four
core debug registers, useful for debugging FW download failures.
Add btintel_get_rom_debug_info() to issue BTINTEL_GET_ROM_DEBUG_INFO
(0xfcde) and log these registers, and invoke it from every FW download
failure and timeout path: btintel_download_fw() (legacy .sfi flow) and
btintel_prepare_fw_download_tlv() (TLV flow), before resetting to the
bootloader.
Tested by corrupting the operational firmware file to force a
download timeout; the driver logged the debug registers on each
failure and retry, e.g.:
Bluetooth: hci0: Firmware loading timeout
Bluetooth: Intel get rom debug info:
dr0:0x80000001 dr1:0x00000000 dr2:0x00000001 dr3:0x00df0071
Signed-off-by: Ravindra <ravindra@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
---
drivers/bluetooth/btintel.c | 47 +++++++++++++++++++++++++++++++++++--
drivers/bluetooth/btintel.h | 9 +++++++
2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 964d2de30e65..5e6d1ddc99c6 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -963,6 +963,41 @@ int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param)
}
EXPORT_SYMBOL_GPL(btintel_send_intel_reset);
+static void btintel_get_rom_debug_info(struct hci_dev *hdev)
+{
+ struct btintel_rp_get_rom_debug_info *rom_debug_info;
+ struct sk_buff *skb;
+
+ skb = __hci_cmd_sync(hdev, BTINTEL_GET_ROM_DEBUG_INFO, 0, NULL,
+ HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Failed to send Intel get rom debug info command (%ld)",
+ PTR_ERR(skb));
+ return;
+ }
+
+ if (skb->len != sizeof(*rom_debug_info)) {
+ bt_dev_err(hdev,
+ "Intel get rom debug info size mismatch (%u != %zu)",
+ skb->len, sizeof(*rom_debug_info));
+ kfree_skb(skb);
+ return;
+ }
+
+ rom_debug_info = (struct btintel_rp_get_rom_debug_info *)skb->data;
+
+ /* A non-zero status here would have already been turned into an
+ * error by the HCI core and reported via the IS_ERR(skb) check above.
+ */
+ bt_dev_info(hdev, "Intel get rom debug info: dr0:0x%08x dr1:0x%08x dr2:0x%08x dr3:0x%08x",
+ le32_to_cpu(rom_debug_info->debug_reg0),
+ le32_to_cpu(rom_debug_info->debug_reg1),
+ le32_to_cpu(rom_debug_info->debug_reg2),
+ le32_to_cpu(rom_debug_info->debug_reg3));
+
+ kfree_skb(skb);
+}
+
int btintel_read_boot_params(struct hci_dev *hdev,
struct intel_boot_params *params)
{
@@ -2212,6 +2247,8 @@ static int btintel_download_fw(struct hci_dev *hdev,
goto done;
}
+ btintel_get_rom_debug_info(hdev);
+
/* When FW download fails, send Intel Reset to retry
* FW download.
*/
@@ -2231,8 +2268,10 @@ static int btintel_download_fw(struct hci_dev *hdev,
* of this device.
*/
err = btintel_download_wait(hdev, calltime, 5000);
- if (err == -ETIMEDOUT)
+ if (err == -ETIMEDOUT) {
+ btintel_get_rom_debug_info(hdev);
btintel_reset_to_bootloader(hdev);
+ }
done:
release_firmware(fw);
@@ -2465,6 +2504,8 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
goto done;
}
+ btintel_get_rom_debug_info(hdev);
+
/* When FW download fails, send Intel Reset to retry
* FW download.
*/
@@ -2484,8 +2525,10 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
* of this device.
*/
err = btintel_download_wait(hdev, calltime, 5000);
- if (err == -ETIMEDOUT)
+ if (err == -ETIMEDOUT) {
+ btintel_get_rom_debug_info(hdev);
btintel_reset_to_bootloader(hdev);
+ }
done:
intel_data->cnvi_bt = ver->cnvi_bt;
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index c00f793d9dc8..b3c4c6f87424 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -178,6 +178,15 @@ struct hci_ppag_enable_cmd {
__le32 ppag_enable_flags;
} __packed;
+#define BTINTEL_GET_ROM_DEBUG_INFO 0xfcde
+struct btintel_rp_get_rom_debug_info {
+ __u8 status;
+ __le32 debug_reg0;
+ __le32 debug_reg1;
+ __le32 debug_reg2;
+ __le32 debug_reg3;
+} __packed;
+
#define INTEL_TLV_TYPE_ID 0x01
#define INTEL_TLV_SYSTEM_EXCEPTION 0x00
--
2.43.0
next reply other threads:[~2026-09-21 13:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 13:10 Ravindra [this message]
2026-09-21 14:10 ` [PATCH v3] Bluetooth: btintel: read ROM debug registers on FW download failure patchwork-bot+bluetooth
-- strict thread matches above, loose matches on Subject: below --
2026-09-21 5:48 Ravindra
2026-09-18 8:44 Ravindra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260921131047.2780402-1-ravindra@intel.com \
--to=ravindra@intel.com \
--cc=chethan.tumkur.narayan@intel.com \
--cc=kiran.k@intel.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=pmenzel@molgen.mpg.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.