aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/core.c123
-rw-r--r--net/wireless/core.h56
-rw-r--r--net/wireless/nl80211.c540
-rw-r--r--net/wireless/nl80211.h12
-rw-r--r--net/wireless/reg.c1164
-rw-r--r--net/wireless/reg.h45
-rw-r--r--net/wireless/scan.c866
-rw-r--r--net/wireless/sysfs.c39
-rw-r--r--net/wireless/util.c2
-rw-r--r--net/wireless/wext-compat.c97
11 files changed, 2618 insertions, 328 deletions
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 938a334c8dbc..dad43c24f695 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10cfg80211-$(CONFIG_NL80211) += nl80211.o 10cfg80211-$(CONFIG_NL80211) += nl80211.o
11 11
diff --git a/net/wireless/core.c b/net/wireless/core.c
index b96fc0c3f1c4..dd7f222919fe 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -7,7 +7,6 @@
7#include <linux/if.h> 7#include <linux/if.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/mutex.h>
11#include <linux/list.h> 10#include <linux/list.h>
12#include <linux/nl80211.h> 11#include <linux/nl80211.h>
13#include <linux/debugfs.h> 12#include <linux/debugfs.h>
@@ -31,18 +30,29 @@ MODULE_DESCRIPTION("wireless configuration support");
31 * only read the list, and that can happen quite 30 * only read the list, and that can happen quite
32 * often because we need to do it for each command */ 31 * often because we need to do it for each command */
33LIST_HEAD(cfg80211_drv_list); 32LIST_HEAD(cfg80211_drv_list);
34DEFINE_MUTEX(cfg80211_drv_mutex); 33
34/*
35 * This is used to protect the cfg80211_drv_list, cfg80211_regdomain,
36 * country_ie_regdomain, the reg_beacon_list and the the last regulatory
37 * request receipt (last_request).
38 */
39DEFINE_MUTEX(cfg80211_mutex);
35 40
36/* for debugfs */ 41/* for debugfs */
37static struct dentry *ieee80211_debugfs_dir; 42static struct dentry *ieee80211_debugfs_dir;
38 43
39/* requires cfg80211_drv_mutex to be held! */ 44/* requires cfg80211_mutex to be held! */
40static struct cfg80211_registered_device *cfg80211_drv_by_wiphy(int wiphy) 45struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx)
41{ 46{
42 struct cfg80211_registered_device *result = NULL, *drv; 47 struct cfg80211_registered_device *result = NULL, *drv;
43 48
49 if (!wiphy_idx_valid(wiphy_idx))
50 return NULL;
51
52 assert_cfg80211_lock();
53
44 list_for_each_entry(drv, &cfg80211_drv_list, list) { 54 list_for_each_entry(drv, &cfg80211_drv_list, list) {
45 if (drv->idx == wiphy) { 55 if (drv->wiphy_idx == wiphy_idx) {
46 result = drv; 56 result = drv;
47 break; 57 break;
48 } 58 }
@@ -51,17 +61,44 @@ static struct cfg80211_registered_device *cfg80211_drv_by_wiphy(int wiphy)
51 return result; 61 return result;
52} 62}
53 63
64int get_wiphy_idx(struct wiphy *wiphy)
65{
66 struct cfg80211_registered_device *drv;
67 if (!wiphy)
68 return WIPHY_IDX_STALE;
69 drv = wiphy_to_dev(wiphy);
70 return drv->wiphy_idx;
71}
72
54/* requires cfg80211_drv_mutex to be held! */ 73/* requires cfg80211_drv_mutex to be held! */
74struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
75{
76 struct cfg80211_registered_device *drv;
77
78 if (!wiphy_idx_valid(wiphy_idx))
79 return NULL;
80
81 assert_cfg80211_lock();
82
83 drv = cfg80211_drv_by_wiphy_idx(wiphy_idx);
84 if (!drv)
85 return NULL;
86 return &drv->wiphy;
87}
88
89/* requires cfg80211_mutex to be held! */
55static struct cfg80211_registered_device * 90static struct cfg80211_registered_device *
56__cfg80211_drv_from_info(struct genl_info *info) 91__cfg80211_drv_from_info(struct genl_info *info)
57{ 92{
58 int ifindex; 93 int ifindex;
59 struct cfg80211_registered_device *bywiphy = NULL, *byifidx = NULL; 94 struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
60 struct net_device *dev; 95 struct net_device *dev;
61 int err = -EINVAL; 96 int err = -EINVAL;
62 97
98 assert_cfg80211_lock();
99
63 if (info->attrs[NL80211_ATTR_WIPHY]) { 100 if (info->attrs[NL80211_ATTR_WIPHY]) {
64 bywiphy = cfg80211_drv_by_wiphy( 101 bywiphyidx = cfg80211_drv_by_wiphy_idx(
65 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); 102 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
66 err = -ENODEV; 103 err = -ENODEV;
67 } 104 }
@@ -78,14 +115,14 @@ __cfg80211_drv_from_info(struct genl_info *info)
78 err = -ENODEV; 115 err = -ENODEV;
79 } 116 }
80 117
81 if (bywiphy && byifidx) { 118 if (bywiphyidx && byifidx) {
82 if (bywiphy != byifidx) 119 if (bywiphyidx != byifidx)
83 return ERR_PTR(-EINVAL); 120 return ERR_PTR(-EINVAL);
84 else 121 else
85 return bywiphy; /* == byifidx */ 122 return bywiphyidx; /* == byifidx */
86 } 123 }
87 if (bywiphy) 124 if (bywiphyidx)
88 return bywiphy; 125 return bywiphyidx;
89 126
90 if (byifidx) 127 if (byifidx)
91 return byifidx; 128 return byifidx;
@@ -98,7 +135,7 @@ cfg80211_get_dev_from_info(struct genl_info *info)
98{ 135{
99 struct cfg80211_registered_device *drv; 136 struct cfg80211_registered_device *drv;
100 137
101 mutex_lock(&cfg80211_drv_mutex); 138 mutex_lock(&cfg80211_mutex);
102 drv = __cfg80211_drv_from_info(info); 139 drv = __cfg80211_drv_from_info(info);
103 140
104 /* if it is not an error we grab the lock on 141 /* if it is not an error we grab the lock on
@@ -107,7 +144,7 @@ cfg80211_get_dev_from_info(struct genl_info *info)
107 if (!IS_ERR(drv)) 144 if (!IS_ERR(drv))
108 mutex_lock(&drv->mtx); 145 mutex_lock(&drv->mtx);
109 146
110 mutex_unlock(&cfg80211_drv_mutex); 147 mutex_unlock(&cfg80211_mutex);
111 148
112 return drv; 149 return drv;
113} 150}
@@ -118,7 +155,7 @@ cfg80211_get_dev_from_ifindex(int ifindex)
118 struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV); 155 struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV);
119 struct net_device *dev; 156 struct net_device *dev;
120 157
121 mutex_lock(&cfg80211_drv_mutex); 158 mutex_lock(&cfg80211_mutex);
122 dev = dev_get_by_index(&init_net, ifindex); 159 dev = dev_get_by_index(&init_net, ifindex);
123 if (!dev) 160 if (!dev)
124 goto out; 161 goto out;
@@ -129,7 +166,7 @@ cfg80211_get_dev_from_ifindex(int ifindex)
129 drv = ERR_PTR(-ENODEV); 166 drv = ERR_PTR(-ENODEV);
130 dev_put(dev); 167 dev_put(dev);
131 out: 168 out:
132 mutex_unlock(&cfg80211_drv_mutex); 169 mutex_unlock(&cfg80211_mutex);
133 return drv; 170 return drv;
134} 171}
135 172
@@ -143,16 +180,16 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
143 char *newname) 180 char *newname)
144{ 181{
145 struct cfg80211_registered_device *drv; 182 struct cfg80211_registered_device *drv;
146 int idx, taken = -1, result, digits; 183 int wiphy_idx, taken = -1, result, digits;
147 184
148 mutex_lock(&cfg80211_drv_mutex); 185 mutex_lock(&cfg80211_mutex);
149 186
150 /* prohibit calling the thing phy%d when %d is not its number */ 187 /* prohibit calling the thing phy%d when %d is not its number */
151 sscanf(newname, PHY_NAME "%d%n", &idx, &taken); 188 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
152 if (taken == strlen(newname) && idx != rdev->idx) { 189 if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
153 /* count number of places needed to print idx */ 190 /* count number of places needed to print wiphy_idx */
154 digits = 1; 191 digits = 1;
155 while (idx /= 10) 192 while (wiphy_idx /= 10)
156 digits++; 193 digits++;
157 /* 194 /*
158 * deny the name if it is phy<idx> where <idx> is printed 195 * deny the name if it is phy<idx> where <idx> is printed
@@ -193,7 +230,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
193 230
194 result = 0; 231 result = 0;
195out_unlock: 232out_unlock:
196 mutex_unlock(&cfg80211_drv_mutex); 233 mutex_unlock(&cfg80211_mutex);
197 if (result == 0) 234 if (result == 0)
198 nl80211_notify_dev_rename(rdev); 235 nl80211_notify_dev_rename(rdev);
199 236
@@ -220,26 +257,28 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
220 257
221 drv->ops = ops; 258 drv->ops = ops;
222 259
223 mutex_lock(&cfg80211_drv_mutex); 260 mutex_lock(&cfg80211_mutex);
224 261
225 drv->idx = wiphy_counter++; 262 drv->wiphy_idx = wiphy_counter++;
226 263
227 if (unlikely(drv->idx < 0)) { 264 if (unlikely(!wiphy_idx_valid(drv->wiphy_idx))) {
228 wiphy_counter--; 265 wiphy_counter--;
229 mutex_unlock(&cfg80211_drv_mutex); 266 mutex_unlock(&cfg80211_mutex);
230 /* ugh, wrapped! */ 267 /* ugh, wrapped! */
231 kfree(drv); 268 kfree(drv);
232 return NULL; 269 return NULL;
233 } 270 }
234 271
235 mutex_unlock(&cfg80211_drv_mutex); 272 mutex_unlock(&cfg80211_mutex);
236 273
237 /* give it a proper name */ 274 /* give it a proper name */
238 dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->idx); 275 dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->wiphy_idx);
239 276
240 mutex_init(&drv->mtx); 277 mutex_init(&drv->mtx);
241 mutex_init(&drv->devlist_mtx); 278 mutex_init(&drv->devlist_mtx);
242 INIT_LIST_HEAD(&drv->netdev_list); 279 INIT_LIST_HEAD(&drv->netdev_list);
280 spin_lock_init(&drv->bss_lock);
281 INIT_LIST_HEAD(&drv->bss_list);
243 282
244 device_initialize(&drv->wiphy.dev); 283 device_initialize(&drv->wiphy.dev);
245 drv->wiphy.dev.class = &ieee80211_class; 284 drv->wiphy.dev.class = &ieee80211_class;
@@ -259,6 +298,9 @@ int wiphy_register(struct wiphy *wiphy)
259 int i; 298 int i;
260 u16 ifmodes = wiphy->interface_modes; 299 u16 ifmodes = wiphy->interface_modes;
261 300
301 if (WARN_ON(wiphy->max_scan_ssids < 1))
302 return -EINVAL;
303
262 /* sanity check ifmodes */ 304 /* sanity check ifmodes */
263 WARN_ON(!ifmodes); 305 WARN_ON(!ifmodes);
264 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; 306 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
@@ -273,10 +315,16 @@ int wiphy_register(struct wiphy *wiphy)
273 315
274 sband->band = band; 316 sband->band = band;
275 317
276 if (!sband->n_channels || !sband->n_bitrates) { 318 if (WARN_ON(!sband->n_channels || !sband->n_bitrates))
277 WARN_ON(1); 319 return -EINVAL;
320
321 /*
322 * Since we use a u32 for rate bitmaps in
323 * ieee80211_get_response_rate, we cannot
324 * have more than 32 legacy rates.
325 */
326 if (WARN_ON(sband->n_bitrates > 32))
278 return -EINVAL; 327 return -EINVAL;
279 }
280 328
281 for (i = 0; i < sband->n_channels; i++) { 329 for (i = 0; i < sband->n_channels; i++) {
282 sband->channels[i].orig_flags = 330 sband->channels[i].orig_flags =
@@ -299,7 +347,7 @@ int wiphy_register(struct wiphy *wiphy)
299 /* check and set up bitrates */ 347 /* check and set up bitrates */
300 ieee80211_set_bitrate_flags(wiphy); 348 ieee80211_set_bitrate_flags(wiphy);
301 349
302 mutex_lock(&cfg80211_drv_mutex); 350 mutex_lock(&cfg80211_mutex);
303 351
304 /* set up regulatory info */ 352 /* set up regulatory info */
305 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE); 353 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
@@ -319,7 +367,7 @@ int wiphy_register(struct wiphy *wiphy)
319 367
320 res = 0; 368 res = 0;
321out_unlock: 369out_unlock:
322 mutex_unlock(&cfg80211_drv_mutex); 370 mutex_unlock(&cfg80211_mutex);
323 return res; 371 return res;
324} 372}
325EXPORT_SYMBOL(wiphy_register); 373EXPORT_SYMBOL(wiphy_register);
@@ -329,7 +377,7 @@ void wiphy_unregister(struct wiphy *wiphy)
329 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); 377 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
330 378
331 /* protect the device list */ 379 /* protect the device list */
332 mutex_lock(&cfg80211_drv_mutex); 380 mutex_lock(&cfg80211_mutex);
333 381
334 BUG_ON(!list_empty(&drv->netdev_list)); 382 BUG_ON(!list_empty(&drv->netdev_list));
335 383
@@ -355,14 +403,17 @@ void wiphy_unregister(struct wiphy *wiphy)
355 device_del(&drv->wiphy.dev); 403 device_del(&drv->wiphy.dev);
356 debugfs_remove(drv->wiphy.debugfsdir); 404 debugfs_remove(drv->wiphy.debugfsdir);
357 405
358 mutex_unlock(&cfg80211_drv_mutex); 406 mutex_unlock(&cfg80211_mutex);
359} 407}
360EXPORT_SYMBOL(wiphy_unregister); 408EXPORT_SYMBOL(wiphy_unregister);
361 409
362void cfg80211_dev_free(struct cfg80211_registered_device *drv) 410void cfg80211_dev_free(struct cfg80211_registered_device *drv)
363{ 411{
412 struct cfg80211_internal_bss *scan, *tmp;
364 mutex_destroy(&drv->mtx); 413 mutex_destroy(&drv->mtx);
365 mutex_destroy(&drv->devlist_mtx); 414 mutex_destroy(&drv->devlist_mtx);
415 list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
416 cfg80211_put_bss(&scan->pub);
366 kfree(drv); 417 kfree(drv);
367} 418}
368 419
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f7fb9f413028..f6c53f5807f4 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -8,6 +8,9 @@
8#include <linux/mutex.h> 8#include <linux/mutex.h>
9#include <linux/list.h> 9#include <linux/list.h>
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h>
12#include <linux/rbtree.h>
13#include <linux/mutex.h>
11#include <net/genetlink.h> 14#include <net/genetlink.h>
12#include <net/wireless.h> 15#include <net/wireless.h>
13#include <net/cfg80211.h> 16#include <net/cfg80211.h>
@@ -35,12 +38,20 @@ struct cfg80211_registered_device {
35 enum environment_cap env; 38 enum environment_cap env;
36 39
37 /* wiphy index, internal only */ 40 /* wiphy index, internal only */
38 int idx; 41 int wiphy_idx;
39 42
40 /* associate netdev list */ 43 /* associate netdev list */
41 struct mutex devlist_mtx; 44 struct mutex devlist_mtx;
42 struct list_head netdev_list; 45 struct list_head netdev_list;
43 46
47 /* BSSes/scanning */
48 spinlock_t bss_lock;
49 struct list_head bss_list;
50 struct rb_root bss_tree;
51 u32 bss_generation;
52 struct cfg80211_scan_request *scan_req; /* protected by RTNL */
53 unsigned long suspend_at;
54
44 /* must be last because of the way we do wiphy_priv(), 55 /* must be last because of the way we do wiphy_priv(),
45 * and it should at least be aligned to NETDEV_ALIGN */ 56 * and it should at least be aligned to NETDEV_ALIGN */
46 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); 57 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -53,9 +64,39 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
53 return container_of(wiphy, struct cfg80211_registered_device, wiphy); 64 return container_of(wiphy, struct cfg80211_registered_device, wiphy);
54} 65}
55 66
56extern struct mutex cfg80211_drv_mutex; 67/* Note 0 is valid, hence phy0 */
68static inline
69bool wiphy_idx_valid(int wiphy_idx)
70{
71 return (wiphy_idx >= 0);
72}
73
74extern struct mutex cfg80211_mutex;
57extern struct list_head cfg80211_drv_list; 75extern struct list_head cfg80211_drv_list;
58 76
77static inline void assert_cfg80211_lock(void)
78{
79 WARN_ON(!mutex_is_locked(&cfg80211_mutex));
80}
81
82/*
83 * You can use this to mark a wiphy_idx as not having an associated wiphy.
84 * It guarantees cfg80211_drv_by_wiphy_idx(wiphy_idx) will return NULL
85 */
86#define WIPHY_IDX_STALE -1
87
88struct cfg80211_internal_bss {
89 struct list_head list;
90 struct rb_node rbn;
91 unsigned long ts;
92 struct kref ref;
93 /* must be last because of priv member */
94 struct cfg80211_bss pub;
95};
96
97struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx);
98int get_wiphy_idx(struct wiphy *wiphy);
99
59/* 100/*
60 * This function returns a pointer to the driver 101 * This function returns a pointer to the driver
61 * that the genl_info item that is passed refers to. 102 * that the genl_info item that is passed refers to.
@@ -63,13 +104,13 @@ extern struct list_head cfg80211_drv_list;
63 * the driver's mutex! 104 * the driver's mutex!
64 * 105 *
65 * This means that you need to call cfg80211_put_dev() 106 * This means that you need to call cfg80211_put_dev()
66 * before being allowed to acquire &cfg80211_drv_mutex! 107 * before being allowed to acquire &cfg80211_mutex!
67 * 108 *
68 * This is necessary because we need to lock the global 109 * This is necessary because we need to lock the global
69 * mutex to get an item off the list safely, and then 110 * mutex to get an item off the list safely, and then
70 * we lock the drv mutex so it doesn't go away under us. 111 * we lock the drv mutex so it doesn't go away under us.
71 * 112 *
72 * We don't want to keep cfg80211_drv_mutex locked 113 * We don't want to keep cfg80211_mutex locked
73 * for all the time in order to allow requests on 114 * for all the time in order to allow requests on
74 * other interfaces to go through at the same time. 115 * other interfaces to go through at the same time.
75 * 116 *
@@ -79,6 +120,9 @@ extern struct list_head cfg80211_drv_list;
79extern struct cfg80211_registered_device * 120extern struct cfg80211_registered_device *
80cfg80211_get_dev_from_info(struct genl_info *info); 121cfg80211_get_dev_from_info(struct genl_info *info);
81 122
123/* requires cfg80211_drv_mutex to be held! */
124struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
125
82/* identical to cfg80211_get_dev_from_info but only operate on ifindex */ 126/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
83extern struct cfg80211_registered_device * 127extern struct cfg80211_registered_device *
84cfg80211_get_dev_from_ifindex(int ifindex); 128cfg80211_get_dev_from_ifindex(int ifindex);
@@ -94,4 +138,8 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
94void ieee80211_set_bitrate_flags(struct wiphy *wiphy); 138void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
95void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby); 139void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby);
96 140
141void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
142void cfg80211_bss_age(struct cfg80211_registered_device *dev,
143 unsigned long age_secs);
144
97#endif /* __NET_WIRELESS_CORE_H */ 145#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1e728fff474e..531bb67cf502 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7,13 +7,13 @@
7#include <linux/if.h> 7#include <linux/if.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/mutex.h>
11#include <linux/list.h> 10#include <linux/list.h>
12#include <linux/if_ether.h> 11#include <linux/if_ether.h>
13#include <linux/ieee80211.h> 12#include <linux/ieee80211.h>
14#include <linux/nl80211.h> 13#include <linux/nl80211.h>
15#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
16#include <linux/netlink.h> 15#include <linux/netlink.h>
16#include <linux/etherdevice.h>
17#include <net/genetlink.h> 17#include <net/genetlink.h>
18#include <net/cfg80211.h> 18#include <net/cfg80211.h>
19#include "core.h" 19#include "core.h"
@@ -105,6 +105,12 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
105 105
106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
107 .len = NL80211_HT_CAPABILITY_LEN }, 107 .len = NL80211_HT_CAPABILITY_LEN },
108
109 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
110 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
111 .len = IEEE80211_MAX_DATA_LEN },
112 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
113 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
108}; 114};
109 115
110/* message building helper */ 116/* message building helper */
@@ -135,8 +141,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
135 if (!hdr) 141 if (!hdr)
136 return -1; 142 return -1;
137 143
138 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); 144 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
139 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 145 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
146 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
147 dev->wiphy.max_scan_ssids);
140 148
141 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 149 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
142 if (!nl_modes) 150 if (!nl_modes)
@@ -247,7 +255,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
247 int start = cb->args[0]; 255 int start = cb->args[0];
248 struct cfg80211_registered_device *dev; 256 struct cfg80211_registered_device *dev;
249 257
250 mutex_lock(&cfg80211_drv_mutex); 258 mutex_lock(&cfg80211_mutex);
251 list_for_each_entry(dev, &cfg80211_drv_list, list) { 259 list_for_each_entry(dev, &cfg80211_drv_list, list) {
252 if (++idx <= start) 260 if (++idx <= start)
253 continue; 261 continue;
@@ -258,7 +266,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
258 break; 266 break;
259 } 267 }
260 } 268 }
261 mutex_unlock(&cfg80211_drv_mutex); 269 mutex_unlock(&cfg80211_mutex);
262 270
263 cb->args[0] = idx; 271 cb->args[0] = idx;
264 272
@@ -461,7 +469,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
461 struct cfg80211_registered_device *dev; 469 struct cfg80211_registered_device *dev;
462 struct wireless_dev *wdev; 470 struct wireless_dev *wdev;
463 471
464 mutex_lock(&cfg80211_drv_mutex); 472 mutex_lock(&cfg80211_mutex);
465 list_for_each_entry(dev, &cfg80211_drv_list, list) { 473 list_for_each_entry(dev, &cfg80211_drv_list, list) {
466 if (wp_idx < wp_start) { 474 if (wp_idx < wp_start) {
467 wp_idx++; 475 wp_idx++;
@@ -488,7 +496,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
488 wp_idx++; 496 wp_idx++;
489 } 497 }
490 out: 498 out:
491 mutex_unlock(&cfg80211_drv_mutex); 499 mutex_unlock(&cfg80211_mutex);
492 500
493 cb->args[0] = wp_idx; 501 cb->args[0] = wp_idx;
494 cb->args[1] = if_idx; 502 cb->args[1] = if_idx;
@@ -738,7 +746,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
738 if (info->attrs[NL80211_ATTR_KEY_IDX]) 746 if (info->attrs[NL80211_ATTR_KEY_IDX])
739 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 747 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
740 748
741 if (key_idx > 3) 749 if (key_idx > 5)
742 return -EINVAL; 750 return -EINVAL;
743 751
744 if (info->attrs[NL80211_ATTR_MAC]) 752 if (info->attrs[NL80211_ATTR_MAC])
@@ -804,30 +812,41 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
804 int err; 812 int err;
805 struct net_device *dev; 813 struct net_device *dev;
806 u8 key_idx; 814 u8 key_idx;
815 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
816 u8 key_index);
807 817
808 if (!info->attrs[NL80211_ATTR_KEY_IDX]) 818 if (!info->attrs[NL80211_ATTR_KEY_IDX])
809 return -EINVAL; 819 return -EINVAL;
810 820
811 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 821 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
812 822
813 if (key_idx > 3) 823 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) {
824 if (key_idx < 4 || key_idx > 5)
825 return -EINVAL;
826 } else if (key_idx > 3)
814 return -EINVAL; 827 return -EINVAL;
815 828
816 /* currently only support setting default key */ 829 /* currently only support setting default key */
817 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT]) 830 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] &&
831 !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
818 return -EINVAL; 832 return -EINVAL;
819 833
820 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 834 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
821 if (err) 835 if (err)
822 return err; 836 return err;
823 837
824 if (!drv->ops->set_default_key) { 838 if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
839 func = drv->ops->set_default_key;
840 else
841 func = drv->ops->set_default_mgmt_key;
842
843 if (!func) {
825 err = -EOPNOTSUPP; 844 err = -EOPNOTSUPP;
826 goto out; 845 goto out;
827 } 846 }
828 847
829 rtnl_lock(); 848 rtnl_lock();
830 err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx); 849 err = func(&drv->wiphy, dev, key_idx);
831 rtnl_unlock(); 850 rtnl_unlock();
832 851
833 out: 852 out:
@@ -863,7 +882,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
863 if (info->attrs[NL80211_ATTR_MAC]) 882 if (info->attrs[NL80211_ATTR_MAC])
864 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 883 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
865 884
866 if (key_idx > 3) 885 if (key_idx > 5)
867 return -EINVAL; 886 return -EINVAL;
868 887
869 /* 888 /*
@@ -894,6 +913,10 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
894 if (params.key_len != 13) 913 if (params.key_len != 13)
895 return -EINVAL; 914 return -EINVAL;
896 break; 915 break;
916 case WLAN_CIPHER_SUITE_AES_CMAC:
917 if (params.key_len != 16)
918 return -EINVAL;
919 break;
897 default: 920 default:
898 return -EINVAL; 921 return -EINVAL;
899 } 922 }
@@ -928,7 +951,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
928 if (info->attrs[NL80211_ATTR_KEY_IDX]) 951 if (info->attrs[NL80211_ATTR_KEY_IDX])
929 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 952 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
930 953
931 if (key_idx > 3) 954 if (key_idx > 5)
932 return -EINVAL; 955 return -EINVAL;
933 956
934 if (info->attrs[NL80211_ATTR_MAC]) 957 if (info->attrs[NL80211_ATTR_MAC])
@@ -1182,6 +1205,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1182 1205
1183 nla_nest_end(msg, txrate); 1206 nla_nest_end(msg, txrate);
1184 } 1207 }
1208 if (sinfo->filled & STATION_INFO_RX_PACKETS)
1209 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,
1210 sinfo->rx_packets);
1211 if (sinfo->filled & STATION_INFO_TX_PACKETS)
1212 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
1213 sinfo->tx_packets);
1185 nla_nest_end(msg, sinfoattr); 1214 nla_nest_end(msg, sinfoattr);
1186 1215
1187 return genlmsg_end(msg, hdr); 1216 return genlmsg_end(msg, hdr);
@@ -1876,6 +1905,19 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1876 int r; 1905 int r;
1877 char *data = NULL; 1906 char *data = NULL;
1878 1907
1908 /*
1909 * You should only get this when cfg80211 hasn't yet initialized
1910 * completely when built-in to the kernel right between the time
1911 * window between nl80211_init() and regulatory_init(), if that is
1912 * even possible.
1913 */
1914 mutex_lock(&cfg80211_mutex);
1915 if (unlikely(!cfg80211_regdomain)) {
1916 mutex_unlock(&cfg80211_mutex);
1917 return -EINPROGRESS;
1918 }
1919 mutex_unlock(&cfg80211_mutex);
1920
1879 if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) 1921 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
1880 return -EINVAL; 1922 return -EINVAL;
1881 1923
@@ -1886,9 +1928,9 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1886 if (is_world_regdom(data)) 1928 if (is_world_regdom(data))
1887 return -EINVAL; 1929 return -EINVAL;
1888#endif 1930#endif
1889 mutex_lock(&cfg80211_drv_mutex); 1931
1890 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY); 1932 r = regulatory_hint_user(data);
1891 mutex_unlock(&cfg80211_drv_mutex); 1933
1892 return r; 1934 return r;
1893} 1935}
1894 1936
@@ -2069,6 +2111,81 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2069 2111
2070#undef FILL_IN_MESH_PARAM_IF_SET 2112#undef FILL_IN_MESH_PARAM_IF_SET
2071 2113
2114static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2115{
2116 struct sk_buff *msg;
2117 void *hdr = NULL;
2118 struct nlattr *nl_reg_rules;
2119 unsigned int i;
2120 int err = -EINVAL;
2121
2122 mutex_lock(&cfg80211_mutex);
2123
2124 if (!cfg80211_regdomain)
2125 goto out;
2126
2127 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2128 if (!msg) {
2129 err = -ENOBUFS;
2130 goto out;
2131 }
2132
2133 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2134 NL80211_CMD_GET_REG);
2135 if (!hdr)
2136 goto nla_put_failure;
2137
2138 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
2139 cfg80211_regdomain->alpha2);
2140
2141 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
2142 if (!nl_reg_rules)
2143 goto nla_put_failure;
2144
2145 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
2146 struct nlattr *nl_reg_rule;
2147 const struct ieee80211_reg_rule *reg_rule;
2148 const struct ieee80211_freq_range *freq_range;
2149 const struct ieee80211_power_rule *power_rule;
2150
2151 reg_rule = &cfg80211_regdomain->reg_rules[i];
2152 freq_range = &reg_rule->freq_range;
2153 power_rule = &reg_rule->power_rule;
2154
2155 nl_reg_rule = nla_nest_start(msg, i);
2156 if (!nl_reg_rule)
2157 goto nla_put_failure;
2158
2159 NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS,
2160 reg_rule->flags);
2161 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
2162 freq_range->start_freq_khz);
2163 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
2164 freq_range->end_freq_khz);
2165 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
2166 freq_range->max_bandwidth_khz);
2167 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
2168 power_rule->max_antenna_gain);
2169 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
2170 power_rule->max_eirp);
2171
2172 nla_nest_end(msg, nl_reg_rule);
2173 }
2174
2175 nla_nest_end(msg, nl_reg_rules);
2176
2177 genlmsg_end(msg, hdr);
2178 err = genlmsg_unicast(msg, info->snd_pid);
2179 goto out;
2180
2181nla_put_failure:
2182 genlmsg_cancel(msg, hdr);
2183 err = -EMSGSIZE;
2184out:
2185 mutex_unlock(&cfg80211_mutex);
2186 return err;
2187}
2188
2072static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 2189static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2073{ 2190{
2074 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; 2191 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -2124,9 +2241,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2124 2241
2125 BUG_ON(rule_idx != num_rules); 2242 BUG_ON(rule_idx != num_rules);
2126 2243
2127 mutex_lock(&cfg80211_drv_mutex); 2244 mutex_lock(&cfg80211_mutex);
2128 r = set_regdom(rd); 2245 r = set_regdom(rd);
2129 mutex_unlock(&cfg80211_drv_mutex); 2246 mutex_unlock(&cfg80211_mutex);
2130 return r; 2247 return r;
2131 2248
2132 bad_reg: 2249 bad_reg:
@@ -2134,6 +2251,302 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2134 return -EINVAL; 2251 return -EINVAL;
2135} 2252}
2136 2253
2254static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
2255 struct genl_info *info)
2256{
2257 struct cfg80211_registered_device *drv;
2258 int err;
2259 struct net_device *dev;
2260 struct mgmt_extra_ie_params params;
2261
2262 memset(&params, 0, sizeof(params));
2263
2264 if (!info->attrs[NL80211_ATTR_MGMT_SUBTYPE])
2265 return -EINVAL;
2266 params.subtype = nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
2267 if (params.subtype > 15)
2268 return -EINVAL; /* FC Subtype field is 4 bits (0..15) */
2269
2270 if (info->attrs[NL80211_ATTR_IE]) {
2271 params.ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2272 params.ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2273 }
2274
2275 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2276 if (err)
2277 return err;
2278
2279 if (drv->ops->set_mgmt_extra_ie) {
2280 rtnl_lock();
2281 err = drv->ops->set_mgmt_extra_ie(&drv->wiphy, dev, &params);
2282 rtnl_unlock();
2283 } else
2284 err = -EOPNOTSUPP;
2285
2286 cfg80211_put_dev(drv);
2287 dev_put(dev);
2288 return err;
2289}
2290
2291static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2292{
2293 struct cfg80211_registered_device *drv;
2294 struct net_device *dev;
2295 struct cfg80211_scan_request *request;
2296 struct cfg80211_ssid *ssid;
2297 struct ieee80211_channel *channel;
2298 struct nlattr *attr;
2299 struct wiphy *wiphy;
2300 int err, tmp, n_ssids = 0, n_channels = 0, i;
2301 enum ieee80211_band band;
2302 size_t ie_len;
2303
2304 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2305 if (err)
2306 return err;
2307
2308 wiphy = &drv->wiphy;
2309
2310 if (!drv->ops->scan) {
2311 err = -EOPNOTSUPP;
2312 goto out;
2313 }
2314
2315 rtnl_lock();
2316
2317 if (drv->scan_req) {
2318 err = -EBUSY;
2319 goto out_unlock;
2320 }
2321
2322 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
2323 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp)
2324 n_channels++;
2325 if (!n_channels) {
2326 err = -EINVAL;
2327 goto out_unlock;
2328 }
2329 } else {
2330 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
2331 if (wiphy->bands[band])
2332 n_channels += wiphy->bands[band]->n_channels;
2333 }
2334
2335 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
2336 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
2337 n_ssids++;
2338
2339 if (n_ssids > wiphy->max_scan_ssids) {
2340 err = -EINVAL;
2341 goto out_unlock;
2342 }
2343
2344 if (info->attrs[NL80211_ATTR_IE])
2345 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2346 else
2347 ie_len = 0;
2348
2349 request = kzalloc(sizeof(*request)
2350 + sizeof(*ssid) * n_ssids
2351 + sizeof(channel) * n_channels
2352 + ie_len, GFP_KERNEL);
2353 if (!request) {
2354 err = -ENOMEM;
2355 goto out_unlock;
2356 }
2357
2358 request->channels = (void *)((char *)request + sizeof(*request));
2359 request->n_channels = n_channels;
2360 if (n_ssids)
2361 request->ssids = (void *)(request->channels + n_channels);
2362 request->n_ssids = n_ssids;
2363 if (ie_len) {
2364 if (request->ssids)
2365 request->ie = (void *)(request->ssids + n_ssids);
2366 else
2367 request->ie = (void *)(request->channels + n_channels);
2368 }
2369
2370 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
2371 /* user specified, bail out if channel not found */
2372 request->n_channels = n_channels;
2373 i = 0;
2374 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
2375 request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr));
2376 if (!request->channels[i]) {
2377 err = -EINVAL;
2378 goto out_free;
2379 }
2380 i++;
2381 }
2382 } else {
2383 /* all channels */
2384 i = 0;
2385 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2386 int j;
2387 if (!wiphy->bands[band])
2388 continue;
2389 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
2390 request->channels[i] = &wiphy->bands[band]->channels[j];
2391 i++;
2392 }
2393 }
2394 }
2395
2396 i = 0;
2397 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
2398 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
2399 if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
2400 err = -EINVAL;
2401 goto out_free;
2402 }
2403 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2404 request->ssids[i].ssid_len = nla_len(attr);
2405 i++;
2406 }
2407 }
2408
2409 if (info->attrs[NL80211_ATTR_IE]) {
2410 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2411 memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]),
2412 request->ie_len);
2413 }
2414
2415 request->ifidx = dev->ifindex;
2416 request->wiphy = &drv->wiphy;
2417
2418 drv->scan_req = request;
2419 err = drv->ops->scan(&drv->wiphy, dev, request);
2420
2421 out_free:
2422 if (err) {
2423 drv->scan_req = NULL;
2424 kfree(request);
2425 }
2426 out_unlock:
2427 rtnl_unlock();
2428 out:
2429 cfg80211_put_dev(drv);
2430 dev_put(dev);
2431 return err;
2432}
2433
2434static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2435 struct cfg80211_registered_device *rdev,
2436 struct net_device *dev,
2437 struct cfg80211_bss *res)
2438{
2439 void *hdr;
2440 struct nlattr *bss;
2441
2442 hdr = nl80211hdr_put(msg, pid, seq, flags,
2443 NL80211_CMD_NEW_SCAN_RESULTS);
2444 if (!hdr)
2445 return -1;
2446
2447 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_GENERATION,
2448 rdev->bss_generation);
2449 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
2450
2451 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
2452 if (!bss)
2453 goto nla_put_failure;
2454 if (!is_zero_ether_addr(res->bssid))
2455 NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid);
2456 if (res->information_elements && res->len_information_elements)
2457 NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS,
2458 res->len_information_elements,
2459 res->information_elements);
2460 if (res->tsf)
2461 NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf);
2462 if (res->beacon_interval)
2463 NLA_PUT_U16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval);
2464 NLA_PUT_U16(msg, NL80211_BSS_CAPABILITY, res->capability);
2465 NLA_PUT_U32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq);
2466
2467 switch (rdev->wiphy.signal_type) {
2468 case CFG80211_SIGNAL_TYPE_MBM:
2469 NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, res->signal);
2470 break;
2471 case CFG80211_SIGNAL_TYPE_UNSPEC:
2472 NLA_PUT_U8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal);
2473 break;
2474 default:
2475 break;
2476 }
2477
2478 nla_nest_end(msg, bss);
2479
2480 return genlmsg_end(msg, hdr);
2481
2482 nla_put_failure:
2483 genlmsg_cancel(msg, hdr);
2484 return -EMSGSIZE;
2485}
2486
2487static int nl80211_dump_scan(struct sk_buff *skb,
2488 struct netlink_callback *cb)
2489{
2490 struct cfg80211_registered_device *dev;
2491 struct net_device *netdev;
2492 struct cfg80211_internal_bss *scan;
2493 int ifidx = cb->args[0];
2494 int start = cb->args[1], idx = 0;
2495 int err;
2496
2497 if (!ifidx) {
2498 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
2499 nl80211_fam.attrbuf, nl80211_fam.maxattr,
2500 nl80211_policy);
2501 if (err)
2502 return err;
2503
2504 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
2505 return -EINVAL;
2506
2507 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
2508 if (!ifidx)
2509 return -EINVAL;
2510 cb->args[0] = ifidx;
2511 }
2512
2513 netdev = dev_get_by_index(&init_net, ifidx);
2514 if (!netdev)
2515 return -ENODEV;
2516
2517 dev = cfg80211_get_dev_from_ifindex(ifidx);
2518 if (IS_ERR(dev)) {
2519 err = PTR_ERR(dev);
2520 goto out_put_netdev;
2521 }
2522
2523 spin_lock_bh(&dev->bss_lock);
2524 cfg80211_bss_expire(dev);
2525
2526 list_for_each_entry(scan, &dev->bss_list, list) {
2527 if (++idx <= start)
2528 continue;
2529 if (nl80211_send_bss(skb,
2530 NETLINK_CB(cb->skb).pid,
2531 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2532 dev, netdev, &scan->pub) < 0) {
2533 idx--;
2534 goto out;
2535 }
2536 }
2537
2538 out:
2539 spin_unlock_bh(&dev->bss_lock);
2540
2541 cb->args[1] = idx;
2542 err = skb->len;
2543 cfg80211_put_dev(dev);
2544 out_put_netdev:
2545 dev_put(netdev);
2546
2547 return err;
2548}
2549
2137static struct genl_ops nl80211_ops[] = { 2550static struct genl_ops nl80211_ops[] = {
2138 { 2551 {
2139 .cmd = NL80211_CMD_GET_WIPHY, 2552 .cmd = NL80211_CMD_GET_WIPHY,
@@ -2220,7 +2633,6 @@ static struct genl_ops nl80211_ops[] = {
2220 .doit = nl80211_get_station, 2633 .doit = nl80211_get_station,
2221 .dumpit = nl80211_dump_station, 2634 .dumpit = nl80211_dump_station,
2222 .policy = nl80211_policy, 2635 .policy = nl80211_policy,
2223 .flags = GENL_ADMIN_PERM,
2224 }, 2636 },
2225 { 2637 {
2226 .cmd = NL80211_CMD_SET_STATION, 2638 .cmd = NL80211_CMD_SET_STATION,
@@ -2272,6 +2684,12 @@ static struct genl_ops nl80211_ops[] = {
2272 .flags = GENL_ADMIN_PERM, 2684 .flags = GENL_ADMIN_PERM,
2273 }, 2685 },
2274 { 2686 {
2687 .cmd = NL80211_CMD_GET_REG,
2688 .doit = nl80211_get_reg,
2689 .policy = nl80211_policy,
2690 /* can be retrieved by unprivileged users */
2691 },
2692 {
2275 .cmd = NL80211_CMD_SET_REG, 2693 .cmd = NL80211_CMD_SET_REG,
2276 .doit = nl80211_set_reg, 2694 .doit = nl80211_set_reg,
2277 .policy = nl80211_policy, 2695 .policy = nl80211_policy,
@@ -2295,12 +2713,32 @@ static struct genl_ops nl80211_ops[] = {
2295 .policy = nl80211_policy, 2713 .policy = nl80211_policy,
2296 .flags = GENL_ADMIN_PERM, 2714 .flags = GENL_ADMIN_PERM,
2297 }, 2715 },
2716 {
2717 .cmd = NL80211_CMD_SET_MGMT_EXTRA_IE,
2718 .doit = nl80211_set_mgmt_extra_ie,
2719 .policy = nl80211_policy,
2720 .flags = GENL_ADMIN_PERM,
2721 },
2722 {
2723 .cmd = NL80211_CMD_TRIGGER_SCAN,
2724 .doit = nl80211_trigger_scan,
2725 .policy = nl80211_policy,
2726 .flags = GENL_ADMIN_PERM,
2727 },
2728 {
2729 .cmd = NL80211_CMD_GET_SCAN,
2730 .policy = nl80211_policy,
2731 .dumpit = nl80211_dump_scan,
2732 },
2298}; 2733};
2299 2734
2300/* multicast groups */ 2735/* multicast groups */
2301static struct genl_multicast_group nl80211_config_mcgrp = { 2736static struct genl_multicast_group nl80211_config_mcgrp = {
2302 .name = "config", 2737 .name = "config",
2303}; 2738};
2739static struct genl_multicast_group nl80211_scan_mcgrp = {
2740 .name = "scan",
2741};
2304 2742
2305/* notification functions */ 2743/* notification functions */
2306 2744
@@ -2320,6 +2758,66 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
2320 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 2758 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
2321} 2759}
2322 2760
2761static int nl80211_send_scan_donemsg(struct sk_buff *msg,
2762 struct cfg80211_registered_device *rdev,
2763 struct net_device *netdev,
2764 u32 pid, u32 seq, int flags,
2765 u32 cmd)
2766{
2767 void *hdr;
2768
2769 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
2770 if (!hdr)
2771 return -1;
2772
2773 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
2774 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
2775
2776 /* XXX: we should probably bounce back the request? */
2777
2778 return genlmsg_end(msg, hdr);
2779
2780 nla_put_failure:
2781 genlmsg_cancel(msg, hdr);
2782 return -EMSGSIZE;
2783}
2784
2785void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
2786 struct net_device *netdev)
2787{
2788 struct sk_buff *msg;
2789
2790 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2791 if (!msg)
2792 return;
2793
2794 if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
2795 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2796 nlmsg_free(msg);
2797 return;
2798 }
2799
2800 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
2801}
2802
2803void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
2804 struct net_device *netdev)
2805{
2806 struct sk_buff *msg;
2807
2808 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2809 if (!msg)
2810 return;
2811
2812 if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
2813 NL80211_CMD_SCAN_ABORTED) < 0) {
2814 nlmsg_free(msg);
2815 return;
2816 }
2817
2818 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
2819}
2820
2323/* initialisation/exit functions */ 2821/* initialisation/exit functions */
2324 2822
2325int nl80211_init(void) 2823int nl80211_init(void)
@@ -2340,6 +2838,10 @@ int nl80211_init(void)
2340 if (err) 2838 if (err)
2341 goto err_out; 2839 goto err_out;
2342 2840
2841 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
2842 if (err)
2843 goto err_out;
2844
2343 return 0; 2845 return 0;
2344 err_out: 2846 err_out:
2345 genl_unregister_family(&nl80211_fam); 2847 genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f3ea5c029aee..69787b621365 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -7,6 +7,10 @@
7extern int nl80211_init(void); 7extern int nl80211_init(void);
8extern void nl80211_exit(void); 8extern void nl80211_exit(void);
9extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); 9extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
10extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
11 struct net_device *netdev);
12extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
13 struct net_device *netdev);
10#else 14#else
11static inline int nl80211_init(void) 15static inline int nl80211_init(void)
12{ 16{
@@ -19,6 +23,14 @@ static inline void nl80211_notify_dev_rename(
19 struct cfg80211_registered_device *rdev) 23 struct cfg80211_registered_device *rdev)
20{ 24{
21} 25}
26static inline void
27nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
28 struct net_device *netdev)
29{}
30static inline void nl80211_send_scan_aborted(
31 struct cfg80211_registered_device *rdev,
32 struct net_device *netdev)
33{}
22#endif /* CONFIG_NL80211 */ 34#endif /* CONFIG_NL80211 */
23 35
24#endif /* __NET_WIRELESS_NL80211_H */ 36#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index bd0a16c3de5e..58df98f10990 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -42,38 +42,6 @@
42#include "core.h" 42#include "core.h"
43#include "reg.h" 43#include "reg.h"
44 44
45/**
46 * struct regulatory_request - receipt of last regulatory request
47 *
48 * @wiphy: this is set if this request's initiator is
49 * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
50 * can be used by the wireless core to deal with conflicts
51 * and potentially inform users of which devices specifically
52 * cased the conflicts.
53 * @initiator: indicates who sent this request, could be any of
54 * of those set in reg_set_by, %REGDOM_SET_BY_*
55 * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
56 * regulatory domain. We have a few special codes:
57 * 00 - World regulatory domain
58 * 99 - built by driver but a specific alpha2 cannot be determined
59 * 98 - result of an intersection between two regulatory domains
60 * @intersect: indicates whether the wireless core should intersect
61 * the requested regulatory domain with the presently set regulatory
62 * domain.
63 * @country_ie_checksum: checksum of the last processed and accepted
64 * country IE
65 * @country_ie_env: lets us know if the AP is telling us we are outdoor,
66 * indoor, or if it doesn't matter
67 */
68struct regulatory_request {
69 struct wiphy *wiphy;
70 enum reg_set_by initiator;
71 char alpha2[2];
72 bool intersect;
73 u32 country_ie_checksum;
74 enum environment_cap country_ie_env;
75};
76
77/* Receipt of information from last regulatory request */ 45/* Receipt of information from last regulatory request */
78static struct regulatory_request *last_request; 46static struct regulatory_request *last_request;
79 47
@@ -86,22 +54,52 @@ static u32 supported_bandwidths[] = {
86 MHZ_TO_KHZ(20), 54 MHZ_TO_KHZ(20),
87}; 55};
88 56
89/* Central wireless core regulatory domains, we only need two, 57/*
58 * Central wireless core regulatory domains, we only need two,
90 * the current one and a world regulatory domain in case we have no 59 * the current one and a world regulatory domain in case we have no
91 * information to give us an alpha2 */ 60 * information to give us an alpha2
92static const struct ieee80211_regdomain *cfg80211_regdomain; 61 */
62const struct ieee80211_regdomain *cfg80211_regdomain;
93 63
94/* We use this as a place for the rd structure built from the 64/*
65 * We use this as a place for the rd structure built from the
95 * last parsed country IE to rest until CRDA gets back to us with 66 * last parsed country IE to rest until CRDA gets back to us with
96 * what it thinks should apply for the same country */ 67 * what it thinks should apply for the same country
68 */
97static const struct ieee80211_regdomain *country_ie_regdomain; 69static const struct ieee80211_regdomain *country_ie_regdomain;
98 70
71/* Used to queue up regulatory hints */
72static LIST_HEAD(reg_requests_list);
73static spinlock_t reg_requests_lock;
74
75/* Used to queue up beacon hints for review */
76static LIST_HEAD(reg_pending_beacons);
77static spinlock_t reg_pending_beacons_lock;
78
79/* Used to keep track of processed beacon hints */
80static LIST_HEAD(reg_beacon_list);
81
82struct reg_beacon {
83 struct list_head list;
84 struct ieee80211_channel chan;
85};
86
99/* We keep a static world regulatory domain in case of the absence of CRDA */ 87/* We keep a static world regulatory domain in case of the absence of CRDA */
100static const struct ieee80211_regdomain world_regdom = { 88static const struct ieee80211_regdomain world_regdom = {
101 .n_reg_rules = 1, 89 .n_reg_rules = 3,
102 .alpha2 = "00", 90 .alpha2 = "00",
103 .reg_rules = { 91 .reg_rules = {
104 REG_RULE(2412-10, 2462+10, 40, 6, 20, 92 /* IEEE 802.11b/g, channels 1..11 */
93 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
94 /* IEEE 802.11a, channel 36..48 */
95 REG_RULE(5180-10, 5240+10, 40, 6, 23,
96 NL80211_RRF_PASSIVE_SCAN |
97 NL80211_RRF_NO_IBSS),
98
99 /* NB: 5260 MHz - 5700 MHz requies DFS */
100
101 /* IEEE 802.11a, channel 149..165 */
102 REG_RULE(5745-10, 5825+10, 40, 6, 23,
105 NL80211_RRF_PASSIVE_SCAN | 103 NL80211_RRF_PASSIVE_SCAN |
106 NL80211_RRF_NO_IBSS), 104 NL80211_RRF_NO_IBSS),
107 } 105 }
@@ -115,9 +113,11 @@ static char *ieee80211_regdom = "US";
115module_param(ieee80211_regdom, charp, 0444); 113module_param(ieee80211_regdom, charp, 0444);
116MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 114MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
117 115
118/* We assume 40 MHz bandwidth for the old regulatory work. 116/*
117 * We assume 40 MHz bandwidth for the old regulatory work.
119 * We make emphasis we are using the exact same frequencies 118 * We make emphasis we are using the exact same frequencies
120 * as before */ 119 * as before
120 */
121 121
122static const struct ieee80211_regdomain us_regdom = { 122static const struct ieee80211_regdomain us_regdom = {
123 .n_reg_rules = 6, 123 .n_reg_rules = 6,
@@ -156,8 +156,10 @@ static const struct ieee80211_regdomain jp_regdom = {
156 156
157static const struct ieee80211_regdomain eu_regdom = { 157static const struct ieee80211_regdomain eu_regdom = {
158 .n_reg_rules = 6, 158 .n_reg_rules = 6,
159 /* This alpha2 is bogus, we leave it here just for stupid 159 /*
160 * backward compatibility */ 160 * This alpha2 is bogus, we leave it here just for stupid
161 * backward compatibility
162 */
161 .alpha2 = "EU", 163 .alpha2 = "EU",
162 .reg_rules = { 164 .reg_rules = {
163 /* IEEE 802.11b/g, channels 1..13 */ 165 /* IEEE 802.11b/g, channels 1..13 */
@@ -226,8 +228,10 @@ static void reset_regdomains(void)
226 cfg80211_regdomain = NULL; 228 cfg80211_regdomain = NULL;
227} 229}
228 230
229/* Dynamic world regulatory domain requested by the wireless 231/*
230 * core upon initialization */ 232 * Dynamic world regulatory domain requested by the wireless
233 * core upon initialization
234 */
231static void update_world_regdomain(const struct ieee80211_regdomain *rd) 235static void update_world_regdomain(const struct ieee80211_regdomain *rd)
232{ 236{
233 BUG_ON(!last_request); 237 BUG_ON(!last_request);
@@ -268,8 +272,10 @@ static bool is_unknown_alpha2(const char *alpha2)
268{ 272{
269 if (!alpha2) 273 if (!alpha2)
270 return false; 274 return false;
271 /* Special case where regulatory domain was built by driver 275 /*
272 * but a specific alpha2 cannot be determined */ 276 * Special case where regulatory domain was built by driver
277 * but a specific alpha2 cannot be determined
278 */
273 if (alpha2[0] == '9' && alpha2[1] == '9') 279 if (alpha2[0] == '9' && alpha2[1] == '9')
274 return true; 280 return true;
275 return false; 281 return false;
@@ -279,9 +285,11 @@ static bool is_intersected_alpha2(const char *alpha2)
279{ 285{
280 if (!alpha2) 286 if (!alpha2)
281 return false; 287 return false;
282 /* Special case where regulatory domain is the 288 /*
289 * Special case where regulatory domain is the
283 * result of an intersection between two regulatory domain 290 * result of an intersection between two regulatory domain
284 * structures */ 291 * structures
292 */
285 if (alpha2[0] == '9' && alpha2[1] == '8') 293 if (alpha2[0] == '9' && alpha2[1] == '8')
286 return true; 294 return true;
287 return false; 295 return false;
@@ -306,8 +314,10 @@ static bool alpha2_equal(const char *alpha2_x, const char *alpha2_y)
306 return false; 314 return false;
307} 315}
308 316
309static bool regdom_changed(const char *alpha2) 317static bool regdom_changes(const char *alpha2)
310{ 318{
319 assert_cfg80211_lock();
320
311 if (!cfg80211_regdomain) 321 if (!cfg80211_regdomain)
312 return true; 322 return true;
313 if (alpha2_equal(cfg80211_regdomain->alpha2, alpha2)) 323 if (alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
@@ -334,8 +344,10 @@ static bool country_ie_integrity_changes(u32 checksum)
334 return false; 344 return false;
335} 345}
336 346
337/* This lets us keep regulatory code which is updated on a regulatory 347/*
338 * basis in userspace. */ 348 * This lets us keep regulatory code which is updated on a regulatory
349 * basis in userspace.
350 */
339static int call_crda(const char *alpha2) 351static int call_crda(const char *alpha2)
340{ 352{
341 char country_env[9 + 2] = "COUNTRY="; 353 char country_env[9 + 2] = "COUNTRY=";
@@ -447,10 +459,12 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
447#undef ONE_GHZ_IN_KHZ 459#undef ONE_GHZ_IN_KHZ
448} 460}
449 461
450/* Converts a country IE to a regulatory domain. A regulatory domain 462/*
463 * Converts a country IE to a regulatory domain. A regulatory domain
451 * structure has a lot of information which the IE doesn't yet have, 464 * structure has a lot of information which the IE doesn't yet have,
452 * so for the other values we use upper max values as we will intersect 465 * so for the other values we use upper max values as we will intersect
453 * with our userspace regulatory agent to get lower bounds. */ 466 * with our userspace regulatory agent to get lower bounds.
467 */
454static struct ieee80211_regdomain *country_ie_2_rd( 468static struct ieee80211_regdomain *country_ie_2_rd(
455 u8 *country_ie, 469 u8 *country_ie,
456 u8 country_ie_len, 470 u8 country_ie_len,
@@ -495,9 +509,11 @@ static struct ieee80211_regdomain *country_ie_2_rd(
495 509
496 *checksum ^= ((flags ^ alpha2[0] ^ alpha2[1]) << 8); 510 *checksum ^= ((flags ^ alpha2[0] ^ alpha2[1]) << 8);
497 511
498 /* We need to build a reg rule for each triplet, but first we must 512 /*
513 * We need to build a reg rule for each triplet, but first we must
499 * calculate the number of reg rules we will need. We will need one 514 * calculate the number of reg rules we will need. We will need one
500 * for each channel subband */ 515 * for each channel subband
516 */
501 while (country_ie_len >= 3) { 517 while (country_ie_len >= 3) {
502 int end_channel = 0; 518 int end_channel = 0;
503 struct ieee80211_country_ie_triplet *triplet = 519 struct ieee80211_country_ie_triplet *triplet =
@@ -535,9 +551,11 @@ static struct ieee80211_regdomain *country_ie_2_rd(
535 if (cur_sub_max_channel < cur_channel) 551 if (cur_sub_max_channel < cur_channel)
536 return NULL; 552 return NULL;
537 553
538 /* Do not allow overlapping channels. Also channels 554 /*
555 * Do not allow overlapping channels. Also channels
539 * passed in each subband must be monotonically 556 * passed in each subband must be monotonically
540 * increasing */ 557 * increasing
558 */
541 if (last_sub_max_channel) { 559 if (last_sub_max_channel) {
542 if (cur_channel <= last_sub_max_channel) 560 if (cur_channel <= last_sub_max_channel)
543 return NULL; 561 return NULL;
@@ -545,10 +563,12 @@ static struct ieee80211_regdomain *country_ie_2_rd(
545 return NULL; 563 return NULL;
546 } 564 }
547 565
548 /* When dot11RegulatoryClassesRequired is supported 566 /*
567 * When dot11RegulatoryClassesRequired is supported
549 * we can throw ext triplets as part of this soup, 568 * we can throw ext triplets as part of this soup,
550 * for now we don't care when those change as we 569 * for now we don't care when those change as we
551 * don't support them */ 570 * don't support them
571 */
552 *checksum ^= ((cur_channel ^ cur_sub_max_channel) << 8) | 572 *checksum ^= ((cur_channel ^ cur_sub_max_channel) << 8) |
553 ((cur_sub_max_channel ^ cur_sub_max_channel) << 16) | 573 ((cur_sub_max_channel ^ cur_sub_max_channel) << 16) |
554 ((triplet->chans.max_power ^ cur_sub_max_channel) << 24); 574 ((triplet->chans.max_power ^ cur_sub_max_channel) << 24);
@@ -559,8 +579,10 @@ static struct ieee80211_regdomain *country_ie_2_rd(
559 country_ie_len -= 3; 579 country_ie_len -= 3;
560 num_rules++; 580 num_rules++;
561 581
562 /* Note: this is not a IEEE requirement but 582 /*
563 * simply a memory requirement */ 583 * Note: this is not a IEEE requirement but
584 * simply a memory requirement
585 */
564 if (num_rules > NL80211_MAX_SUPP_REG_RULES) 586 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
565 return NULL; 587 return NULL;
566 } 588 }
@@ -588,8 +610,10 @@ static struct ieee80211_regdomain *country_ie_2_rd(
588 struct ieee80211_freq_range *freq_range = NULL; 610 struct ieee80211_freq_range *freq_range = NULL;
589 struct ieee80211_power_rule *power_rule = NULL; 611 struct ieee80211_power_rule *power_rule = NULL;
590 612
591 /* Must parse if dot11RegulatoryClassesRequired is true, 613 /*
592 * we don't support this yet */ 614 * Must parse if dot11RegulatoryClassesRequired is true,
615 * we don't support this yet
616 */
593 if (triplet->ext.reg_extension_id >= 617 if (triplet->ext.reg_extension_id >=
594 IEEE80211_COUNTRY_EXTENSION_ID) { 618 IEEE80211_COUNTRY_EXTENSION_ID) {
595 country_ie += 3; 619 country_ie += 3;
@@ -611,10 +635,12 @@ static struct ieee80211_regdomain *country_ie_2_rd(
611 end_channel = triplet->chans.first_channel + 635 end_channel = triplet->chans.first_channel +
612 (4 * (triplet->chans.num_channels - 1)); 636 (4 * (triplet->chans.num_channels - 1));
613 637
614 /* The +10 is since the regulatory domain expects 638 /*
639 * The +10 is since the regulatory domain expects
615 * the actual band edge, not the center of freq for 640 * the actual band edge, not the center of freq for
616 * its start and end freqs, assuming 20 MHz bandwidth on 641 * its start and end freqs, assuming 20 MHz bandwidth on
617 * the channels passed */ 642 * the channels passed
643 */
618 freq_range->start_freq_khz = 644 freq_range->start_freq_khz =
619 MHZ_TO_KHZ(ieee80211_channel_to_frequency( 645 MHZ_TO_KHZ(ieee80211_channel_to_frequency(
620 triplet->chans.first_channel) - 10); 646 triplet->chans.first_channel) - 10);
@@ -622,9 +648,11 @@ static struct ieee80211_regdomain *country_ie_2_rd(
622 MHZ_TO_KHZ(ieee80211_channel_to_frequency( 648 MHZ_TO_KHZ(ieee80211_channel_to_frequency(
623 end_channel) + 10); 649 end_channel) + 10);
624 650
625 /* Large arbitrary values, we intersect later */ 651 /*
626 /* Increment this if we ever support >= 40 MHz channels 652 * These are large arbitrary values we use to intersect later.
627 * in IEEE 802.11 */ 653 * Increment this if we ever support >= 40 MHz channels
654 * in IEEE 802.11
655 */
628 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40); 656 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40);
629 power_rule->max_antenna_gain = DBI_TO_MBI(100); 657 power_rule->max_antenna_gain = DBI_TO_MBI(100);
630 power_rule->max_eirp = DBM_TO_MBM(100); 658 power_rule->max_eirp = DBM_TO_MBM(100);
@@ -640,8 +668,10 @@ static struct ieee80211_regdomain *country_ie_2_rd(
640} 668}
641 669
642 670
643/* Helper for regdom_intersect(), this does the real 671/*
644 * mathematical intersection fun */ 672 * Helper for regdom_intersect(), this does the real
673 * mathematical intersection fun
674 */
645static int reg_rules_intersect( 675static int reg_rules_intersect(
646 const struct ieee80211_reg_rule *rule1, 676 const struct ieee80211_reg_rule *rule1,
647 const struct ieee80211_reg_rule *rule2, 677 const struct ieee80211_reg_rule *rule2,
@@ -719,11 +749,13 @@ static struct ieee80211_regdomain *regdom_intersect(
719 if (!rd1 || !rd2) 749 if (!rd1 || !rd2)
720 return NULL; 750 return NULL;
721 751
722 /* First we get a count of the rules we'll need, then we actually 752 /*
753 * First we get a count of the rules we'll need, then we actually
723 * build them. This is to so we can malloc() and free() a 754 * build them. This is to so we can malloc() and free() a
724 * regdomain once. The reason we use reg_rules_intersect() here 755 * regdomain once. The reason we use reg_rules_intersect() here
725 * is it will return -EINVAL if the rule computed makes no sense. 756 * is it will return -EINVAL if the rule computed makes no sense.
726 * All rules that do check out OK are valid. */ 757 * All rules that do check out OK are valid.
758 */
727 759
728 for (x = 0; x < rd1->n_reg_rules; x++) { 760 for (x = 0; x < rd1->n_reg_rules; x++) {
729 rule1 = &rd1->reg_rules[x]; 761 rule1 = &rd1->reg_rules[x];
@@ -751,14 +783,18 @@ static struct ieee80211_regdomain *regdom_intersect(
751 rule1 = &rd1->reg_rules[x]; 783 rule1 = &rd1->reg_rules[x];
752 for (y = 0; y < rd2->n_reg_rules; y++) { 784 for (y = 0; y < rd2->n_reg_rules; y++) {
753 rule2 = &rd2->reg_rules[y]; 785 rule2 = &rd2->reg_rules[y];
754 /* This time around instead of using the stack lets 786 /*
787 * This time around instead of using the stack lets
755 * write to the target rule directly saving ourselves 788 * write to the target rule directly saving ourselves
756 * a memcpy() */ 789 * a memcpy()
790 */
757 intersected_rule = &rd->reg_rules[rule_idx]; 791 intersected_rule = &rd->reg_rules[rule_idx];
758 r = reg_rules_intersect(rule1, rule2, 792 r = reg_rules_intersect(rule1, rule2,
759 intersected_rule); 793 intersected_rule);
760 /* No need to memset here the intersected rule here as 794 /*
761 * we're not using the stack anymore */ 795 * No need to memset here the intersected rule here as
796 * we're not using the stack anymore
797 */
762 if (r) 798 if (r)
763 continue; 799 continue;
764 rule_idx++; 800 rule_idx++;
@@ -777,8 +813,10 @@ static struct ieee80211_regdomain *regdom_intersect(
777 return rd; 813 return rd;
778} 814}
779 815
780/* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may 816/*
781 * want to just have the channel structure use these */ 817 * XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
818 * want to just have the channel structure use these
819 */
782static u32 map_regdom_flags(u32 rd_flags) 820static u32 map_regdom_flags(u32 rd_flags)
783{ 821{
784 u32 channel_flags = 0; 822 u32 channel_flags = 0;
@@ -791,48 +829,45 @@ static u32 map_regdom_flags(u32 rd_flags)
791 return channel_flags; 829 return channel_flags;
792} 830}
793 831
794/** 832static int freq_reg_info_regd(struct wiphy *wiphy,
795 * freq_reg_info - get regulatory information for the given frequency 833 u32 center_freq,
796 * @center_freq: Frequency in KHz for which we want regulatory information for 834 u32 *bandwidth,
797 * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one 835 const struct ieee80211_reg_rule **reg_rule,
798 * you can set this to 0. If this frequency is allowed we then set 836 const struct ieee80211_regdomain *custom_regd)
799 * this value to the maximum allowed bandwidth.
800 * @reg_rule: the regulatory rule which we have for this frequency
801 *
802 * Use this function to get the regulatory rule for a specific frequency on
803 * a given wireless device. If the device has a specific regulatory domain
804 * it wants to follow we respect that unless a country IE has been received
805 * and processed already.
806 *
807 * Returns 0 if it was able to find a valid regulatory rule which does
808 * apply to the given center_freq otherwise it returns non-zero. It will
809 * also return -ERANGE if we determine the given center_freq does not even have
810 * a regulatory rule for a frequency range in the center_freq's band. See
811 * freq_in_rule_band() for our current definition of a band -- this is purely
812 * subjective and right now its 802.11 specific.
813 */
814static int freq_reg_info(u32 center_freq, u32 *bandwidth,
815 const struct ieee80211_reg_rule **reg_rule)
816{ 837{
817 int i; 838 int i;
818 bool band_rule_found = false; 839 bool band_rule_found = false;
840 const struct ieee80211_regdomain *regd;
819 u32 max_bandwidth = 0; 841 u32 max_bandwidth = 0;
820 842
821 if (!cfg80211_regdomain) 843 regd = custom_regd ? custom_regd : cfg80211_regdomain;
844
845 /*
846 * Follow the driver's regulatory domain, if present, unless a country
847 * IE has been processed or a user wants to help complaince further
848 */
849 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE &&
850 last_request->initiator != REGDOM_SET_BY_USER &&
851 wiphy->regd)
852 regd = wiphy->regd;
853
854 if (!regd)
822 return -EINVAL; 855 return -EINVAL;
823 856
824 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) { 857 for (i = 0; i < regd->n_reg_rules; i++) {
825 const struct ieee80211_reg_rule *rr; 858 const struct ieee80211_reg_rule *rr;
826 const struct ieee80211_freq_range *fr = NULL; 859 const struct ieee80211_freq_range *fr = NULL;
827 const struct ieee80211_power_rule *pr = NULL; 860 const struct ieee80211_power_rule *pr = NULL;
828 861
829 rr = &cfg80211_regdomain->reg_rules[i]; 862 rr = &regd->reg_rules[i];
830 fr = &rr->freq_range; 863 fr = &rr->freq_range;
831 pr = &rr->power_rule; 864 pr = &rr->power_rule;
832 865
833 /* We only need to know if one frequency rule was 866 /*
867 * We only need to know if one frequency rule was
834 * was in center_freq's band, that's enough, so lets 868 * was in center_freq's band, that's enough, so lets
835 * not overwrite it once found */ 869 * not overwrite it once found
870 */
836 if (!band_rule_found) 871 if (!band_rule_found)
837 band_rule_found = freq_in_rule_band(fr, center_freq); 872 band_rule_found = freq_in_rule_band(fr, center_freq);
838 873
@@ -850,6 +885,14 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
850 885
851 return !max_bandwidth; 886 return !max_bandwidth;
852} 887}
888EXPORT_SYMBOL(freq_reg_info);
889
890int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
891 const struct ieee80211_reg_rule **reg_rule)
892{
893 return freq_reg_info_regd(wiphy, center_freq,
894 bandwidth, reg_rule, NULL);
895}
853 896
854static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, 897static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
855 unsigned int chan_idx) 898 unsigned int chan_idx)
@@ -861,6 +904,11 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
861 const struct ieee80211_power_rule *power_rule = NULL; 904 const struct ieee80211_power_rule *power_rule = NULL;
862 struct ieee80211_supported_band *sband; 905 struct ieee80211_supported_band *sband;
863 struct ieee80211_channel *chan; 906 struct ieee80211_channel *chan;
907 struct wiphy *request_wiphy = NULL;
908
909 assert_cfg80211_lock();
910
911 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
864 912
865 sband = wiphy->bands[band]; 913 sband = wiphy->bands[band];
866 BUG_ON(chan_idx >= sband->n_channels); 914 BUG_ON(chan_idx >= sband->n_channels);
@@ -868,11 +916,12 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
868 916
869 flags = chan->orig_flags; 917 flags = chan->orig_flags;
870 918
871 r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq), 919 r = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq),
872 &max_bandwidth, &reg_rule); 920 &max_bandwidth, &reg_rule);
873 921
874 if (r) { 922 if (r) {
875 /* This means no regulatory rule was found in the country IE 923 /*
924 * This means no regulatory rule was found in the country IE
876 * with a frequency range on the center_freq's band, since 925 * with a frequency range on the center_freq's band, since
877 * IEEE-802.11 allows for a country IE to have a subset of the 926 * IEEE-802.11 allows for a country IE to have a subset of the
878 * regulatory information provided in a country we ignore 927 * regulatory information provided in a country we ignore
@@ -891,8 +940,10 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
891 chan->center_freq, wiphy_name(wiphy)); 940 chan->center_freq, wiphy_name(wiphy));
892#endif 941#endif
893 } else { 942 } else {
894 /* In this case we know the country IE has at least one reg rule 943 /*
895 * for the band so we respect its band definitions */ 944 * In this case we know the country IE has at least one reg rule
945 * for the band so we respect its band definitions
946 */
896#ifdef CONFIG_CFG80211_REG_DEBUG 947#ifdef CONFIG_CFG80211_REG_DEBUG
897 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) 948 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
898 printk(KERN_DEBUG "cfg80211: Disabling " 949 printk(KERN_DEBUG "cfg80211: Disabling "
@@ -908,6 +959,24 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
908 959
909 power_rule = &reg_rule->power_rule; 960 power_rule = &reg_rule->power_rule;
910 961
962 if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
963 request_wiphy && request_wiphy == wiphy &&
964 request_wiphy->strict_regulatory) {
965 /*
966 * This gaurantees the driver's requested regulatory domain
967 * will always be used as a base for further regulatory
968 * settings
969 */
970 chan->flags = chan->orig_flags =
971 map_regdom_flags(reg_rule->flags);
972 chan->max_antenna_gain = chan->orig_mag =
973 (int) MBI_TO_DBI(power_rule->max_antenna_gain);
974 chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
975 chan->max_power = chan->orig_mpwr =
976 (int) MBM_TO_DBM(power_rule->max_eirp);
977 return;
978 }
979
911 chan->flags = flags | map_regdom_flags(reg_rule->flags); 980 chan->flags = flags | map_regdom_flags(reg_rule->flags);
912 chan->max_antenna_gain = min(chan->orig_mag, 981 chan->max_antenna_gain = min(chan->orig_mag,
913 (int) MBI_TO_DBI(power_rule->max_antenna_gain)); 982 (int) MBI_TO_DBI(power_rule->max_antenna_gain));
@@ -936,7 +1005,14 @@ static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
936 if (!last_request) 1005 if (!last_request)
937 return true; 1006 return true;
938 if (setby == REGDOM_SET_BY_CORE && 1007 if (setby == REGDOM_SET_BY_CORE &&
939 wiphy->fw_handles_regulatory) 1008 wiphy->custom_regulatory)
1009 return true;
1010 /*
1011 * wiphy->regd will be set once the device has its own
1012 * desired regulatory domain set
1013 */
1014 if (wiphy->strict_regulatory && !wiphy->regd &&
1015 !is_world_regdom(last_request->alpha2))
940 return true; 1016 return true;
941 return false; 1017 return false;
942} 1018}
@@ -946,117 +1022,374 @@ static void update_all_wiphy_regulatory(enum reg_set_by setby)
946 struct cfg80211_registered_device *drv; 1022 struct cfg80211_registered_device *drv;
947 1023
948 list_for_each_entry(drv, &cfg80211_drv_list, list) 1024 list_for_each_entry(drv, &cfg80211_drv_list, list)
949 if (!ignore_reg_update(&drv->wiphy, setby)) 1025 wiphy_update_regulatory(&drv->wiphy, setby);
950 wiphy_update_regulatory(&drv->wiphy, setby); 1026}
1027
1028static void handle_reg_beacon(struct wiphy *wiphy,
1029 unsigned int chan_idx,
1030 struct reg_beacon *reg_beacon)
1031{
1032#ifdef CONFIG_CFG80211_REG_DEBUG
1033#define REG_DEBUG_BEACON_FLAG(desc) \
1034 printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
1035 "frequency: %d MHz (Ch %d) on %s\n", \
1036 reg_beacon->chan.center_freq, \
1037 ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
1038 wiphy_name(wiphy));
1039#else
1040#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
1041#endif
1042 struct ieee80211_supported_band *sband;
1043 struct ieee80211_channel *chan;
1044
1045 assert_cfg80211_lock();
1046
1047 sband = wiphy->bands[reg_beacon->chan.band];
1048 chan = &sband->channels[chan_idx];
1049
1050 if (likely(chan->center_freq != reg_beacon->chan.center_freq))
1051 return;
1052
1053 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
1054 chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
1055 REG_DEBUG_BEACON_FLAG("active scanning");
1056 }
1057
1058 if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
1059 chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
1060 REG_DEBUG_BEACON_FLAG("beaconing");
1061 }
1062
1063 chan->beacon_found = true;
1064#undef REG_DEBUG_BEACON_FLAG
1065}
1066
1067/*
1068 * Called when a scan on a wiphy finds a beacon on
1069 * new channel
1070 */
1071static void wiphy_update_new_beacon(struct wiphy *wiphy,
1072 struct reg_beacon *reg_beacon)
1073{
1074 unsigned int i;
1075 struct ieee80211_supported_band *sband;
1076
1077 assert_cfg80211_lock();
1078
1079 if (!wiphy->bands[reg_beacon->chan.band])
1080 return;
1081
1082 sband = wiphy->bands[reg_beacon->chan.band];
1083
1084 for (i = 0; i < sband->n_channels; i++)
1085 handle_reg_beacon(wiphy, i, reg_beacon);
1086}
1087
1088/*
1089 * Called upon reg changes or a new wiphy is added
1090 */
1091static void wiphy_update_beacon_reg(struct wiphy *wiphy)
1092{
1093 unsigned int i;
1094 struct ieee80211_supported_band *sband;
1095 struct reg_beacon *reg_beacon;
1096
1097 assert_cfg80211_lock();
1098
1099 if (list_empty(&reg_beacon_list))
1100 return;
1101
1102 list_for_each_entry(reg_beacon, &reg_beacon_list, list) {
1103 if (!wiphy->bands[reg_beacon->chan.band])
1104 continue;
1105 sband = wiphy->bands[reg_beacon->chan.band];
1106 for (i = 0; i < sband->n_channels; i++)
1107 handle_reg_beacon(wiphy, i, reg_beacon);
1108 }
1109}
1110
1111static bool reg_is_world_roaming(struct wiphy *wiphy)
1112{
1113 if (is_world_regdom(cfg80211_regdomain->alpha2) ||
1114 (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
1115 return true;
1116 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE &&
1117 wiphy->custom_regulatory)
1118 return true;
1119 return false;
1120}
1121
1122/* Reap the advantages of previously found beacons */
1123static void reg_process_beacons(struct wiphy *wiphy)
1124{
1125 if (!reg_is_world_roaming(wiphy))
1126 return;
1127 wiphy_update_beacon_reg(wiphy);
951} 1128}
952 1129
953void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby) 1130void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
954{ 1131{
955 enum ieee80211_band band; 1132 enum ieee80211_band band;
1133
1134 if (ignore_reg_update(wiphy, setby))
1135 goto out;
956 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1136 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
957 if (wiphy->bands[band]) 1137 if (wiphy->bands[band])
958 handle_band(wiphy, band); 1138 handle_band(wiphy, band);
959 if (wiphy->reg_notifier)
960 wiphy->reg_notifier(wiphy, setby);
961 } 1139 }
1140out:
1141 reg_process_beacons(wiphy);
1142 if (wiphy->reg_notifier)
1143 wiphy->reg_notifier(wiphy, last_request);
1144}
1145
1146static void handle_channel_custom(struct wiphy *wiphy,
1147 enum ieee80211_band band,
1148 unsigned int chan_idx,
1149 const struct ieee80211_regdomain *regd)
1150{
1151 int r;
1152 u32 max_bandwidth = 0;
1153 const struct ieee80211_reg_rule *reg_rule = NULL;
1154 const struct ieee80211_power_rule *power_rule = NULL;
1155 struct ieee80211_supported_band *sband;
1156 struct ieee80211_channel *chan;
1157
1158 sband = wiphy->bands[band];
1159 BUG_ON(chan_idx >= sband->n_channels);
1160 chan = &sband->channels[chan_idx];
1161
1162 r = freq_reg_info_regd(wiphy, MHZ_TO_KHZ(chan->center_freq),
1163 &max_bandwidth, &reg_rule, regd);
1164
1165 if (r) {
1166 chan->flags = IEEE80211_CHAN_DISABLED;
1167 return;
1168 }
1169
1170 power_rule = &reg_rule->power_rule;
1171
1172 chan->flags |= map_regdom_flags(reg_rule->flags);
1173 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
1174 chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
1175 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
962} 1176}
963 1177
964/* Return value which can be used by ignore_request() to indicate 1178static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band,
965 * it has been determined we should intersect two regulatory domains */ 1179 const struct ieee80211_regdomain *regd)
1180{
1181 unsigned int i;
1182 struct ieee80211_supported_band *sband;
1183
1184 BUG_ON(!wiphy->bands[band]);
1185 sband = wiphy->bands[band];
1186
1187 for (i = 0; i < sband->n_channels; i++)
1188 handle_channel_custom(wiphy, band, i, regd);
1189}
1190
1191/* Used by drivers prior to wiphy registration */
1192void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1193 const struct ieee80211_regdomain *regd)
1194{
1195 enum ieee80211_band band;
1196 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1197 if (wiphy->bands[band])
1198 handle_band_custom(wiphy, band, regd);
1199 }
1200}
1201EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1202
1203static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
1204 const struct ieee80211_regdomain *src_regd)
1205{
1206 struct ieee80211_regdomain *regd;
1207 int size_of_regd = 0;
1208 unsigned int i;
1209
1210 size_of_regd = sizeof(struct ieee80211_regdomain) +
1211 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
1212
1213 regd = kzalloc(size_of_regd, GFP_KERNEL);
1214 if (!regd)
1215 return -ENOMEM;
1216
1217 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
1218
1219 for (i = 0; i < src_regd->n_reg_rules; i++)
1220 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
1221 sizeof(struct ieee80211_reg_rule));
1222
1223 *dst_regd = regd;
1224 return 0;
1225}
1226
1227/*
1228 * Return value which can be used by ignore_request() to indicate
1229 * it has been determined we should intersect two regulatory domains
1230 */
966#define REG_INTERSECT 1 1231#define REG_INTERSECT 1
967 1232
968/* This has the logic which determines when a new request 1233/* This has the logic which determines when a new request
969 * should be ignored. */ 1234 * should be ignored. */
970static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by, 1235static int ignore_request(struct wiphy *wiphy,
971 const char *alpha2) 1236 struct regulatory_request *pending_request)
972{ 1237{
1238 struct wiphy *last_wiphy = NULL;
1239
1240 assert_cfg80211_lock();
1241
973 /* All initial requests are respected */ 1242 /* All initial requests are respected */
974 if (!last_request) 1243 if (!last_request)
975 return 0; 1244 return 0;
976 1245
977 switch (set_by) { 1246 switch (pending_request->initiator) {
978 case REGDOM_SET_BY_INIT: 1247 case REGDOM_SET_BY_INIT:
979 return -EINVAL; 1248 return -EINVAL;
980 case REGDOM_SET_BY_CORE: 1249 case REGDOM_SET_BY_CORE:
981 /* 1250 return -EINVAL;
982 * Always respect new wireless core hints, should only happen
983 * when updating the world regulatory domain at init.
984 */
985 return 0;
986 case REGDOM_SET_BY_COUNTRY_IE: 1251 case REGDOM_SET_BY_COUNTRY_IE:
987 if (unlikely(!is_an_alpha2(alpha2))) 1252
1253 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1254
1255 if (unlikely(!is_an_alpha2(pending_request->alpha2)))
988 return -EINVAL; 1256 return -EINVAL;
989 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 1257 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
990 if (last_request->wiphy != wiphy) { 1258 if (last_wiphy != wiphy) {
991 /* 1259 /*
992 * Two cards with two APs claiming different 1260 * Two cards with two APs claiming different
993 * different Country IE alpha2s. We could 1261 * different Country IE alpha2s. We could
994 * intersect them, but that seems unlikely 1262 * intersect them, but that seems unlikely
995 * to be correct. Reject second one for now. 1263 * to be correct. Reject second one for now.
996 */ 1264 */
997 if (!alpha2_equal(alpha2, 1265 if (regdom_changes(pending_request->alpha2))
998 cfg80211_regdomain->alpha2))
999 return -EOPNOTSUPP; 1266 return -EOPNOTSUPP;
1000 return -EALREADY; 1267 return -EALREADY;
1001 } 1268 }
1002 /* Two consecutive Country IE hints on the same wiphy. 1269 /*
1003 * This should be picked up early by the driver/stack */ 1270 * Two consecutive Country IE hints on the same wiphy.
1004 if (WARN_ON(!alpha2_equal(cfg80211_regdomain->alpha2, 1271 * This should be picked up early by the driver/stack
1005 alpha2))) 1272 */
1273 if (WARN_ON(regdom_changes(pending_request->alpha2)))
1006 return 0; 1274 return 0;
1007 return -EALREADY; 1275 return -EALREADY;
1008 } 1276 }
1009 return REG_INTERSECT; 1277 return REG_INTERSECT;
1010 case REGDOM_SET_BY_DRIVER: 1278 case REGDOM_SET_BY_DRIVER:
1011 if (last_request->initiator == REGDOM_SET_BY_DRIVER) 1279 if (last_request->initiator == REGDOM_SET_BY_CORE) {
1280 if (is_old_static_regdom(cfg80211_regdomain))
1281 return 0;
1282 if (regdom_changes(pending_request->alpha2))
1283 return 0;
1012 return -EALREADY; 1284 return -EALREADY;
1013 return 0; 1285 }
1286
1287 /*
1288 * This would happen if you unplug and plug your card
1289 * back in or if you add a new device for which the previously
1290 * loaded card also agrees on the regulatory domain.
1291 */
1292 if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
1293 !regdom_changes(pending_request->alpha2))
1294 return -EALREADY;
1295
1296 return REG_INTERSECT;
1014 case REGDOM_SET_BY_USER: 1297 case REGDOM_SET_BY_USER:
1015 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) 1298 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
1016 return REG_INTERSECT; 1299 return REG_INTERSECT;
1017 /* If the user knows better the user should set the regdom 1300 /*
1018 * to their country before the IE is picked up */ 1301 * If the user knows better the user should set the regdom
1302 * to their country before the IE is picked up
1303 */
1019 if (last_request->initiator == REGDOM_SET_BY_USER && 1304 if (last_request->initiator == REGDOM_SET_BY_USER &&
1020 last_request->intersect) 1305 last_request->intersect)
1021 return -EOPNOTSUPP; 1306 return -EOPNOTSUPP;
1307 /*
1308 * Process user requests only after previous user/driver/core
1309 * requests have been processed
1310 */
1311 if (last_request->initiator == REGDOM_SET_BY_CORE ||
1312 last_request->initiator == REGDOM_SET_BY_DRIVER ||
1313 last_request->initiator == REGDOM_SET_BY_USER) {
1314 if (regdom_changes(last_request->alpha2))
1315 return -EAGAIN;
1316 }
1317
1318 if (!is_old_static_regdom(cfg80211_regdomain) &&
1319 !regdom_changes(pending_request->alpha2))
1320 return -EALREADY;
1321
1022 return 0; 1322 return 0;
1023 } 1323 }
1024 1324
1025 return -EINVAL; 1325 return -EINVAL;
1026} 1326}
1027 1327
1028/* Caller must hold &cfg80211_drv_mutex */ 1328/**
1029int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, 1329 * __regulatory_hint - hint to the wireless core a regulatory domain
1030 const char *alpha2, 1330 * @wiphy: if the hint comes from country information from an AP, this
1031 u32 country_ie_checksum, 1331 * is required to be set to the wiphy that received the information
1032 enum environment_cap env) 1332 * @pending_request: the regulatory request currently being processed
1333 *
1334 * The Wireless subsystem can use this function to hint to the wireless core
1335 * what it believes should be the current regulatory domain.
1336 *
1337 * Returns zero if all went fine, %-EALREADY if a regulatory domain had
1338 * already been set or other standard error codes.
1339 *
1340 * Caller must hold &cfg80211_mutex
1341 */
1342static int __regulatory_hint(struct wiphy *wiphy,
1343 struct regulatory_request *pending_request)
1033{ 1344{
1034 struct regulatory_request *request;
1035 bool intersect = false; 1345 bool intersect = false;
1036 int r = 0; 1346 int r = 0;
1037 1347
1038 r = ignore_request(wiphy, set_by, alpha2); 1348 assert_cfg80211_lock();
1349
1350 r = ignore_request(wiphy, pending_request);
1039 1351
1040 if (r == REG_INTERSECT) 1352 if (r == REG_INTERSECT) {
1353 if (pending_request->initiator == REGDOM_SET_BY_DRIVER) {
1354 r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain);
1355 if (r) {
1356 kfree(pending_request);
1357 return r;
1358 }
1359 }
1041 intersect = true; 1360 intersect = true;
1042 else if (r) 1361 } else if (r) {
1362 /*
1363 * If the regulatory domain being requested by the
1364 * driver has already been set just copy it to the
1365 * wiphy
1366 */
1367 if (r == -EALREADY &&
1368 pending_request->initiator == REGDOM_SET_BY_DRIVER) {
1369 r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain);
1370 if (r) {
1371 kfree(pending_request);
1372 return r;
1373 }
1374 r = -EALREADY;
1375 goto new_request;
1376 }
1377 kfree(pending_request);
1043 return r; 1378 return r;
1379 }
1044 1380
1045 request = kzalloc(sizeof(struct regulatory_request), 1381new_request:
1046 GFP_KERNEL); 1382 kfree(last_request);
1047 if (!request)
1048 return -ENOMEM;
1049 1383
1050 request->alpha2[0] = alpha2[0]; 1384 last_request = pending_request;
1051 request->alpha2[1] = alpha2[1]; 1385 last_request->intersect = intersect;
1052 request->initiator = set_by; 1386
1053 request->wiphy = wiphy; 1387 pending_request = NULL;
1054 request->intersect = intersect; 1388
1055 request->country_ie_checksum = country_ie_checksum; 1389 /* When r == REG_INTERSECT we do need to call CRDA */
1056 request->country_ie_env = env; 1390 if (r < 0)
1391 return r;
1057 1392
1058 kfree(last_request);
1059 last_request = request;
1060 /* 1393 /*
1061 * Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled 1394 * Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled
1062 * AND if CRDA is NOT present nothing will happen, if someone 1395 * AND if CRDA is NOT present nothing will happen, if someone
@@ -1067,29 +1400,194 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
1067 * 1400 *
1068 * to intersect with the static rd 1401 * to intersect with the static rd
1069 */ 1402 */
1070 return call_crda(alpha2); 1403 return call_crda(last_request->alpha2);
1071} 1404}
1072 1405
1073void regulatory_hint(struct wiphy *wiphy, const char *alpha2) 1406/* This currently only processes user and driver regulatory hints */
1407static void reg_process_hint(struct regulatory_request *reg_request)
1074{ 1408{
1409 int r = 0;
1410 struct wiphy *wiphy = NULL;
1411
1412 BUG_ON(!reg_request->alpha2);
1413
1414 mutex_lock(&cfg80211_mutex);
1415
1416 if (wiphy_idx_valid(reg_request->wiphy_idx))
1417 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
1418
1419 if (reg_request->initiator == REGDOM_SET_BY_DRIVER &&
1420 !wiphy) {
1421 kfree(reg_request);
1422 goto out;
1423 }
1424
1425 r = __regulatory_hint(wiphy, reg_request);
1426 /* This is required so that the orig_* parameters are saved */
1427 if (r == -EALREADY && wiphy && wiphy->strict_regulatory)
1428 wiphy_update_regulatory(wiphy, reg_request->initiator);
1429out:
1430 mutex_unlock(&cfg80211_mutex);
1431}
1432
1433/* Processes regulatory hints, this is all the REGDOM_SET_BY_* */
1434static void reg_process_pending_hints(void)
1435 {
1436 struct regulatory_request *reg_request;
1437
1438 spin_lock(&reg_requests_lock);
1439 while (!list_empty(&reg_requests_list)) {
1440 reg_request = list_first_entry(&reg_requests_list,
1441 struct regulatory_request,
1442 list);
1443 list_del_init(&reg_request->list);
1444
1445 spin_unlock(&reg_requests_lock);
1446 reg_process_hint(reg_request);
1447 spin_lock(&reg_requests_lock);
1448 }
1449 spin_unlock(&reg_requests_lock);
1450}
1451
1452/* Processes beacon hints -- this has nothing to do with country IEs */
1453static void reg_process_pending_beacon_hints(void)
1454{
1455 struct cfg80211_registered_device *drv;
1456 struct reg_beacon *pending_beacon, *tmp;
1457
1458 mutex_lock(&cfg80211_mutex);
1459
1460 /* This goes through the _pending_ beacon list */
1461 spin_lock_bh(&reg_pending_beacons_lock);
1462
1463 if (list_empty(&reg_pending_beacons)) {
1464 spin_unlock_bh(&reg_pending_beacons_lock);
1465 goto out;
1466 }
1467
1468 list_for_each_entry_safe(pending_beacon, tmp,
1469 &reg_pending_beacons, list) {
1470
1471 list_del_init(&pending_beacon->list);
1472
1473 /* Applies the beacon hint to current wiphys */
1474 list_for_each_entry(drv, &cfg80211_drv_list, list)
1475 wiphy_update_new_beacon(&drv->wiphy, pending_beacon);
1476
1477 /* Remembers the beacon hint for new wiphys or reg changes */
1478 list_add_tail(&pending_beacon->list, &reg_beacon_list);
1479 }
1480
1481 spin_unlock_bh(&reg_pending_beacons_lock);
1482out:
1483 mutex_unlock(&cfg80211_mutex);
1484}
1485
1486static void reg_todo(struct work_struct *work)
1487{
1488 reg_process_pending_hints();
1489 reg_process_pending_beacon_hints();
1490}
1491
1492static DECLARE_WORK(reg_work, reg_todo);
1493
1494static void queue_regulatory_request(struct regulatory_request *request)
1495{
1496 spin_lock(&reg_requests_lock);
1497 list_add_tail(&request->list, &reg_requests_list);
1498 spin_unlock(&reg_requests_lock);
1499
1500 schedule_work(&reg_work);
1501}
1502
1503/* Core regulatory hint -- happens once during cfg80211_init() */
1504static int regulatory_hint_core(const char *alpha2)
1505{
1506 struct regulatory_request *request;
1507
1508 BUG_ON(last_request);
1509
1510 request = kzalloc(sizeof(struct regulatory_request),
1511 GFP_KERNEL);
1512 if (!request)
1513 return -ENOMEM;
1514
1515 request->alpha2[0] = alpha2[0];
1516 request->alpha2[1] = alpha2[1];
1517 request->initiator = REGDOM_SET_BY_CORE;
1518
1519 queue_regulatory_request(request);
1520
1521 return 0;
1522}
1523
1524/* User hints */
1525int regulatory_hint_user(const char *alpha2)
1526{
1527 struct regulatory_request *request;
1528
1529 BUG_ON(!alpha2);
1530
1531 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1532 if (!request)
1533 return -ENOMEM;
1534
1535 request->wiphy_idx = WIPHY_IDX_STALE;
1536 request->alpha2[0] = alpha2[0];
1537 request->alpha2[1] = alpha2[1];
1538 request->initiator = REGDOM_SET_BY_USER,
1539
1540 queue_regulatory_request(request);
1541
1542 return 0;
1543}
1544
1545/* Driver hints */
1546int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1547{
1548 struct regulatory_request *request;
1549
1075 BUG_ON(!alpha2); 1550 BUG_ON(!alpha2);
1551 BUG_ON(!wiphy);
1552
1553 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1554 if (!request)
1555 return -ENOMEM;
1556
1557 request->wiphy_idx = get_wiphy_idx(wiphy);
1076 1558
1077 mutex_lock(&cfg80211_drv_mutex); 1559 /* Must have registered wiphy first */
1078 __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, 0, ENVIRON_ANY); 1560 BUG_ON(!wiphy_idx_valid(request->wiphy_idx));
1079 mutex_unlock(&cfg80211_drv_mutex); 1561
1562 request->alpha2[0] = alpha2[0];
1563 request->alpha2[1] = alpha2[1];
1564 request->initiator = REGDOM_SET_BY_DRIVER;
1565
1566 queue_regulatory_request(request);
1567
1568 return 0;
1080} 1569}
1081EXPORT_SYMBOL(regulatory_hint); 1570EXPORT_SYMBOL(regulatory_hint);
1082 1571
1083static bool reg_same_country_ie_hint(struct wiphy *wiphy, 1572static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1084 u32 country_ie_checksum) 1573 u32 country_ie_checksum)
1085{ 1574{
1086 if (!last_request->wiphy) 1575 struct wiphy *request_wiphy;
1576
1577 assert_cfg80211_lock();
1578
1579 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1580
1581 if (!request_wiphy)
1087 return false; 1582 return false;
1088 if (likely(last_request->wiphy != wiphy)) 1583
1584 if (likely(request_wiphy != wiphy))
1089 return !country_ie_integrity_changes(country_ie_checksum); 1585 return !country_ie_integrity_changes(country_ie_checksum);
1090 /* We should not have let these through at this point, they 1586 /*
1587 * We should not have let these through at this point, they
1091 * should have been picked up earlier by the first alpha2 check 1588 * should have been picked up earlier by the first alpha2 check
1092 * on the device */ 1589 * on the device
1590 */
1093 if (WARN_ON(!country_ie_integrity_changes(country_ie_checksum))) 1591 if (WARN_ON(!country_ie_integrity_changes(country_ie_checksum)))
1094 return true; 1592 return true;
1095 return false; 1593 return false;
@@ -1103,11 +1601,14 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1103 char alpha2[2]; 1601 char alpha2[2];
1104 u32 checksum = 0; 1602 u32 checksum = 0;
1105 enum environment_cap env = ENVIRON_ANY; 1603 enum environment_cap env = ENVIRON_ANY;
1604 struct regulatory_request *request;
1106 1605
1107 if (!last_request) 1606 mutex_lock(&cfg80211_mutex);
1108 return;
1109 1607
1110 mutex_lock(&cfg80211_drv_mutex); 1608 if (unlikely(!last_request)) {
1609 mutex_unlock(&cfg80211_mutex);
1610 return;
1611 }
1111 1612
1112 /* IE len must be evenly divisible by 2 */ 1613 /* IE len must be evenly divisible by 2 */
1113 if (country_ie_len & 0x01) 1614 if (country_ie_len & 0x01)
@@ -1116,9 +1617,11 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1116 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 1617 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1117 goto out; 1618 goto out;
1118 1619
1119 /* Pending country IE processing, this can happen after we 1620 /*
1621 * Pending country IE processing, this can happen after we
1120 * call CRDA and wait for a response if a beacon was received before 1622 * call CRDA and wait for a response if a beacon was received before
1121 * we were able to process the last regulatory_hint_11d() call */ 1623 * we were able to process the last regulatory_hint_11d() call
1624 */
1122 if (country_ie_regdomain) 1625 if (country_ie_regdomain)
1123 goto out; 1626 goto out;
1124 1627
@@ -1130,33 +1633,44 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1130 else if (country_ie[2] == 'O') 1633 else if (country_ie[2] == 'O')
1131 env = ENVIRON_OUTDOOR; 1634 env = ENVIRON_OUTDOOR;
1132 1635
1133 /* We will run this for *every* beacon processed for the BSSID, so 1636 /*
1637 * We will run this for *every* beacon processed for the BSSID, so
1134 * we optimize an early check to exit out early if we don't have to 1638 * we optimize an early check to exit out early if we don't have to
1135 * do anything */ 1639 * do anything
1136 if (likely(last_request->wiphy)) { 1640 */
1641 if (likely(wiphy_idx_valid(last_request->wiphy_idx))) {
1137 struct cfg80211_registered_device *drv_last_ie; 1642 struct cfg80211_registered_device *drv_last_ie;
1138 1643
1139 drv_last_ie = wiphy_to_dev(last_request->wiphy); 1644 drv_last_ie =
1645 cfg80211_drv_by_wiphy_idx(last_request->wiphy_idx);
1140 1646
1141 /* Lets keep this simple -- we trust the first AP 1647 /*
1142 * after we intersect with CRDA */ 1648 * Lets keep this simple -- we trust the first AP
1143 if (likely(last_request->wiphy == wiphy)) { 1649 * after we intersect with CRDA
1144 /* Ignore IEs coming in on this wiphy with 1650 */
1145 * the same alpha2 and environment cap */ 1651 if (likely(&drv_last_ie->wiphy == wiphy)) {
1652 /*
1653 * Ignore IEs coming in on this wiphy with
1654 * the same alpha2 and environment cap
1655 */
1146 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2, 1656 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
1147 alpha2) && 1657 alpha2) &&
1148 env == drv_last_ie->env)) { 1658 env == drv_last_ie->env)) {
1149 goto out; 1659 goto out;
1150 } 1660 }
1151 /* the wiphy moved on to another BSSID or the AP 1661 /*
1662 * the wiphy moved on to another BSSID or the AP
1152 * was reconfigured. XXX: We need to deal with the 1663 * was reconfigured. XXX: We need to deal with the
1153 * case where the user suspends and goes to goes 1664 * case where the user suspends and goes to goes
1154 * to another country, and then gets IEs from an 1665 * to another country, and then gets IEs from an
1155 * AP with different settings */ 1666 * AP with different settings
1667 */
1156 goto out; 1668 goto out;
1157 } else { 1669 } else {
1158 /* Ignore IEs coming in on two separate wiphys with 1670 /*
1159 * the same alpha2 and environment cap */ 1671 * Ignore IEs coming in on two separate wiphys with
1672 * the same alpha2 and environment cap
1673 */
1160 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2, 1674 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
1161 alpha2) && 1675 alpha2) &&
1162 env == drv_last_ie->env)) { 1676 env == drv_last_ie->env)) {
@@ -1171,28 +1685,97 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1171 if (!rd) 1685 if (!rd)
1172 goto out; 1686 goto out;
1173 1687
1174 /* This will not happen right now but we leave it here for the 1688 /*
1689 * This will not happen right now but we leave it here for the
1175 * the future when we want to add suspend/resume support and having 1690 * the future when we want to add suspend/resume support and having
1176 * the user move to another country after doing so, or having the user 1691 * the user move to another country after doing so, or having the user
1177 * move to another AP. Right now we just trust the first AP. This is why 1692 * move to another AP. Right now we just trust the first AP.
1178 * this is marked as likley(). If we hit this before we add this support 1693 *
1179 * we want to be informed of it as it would indicate a mistake in the 1694 * If we hit this before we add this support we want to be informed of
1180 * current design */ 1695 * it as it would indicate a mistake in the current design
1181 if (likely(WARN_ON(reg_same_country_ie_hint(wiphy, checksum)))) 1696 */
1182 goto out; 1697 if (WARN_ON(reg_same_country_ie_hint(wiphy, checksum)))
1698 goto free_rd_out;
1699
1700 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1701 if (!request)
1702 goto free_rd_out;
1183 1703
1184 /* We keep this around for when CRDA comes back with a response so 1704 /*
1185 * we can intersect with that */ 1705 * We keep this around for when CRDA comes back with a response so
1706 * we can intersect with that
1707 */
1186 country_ie_regdomain = rd; 1708 country_ie_regdomain = rd;
1187 1709
1188 __regulatory_hint(wiphy, REGDOM_SET_BY_COUNTRY_IE, 1710 request->wiphy_idx = get_wiphy_idx(wiphy);
1189 country_ie_regdomain->alpha2, checksum, env); 1711 request->alpha2[0] = rd->alpha2[0];
1712 request->alpha2[1] = rd->alpha2[1];
1713 request->initiator = REGDOM_SET_BY_COUNTRY_IE;
1714 request->country_ie_checksum = checksum;
1715 request->country_ie_env = env;
1716
1717 mutex_unlock(&cfg80211_mutex);
1190 1718
1719 queue_regulatory_request(request);
1720
1721 return;
1722
1723free_rd_out:
1724 kfree(rd);
1191out: 1725out:
1192 mutex_unlock(&cfg80211_drv_mutex); 1726 mutex_unlock(&cfg80211_mutex);
1193} 1727}
1194EXPORT_SYMBOL(regulatory_hint_11d); 1728EXPORT_SYMBOL(regulatory_hint_11d);
1195 1729
1730static bool freq_is_chan_12_13_14(u16 freq)
1731{
1732 if (freq == ieee80211_channel_to_frequency(12) ||
1733 freq == ieee80211_channel_to_frequency(13) ||
1734 freq == ieee80211_channel_to_frequency(14))
1735 return true;
1736 return false;
1737}
1738
1739int regulatory_hint_found_beacon(struct wiphy *wiphy,
1740 struct ieee80211_channel *beacon_chan,
1741 gfp_t gfp)
1742{
1743 struct reg_beacon *reg_beacon;
1744
1745 if (likely((beacon_chan->beacon_found ||
1746 (beacon_chan->flags & IEEE80211_CHAN_RADAR) ||
1747 (beacon_chan->band == IEEE80211_BAND_2GHZ &&
1748 !freq_is_chan_12_13_14(beacon_chan->center_freq)))))
1749 return 0;
1750
1751 reg_beacon = kzalloc(sizeof(struct reg_beacon), gfp);
1752 if (!reg_beacon)
1753 return -ENOMEM;
1754
1755#ifdef CONFIG_CFG80211_REG_DEBUG
1756 printk(KERN_DEBUG "cfg80211: Found new beacon on "
1757 "frequency: %d MHz (Ch %d) on %s\n",
1758 beacon_chan->center_freq,
1759 ieee80211_frequency_to_channel(beacon_chan->center_freq),
1760 wiphy_name(wiphy));
1761#endif
1762 memcpy(&reg_beacon->chan, beacon_chan,
1763 sizeof(struct ieee80211_channel));
1764
1765
1766 /*
1767 * Since we can be called from BH or and non-BH context
1768 * we must use spin_lock_bh()
1769 */
1770 spin_lock_bh(&reg_pending_beacons_lock);
1771 list_add_tail(&reg_beacon->list, &reg_pending_beacons);
1772 spin_unlock_bh(&reg_pending_beacons_lock);
1773
1774 schedule_work(&reg_work);
1775
1776 return 0;
1777}
1778
1196static void print_rd_rules(const struct ieee80211_regdomain *rd) 1779static void print_rd_rules(const struct ieee80211_regdomain *rd)
1197{ 1780{
1198 unsigned int i; 1781 unsigned int i;
@@ -1208,8 +1791,10 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1208 freq_range = &reg_rule->freq_range; 1791 freq_range = &reg_rule->freq_range;
1209 power_rule = &reg_rule->power_rule; 1792 power_rule = &reg_rule->power_rule;
1210 1793
1211 /* There may not be documentation for max antenna gain 1794 /*
1212 * in certain regions */ 1795 * There may not be documentation for max antenna gain
1796 * in certain regions
1797 */
1213 if (power_rule->max_antenna_gain) 1798 if (power_rule->max_antenna_gain)
1214 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), " 1799 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), "
1215 "(%d mBi, %d mBm)\n", 1800 "(%d mBi, %d mBm)\n",
@@ -1232,13 +1817,12 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1232{ 1817{
1233 1818
1234 if (is_intersected_alpha2(rd->alpha2)) { 1819 if (is_intersected_alpha2(rd->alpha2)) {
1235 struct wiphy *wiphy = NULL;
1236 struct cfg80211_registered_device *drv;
1237 1820
1238 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 1821 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
1239 if (last_request->wiphy) { 1822 struct cfg80211_registered_device *drv;
1240 wiphy = last_request->wiphy; 1823 drv = cfg80211_drv_by_wiphy_idx(
1241 drv = wiphy_to_dev(wiphy); 1824 last_request->wiphy_idx);
1825 if (drv) {
1242 printk(KERN_INFO "cfg80211: Current regulatory " 1826 printk(KERN_INFO "cfg80211: Current regulatory "
1243 "domain updated by AP to: %c%c\n", 1827 "domain updated by AP to: %c%c\n",
1244 drv->country_ie_alpha2[0], 1828 drv->country_ie_alpha2[0],
@@ -1248,7 +1832,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1248 "domain intersected: \n"); 1832 "domain intersected: \n");
1249 } else 1833 } else
1250 printk(KERN_INFO "cfg80211: Current regulatory " 1834 printk(KERN_INFO "cfg80211: Current regulatory "
1251 "intersected: \n"); 1835 "domain intersected: \n");
1252 } else if (is_world_regdom(rd->alpha2)) 1836 } else if (is_world_regdom(rd->alpha2))
1253 printk(KERN_INFO "cfg80211: World regulatory " 1837 printk(KERN_INFO "cfg80211: World regulatory "
1254 "domain updated:\n"); 1838 "domain updated:\n");
@@ -1304,7 +1888,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1304{ 1888{
1305 const struct ieee80211_regdomain *intersected_rd = NULL; 1889 const struct ieee80211_regdomain *intersected_rd = NULL;
1306 struct cfg80211_registered_device *drv = NULL; 1890 struct cfg80211_registered_device *drv = NULL;
1307 struct wiphy *wiphy = NULL; 1891 struct wiphy *request_wiphy;
1308 /* Some basic sanity checks first */ 1892 /* Some basic sanity checks first */
1309 1893
1310 if (is_world_regdom(rd->alpha2)) { 1894 if (is_world_regdom(rd->alpha2)) {
@@ -1321,23 +1905,27 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1321 if (!last_request) 1905 if (!last_request)
1322 return -EINVAL; 1906 return -EINVAL;
1323 1907
1324 /* Lets only bother proceeding on the same alpha2 if the current 1908 /*
1909 * Lets only bother proceeding on the same alpha2 if the current
1325 * rd is non static (it means CRDA was present and was used last) 1910 * rd is non static (it means CRDA was present and was used last)
1326 * and the pending request came in from a country IE */ 1911 * and the pending request came in from a country IE
1912 */
1327 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) { 1913 if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) {
1328 /* If someone else asked us to change the rd lets only bother 1914 /*
1329 * checking if the alpha2 changes if CRDA was already called */ 1915 * If someone else asked us to change the rd lets only bother
1916 * checking if the alpha2 changes if CRDA was already called
1917 */
1330 if (!is_old_static_regdom(cfg80211_regdomain) && 1918 if (!is_old_static_regdom(cfg80211_regdomain) &&
1331 !regdom_changed(rd->alpha2)) 1919 !regdom_changes(rd->alpha2))
1332 return -EINVAL; 1920 return -EINVAL;
1333 } 1921 }
1334 1922
1335 wiphy = last_request->wiphy; 1923 /*
1336 1924 * Now lets set the regulatory domain, update all driver channels
1337 /* Now lets set the regulatory domain, update all driver channels
1338 * and finally inform them of what we have done, in case they want 1925 * and finally inform them of what we have done, in case they want
1339 * to review or adjust their own settings based on their own 1926 * to review or adjust their own settings based on their own
1340 * internal EEPROM data */ 1927 * internal EEPROM data
1928 */
1341 1929
1342 if (WARN_ON(!reg_is_valid_request(rd->alpha2))) 1930 if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
1343 return -EINVAL; 1931 return -EINVAL;
@@ -1349,7 +1937,28 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1349 return -EINVAL; 1937 return -EINVAL;
1350 } 1938 }
1351 1939
1940 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1941
1352 if (!last_request->intersect) { 1942 if (!last_request->intersect) {
1943 int r;
1944
1945 if (last_request->initiator != REGDOM_SET_BY_DRIVER) {
1946 reset_regdomains();
1947 cfg80211_regdomain = rd;
1948 return 0;
1949 }
1950
1951 /*
1952 * For a driver hint, lets copy the regulatory domain the
1953 * driver wanted to the wiphy to deal with conflicts
1954 */
1955
1956 BUG_ON(request_wiphy->regd);
1957
1958 r = reg_copy_regd(&request_wiphy->regd, rd);
1959 if (r)
1960 return r;
1961
1353 reset_regdomains(); 1962 reset_regdomains();
1354 cfg80211_regdomain = rd; 1963 cfg80211_regdomain = rd;
1355 return 0; 1964 return 0;
@@ -1363,8 +1972,16 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1363 if (!intersected_rd) 1972 if (!intersected_rd)
1364 return -EINVAL; 1973 return -EINVAL;
1365 1974
1366 /* We can trash what CRDA provided now */ 1975 /*
1367 kfree(rd); 1976 * We can trash what CRDA provided now.
1977 * However if a driver requested this specific regulatory
1978 * domain we keep it for its private use
1979 */
1980 if (last_request->initiator == REGDOM_SET_BY_DRIVER)
1981 request_wiphy->regd = rd;
1982 else
1983 kfree(rd);
1984
1368 rd = NULL; 1985 rd = NULL;
1369 1986
1370 reset_regdomains(); 1987 reset_regdomains();
@@ -1381,8 +1998,10 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1381 BUG_ON(!country_ie_regdomain); 1998 BUG_ON(!country_ie_regdomain);
1382 1999
1383 if (rd != country_ie_regdomain) { 2000 if (rd != country_ie_regdomain) {
1384 /* Intersect what CRDA returned and our what we 2001 /*
1385 * had built from the Country IE received */ 2002 * Intersect what CRDA returned and our what we
2003 * had built from the Country IE received
2004 */
1386 2005
1387 intersected_rd = regdom_intersect(rd, country_ie_regdomain); 2006 intersected_rd = regdom_intersect(rd, country_ie_regdomain);
1388 2007
@@ -1392,16 +2011,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1392 kfree(country_ie_regdomain); 2011 kfree(country_ie_regdomain);
1393 country_ie_regdomain = NULL; 2012 country_ie_regdomain = NULL;
1394 } else { 2013 } else {
1395 /* This would happen when CRDA was not present and 2014 /*
2015 * This would happen when CRDA was not present and
1396 * OLD_REGULATORY was enabled. We intersect our Country 2016 * OLD_REGULATORY was enabled. We intersect our Country
1397 * IE rd and what was set on cfg80211 originally */ 2017 * IE rd and what was set on cfg80211 originally
2018 */
1398 intersected_rd = regdom_intersect(rd, cfg80211_regdomain); 2019 intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
1399 } 2020 }
1400 2021
1401 if (!intersected_rd) 2022 if (!intersected_rd)
1402 return -EINVAL; 2023 return -EINVAL;
1403 2024
1404 drv = wiphy_to_dev(wiphy); 2025 drv = wiphy_to_dev(request_wiphy);
1405 2026
1406 drv->country_ie_alpha2[0] = rd->alpha2[0]; 2027 drv->country_ie_alpha2[0] = rd->alpha2[0];
1407 drv->country_ie_alpha2[1] = rd->alpha2[1]; 2028 drv->country_ie_alpha2[1] = rd->alpha2[1];
@@ -1419,13 +2040,17 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1419} 2040}
1420 2041
1421 2042
1422/* Use this call to set the current regulatory domain. Conflicts with 2043/*
2044 * Use this call to set the current regulatory domain. Conflicts with
1423 * multiple drivers can be ironed out later. Caller must've already 2045 * multiple drivers can be ironed out later. Caller must've already
1424 * kmalloc'd the rd structure. Caller must hold cfg80211_drv_mutex */ 2046 * kmalloc'd the rd structure. Caller must hold cfg80211_mutex
2047 */
1425int set_regdom(const struct ieee80211_regdomain *rd) 2048int set_regdom(const struct ieee80211_regdomain *rd)
1426{ 2049{
1427 int r; 2050 int r;
1428 2051
2052 assert_cfg80211_lock();
2053
1429 /* Note that this doesn't update the wiphys, this is done below */ 2054 /* Note that this doesn't update the wiphys, this is done below */
1430 r = __set_regdom(rd); 2055 r = __set_regdom(rd);
1431 if (r) { 2056 if (r) {
@@ -1445,53 +2070,82 @@ int set_regdom(const struct ieee80211_regdomain *rd)
1445 return r; 2070 return r;
1446} 2071}
1447 2072
1448/* Caller must hold cfg80211_drv_mutex */ 2073/* Caller must hold cfg80211_mutex */
1449void reg_device_remove(struct wiphy *wiphy) 2074void reg_device_remove(struct wiphy *wiphy)
1450{ 2075{
1451 if (!last_request || !last_request->wiphy) 2076 struct wiphy *request_wiphy;
2077
2078 assert_cfg80211_lock();
2079
2080 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2081
2082 kfree(wiphy->regd);
2083 if (!last_request || !request_wiphy)
1452 return; 2084 return;
1453 if (last_request->wiphy != wiphy) 2085 if (request_wiphy != wiphy)
1454 return; 2086 return;
1455 last_request->wiphy = NULL; 2087 last_request->wiphy_idx = WIPHY_IDX_STALE;
1456 last_request->country_ie_env = ENVIRON_ANY; 2088 last_request->country_ie_env = ENVIRON_ANY;
1457} 2089}
1458 2090
1459int regulatory_init(void) 2091int regulatory_init(void)
1460{ 2092{
1461 int err; 2093 int err = 0;
1462 2094
1463 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0); 2095 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);
1464 if (IS_ERR(reg_pdev)) 2096 if (IS_ERR(reg_pdev))
1465 return PTR_ERR(reg_pdev); 2097 return PTR_ERR(reg_pdev);
1466 2098
2099 spin_lock_init(&reg_requests_lock);
2100 spin_lock_init(&reg_pending_beacons_lock);
2101
1467#ifdef CONFIG_WIRELESS_OLD_REGULATORY 2102#ifdef CONFIG_WIRELESS_OLD_REGULATORY
1468 cfg80211_regdomain = static_regdom(ieee80211_regdom); 2103 cfg80211_regdomain = static_regdom(ieee80211_regdom);
1469 2104
1470 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n"); 2105 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
1471 print_regdomain_info(cfg80211_regdomain); 2106 print_regdomain_info(cfg80211_regdomain);
1472 /* The old code still requests for a new regdomain and if 2107 /*
2108 * The old code still requests for a new regdomain and if
1473 * you have CRDA you get it updated, otherwise you get 2109 * you have CRDA you get it updated, otherwise you get
1474 * stuck with the static values. We ignore "EU" code as 2110 * stuck with the static values. We ignore "EU" code as
1475 * that is not a valid ISO / IEC 3166 alpha2 */ 2111 * that is not a valid ISO / IEC 3166 alpha2
2112 */
1476 if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U') 2113 if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U')
1477 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, 2114 err = regulatory_hint_core(ieee80211_regdom);
1478 ieee80211_regdom, 0, ENVIRON_ANY);
1479#else 2115#else
1480 cfg80211_regdomain = cfg80211_world_regdom; 2116 cfg80211_regdomain = cfg80211_world_regdom;
1481 2117
1482 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", 0, ENVIRON_ANY); 2118 err = regulatory_hint_core("00");
1483 if (err) 2119#endif
1484 printk(KERN_ERR "cfg80211: calling CRDA failed - " 2120 if (err) {
1485 "unable to update world regulatory domain, " 2121 if (err == -ENOMEM)
1486 "using static definition\n"); 2122 return err;
2123 /*
2124 * N.B. kobject_uevent_env() can fail mainly for when we're out
2125 * memory which is handled and propagated appropriately above
2126 * but it can also fail during a netlink_broadcast() or during
2127 * early boot for call_usermodehelper(). For now treat these
2128 * errors as non-fatal.
2129 */
2130 printk(KERN_ERR "cfg80211: kobject_uevent_env() was unable "
2131 "to call CRDA during init");
2132#ifdef CONFIG_CFG80211_REG_DEBUG
2133 /* We want to find out exactly why when debugging */
2134 WARN_ON(err);
1487#endif 2135#endif
2136 }
1488 2137
1489 return 0; 2138 return 0;
1490} 2139}
1491 2140
1492void regulatory_exit(void) 2141void regulatory_exit(void)
1493{ 2142{
1494 mutex_lock(&cfg80211_drv_mutex); 2143 struct regulatory_request *reg_request, *tmp;
2144 struct reg_beacon *reg_beacon, *btmp;
2145
2146 cancel_work_sync(&reg_work);
2147
2148 mutex_lock(&cfg80211_mutex);
1495 2149
1496 reset_regdomains(); 2150 reset_regdomains();
1497 2151
@@ -1502,5 +2156,33 @@ void regulatory_exit(void)
1502 2156
1503 platform_device_unregister(reg_pdev); 2157 platform_device_unregister(reg_pdev);
1504 2158
1505 mutex_unlock(&cfg80211_drv_mutex); 2159 spin_lock_bh(&reg_pending_beacons_lock);
2160 if (!list_empty(&reg_pending_beacons)) {
2161 list_for_each_entry_safe(reg_beacon, btmp,
2162 &reg_pending_beacons, list) {
2163 list_del(&reg_beacon->list);
2164 kfree(reg_beacon);
2165 }
2166 }
2167 spin_unlock_bh(&reg_pending_beacons_lock);
2168
2169 if (!list_empty(&reg_beacon_list)) {
2170 list_for_each_entry_safe(reg_beacon, btmp,
2171 &reg_beacon_list, list) {
2172 list_del(&reg_beacon->list);
2173 kfree(reg_beacon);
2174 }
2175 }
2176
2177 spin_lock(&reg_requests_lock);
2178 if (!list_empty(&reg_requests_list)) {
2179 list_for_each_entry_safe(reg_request, tmp,
2180 &reg_requests_list, list) {
2181 list_del(&reg_request->list);
2182 kfree(reg_request);
2183 }
2184 }
2185 spin_unlock(&reg_requests_lock);
2186
2187 mutex_unlock(&cfg80211_mutex);
1506} 2188}
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index a76ea3ff7cd6..e37829a49dc4 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -1,9 +1,13 @@
1#ifndef __NET_WIRELESS_REG_H 1#ifndef __NET_WIRELESS_REG_H
2#define __NET_WIRELESS_REG_H 2#define __NET_WIRELESS_REG_H
3 3
4extern const struct ieee80211_regdomain *cfg80211_regdomain;
5
4bool is_world_regdom(const char *alpha2); 6bool is_world_regdom(const char *alpha2);
5bool reg_is_valid_request(const char *alpha2); 7bool reg_is_valid_request(const char *alpha2);
6 8
9int regulatory_hint_user(const char *alpha2);
10
7void reg_device_remove(struct wiphy *wiphy); 11void reg_device_remove(struct wiphy *wiphy);
8 12
9int regulatory_init(void); 13int regulatory_init(void);
@@ -11,34 +15,25 @@ void regulatory_exit(void);
11 15
12int set_regdom(const struct ieee80211_regdomain *rd); 16int set_regdom(const struct ieee80211_regdomain *rd);
13 17
14enum environment_cap {
15 ENVIRON_ANY,
16 ENVIRON_INDOOR,
17 ENVIRON_OUTDOOR,
18};
19
20
21/** 18/**
22 * __regulatory_hint - hint to the wireless core a regulatory domain 19 * regulatory_hint_found_beacon - hints a beacon was found on a channel
23 * @wiphy: if the hint comes from country information from an AP, this 20 * @wiphy: the wireless device where the beacon was found on
24 * is required to be set to the wiphy that received the information 21 * @beacon_chan: the channel on which the beacon was found on
25 * @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain 22 * @gfp: context flags
26 * should be in.
27 * @country_ie_checksum: checksum of processed country IE, set this to 0
28 * if the hint did not come from a country IE
29 * @country_ie_env: the environment the IE told us we are in, %ENVIRON_*
30 *
31 * The Wireless subsystem can use this function to hint to the wireless core
32 * what it believes should be the current regulatory domain by giving it an
33 * ISO/IEC 3166 alpha2 country code it knows its regulatory domain should be
34 * in.
35 * 23 *
36 * Returns zero if all went fine, %-EALREADY if a regulatory domain had 24 * This informs the wireless core that a beacon from an AP was found on
37 * already been set or other standard error codes. 25 * the channel provided. This allows the wireless core to make educated
26 * guesses on regulatory to help with world roaming. This is only used for
27 * world roaming -- when we do not know our current location. This is
28 * only useful on channels 12, 13 and 14 on the 2 GHz band as channels
29 * 1-11 are already enabled by the world regulatory domain; and on
30 * non-radar 5 GHz channels.
38 * 31 *
32 * Drivers do not need to call this, cfg80211 will do it for after a scan
33 * on a newly found BSS.
39 */ 34 */
40extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, 35int regulatory_hint_found_beacon(struct wiphy *wiphy,
41 const char *alpha2, u32 country_ie_checksum, 36 struct ieee80211_channel *beacon_chan,
42 enum environment_cap country_ie_env); 37 gfp_t gfp);
43 38
44#endif /* __NET_WIRELESS_REG_H */ 39#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
new file mode 100644
index 000000000000..280dbcd02c15
--- /dev/null
+++ b/net/wireless/scan.c
@@ -0,0 +1,866 @@
1/*
2 * cfg80211 scan result handling
3 *
4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
5 */
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/netdevice.h>
9#include <linux/wireless.h>
10#include <linux/nl80211.h>
11#include <linux/etherdevice.h>
12#include <net/arp.h>
13#include <net/cfg80211.h>
14#include <net/iw_handler.h>
15#include "core.h"
16#include "nl80211.h"
17
18#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
19
20void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
21{
22 struct net_device *dev;
23#ifdef CONFIG_WIRELESS_EXT
24 union iwreq_data wrqu;
25#endif
26
27 dev = dev_get_by_index(&init_net, request->ifidx);
28 if (!dev)
29 goto out;
30
31 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
32 wiphy_to_dev(request->wiphy)->scan_req = NULL;
33
34 if (aborted)
35 nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
36 else
37 nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
38
39#ifdef CONFIG_WIRELESS_EXT
40 if (!aborted) {
41 memset(&wrqu, 0, sizeof(wrqu));
42
43 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
44 }
45#endif
46
47 dev_put(dev);
48
49 out:
50 kfree(request);
51}
52EXPORT_SYMBOL(cfg80211_scan_done);
53
54static void bss_release(struct kref *ref)
55{
56 struct cfg80211_internal_bss *bss;
57
58 bss = container_of(ref, struct cfg80211_internal_bss, ref);
59 if (bss->pub.free_priv)
60 bss->pub.free_priv(&bss->pub);
61 kfree(bss);
62}
63
64/* must hold dev->bss_lock! */
65void cfg80211_bss_age(struct cfg80211_registered_device *dev,
66 unsigned long age_secs)
67{
68 struct cfg80211_internal_bss *bss;
69 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
70
71 list_for_each_entry(bss, &dev->bss_list, list) {
72 bss->ts -= age_jiffies;
73 }
74}
75
76/* must hold dev->bss_lock! */
77void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
78{
79 struct cfg80211_internal_bss *bss, *tmp;
80 bool expired = false;
81
82 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
83 if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
84 continue;
85 list_del(&bss->list);
86 rb_erase(&bss->rbn, &dev->bss_tree);
87 kref_put(&bss->ref, bss_release);
88 expired = true;
89 }
90
91 if (expired)
92 dev->bss_generation++;
93}
94
95static u8 *find_ie(u8 num, u8 *ies, size_t len)
96{
97 while (len > 2 && ies[0] != num) {
98 len -= ies[1] + 2;
99 ies += ies[1] + 2;
100 }
101 if (len < 2)
102 return NULL;
103 if (len < 2 + ies[1])
104 return NULL;
105 return ies;
106}
107
108static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
109{
110 const u8 *ie1 = find_ie(num, ies1, len1);
111 const u8 *ie2 = find_ie(num, ies2, len2);
112 int r;
113
114 if (!ie1 && !ie2)
115 return 0;
116 if (!ie1)
117 return -1;
118
119 r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
120 if (r == 0 && ie1[1] != ie2[1])
121 return ie2[1] - ie1[1];
122 return r;
123}
124
125static bool is_bss(struct cfg80211_bss *a,
126 const u8 *bssid,
127 const u8 *ssid, size_t ssid_len)
128{
129 const u8 *ssidie;
130
131 if (bssid && compare_ether_addr(a->bssid, bssid))
132 return false;
133
134 if (!ssid)
135 return true;
136
137 ssidie = find_ie(WLAN_EID_SSID,
138 a->information_elements,
139 a->len_information_elements);
140 if (!ssidie)
141 return false;
142 if (ssidie[1] != ssid_len)
143 return false;
144 return memcmp(ssidie + 2, ssid, ssid_len) == 0;
145}
146
147static bool is_mesh(struct cfg80211_bss *a,
148 const u8 *meshid, size_t meshidlen,
149 const u8 *meshcfg)
150{
151 const u8 *ie;
152
153 if (!is_zero_ether_addr(a->bssid))
154 return false;
155
156 ie = find_ie(WLAN_EID_MESH_ID,
157 a->information_elements,
158 a->len_information_elements);
159 if (!ie)
160 return false;
161 if (ie[1] != meshidlen)
162 return false;
163 if (memcmp(ie + 2, meshid, meshidlen))
164 return false;
165
166 ie = find_ie(WLAN_EID_MESH_CONFIG,
167 a->information_elements,
168 a->len_information_elements);
169 if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
170 return false;
171
172 /*
173 * Ignore mesh capability (last two bytes of the IE) when
174 * comparing since that may differ between stations taking
175 * part in the same mesh.
176 */
177 return memcmp(ie + 2, meshcfg, IEEE80211_MESH_CONFIG_LEN - 2) == 0;
178}
179
180static int cmp_bss(struct cfg80211_bss *a,
181 struct cfg80211_bss *b)
182{
183 int r;
184
185 if (a->channel != b->channel)
186 return b->channel->center_freq - a->channel->center_freq;
187
188 r = memcmp(a->bssid, b->bssid, ETH_ALEN);
189 if (r)
190 return r;
191
192 if (is_zero_ether_addr(a->bssid)) {
193 r = cmp_ies(WLAN_EID_MESH_ID,
194 a->information_elements,
195 a->len_information_elements,
196 b->information_elements,
197 b->len_information_elements);
198 if (r)
199 return r;
200 return cmp_ies(WLAN_EID_MESH_CONFIG,
201 a->information_elements,
202 a->len_information_elements,
203 b->information_elements,
204 b->len_information_elements);
205 }
206
207 return cmp_ies(WLAN_EID_SSID,
208 a->information_elements,
209 a->len_information_elements,
210 b->information_elements,
211 b->len_information_elements);
212}
213
214struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
215 struct ieee80211_channel *channel,
216 const u8 *bssid,
217 const u8 *ssid, size_t ssid_len,
218 u16 capa_mask, u16 capa_val)
219{
220 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
221 struct cfg80211_internal_bss *bss, *res = NULL;
222
223 spin_lock_bh(&dev->bss_lock);
224
225 list_for_each_entry(bss, &dev->bss_list, list) {
226 if ((bss->pub.capability & capa_mask) != capa_val)
227 continue;
228 if (channel && bss->pub.channel != channel)
229 continue;
230 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
231 res = bss;
232 kref_get(&res->ref);
233 break;
234 }
235 }
236
237 spin_unlock_bh(&dev->bss_lock);
238 if (!res)
239 return NULL;
240 return &res->pub;
241}
242EXPORT_SYMBOL(cfg80211_get_bss);
243
244struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
245 struct ieee80211_channel *channel,
246 const u8 *meshid, size_t meshidlen,
247 const u8 *meshcfg)
248{
249 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
250 struct cfg80211_internal_bss *bss, *res = NULL;
251
252 spin_lock_bh(&dev->bss_lock);
253
254 list_for_each_entry(bss, &dev->bss_list, list) {
255 if (channel && bss->pub.channel != channel)
256 continue;
257 if (is_mesh(&bss->pub, meshid, meshidlen, meshcfg)) {
258 res = bss;
259 kref_get(&res->ref);
260 break;
261 }
262 }
263
264 spin_unlock_bh(&dev->bss_lock);
265 if (!res)
266 return NULL;
267 return &res->pub;
268}
269EXPORT_SYMBOL(cfg80211_get_mesh);
270
271
272static void rb_insert_bss(struct cfg80211_registered_device *dev,
273 struct cfg80211_internal_bss *bss)
274{
275 struct rb_node **p = &dev->bss_tree.rb_node;
276 struct rb_node *parent = NULL;
277 struct cfg80211_internal_bss *tbss;
278 int cmp;
279
280 while (*p) {
281 parent = *p;
282 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
283
284 cmp = cmp_bss(&bss->pub, &tbss->pub);
285
286 if (WARN_ON(!cmp)) {
287 /* will sort of leak this BSS */
288 return;
289 }
290
291 if (cmp < 0)
292 p = &(*p)->rb_left;
293 else
294 p = &(*p)->rb_right;
295 }
296
297 rb_link_node(&bss->rbn, parent, p);
298 rb_insert_color(&bss->rbn, &dev->bss_tree);
299}
300
301static struct cfg80211_internal_bss *
302rb_find_bss(struct cfg80211_registered_device *dev,
303 struct cfg80211_internal_bss *res)
304{
305 struct rb_node *n = dev->bss_tree.rb_node;
306 struct cfg80211_internal_bss *bss;
307 int r;
308
309 while (n) {
310 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
311 r = cmp_bss(&res->pub, &bss->pub);
312
313 if (r == 0)
314 return bss;
315 else if (r < 0)
316 n = n->rb_left;
317 else
318 n = n->rb_right;
319 }
320
321 return NULL;
322}
323
324static struct cfg80211_internal_bss *
325cfg80211_bss_update(struct cfg80211_registered_device *dev,
326 struct cfg80211_internal_bss *res,
327 bool overwrite)
328{
329 struct cfg80211_internal_bss *found = NULL;
330 const u8 *meshid, *meshcfg;
331
332 /*
333 * The reference to "res" is donated to this function.
334 */
335
336 if (WARN_ON(!res->pub.channel)) {
337 kref_put(&res->ref, bss_release);
338 return NULL;
339 }
340
341 res->ts = jiffies;
342
343 if (is_zero_ether_addr(res->pub.bssid)) {
344 /* must be mesh, verify */
345 meshid = find_ie(WLAN_EID_MESH_ID, res->pub.information_elements,
346 res->pub.len_information_elements);
347 meshcfg = find_ie(WLAN_EID_MESH_CONFIG,
348 res->pub.information_elements,
349 res->pub.len_information_elements);
350 if (!meshid || !meshcfg ||
351 meshcfg[1] != IEEE80211_MESH_CONFIG_LEN) {
352 /* bogus mesh */
353 kref_put(&res->ref, bss_release);
354 return NULL;
355 }
356 }
357
358 spin_lock_bh(&dev->bss_lock);
359
360 found = rb_find_bss(dev, res);
361
362 if (found && overwrite) {
363 list_replace(&found->list, &res->list);
364 rb_replace_node(&found->rbn, &res->rbn,
365 &dev->bss_tree);
366 kref_put(&found->ref, bss_release);
367 found = res;
368 } else if (found) {
369 kref_get(&found->ref);
370 found->pub.beacon_interval = res->pub.beacon_interval;
371 found->pub.tsf = res->pub.tsf;
372 found->pub.signal = res->pub.signal;
373 found->pub.capability = res->pub.capability;
374 found->ts = res->ts;
375 kref_put(&res->ref, bss_release);
376 } else {
377 /* this "consumes" the reference */
378 list_add_tail(&res->list, &dev->bss_list);
379 rb_insert_bss(dev, res);
380 found = res;
381 }
382
383 dev->bss_generation++;
384 spin_unlock_bh(&dev->bss_lock);
385
386 kref_get(&found->ref);
387 return found;
388}
389
390struct cfg80211_bss *
391cfg80211_inform_bss_frame(struct wiphy *wiphy,
392 struct ieee80211_channel *channel,
393 struct ieee80211_mgmt *mgmt, size_t len,
394 s32 signal, gfp_t gfp)
395{
396 struct cfg80211_internal_bss *res;
397 size_t ielen = len - offsetof(struct ieee80211_mgmt,
398 u.probe_resp.variable);
399 bool overwrite;
400 size_t privsz = wiphy->bss_priv_size;
401
402 if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
403 (signal < 0 || signal > 100)))
404 return NULL;
405
406 if (WARN_ON(!mgmt || !wiphy ||
407 len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
408 return NULL;
409
410 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
411 if (!res)
412 return NULL;
413
414 memcpy(res->pub.bssid, mgmt->bssid, ETH_ALEN);
415 res->pub.channel = channel;
416 res->pub.signal = signal;
417 res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
418 res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
419 res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
420 /* point to after the private area */
421 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
422 memcpy(res->pub.information_elements, mgmt->u.probe_resp.variable, ielen);
423 res->pub.len_information_elements = ielen;
424
425 kref_init(&res->ref);
426
427 overwrite = ieee80211_is_probe_resp(mgmt->frame_control);
428
429 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, overwrite);
430 if (!res)
431 return NULL;
432
433 if (res->pub.capability & WLAN_CAPABILITY_ESS)
434 regulatory_hint_found_beacon(wiphy, channel, gfp);
435
436 /* cfg80211_bss_update gives us a referenced result */
437 return &res->pub;
438}
439EXPORT_SYMBOL(cfg80211_inform_bss_frame);
440
441void cfg80211_put_bss(struct cfg80211_bss *pub)
442{
443 struct cfg80211_internal_bss *bss;
444
445 if (!pub)
446 return;
447
448 bss = container_of(pub, struct cfg80211_internal_bss, pub);
449 kref_put(&bss->ref, bss_release);
450}
451EXPORT_SYMBOL(cfg80211_put_bss);
452
453void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
454{
455 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
456 struct cfg80211_internal_bss *bss;
457
458 if (WARN_ON(!pub))
459 return;
460
461 bss = container_of(pub, struct cfg80211_internal_bss, pub);
462
463 spin_lock_bh(&dev->bss_lock);
464
465 list_del(&bss->list);
466 rb_erase(&bss->rbn, &dev->bss_tree);
467
468 spin_unlock_bh(&dev->bss_lock);
469
470 kref_put(&bss->ref, bss_release);
471}
472EXPORT_SYMBOL(cfg80211_unlink_bss);
473
474#ifdef CONFIG_WIRELESS_EXT
475int cfg80211_wext_siwscan(struct net_device *dev,
476 struct iw_request_info *info,
477 union iwreq_data *wrqu, char *extra)
478{
479 struct cfg80211_registered_device *rdev;
480 struct wiphy *wiphy;
481 struct iw_scan_req *wreq = NULL;
482 struct cfg80211_scan_request *creq;
483 int i, err, n_channels = 0;
484 enum ieee80211_band band;
485
486 if (!netif_running(dev))
487 return -ENETDOWN;
488
489 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);
490
491 if (IS_ERR(rdev))
492 return PTR_ERR(rdev);
493
494 if (rdev->scan_req) {
495 err = -EBUSY;
496 goto out;
497 }
498
499 wiphy = &rdev->wiphy;
500
501 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
502 if (wiphy->bands[band])
503 n_channels += wiphy->bands[band]->n_channels;
504
505 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
506 n_channels * sizeof(void *),
507 GFP_ATOMIC);
508 if (!creq) {
509 err = -ENOMEM;
510 goto out;
511 }
512
513 creq->wiphy = wiphy;
514 creq->ifidx = dev->ifindex;
515 creq->ssids = (void *)(creq + 1);
516 creq->channels = (void *)(creq->ssids + 1);
517 creq->n_channels = n_channels;
518 creq->n_ssids = 1;
519
520 /* all channels */
521 i = 0;
522 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
523 int j;
524 if (!wiphy->bands[band])
525 continue;
526 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
527 creq->channels[i] = &wiphy->bands[band]->channels[j];
528 i++;
529 }
530 }
531
532 /* translate scan request */
533 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
534 wreq = (struct iw_scan_req *)extra;
535
536 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
537 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
538 return -EINVAL;
539 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
540 creq->ssids[0].ssid_len = wreq->essid_len;
541 }
542 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
543 creq->n_ssids = 0;
544 }
545
546 rdev->scan_req = creq;
547 err = rdev->ops->scan(wiphy, dev, creq);
548 if (err) {
549 rdev->scan_req = NULL;
550 kfree(creq);
551 }
552 out:
553 cfg80211_put_dev(rdev);
554 return err;
555}
556EXPORT_SYMBOL(cfg80211_wext_siwscan);
557
558static void ieee80211_scan_add_ies(struct iw_request_info *info,
559 struct cfg80211_bss *bss,
560 char **current_ev, char *end_buf)
561{
562 u8 *pos, *end, *next;
563 struct iw_event iwe;
564
565 if (!bss->information_elements ||
566 !bss->len_information_elements)
567 return;
568
569 /*
570 * If needed, fragment the IEs buffer (at IE boundaries) into short
571 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
572 */
573 pos = bss->information_elements;
574 end = pos + bss->len_information_elements;
575
576 while (end - pos > IW_GENERIC_IE_MAX) {
577 next = pos + 2 + pos[1];
578 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
579 next = next + 2 + next[1];
580
581 memset(&iwe, 0, sizeof(iwe));
582 iwe.cmd = IWEVGENIE;
583 iwe.u.data.length = next - pos;
584 *current_ev = iwe_stream_add_point(info, *current_ev,
585 end_buf, &iwe, pos);
586
587 pos = next;
588 }
589
590 if (end > pos) {
591 memset(&iwe, 0, sizeof(iwe));
592 iwe.cmd = IWEVGENIE;
593 iwe.u.data.length = end - pos;
594 *current_ev = iwe_stream_add_point(info, *current_ev,
595 end_buf, &iwe, pos);
596 }
597}
598
599static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
600{
601 unsigned long end = jiffies;
602
603 if (end >= start)
604 return jiffies_to_msecs(end - start);
605
606 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
607}
608
609static char *
610ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
611 struct cfg80211_internal_bss *bss, char *current_ev,
612 char *end_buf)
613{
614 struct iw_event iwe;
615 u8 *buf, *cfg, *p;
616 u8 *ie = bss->pub.information_elements;
617 int rem = bss->pub.len_information_elements, i, sig;
618 bool ismesh = false;
619
620 memset(&iwe, 0, sizeof(iwe));
621 iwe.cmd = SIOCGIWAP;
622 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
623 memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
624 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
625 IW_EV_ADDR_LEN);
626
627 memset(&iwe, 0, sizeof(iwe));
628 iwe.cmd = SIOCGIWFREQ;
629 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
630 iwe.u.freq.e = 0;
631 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
632 IW_EV_FREQ_LEN);
633
634 memset(&iwe, 0, sizeof(iwe));
635 iwe.cmd = SIOCGIWFREQ;
636 iwe.u.freq.m = bss->pub.channel->center_freq;
637 iwe.u.freq.e = 6;
638 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
639 IW_EV_FREQ_LEN);
640
641 if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
642 memset(&iwe, 0, sizeof(iwe));
643 iwe.cmd = IWEVQUAL;
644 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
645 IW_QUAL_NOISE_INVALID |
646 IW_QUAL_QUAL_UPDATED;
647 switch (wiphy->signal_type) {
648 case CFG80211_SIGNAL_TYPE_MBM:
649 sig = bss->pub.signal / 100;
650 iwe.u.qual.level = sig;
651 iwe.u.qual.updated |= IW_QUAL_DBM;
652 if (sig < -110) /* rather bad */
653 sig = -110;
654 else if (sig > -40) /* perfect */
655 sig = -40;
656 /* will give a range of 0 .. 70 */
657 iwe.u.qual.qual = sig + 110;
658 break;
659 case CFG80211_SIGNAL_TYPE_UNSPEC:
660 iwe.u.qual.level = bss->pub.signal;
661 /* will give range 0 .. 100 */
662 iwe.u.qual.qual = bss->pub.signal;
663 break;
664 default:
665 /* not reached */
666 break;
667 }
668 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
669 &iwe, IW_EV_QUAL_LEN);
670 }
671
672 memset(&iwe, 0, sizeof(iwe));
673 iwe.cmd = SIOCGIWENCODE;
674 if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
675 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
676 else
677 iwe.u.data.flags = IW_ENCODE_DISABLED;
678 iwe.u.data.length = 0;
679 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
680 &iwe, "");
681
682 while (rem >= 2) {
683 /* invalid data */
684 if (ie[1] > rem - 2)
685 break;
686
687 switch (ie[0]) {
688 case WLAN_EID_SSID:
689 memset(&iwe, 0, sizeof(iwe));
690 iwe.cmd = SIOCGIWESSID;
691 iwe.u.data.length = ie[1];
692 iwe.u.data.flags = 1;
693 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
694 &iwe, ie + 2);
695 break;
696 case WLAN_EID_MESH_ID:
697 memset(&iwe, 0, sizeof(iwe));
698 iwe.cmd = SIOCGIWESSID;
699 iwe.u.data.length = ie[1];
700 iwe.u.data.flags = 1;
701 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
702 &iwe, ie + 2);
703 break;
704 case WLAN_EID_MESH_CONFIG:
705 ismesh = true;
706 if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
707 break;
708 buf = kmalloc(50, GFP_ATOMIC);
709 if (!buf)
710 break;
711 cfg = ie + 2;
712 memset(&iwe, 0, sizeof(iwe));
713 iwe.cmd = IWEVCUSTOM;
714 sprintf(buf, "Mesh network (version %d)", cfg[0]);
715 iwe.u.data.length = strlen(buf);
716 current_ev = iwe_stream_add_point(info, current_ev,
717 end_buf,
718 &iwe, buf);
719 sprintf(buf, "Path Selection Protocol ID: "
720 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
721 cfg[4]);
722 iwe.u.data.length = strlen(buf);
723 current_ev = iwe_stream_add_point(info, current_ev,
724 end_buf,
725 &iwe, buf);
726 sprintf(buf, "Path Selection Metric ID: "
727 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
728 cfg[8]);
729 iwe.u.data.length = strlen(buf);
730 current_ev = iwe_stream_add_point(info, current_ev,
731 end_buf,
732 &iwe, buf);
733 sprintf(buf, "Congestion Control Mode ID: "
734 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
735 cfg[11], cfg[12]);
736 iwe.u.data.length = strlen(buf);
737 current_ev = iwe_stream_add_point(info, current_ev,
738 end_buf,
739 &iwe, buf);
740 sprintf(buf, "Channel Precedence: "
741 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
742 cfg[15], cfg[16]);
743 iwe.u.data.length = strlen(buf);
744 current_ev = iwe_stream_add_point(info, current_ev,
745 end_buf,
746 &iwe, buf);
747 kfree(buf);
748 break;
749 case WLAN_EID_SUPP_RATES:
750 case WLAN_EID_EXT_SUPP_RATES:
751 /* display all supported rates in readable format */
752 p = current_ev + iwe_stream_lcp_len(info);
753
754 memset(&iwe, 0, sizeof(iwe));
755 iwe.cmd = SIOCGIWRATE;
756 /* Those two flags are ignored... */
757 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
758
759 for (i = 0; i < ie[1]; i++) {
760 iwe.u.bitrate.value =
761 ((ie[i + 2] & 0x7f) * 500000);
762 p = iwe_stream_add_value(info, current_ev, p,
763 end_buf, &iwe, IW_EV_PARAM_LEN);
764 }
765 current_ev = p;
766 break;
767 }
768 rem -= ie[1] + 2;
769 ie += ie[1] + 2;
770 }
771
772 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
773 || ismesh) {
774 memset(&iwe, 0, sizeof(iwe));
775 iwe.cmd = SIOCGIWMODE;
776 if (ismesh)
777 iwe.u.mode = IW_MODE_MESH;
778 else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
779 iwe.u.mode = IW_MODE_MASTER;
780 else
781 iwe.u.mode = IW_MODE_ADHOC;
782 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
783 &iwe, IW_EV_UINT_LEN);
784 }
785
786 buf = kmalloc(30, GFP_ATOMIC);
787 if (buf) {
788 memset(&iwe, 0, sizeof(iwe));
789 iwe.cmd = IWEVCUSTOM;
790 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf));
791 iwe.u.data.length = strlen(buf);
792 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
793 &iwe, buf);
794 memset(&iwe, 0, sizeof(iwe));
795 iwe.cmd = IWEVCUSTOM;
796 sprintf(buf, " Last beacon: %ums ago",
797 elapsed_jiffies_msecs(bss->ts));
798 iwe.u.data.length = strlen(buf);
799 current_ev = iwe_stream_add_point(info, current_ev,
800 end_buf, &iwe, buf);
801 kfree(buf);
802 }
803
804 ieee80211_scan_add_ies(info, &bss->pub, &current_ev, end_buf);
805
806 return current_ev;
807}
808
809
810static int ieee80211_scan_results(struct cfg80211_registered_device *dev,
811 struct iw_request_info *info,
812 char *buf, size_t len)
813{
814 char *current_ev = buf;
815 char *end_buf = buf + len;
816 struct cfg80211_internal_bss *bss;
817
818 spin_lock_bh(&dev->bss_lock);
819 cfg80211_bss_expire(dev);
820
821 list_for_each_entry(bss, &dev->bss_list, list) {
822 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
823 spin_unlock_bh(&dev->bss_lock);
824 return -E2BIG;
825 }
826 current_ev = ieee80211_bss(&dev->wiphy, info, bss,
827 current_ev, end_buf);
828 }
829 spin_unlock_bh(&dev->bss_lock);
830 return current_ev - buf;
831}
832
833
834int cfg80211_wext_giwscan(struct net_device *dev,
835 struct iw_request_info *info,
836 struct iw_point *data, char *extra)
837{
838 struct cfg80211_registered_device *rdev;
839 int res;
840
841 if (!netif_running(dev))
842 return -ENETDOWN;
843
844 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);
845
846 if (IS_ERR(rdev))
847 return PTR_ERR(rdev);
848
849 if (rdev->scan_req) {
850 res = -EAGAIN;
851 goto out;
852 }
853
854 res = ieee80211_scan_results(rdev, info, extra, data->length);
855 data->length = 0;
856 if (res >= 0) {
857 data->length = res;
858 res = 0;
859 }
860
861 out:
862 cfg80211_put_dev(rdev);
863 return res;
864}
865EXPORT_SYMBOL(cfg80211_wext_giwscan);
866#endif
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 79a382877641..efe3c5c92b2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -31,7 +31,7 @@ static ssize_t name ## _show(struct device *dev, \
31 return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ 31 return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
32} 32}
33 33
34SHOW_FMT(index, "%d", idx); 34SHOW_FMT(index, "%d", wiphy_idx);
35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
36 36
37static struct device_attribute ieee80211_dev_attrs[] = { 37static struct device_attribute ieee80211_dev_attrs[] = {
@@ -55,6 +55,41 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
55} 55}
56#endif 56#endif
57 57
58static int wiphy_suspend(struct device *dev, pm_message_t state)
59{
60 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
61 int ret = 0;
62
63 rdev->suspend_at = get_seconds();
64
65 if (rdev->ops->suspend) {
66 rtnl_lock();
67 ret = rdev->ops->suspend(&rdev->wiphy);
68 rtnl_unlock();
69 }
70
71 return ret;
72}
73
74static int wiphy_resume(struct device *dev)
75{
76 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
77 int ret = 0;
78
79 /* Age scan results with time spent in suspend */
80 spin_lock_bh(&rdev->bss_lock);
81 cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at);
82 spin_unlock_bh(&rdev->bss_lock);
83
84 if (rdev->ops->resume) {
85 rtnl_lock();
86 ret = rdev->ops->resume(&rdev->wiphy);
87 rtnl_unlock();
88 }
89
90 return ret;
91}
92
58struct class ieee80211_class = { 93struct class ieee80211_class = {
59 .name = "ieee80211", 94 .name = "ieee80211",
60 .owner = THIS_MODULE, 95 .owner = THIS_MODULE,
@@ -63,6 +98,8 @@ struct class ieee80211_class = {
63#ifdef CONFIG_HOTPLUG 98#ifdef CONFIG_HOTPLUG
64 .dev_uevent = wiphy_uevent, 99 .dev_uevent = wiphy_uevent,
65#endif 100#endif
101 .suspend = wiphy_suspend,
102 .resume = wiphy_resume,
66}; 103};
67 104
68int wiphy_sysfs_init(void) 105int wiphy_sysfs_init(void)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index e76cc28b0345..487cdd9bcffc 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -9,7 +9,7 @@
9 9
10struct ieee80211_rate * 10struct ieee80211_rate *
11ieee80211_get_response_rate(struct ieee80211_supported_band *sband, 11ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
12 u64 basic_rates, int bitrate) 12 u32 basic_rates, int bitrate)
13{ 13{
14 struct ieee80211_rate *result = &sband->bitrates[0]; 14 struct ieee80211_rate *result = &sband->bitrates[0];
15 int i; 15 int i;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 58e489fd4aed..b84a9b4fe96a 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -137,3 +137,100 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
137 return 0; 137 return 0;
138} 138}
139EXPORT_SYMBOL(cfg80211_wext_giwmode); 139EXPORT_SYMBOL(cfg80211_wext_giwmode);
140
141
142int cfg80211_wext_giwrange(struct net_device *dev,
143 struct iw_request_info *info,
144 struct iw_point *data, char *extra)
145{
146 struct wireless_dev *wdev = dev->ieee80211_ptr;
147 struct iw_range *range = (struct iw_range *) extra;
148 enum ieee80211_band band;
149 int c = 0;
150
151 if (!wdev)
152 return -EOPNOTSUPP;
153
154 data->length = sizeof(struct iw_range);
155 memset(range, 0, sizeof(struct iw_range));
156
157 range->we_version_compiled = WIRELESS_EXT;
158 range->we_version_source = 21;
159 range->retry_capa = IW_RETRY_LIMIT;
160 range->retry_flags = IW_RETRY_LIMIT;
161 range->min_retry = 0;
162 range->max_retry = 255;
163 range->min_rts = 0;
164 range->max_rts = 2347;
165 range->min_frag = 256;
166 range->max_frag = 2346;
167
168 range->encoding_size[0] = 5;
169 range->encoding_size[1] = 13;
170 range->num_encoding_sizes = 2;
171 range->max_encoding_tokens = 4;
172
173 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
174
175 switch (wdev->wiphy->signal_type) {
176 case CFG80211_SIGNAL_TYPE_NONE:
177 break;
178 case CFG80211_SIGNAL_TYPE_MBM:
179 range->max_qual.level = -110;
180 range->max_qual.qual = 70;
181 range->avg_qual.qual = 35;
182 range->max_qual.updated |= IW_QUAL_DBM;
183 range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
184 range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
185 break;
186 case CFG80211_SIGNAL_TYPE_UNSPEC:
187 range->max_qual.level = 100;
188 range->max_qual.qual = 100;
189 range->avg_qual.qual = 50;
190 range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
191 range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
192 break;
193 }
194
195 range->avg_qual.level = range->max_qual.level / 2;
196 range->avg_qual.noise = range->max_qual.noise / 2;
197 range->avg_qual.updated = range->max_qual.updated;
198
199 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
200 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
201
202
203 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
204 int i;
205 struct ieee80211_supported_band *sband;
206
207 sband = wdev->wiphy->bands[band];
208
209 if (!sband)
210 continue;
211
212 for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
213 struct ieee80211_channel *chan = &sband->channels[i];
214
215 if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
216 range->freq[c].i =
217 ieee80211_frequency_to_channel(
218 chan->center_freq);
219 range->freq[c].m = chan->center_freq;
220 range->freq[c].e = 6;
221 c++;
222 }
223 }
224 }
225 range->num_channels = c;
226 range->num_frequency = c;
227
228 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
229 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
230 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
231
232 range->scan_capa |= IW_SCAN_CAPA_ESSID;
233
234 return 0;
235}
236EXPORT_SYMBOL(cfg80211_wext_giwrange);