diff options
Diffstat (limited to 'net/wireless/ap.c')
| -rw-r--r-- | net/wireless/ap.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/net/wireless/ap.c b/net/wireless/ap.c index 324e8d851dc4..9a9a870806f5 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Parts of this file are + * Copyright (C) 2022-2023 Intel Corporation + */ #include <linux/ieee80211.h> #include <linux/export.h> #include <net/cfg80211.h> @@ -6,13 +11,14 @@ #include "rdev-ops.h" -static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev) +static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev, + struct net_device *dev, unsigned int link_id, + bool notify) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err; - ASSERT_WDEV_LOCK(wdev); + lockdep_assert_wiphy(wdev->wiphy); if (!rdev->ops->stop_ap) return -EOPNOTSUPP; @@ -21,28 +27,48 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP; - if (!wdev->beacon_interval) + if (!wdev->links[link_id].ap.beacon_interval) return -ENOENT; - err = rdev_stop_ap(rdev, dev); + err = rdev_stop_ap(rdev, dev, link_id); if (!err) { - wdev->beacon_interval = 0; - wdev->channel = NULL; - wdev->ssid_len = 0; + wdev->conn_owner_nlportid = 0; + wdev->links[link_id].ap.beacon_interval = 0; + memset(&wdev->links[link_id].ap.chandef, 0, + sizeof(wdev->links[link_id].ap.chandef)); + wdev->u.ap.ssid_len = 0; + rdev_set_qos_map(rdev, dev, NULL); + if (notify) + nl80211_send_ap_stopped(wdev, link_id); + + /* 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) + struct net_device *dev, int link_id, + bool notify) { - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; + unsigned int link; + int ret = 0; - wdev_lock(wdev); - err = __cfg80211_stop_ap(rdev, dev); - wdev_unlock(wdev); + if (link_id >= 0) + return ___cfg80211_stop_ap(rdev, dev, link_id, notify); - return err; + for_each_valid_link(dev->ieee80211_ptr, link) { + int ret1 = ___cfg80211_stop_ap(rdev, dev, link, notify); + + if (ret1) + ret = ret1; + /* try the next one also if one errored */ + } + + return ret; } |
