diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/utils.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index f0ffd62f02d3..161b99efd63d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -90,11 +90,17 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd) * the mutex, this ensures we don't try to send two * (or more) synchronous commands at a time. */ - if (!(cmd->flags & CMD_ASYNC)) + if (!(cmd->flags & CMD_ASYNC)) { lockdep_assert_held(&mvm->mutex); + if (!(cmd->flags & CMD_SEND_IN_IDLE)) + iwl_mvm_ref(mvm, IWL_MVM_REF_SENDING_CMD); + } ret = iwl_trans_send_cmd(mvm->trans, cmd); + if (!(cmd->flags & (CMD_ASYNC | CMD_SEND_IN_IDLE))) + iwl_mvm_unref(mvm, IWL_MVM_REF_SENDING_CMD); + /* * If the caller wants the SKB, then don't hide any problems, the * caller might access the response buffer which will be NULL if @@ -581,12 +587,45 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 minq, u8 maxq) for (i = minq; i <= maxq; i++) if (mvm->queue_info[i].hw_queue_refcount == 0 && - !mvm->queue_info[i].setup_reserved) + mvm->queue_info[i].status == IWL_MVM_QUEUE_FREE) return i; return -ENOSPC; } +int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id, + int tid, int frame_limit, u16 ssn) +{ + struct iwl_scd_txq_cfg_cmd cmd = { + .scd_queue = queue, + .enable = 1, + .window = frame_limit, + .sta_id = sta_id, + .ssn = cpu_to_le16(ssn), + .tx_fifo = fifo, + .aggregate = (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE || + queue == IWL_MVM_DQA_BSS_CLIENT_QUEUE), + .tid = tid, + }; + int ret; + + spin_lock_bh(&mvm->queue_info_lock); + if (WARN(mvm->queue_info[queue].hw_queue_refcount == 0, + "Trying to reconfig unallocated queue %d\n", queue)) { + spin_unlock_bh(&mvm->queue_info_lock); + return -ENXIO; + } + spin_unlock_bh(&mvm->queue_info_lock); + + IWL_DEBUG_TX_QUEUES(mvm, "Reconfig SCD for TXQ #%d\n", queue); + + ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd); + WARN_ONCE(ret, "Failed to re-configure queue %d on FIFO %d, ret=%d\n", + queue, fifo, ret); + + return ret; +} + void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg, unsigned int wdg_timeout) @@ -682,6 +721,8 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, mvm->queue_info[queue].hw_queue_refcount--; cmd.enable = mvm->queue_info[queue].hw_queue_refcount ? 1 : 0; + if (!cmd.enable) + mvm->queue_info[queue].status = IWL_MVM_QUEUE_FREE; IWL_DEBUG_TX_QUEUES(mvm, "Disabling TXQ #%d refcount=%d (mac80211 map:0x%x)\n", |