mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 15:29:16 +00:00
e005bd7dde
Since we now prevent regulatory restore during STA disconnect if concurrent AP interfaces are active, we need to reschedule this check when the AP state changes. This fixes never doing a restore when an AP is the last interface to stop. Or to put it another way: we need to re-check after anything we check here changes. Cc: stable@vger.kernel.org Fixes: 113f3aaa81bd ("cfg80211: Prevent regulatory restore during STA disconnect in concurrent interfaces") Signed-off-by: Johannes Berg <johannes.berg@intel.com>
61 lines
1.3 KiB
C
61 lines
1.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/ieee80211.h>
|
|
#include <linux/export.h>
|
|
#include <net/cfg80211.h>
|
|
#include "nl80211.h"
|
|
#include "core.h"
|
|
#include "rdev-ops.h"
|
|
|
|
|
|
int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev, bool notify)
|
|
{
|
|
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->conn_owner_nlportid = 0;
|
|
wdev->beacon_interval = 0;
|
|
memset(&wdev->chandef, 0, sizeof(wdev->chandef));
|
|
wdev->ssid_len = 0;
|
|
rdev_set_qos_map(rdev, dev, NULL);
|
|
if (notify)
|
|
nl80211_send_ap_stopped(wdev);
|
|
|
|
/* Should we apply the grace period during beaconing interface
|
|
* shutdown also?
|
|
*/
|
|
cfg80211_sched_dfs_chan_update(rdev);
|
|
}
|
|
|
|
schedule_work(&cfg80211_disconnect_work);
|
|
|
|
return err;
|
|
}
|
|
|
|
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev, bool notify)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
wdev_lock(wdev);
|
|
err = __cfg80211_stop_ap(rdev, dev, notify);
|
|
wdev_unlock(wdev);
|
|
|
|
return err;
|
|
}
|