Commit 94f9b97b authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: be more careful in suspend/resume

When suspending with all netdevs down, the device
is stopped but we still call a number of driver
callbacks that the driver might not expect. The
same happens during resume, we might call a few
callbacks without starting the driver. Fix this
by checking open_count around more things and
exiting quickly if it is 0.

Also, while at this I noticed that the coverage
class isn't reprogrammed after resume, so add
that.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3f29c522
...@@ -34,6 +34,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) ...@@ -34,6 +34,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
struct sta_info *sta; struct sta_info *sta;
if (!local->open_count)
goto suspend;
ieee80211_scan_cancel(local); ieee80211_scan_cancel(local);
if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
......
...@@ -1157,27 +1157,37 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1157,27 +1157,37 @@ int ieee80211_reconfig(struct ieee80211_local *local)
} }
#endif #endif
/* restart hardware */ /* setup fragmentation threshold */
if (local->open_count) { drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
/*
* Upon resume hardware can sometimes be goofy due to /* setup RTS threshold */
* various platform / driver / bus issues, so restarting drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
* the device may at times not work immediately. Propagate
* the error. /* reset coverage class */
*/ drv_set_coverage_class(local, hw->wiphy->coverage_class);
res = drv_start(local);
if (res) { /* everything else happens only if HW was up & running */
WARN(local->suspended, "Hardware became unavailable " if (!local->open_count)
"upon resume. This could be a software issue " goto wake_up;
"prior to suspend or a hardware issue.\n");
return res;
}
ieee80211_led_radio(local, true); /*
ieee80211_mod_tpt_led_trig(local, * Upon resume hardware can sometimes be goofy due to
IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); * various platform / driver / bus issues, so restarting
* the device may at times not work immediately. Propagate
* the error.
*/
res = drv_start(local);
if (res) {
WARN(local->suspended, "Hardware became unavailable "
"upon resume. This could be a software issue "
"prior to suspend or a hardware issue.\n");
return res;
} }
ieee80211_led_radio(local, true);
ieee80211_mod_tpt_led_trig(local,
IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
/* add interfaces */ /* add interfaces */
list_for_each_entry(sdata, &local->interfaces, list) { list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
...@@ -1201,12 +1211,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1201,12 +1211,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
} }
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
/* setup fragmentation threshold */
drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
/* setup RTS threshold */
drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
/* reconfigure hardware */ /* reconfigure hardware */
ieee80211_hw_config(local, ~0); ieee80211_hw_config(local, ~0);
...@@ -1287,9 +1291,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1287,9 +1291,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if (ieee80211_sdata_running(sdata)) if (ieee80211_sdata_running(sdata))
ieee80211_enable_keys(sdata); ieee80211_enable_keys(sdata);
#ifdef CONFIG_PM
wake_up: wake_up:
#endif
ieee80211_wake_queues_by_reason(hw, ieee80211_wake_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND); IEEE80211_QUEUE_STOP_REASON_SUSPEND);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment