348baf0eac
There are a few cases, e.g. suspend, where an AP interface is stopped by the kernel rather than by userspace request, most commonly when suspending. To let userspace know about this, send the NL80211_CMD_STOP_AP command as an event every time an AP interface is stopped. This also happens when userspace did in fact request the AP stop, but that's not a problem. For full-MAC drivers this may need to be extended to also cover cases where the device stopped the AP operation for some reason, this a bit more complicated because then all cfg80211 state also needs to be reset; such API is not part of this patch. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
51 lines
1.0 KiB
C
51 lines
1.0 KiB
C
#include <linux/ieee80211.h>
|
|
#include <linux/export.h>
|
|
#include <net/cfg80211.h>
|
|
#include "nl80211.h"
|
|
#include "core.h"
|
|
#include "rdev-ops.h"
|
|
|
|
|
|
static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
ASSERT_WDEV_LOCK(wdev);
|
|
|
|
if (!rdev->ops->stop_ap)
|
|
return -EOPNOTSUPP;
|
|
|
|
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
|
|
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
|
return -EOPNOTSUPP;
|
|
|
|
if (!wdev->beacon_interval)
|
|
return -ENOENT;
|
|
|
|
err = rdev_stop_ap(rdev, dev);
|
|
if (!err) {
|
|
wdev->beacon_interval = 0;
|
|
wdev->channel = NULL;
|
|
wdev->ssid_len = 0;
|
|
rdev_set_qos_map(rdev, dev, NULL);
|
|
nl80211_send_ap_stopped(wdev);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
wdev_lock(wdev);
|
|
err = __cfg80211_stop_ap(rdev, dev);
|
|
wdev_unlock(wdev);
|
|
|
|
return err;
|
|
}
|