Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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) {
+28 −26
Original line number Diff line number Diff line
@@ -1157,8 +1157,19 @@ int ieee80211_reconfig(struct ieee80211_local *local)
	}
#endif

	/* restart hardware */
	if (local->open_count) {
	/* setup fragmentation threshold */
	drv_set_frag_threshold(local, hw->wiphy->frag_threshold);

	/* 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
@@ -1176,7 +1187,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
	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) {
@@ -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);