160771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior#include <linux/ieee80211.h>
260771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior#include <linux/export.h>
360771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior#include <net/cfg80211.h>
460771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior#include "nl80211.h"
560771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior#include "core.h"
6e35e4d28b687d4e849573419fdcf90f1cce2a14cHila Gonen#include "rdev-ops.h"
760771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
860771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
9f04c22033c25f71617ac62bcfe75698baa17a0b8Michal Kaziorint __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
10f04c22033c25f71617ac62bcfe75698baa17a0b8Michal Kazior		       struct net_device *dev, bool notify)
1160771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior{
1260771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	struct wireless_dev *wdev = dev->ieee80211_ptr;
1360771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	int err;
1460771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
1560771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	ASSERT_WDEV_LOCK(wdev);
1660771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
1760771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	if (!rdev->ops->stop_ap)
1860771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior		return -EOPNOTSUPP;
1960771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
2060771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2160771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2260771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior		return -EOPNOTSUPP;
2360771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
2460771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	if (!wdev->beacon_interval)
2560771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior		return -ENOENT;
2660771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
27e35e4d28b687d4e849573419fdcf90f1cce2a14cHila Gonen	err = rdev_stop_ap(rdev, dev);
28f4489ebeffa436c8427a20e2f05004e783708cdeMichal Kazior	if (!err) {
2960771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior		wdev->beacon_interval = 0;
309e0e29615a2077be852b1245b57c5b00fa609522Michal Kazior		memset(&wdev->chandef, 0, sizeof(wdev->chandef));
3106e191e22eb99ceeda60234502446c4c54492883Antonio Quartulli		wdev->ssid_len = 0;
32fa9ffc745610f31c6bc136d5a6a1782e00870e72Kyeyoon Park		rdev_set_qos_map(rdev, dev, NULL);
337c8d5e03acc680eb433b0d5dbacbb6cc9db663a1Ilan Peer		if (notify)
347c8d5e03acc680eb433b0d5dbacbb6cc9db663a1Ilan Peer			nl80211_send_ap_stopped(wdev);
35f4489ebeffa436c8427a20e2f05004e783708cdeMichal Kazior	}
3660771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
3760771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	return err;
3860771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior}
3960771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
4060771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kaziorint cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
417c8d5e03acc680eb433b0d5dbacbb6cc9db663a1Ilan Peer		     struct net_device *dev, bool notify)
4260771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior{
4360771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	struct wireless_dev *wdev = dev->ieee80211_ptr;
4460771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	int err;
4560771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
4660771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	wdev_lock(wdev);
477c8d5e03acc680eb433b0d5dbacbb6cc9db663a1Ilan Peer	err = __cfg80211_stop_ap(rdev, dev, notify);
4860771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	wdev_unlock(wdev);
4960771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior
5060771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior	return err;
5160771780c27cbc93d0b78da0c7fd7a8a540b029eMichal Kazior}
52