[PATCH ath-next v3 08/10] wifi: ath10k: trigger recovery on corrupted HTC bundle lookahead

From: Kang Yang

Date: Thu Nov 12 2026 - 06:45:01 EST


When firmware crashes, the SDIO interrupt handler may read a
corrupted RX lookahead whose header reports more messages than
ar->htc.max_msgs_per_htc_bundle. The driver then prints errors such
as:

HTC bundle length 2322 exceeds maximum 32
failed to allocate a bundle: -12
failed to get pending recv messages: -12
failed to process pending SDIO interrupts: -12

The handler returns -ENOMEM without consuming the mailbox lookahead
or checking the firmware-crash CPU interrupt. The SDIO interrupt
therefore remains asserted and ath10k_sdio_irq_handler() repeatedly
processes the same invalid lookahead.

Stress-test logs show that this interrupt storm can continue for
15 to 20 seconds before the firmware watchdog allows the crash
interrupt to be observed and recovery to start. RX remains stalled
and user traffic times out during this interval.

ath10k_sdio_mbox_rx_alloc() already triggers recovery when the
lookahead payload length exceeds ATH10K_HTC_MBOX_MAX_PAYLOAD_LENGTH.
A bundle count above max_msgs_per_htc_bundle is the same class of
corrupted lookahead.

Mask the target interrupts immediately when the invalid bundle count
is detected, then start recovery so the HIF is reinitialized instead
of waiting for the firmware watchdog.

Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1
Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189

Signed-off-by: Kang Yang <kang.yang@xxxxxxxxxxxxxxxx>
---
drivers/net/wireless/ath/ath10k/sdio.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
index 748ba6749339..fdf19ce4b55b 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.c
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -497,6 +497,8 @@ static int ath10k_sdio_mbox_rx_process_packets(struct ath10k *ar,
return ret;
}

+static int ath10k_sdio_disable_intrs(struct ath10k *ar);
+
static int ath10k_sdio_mbox_alloc_bundle(struct ath10k *ar,
struct ath10k_sdio_rx_data *rx_pkts,
struct ath10k_htc_hdr *htc_hdr,
@@ -513,6 +515,11 @@ static int ath10k_sdio_mbox_alloc_bundle(struct ath10k *ar,
"HTC bundle length %u exceeds maximum %u\n",
le16_to_cpu(htc_hdr->len),
max_msgs);
+ ath10k_core_start_recovery(ar);
+ /* Recovery is a no-op if already pending, so also mask the
+ * target interrupts to stop the IRQ storm.
+ */
+ ath10k_sdio_disable_intrs(ar);
return -ENOMEM;
}


--
2.34.1