ap.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Parts of this file are
  4. * Copyright (C) 2022 Intel Corporation
  5. */
  6. #include <linux/ieee80211.h>
  7. #include <linux/export.h>
  8. #include <net/cfg80211.h>
  9. #include "nl80211.h"
  10. #include "core.h"
  11. #include "rdev-ops.h"
  12. static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
  13. struct net_device *dev, unsigned int link_id,
  14. bool notify)
  15. {
  16. struct wireless_dev *wdev = dev->ieee80211_ptr;
  17. int err;
  18. ASSERT_WDEV_LOCK(wdev);
  19. if (!rdev->ops->stop_ap)
  20. return -EOPNOTSUPP;
  21. if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
  22. dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
  23. return -EOPNOTSUPP;
  24. if (!wdev->links[link_id].ap.beacon_interval)
  25. return -ENOENT;
  26. err = rdev_stop_ap(rdev, dev, link_id);
  27. if (!err) {
  28. wdev->conn_owner_nlportid = 0;
  29. wdev->links[link_id].ap.beacon_interval = 0;
  30. memset(&wdev->links[link_id].ap.chandef, 0,
  31. sizeof(wdev->links[link_id].ap.chandef));
  32. wdev->u.ap.ssid_len = 0;
  33. rdev_set_qos_map(rdev, dev, NULL);
  34. if (notify)
  35. nl80211_send_ap_stopped(wdev, link_id);
  36. /* Should we apply the grace period during beaconing interface
  37. * shutdown also?
  38. */
  39. cfg80211_sched_dfs_chan_update(rdev);
  40. }
  41. schedule_work(&cfg80211_disconnect_work);
  42. return err;
  43. }
  44. int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
  45. struct net_device *dev, int link_id,
  46. bool notify)
  47. {
  48. unsigned int link;
  49. int ret = 0;
  50. if (link_id >= 0)
  51. return ___cfg80211_stop_ap(rdev, dev, link_id, notify);
  52. for_each_valid_link(dev->ieee80211_ptr, link) {
  53. int ret1 = ___cfg80211_stop_ap(rdev, dev, link, notify);
  54. if (ret1)
  55. ret = ret1;
  56. /* try the next one also if one errored */
  57. }
  58. return ret;
  59. }
  60. int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
  61. struct net_device *dev, int link_id,
  62. bool notify)
  63. {
  64. struct wireless_dev *wdev = dev->ieee80211_ptr;
  65. int err;
  66. wdev_lock(wdev);
  67. err = __cfg80211_stop_ap(rdev, dev, link_id, notify);
  68. wdev_unlock(wdev);
  69. return err;
  70. }