mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] wifi: rsi: fix background scan result and state lifetime
@ 2026-10-28 14:19 Zhao Li
  2026-10-28 14:19 ` [PATCH 1/3] wifi: rsi: initialize background scan completion data Zhao Li
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Zhao Li @ 2026-10-28 14:19 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Sebastian Krzyszkowiak, Arend van Spriel, Ville Nummela,
	Jiangshan Yi, Marek Vasut, Toke Høiland-Jørgensen,
	Stefan Hansson, Ping-Ke Shih, Jakub Kicinski, Ethan Nelson-Moore,
	Pengpeng Hou, Prameela Rani Garnepudi, Siva Rebbagondla,
	Kalle Valo, linux-wireless, linux-kernel

Initialize background-scan results and report cancellation as aborted.
Report command-preparation failures instead of leaving mac80211 waiting
for a completion, then serialize the saved request with cancellation and
firmware completion.

The patches are ordered. Patch 2 clears the saved request on every failed
start; patch 3 relies on that invariant when it treats bgscan_en and
hwscan as one state protected by scan_mutex.

The driver is orphaned and this series was not run on RS9113 or RS9116
hardware. Testing from device users would be helpful.
LLM assistance was used to review this series.

---
The series applies without source changes to the retained 6.1.y, 6.6.y,
6.12.y, 6.18.y, 7.2.10, and v7.3 trees. The retained 5.10.y and 5.15.y
trees need a context adaptation in patch 2.

Zhao Li (3):
  wifi: rsi: initialize background scan completion data
  wifi: rsi: report background scan start failures
  wifi: rsi: serialize background scan state

 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 50 ++++++++++++++-------
 drivers/net/wireless/rsi/rsi_91x_main.c     |  1 +
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 30 ++++++++-----
 drivers/net/wireless/rsi/rsi_main.h         |  2 +
 drivers/net/wireless/rsi/rsi_mgmt.h         |  3 +-
 5 files changed, 56 insertions(+), 30 deletions(-)


base-commit: 25e73f1d6868c759c8eb56cad4e411692c5341b4
-- 
2.56.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] wifi: rsi: initialize background scan completion data
  2026-10-28 14:19 [PATCH 0/3] wifi: rsi: fix background scan result and state lifetime Zhao Li
@ 2026-10-28 14:19 ` Zhao Li
  2026-10-28 14:19 ` [PATCH 2/3] wifi: rsi: report background scan start failures Zhao Li
  2026-10-28 14:19 ` [PATCH 3/3] wifi: rsi: serialize background scan state Zhao Li
  2 siblings, 0 replies; 4+ messages in thread
From: Zhao Li @ 2026-10-28 14:19 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Sebastian Krzyszkowiak, Arend van Spriel, Ville Nummela,
	Jiangshan Yi, Marek Vasut, Toke Høiland-Jørgensen,
	Stefan Hansson, Ping-Ke Shih, Jakub Kicinski, Ethan Nelson-Moore,
	Pengpeng Hou, Prameela Rani Garnepudi, Siva Rebbagondla,
	Kalle Valo, linux-wireless, linux-kernel, stable

Background scan completion can expose uninitialized timestamp and BSSID
fields to userspace, while cancellation is reported as a successful scan.

Both completion paths allocate cfg80211_scan_info on the stack but set
only aborted. mac80211 copies the other fields, and nl80211 can emit the
14 uninitialized bytes when the stack value interpreted as TSF is nonzero.

Zero-initialize the result and mark cancellation aborted.

LLM assistance was used to find the bug and review.

Fixes: 7fdcb8e12660 ("rsi: add support for hardware scan offload")
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
---
Validation: W=1 module builds with MODPOST passed with CONFIG_RSI_COEX
enabled and disabled. Not reproduced; RS9113/RS9116 hardware was
unavailable.
Sparse C=2 passed. Targeted Smatch introduced no new diagnostics.

 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 5 +++--
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 3 +--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 3faf2235728b..27bfdb6affaf 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -276,7 +276,9 @@ static void rsi_mac80211_cancel_hw_scan(struct ieee80211_hw *hw,
 {
 	struct rsi_hw *adapter = hw->priv;
 	struct rsi_common *common = adapter->priv;
-	struct cfg80211_scan_info info;
+	struct cfg80211_scan_info info = {
+		.aborted = true,
+	};
 
 	rsi_dbg(INFO_ZONE, "***** Hardware scan stop *****\n");
 	mutex_lock(&common->mutex);
@@ -284,7 +286,6 @@ static void rsi_mac80211_cancel_hw_scan(struct ieee80211_hw *hw,
 	if (common->bgscan_en) {
 		if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
 			common->bgscan_en = false;
-		info.aborted = false;
 		ieee80211_scan_completed(adapter->hw, &info);
 		rsi_dbg(INFO_ZONE, "Back ground scan cancelled\n");
 	}
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index d9dcbb255317..9ceb6cba3546 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -2107,11 +2107,10 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
 	case BG_SCAN_PROBE_REQ:
 		rsi_dbg(INFO_ZONE, "BG scan complete event\n");
 		if (common->bgscan_en) {
-			struct cfg80211_scan_info info;
+			struct cfg80211_scan_info info = {};
 
 			if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
 				common->bgscan_en = 0;
-			info.aborted = false;
 			ieee80211_scan_completed(adapter->hw, &info);
 		}
 		rsi_dbg(INFO_ZONE, "Background scan completed\n");
-- 
2.56.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] wifi: rsi: report background scan start failures
  2026-10-28 14:19 [PATCH 0/3] wifi: rsi: fix background scan result and state lifetime Zhao Li
  2026-10-28 14:19 ` [PATCH 1/3] wifi: rsi: initialize background scan completion data Zhao Li
@ 2026-10-28 14:19 ` Zhao Li
  2026-10-28 14:19 ` [PATCH 3/3] wifi: rsi: serialize background scan state Zhao Li
  2 siblings, 0 replies; 4+ messages in thread
From: Zhao Li @ 2026-10-28 14:19 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Sebastian Krzyszkowiak, Arend van Spriel, Ville Nummela,
	Jiangshan Yi, Marek Vasut, Toke Høiland-Jørgensen,
	Stefan Hansson, Ping-Ke Shih, Jakub Kicinski, Ethan Nelson-Moore,
	Pengpeng Hou, Prameela Rani Garnepudi, Siva Rebbagondla,
	Kalle Valo, linux-wireless, linux-kernel, stable

rsi_mac80211_hw_scan_start() returns success when a background-scan
command cannot be prepared. The driver never marks the scan active in
that case, so neither cancellation nor the firmware-event path reports
completion and mac80211 keeps the request pending.

Build the probe request before queueing the start parameters, propagate
preparation errors, and clear the saved request before mac80211 frees it.
Successful scans keep the existing firmware command order.

LLM assistance was used to find the bug and review.

Fixes: 7fdcb8e12660 ("rsi: add support for hardware scan offload")
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
---
Validation: W=1 module builds with MODPOST passed with CONFIG_RSI_COEX
enabled and disabled. Not reproduced; RS9113/RS9116 hardware was
unavailable.
Sparse C=2 passed. Targeted Smatch introduced no new diagnostics.

 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 14 ++++++++------
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 13 ++++++++-----
 drivers/net/wireless/rsi/rsi_mgmt.h         |  3 +--
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 27bfdb6affaf..a2e981e261d6 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -237,6 +237,7 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 	struct cfg80211_scan_request *scan_req = &hw_req->req;
 	struct rsi_hw *adapter = hw->priv;
 	struct rsi_common *common = adapter->priv;
+	int ret;
 
 	rsi_dbg(INFO_ZONE, "***** Hardware scan start *****\n");
 	common->mac_ops_resumed = false;
@@ -260,15 +261,16 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 
 	mutex_lock(&common->mutex);
 	common->hwscan = scan_req;
-	if (!rsi_send_bgscan_params(common, RSI_START_BGSCAN)) {
-		if (!rsi_send_bgscan_probe_req(common, vif)) {
-			rsi_dbg(INFO_ZONE, "Background scan started...\n");
-			common->bgscan_en = true;
-		}
+	ret = rsi_start_bgscan(common, vif);
+	if (ret) {
+		common->hwscan = NULL;
+	} else {
+		rsi_dbg(INFO_ZONE, "Background scan started...\n");
+		common->bgscan_en = true;
 	}
 	mutex_unlock(&common->mutex);
 
-	return 0;
+	return ret;
 }
 
 static void rsi_mac80211_cancel_hw_scan(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 9ceb6cba3546..165423313c5f 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1862,11 +1862,8 @@ int rsi_send_bgscan_params(struct rsi_common *common, int enable)
 	return rsi_send_internal_mgmt_frame(common, skb);
 }
 
-/* This function sends the probe request to be used by firmware in
- * background scan
- */
-int rsi_send_bgscan_probe_req(struct rsi_common *common,
-			      struct ieee80211_vif *vif)
+/* Send the firmware commands that start a background scan. */
+int rsi_start_bgscan(struct rsi_common *common, struct ieee80211_vif *vif)
 {
 	struct cfg80211_scan_request *scan_req = common->hwscan;
 	struct rsi_bgscan_probe *bgscan;
@@ -1875,6 +1872,7 @@ int rsi_send_bgscan_probe_req(struct rsi_common *common,
 	u16 frame_len = sizeof(*bgscan);
 	size_t ssid_len = 0;
 	u8 *ssid = NULL;
+	int ret;
 
 	rsi_dbg(MGMT_TX_ZONE,
 		"%s: Sending bgscan probe req frame\n", __func__);
@@ -1928,6 +1926,11 @@ int rsi_send_bgscan_probe_req(struct rsi_common *common,
 	skb_put(skb, frame_len + probereq_skb->len);
 
 	dev_kfree_skb(probereq_skb);
+	ret = rsi_send_bgscan_params(common, RSI_START_BGSCAN);
+	if (ret) {
+		dev_kfree_skb(skb);
+		return ret;
+	}
 
 	return rsi_send_internal_mgmt_frame(common, skb);
 }
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 236b21482f38..6a4907e6bca9 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -753,6 +753,5 @@ int rsi_send_ps_request(struct rsi_hw *adapter, bool enable,
 			struct ieee80211_vif *vif);
 void init_bgscan_params(struct rsi_common *common);
 int rsi_send_bgscan_params(struct rsi_common *common, int enable);
-int rsi_send_bgscan_probe_req(struct rsi_common *common,
-			      struct ieee80211_vif *vif);
+int rsi_start_bgscan(struct rsi_common *common, struct ieee80211_vif *vif);
 #endif
-- 
2.56.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] wifi: rsi: serialize background scan state
  2026-10-28 14:19 [PATCH 0/3] wifi: rsi: fix background scan result and state lifetime Zhao Li
  2026-10-28 14:19 ` [PATCH 1/3] wifi: rsi: initialize background scan completion data Zhao Li
  2026-10-28 14:19 ` [PATCH 2/3] wifi: rsi: report background scan start failures Zhao Li
@ 2026-10-28 14:19 ` Zhao Li
  2 siblings, 0 replies; 4+ messages in thread
From: Zhao Li @ 2026-10-28 14:19 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Sebastian Krzyszkowiak, Arend van Spriel, Ville Nummela,
	Jiangshan Yi, Marek Vasut, Toke Høiland-Jørgensen,
	Stefan Hansson, Ping-Ke Shih, Jakub Kicinski, Ethan Nelson-Moore,
	Pengpeng Hou, Prameela Rani Garnepudi, Siva Rebbagondla,
	Kalle Valo, linux-wireless, linux-kernel, stable

The firmware completion event runs in the RX thread without
common->mutex, while scan cancellation can clear hwscan under that mutex.
Both paths test bgscan_en before sending STOP and reporting completion.
An interleaving can therefore dereference a NULL or freed request in
rsi_send_bgscan_params(), or report the scan twice.

The RX path cannot take common->mutex: rsi_mac80211_start() holds it while
waiting for that path to finish firmware initialization after
hibernation.

Add a scan-specific mutex and use it to serialize start, cancellation,
and firmware completion. Clear bgscan_en and hwscan together even when
STOP cannot be queued so a later event cannot report the same scan again.

LLM assistance was used to find the bug and review.

Fixes: 7fdcb8e12660 ("rsi: add support for hardware scan offload")
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
---
Validation: W=1 module builds with MODPOST passed with CONFIG_RSI_COEX
enabled and disabled. Not reproduced; RS9113/RS9116 hardware was
unavailable.
Sparse C=2 passed. Targeted Smatch introduced no new diagnostics.
Host state is serialized, but no hardware or protocol evidence established
how a late event from a scan whose STOP command was not queued is attributed
after a later scan starts.

 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 31 +++++++++++++++------
 drivers/net/wireless/rsi/rsi_91x_main.c     |  1 +
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 16 +++++++----
 drivers/net/wireless/rsi/rsi_main.h         |  2 ++
 4 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index a2e981e261d6..5617c7ef6196 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -249,15 +249,21 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 	    scan_req->n_channels == 0)
 		return -EINVAL;
 
+	mutex_lock(&common->scan_mutex);
+
 	/* Scan already in progress. So return */
-	if (common->bgscan_en)
-		return -EBUSY;
+	if (common->bgscan_en) {
+		ret = -EBUSY;
+		goto out;
+	}
 
 	/* If STA is not connected, return with special value 1, in order
 	 * to start sw_scan in mac80211
 	 */
-	if (!vif->cfg.assoc)
-		return 1;
+	if (!vif->cfg.assoc) {
+		ret = 1;
+		goto out;
+	}
 
 	mutex_lock(&common->mutex);
 	common->hwscan = scan_req;
@@ -270,6 +276,9 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 	}
 	mutex_unlock(&common->mutex);
 
