diff options
Diffstat (limited to 'net/mac80211/mlme.c')
| -rw-r--r-- | net/mac80211/mlme.c | 28 | 
1 files changed, 23 insertions, 5 deletions
| diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9f6464f3e05..141577412d8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -647,6 +647,9 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,  		our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) &  								mask) >> shift; +		if (our_mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED) +			continue; +  		switch (ap_mcs) {  		default:  			if (our_mcs <= ap_mcs) @@ -3503,6 +3506,14 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;  	/* +	 * Stop timers before deleting work items, as timers +	 * could race and re-add the work-items. They will be +	 * re-established on connection. +	 */ +	del_timer_sync(&ifmgd->conn_mon_timer); +	del_timer_sync(&ifmgd->bcn_mon_timer); + +	/*  	 * we need to use atomic bitops for the running bits  	 * only because both timers might fire at the same  	 * time -- the code here is properly synchronised. @@ -3516,13 +3527,9 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)  	if (del_timer_sync(&ifmgd->timer))  		set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); -	cancel_work_sync(&ifmgd->chswitch_work);  	if (del_timer_sync(&ifmgd->chswitch_timer))  		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); - -	/* these will just be re-established on connection */ -	del_timer_sync(&ifmgd->conn_mon_timer); -	del_timer_sync(&ifmgd->bcn_mon_timer); +	cancel_work_sync(&ifmgd->chswitch_work);  }  void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) @@ -4315,6 +4322,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)  {  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; +	/* +	 * Make sure some work items will not run after this, +	 * they will not do anything but might not have been +	 * cancelled when disconnecting. +	 */ +	cancel_work_sync(&ifmgd->monitor_work); +	cancel_work_sync(&ifmgd->beacon_connection_loss_work); +	cancel_work_sync(&ifmgd->request_smps_work); +	cancel_work_sync(&ifmgd->csa_connection_drop_work); +	cancel_work_sync(&ifmgd->chswitch_work); +  	mutex_lock(&ifmgd->mtx);  	if (ifmgd->assoc_data)  		ieee80211_destroy_assoc_data(sdata, false); |