Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Parts of this file are
0004  * Copyright (C) 2022 Intel Corporation
0005  */
0006 #include <linux/ieee80211.h>
0007 #include <linux/export.h>
0008 #include <net/cfg80211.h>
0009 #include "nl80211.h"
0010 #include "core.h"
0011 #include "rdev-ops.h"
0012 
0013 
0014 static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
0015                    struct net_device *dev, unsigned int link_id,
0016                    bool notify)
0017 {
0018     struct wireless_dev *wdev = dev->ieee80211_ptr;
0019     int err;
0020 
0021     ASSERT_WDEV_LOCK(wdev);
0022 
0023     if (!rdev->ops->stop_ap)
0024         return -EOPNOTSUPP;
0025 
0026     if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
0027         dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
0028         return -EOPNOTSUPP;
0029 
0030     if (!wdev->links[link_id].ap.beacon_interval)
0031         return -ENOENT;
0032 
0033     err = rdev_stop_ap(rdev, dev, link_id);
0034     if (!err) {
0035         wdev->conn_owner_nlportid = 0;
0036         wdev->links[link_id].ap.beacon_interval = 0;
0037         memset(&wdev->links[link_id].ap.chandef, 0,
0038                sizeof(wdev->links[link_id].ap.chandef));
0039         wdev->u.ap.ssid_len = 0;
0040         rdev_set_qos_map(rdev, dev, NULL);
0041         if (notify)
0042             nl80211_send_ap_stopped(wdev);
0043 
0044         /* Should we apply the grace period during beaconing interface
0045          * shutdown also?
0046          */
0047         cfg80211_sched_dfs_chan_update(rdev);
0048     }
0049 
0050     schedule_work(&cfg80211_disconnect_work);
0051 
0052     return err;
0053 }
0054 
0055 int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
0056                struct net_device *dev, int link_id,
0057                bool notify)
0058 {
0059     unsigned int link;
0060     int ret = 0;
0061 
0062     if (link_id >= 0)
0063         return ___cfg80211_stop_ap(rdev, dev, link_id, notify);
0064 
0065     for_each_valid_link(dev->ieee80211_ptr, link) {
0066         int ret1 = ___cfg80211_stop_ap(rdev, dev, link, notify);
0067 
0068         if (ret1)
0069             ret = ret1;
0070         /* try the next one also if one errored */
0071     }
0072 
0073     return ret;
0074 }
0075 
0076 int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
0077              struct net_device *dev, int link_id,
0078              bool notify)
0079 {
0080     struct wireless_dev *wdev = dev->ieee80211_ptr;
0081     int err;
0082 
0083     wdev_lock(wdev);
0084     err = __cfg80211_stop_ap(rdev, dev, link_id, notify);
0085     wdev_unlock(wdev);
0086 
0087     return err;
0088 }