diff options
author | Johannes Berg <johannes.berg@intel.com> | 2016-10-26 01:56:59 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2016-10-26 01:59:52 -0400 |
commit | e1957dba5b54b9c9b1d16f9d5f3f8d41d82bee41 (patch) | |
tree | d059eed01943b33083d6313ec4ad4b2262f5c02c /net/wireless/sysfs.c | |
parent | b4f0fd4baa90ecce798e0d26d1cce8f4457f2028 (diff) |
cfg80211: process events caused by suspend before suspending
When suspending without WoWLAN, cfg80211 will ask drivers to
disconnect. Even when the driver does this synchronously, and
immediately returns with a notification, cfg80211 schedules
the handling thereof to a workqueue, and may then call back
into the driver when the driver was already suspended/ing.
Fix this by processing all events caused by cfg80211_leave_all()
directly after that function returns. The driver still needs to
do the right thing here and wait for the firmware response, but
that is - at least - true for mwifiex where this occurred.
Reported-by: Amitkumar Karwar <akarwar@marvell.com>
Tested-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/sysfs.c')
-rw-r--r-- | net/wireless/sysfs.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 0082f4b01795..14b3f007826d 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -104,13 +104,16 @@ static int wiphy_suspend(struct device *dev) | |||
104 | 104 | ||
105 | rtnl_lock(); | 105 | rtnl_lock(); |
106 | if (rdev->wiphy.registered) { | 106 | if (rdev->wiphy.registered) { |
107 | if (!rdev->wiphy.wowlan_config) | 107 | if (!rdev->wiphy.wowlan_config) { |
108 | cfg80211_leave_all(rdev); | 108 | cfg80211_leave_all(rdev); |
109 | cfg80211_process_rdev_events(rdev); | ||
110 | } | ||
109 | if (rdev->ops->suspend) | 111 | if (rdev->ops->suspend) |
110 | ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); | 112 | ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); |
111 | if (ret == 1) { | 113 | if (ret == 1) { |
112 | /* Driver refuse to configure wowlan */ | 114 | /* Driver refuse to configure wowlan */ |
113 | cfg80211_leave_all(rdev); | 115 | cfg80211_leave_all(rdev); |
116 | cfg80211_process_rdev_events(rdev); | ||
114 | ret = rdev_suspend(rdev, NULL); | 117 | ret = rdev_suspend(rdev, NULL); |
115 | } | 118 | } |
116 | } | 119 | } |