aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-08-26 02:11:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-29 15:33:00 -0400
commit7f01d567c5b9e136d9b070e00be88169d5b2227e (patch)
tree9d324c7d826a9a3ace799df5bceae41c5795bbcb /drivers/net/wireless/iwlwifi/iwl-agn-tx.c
parent464021ffc1c080283e67729d966d76612728a08c (diff)
iwlagn: move the disable agg logic to transport layer
Since all the check_empty logic is now in the transport layer, the upper layer doesn't need to know anything about tx queues. The disable aggregation flow was the last to know what a tx queue is, so move it too. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c63
1 files changed, 4 insertions, 59 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 45eb45af5953..bc3268a0c752 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -408,10 +408,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
408int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 408int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
409 struct ieee80211_sta *sta, u16 tid) 409 struct ieee80211_sta *sta, u16 tid)
410{ 410{
411 int txq_id, sta_id, ssn; 411 int sta_id;
412 struct iwl_tid_data *tid_data; 412 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
413 int write_ptr, read_ptr;
414 unsigned long flags;
415 413
416 sta_id = iwl_sta_id(sta); 414 sta_id = iwl_sta_id(sta);
417 415
@@ -420,61 +418,8 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
420 return -ENXIO; 418 return -ENXIO;
421 } 419 }
422 420
423 spin_lock_irqsave(&priv->shrd->sta_lock, flags); 421 return iwl_trans_tx_agg_disable(trans(priv), vif_priv->ctx->ctxid,
424 422 sta_id, tid);
425 tid_data = &priv->shrd->tid_data[sta_id][tid];
426 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
427 txq_id = tid_data->agg.txq_id;
428
429 switch (priv->shrd->tid_data[sta_id][tid].agg.state) {
430 case IWL_EMPTYING_HW_QUEUE_ADDBA:
431 /*
432 * This can happen if the peer stops aggregation
433 * again before we've had a chance to drain the
434 * queue we selected previously, i.e. before the
435 * session was really started completely.
436 */
437 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
438 goto turn_off;
439 case IWL_AGG_ON:
440 break;
441 default:
442 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
443 }
444
445 write_ptr = priv->txq[txq_id].q.write_ptr;
446 read_ptr = priv->txq[txq_id].q.read_ptr;
447
448 /* The queue is not empty */
449 if (write_ptr != read_ptr) {
450 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
451 priv->shrd->tid_data[sta_id][tid].agg.state =
452 IWL_EMPTYING_HW_QUEUE_DELBA;
453 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
454 return 0;
455 }
456
457 IWL_DEBUG_HT(priv, "HW queue is empty\n");
458 turn_off:
459 priv->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
460
461 /* do not restore/save irqs */
462 spin_unlock(&priv->shrd->sta_lock);
463 spin_lock(&priv->shrd->lock);
464
465 /*
466 * the only reason this call can fail is queue number out of range,
467 * which can happen if uCode is reloaded and all the station
468 * information are lost. if it is outside the range, there is no need
469 * to deactivate the uCode queue, just return "success" to allow
470 * mac80211 to clean up it own data.
471 */
472 iwl_trans_txq_agg_disable(trans(priv), txq_id);
473 spin_unlock_irqrestore(&priv->shrd->lock, flags);
474
475 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
476
477 return 0;
478} 423}
479 424
480static void iwlagn_non_agg_tx_status(struct iwl_priv *priv, 425static void iwlagn_non_agg_tx_status(struct iwl_priv *priv,