diff options
-rw-r--r-- | include/net/cfg80211.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 6 | ||||
-rw-r--r-- | net/wireless/util.c | 14 |
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 | ||
2700 | struct ieee80211_txrx_stypes { | 2702 | struct 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 |