diff options
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r-- | net/wireless/core.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index dcd64d5b07aa..443d4d7deea2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -230,9 +230,24 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) | |||
230 | rtnl_lock(); | 230 | rtnl_lock(); |
231 | mutex_lock(&rdev->devlist_mtx); | 231 | mutex_lock(&rdev->devlist_mtx); |
232 | 232 | ||
233 | list_for_each_entry(wdev, &rdev->wdev_list, list) | 233 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
234 | if (wdev->netdev) | 234 | if (wdev->netdev) { |
235 | dev_close(wdev->netdev); | 235 | dev_close(wdev->netdev); |
236 | continue; | ||
237 | } | ||
238 | /* otherwise, check iftype */ | ||
239 | switch (wdev->iftype) { | ||
240 | case NL80211_IFTYPE_P2P_DEVICE: | ||
241 | if (!wdev->p2p_started) | ||
242 | break; | ||
243 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | ||
244 | wdev->p2p_started = false; | ||
245 | rdev->opencount--; | ||
246 | break; | ||
247 | default: | ||
248 | break; | ||
249 | } | ||
250 | } | ||
236 | 251 | ||
237 | mutex_unlock(&rdev->devlist_mtx); | 252 | mutex_unlock(&rdev->devlist_mtx); |
238 | rtnl_unlock(); | 253 | rtnl_unlock(); |
@@ -407,6 +422,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) | |||
407 | if (WARN_ON(wiphy->software_iftypes & types)) | 422 | if (WARN_ON(wiphy->software_iftypes & types)) |
408 | return -EINVAL; | 423 | return -EINVAL; |
409 | 424 | ||
425 | /* Only a single P2P_DEVICE can be allowed */ | ||
426 | if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && | ||
427 | c->limits[j].max > 1)) | ||
428 | return -EINVAL; | ||
429 | |||
410 | cnt += c->limits[j].max; | 430 | cnt += c->limits[j].max; |
411 | /* | 431 | /* |
412 | * Don't advertise an unsupported type | 432 | * Don't advertise an unsupported type |
@@ -734,6 +754,35 @@ static void wdev_cleanup_work(struct work_struct *work) | |||
734 | dev_put(wdev->netdev); | 754 | dev_put(wdev->netdev); |
735 | } | 755 | } |
736 | 756 | ||
757 | void cfg80211_unregister_wdev(struct wireless_dev *wdev) | ||
758 | { | ||
759 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
760 | |||
761 | ASSERT_RTNL(); | ||
762 | |||
763 | if (WARN_ON(wdev->netdev)) | ||
764 | return; | ||
765 | |||
766 | mutex_lock(&rdev->devlist_mtx); | ||
767 | list_del_rcu(&wdev->list); | ||
768 | rdev->devlist_generation++; | ||
769 | |||
770 | switch (wdev->iftype) { | ||
771 | case NL80211_IFTYPE_P2P_DEVICE: | ||
772 | if (!wdev->p2p_started) | ||
773 | break; | ||
774 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | ||
775 | wdev->p2p_started = false; | ||
776 | rdev->opencount--; | ||
777 | break; | ||
778 | default: | ||
779 | WARN_ON_ONCE(1); | ||
780 | break; | ||
781 | } | ||
782 | mutex_unlock(&rdev->devlist_mtx); | ||
783 | } | ||
784 | EXPORT_SYMBOL(cfg80211_unregister_wdev); | ||
785 | |||
737 | static struct device_type wiphy_type = { | 786 | static struct device_type wiphy_type = { |
738 | .name = "wlan", | 787 | .name = "wlan", |
739 | }; | 788 | }; |