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

Commit 682e5f64 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Wey-Yi Guy
Browse files

iwlwifi: split between AGG_ON and AGG_STARTING



This allows not to notify the transport about aggregation stopped
while aggregation haven't been started.

Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent c27cf685
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -522,6 +522,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
{
	struct iwl_tid_data *tid_data;
	int sta_id, txq_id;
	enum iwl_agg_state agg_state;

	sta_id = iwl_sta_id(sta);

@@ -545,6 +546,13 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
		*/
		IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
		goto turn_off;
	case IWL_AGG_STARTING:
		/*
		 * This can happen when the session is stopped before
		 * we receive ADDBA response
		 */
		IWL_DEBUG_HT(priv, "AGG stop before AGG became operational\n");
		goto turn_off;
	case IWL_AGG_ON:
		break;
	default:
@@ -576,11 +584,16 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
	IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
			    tid_data->agg.ssn);
turn_off:
	agg_state = priv->tid_data[sta_id][tid].agg.state;
	priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;

	spin_unlock_bh(&priv->sta_lock);

	if (test_bit(txq_id, priv->agg_q_alloc)) {
		/* If the transport didn't know that we wanted to start
		 * agreggation, don't tell it that we want to stop them
		 */
		if (agg_state != IWL_AGG_STARTING)
			iwl_trans_tx_agg_disable(priv->trans, txq_id);
		iwlagn_dealloc_agg_txq(priv, txq_id);
	}
@@ -634,7 +647,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
	if (*ssn == tid_data->next_reclaimed) {
		IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
				    tid_data->agg.ssn);
		tid_data->agg.state = IWL_AGG_ON;
		tid_data->agg.state = IWL_AGG_STARTING;
		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
	} else {
		IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, "
@@ -661,6 +674,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
	spin_lock_bh(&priv->sta_lock);
	ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn;
	q = priv->tid_data[sta_priv->sta_id][tid].agg.txq_id;
	priv->tid_data[sta_priv->sta_id][tid].agg.state = IWL_AGG_ON;
	spin_unlock_bh(&priv->sta_lock);

	fifo = ctx->ac_to_fifo[tid_to_ac[tid]];
@@ -745,7 +759,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
			IWL_DEBUG_TX_QUEUES(priv,
				"Can continue ADDBA flow ssn = next_recl ="
				" %d", tid_data->next_reclaimed);
			tid_data->agg.state = IWL_AGG_ON;
			tid_data->agg.state = IWL_AGG_STARTING;
			ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
		}
		break;
+2 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ struct iwl_qos_info {
 * These states relate to a specific RA / TID.
 *
 * @IWL_AGG_OFF: aggregation is not used
 * @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
 *	HW queue to be empty from packets for this RA /TID.
@@ -202,6 +203,7 @@ struct iwl_qos_info {
 */
enum iwl_agg_state {
	IWL_AGG_OFF = 0,
	IWL_AGG_STARTING,
	IWL_AGG_ON,
	IWL_EMPTYING_HW_QUEUE_ADDBA,
	IWL_EMPTYING_HW_QUEUE_DELBA,