aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/core.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/wireless/core.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r--net/wireless/core.c231
1 files changed, 163 insertions, 68 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d6d046b9f6f2..880dbe2e6f94 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -4,6 +4,8 @@
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
7#include <linux/if.h> 9#include <linux/if.h>
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/err.h> 11#include <linux/err.h>
@@ -44,6 +46,11 @@ static struct dentry *ieee80211_debugfs_dir;
44/* for the cleanup, scan and event works */ 46/* for the cleanup, scan and event works */
45struct workqueue_struct *cfg80211_wq; 47struct workqueue_struct *cfg80211_wq;
46 48
49static bool cfg80211_disable_40mhz_24ghz;
50module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
51MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
52 "Disable 40MHz support in the 2.4GHz band");
53
47/* requires cfg80211_mutex to be held! */ 54/* requires cfg80211_mutex to be held! */
48struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) 55struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
49{ 56{
@@ -216,8 +223,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
216 rdev->wiphy.debugfsdir, 223 rdev->wiphy.debugfsdir,
217 rdev->wiphy.debugfsdir->d_parent, 224 rdev->wiphy.debugfsdir->d_parent,
218 newname)) 225 newname))
219 printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", 226 pr_err("failed to rename debugfs dir to %s!\n", newname);
220 newname);
221 227
222 nl80211_notify_dev_rename(rdev); 228 nl80211_notify_dev_rename(rdev);
223 229
@@ -253,11 +259,16 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
253 WARN_ON(err); 259 WARN_ON(err);
254 wdev->netdev->features |= NETIF_F_NETNS_LOCAL; 260 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
255 } 261 }
262
263 return err;
256 } 264 }
257 265
258 wiphy_net_set(&rdev->wiphy, net); 266 wiphy_net_set(&rdev->wiphy, net);
259 267
260 return err; 268 err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev));
269 WARN_ON(err);
270
271 return 0;
261} 272}
262 273
263static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) 274static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
@@ -326,6 +337,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
326 WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf); 337 WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf);
327 WARN_ON(ops->add_station && !ops->del_station); 338 WARN_ON(ops->add_station && !ops->del_station);
328 WARN_ON(ops->add_mpath && !ops->del_mpath); 339 WARN_ON(ops->add_mpath && !ops->del_mpath);
340 WARN_ON(ops->join_mesh && !ops->leave_mesh);
329 341
330 alloc_size = sizeof(*rdev) + sizeof_priv; 342 alloc_size = sizeof(*rdev) + sizeof_priv;
331 343
@@ -354,11 +366,12 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
354 366
355 mutex_init(&rdev->mtx); 367 mutex_init(&rdev->mtx);
356 mutex_init(&rdev->devlist_mtx); 368 mutex_init(&rdev->devlist_mtx);
369 mutex_init(&rdev->sched_scan_mtx);
357 INIT_LIST_HEAD(&rdev->netdev_list); 370 INIT_LIST_HEAD(&rdev->netdev_list);
358 spin_lock_init(&rdev->bss_lock); 371 spin_lock_init(&rdev->bss_lock);
359 INIT_LIST_HEAD(&rdev->bss_list); 372 INIT_LIST_HEAD(&rdev->bss_list);
360 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 373 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
361 374 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
362#ifdef CONFIG_CFG80211_WEXT 375#ifdef CONFIG_CFG80211_WEXT
363 rdev->wiphy.wext = &cfg80211_wext_handler; 376 rdev->wiphy.wext = &cfg80211_wext_handler;
364#endif 377#endif
@@ -404,6 +417,67 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
404} 417}
405EXPORT_SYMBOL(wiphy_new); 418EXPORT_SYMBOL(wiphy_new);
406 419
420static int wiphy_verify_combinations(struct wiphy *wiphy)
421{
422 const struct ieee80211_iface_combination *c;
423 int i, j;
424
425 /* If we have combinations enforce them */
426 if (wiphy->n_iface_combinations)
427 wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS;
428
429 for (i = 0; i < wiphy->n_iface_combinations; i++) {
430 u32 cnt = 0;
431 u16 all_iftypes = 0;
432
433 c = &wiphy->iface_combinations[i];
434
435 /* Combinations with just one interface aren't real */
436 if (WARN_ON(c->max_interfaces < 2))
437 return -EINVAL;
438
439 /* Need at least one channel */
440 if (WARN_ON(!c->num_different_channels))
441 return -EINVAL;
442
443 if (WARN_ON(!c->n_limits))
444 return -EINVAL;
445
446 for (j = 0; j < c->n_limits; j++) {
447 u16 types = c->limits[j].types;
448
449 /*
450 * interface types shouldn't overlap, this is
451 * used in cfg80211_can_change_interface()
452 */
453 if (WARN_ON(types & all_iftypes))
454 return -EINVAL;
455 all_iftypes |= types;
456
457 if (WARN_ON(!c->limits[j].max))
458 return -EINVAL;
459
460 /* Shouldn't list software iftypes in combinations! */
461 if (WARN_ON(wiphy->software_iftypes & types))
462 return -EINVAL;
463
464 cnt += c->limits[j].max;
465 /*
466 * Don't advertise an unsupported type
467 * in a combination.
468 */
469 if (WARN_ON((wiphy->interface_modes & types) != types))
470 return -EINVAL;
471 }
472
473 /* You can't even choose that many! */
474 if (WARN_ON(cnt < c->max_interfaces))
475 return -EINVAL;
476 }
477
478 return 0;
479}
480
407int wiphy_register(struct wiphy *wiphy) 481int wiphy_register(struct wiphy *wiphy)
408{ 482{
409 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 483 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -428,10 +502,14 @@ int wiphy_register(struct wiphy *wiphy)
428 502
429 /* sanity check ifmodes */ 503 /* sanity check ifmodes */
430 WARN_ON(!ifmodes); 504 WARN_ON(!ifmodes);
431 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; 505 ifmodes &= ((1 << NUM_NL80211_IFTYPES) - 1) & ~1;
432 if (WARN_ON(ifmodes != wiphy->interface_modes)) 506 if (WARN_ON(ifmodes != wiphy->interface_modes))
433 wiphy->interface_modes = ifmodes; 507 wiphy->interface_modes = ifmodes;
434 508
509 res = wiphy_verify_combinations(wiphy);
510 if (res)
511 return res;
512
435 /* sanity check supported bands/channels */ 513 /* sanity check supported bands/channels */
436 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 514 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
437 sband = wiphy->bands[band]; 515 sband = wiphy->bands[band];
@@ -444,6 +522,18 @@ int wiphy_register(struct wiphy *wiphy)
444 return -EINVAL; 522 return -EINVAL;
445 523
446 /* 524 /*
525 * Since cfg80211_disable_40mhz_24ghz is global, we can
526 * modify the sband's ht data even if the driver uses a
527 * global structure for that.
528 */
529 if (cfg80211_disable_40mhz_24ghz &&
530 band == IEEE80211_BAND_2GHZ &&
531 sband->ht_cap.ht_supported) {
532 sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
533 sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
534 }
535
536 /*
447 * Since we use a u32 for rate bitmaps in 537 * Since we use a u32 for rate bitmaps in
448 * ieee80211_get_response_rate, we cannot 538 * ieee80211_get_response_rate, we cannot
449 * have more than 32 legacy rates. 539 * have more than 32 legacy rates.
@@ -469,6 +559,13 @@ int wiphy_register(struct wiphy *wiphy)
469 return -EINVAL; 559 return -EINVAL;
470 } 560 }
471 561
562 if (rdev->wiphy.wowlan.n_patterns) {
563 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
564 rdev->wiphy.wowlan.pattern_min_len >
565 rdev->wiphy.wowlan.pattern_max_len))
566 return -EINVAL;
567 }
568
472 /* check and set up bitrates */ 569 /* check and set up bitrates */
473 ieee80211_set_bitrate_flags(wiphy); 570 ieee80211_set_bitrate_flags(wiphy);
474 571
@@ -605,8 +702,10 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
605 rfkill_destroy(rdev->rfkill); 702 rfkill_destroy(rdev->rfkill);
606 mutex_destroy(&rdev->mtx); 703 mutex_destroy(&rdev->mtx);
607 mutex_destroy(&rdev->devlist_mtx); 704 mutex_destroy(&rdev->devlist_mtx);
705 mutex_destroy(&rdev->sched_scan_mtx);
608 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 706 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
609 cfg80211_put_bss(&scan->pub); 707 cfg80211_put_bss(&scan->pub);
708 cfg80211_rdev_free_wowlan(rdev);
610 kfree(rdev); 709 kfree(rdev);
611} 710}
612 711
@@ -642,6 +741,15 @@ static void wdev_cleanup_work(struct work_struct *work)
642 741
643 cfg80211_unlock_rdev(rdev); 742 cfg80211_unlock_rdev(rdev);
644 743
744 mutex_lock(&rdev->sched_scan_mtx);
745
746 if (WARN_ON(rdev->sched_scan_req &&
747 rdev->sched_scan_req->dev == wdev->netdev)) {
748 __cfg80211_stop_sched_scan(rdev, false);
749 }
750
751 mutex_unlock(&rdev->sched_scan_mtx);
752
645 mutex_lock(&rdev->devlist_mtx); 753 mutex_lock(&rdev->devlist_mtx);
646 rdev->opencount--; 754 rdev->opencount--;
647 mutex_unlock(&rdev->devlist_mtx); 755 mutex_unlock(&rdev->devlist_mtx);
@@ -661,6 +769,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
661 struct net_device *dev = ndev; 769 struct net_device *dev = ndev;
662 struct wireless_dev *wdev = dev->ieee80211_ptr; 770 struct wireless_dev *wdev = dev->ieee80211_ptr;
663 struct cfg80211_registered_device *rdev; 771 struct cfg80211_registered_device *rdev;
772 int ret;
664 773
665 if (!wdev) 774 if (!wdev)
666 return NOTIFY_DONE; 775 return NOTIFY_DONE;
@@ -683,8 +792,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
683 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work); 792 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
684 INIT_LIST_HEAD(&wdev->event_list); 793 INIT_LIST_HEAD(&wdev->event_list);
685 spin_lock_init(&wdev->event_lock); 794 spin_lock_init(&wdev->event_lock);
686 INIT_LIST_HEAD(&wdev->action_registrations); 795 INIT_LIST_HEAD(&wdev->mgmt_registrations);
687 spin_lock_init(&wdev->action_registrations_lock); 796 spin_lock_init(&wdev->mgmt_registrations_lock);
688 797
689 mutex_lock(&rdev->devlist_mtx); 798 mutex_lock(&rdev->devlist_mtx);
690 list_add_rcu(&wdev->list, &rdev->netdev_list); 799 list_add_rcu(&wdev->list, &rdev->netdev_list);
@@ -694,8 +803,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
694 803
695 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj, 804 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
696 "phy80211")) { 805 "phy80211")) {
697 printk(KERN_ERR "wireless: failed to add phy80211 " 806 pr_err("failed to add phy80211 symlink to netdev!\n");
698 "symlink to netdev!\n");
699 } 807 }
700 wdev->netdev = dev; 808 wdev->netdev = dev;
701 wdev->sme_state = CFG80211_SME_IDLE; 809 wdev->sme_state = CFG80211_SME_IDLE;
@@ -712,18 +820,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
712 wdev->ps = false; 820 wdev->ps = false;
713 /* allow mac80211 to determine the timeout */ 821 /* allow mac80211 to determine the timeout */
714 wdev->ps_timeout = -1; 822 wdev->ps_timeout = -1;
715 if (rdev->ops->set_power_mgmt)
716 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
717 wdev->ps,
718 wdev->ps_timeout)) {
719 /* assume this means it's off */
720 wdev->ps = false;
721 }
722 823
723 if (!dev->ethtool_ops) 824 if (!dev->ethtool_ops)
724 dev->ethtool_ops = &cfg80211_ethtool_ops; 825 dev->ethtool_ops = &cfg80211_ethtool_ops;
725 826
726 if ((wdev->iftype == NL80211_IFTYPE_STATION || 827 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
828 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
727 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) 829 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
728 dev->priv_flags |= IFF_DONT_BRIDGE; 830 dev->priv_flags |= IFF_DONT_BRIDGE;
729 break; 831 break;
@@ -732,7 +834,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
732 case NL80211_IFTYPE_ADHOC: 834 case NL80211_IFTYPE_ADHOC:
733 cfg80211_leave_ibss(rdev, dev, true); 835 cfg80211_leave_ibss(rdev, dev, true);
734 break; 836 break;
837 case NL80211_IFTYPE_P2P_CLIENT:
735 case NL80211_IFTYPE_STATION: 838 case NL80211_IFTYPE_STATION:
839 mutex_lock(&rdev->sched_scan_mtx);
840 __cfg80211_stop_sched_scan(rdev, false);
841 mutex_unlock(&rdev->sched_scan_mtx);
842
736 wdev_lock(wdev); 843 wdev_lock(wdev);
737#ifdef CONFIG_CFG80211_WEXT 844#ifdef CONFIG_CFG80211_WEXT
738 kfree(wdev->wext.ie); 845 kfree(wdev->wext.ie);
@@ -745,9 +852,13 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
745 cfg80211_mlme_down(rdev, dev); 852 cfg80211_mlme_down(rdev, dev);
746 wdev_unlock(wdev); 853 wdev_unlock(wdev);
747 break; 854 break;
855 case NL80211_IFTYPE_MESH_POINT:
856 cfg80211_leave_mesh(rdev, dev);
857 break;
748 default: 858 default:
749 break; 859 break;
750 } 860 }
861 wdev->beacon_interval = 0;
751 break; 862 break;
752 case NETDEV_DOWN: 863 case NETDEV_DOWN:
753 dev_hold(dev); 864 dev_hold(dev);
@@ -768,23 +879,53 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
768 } 879 }
769 cfg80211_lock_rdev(rdev); 880 cfg80211_lock_rdev(rdev);
770 mutex_lock(&rdev->devlist_mtx); 881 mutex_lock(&rdev->devlist_mtx);
771#ifdef CONFIG_CFG80211_WEXT
772 wdev_lock(wdev); 882 wdev_lock(wdev);
773 switch (wdev->iftype) { 883 switch (wdev->iftype) {
884#ifdef CONFIG_CFG80211_WEXT
774 case NL80211_IFTYPE_ADHOC: 885 case NL80211_IFTYPE_ADHOC:
775 cfg80211_ibss_wext_join(rdev, wdev); 886 cfg80211_ibss_wext_join(rdev, wdev);
776 break; 887 break;
777 case NL80211_IFTYPE_STATION: 888 case NL80211_IFTYPE_STATION:
778 cfg80211_mgd_wext_connect(rdev, wdev); 889 cfg80211_mgd_wext_connect(rdev, wdev);
779 break; 890 break;
891#endif
892#ifdef CONFIG_MAC80211_MESH
893 case NL80211_IFTYPE_MESH_POINT:
894 {
895 /* backward compat code... */
896 struct mesh_setup setup;
897 memcpy(&setup, &default_mesh_setup,
898 sizeof(setup));
899 /* back compat only needed for mesh_id */
900 setup.mesh_id = wdev->ssid;
901 setup.mesh_id_len = wdev->mesh_id_up_len;
902 if (wdev->mesh_id_up_len)
903 __cfg80211_join_mesh(rdev, dev,
904 &setup,
905 &default_mesh_config);
906 break;
907 }
908#endif
780 default: 909 default:
781 break; 910 break;
782 } 911 }
783 wdev_unlock(wdev); 912 wdev_unlock(wdev);
784#endif
785 rdev->opencount++; 913 rdev->opencount++;
786 mutex_unlock(&rdev->devlist_mtx); 914 mutex_unlock(&rdev->devlist_mtx);
787 cfg80211_unlock_rdev(rdev); 915 cfg80211_unlock_rdev(rdev);
916
917 /*
918 * Configure power management to the driver here so that its
919 * correctly set also after interface type changes etc.
920 */
921 if (wdev->iftype == NL80211_IFTYPE_STATION &&
922 rdev->ops->set_power_mgmt)
923 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
924 wdev->ps,
925 wdev->ps_timeout)) {
926 /* assume this means it's off */
927 wdev->ps = false;
928 }
788 break; 929 break;
789 case NETDEV_UNREGISTER: 930 case NETDEV_UNREGISTER:
790 /* 931 /*
@@ -804,7 +945,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
804 sysfs_remove_link(&dev->dev.kobj, "phy80211"); 945 sysfs_remove_link(&dev->dev.kobj, "phy80211");
805 list_del_rcu(&wdev->list); 946 list_del_rcu(&wdev->list);
806 rdev->devlist_generation++; 947 rdev->devlist_generation++;
807 cfg80211_mlme_purge_actions(wdev); 948 cfg80211_mlme_purge_registrations(wdev);
808#ifdef CONFIG_CFG80211_WEXT 949#ifdef CONFIG_CFG80211_WEXT
809 kfree(wdev->wext.keys); 950 kfree(wdev->wext.keys);
810#endif 951#endif
@@ -824,6 +965,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
824 return notifier_from_errno(-EOPNOTSUPP); 965 return notifier_from_errno(-EOPNOTSUPP);
825 if (rfkill_blocked(rdev->rfkill)) 966 if (rfkill_blocked(rdev->rfkill))
826 return notifier_from_errno(-ERFKILL); 967 return notifier_from_errno(-ERFKILL);
968 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
969 if (ret)
970 return notifier_from_errno(ret);
827 break; 971 break;
828 } 972 }
829 973
@@ -910,52 +1054,3 @@ static void __exit cfg80211_exit(void)
910 destroy_workqueue(cfg80211_wq); 1054 destroy_workqueue(cfg80211_wq);
911} 1055}
912module_exit(cfg80211_exit); 1056module_exit(cfg80211_exit);
913
914static int ___wiphy_printk(const char *level, const struct wiphy *wiphy,
915 struct va_format *vaf)
916{
917 if (!wiphy)
918 return printk("%s(NULL wiphy *): %pV", level, vaf);
919
920 return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf);
921}
922
923int __wiphy_printk(const char *level, const struct wiphy *wiphy,
924 const char *fmt, ...)
925{
926 struct va_format vaf;
927 va_list args;
928 int r;
929
930 va_start(args, fmt);
931
932 vaf.fmt = fmt;
933 vaf.va = &args;
934
935 r = ___wiphy_printk(level, wiphy, &vaf);
936 va_end(args);
937
938 return r;
939}
940EXPORT_SYMBOL(__wiphy_printk);
941
942#define define_wiphy_printk_level(func, kern_level) \
943int func(const struct wiphy *wiphy, const char *fmt, ...) \
944{ \
945 struct va_format vaf; \
946 va_list args; \
947 int r; \
948 \
949 va_start(args, fmt); \
950 \
951 vaf.fmt = fmt; \
952 vaf.va = &args; \
953 \
954 r = ___wiphy_printk(kern_level, wiphy, &vaf); \
955 va_end(args); \
956 \
957 return r; \
958} \
959EXPORT_SYMBOL(func);
960
961define_wiphy_printk_level(wiphy_debug, KERN_DEBUG);