Search Linux Wireless

[PATCHv2] mac80211: fix recalc_radar hwconf sync problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



local->hw.conf maybe not be synced when recalcing whether radar is
enabled, sometimes leaving radar enabled even if it's not neccesary
anymore.

Fix this by:
 * setting radar_enabled when creating the chanctx
 * turning radar_enabled off before destroying the last channel context

Reported-by: Zefir Kurtisi <zefir.kurtisi@xxxxxxxxxxx>
Signed-off-by: Simon Wunderlich <siwu@xxxxxxxxxxxxxxxxxx>
---
 net/mac80211/chan.c |   32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 931be41..1f54ffe 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -57,6 +57,22 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
 	return NULL;
 }
 
+static bool ieee80211_is_radar_required(struct ieee80211_local *local)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+		if (sdata->radar_required) {
+			rcu_read_unlock();
+			return true;
+		}
+	}
+	rcu_read_unlock();
+
+	return false;
+}
+
 static struct ieee80211_chanctx *
 ieee80211_new_chanctx(struct ieee80211_local *local,
 		      const struct cfg80211_chan_def *chandef,
@@ -76,6 +92,9 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
 	ctx->conf.rx_chains_static = 1;
 	ctx->conf.rx_chains_dynamic = 1;
 	ctx->mode = mode;
+	ctx->conf.radar_enabled = ieee80211_is_radar_required(local);
+	if (!local->use_chanctx)
+		local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 
 	/* acquire mutex to prevent idle from changing */
 	mutex_lock(&local->mtx);
@@ -118,6 +137,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
 
 	if (!local->use_chanctx) {
 		local->_oper_channel_type = NL80211_CHAN_NO_HT;
+		local->hw.conf.radar_enabled = false;
 		ieee80211_hw_config(local, 0);
 	} else {
 		drv_remove_chanctx(local, ctx);
@@ -237,19 +257,11 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
 void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
 				    struct ieee80211_chanctx *chanctx)
 {
-	struct ieee80211_sub_if_data *sdata;
-	bool radar_enabled = false;
+	bool radar_enabled;
 
 	lockdep_assert_held(&local->chanctx_mtx);
 
-	rcu_read_lock();
-	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-		if (sdata->radar_required) {
-			radar_enabled = true;
-			break;
-		}
-	}
-	rcu_read_unlock();
+	radar_enabled = ieee80211_is_radar_required(local);
 
 	if (radar_enabled == chanctx->conf.radar_enabled)
 		return;
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux