diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-08-26 02:11:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 15:33:00 -0400 |
commit | 7f01d567c5b9e136d9b070e00be88169d5b2227e (patch) | |
tree | 9d324c7d826a9a3ace799df5bceae41c5795bbcb /drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |
parent | 464021ffc1c080283e67729d966d76612728a08c (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.c | 63 |
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, | |||
408 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 408 | int 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 | ||
480 | static void iwlagn_non_agg_tx_status(struct iwl_priv *priv, | 425 | static void iwlagn_non_agg_tx_status(struct iwl_priv *priv, |