diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-03-26 09:50:55 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2012-04-18 10:32:19 -0400 |
commit | 682e5f64de0ab5be3fb2de9f66a1da87de48ec09 (patch) | |
tree | 9c572be29d52ffdffde5574aac929430a5334185 /drivers/net/wireless/iwlwifi | |
parent | c27cf685d185cc4604776252fdcaca5ad24abcca (diff) |
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: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 2 |
2 files changed, 19 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 76fea8f5f9c9..b77a079a136d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -522,6 +522,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
522 | { | 522 | { |
523 | struct iwl_tid_data *tid_data; | 523 | struct iwl_tid_data *tid_data; |
524 | int sta_id, txq_id; | 524 | int sta_id, txq_id; |
525 | enum iwl_agg_state agg_state; | ||
525 | 526 | ||
526 | sta_id = iwl_sta_id(sta); | 527 | sta_id = iwl_sta_id(sta); |
527 | 528 | ||
@@ -545,6 +546,13 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
545 | */ | 546 | */ |
546 | IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); | 547 | IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); |
547 | goto turn_off; | 548 | goto turn_off; |
549 | case IWL_AGG_STARTING: | ||
550 | /* | ||
551 | * This can happen when the session is stopped before | ||
552 | * we receive ADDBA response | ||
553 | */ | ||
554 | IWL_DEBUG_HT(priv, "AGG stop before AGG became operational\n"); | ||
555 | goto turn_off; | ||
548 | case IWL_AGG_ON: | 556 | case IWL_AGG_ON: |
549 | break; | 557 | break; |
550 | default: | 558 | default: |
@@ -576,12 +584,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
576 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", | 584 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", |
577 | tid_data->agg.ssn); | 585 | tid_data->agg.ssn); |
578 | turn_off: | 586 | turn_off: |
587 | agg_state = priv->tid_data[sta_id][tid].agg.state; | ||
579 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 588 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; |
580 | 589 | ||
581 | spin_unlock_bh(&priv->sta_lock); | 590 | spin_unlock_bh(&priv->sta_lock); |
582 | 591 | ||
583 | if (test_bit(txq_id, priv->agg_q_alloc)) { | 592 | if (test_bit(txq_id, priv->agg_q_alloc)) { |
584 | iwl_trans_tx_agg_disable(priv->trans, txq_id); | 593 | /* If the transport didn't know that we wanted to start |
594 | * agreggation, don't tell it that we want to stop them | ||
595 | */ | ||
596 | if (agg_state != IWL_AGG_STARTING) | ||
597 | iwl_trans_tx_agg_disable(priv->trans, txq_id); | ||
585 | iwlagn_dealloc_agg_txq(priv, txq_id); | 598 | iwlagn_dealloc_agg_txq(priv, txq_id); |
586 | } | 599 | } |
587 | 600 | ||
@@ -634,7 +647,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
634 | if (*ssn == tid_data->next_reclaimed) { | 647 | if (*ssn == tid_data->next_reclaimed) { |
635 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", | 648 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", |
636 | tid_data->agg.ssn); | 649 | tid_data->agg.ssn); |
637 | tid_data->agg.state = IWL_AGG_ON; | 650 | tid_data->agg.state = IWL_AGG_STARTING; |
638 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 651 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
639 | } else { | 652 | } else { |
640 | IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " | 653 | 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, | |||
661 | spin_lock_bh(&priv->sta_lock); | 674 | spin_lock_bh(&priv->sta_lock); |
662 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; | 675 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; |
663 | q = priv->tid_data[sta_priv->sta_id][tid].agg.txq_id; | 676 | q = priv->tid_data[sta_priv->sta_id][tid].agg.txq_id; |
677 | priv->tid_data[sta_priv->sta_id][tid].agg.state = IWL_AGG_ON; | ||
664 | spin_unlock_bh(&priv->sta_lock); | 678 | spin_unlock_bh(&priv->sta_lock); |
665 | 679 | ||
666 | fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; | 680 | 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) | |||
745 | IWL_DEBUG_TX_QUEUES(priv, | 759 | IWL_DEBUG_TX_QUEUES(priv, |
746 | "Can continue ADDBA flow ssn = next_recl =" | 760 | "Can continue ADDBA flow ssn = next_recl =" |
747 | " %d", tid_data->next_reclaimed); | 761 | " %d", tid_data->next_reclaimed); |
748 | tid_data->agg.state = IWL_AGG_ON; | 762 | tid_data->agg.state = IWL_AGG_STARTING; |
749 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); | 763 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); |
750 | } | 764 | } |
751 | break; | 765 | break; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f3eccf6709d1..3816429cdbd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -194,6 +194,7 @@ struct iwl_qos_info { | |||
194 | * These states relate to a specific RA / TID. | 194 | * These states relate to a specific RA / TID. |
195 | * | 195 | * |
196 | * @IWL_AGG_OFF: aggregation is not used | 196 | * @IWL_AGG_OFF: aggregation is not used |
197 | * @IWL_AGG_STARTING: aggregation are starting (between start and oper) | ||
197 | * @IWL_AGG_ON: aggregation session is up | 198 | * @IWL_AGG_ON: aggregation session is up |
198 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the | 199 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the |
199 | * HW queue to be empty from packets for this RA /TID. | 200 | * HW queue to be empty from packets for this RA /TID. |
@@ -202,6 +203,7 @@ struct iwl_qos_info { | |||
202 | */ | 203 | */ |
203 | enum iwl_agg_state { | 204 | enum iwl_agg_state { |
204 | IWL_AGG_OFF = 0, | 205 | IWL_AGG_OFF = 0, |
206 | IWL_AGG_STARTING, | ||
205 | IWL_AGG_ON, | 207 | IWL_AGG_ON, |
206 | IWL_EMPTYING_HW_QUEUE_ADDBA, | 208 | IWL_EMPTYING_HW_QUEUE_ADDBA, |
207 | IWL_EMPTYING_HW_QUEUE_DELBA, | 209 | IWL_EMPTYING_HW_QUEUE_DELBA, |