summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-11-21 22:31:54 +0200
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-12-16 07:22:38 -0800
commit1ba42da479e8b4a4198a702bc819850d9926a035 (patch)
tree09c0fb2e028c7b3a4b18e1b9516c2255da6911d2
parenteb9a372a73ea3e2b7e795a7ea03a5b8d92815672 (diff)
iwlwifi: we can wake SW queues even when draining HW queues
In the very first implementation of HT, the driver was responsible for the queueing: stopping and waking the queues while the HW queues where being drained. In this implementation, we had to deal with the case where we were draining the AGG queue because we wanted to tear down the BA agreement. In the normal flow (when we don't drain any HW queue), when packets are reclaimed, we wake the SW queue in case the SW queue was stopped which can happen when the HW queues are too full. While draining a HW queue, we must make sure that we don't wake the SW queue, since the whole point of the draining is to empty totally the HW queue and not only get below a certain threshold. This is why there is condition in the reclaim function: if (NOT EMPTYING DELBA) wake the SW queue is applicable Since then, a lot has changed and mac80211 is now able to buffer packets that are being sent to a packet list that will be spliced after the driver has reported it has drained its HW queues. Hence, there is no need for the for aforementioned if, and we can safely wake up the queue even if we are draining HW queues. Removing this if, also allows us to remove the wake_queue in check_empty that was there in order to deal with a corner case created by the if. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c16
1 files changed, 3 insertions, 13 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 4d318431270b..ac689ed2eba8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1297,8 +1297,6 @@ static int iwlagn_txq_check_empty(struct iwl_trans *trans,
iwl_stop_tx_ba_trans_ready(priv(trans),
NUM_IWL_RXON_CTX,
sta_id, tid);
- iwl_wake_queue(trans, &trans_pcie->txq[txq_id],
- "DELBA flow complete");
}
break;
case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1326,28 +1324,20 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
- enum iwl_agg_state agg_state;
/* n_bd is usually 256 => n_bd - 1 = 0xff */
int tfd_num = ssn & (txq->q.n_bd - 1);
int freed = 0;
- bool cond;
txq->time_stamp = jiffies;
- if (txq->sched_retry) {
- agg_state =
- trans->shrd->tid_data[txq->sta_id][txq->tid].agg.state;
- cond = (agg_state != IWL_EMPTYING_HW_QUEUE_DELBA);
- } else {
- cond = (status != TX_STATUS_FAIL_PASSIVE_NO_RX);
- }
-
if (txq->q.read_ptr != tfd_num) {
IWL_DEBUG_TX_REPLY(trans, "[Q %d | AC %d] %d -> %d (%d)\n",
txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr,
tfd_num, ssn);
freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
- if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond)
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ (!txq->sched_retry ||
+ status != TX_STATUS_FAIL_PASSIVE_NO_RX))
iwl_wake_queue(trans, txq, "Packets reclaimed");
}