diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-01-20 18:02:40 +0300 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-03-12 10:57:43 +0300 |
commit | e0b8d405132db38fafc9da86ef4de0ebe2be468e (patch) | |
tree | 07e1cacc2db49e3a7534e4d012e75e96f5ad0d45 /drivers/net/wireless/iwlwifi/pcie/tx.c | |
parent | ad82d8a5366fc3f84ea9ee0fa417cdfb42b28ec8 (diff) | |
download | linux-e0b8d405132db38fafc9da86ef4de0ebe2be468e.tar.xz |
iwlwifi: pcie: allow the op_mode to freeze the stuck queue timer
This allows the op_mode to let the transport know that a
queue is currently frozen and that its timer should be
stopped.
When the queue is unfrozen, its timer should be set to
expire after the remainder of the timeout has elapsed.
This can be used when stations go to sleep. When a station
goes to sleep, the op_mode can freeze the timer so that the
queue will never be considered as stuck. When the station
wakes up, the queue will be unfrozen.
This is meant to avoid false positives that would happen if
a buggy station goes to sleep for a very long time. In case
we have a dedicated queue for this station (BA agreement)
and it goes to sleep for a very long time, the queue would
rightfully be stopped during all that time. In this case,
the stuck queue timer could fire and that would be a false
positive.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 26e6dd0e9f05..06952aadfd7b 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -929,10 +929,19 @@ error: static inline void iwl_pcie_txq_progress(struct iwl_txq *txq) { + lockdep_assert_held(&txq->lock); + if (!txq->wd_timeout) return; /* + * station is asleep and we send data - that must + * be uAPSD or PS-Poll. Don't rearm the timer. + */ + if (txq->frozen) + return; + + /* * if empty delete timer, otherwise move timer forward * since we're making progress on this queue */ @@ -1265,6 +1274,9 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, SCD_TX_STTS_QUEUE_OFFSET(txq_id); static const u32 zero_val[4] = {}; + trans_pcie->txq[txq_id].frozen_expiry_remainder = 0; + trans_pcie->txq[txq_id].frozen = false; + /* * Upon HW Rfkill - we stop the device, and then stop the queues * in the op_mode. Just for the sake of the simplicity of the op_mode, |