aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r--net/wireless/core.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f1da0b93bc56..5031db7b275b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the linux wireless configuration interface. 2 * This is the linux wireless configuration interface.
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -19,6 +19,7 @@
19#include "nl80211.h" 19#include "nl80211.h"
20#include "core.h" 20#include "core.h"
21#include "sysfs.h" 21#include "sysfs.h"
22#include "reg.h"
22 23
23/* name for sysfs, %d is appended */ 24/* name for sysfs, %d is appended */
24#define PHY_NAME "phy" 25#define PHY_NAME "phy"
@@ -32,7 +33,6 @@ MODULE_DESCRIPTION("wireless configuration support");
32 * often because we need to do it for each command */ 33 * often because we need to do it for each command */
33LIST_HEAD(cfg80211_drv_list); 34LIST_HEAD(cfg80211_drv_list);
34DEFINE_MUTEX(cfg80211_drv_mutex); 35DEFINE_MUTEX(cfg80211_drv_mutex);
35static int wiphy_counter;
36 36
37/* for debugfs */ 37/* for debugfs */
38static struct dentry *ieee80211_debugfs_dir; 38static struct dentry *ieee80211_debugfs_dir;
@@ -184,7 +184,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
184 if (result) 184 if (result)
185 goto out_unlock; 185 goto out_unlock;
186 186
187 if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, 187 if (rdev->wiphy.debugfsdir &&
188 !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
188 rdev->wiphy.debugfsdir, 189 rdev->wiphy.debugfsdir,
189 rdev->wiphy.debugfsdir->d_parent, 190 rdev->wiphy.debugfsdir->d_parent,
190 newname)) 191 newname))
@@ -204,6 +205,8 @@ out_unlock:
204 205
205struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv) 206struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
206{ 207{
208 static int wiphy_counter;
209
207 struct cfg80211_registered_device *drv; 210 struct cfg80211_registered_device *drv;
208 int alloc_size; 211 int alloc_size;
209 212
@@ -220,21 +223,18 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
220 223
221 mutex_lock(&cfg80211_drv_mutex); 224 mutex_lock(&cfg80211_drv_mutex);
222 225
223 drv->idx = wiphy_counter; 226 drv->idx = wiphy_counter++;
224
225 /* now increase counter for the next device unless
226 * it has wrapped previously */
227 if (wiphy_counter >= 0)
228 wiphy_counter++;
229
230 mutex_unlock(&cfg80211_drv_mutex);
231 227
232 if (unlikely(drv->idx < 0)) { 228 if (unlikely(drv->idx < 0)) {
229 wiphy_counter--;
230 mutex_unlock(&cfg80211_drv_mutex);
233 /* ugh, wrapped! */ 231 /* ugh, wrapped! */
234 kfree(drv); 232 kfree(drv);
235 return NULL; 233 return NULL;
236 } 234 }
237 235
236 mutex_unlock(&cfg80211_drv_mutex);
237
238 /* give it a proper name */ 238 /* give it a proper name */
239 snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE, 239 snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE,
240 PHY_NAME "%d", drv->idx); 240 PHY_NAME "%d", drv->idx);
@@ -259,6 +259,13 @@ int wiphy_register(struct wiphy *wiphy)
259 struct ieee80211_supported_band *sband; 259 struct ieee80211_supported_band *sband;
260 bool have_band = false; 260 bool have_band = false;
261 int i; 261 int i;
262 u16 ifmodes = wiphy->interface_modes;
263
264 /* sanity check ifmodes */
265 WARN_ON(!ifmodes);
266 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
267 if (WARN_ON(ifmodes != wiphy->interface_modes))
268 wiphy->interface_modes = ifmodes;
262 269
263 /* sanity check supported bands/channels */ 270 /* sanity check supported bands/channels */
264 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 271 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
@@ -295,7 +302,9 @@ int wiphy_register(struct wiphy *wiphy)
295 ieee80211_set_bitrate_flags(wiphy); 302 ieee80211_set_bitrate_flags(wiphy);
296 303
297 /* set up regulatory info */ 304 /* set up regulatory info */
298 wiphy_update_regulatory(wiphy); 305 mutex_lock(&cfg80211_reg_mutex);
306 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
307 mutex_unlock(&cfg80211_reg_mutex);
299 308
300 mutex_lock(&cfg80211_drv_mutex); 309 mutex_lock(&cfg80211_drv_mutex);
301 310
@@ -309,6 +318,8 @@ int wiphy_register(struct wiphy *wiphy)
309 drv->wiphy.debugfsdir = 318 drv->wiphy.debugfsdir =
310 debugfs_create_dir(wiphy_name(&drv->wiphy), 319 debugfs_create_dir(wiphy_name(&drv->wiphy),
311 ieee80211_debugfs_dir); 320 ieee80211_debugfs_dir);
321 if (IS_ERR(drv->wiphy.debugfsdir))
322 drv->wiphy.debugfsdir = NULL;
312 323
313 res = 0; 324 res = 0;
314out_unlock: 325out_unlock:
@@ -373,6 +384,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
373 384
374 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); 385 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
375 386
387 WARN_ON(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_UNSPECIFIED);
388
376 switch (state) { 389 switch (state) {
377 case NETDEV_REGISTER: 390 case NETDEV_REGISTER:
378 mutex_lock(&rdev->devlist_mtx); 391 mutex_lock(&rdev->devlist_mtx);
@@ -404,7 +417,9 @@ static struct notifier_block cfg80211_netdev_notifier = {
404 417
405static int cfg80211_init(void) 418static int cfg80211_init(void)
406{ 419{
407 int err = wiphy_sysfs_init(); 420 int err;
421
422 err = wiphy_sysfs_init();
408 if (err) 423 if (err)
409 goto out_fail_sysfs; 424 goto out_fail_sysfs;
410 425
@@ -418,8 +433,14 @@ static int cfg80211_init(void)
418 433
419 ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL); 434 ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL);
420 435
436 err = regulatory_init();
437 if (err)
438 goto out_fail_reg;
439
421 return 0; 440 return 0;
422 441
442out_fail_reg:
443 debugfs_remove(ieee80211_debugfs_dir);
423out_fail_nl80211: 444out_fail_nl80211:
424 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 445 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
425out_fail_notifier: 446out_fail_notifier:
@@ -427,6 +448,7 @@ out_fail_notifier:
427out_fail_sysfs: 448out_fail_sysfs:
428 return err; 449 return err;
429} 450}
451
430subsys_initcall(cfg80211_init); 452subsys_initcall(cfg80211_init);
431 453
432static void cfg80211_exit(void) 454static void cfg80211_exit(void)
@@ -435,5 +457,6 @@ static void cfg80211_exit(void)
435 nl80211_exit(); 457 nl80211_exit();
436 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 458 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
437 wiphy_sysfs_exit(); 459 wiphy_sysfs_exit();
460 regulatory_exit();
438} 461}
439module_exit(cfg80211_exit); 462module_exit(cfg80211_exit);