summaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-06-25 12:35:07 +0200
committerJohannes Berg <johannes.berg@intel.com>2014-06-25 18:06:20 +0200
commit71e6195ed2541d764fb0d7ef39cdb2236817116b (patch)
tree6b05bec5528281f5cd790905f3e5a21927184218 /net/mac80211/util.c
parentmac80211: implement multi-vif in-place reservations (diff)
downloadlinux-71e6195ed2541d764fb0d7ef39cdb2236817116b.tar.xz
linux-71e6195ed2541d764fb0d7ef39cdb2236817116b.zip
mac80211: make check_combinations() aware of chanctx reservation
The ieee80211_check_combinations() computes radar_detect accordingly depending on chanctx reservation status. This makes it possible to use the function for channel_switch validation. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1b42aa16ec03..ea79668c2e5f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2933,6 +2933,35 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local,
ps->dtim_count = dtim_count;
}
+static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx)
+{
+ struct ieee80211_sub_if_data *sdata;
+ u8 radar_detect = 0;
+
+ lockdep_assert_held(&local->chanctx_mtx);
+
+ if (WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED))
+ return 0;
+
+ list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
+ if (sdata->reserved_radar_required)
+ radar_detect |= BIT(sdata->reserved_chandef.width);
+
+ /*
+ * An in-place reservation context should not have any assigned vifs
+ * until it replaces the other context.
+ */
+ WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
+ !list_empty(&ctx->assigned_vifs));
+
+ list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
+ if (sdata->radar_required)
+ radar_detect |= BIT(sdata->vif.bss_conf.chandef.width);
+
+ return radar_detect;
+}
+
int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
const struct cfg80211_chan_def *chandef,
enum ieee80211_chanctx_mode chanmode,
@@ -2976,8 +3005,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
list_for_each_entry(ctx, &local->chanctx_list, list) {
if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
continue;
- if (ctx->conf.radar_enabled)
- radar_detect |= BIT(ctx->conf.def.width);
+ radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
num_different_channels++;
continue;
@@ -3039,8 +3067,7 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
num_different_channels++;
- if (ctx->conf.radar_enabled)
- radar_detect |= BIT(ctx->conf.def.width);
+ radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
}
list_for_each_entry_rcu(sdata, &local->interfaces, list)