1 #include <linux/ieee80211.h> 2 #include <linux/export.h> 3 #include <net/cfg80211.h> 4 #include "nl80211.h" 5 #include "core.h" 6 #include "rdev-ops.h" 7 8 9 static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 10 struct net_device *dev) 11 { 12 struct wireless_dev *wdev = dev->ieee80211_ptr; 13 int err; 14 15 ASSERT_WDEV_LOCK(wdev); 16 17 if (!rdev->ops->stop_ap) 18 return -EOPNOTSUPP; 19 20 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 21 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 22 return -EOPNOTSUPP; 23 24 if (!wdev->beacon_interval) 25 return -ENOENT; 26 27 err = rdev_stop_ap(rdev, dev); 28 if (!err) { 29 wdev->beacon_interval = 0; 30 wdev->channel = NULL; 31 wdev->ssid_len = 0; 32 } 33 34 return err; 35 } 36 37 int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 38 struct net_device *dev) 39 { 40 struct wireless_dev *wdev = dev->ieee80211_ptr; 41 int err; 42 43 wdev_lock(wdev); 44 err = __cfg80211_stop_ap(rdev, dev); 45 wdev_unlock(wdev); 46 47 return err; 48 } 49 50 void cfg80211_ch_switch_notify(struct net_device *dev, 51 struct cfg80211_chan_def *chandef) 52 { 53 struct wireless_dev *wdev = dev->ieee80211_ptr; 54 struct wiphy *wiphy = wdev->wiphy; 55 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 56 57 trace_cfg80211_ch_switch_notify(dev, chandef); 58 59 wdev_lock(wdev); 60 61 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && 62 wdev->iftype != NL80211_IFTYPE_P2P_GO)) 63 goto out; 64 65 wdev->channel = chandef->chan; 66 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL); 67 out: 68 wdev_unlock(wdev); 69 return; 70 } 71 EXPORT_SYMBOL(cfg80211_ch_switch_notify); 72 73 bool cfg80211_rx_spurious_frame(struct net_device *dev, 74 const u8 *addr, gfp_t gfp) 75 { 76 struct wireless_dev *wdev = dev->ieee80211_ptr; 77 bool ret; 78 79 trace_cfg80211_rx_spurious_frame(dev, addr); 80 81 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && 82 wdev->iftype != NL80211_IFTYPE_P2P_GO)) { 83 trace_cfg80211_return_bool(false); 84 return false; 85 } 86 ret = nl80211_unexpected_frame(dev, addr, gfp); 87 trace_cfg80211_return_bool(ret); 88 return ret; 89 } 90 EXPORT_SYMBOL(cfg80211_rx_spurious_frame); 91 92 bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, 93 const u8 *addr, gfp_t gfp) 94 { 95 struct wireless_dev *wdev = dev->ieee80211_ptr; 96 bool ret; 97 98 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr); 99 100 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && 101 wdev->iftype != NL80211_IFTYPE_P2P_GO && 102 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) { 103 trace_cfg80211_return_bool(false); 104 return false; 105 } 106 ret = nl80211_unexpected_4addr_frame(dev, addr, gfp); 107 trace_cfg80211_return_bool(ret); 108 return ret; 109 } 110 EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); 111