[PATCH v2] wifi: ath11k: run ahb shutdown() teardown only on WCN6750
André Valentin <[email protected]>
| Newsgroups | org.kernel.vger.stable,org.infradead.lists.ath11k,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
The AHB shutdown() callback was added solely for WCN6750, which must stop
DMA before the SMMU is torn down at system reboot/shutdown. It was
registered unconditionally in the shared
ath11k_ahb_driver, so it also runs on the IPQ AHB targets (IPQ8074/
IPQ6018/IPQ5018), which never had a shutdown() handler before and have no
such SMMU requirement.
The commit message claimed the change "will not impact other AHB ath11k
devices", but it does: on IPQ6018 the teardown stops the WCSS Q6 remote
processor firmware, which leaves shared WCSS state such that the boot ROM
hangs during DDR training on the following warm reset -- only a cold
(power-on) reset recovers, so a plain reboot never comes back and needs a
physical power cycle. This was pinned by bisecting the teardown: skipping
ath11k_qmi_firmware_stop() (i.e. not stopping the Q6) is what lets the
warm reset train DDR and boot normally, whereas none of the q6v5 power,
reset or clock steps reproduce it on their own.
Restrict the shutdown() teardown to WCN6750 via hw_params, restoring the
pre-regression behaviour for the IPQ AHB targets: they simply have no
shutdown() teardown again, exactly as they did for years before that
change, and on reboot/shutdown the SoC reset re-initializes the WCSS from
scratch. WCN6750 keeps the teardown. Module removal (rmmod / remove()) is
unchanged for all targets.
Verified on a MikroTik Chateau 5G R17 ax (IPQ6018): before, a plain
reboot froze in the boot ROM during DDR training; after, it trains DDR
and boots the kernel across repeated reboots.
Fixes: ac41c2b642b1 ("wifi: ath11k: Register shutdown handler for WCN6750")
Cc: [email protected]
Cc: Manikanta Pubbisetty <[email protected]>
Signed-off-by: André Valentin <[email protected]>
---
Changes in v2 (per Jeff Johnson's review):
- Drive the difference from hw_params instead of comparing ab->hw_rev in
ath11k_ahb_shutdown(): add shutdown_teardown, set only for WCN6750.
- Frame it as restoring the pre-regression behaviour for the IPQ AHB
targets (no shutdown() teardown), rather than a per-SoC quirk.
v1: https://lore.kernel.org/linux-wireless/[email protected]/
drivers/net/wireless/ath/ath11k/ahb.c | 11 +++++++++++
drivers/net/wireless/ath/ath11k/core.c | 1 +
drivers/net/wireless/ath/ath11k/hw.h | 4 ++++
3 files changed, 16 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 1e1dea4..5d71ff4 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -1288,6 +1288,17 @@ static void ath11k_ahb_shutdown(struct platform_device *pdev)
* remove() is invoked during rmmod & shutdown() during
* system reboot/shutdown.
*/
+
+ /* The teardown below is only needed on WCN6750 (stop DMA before the
+ * SMMU is torn down). It was registered for all AHB targets, but on
+ * the IPQ SoCs it stops the WCSS Q6 firmware and leaves shared state
+ * that hangs the boot ROM during DDR training on the next warm reset;
+ * they never had a shutdown() teardown before and the SoC reset
+ * re-initializes the WCSS from scratch, so skip it there.
+ */
+ if (!ab->hw_params.shutdown_teardown)
+ return;
+
ath11k_ahb_remove_prepare(ab);
if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)))
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 8dacc87..c6df829 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -578,6 +578,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
{
.name = "wcn6750 hw1.0",
.hw_rev = ATH11K_HW_WCN6750_HW10,
+ .shutdown_teardown = true,
.fw = {
.dir = "WCN6750/hw1.0",
.board_size = 256 * 1024,
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index 4996536..8279eb4 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -231,6 +231,10 @@ struct ath11k_hw_params {
bool cfr_support;
u32 cfr_num_stream_bufs;
u32 cfr_stream_buf_size;
+ /* run the ahb shutdown() teardown; only WCN6750 needs it, to stop
+ * DMA before the SMMU is torn down at reboot/shutdown
+ */
+ bool shutdown_teardown;
};
struct ath11k_hw_ops {
base-commit: f9a2394a23482bfd330911e9c8295b71724feacd
--
2.47.3