[RFC PATCH 1/1] Bluetooth: qca: Clear 5th byte in TLV tag 27 for WCN3950

From: Stanislavs Nilovs

Date: Tue Nov 03 2026 - 06:12:37 EST


This fixes an incompatibility issue of TLV with 5th byte set to some
value in Tag 27 (Deep Sleep) and the QCA driver for WCN3950 SoC. If the
value is set in TLV, then 2 symptoms are observed:

1) The QCA pre-shutdown command (0xfc08) always fails with timeout.

2) SoC becomes unstable. During power cycling test it could stop
answering to any commands and QCA driver enters into the "SoC crashed"
loop and can never recover.

Setting the 5th byte to 0 resolves both issues - pre-shutdown never
times out (so, is always replied) and no crash loops observed.

The Claude Opus 5 (Anthropic) was used to create scripts for dumping the
tag values from TLV files and compare the differences. The fix itself
was written by me and verified on real hardware.

Signed-off-by: Stanislavs Nilovs <valorcool@xxxxxxxxx>
---
drivers/bluetooth/btqca.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 60735b70d89a..a7302a3f9774 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -443,6 +443,15 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
*/
tlv_nvm->data[0] |= 0x01;

+ /* The byte 5 in tag 27 (Deep Sleep) doesn't work with QCA driver.
+ * If a value is set to anything other than 0, then module can
+ * enter is some "endless" sleep and stops responding to our
+ * commands, and the QCA driver enters into endless "SoC crash"
+ * loop. Setting this byte to 0 resolves all problems.
+ */
+ if (tag_len >= 5 && soc_type == QCA_WCN3950)
+ tlv_nvm->data[4] = 0x00;
+
break;
}

--
2.53.0