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->conn_owner_nlportid = 0;
  24. wdev->beacon_interval = 0;
  25. memset(&wdev->chandef, 0, sizeof(wdev->chandef));
  26. wdev->ssid_len = 0;
  27. rdev_set_qos_map(rdev, dev, NULL);
  28. if (notify)
  29. nl80211_send_ap_stopped(wdev);
  30. /* Should we apply the grace period during beaconing interface
  31. * shutdown also?
  32. */
  33. cfg80211_sched_dfs_chan_update(rdev);
  34. }
  35. schedule_work(&cfg80211_disconnect_work);
  36. return err;
  37. }
  38. int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
  39. struct net_device *dev, bool notify)
  40. {
  41. struct wireless_dev *wdev = dev->ieee80211_ptr;
  42. int err;
  43. wdev_lock(wdev);
  44. err = __cfg80211_stop_ap(rdev, dev, notify);
  45. wdev_unlock(wdev);
  46. return err;
  47. }