aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-17 18:04:31 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-17 18:04:31 -0400
commitaf4330631cd48987755f1a8d324dc318f60cf16b (patch)
tree3c9233e81b450921326da13a7f8abacb58ab1f5e /net
parent2d6a5e9500103680464a723a4564961675652680 (diff)
parent808ff697b357cee54e214efd27921a9ec6461a94 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c16
-rw-r--r--net/mac80211/mlme.c38
-rw-r--r--net/mac80211/scan.c12
-rw-r--r--net/mac80211/wme.c9
-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
10 files changed, 206 insertions, 69 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ecbc8e0cb3e7..fbb91f1aebb2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -972,6 +972,7 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
972 char *ie, size_t len); 972 char *ie, size_t len);
973 973
974void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); 974void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
975void ieee80211_scan_failed(struct ieee80211_local *local);
975int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, 976int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
976 struct cfg80211_scan_request *req); 977 struct cfg80211_scan_request *req);
977struct ieee80211_bss * 978struct ieee80211_bss *
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 2acc416e77e1..f9f27b9cadbe 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -370,6 +370,18 @@ static int ieee80211_stop(struct net_device *dev)
370 rcu_read_unlock(); 370 rcu_read_unlock();
371 371
372 /* 372 /*
373 * Announce that we are leaving the network, in case we are a
374 * station interface type. This must be done before removing
375 * all stations associated with sta_info_flush, otherwise STA
376 * information will be gone and no announce being done.
377 */
378 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
379 if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
380 ieee80211_sta_deauthenticate(sdata,
381 WLAN_REASON_DEAUTH_LEAVING);
382 }
383
384 /*
373 * Remove all stations associated with this interface. 385 * Remove all stations associated with this interface.
374 * 386 *
375 * This must be done before calling ops->remove_interface() 387 * This must be done before calling ops->remove_interface()
@@ -454,10 +466,6 @@ static int ieee80211_stop(struct net_device *dev)
454 netif_addr_unlock_bh(local->mdev); 466 netif_addr_unlock_bh(local->mdev);
455 break; 467 break;
456 case NL80211_IFTYPE_STATION: 468 case NL80211_IFTYPE_STATION:
457 /* Announce that we are leaving the network. */
458 if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
459 ieee80211_sta_deauthenticate(sdata,
460 WLAN_REASON_DEAUTH_LEAVING);
461 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 469 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
462 del_timer_sync(&sdata->u.mgd.chswitch_timer); 470 del_timer_sync(&sdata->u.mgd.chswitch_timer);
463 del_timer_sync(&sdata->u.mgd.timer); 471 del_timer_sync(&sdata->u.mgd.timer);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 391445c6b892..841b8450b3de 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -417,9 +417,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
417 417
418 memset(&params, 0, sizeof(params)); 418 memset(&params, 0, sizeof(params));
419 419
420 if (!local->ops->conf_tx)
421 return;
422
423 local->wmm_acm = 0; 420 local->wmm_acm = 0;
424 for (; left >= 4; left -= 4, pos += 4) { 421 for (; left >= 4; left -= 4, pos += 4) {
425 int aci = (pos[0] >> 5) & 0x03; 422 int aci = (pos[0] >> 5) & 0x03;
@@ -427,26 +424,26 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
427 int queue; 424 int queue;
428 425
429 switch (aci) { 426 switch (aci) {
430 case 1: 427 case 1: /* AC_BK */
431 queue = 3; 428 queue = 3;
432 if (acm) 429 if (acm)
433 local->wmm_acm |= BIT(0) | BIT(3); 430 local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
434 break; 431 break;
435 case 2: 432 case 2: /* AC_VI */
436 queue = 1; 433 queue = 1;
437 if (acm) 434 if (acm)
438 local->wmm_acm |= BIT(4) | BIT(5); 435 local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
439 break; 436 break;
440 case 3: 437 case 3: /* AC_VO */
441 queue = 0; 438 queue = 0;
442 if (acm) 439 if (acm)
443 local->wmm_acm |= BIT(6) | BIT(7); 440 local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
444 break; 441 break;
445 case 0: 442 case 0: /* AC_BE */
446 default: 443 default:
447 queue = 2; 444 queue = 2;
448 if (acm) 445 if (acm)
449 local->wmm_acm |= BIT(1) | BIT(2); 446 local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
450 break; 447 break;
451 } 448 }
452 449
@@ -460,9 +457,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
460 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, 457 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
461 params.cw_max, params.txop); 458 params.cw_max, params.txop);
462#endif 459#endif
463 /* TODO: handle ACM (block TX, fallback to next lowest allowed 460 if (local->ops->conf_tx &&
464 * AC for now) */ 461 local->ops->conf_tx(local_to_hw(local), queue, &params)) {
465 if (local->ops->conf_tx(local_to_hw(local), queue, &params)) {
466 printk(KERN_DEBUG "%s: failed to set TX queue " 462 printk(KERN_DEBUG "%s: failed to set TX queue "
467 "parameters for queue %d\n", local->mdev->name, queue); 463 "parameters for queue %d\n", local->mdev->name, queue);
468 } 464 }
@@ -1724,7 +1720,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
1724 local->int_scan_req.ssids[0].ssid_len = 0; 1720 local->int_scan_req.ssids[0].ssid_len = 0;
1725 else 1721 else
1726 local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len; 1722 local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len;
1727 ieee80211_start_scan(sdata, &local->int_scan_req); 1723
1724 if (ieee80211_start_scan(sdata, &local->int_scan_req))
1725 ieee80211_scan_failed(local);
1726
1728 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE; 1727 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
1729 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); 1728 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
1730 } else { 1729 } else {
@@ -1761,7 +1760,14 @@ static void ieee80211_sta_work(struct work_struct *work)
1761 ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE && 1760 ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1762 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE && 1761 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE &&
1763 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) { 1762 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) {
1764 ieee80211_start_scan(sdata, local->scan_req); 1763 /*
1764 * The call to ieee80211_start_scan can fail but ieee80211_request_scan
1765 * (which queued ieee80211_sta_work) did not return an error. Thus, call
1766 * ieee80211_scan_failed here if ieee80211_start_scan fails in order to
1767 * notify the scan requester.
1768 */
1769 if (ieee80211_start_scan(sdata, local->scan_req))
1770 ieee80211_scan_failed(local);
1765 return; 1771 return;
1766 } 1772 }
1767 1773
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 0e81e1633a66..5030a3c87509 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -202,6 +202,18 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
202 return RX_QUEUED; 202 return RX_QUEUED;
203} 203}
204 204
205void ieee80211_scan_failed(struct ieee80211_local *local)
206{
207 if (WARN_ON(!local->scan_req))
208 return;
209
210 /* notify cfg80211 about the failed scan */
211 if (local->scan_req != &local->int_scan_req)
212 cfg80211_scan_done(local->scan_req, true);
213
214 local->scan_req = NULL;
215}
216
205void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 217void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
206{ 218{
207 struct ieee80211_local *local = hw_to_local(hw); 219 struct ieee80211_local *local = hw_to_local(hw);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 093a4ab7f28b..0b8ad1f4ecdd 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -99,10 +99,13 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
99 /* in case we are a client verify acm is not set for this ac */ 99 /* in case we are a client verify acm is not set for this ac */
100 while (unlikely(local->wmm_acm & BIT(skb->priority))) { 100 while (unlikely(local->wmm_acm & BIT(skb->priority))) {
101 if (wme_downgrade_ac(skb)) { 101 if (wme_downgrade_ac(skb)) {
102 /* The old code would drop the packet in this 102 /*
103 * case. 103 * This should not really happen. The AP has marked all
104 * lower ACs to require admission control which is not
105 * a reasonable configuration. Allow the frame to be
106 * transmitted using AC_BK as a workaround.
104 */ 107 */
105 return 0; 108 break;
106 } 109 }
107 } 110 }
108 111
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