18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <linux/ieee80211.h>
38c2ecf20Sopenharmony_ci#include <linux/export.h>
48c2ecf20Sopenharmony_ci#include <net/cfg80211.h>
58c2ecf20Sopenharmony_ci#include "nl80211.h"
68c2ecf20Sopenharmony_ci#include "core.h"
78c2ecf20Sopenharmony_ci#include "rdev-ops.h"
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciint __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
118c2ecf20Sopenharmony_ci		       struct net_device *dev, bool notify)
128c2ecf20Sopenharmony_ci{
138c2ecf20Sopenharmony_ci	struct wireless_dev *wdev = dev->ieee80211_ptr;
148c2ecf20Sopenharmony_ci	int err;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	ASSERT_WDEV_LOCK(wdev);
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	if (!rdev->ops->stop_ap)
198c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
228c2ecf20Sopenharmony_ci	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
238c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	if (!wdev->beacon_interval)
268c2ecf20Sopenharmony_ci		return -ENOENT;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	err = rdev_stop_ap(rdev, dev);
298c2ecf20Sopenharmony_ci	if (!err) {
308c2ecf20Sopenharmony_ci		wdev->conn_owner_nlportid = 0;
318c2ecf20Sopenharmony_ci		wdev->beacon_interval = 0;
328c2ecf20Sopenharmony_ci		memset(&wdev->chandef, 0, sizeof(wdev->chandef));
338c2ecf20Sopenharmony_ci		wdev->ssid_len = 0;
348c2ecf20Sopenharmony_ci		rdev_set_qos_map(rdev, dev, NULL);
358c2ecf20Sopenharmony_ci		if (notify)
368c2ecf20Sopenharmony_ci			nl80211_send_ap_stopped(wdev);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci		/* Should we apply the grace period during beaconing interface
398c2ecf20Sopenharmony_ci		 * shutdown also?
408c2ecf20Sopenharmony_ci		 */
418c2ecf20Sopenharmony_ci		cfg80211_sched_dfs_chan_update(rdev);
428c2ecf20Sopenharmony_ci	}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	schedule_work(&cfg80211_disconnect_work);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	return err;
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ciint cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
508c2ecf20Sopenharmony_ci		     struct net_device *dev, bool notify)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	struct wireless_dev *wdev = dev->ieee80211_ptr;
538c2ecf20Sopenharmony_ci	int err;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	wdev_lock(wdev);
568c2ecf20Sopenharmony_ci	err = __cfg80211_stop_ap(rdev, dev, notify);
578c2ecf20Sopenharmony_ci	wdev_unlock(wdev);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	return err;
608c2ecf20Sopenharmony_ci}
61