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

Commit bd800e41 authored by Naftali Goldstein's avatar Naftali Goldstein Committed by Luca Coelho
Browse files

iwlwifi: mvm: change state when queueing agg start work



Add a new state to enum iwl_mvm_agg_state, which is used between
queueing the work that starts tx aggregations and actually starting that
work (changing to state IWL_AGG_STARTING).
This solves a race where ieee80211_start_tx_ba_session is called a
second time, before the work queued by the first run has a chance to
change the agg_state. In this case the second call to
ieee80211_start_tx_ba_session returns an error, and the fallback is to
abort the ba session start.

Fixes: 482e4844 ("iwlwifi: mvm: change open and close criteria of a BA session")
Signed-off-by: default avatarNaftali Goldstein <naftali.goldstein@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 0fe8bed6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -661,7 +661,8 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
	    (lq_sta->tx_agg_tid_en & BIT(tid)) &&
	    (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
		IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
		rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta);
		if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0)
			tid_data->state = IWL_AGG_QUEUED;
	}
}

+4 −2
Original line number Diff line number Diff line
@@ -2385,8 +2385,10 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
		return -EINVAL;

	if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
		IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n",
	if (mvmsta->tid_data[tid].state != IWL_AGG_QUEUED &&
	    mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
		IWL_ERR(mvm,
			"Start AGG when state is not IWL_AGG_QUEUED or IWL_AGG_OFF %d!\n",
			mvmsta->tid_data[tid].state);
		return -ENXIO;
	}
+2 −0
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ struct iwl_mvm_vif;
 * These states relate to a specific RA / TID.
 *
 * @IWL_AGG_OFF: aggregation is not used
 * @IWL_AGG_QUEUED: aggregation start work has been queued
 * @IWL_AGG_STARTING: aggregation are starting (between start and oper)
 * @IWL_AGG_ON: aggregation session is up
 * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the
@@ -290,6 +291,7 @@ struct iwl_mvm_vif;
 */
enum iwl_mvm_agg_state {
	IWL_AGG_OFF = 0,
	IWL_AGG_QUEUED,
	IWL_AGG_STARTING,
	IWL_AGG_ON,
	IWL_EMPTYING_HW_QUEUE_ADDBA,