cfg80211: allow restricting supported dfs regions

At the moment, the ath9k/ath10k DFS module only supports detecting ETSI
radar patterns.
Add a bitmap in the interface combinations, indicating which DFS regions
are supported by the detector. If unset, support for all regions is
assumed.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Felix Fietkau 2014-05-05 11:48:40 +02:00 committed by Johannes Berg
parent f6837ba8c9
commit 8c48b50a1a
4 changed files with 23 additions and 2 deletions

View File

@ -2638,6 +2638,7 @@ struct ieee80211_iface_limit {
* between infrastructure and AP types must match. This is required * between infrastructure and AP types must match. This is required
* only in special cases. * only in special cases.
* @radar_detect_widths: bitmap of channel widths supported for radar detection * @radar_detect_widths: bitmap of channel widths supported for radar detection
* @radar_detect_regions: bitmap of regions supported for radar detection
* *
* With this structure the driver can describe which interface * With this structure the driver can describe which interface
* combinations it supports concurrently. * combinations it supports concurrently.
@ -2695,6 +2696,7 @@ struct ieee80211_iface_combination {
u8 n_limits; u8 n_limits;
bool beacon_int_infra_match; bool beacon_int_infra_match;
u8 radar_detect_widths; u8 radar_detect_widths;
u8 radar_detect_regions;
}; };
struct ieee80211_txrx_stypes { struct ieee80211_txrx_stypes {

View File

@ -3688,6 +3688,8 @@ enum nl80211_iface_limit_attrs {
* different channels may be used within this group. * different channels may be used within this group.
* @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
* of supported channel widths for radar detection. * of supported channel widths for radar detection.
* @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
* of supported regulatory regions for radar detection.
* @NUM_NL80211_IFACE_COMB: number of attributes * @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number * @MAX_NL80211_IFACE_COMB: highest attribute number
* *
@ -3721,6 +3723,7 @@ enum nl80211_if_combination_attrs {
NL80211_IFACE_COMB_STA_AP_BI_MATCH, NL80211_IFACE_COMB_STA_AP_BI_MATCH,
NL80211_IFACE_COMB_NUM_CHANNELS, NL80211_IFACE_COMB_NUM_CHANNELS,
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
/* keep last */ /* keep last */
NUM_NL80211_IFACE_COMB, NUM_NL80211_IFACE_COMB,

View File

@ -970,8 +970,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
c->max_interfaces)) c->max_interfaces))
goto nla_put_failure; goto nla_put_failure;
if (large && if (large &&
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
c->radar_detect_widths)) c->radar_detect_widths) ||
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
c->radar_detect_regions)))
goto nla_put_failure; goto nla_put_failure;
nla_nest_end(msg, nl_combi); nla_nest_end(msg, nl_combi);

View File

@ -1274,10 +1274,20 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
void *data), void *data),
void *data) void *data)
{ {
const struct ieee80211_regdomain *regdom;
enum nl80211_dfs_regions region = 0;
int i, j, iftype; int i, j, iftype;
int num_interfaces = 0; int num_interfaces = 0;
u32 used_iftypes = 0; u32 used_iftypes = 0;
if (radar_detect) {
rcu_read_lock();
regdom = rcu_dereference(cfg80211_regdomain);
if (regdom)
region = regdom->dfs_region;
rcu_read_unlock();
}
for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
num_interfaces += iftype_num[iftype]; num_interfaces += iftype_num[iftype];
if (iftype_num[iftype] > 0 && if (iftype_num[iftype] > 0 &&
@ -1318,6 +1328,10 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
if (radar_detect != (c->radar_detect_widths & radar_detect)) if (radar_detect != (c->radar_detect_widths & radar_detect))
goto cont; goto cont;
if (radar_detect && c->radar_detect_regions &&
!(c->radar_detect_regions & BIT(region)))
goto cont;
/* Finally check that all iftypes that we're currently /* Finally check that all iftypes that we're currently
* using are actually part of this combination. If they * using are actually part of this combination. If they
* aren't then we can't use this combination and have * aren't then we can't use this combination and have