1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Parts of this file are |
4 | * Copyright (C) 2022-2023 Intel Corporation |
5 | */ |
6 | #include <linux/ieee80211.h> |
7 | #include <linux/export.h> |
8 | #include <net/cfg80211.h> |
9 | #include "nl80211.h" |
10 | #include "core.h" |
11 | #include "rdev-ops.h" |
12 | |
13 | |
14 | static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
15 | struct net_device *dev, unsigned int link_id, |
16 | bool notify) |
17 | { |
18 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
19 | int err; |
20 | |
21 | lockdep_assert_wiphy(wdev->wiphy); |
22 | |
23 | if (!rdev->ops->stop_ap) |
24 | return -EOPNOTSUPP; |
25 | |
26 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
27 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
28 | return -EOPNOTSUPP; |
29 | |
30 | if (!wdev->links[link_id].ap.beacon_interval) |
31 | return -ENOENT; |
32 | |
33 | err = rdev_stop_ap(rdev, dev, link_id); |
34 | if (!err) { |
35 | wdev->conn_owner_nlportid = 0; |
36 | wdev->links[link_id].ap.beacon_interval = 0; |
37 | memset(&wdev->links[link_id].ap.chandef, 0, |
38 | sizeof(wdev->links[link_id].ap.chandef)); |
39 | wdev->u.ap.ssid_len = 0; |
40 | rdev_set_qos_map(rdev, dev, NULL); |
41 | if (notify) |
42 | nl80211_send_ap_stopped(wdev, link_id); |
43 | |
44 | /* Should we apply the grace period during beaconing interface |
45 | * shutdown also? |
46 | */ |
47 | cfg80211_sched_dfs_chan_update(rdev); |
48 | } |
49 | |
50 | schedule_work(work: &cfg80211_disconnect_work); |
51 | |
52 | return err; |
53 | } |
54 | |
55 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
56 | struct net_device *dev, int link_id, |
57 | bool notify) |
58 | { |
59 | unsigned int link; |
60 | int ret = 0; |
61 | |
62 | if (link_id >= 0) |
63 | return ___cfg80211_stop_ap(rdev, dev, link_id, notify); |
64 | |
65 | for_each_valid_link(dev->ieee80211_ptr, link) { |
66 | int ret1 = ___cfg80211_stop_ap(rdev, dev, link_id: link, notify); |
67 | |
68 | if (ret1) |
69 | ret = ret1; |
70 | /* try the next one also if one errored */ |
71 | } |
72 | |
73 | return ret; |
74 | } |
75 | |