diff options
author | Sara Sharon <sara.sharon@intel.com> | 2017-03-06 10:16:11 +0200 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2017-06-02 14:14:12 +0300 |
commit | d6d517b7730c2dada199db83ebbc670c50fa9952 (patch) | |
tree | cf94b66e7cd2f2f08e61db6a5e71a78e5923af4e /drivers/net/wireless/intel/iwlwifi/mvm/sta.c | |
parent | 3a07d36c2d891b30c25e03146eceaeb6e6375810 (diff) |
iwlwifi: add wait for tx queue empty
Now that we have 512 queues, add a wait for single TX
queue to gen2.
This replaces gen1 wait_tx_queues_empty, which was limited
to 32 queues.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/sta.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 9f74d4ff6b73..3dad87b79cf0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1590,6 +1590,29 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm, } } +int iwl_mvm_wait_sta_queues_empty(struct iwl_mvm *mvm, + struct iwl_mvm_sta *mvm_sta) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(mvm_sta->tid_data); i++) { + u16 txq_id; + + spin_lock_bh(&mvm_sta->lock); + txq_id = mvm_sta->tid_data[i].txq_id; + spin_unlock_bh(&mvm_sta->lock); + + if (txq_id == IWL_MVM_INVALID_QUEUE) + continue; + + ret = iwl_trans_wait_txq_empty(mvm->trans, txq_id); + if (ret) + break; + } + + return ret; +} + int iwl_mvm_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -1614,8 +1637,14 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, ret = iwl_mvm_flush_sta(mvm, mvm_sta, false, 0); if (ret) return ret; - ret = iwl_trans_wait_tx_queues_empty(mvm->trans, - mvm_sta->tfd_queue_msk); + if (iwl_mvm_has_new_tx_api(mvm)) { + ret = iwl_mvm_wait_sta_queues_empty(mvm, mvm_sta); + } else { + u32 q_mask = mvm_sta->tfd_queue_msk; + + ret = iwl_trans_wait_tx_queues_empty(mvm->trans, + q_mask); + } if (ret) return ret; ret = iwl_mvm_drain_sta(mvm, mvm_sta, false); @@ -2850,7 +2879,13 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, iwl_mvm_drain_sta(mvm, mvmsta, true); if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), 0)) IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); - iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(txq_id)); + + if (iwl_mvm_has_new_tx_api(mvm)) + iwl_trans_wait_txq_empty(mvm->trans, txq_id); + + else + iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(txq_id)); + iwl_mvm_drain_sta(mvm, mvmsta, false); iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); |