aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c13
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/nl80211.c62
-rw-r--r--net/wireless/nl80211.h5
-rw-r--r--net/wireless/reg.c116
5 files changed, 153 insertions, 46 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index dd7f222919fe..17fe39049740 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -350,7 +350,7 @@ int wiphy_register(struct wiphy *wiphy)
350 mutex_lock(&cfg80211_mutex); 350 mutex_lock(&cfg80211_mutex);
351 351
352 /* set up regulatory info */ 352 /* set up regulatory info */
353 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE); 353 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
354 354
355 res = device_add(&drv->wiphy.dev); 355 res = device_add(&drv->wiphy.dev);
356 if (res) 356 if (res)
@@ -365,6 +365,17 @@ int wiphy_register(struct wiphy *wiphy)
365 if (IS_ERR(drv->wiphy.debugfsdir)) 365 if (IS_ERR(drv->wiphy.debugfsdir))
366 drv->wiphy.debugfsdir = NULL; 366 drv->wiphy.debugfsdir = NULL;
367 367
368 if (wiphy->custom_regulatory) {
369 struct regulatory_request request;
370
371 request.wiphy_idx = get_wiphy_idx(wiphy);
372 request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
373 request.alpha2[0] = '9';
374 request.alpha2[1] = '9';
375
376 nl80211_send_reg_change_event(&request);
377 }
378
368 res = 0; 379 res = 0;
369out_unlock: 380out_unlock:
370 mutex_unlock(&cfg80211_mutex); 381 mutex_unlock(&cfg80211_mutex);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f6c53f5807f4..6acd483a61f8 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -136,7 +136,8 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
136 char *newname); 136 char *newname);
137 137
138void ieee80211_set_bitrate_flags(struct wiphy *wiphy); 138void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
139void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby); 139void wiphy_update_regulatory(struct wiphy *wiphy,
140 enum nl80211_reg_initiator setby);
140 141
141void cfg80211_bss_expire(struct cfg80211_registered_device *dev); 142void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
142void cfg80211_bss_age(struct cfg80211_registered_device *dev, 143void cfg80211_bss_age(struct cfg80211_registered_device *dev,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 531bb67cf502..8ac3d26014a8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2739,6 +2739,9 @@ static struct genl_multicast_group nl80211_config_mcgrp = {
2739static struct genl_multicast_group nl80211_scan_mcgrp = { 2739static struct genl_multicast_group nl80211_scan_mcgrp = {
2740 .name = "scan", 2740 .name = "scan",
2741}; 2741};
2742static struct genl_multicast_group nl80211_regulatory_mcgrp = {
2743 .name = "regulatory",
2744};
2742 2745
2743/* notification functions */ 2746/* notification functions */
2744 2747
@@ -2818,6 +2821,61 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
2818 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 2821 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
2819} 2822}
2820 2823
2824/*
2825 * This can happen on global regulatory changes or device specific settings
2826 * based on custom world regulatory domains.
2827 */
2828void nl80211_send_reg_change_event(struct regulatory_request *request)
2829{
2830 struct sk_buff *msg;
2831 void *hdr;
2832
2833 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2834 if (!msg)
2835 return;
2836
2837 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
2838 if (!hdr) {
2839 nlmsg_free(msg);
2840 return;
2841 }
2842
2843 /* Userspace can always count this one always being set */
2844 NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);
2845
2846 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
2847 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2848 NL80211_REGDOM_TYPE_WORLD);
2849 else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
2850 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2851 NL80211_REGDOM_TYPE_CUSTOM_WORLD);
2852 else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
2853 request->intersect)
2854 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2855 NL80211_REGDOM_TYPE_INTERSECTION);
2856 else {
2857 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2858 NL80211_REGDOM_TYPE_COUNTRY);
2859 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
2860 }
2861
2862 if (wiphy_idx_valid(request->wiphy_idx))
2863 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
2864
2865 if (genlmsg_end(msg, hdr) < 0) {
2866 nlmsg_free(msg);
2867 return;
2868 }
2869
2870 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL);
2871
2872 return;
2873
2874nla_put_failure:
2875 genlmsg_cancel(msg, hdr);
2876 nlmsg_free(msg);
2877}
2878
2821/* initialisation/exit functions */ 2879/* initialisation/exit functions */
2822 2880
2823int nl80211_init(void) 2881int nl80211_init(void)
@@ -2842,6 +2900,10 @@ int nl80211_init(void)
2842 if (err) 2900 if (err)
2843 goto err_out; 2901 goto err_out;
2844 2902
2903 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
2904 if (err)
2905 goto err_out;
2906
2845 return 0; 2907 return 0;
2846 err_out: 2908 err_out:
2847 genl_unregister_family(&nl80211_fam); 2909 genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 69787b621365..e65a3c38c52f 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -11,6 +11,7 @@ extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
11 struct net_device *netdev); 11 struct net_device *netdev);
12extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 12extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
13 struct net_device *netdev); 13 struct net_device *netdev);
14extern void nl80211_send_reg_change_event(struct regulatory_request *request);
14#else 15#else
15static inline int nl80211_init(void) 16static inline int nl80211_init(void)
16{ 17{
@@ -31,6 +32,10 @@ static inline void nl80211_send_scan_aborted(
31 struct cfg80211_registered_device *rdev, 32 struct cfg80211_registered_device *rdev,
32 struct net_device *netdev) 33 struct net_device *netdev)
33{} 34{}
35static inline void
36nl80211_send_reg_change_event(struct regulatory_request *request)
37{
38}
34#endif /* CONFIG_NL80211 */ 39#endif /* CONFIG_NL80211 */
35 40
36#endif /* __NET_WIRELESS_NL80211_H */ 41#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 58df98f10990..eb8b8ed16155 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -41,6 +41,7 @@
41#include <net/cfg80211.h> 41#include <net/cfg80211.h>
42#include "core.h" 42#include "core.h"
43#include "reg.h" 43#include "reg.h"
44#include "nl80211.h"
44 45
45/* Receipt of information from last regulatory request */ 46/* Receipt of information from last regulatory request */
46static struct regulatory_request *last_request; 47static struct regulatory_request *last_request;
@@ -86,20 +87,31 @@ struct reg_beacon {
86 87
87/* We keep a static world regulatory domain in case of the absence of CRDA */ 88/* We keep a static world regulatory domain in case of the absence of CRDA */
88static const struct ieee80211_regdomain world_regdom = { 89static const struct ieee80211_regdomain world_regdom = {
89 .n_reg_rules = 3, 90 .n_reg_rules = 5,
90 .alpha2 = "00", 91 .alpha2 = "00",
91 .reg_rules = { 92 .reg_rules = {
92 /* IEEE 802.11b/g, channels 1..11 */ 93 /* IEEE 802.11b/g, channels 1..11 */
93 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), 94 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
94 /* IEEE 802.11a, channel 36..48 */ 95 /* IEEE 802.11b/g, channels 12..13. No HT40
95 REG_RULE(5180-10, 5240+10, 40, 6, 23, 96 * channel fits here. */
97 REG_RULE(2467-10, 2472+10, 20, 6, 20,
96 NL80211_RRF_PASSIVE_SCAN | 98 NL80211_RRF_PASSIVE_SCAN |
97 NL80211_RRF_NO_IBSS), 99 NL80211_RRF_NO_IBSS),
100 /* IEEE 802.11 channel 14 - Only JP enables
101 * this and for 802.11b only */
102 REG_RULE(2484-10, 2484+10, 20, 6, 20,
103 NL80211_RRF_PASSIVE_SCAN |
104 NL80211_RRF_NO_IBSS |
105 NL80211_RRF_NO_OFDM),
106 /* IEEE 802.11a, channel 36..48 */
107 REG_RULE(5180-10, 5240+10, 40, 6, 20,
108 NL80211_RRF_PASSIVE_SCAN |
109 NL80211_RRF_NO_IBSS),
98 110
99 /* NB: 5260 MHz - 5700 MHz requies DFS */ 111 /* NB: 5260 MHz - 5700 MHz requies DFS */
100 112
101 /* IEEE 802.11a, channel 149..165 */ 113 /* IEEE 802.11a, channel 149..165 */
102 REG_RULE(5745-10, 5825+10, 40, 6, 23, 114 REG_RULE(5745-10, 5825+10, 40, 6, 20,
103 NL80211_RRF_PASSIVE_SCAN | 115 NL80211_RRF_PASSIVE_SCAN |
104 NL80211_RRF_NO_IBSS), 116 NL80211_RRF_NO_IBSS),
105 } 117 }
@@ -846,8 +858,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
846 * Follow the driver's regulatory domain, if present, unless a country 858 * Follow the driver's regulatory domain, if present, unless a country
847 * IE has been processed or a user wants to help complaince further 859 * IE has been processed or a user wants to help complaince further
848 */ 860 */
849 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE && 861 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
850 last_request->initiator != REGDOM_SET_BY_USER && 862 last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
851 wiphy->regd) 863 wiphy->regd)
852 regd = wiphy->regd; 864 regd = wiphy->regd;
853 865
@@ -932,7 +944,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
932 * http://tinyurl.com/11d-clarification 944 * http://tinyurl.com/11d-clarification
933 */ 945 */
934 if (r == -ERANGE && 946 if (r == -ERANGE &&
935 last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 947 last_request->initiator ==
948 NL80211_REGDOM_SET_BY_COUNTRY_IE) {
936#ifdef CONFIG_CFG80211_REG_DEBUG 949#ifdef CONFIG_CFG80211_REG_DEBUG
937 printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz " 950 printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
938 "intact on %s - no rule found in band on " 951 "intact on %s - no rule found in band on "
@@ -945,7 +958,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
945 * for the band so we respect its band definitions 958 * for the band so we respect its band definitions
946 */ 959 */
947#ifdef CONFIG_CFG80211_REG_DEBUG 960#ifdef CONFIG_CFG80211_REG_DEBUG
948 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) 961 if (last_request->initiator ==
962 NL80211_REGDOM_SET_BY_COUNTRY_IE)
949 printk(KERN_DEBUG "cfg80211: Disabling " 963 printk(KERN_DEBUG "cfg80211: Disabling "
950 "channel %d MHz on %s due to " 964 "channel %d MHz on %s due to "
951 "Country IE\n", 965 "Country IE\n",
@@ -959,7 +973,7 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
959 973
960 power_rule = &reg_rule->power_rule; 974 power_rule = &reg_rule->power_rule;
961 975
962 if (last_request->initiator == REGDOM_SET_BY_DRIVER && 976 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
963 request_wiphy && request_wiphy == wiphy && 977 request_wiphy && request_wiphy == wiphy &&
964 request_wiphy->strict_regulatory) { 978 request_wiphy->strict_regulatory) {
965 /* 979 /*
@@ -1000,11 +1014,12 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
1000 handle_channel(wiphy, band, i); 1014 handle_channel(wiphy, band, i);
1001} 1015}
1002 1016
1003static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby) 1017static bool ignore_reg_update(struct wiphy *wiphy,
1018 enum nl80211_reg_initiator initiator)
1004{ 1019{
1005 if (!last_request) 1020 if (!last_request)
1006 return true; 1021 return true;
1007 if (setby == REGDOM_SET_BY_CORE && 1022 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
1008 wiphy->custom_regulatory) 1023 wiphy->custom_regulatory)
1009 return true; 1024 return true;
1010 /* 1025 /*
@@ -1017,12 +1032,12 @@ static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
1017 return false; 1032 return false;
1018} 1033}
1019 1034
1020static void update_all_wiphy_regulatory(enum reg_set_by setby) 1035static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
1021{ 1036{
1022 struct cfg80211_registered_device *drv; 1037 struct cfg80211_registered_device *drv;
1023 1038
1024 list_for_each_entry(drv, &cfg80211_drv_list, list) 1039 list_for_each_entry(drv, &cfg80211_drv_list, list)
1025 wiphy_update_regulatory(&drv->wiphy, setby); 1040 wiphy_update_regulatory(&drv->wiphy, initiator);
1026} 1041}
1027 1042
1028static void handle_reg_beacon(struct wiphy *wiphy, 1043static void handle_reg_beacon(struct wiphy *wiphy,
@@ -1113,7 +1128,7 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
1113 if (is_world_regdom(cfg80211_regdomain->alpha2) || 1128 if (is_world_regdom(cfg80211_regdomain->alpha2) ||
1114 (wiphy->regd && is_world_regdom(wiphy->regd->alpha2))) 1129 (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
1115 return true; 1130 return true;
1116 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE && 1131 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1117 wiphy->custom_regulatory) 1132 wiphy->custom_regulatory)
1118 return true; 1133 return true;
1119 return false; 1134 return false;
@@ -1127,11 +1142,12 @@ static void reg_process_beacons(struct wiphy *wiphy)
1127 wiphy_update_beacon_reg(wiphy); 1142 wiphy_update_beacon_reg(wiphy);
1128} 1143}
1129 1144
1130void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby) 1145void wiphy_update_regulatory(struct wiphy *wiphy,
1146 enum nl80211_reg_initiator initiator)
1131{ 1147{
1132 enum ieee80211_band band; 1148 enum ieee80211_band band;
1133 1149
1134 if (ignore_reg_update(wiphy, setby)) 1150 if (ignore_reg_update(wiphy, initiator))
1135 goto out; 1151 goto out;
1136 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1152 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1137 if (wiphy->bands[band]) 1153 if (wiphy->bands[band])
@@ -1244,17 +1260,16 @@ static int ignore_request(struct wiphy *wiphy,
1244 return 0; 1260 return 0;
1245 1261
1246 switch (pending_request->initiator) { 1262 switch (pending_request->initiator) {
1247 case REGDOM_SET_BY_INIT: 1263 case NL80211_REGDOM_SET_BY_CORE:
1248 return -EINVAL; 1264 return -EINVAL;
1249 case REGDOM_SET_BY_CORE: 1265 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1250 return -EINVAL;
1251 case REGDOM_SET_BY_COUNTRY_IE:
1252 1266
1253 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 1267 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1254 1268
1255 if (unlikely(!is_an_alpha2(pending_request->alpha2))) 1269 if (unlikely(!is_an_alpha2(pending_request->alpha2)))
1256 return -EINVAL; 1270 return -EINVAL;
1257 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 1271 if (last_request->initiator ==
1272 NL80211_REGDOM_SET_BY_COUNTRY_IE) {
1258 if (last_wiphy != wiphy) { 1273 if (last_wiphy != wiphy) {
1259 /* 1274 /*
1260 * Two cards with two APs claiming different 1275 * Two cards with two APs claiming different
@@ -1275,8 +1290,8 @@ static int ignore_request(struct wiphy *wiphy,
1275 return -EALREADY; 1290 return -EALREADY;
1276 } 1291 }
1277 return REG_INTERSECT; 1292 return REG_INTERSECT;
1278 case REGDOM_SET_BY_DRIVER: 1293 case NL80211_REGDOM_SET_BY_DRIVER:
1279 if (last_request->initiator == REGDOM_SET_BY_CORE) { 1294 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
1280 if (is_old_static_regdom(cfg80211_regdomain)) 1295 if (is_old_static_regdom(cfg80211_regdomain))
1281 return 0; 1296 return 0;
1282 if (regdom_changes(pending_request->alpha2)) 1297 if (regdom_changes(pending_request->alpha2))
@@ -1289,28 +1304,28 @@ static int ignore_request(struct wiphy *wiphy,
1289 * back in or if you add a new device for which the previously 1304 * back in or if you add a new device for which the previously
1290 * loaded card also agrees on the regulatory domain. 1305 * loaded card also agrees on the regulatory domain.
1291 */ 1306 */
1292 if (last_request->initiator == REGDOM_SET_BY_DRIVER && 1307 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1293 !regdom_changes(pending_request->alpha2)) 1308 !regdom_changes(pending_request->alpha2))
1294 return -EALREADY; 1309 return -EALREADY;
1295 1310
1296 return REG_INTERSECT; 1311 return REG_INTERSECT;
1297 case REGDOM_SET_BY_USER: 1312 case NL80211_REGDOM_SET_BY_USER:
1298 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) 1313 if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
1299 return REG_INTERSECT; 1314 return REG_INTERSECT;
1300 /* 1315 /*
1301 * If the user knows better the user should set the regdom 1316 * If the user knows better the user should set the regdom
1302 * to their country before the IE is picked up 1317 * to their country before the IE is picked up
1303 */ 1318 */
1304 if (last_request->initiator == REGDOM_SET_BY_USER && 1319 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER &&
1305 last_request->intersect) 1320 last_request->intersect)
1306 return -EOPNOTSUPP; 1321 return -EOPNOTSUPP;
1307 /* 1322 /*
1308 * Process user requests only after previous user/driver/core 1323 * Process user requests only after previous user/driver/core
1309 * requests have been processed 1324 * requests have been processed
1310 */ 1325 */
1311 if (last_request->initiator == REGDOM_SET_BY_CORE || 1326 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE ||
1312 last_request->initiator == REGDOM_SET_BY_DRIVER || 1327 last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
1313 last_request->initiator == REGDOM_SET_BY_USER) { 1328 last_request->initiator == NL80211_REGDOM_SET_BY_USER) {
1314 if (regdom_changes(last_request->alpha2)) 1329 if (regdom_changes(last_request->alpha2))
1315 return -EAGAIN; 1330 return -EAGAIN;
1316 } 1331 }
@@ -1350,7 +1365,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
1350 r = ignore_request(wiphy, pending_request); 1365 r = ignore_request(wiphy, pending_request);
1351 1366
1352 if (r == REG_INTERSECT) { 1367 if (r == REG_INTERSECT) {
1353 if (pending_request->initiator == REGDOM_SET_BY_DRIVER) { 1368 if (pending_request->initiator ==
1369 NL80211_REGDOM_SET_BY_DRIVER) {
1354 r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain); 1370 r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain);
1355 if (r) { 1371 if (r) {
1356 kfree(pending_request); 1372 kfree(pending_request);
@@ -1365,7 +1381,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
1365 * wiphy 1381 * wiphy
1366 */ 1382 */
1367 if (r == -EALREADY && 1383 if (r == -EALREADY &&
1368 pending_request->initiator == REGDOM_SET_BY_DRIVER) { 1384 pending_request->initiator ==
1385 NL80211_REGDOM_SET_BY_DRIVER) {
1369 r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain); 1386 r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain);
1370 if (r) { 1387 if (r) {
1371 kfree(pending_request); 1388 kfree(pending_request);
@@ -1387,8 +1404,16 @@ new_request:
1387 pending_request = NULL; 1404 pending_request = NULL;
1388 1405
1389 /* When r == REG_INTERSECT we do need to call CRDA */ 1406 /* When r == REG_INTERSECT we do need to call CRDA */
1390 if (r < 0) 1407 if (r < 0) {
1408 /*
1409 * Since CRDA will not be called in this case as we already
1410 * have applied the requested regulatory domain before we just
1411 * inform userspace we have processed the request
1412 */
1413 if (r == -EALREADY)
1414 nl80211_send_reg_change_event(last_request);
1391 return r; 1415 return r;
1416 }
1392 1417
1393 /* 1418 /*
1394 * Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled 1419 * Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled
@@ -1416,7 +1441,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1416 if (wiphy_idx_valid(reg_request->wiphy_idx)) 1441 if (wiphy_idx_valid(reg_request->wiphy_idx))
1417 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); 1442 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
1418 1443
1419 if (reg_request->initiator == REGDOM_SET_BY_DRIVER && 1444 if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1420 !wiphy) { 1445 !wiphy) {
1421 kfree(reg_request); 1446 kfree(reg_request);
1422 goto out; 1447 goto out;
@@ -1430,7 +1455,7 @@ out:
1430 mutex_unlock(&cfg80211_mutex); 1455 mutex_unlock(&cfg80211_mutex);
1431} 1456}
1432 1457
1433/* Processes regulatory hints, this is all the REGDOM_SET_BY_* */ 1458/* Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* */
1434static void reg_process_pending_hints(void) 1459static void reg_process_pending_hints(void)
1435 { 1460 {
1436 struct regulatory_request *reg_request; 1461 struct regulatory_request *reg_request;
@@ -1514,7 +1539,7 @@ static int regulatory_hint_core(const char *alpha2)
1514 1539
1515 request->alpha2[0] = alpha2[0]; 1540 request->alpha2[0] = alpha2[0];
1516 request->alpha2[1] = alpha2[1]; 1541 request->alpha2[1] = alpha2[1];
1517 request->initiator = REGDOM_SET_BY_CORE; 1542 request->initiator = NL80211_REGDOM_SET_BY_CORE;
1518 1543
1519 queue_regulatory_request(request); 1544 queue_regulatory_request(request);
1520 1545
@@ -1535,7 +1560,7 @@ int regulatory_hint_user(const char *alpha2)
1535 request->wiphy_idx = WIPHY_IDX_STALE; 1560 request->wiphy_idx = WIPHY_IDX_STALE;
1536 request->alpha2[0] = alpha2[0]; 1561 request->alpha2[0] = alpha2[0];
1537 request->alpha2[1] = alpha2[1]; 1562 request->alpha2[1] = alpha2[1];
1538 request->initiator = REGDOM_SET_BY_USER, 1563 request->initiator = NL80211_REGDOM_SET_BY_USER,
1539 1564
1540 queue_regulatory_request(request); 1565 queue_regulatory_request(request);
1541 1566
@@ -1561,7 +1586,7 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1561 1586
1562 request->alpha2[0] = alpha2[0]; 1587 request->alpha2[0] = alpha2[0];
1563 request->alpha2[1] = alpha2[1]; 1588 request->alpha2[1] = alpha2[1];
1564 request->initiator = REGDOM_SET_BY_DRIVER; 1589 request->initiator = NL80211_REGDOM_SET_BY_DRIVER;
1565 1590
1566 queue_regulatory_request(request); 1591 queue_regulatory_request(request);
1567 1592
@@ -1710,7 +1735,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1710 request->wiphy_idx = get_wiphy_idx(wiphy); 1735 request->wiphy_idx = get_wiphy_idx(wiphy);
1711 request->alpha2[0] = rd->alpha2[0]; 1736 request->alpha2[0] = rd->alpha2[0];
1712 request->alpha2[1] = rd->alpha2[1]; 1737 request->alpha2[1] = rd->alpha2[1];
1713 request->initiator = REGDOM_SET_BY_COUNTRY_IE; 1738 request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE;
1714 request->country_ie_checksum = checksum; 1739 request->country_ie_checksum = checksum;
1715 request->country_ie_env = env; 1740 request->country_ie_env = env;
1716 1741
@@ -1818,7 +1843,8 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1818 1843
1819 if (is_intersected_alpha2(rd->alpha2)) { 1844 if (is_intersected_alpha2(rd->alpha2)) {
1820 1845
1821 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 1846 if (last_request->initiator ==
1847 NL80211_REGDOM_SET_BY_COUNTRY_IE) {
1822 struct cfg80211_registered_device *drv; 1848 struct cfg80211_registered_device *drv;
1823 drv = cfg80211_drv_by_wiphy_idx( 1849 drv = cfg80211_drv_by_wiphy_idx(
1824 last_request->wiphy_idx); 1850 last_request->wiphy_idx);
@@ -1910,7 +1936,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1910 * rd is non static (it means CRDA was present and was used last) 1936 * rd is non static (it means CRDA was present and was used last)
1911 * and the pending request came in from a country IE 1937 * and the pending request came in from a country IE
1912 */ 1938 */
1913 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) { 1939 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
1914 /* 1940 /*
1915 * If someone else asked us to change the rd lets only bother 1941 * If someone else asked us to change the rd lets only bother
1916 * checking if the alpha2 changes if CRDA was already called 1942 * checking if the alpha2 changes if CRDA was already called
@@ -1942,7 +1968,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1942 if (!last_request->intersect) { 1968 if (!last_request->intersect) {
1943 int r; 1969 int r;
1944 1970
1945 if (last_request->initiator != REGDOM_SET_BY_DRIVER) { 1971 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
1946 reset_regdomains(); 1972 reset_regdomains();
1947 cfg80211_regdomain = rd; 1973 cfg80211_regdomain = rd;
1948 return 0; 1974 return 0;
@@ -1966,7 +1992,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1966 1992
1967 /* Intersection requires a bit more work */ 1993 /* Intersection requires a bit more work */
1968 1994
1969 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) { 1995 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
1970 1996
1971 intersected_rd = regdom_intersect(rd, cfg80211_regdomain); 1997 intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
1972 if (!intersected_rd) 1998 if (!intersected_rd)
@@ -1977,7 +2003,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1977 * However if a driver requested this specific regulatory 2003 * However if a driver requested this specific regulatory
1978 * domain we keep it for its private use 2004 * domain we keep it for its private use
1979 */ 2005 */
1980 if (last_request->initiator == REGDOM_SET_BY_DRIVER) 2006 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
1981 request_wiphy->regd = rd; 2007 request_wiphy->regd = rd;
1982 else 2008 else
1983 kfree(rd); 2009 kfree(rd);
@@ -2067,6 +2093,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2067 2093
2068 print_regdomain(cfg80211_regdomain); 2094 print_regdomain(cfg80211_regdomain);
2069 2095
2096 nl80211_send_reg_change_event(last_request);
2097
2070 return r; 2098 return r;
2071} 2099}
2072 2100