diff options
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r-- | net/wireless/core.c | 39 |
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 | ||
75 | int get_wiphy_idx(struct wiphy *wiphy) | 72 | int 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 | ||