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.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 92b812442488..7fdb9409ad2a 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-2009 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -31,15 +31,10 @@ MODULE_AUTHOR("Johannes Berg");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_DESCRIPTION("wireless configuration support"); 32MODULE_DESCRIPTION("wireless configuration support");
33 33
34/* RCU might be appropriate here since we usually 34/* RCU-protected (and cfg80211_mutex for writers) */
35 * only read the list, and that can happen quite
36 * often because we need to do it for each command */
37LIST_HEAD(cfg80211_rdev_list); 35LIST_HEAD(cfg80211_rdev_list);
38int cfg80211_rdev_list_generation; 36int cfg80211_rdev_list_generation;
39 37
40/*
41 * This is used to protect the cfg80211_rdev_list
42 */
43DEFINE_MUTEX(cfg80211_mutex); 38DEFINE_MUTEX(cfg80211_mutex);
44 39
45/* for debugfs */ 40/* for debugfs */
@@ -402,6 +397,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
402 rdev->wiphy.retry_long = 4; 397 rdev->wiphy.retry_long = 4;
403 rdev->wiphy.frag_threshold = (u32) -1; 398 rdev->wiphy.frag_threshold = (u32) -1;
404 rdev->wiphy.rts_threshold = (u32) -1; 399 rdev->wiphy.rts_threshold = (u32) -1;
400 rdev->wiphy.coverage_class = 0;
405 401
406 return &rdev->wiphy; 402 return &rdev->wiphy;
407} 403}
@@ -417,6 +413,18 @@ int wiphy_register(struct wiphy *wiphy)
417 int i; 413 int i;
418 u16 ifmodes = wiphy->interface_modes; 414 u16 ifmodes = wiphy->interface_modes;
419 415
416 if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
417 return -EINVAL;
418
419 if (WARN_ON(wiphy->addresses &&
420 !is_zero_ether_addr(wiphy->perm_addr) &&
421 memcmp(wiphy->perm_addr, wiphy->addresses[0].addr,
422 ETH_ALEN)))
423 return -EINVAL;
424
425 if (wiphy->addresses)
426 memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
427
420 /* sanity check ifmodes */ 428 /* sanity check ifmodes */
421 WARN_ON(!ifmodes); 429 WARN_ON(!ifmodes);
422 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; 430 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
@@ -476,7 +484,7 @@ int wiphy_register(struct wiphy *wiphy)
476 /* set up regulatory info */ 484 /* set up regulatory info */
477 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); 485 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
478 486
479 list_add(&rdev->list, &cfg80211_rdev_list); 487 list_add_rcu(&rdev->list, &cfg80211_rdev_list);
480 cfg80211_rdev_list_generation++; 488 cfg80211_rdev_list_generation++;
481 489
482 mutex_unlock(&cfg80211_mutex); 490 mutex_unlock(&cfg80211_mutex);
@@ -553,7 +561,8 @@ void wiphy_unregister(struct wiphy *wiphy)
553 * it impossible to find from userspace. 561 * it impossible to find from userspace.
554 */ 562 */
555 debugfs_remove_recursive(rdev->wiphy.debugfsdir); 563 debugfs_remove_recursive(rdev->wiphy.debugfsdir);
556 list_del(&rdev->list); 564 list_del_rcu(&rdev->list);
565 synchronize_rcu();
557 566
558 /* 567 /*
559 * Try to grab rdev->mtx. If a command is still in progress, 568 * Try to grab rdev->mtx. If a command is still in progress,
@@ -668,8 +677,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
668 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work); 677 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
669 INIT_LIST_HEAD(&wdev->event_list); 678 INIT_LIST_HEAD(&wdev->event_list);
670 spin_lock_init(&wdev->event_lock); 679 spin_lock_init(&wdev->event_lock);
680 INIT_LIST_HEAD(&wdev->action_registrations);
681 spin_lock_init(&wdev->action_registrations_lock);
682
671 mutex_lock(&rdev->devlist_mtx); 683 mutex_lock(&rdev->devlist_mtx);
672 list_add(&wdev->list, &rdev->netdev_list); 684 list_add_rcu(&wdev->list, &rdev->netdev_list);
673 rdev->devlist_generation++; 685 rdev->devlist_generation++;
674 /* can only change netns with wiphy */ 686 /* can only change netns with wiphy */
675 dev->features |= NETIF_F_NETNS_LOCAL; 687 dev->features |= NETIF_F_NETNS_LOCAL;
@@ -686,19 +698,21 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
686 wdev->wext.default_key = -1; 698 wdev->wext.default_key = -1;
687 wdev->wext.default_mgmt_key = -1; 699 wdev->wext.default_mgmt_key = -1;
688 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 700 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
701#endif
702
689 if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) 703 if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
690 wdev->wext.ps = true; 704 wdev->ps = true;
691 else 705 else
692 wdev->wext.ps = false; 706 wdev->ps = false;
693 wdev->wext.ps_timeout = 100; 707 wdev->ps_timeout = 100;
694 if (rdev->ops->set_power_mgmt) 708 if (rdev->ops->set_power_mgmt)
695 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, 709 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
696 wdev->wext.ps, 710 wdev->ps,
697 wdev->wext.ps_timeout)) { 711 wdev->ps_timeout)) {
698 /* assume this means it's off */ 712 /* assume this means it's off */
699 wdev->wext.ps = false; 713 wdev->ps = false;
700 } 714 }
701#endif 715
702 if (!dev->ethtool_ops) 716 if (!dev->ethtool_ops)
703 dev->ethtool_ops = &cfg80211_ethtool_ops; 717 dev->ethtool_ops = &cfg80211_ethtool_ops;
704 718
@@ -781,13 +795,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
781 */ 795 */
782 if (!list_empty(&wdev->list)) { 796 if (!list_empty(&wdev->list)) {
783 sysfs_remove_link(&dev->dev.kobj, "phy80211"); 797 sysfs_remove_link(&dev->dev.kobj, "phy80211");
784 list_del_init(&wdev->list); 798 list_del_rcu(&wdev->list);
785 rdev->devlist_generation++; 799 rdev->devlist_generation++;
800 cfg80211_mlme_purge_actions(wdev);
786#ifdef CONFIG_CFG80211_WEXT 801#ifdef CONFIG_CFG80211_WEXT
787 kfree(wdev->wext.keys); 802 kfree(wdev->wext.keys);
788#endif 803#endif
789 } 804 }
790 mutex_unlock(&rdev->devlist_mtx); 805 mutex_unlock(&rdev->devlist_mtx);
806 /*
807 * synchronise (so that we won't find this netdev
808 * from other code any more) and then clear the list
809 * head so that the above code can safely check for
810 * !list_empty() to avoid double-cleanup.
811 */
812 synchronize_rcu();
813 INIT_LIST_HEAD(&wdev->list);
791 break; 814 break;
792 case NETDEV_PRE_UP: 815 case NETDEV_PRE_UP:
793 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 816 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))