diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-04-30 08:19:04 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-05-09 06:21:34 -0400 |
commit | f6837ba8c98afcf28ec25f6863a8597274aeefd6 (patch) | |
tree | 25e045970c4161b73457e42ded044dd908e81c6c /net/wireless | |
parent | f29f58a9e53252a50eaea0ece59f1af5fad56b5f (diff) |
mac80211: handle failed restart/resume better
When the driver fails during HW restart or resume, the whole
stack goes into a very confused state with interfaces being
up while the hardware is down etc.
Address this by shutting down everything; we'll run into a
lot of warnings in the process but that's better than having
the whole stack get messed up.
Reviewed-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index 7e023b74f009..39788711ce6e 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -210,15 +210,12 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | 213 | void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy) |
214 | { | 214 | { |
215 | struct cfg80211_registered_device *rdev = data; | 215 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
216 | struct wireless_dev *wdev; | 216 | struct wireless_dev *wdev; |
217 | 217 | ||
218 | if (!blocked) | 218 | ASSERT_RTNL(); |
219 | return 0; | ||
220 | |||
221 | rtnl_lock(); | ||
222 | 219 | ||
223 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 220 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
224 | if (wdev->netdev) { | 221 | if (wdev->netdev) { |
@@ -234,7 +231,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) | |||
234 | break; | 231 | break; |
235 | } | 232 | } |
236 | } | 233 | } |
234 | } | ||
235 | EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces); | ||
237 | 236 | ||
237 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | ||
238 | { | ||
239 | struct cfg80211_registered_device *rdev = data; | ||
240 | |||
241 | if (!blocked) | ||
242 | return 0; | ||
243 | |||
244 | rtnl_lock(); | ||
245 | cfg80211_shutdown_all_interfaces(&rdev->wiphy); | ||
238 | rtnl_unlock(); | 246 | rtnl_unlock(); |
239 | 247 | ||
240 | return 0; | 248 | return 0; |