mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-19 16:14:13 +08:00
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: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
3f29c52218
commit
94f9b97be5
@ -34,6 +34,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct sta_info *sta;
|
||||
|
||||
if (!local->open_count)
|
||||
goto suspend;
|
||||
|
||||
ieee80211_scan_cancel(local);
|
||||
|
||||
if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
|
||||
|
@ -1157,27 +1157,37 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* restart hardware */
|
||||
if (local->open_count) {
|
||||
/*
|
||||
* Upon resume hardware can sometimes be goofy due to
|
||||
* 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;
|
||||
}
|
||||
/* setup fragmentation threshold */
|
||||
drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
|
||||
|
||||
ieee80211_led_radio(local, true);
|
||||
ieee80211_mod_tpt_led_trig(local,
|
||||
IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
|
||||
/* setup RTS threshold */
|
||||
drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
|
||||
|
||||
/* reset coverage class */
|
||||
drv_set_coverage_class(local, hw->wiphy->coverage_class);
|
||||
|
||||
/* everything else happens only if HW was up & running */
|
||||
if (!local->open_count)
|
||||
goto wake_up;
|
||||
|
||||
/*
|
||||
* Upon resume hardware can sometimes be goofy due to
|
||||
* 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 */
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
||||
@ -1201,12 +1211,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
}
|
||||
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 */
|
||||
ieee80211_hw_config(local, ~0);
|
||||
|
||||
@ -1287,9 +1291,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
if (ieee80211_sdata_running(sdata))
|
||||
ieee80211_enable_keys(sdata);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
wake_up:
|
||||
#endif
|
||||
ieee80211_wake_queues_by_reason(hw,
|
||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user