+out:
+	mutex_unlock(&common->scan_mutex);
+
 	return ret;
 }
 
@@ -283,16 +292,20 @@ static void rsi_mac80211_cancel_hw_scan(struct ieee80211_hw *hw,
 	};
 
 	rsi_dbg(INFO_ZONE, "***** Hardware scan stop *****\n");
-	mutex_lock(&common->mutex);
+	mutex_lock(&common->scan_mutex);
 
 	if (common->bgscan_en) {
-		if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
-			common->bgscan_en = false;
+		mutex_lock(&common->mutex);
+		if (rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
+			rsi_dbg(ERR_ZONE, "Failed to stop background scan\n");
+		mutex_unlock(&common->mutex);
+		common->bgscan_en = false;
+		common->hwscan = NULL;
 		ieee80211_scan_completed(adapter->hw, &info);
 		rsi_dbg(INFO_ZONE, "Back ground scan cancelled\n");
 	}
-	common->hwscan = NULL;
-	mutex_unlock(&common->mutex);
+
+	mutex_unlock(&common->scan_mutex);
 }
 
 /**
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index 2ce514766620..16f57c964ca3 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -325,6 +325,7 @@ struct rsi_hw *rsi_91x_init(u16 oper_mode)
 
 	rsi_init_event(&common->tx_thread.event);
 	mutex_init(&common->mutex);
+	mutex_init(&common->scan_mutex);
 	mutex_init(&common->tx_lock);
 	mutex_init(&common->rx_lock);
 	mutex_init(&common->tx_bus_mutex);
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 165423313c5f..5f11de44f880 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -2107,17 +2107,23 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
 		rsi_dbg(INFO_ZONE, "Wakeup/Sleep confirmation.\n");
 		return rsi_handle_ps_confirm(adapter, msg);
 
-	case BG_SCAN_PROBE_REQ:
+	case BG_SCAN_PROBE_REQ: {
+		struct cfg80211_scan_info info = {};
+
 		rsi_dbg(INFO_ZONE, "BG scan complete event\n");
+		mutex_lock(&common->scan_mutex);
 		if (common->bgscan_en) {
-			struct cfg80211_scan_info info = {};
-
-			if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
-				common->bgscan_en = 0;
+			if (rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
+				rsi_dbg(ERR_ZONE,
+					"Failed to stop background scan\n");
+			common->bgscan_en = false;
+			common->hwscan = NULL;
 			ieee80211_scan_completed(adapter->hw, &info);
 		}
+		mutex_unlock(&common->scan_mutex);
 		rsi_dbg(INFO_ZONE, "Background scan completed\n");
 		break;
+	}
 
 	default:
 		rsi_dbg(INFO_ZONE, "%s: Invalid TA confirm pkt received\n",
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index dcf8fb40698b..5fa8fd93a17e 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -250,6 +250,8 @@ struct rsi_common {
 	struct completion wlan_init_completion;
 	/* Mutex declaration */
 	struct mutex mutex;
+	/* Protect background scan state. */
+	struct mutex scan_mutex;
 	/* Mutex used for tx thread */
 	struct mutex tx_lock;
 	/* Mutex used for rx thread */
-- 
2.56.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-28 14:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-28 14:19 [PATCH 0/3] wifi: rsi: fix background scan result and state lifetime Zhao Li
2026-10-28 14:19 ` [PATCH 1/3] wifi: rsi: initialize background scan completion data Zhao Li
2026-10-28 14:19 ` [PATCH 2/3] wifi: rsi: report background scan start failures Zhao Li
2026-10-28 14:19 ` [PATCH 3/3] wifi: rsi: serialize background scan state Zhao Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®