cfg80211/mac80211: move interface counting for combination check to mac80211
Move the counting part of the interface combination check from cfg80211 to mac80211. This is needed to simplify locking when the driver has to perform a combination check by itself (eg. with channel-switch). Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:

committed by
Johannes Berg

parent
2beb6dab2d
commit
73de86a389
@@ -2797,3 +2797,75 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local,
|
||||
|
||||
ps->dtim_count = dtim_count;
|
||||
}
|
||||
|
||||
int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
enum ieee80211_chanctx_mode chanmode,
|
||||
u8 radar_detect)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *sdata_iter;
|
||||
enum nl80211_iftype iftype = sdata->wdev.iftype;
|
||||
int num[NUM_NL80211_IFTYPES];
|
||||
struct ieee80211_chanctx *ctx;
|
||||
int num_different_channels = 1;
|
||||
int total = 1;
|
||||
|
||||
lockdep_assert_held(&local->chanctx_mtx);
|
||||
|
||||
if (WARN_ON(hweight32(radar_detect) > 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(chanmode == IEEE80211_CHANCTX_SHARED && !chandef->chan))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
|
||||
return -EINVAL;
|
||||
|
||||
/* Always allow software iftypes */
|
||||
if (local->hw.wiphy->software_iftypes & BIT(iftype)) {
|
||||
if (radar_detect)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(num, 0, sizeof(num));
|
||||
|
||||
if (iftype != NL80211_IFTYPE_UNSPECIFIED)
|
||||
num[iftype] = 1;
|
||||
|
||||
list_for_each_entry(ctx, &local->chanctx_list, list) {
|
||||
if (ctx->conf.radar_enabled)
|
||||
radar_detect |= BIT(ctx->conf.def.width);
|
||||
if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
|
||||
num_different_channels++;
|
||||
continue;
|
||||
}
|
||||
if ((chanmode == IEEE80211_CHANCTX_SHARED) &&
|
||||
cfg80211_chandef_compatible(chandef,
|
||||
&ctx->conf.def))
|
||||
continue;
|
||||
num_different_channels++;
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) {
|
||||
struct wireless_dev *wdev_iter;
|
||||
|
||||
wdev_iter = &sdata_iter->wdev;
|
||||
|
||||
if (sdata_iter == sdata ||
|
||||
rcu_access_pointer(sdata_iter->vif.chanctx_conf) == NULL ||
|
||||
local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype))
|
||||
continue;
|
||||
|
||||
num[wdev_iter->iftype]++;
|
||||
total++;
|
||||
}
|
||||
|
||||
if (total == 1 && !radar_detect)
|
||||
return 0;
|
||||
|
||||
return cfg80211_check_combinations(local->hw.wiphy,
|
||||
num_different_channels,
|
||||
radar_detect, num);
|
||||
}
|
||||
|
Reference in New Issue
Block a user