diff options
| -rw-r--r-- | net/mac80211/pm.c | 2 | ||||
| -rw-r--r-- | net/wireless/core.c | 90 | ||||
| -rw-r--r-- | net/wireless/core.h | 3 | ||||
| -rw-r--r-- | net/wireless/rdev-ops.h | 7 | ||||
| -rw-r--r-- | net/wireless/reg.c | 42 | ||||
| -rw-r--r-- | net/wireless/sysfs.c | 25 |
6 files changed, 82 insertions, 87 deletions
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 00a43a70e1fc..800f1aff472f 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -132,7 +132,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_SUSPEND, false); - return err; + local->wowlan = false; } else { goto suspend; } diff --git a/net/wireless/core.c b/net/wireless/core.c index c9d4e3d5af5e..e2cd8b8c2f09 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -887,61 +887,6 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, rdev->num_running_monitor_ifaces += num; } -void cfg80211_leave(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev) -{ - struct net_device *dev = wdev->netdev; - struct cfg80211_sched_scan_request *sched_scan_req; - - ASSERT_RTNL(); - - switch (wdev->iftype) { - case NL80211_IFTYPE_ADHOC: - cfg80211_leave_ibss(rdev, dev, true); - break; - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_STATION: - sched_scan_req = rtnl_dereference(rdev->sched_scan_req); - if (sched_scan_req && dev == sched_scan_req->dev) - __cfg80211_stop_sched_scan(rdev, false); - wdev_lock(wdev); -#ifdef CONFIG_CFG80211_WEXT - kfree(wdev->wext.ie); - wdev->wext.ie = NULL; - wdev->wext.ie_len = 0; - wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; -#endif - cfg80211_disconnect(rdev, dev, - WLAN_REASON_DEAUTH_LEAVING, true); - wdev_unlock(wdev); - break; - case NL80211_IFTYPE_MESH_POINT: - cfg80211_leave_mesh(rdev, dev); - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - cfg80211_stop_ap(rdev, dev, true); - break; - case NL80211_IFTYPE_OCB: - __cfg80211_leave_ocb(rdev, dev); - break; - case NL80211_IFTYPE_WDS: - /* must be handled by mac80211/driver, has no APIs */ - break; - case NL80211_IFTYPE_P2P_DEVICE: - /* cannot happen, has no netdev */ - break; - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_MONITOR: - /* nothing to do */ - break; - case NL80211_IFTYPE_UNSPECIFIED: - case NUM_NL80211_IFTYPES: - /* invalid */ - break; - } -} - static int cfg80211_netdev_notifier_call(struct notifier_block *nb, unsigned long state, void *ptr) { @@ -1003,7 +948,40 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, dev->priv_flags |= IFF_DONT_BRIDGE; break; case NETDEV_GOING_DOWN: - cfg80211_leave(rdev, wdev); + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + cfg80211_leave_ibss(rdev, dev, true); + break; + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_STATION: + ASSERT_RTNL(); + sched_scan_req = rtnl_dereference(rdev->sched_scan_req); + if (sched_scan_req && dev == sched_scan_req->dev) + __cfg80211_stop_sched_scan(rdev, false); + + wdev_lock(wdev); +#ifdef CONFIG_CFG80211_WEXT + kfree(wdev->wext.ie); + wdev->wext.ie = NULL; + wdev->wext.ie_len = 0; + wdev->wext.connect.auth_type = + NL80211_AUTHTYPE_AUTOMATIC; +#endif + cfg80211_disconnect(rdev, dev, + WLAN_REASON_DEAUTH_LEAVING, true); + cfg80211_mlme_down(rdev, dev); + wdev_unlock(wdev); + break; + case NL80211_IFTYPE_MESH_POINT: + cfg80211_leave_mesh(rdev, dev); + break; + case NL80211_IFTYPE_AP: + cfg80211_stop_ap(rdev, dev, false); + break; + default: + break; + } + wdev->beacon_interval = 0; break; case NETDEV_DOWN: cfg80211_update_iface_num(rdev, wdev->iftype, -1); diff --git a/net/wireless/core.h b/net/wireless/core.h index 00de86ca46b5..a918fc303d51 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -470,9 +470,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num); -void cfg80211_leave(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev); - void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev); diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index c23516d0f807..571aa9424354 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -6,12 +6,11 @@ #include "core.h" #include "trace.h" -static inline int rdev_suspend(struct cfg80211_registered_device *rdev, - struct cfg80211_wowlan *wowlan) +static inline int rdev_suspend(struct cfg80211_registered_device *rdev) { int ret; - trace_rdev_suspend(&rdev->wiphy, wowlan); - ret = rdev->ops->suspend(&rdev->wiphy, wowlan); + trace_rdev_suspend(&rdev->wiphy, rdev->wiphy.wowlan_config); + ret = rdev->ops->suspend(&rdev->wiphy, rdev->wiphy.wowlan_config); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9fbc23a1cb53..197223277901 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1676,12 +1676,48 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy) { struct wireless_dev *wdev; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - + struct net_device *dev; + struct cfg80211_sched_scan_request *sched_scan_req; ASSERT_RTNL(); list_for_each_entry(wdev, &rdev->wdev_list, list) - if (!reg_wdev_chan_valid(wiphy, wdev)) - cfg80211_leave(rdev, wdev); + if (!reg_wdev_chan_valid(wiphy, wdev)) { + dev = wdev->netdev; + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + cfg80211_leave_ibss(rdev, dev, true); + break; + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_STATION: + ASSERT_RTNL(); + sched_scan_req = rtnl_dereference(rdev->sched_scan_req); + if (sched_scan_req && dev == sched_scan_req->dev) + __cfg80211_stop_sched_scan(rdev, false); + + wdev_lock(wdev); +#ifdef CONFIG_CFG80211_WEXT + kfree(wdev->wext.ie); + wdev->wext.ie = NULL; + wdev->wext.ie_len = 0; + wdev->wext.connect.auth_type = + NL80211_AUTHTYPE_AUTOMATIC; +#endif + cfg80211_disconnect(rdev, dev, + WLAN_REASON_DEAUTH_LEAVING, true); + cfg80211_mlme_down(rdev, dev); + wdev_unlock(wdev); + break; + case NL80211_IFTYPE_MESH_POINT: + cfg80211_leave_mesh(rdev, dev); + break; + case NL80211_IFTYPE_AP: + cfg80211_stop_ap(rdev, dev, false); + break; + default: + break; + } + wdev->beacon_interval = 0; + } } static void reg_check_chans_work(struct work_struct *work) diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 9cee0220665d..0178de1fc9aa 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -87,14 +87,6 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env) } #ifdef CONFIG_PM_SLEEP -static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) -{ - struct wireless_dev *wdev; - - list_for_each_entry(wdev, &rdev->wdev_list, list) - cfg80211_leave(rdev, wdev); -} - static int wiphy_suspend(struct device *dev) { struct cfg80211_registered_device *rdev = dev_to_rdev(dev); @@ -102,19 +94,12 @@ static int wiphy_suspend(struct device *dev) rdev->suspend_at = get_seconds(); - rtnl_lock(); - if (rdev->wiphy.registered) { - if (!rdev->wiphy.wowlan_config) - cfg80211_leave_all(rdev); - if (rdev->ops->suspend) - ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); - if (ret == 1) { - /* Driver refuse to configure wowlan */ - cfg80211_leave_all(rdev); - ret = rdev_suspend(rdev, NULL); - } + if (rdev->ops->suspend) { + rtnl_lock(); + if (rdev->wiphy.registered) + ret = rdev_suspend(rdev); + rtnl_unlock(); } - rtnl_unlock(); return ret; } |
