Thread (5 messages) flat view 5 messages, 4 authors, 2025-08-23

Re: [PATCH v5] Fix SSR(SubSystem Restart) fail when BT_EN is pulled up by hw

From: Shuai Zhang <hidden>
Date: 2025-08-21 11:34:57
Also in: linux-arm-msm

Dear,Paul

On 8/20/2025 9:32 PM, Paul Menzel wrote:
Dear Shuai,


Thank you for the improved version. The commit message summary/title still has the space missing before the ( and should be prefixed with `Bluetooth:` to pass the linters.

Am 20.08.25 um 14:06 schrieb Shuai Zhang:
quoted
When the host actively triggers SSR and collects coredump data,
the Bluetooth stack sends a reset command to the controller. However, due
to the inability to clear the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits,
the reset command times out.

To address this, this patch clears the QCA_SSR_TRIGGERED and
QCA_IBS_DISABLED flags and adds a 50ms delay after SSR, but only when
HCI_QUIRK_NON_PERSISTENT_SETUP is not set. This ensures the controller
completes the SSR process when BT_EN is always high due to hardware.

For the purpose of HCI_QUIRK_NON_PERSISTENT_SETUP, please refer to
commit 740011cfe948 ("Bluetooth: Add new quirk for non-persistent setup
settings")
Missing dot/period at the end.

Also, the comment in `include/net/bluetooth/hci.h` is more helpful to me than the commit.
quoted
The HCI_QUIRK_NON_PERSISTENT_SETUP quirk is associated with BT_EN,
and its presence can be used to determine whether BT_EN is defined in DTS.

After SSR, host will not download the firmware, causing
controller to remain in the IBS_WAKE state. Host needs
to synchronize with the controller to maintain proper operation.

Multiple triggers of SSR only first generate coredump file,
duo to memcoredump_flag no clear.
due to
quoted
add clear coredump flag when ssr completed.

When the SSR duration exceeds 2 seconds, it triggers
host tx_idle_timeout, which sets host TX state to sleep. due to the
hardware pulling up bt_en, the firmware is not downloaded after the SSR.
As a result, the controller does not enter sleep mode. Consequently,
when the host sends a command afterward, it sends 0xFD to the controller,
but the controller does not respond, leading to a command timeout.

So reset tx_idle_timer after SSR to prevent host enter TX IBS_Sloeep mode.
Sleep
quoted
Signed-off-by: Shuai Zhang <redacted>
---
  drivers/bluetooth/hci_qca.c | 31 +++++++++++++++++++++++++++++++
  1 file changed, 31 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4e56782b0..403d65952 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1653,6 +1653,37 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
          skb_queue_purge(&qca->rx_memdump_q);
      }
  +    /*
+     * If the BT chip's bt_en pin is connected to a 3.3V power supply via
+     * hardware and always stays high, driver cannot control the bt_en pin.
+     * As a result, during SSR(SubSystem Restart), QCA_SSR_TRIGGERED and
Missing space before (.
quoted
+     * QCA_IBS_DISABLED flags cannot be cleared, which leads to a reset
+     * command timeout.
+     * Add an msleep delay to ensure controller completes the SSR process.
+     *
+     * Host will not download the firmware after SSR, controller to remain
+     * in the IBS_WAKE state, and the host needs to synchronize with it
+     *
+     * Since the bluetooth chip has been reset, clear the memdump state.
+     */
+    if (!test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
+        /*
+         * When the SSR (Sub-System Restart) duration exceeds 2 seconds,
+         * it triggers host tx_idle_delay, which sets host TX state
+         * to sleep. Reset tx_idle_timer after SSR to prevent
+         * host enter TX IBS_Sloeep mode.
Sleep?
quoted
+         */
+        mod_timer(&qca->tx_idle_timer, jiffies +
+                  msecs_to_jiffies(qca->tx_idle_delay));
+        msleep(50);
Add a comment, why 50 ms and not 20 ms or 100 ms?
quoted
+
+        clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
+        clear_bit(QCA_IBS_DISABLED, &qca->flags);
+
+        qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
+        qca->memdump_state = QCA_MEMDUMP_IDLE;
+    }
+
      clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
  }
  

Kind regards,

Paul
Thanks again for your thorough check. 
I’ll revise the content and share the updated version soon


BR,
Shuai


Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help