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.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index b677eab55b68..5ffff039b017 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -57,9 +57,6 @@ struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
57{ 57{
58 struct cfg80211_registered_device *result = NULL, *rdev; 58 struct cfg80211_registered_device *result = NULL, *rdev;
59 59
60 if (!wiphy_idx_valid(wiphy_idx))
61 return NULL;
62
63 assert_cfg80211_lock(); 60 assert_cfg80211_lock();
64 61
65 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 62 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
@@ -74,10 +71,8 @@ struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
74 71
75int get_wiphy_idx(struct wiphy *wiphy) 72int get_wiphy_idx(struct wiphy *wiphy)
76{ 73{
77 struct cfg80211_registered_device *rdev; 74 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
78 if (!wiphy) 75
79 return WIPHY_IDX_STALE;
80 rdev = wiphy_to_dev(wiphy);
81 return rdev->wiphy_idx; 76 return rdev->wiphy_idx;
82} 77}
83 78
@@ -86,9 +81,6 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
86{ 81{
87 struct cfg80211_registered_device *rdev; 82 struct cfg80211_registered_device *rdev;
88 83
89 if (!wiphy_idx_valid(wiphy_idx))
90 return NULL;
91
92 assert_cfg80211_lock(); 84 assert_cfg80211_lock();
93 85
94 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx); 86 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
@@ -309,7 +301,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
309 301
310 rdev->wiphy_idx = wiphy_counter++; 302 rdev->wiphy_idx = wiphy_counter++;
311 303
312 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { 304 if (unlikely(rdev->wiphy_idx < 0)) {
313 wiphy_counter--; 305 wiphy_counter--;
314 mutex_unlock(&cfg80211_mutex); 306 mutex_unlock(&cfg80211_mutex);
315 /* ugh, wrapped! */ 307 /* ugh, wrapped! */
@@ -332,6 +324,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
332 INIT_LIST_HEAD(&rdev->bss_list); 324 INIT_LIST_HEAD(&rdev->bss_list);
333 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 325 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
334 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results); 326 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
327 INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk,
328 cfg80211_dfs_channels_update_work);
335#ifdef CONFIG_CFG80211_WEXT 329#ifdef CONFIG_CFG80211_WEXT
336 rdev->wiphy.wext = &cfg80211_wext_handler; 330 rdev->wiphy.wext = &cfg80211_wext_handler;
337#endif 331#endif
@@ -373,7 +367,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
373 rdev->wiphy.rts_threshold = (u32) -1; 367 rdev->wiphy.rts_threshold = (u32) -1;
374 rdev->wiphy.coverage_class = 0; 368 rdev->wiphy.coverage_class = 0;
375 369
376 rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH; 370 rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH |
371 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
377 372
378 return &rdev->wiphy; 373 return &rdev->wiphy;
379} 374}
@@ -390,8 +385,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
390 385
391 c = &wiphy->iface_combinations[i]; 386 c = &wiphy->iface_combinations[i];
392 387
393 /* Combinations with just one interface aren't real */ 388 /*
394 if (WARN_ON(c->max_interfaces < 2)) 389 * Combinations with just one interface aren't real,
390 * however we make an exception for DFS.
391 */
392 if (WARN_ON((c->max_interfaces < 2) && !c->radar_detect_widths))
395 return -EINVAL; 393 return -EINVAL;
396 394
397 /* Need at least one channel */ 395 /* Need at least one channel */
@@ -406,6 +404,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
406 CFG80211_MAX_NUM_DIFFERENT_CHANNELS)) 404 CFG80211_MAX_NUM_DIFFERENT_CHANNELS))
407 return -EINVAL; 405 return -EINVAL;
408 406
407 /* DFS only works on one channel. */
408 if (WARN_ON(c->radar_detect_widths &&
409 (c->num_different_channels > 1)))
410 return -EINVAL;
411
409 if (WARN_ON(!c->n_limits)) 412 if (WARN_ON(!c->n_limits))
410 return -EINVAL; 413 return -EINVAL;
411 414
@@ -478,6 +481,11 @@ int wiphy_register(struct wiphy *wiphy)
478 ETH_ALEN))) 481 ETH_ALEN)))
479 return -EINVAL; 482 return -EINVAL;
480 483
484 if (WARN_ON(wiphy->max_acl_mac_addrs &&
485 (!(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME) ||
486 !rdev->ops->set_mac_acl)))
487 return -EINVAL;
488
481 if (wiphy->addresses) 489 if (wiphy->addresses)
482 memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN); 490 memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
483 491
@@ -690,6 +698,7 @@ void wiphy_unregister(struct wiphy *wiphy)
690 flush_work(&rdev->scan_done_wk); 698 flush_work(&rdev->scan_done_wk);
691 cancel_work_sync(&rdev->conn_work); 699 cancel_work_sync(&rdev->conn_work);
692 flush_work(&rdev->event_work); 700 flush_work(&rdev->event_work);
701 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
693 702
694 if (rdev->wowlan && rdev->ops->set_wakeup) 703 if (rdev->wowlan && rdev->ops->set_wakeup)
695 rdev_set_wakeup(rdev, false); 704 rdev_set_wakeup(rdev, false);
@@ -710,7 +719,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
710 kfree(reg); 719 kfree(reg);
711 } 720 }
712 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 721 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
713 cfg80211_put_bss(&scan->pub); 722 cfg80211_put_bss(&rdev->wiphy, &scan->pub);
714 kfree(rdev); 723 kfree(rdev);
715} 724}
716 725