diff mbox series

[v13,3/3] mac80211: MBSSID channel switch

Message ID 20211006040938.9531-4-alokad@codeaurora.org (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series MBSSID and EMA support in AP mode | expand

Commit Message

Aloka Dixit Oct. 6, 2021, 4:09 a.m. UTC
From: John Crispin <john@phrozen.org>

Trigger ieee80211_csa_finish() on the non-transmitting interfaces
when channel switch concludes on the transmitting interface.

Signed-off-by: John Crispin <john@phrozen.org>
Co-developed-by: Aloka Dixit <alokad@codeaurora.org>
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
---
v13: Replaced list_for_each_entry_safe() by list_for_each_entry()

 net/mac80211/cfg.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Johannes Berg Nov. 26, 2021, 11:16 a.m. UTC | #1
On Tue, 2021-10-05 at 21:09 -0700, Aloka Dixit wrote:
> From: John Crispin <john@phrozen.org>
> 
> Trigger ieee80211_csa_finish() on the non-transmitting interfaces
> when channel switch concludes on the transmitting interface.
> 
> Signed-off-by: John Crispin <john@phrozen.org>
> Co-developed-by: Aloka Dixit <alokad@codeaurora.org>
> Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
> ---
> v13: Replaced list_for_each_entry_safe() by list_for_each_entry()
> 

Uh, ouch. I guess I miscommunicated that.

What I really meant was that the list iteration here:

> +	if (vif->mbssid_tx_vif == vif) {
> +		struct ieee80211_sub_if_data *child;
> +
> +		list_for_each_entry(child, &sdata->local->interfaces,
> list)

does not seem correct, since it's not locked, and you don't have any
guarantees that it's not being modified since the only thing here is
that the vif pointer is coming in valid from the driver?

johannes
diff mbox series

Patch

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index cfe99de457cb..8a107439451c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3271,8 +3271,18 @@  void ieee80211_csa_finish(struct ieee80211_vif *vif)
 {
 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 
-	ieee80211_queue_work(&sdata->local->hw,
-			     &sdata->csa_finalize_work);
+	if (vif->mbssid_tx_vif == vif) {
+		struct ieee80211_sub_if_data *child;
+
+		list_for_each_entry(child, &sdata->local->interfaces, list)
+			if (child != sdata && child->vif.mbssid_tx_vif == vif &&
+			    ieee80211_sdata_running(child)) {
+				ieee80211_queue_work(&child->local->hw,
+						     &child->csa_finalize_work);
+			}
+	}
+
+	ieee80211_queue_work(&sdata->local->hw, &sdata->csa_finalize_work);
 }
 EXPORT_SYMBOL(ieee80211_csa_finish);