Linux wireless drivers development
 help / color / mirror / Atom feed
From: "André Valentin" <avalentin@marcant.net>
To: Jeff Johnson <jjohnson@kernel.org>
Cc: linux-wireless@vger.kernel.org, ath11k@lists.infradead.org,
	Kalle Valo <kvalo@kernel.org>,
	avalentin@marcant.net, stable@vger.kernel.org,
	Manikanta Pubbisetty <manikanta.pubbisetty@oss.qualcomm.com>
Subject: [PATCH v3] wifi: ath11k: run ahb shutdown() teardown only on WCN6750
Date: Mon, 10 Aug 2026 21:28:59 +0200	[thread overview]
Message-ID: <20260810192859.949348-1-avalentin@marcant.net> (raw)
In-Reply-To: <20260808213551.4169863-1-avalentin@marcant.net>

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: stable@vger.kernel.org
Cc: Manikanta Pubbisetty <manikanta.pubbisetty@oss.qualcomm.com>
Signed-off-by: André Valentin <avalentin@marcant.net>
---
Changes in v3 (per Jeff Johnson's v2 review):
- ahb.c/hw.h: fix block comment style (/* on its own line) and drop the
  chip references from the generic code -- describe the behaviour, not the
  chipset; only the hw_params initializer ties it to WCN6750.
- core.c: explicitly initialize shutdown_teardown in every hw_params record
  (= false on all but WCN6750).

v2: https://lore.kernel.org/linux-wireless/20260808213551.4169863-1-avalentin@marcant.net/
v1: https://lore.kernel.org/linux-wireless/20260807094858.1548216-1-avalentin@marcant.net/

 drivers/net/wireless/ath/ath11k/ahb.c  | 10 ++++++++++
 drivers/net/wireless/ath/ath11k/core.c | 10 ++++++++++
 drivers/net/wireless/ath/ath11k/hw.h   |  7 +++++++
 3 files changed, 27 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 1e1dea4..18f7bff 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -1288,6 +1288,16 @@ static void ath11k_ahb_shutdown(struct platform_device *pdev)
 	 * remove() is invoked during rmmod & shutdown() during
 	 * system reboot/shutdown.
 	 */
+
+	/*
+	 * Only run the teardown where hw_params requests it. Where it is not
+	 * required, stopping the firmware here would leave shared state that
+	 * hangs the following warm reset, so skip it and let the SoC reset
+	 * re-initialize the hardware from scratch instead.
+	 */
+	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..2a10173 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -41,6 +41,7 @@ MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");
 static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.hw_rev = ATH11K_HW_IPQ8074,
+		.shutdown_teardown = false,
 		.name = "ipq8074 hw2.0",
 		.fw = {
 			.dir = "IPQ8074/hw2.0",
@@ -130,6 +131,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	},
 	{
 		.hw_rev = ATH11K_HW_IPQ6018_HW10,
+		.shutdown_teardown = false,
 		.name = "ipq6018 hw1.0",
 		.fw = {
 			.dir = "IPQ6018/hw1.0",
@@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.name = "qca6390 hw2.0",
 		.hw_rev = ATH11K_HW_QCA6390_HW20,
+		.shutdown_teardown = false,
 		.fw = {
 			.dir = "QCA6390/hw2.0",
 			.board_size = 256 * 1024,
@@ -310,6 +313,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.name = "qcn9074 hw1.0",
 		.hw_rev = ATH11K_HW_QCN9074_HW10,
+		.shutdown_teardown = false,
 		.fw = {
 			.dir = "QCN9074/hw1.0",
 			.board_size = 256 * 1024,
@@ -396,6 +400,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.name = "wcn6855 hw2.0",
 		.hw_rev = ATH11K_HW_WCN6855_HW20,
+		.shutdown_teardown = false,
 		.fw = {
 			.dir = "WCN6855/hw2.0",
 			.board_size = 256 * 1024,
@@ -488,6 +493,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.name = "wcn6855 hw2.1",
 		.hw_rev = ATH11K_HW_WCN6855_HW21,
+		.shutdown_teardown = false,
 		.fw = {
 			.dir = "WCN6855/hw2.1",
 			.board_size = 256 * 1024,
@@ -578,6 +584,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,
@@ -662,6 +669,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	},
 	{
 		.hw_rev = ATH11K_HW_IPQ5018_HW10,
+		.shutdown_teardown = false,
 		.name = "ipq5018 hw1.0",
 		.fw = {
 			.dir = "IPQ5018/hw1.0",
@@ -748,6 +756,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.name = "qca2066 hw2.1",
 		.hw_rev = ATH11K_HW_QCA2066_HW21,
+		.shutdown_teardown = false,
 		.fw = {
 			.dir = "QCA2066/hw2.1",
 			.board_size = 256 * 1024,
@@ -839,6 +848,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
 	{
 		.name = "qca6698aq hw2.1",
 		.hw_rev = ATH11K_HW_QCA6698AQ_HW21,
+		.shutdown_teardown = false,
 		.fw = {
 			.dir = "QCA6698AQ/hw2.1",
 			.board_size = 256 * 1024,
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index 4996536..f35bb96 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -231,6 +231,13 @@ struct ath11k_hw_params {
 	bool cfr_support;
 	u32 cfr_num_stream_bufs;
 	u32 cfr_stream_buf_size;
+	/*
+	 * Run the ahb shutdown() teardown (stop DMA before the SMMU is torn
+	 * down at reboot/shutdown). Only set where the teardown is required;
+	 * where it is not, running it would stop the firmware and leave shared
+	 * state that hangs the following warm reset.
+	 */
+	bool shutdown_teardown;
 };
 
 struct ath11k_hw_ops {

base-commit: f9a2394a23482bfd330911e9c8295b71724feacd
-- 
2.47.3


      parent reply	other threads:[~2026-08-10 19:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-07  9:48 [PATCH] wifi: ath11k: run ahb shutdown() teardown only on WCN6750 André Valentin
2026-08-07 15:34 ` Jeff Johnson
2026-08-07 15:39   ` Jeff Johnson
2026-08-08 21:35 ` [PATCH v2] " André Valentin
2026-08-10 19:05   ` Jeff Johnson
2026-08-10 19:28   ` André Valentin [this message]

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=20260810192859.949348-1-avalentin@marcant.net \
    --to=avalentin@marcant.net \
    --cc=ath11k@lists.infradead.org \
    --cc=jjohnson@kernel.org \
    --cc=kvalo@kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=manikanta.pubbisetty@oss.qualcomm.com \
    --cc=stable@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox