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

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
...@@ -661,7 +661,8 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, ...@@ -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)) && (lq_sta->tx_agg_tid_en & BIT(tid)) &&
(tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) { (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); 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;
} }
} }
......
...@@ -2385,8 +2385,10 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -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)) if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
return -EINVAL; return -EINVAL;
if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) { if (mvmsta->tid_data[tid].state != IWL_AGG_QUEUED &&
IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n", 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); mvmsta->tid_data[tid].state);
return -ENXIO; return -ENXIO;
} }
......
...@@ -281,6 +281,7 @@ struct iwl_mvm_vif; ...@@ -281,6 +281,7 @@ struct iwl_mvm_vif;
* These states relate to a specific RA / TID. * These states relate to a specific RA / TID.
* *
* @IWL_AGG_OFF: aggregation is not used * @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_STARTING: aggregation are starting (between start and oper)
* @IWL_AGG_ON: aggregation session is up * @IWL_AGG_ON: aggregation session is up
* @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the
...@@ -290,6 +291,7 @@ struct iwl_mvm_vif; ...@@ -290,6 +291,7 @@ struct iwl_mvm_vif;
*/ */
enum iwl_mvm_agg_state { enum iwl_mvm_agg_state {
IWL_AGG_OFF = 0, IWL_AGG_OFF = 0,
IWL_AGG_QUEUED,
IWL_AGG_STARTING, IWL_AGG_STARTING,
IWL_AGG_ON, IWL_AGG_ON,
IWL_EMPTYING_HW_QUEUE_ADDBA, IWL_EMPTYING_HW_QUEUE_ADDBA,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment