aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2012-03-26 09:50:55 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2012-04-18 10:32:19 -0400
commit682e5f64de0ab5be3fb2de9f66a1da87de48ec09 (patch)
tree9c572be29d52ffdffde5574aac929430a5334185 /drivers/net/wireless/iwlwifi
parentc27cf685d185cc4604776252fdcaca5ad24abcca (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.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
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);
578turn_off: 586turn_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 */
203enum iwl_agg_state { 204enum 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,