ap.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/ieee80211.h>
  3. #include <linux/export.h>
  4. #include <net/cfg80211.h>
  5. #include "nl80211.h"
  6. #include "core.h"
  7. #include "rdev-ops.h"
  8. int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
  9. struct net_device *dev, bool notify)
  10. {
  11. struct wireless_dev *wdev = dev->ieee80211_ptr;
  12. int err;
  13. ASSERT_WDEV_LOCK(wdev);
  14. if (!rdev->ops->stop_ap)
  15. return -EOPNOTSUPP;
  16. if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
  17. dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
  18. return -EOPNOTSUPP;
  19. if (!wdev->beacon_interval)
  20. return -ENOENT;
  21. err = rdev_stop_ap(rdev, dev);
  22. if (!err) {
  23. wdev->beacon_interval = 0;
  24. memset(&wdev->chandef, 0, sizeof(wdev->chandef));
  25. wdev->ssid_len = 0;
  26. rdev_set_qos_map(rdev, dev, NULL);
  27. if (notify)
  28. nl80211_send_ap_stopped(wdev);
  29. /* Should we apply the grace period during beaconing interface
  30. * shutdown also?
  31. */
  32. cfg80211_sched_dfs_chan_update(rdev);
  33. }
  34. schedule_work(&cfg80211_disconnect_work);
  35. return err;
  36. }
  37. int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
  38. struct net_device *dev, bool notify)
  39. {
  40. struct wireless_dev *wdev = dev->ieee80211_ptr;
  41. int err;
  42. wdev_lock(wdev);
  43. err = __cfg80211_stop_ap(rdev, dev, notify);
  44. wdev_unlock(wdev);
  45. return err;
  46. }