diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/time-event.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | 36 | 
1 files changed, 24 insertions, 12 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index e91f8e889df7..ab06dcda1462 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -49,14 +49,13 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)  	struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);  	/* -	 * Clear the ROC_RUNNING /ROC_AUX_RUNNING status bit. +	 * Clear the ROC_RUNNING status bit.  	 * This will cause the TX path to drop offchannel transmissions.  	 * That would also be done by mac80211, but it is racy, in particular  	 * in the case that the time event actually completed in the firmware  	 * (which is handled in iwl_mvm_te_handle_notif).  	 */  	clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); -	clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);  	synchronize_net(); @@ -82,9 +81,19 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)  			mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif);  			iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true);  		} -	} else { +	} + +	/* +	 * Clear the ROC_AUX_RUNNING status bit. +	 * This will cause the TX path to drop offchannel transmissions. +	 * That would also be done by mac80211, but it is racy, in particular +	 * in the case that the time event actually completed in the firmware +	 * (which is handled in iwl_mvm_te_handle_notif). +	 */ +	if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) {  		/* do the same in case of hot spot 2.0 */  		iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true); +  		/* In newer version of this command an aux station is added only  		 * in cases of dedicated tx queue and need to be removed in end  		 * of use */ @@ -687,11 +696,14 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,  	iwl_mvm_te_clear_data(mvm, te_data);  	spin_unlock_bh(&mvm->time_event_lock); -	/* When session protection is supported, the te_data->id field +	/* When session protection is used, the te_data->id field  	 * is reused to save session protection's configuration. +	 * For AUX ROC, HOT_SPOT_CMD is used and the te_data->id field is set +	 * to HOT_SPOT_CMD.  	 */  	if (fw_has_capa(&mvm->fw->ucode_capa, -			IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) { +			IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD) && +	    id != HOT_SPOT_CMD) {  		if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {  			/* Session protection is still ongoing. Cancel it */  			iwl_mvm_cancel_session_protection(mvm, mvmvif, id); @@ -1027,7 +1039,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)  			iwl_mvm_p2p_roc_finished(mvm);  		} else {  			iwl_mvm_remove_aux_roc_te(mvm, mvmvif, -						  &mvmvif->time_event_data); +						  &mvmvif->hs_time_event_data);  			iwl_mvm_roc_finished(mvm);  		} @@ -1158,15 +1170,10 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,  			cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,  							mvmvif->color)),  		.action = cpu_to_le32(FW_CTXT_ACTION_ADD), +		.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),  		.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),  	}; -	/* The time_event_data.id field is reused to save session -	 * protection's configuration. -	 */ -	mvmvif->time_event_data.id = SESSION_PROTECT_CONF_ASSOC; -	cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id); -  	lockdep_assert_held(&mvm->mutex);  	spin_lock_bh(&mvm->time_event_lock); @@ -1180,6 +1187,11 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,  	}  	iwl_mvm_te_clear_data(mvm, te_data); +	/* +	 * The time_event_data.id field is reused to save session +	 * protection's configuration. +	 */ +	te_data->id = le32_to_cpu(cmd.conf_id);  	te_data->duration = le32_to_cpu(cmd.duration_tu);  	te_data->vif = vif;  	spin_unlock_bh(&mvm->time_event_lock); |