aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h2
-rw-r--r--include/uapi/linux/nl80211.h3
-rw-r--r--net/wireless/nl80211.c6
-rw-r--r--net/wireless/util.c14
4 files changed, 23 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5c7169b0ac57..e3a48b0a2b3b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2638,6 +2638,7 @@ struct ieee80211_iface_limit {
2638 * between infrastructure and AP types must match. This is required 2638 * between infrastructure and AP types must match. This is required
2639 * only in special cases. 2639 * only in special cases.
2640 * @radar_detect_widths: bitmap of channel widths supported for radar detection 2640 * @radar_detect_widths: bitmap of channel widths supported for radar detection
2641 * @radar_detect_regions: bitmap of regions supported for radar detection
2641 * 2642 *
2642 * With this structure the driver can describe which interface 2643 * With this structure the driver can describe which interface
2643 * combinations it supports concurrently. 2644 * combinations it supports concurrently.
@@ -2695,6 +2696,7 @@ struct ieee80211_iface_combination {
2695 u8 n_limits; 2696 u8 n_limits;
2696 bool beacon_int_infra_match; 2697 bool beacon_int_infra_match;
2697 u8 radar_detect_widths; 2698 u8 radar_detect_widths;
2699 u8 radar_detect_regions;
2698}; 2700};
2699 2701
2700struct ieee80211_txrx_stypes { 2702struct ieee80211_txrx_stypes {
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 406010d4def0..b65095a85dee 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3688,6 +3688,8 @@ enum nl80211_iface_limit_attrs {
3688 * different channels may be used within this group. 3688 * different channels may be used within this group.
3689 * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap 3689 * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
3690 * of supported channel widths for radar detection. 3690 * of supported channel widths for radar detection.
3691 * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
3692 * of supported regulatory regions for radar detection.
3691 * @NUM_NL80211_IFACE_COMB: number of attributes 3693 * @NUM_NL80211_IFACE_COMB: number of attributes
3692 * @MAX_NL80211_IFACE_COMB: highest attribute number 3694 * @MAX_NL80211_IFACE_COMB: highest attribute number
3693 * 3695 *
@@ -3721,6 +3723,7 @@ enum nl80211_if_combination_attrs {
3721 NL80211_IFACE_COMB_STA_AP_BI_MATCH, 3723 NL80211_IFACE_COMB_STA_AP_BI_MATCH,
3722 NL80211_IFACE_COMB_NUM_CHANNELS, 3724 NL80211_IFACE_COMB_NUM_CHANNELS,
3723 NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, 3725 NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
3726 NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
3724 3727
3725 /* keep last */ 3728 /* keep last */
3726 NUM_NL80211_IFACE_COMB, 3729 NUM_NL80211_IFACE_COMB,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0f1b18f209d6..c0833830cfe7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -970,8 +970,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
970 c->max_interfaces)) 970 c->max_interfaces))
971 goto nla_put_failure; 971 goto nla_put_failure;
972 if (large && 972 if (large &&
973 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, 973 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
974 c->radar_detect_widths)) 974 c->radar_detect_widths) ||
975 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
976 c->radar_detect_regions)))
975 goto nla_put_failure; 977 goto nla_put_failure;
976 978
977 nla_nest_end(msg, nl_combi); 979 nla_nest_end(msg, nl_combi);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index a756429b3a0a..8c61d5c6fad3 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1274,10 +1274,20 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
1274 void *data), 1274 void *data),
1275 void *data) 1275 void *data)
1276{ 1276{
1277 const struct ieee80211_regdomain *regdom;
1278 enum nl80211_dfs_regions region = 0;
1277 int i, j, iftype; 1279 int i, j, iftype;
1278 int num_interfaces = 0; 1280 int num_interfaces = 0;
1279 u32 used_iftypes = 0; 1281 u32 used_iftypes = 0;
1280 1282
1283 if (radar_detect) {
1284 rcu_read_lock();
1285 regdom = rcu_dereference(cfg80211_regdomain);
1286 if (regdom)
1287 region = regdom->dfs_region;
1288 rcu_read_unlock();
1289 }
1290
1281 for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { 1291 for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
1282 num_interfaces += iftype_num[iftype]; 1292 num_interfaces += iftype_num[iftype];
1283 if (iftype_num[iftype] > 0 && 1293 if (iftype_num[iftype] > 0 &&
@@ -1318,6 +1328,10 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
1318 if (radar_detect != (c->radar_detect_widths & radar_detect)) 1328 if (radar_detect != (c->radar_detect_widths & radar_detect))
1319 goto cont; 1329 goto cont;
1320 1330
1331 if (radar_detect && c->radar_detect_regions &&
1332 !(c->radar_detect_regions & BIT(region)))
1333 goto cont;
1334
1321 /* Finally check that all iftypes that we're currently 1335 /* Finally check that all iftypes that we're currently
1322 * using are actually part of this combination. If they 1336 * using are actually part of this combination. If they
1323 * aren't then we can't use this combination and have 1337 * aren't then we can't use this combination and have