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.c106
1 files changed, 105 insertions, 1 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index fe01de29bfe8..c22ef3492ee6 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -46,6 +46,11 @@ static struct dentry *ieee80211_debugfs_dir;
46/* for the cleanup, scan and event works */ 46/* for the cleanup, scan and event works */
47struct workqueue_struct *cfg80211_wq; 47struct workqueue_struct *cfg80211_wq;
48 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
49/* requires cfg80211_mutex to be held! */ 54/* requires cfg80211_mutex to be held! */
50struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) 55struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
51{ 56{
@@ -365,7 +370,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
365 spin_lock_init(&rdev->bss_lock); 370 spin_lock_init(&rdev->bss_lock);
366 INIT_LIST_HEAD(&rdev->bss_list); 371 INIT_LIST_HEAD(&rdev->bss_list);
367 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
368 373 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
369#ifdef CONFIG_CFG80211_WEXT 374#ifdef CONFIG_CFG80211_WEXT
370 rdev->wiphy.wext = &cfg80211_wext_handler; 375 rdev->wiphy.wext = &cfg80211_wext_handler;
371#endif 376#endif
@@ -411,6 +416,67 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
411} 416}
412EXPORT_SYMBOL(wiphy_new); 417EXPORT_SYMBOL(wiphy_new);
413 418
419static int wiphy_verify_combinations(struct wiphy *wiphy)
420{
421 const struct ieee80211_iface_combination *c;
422 int i, j;
423
424 /* If we have combinations enforce them */
425 if (wiphy->n_iface_combinations)
426 wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS;
427
428 for (i = 0; i < wiphy->n_iface_combinations; i++) {
429 u32 cnt = 0;
430 u16 all_iftypes = 0;
431
432 c = &wiphy->iface_combinations[i];
433
434 /* Combinations with just one interface aren't real */
435 if (WARN_ON(c->max_interfaces < 2))
436 return -EINVAL;
437
438 /* Need at least one channel */
439 if (WARN_ON(!c->num_different_channels))
440 return -EINVAL;
441
442 if (WARN_ON(!c->n_limits))
443 return -EINVAL;
444
445 for (j = 0; j < c->n_limits; j++) {
446 u16 types = c->limits[j].types;
447
448 /*
449 * interface types shouldn't overlap, this is
450 * used in cfg80211_can_change_interface()
451 */
452 if (WARN_ON(types & all_iftypes))
453 return -EINVAL;
454 all_iftypes |= types;
455
456 if (WARN_ON(!c->limits[j].max))
457 return -EINVAL;
458
459 /* Shouldn't list software iftypes in combinations! */
460 if (WARN_ON(wiphy->software_iftypes & types))
461 return -EINVAL;
462
463 cnt += c->limits[j].max;
464 /*
465 * Don't advertise an unsupported type
466 * in a combination.
467 */
468 if (WARN_ON((wiphy->interface_modes & types) != types))
469 return -EINVAL;
470 }
471
472 /* You can't even choose that many! */
473 if (WARN_ON(cnt < c->max_interfaces))
474 return -EINVAL;
475 }
476
477 return 0;
478}
479
414int wiphy_register(struct wiphy *wiphy) 480int wiphy_register(struct wiphy *wiphy)
415{ 481{
416 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 482 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -439,6 +505,10 @@ int wiphy_register(struct wiphy *wiphy)
439 if (WARN_ON(ifmodes != wiphy->interface_modes)) 505 if (WARN_ON(ifmodes != wiphy->interface_modes))
440 wiphy->interface_modes = ifmodes; 506 wiphy->interface_modes = ifmodes;
441 507
508 res = wiphy_verify_combinations(wiphy);
509 if (res)
510 return res;
511
442 /* sanity check supported bands/channels */ 512 /* sanity check supported bands/channels */
443 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 513 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
444 sband = wiphy->bands[band]; 514 sband = wiphy->bands[band];
@@ -451,6 +521,18 @@ int wiphy_register(struct wiphy *wiphy)
451 return -EINVAL; 521 return -EINVAL;
452 522
453 /* 523 /*
524 * Since cfg80211_disable_40mhz_24ghz is global, we can
525 * modify the sband's ht data even if the driver uses a
526 * global structure for that.
527 */
528 if (cfg80211_disable_40mhz_24ghz &&
529 band == IEEE80211_BAND_2GHZ &&
530 sband->ht_cap.ht_supported) {
531 sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
532 sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
533 }
534
535 /*
454 * Since we use a u32 for rate bitmaps in 536 * Since we use a u32 for rate bitmaps in
455 * ieee80211_get_response_rate, we cannot 537 * ieee80211_get_response_rate, we cannot
456 * have more than 32 legacy rates. 538 * have more than 32 legacy rates.
@@ -476,6 +558,13 @@ int wiphy_register(struct wiphy *wiphy)
476 return -EINVAL; 558 return -EINVAL;
477 } 559 }
478 560
561 if (rdev->wiphy.wowlan.n_patterns) {
562 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
563 rdev->wiphy.wowlan.pattern_min_len >
564 rdev->wiphy.wowlan.pattern_max_len))
565 return -EINVAL;
566 }
567
479 /* check and set up bitrates */ 568 /* check and set up bitrates */
480 ieee80211_set_bitrate_flags(wiphy); 569 ieee80211_set_bitrate_flags(wiphy);
481 570
@@ -614,6 +703,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
614 mutex_destroy(&rdev->devlist_mtx); 703 mutex_destroy(&rdev->devlist_mtx);
615 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 704 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
616 cfg80211_put_bss(&scan->pub); 705 cfg80211_put_bss(&scan->pub);
706 cfg80211_rdev_free_wowlan(rdev);
617 kfree(rdev); 707 kfree(rdev);
618} 708}
619 709
@@ -647,6 +737,11 @@ static void wdev_cleanup_work(struct work_struct *work)
647 ___cfg80211_scan_done(rdev, true); 737 ___cfg80211_scan_done(rdev, true);
648 } 738 }
649 739
740 if (WARN_ON(rdev->sched_scan_req &&
741 rdev->sched_scan_req->dev == wdev->netdev)) {
742 __cfg80211_stop_sched_scan(rdev, false);
743 }
744
650 cfg80211_unlock_rdev(rdev); 745 cfg80211_unlock_rdev(rdev);
651 746
652 mutex_lock(&rdev->devlist_mtx); 747 mutex_lock(&rdev->devlist_mtx);
@@ -668,6 +763,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
668 struct net_device *dev = ndev; 763 struct net_device *dev = ndev;
669 struct wireless_dev *wdev = dev->ieee80211_ptr; 764 struct wireless_dev *wdev = dev->ieee80211_ptr;
670 struct cfg80211_registered_device *rdev; 765 struct cfg80211_registered_device *rdev;
766 int ret;
671 767
672 if (!wdev) 768 if (!wdev)
673 return NOTIFY_DONE; 769 return NOTIFY_DONE;
@@ -734,6 +830,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
734 break; 830 break;
735 case NL80211_IFTYPE_P2P_CLIENT: 831 case NL80211_IFTYPE_P2P_CLIENT:
736 case NL80211_IFTYPE_STATION: 832 case NL80211_IFTYPE_STATION:
833 cfg80211_lock_rdev(rdev);
834 __cfg80211_stop_sched_scan(rdev, false);
835 cfg80211_unlock_rdev(rdev);
836
737 wdev_lock(wdev); 837 wdev_lock(wdev);
738#ifdef CONFIG_CFG80211_WEXT 838#ifdef CONFIG_CFG80211_WEXT
739 kfree(wdev->wext.ie); 839 kfree(wdev->wext.ie);
@@ -752,6 +852,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
752 default: 852 default:
753 break; 853 break;
754 } 854 }
855 wdev->beacon_interval = 0;
755 break; 856 break;
756 case NETDEV_DOWN: 857 case NETDEV_DOWN:
757 dev_hold(dev); 858 dev_hold(dev);
@@ -858,6 +959,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
858 return notifier_from_errno(-EOPNOTSUPP); 959 return notifier_from_errno(-EOPNOTSUPP);
859 if (rfkill_blocked(rdev->rfkill)) 960 if (rfkill_blocked(rdev->rfkill))
860 return notifier_from_errno(-ERFKILL); 961 return notifier_from_errno(-ERFKILL);
962 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
963 if (ret)
964 return notifier_from_errno(ret);
861 break; 965 break;
862 } 966 }
863 967