]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/net/wireless/intel/iwlwifi/mvm/utils.c
iwlwifi: mvm: remove references to queue_info in new TX path
[mirror_ubuntu-bionic-kernel.git] / drivers / net / wireless / intel / iwlwifi / mvm / utils.c
index dedea96a8e0ff7cd3c609d9e5a45976705b54451..8f4f176e204e588567f7fc8552f9982cc65c80b3 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
- * Copyright (C) 2015 Intel Deutschland GmbH
+ * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -34,6 +34,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -591,6 +592,10 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq)
 
        lockdep_assert_held(&mvm->queue_info_lock);
 
+       /* This should not be hit with new TX path */
+       if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
+               return -ENOSPC;
+
        /* Start by looking for a free queue */
        for (i = minq; i <= maxq; i++)
                if (mvm->queue_info[i].hw_queue_refcount == 0 &&
@@ -627,6 +632,9 @@ int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
        };
        int ret;
 
+       if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
+               return -EINVAL;
+
        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)) {
@@ -644,50 +652,94 @@ int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
        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)
+static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue,
+                                      int mac80211_queue, u8 sta_id, u8 tid)
 {
        bool enable_queue = true;
 
        spin_lock_bh(&mvm->queue_info_lock);
 
        /* Make sure this TID isn't already enabled */
-       if (mvm->queue_info[queue].tid_bitmap & BIT(cfg->tid)) {
+       if (mvm->queue_info[queue].tid_bitmap & BIT(tid)) {
                spin_unlock_bh(&mvm->queue_info_lock);
                IWL_ERR(mvm, "Trying to enable TXQ %d with existing TID %d\n",
-                       queue, cfg->tid);
-               return;
+                       queue, tid);
+               return false;
        }
 
        /* Update mappings and refcounts */
        if (mvm->queue_info[queue].hw_queue_refcount > 0)
                enable_queue = false;
 
-       mvm->queue_info[queue].hw_queue_to_mac80211 |= BIT(mac80211_queue);
+       mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue);
+
        mvm->queue_info[queue].hw_queue_refcount++;
-       mvm->queue_info[queue].tid_bitmap |= BIT(cfg->tid);
-       mvm->queue_info[queue].ra_sta_id = cfg->sta_id;
+       mvm->queue_info[queue].tid_bitmap |= BIT(tid);
+       mvm->queue_info[queue].ra_sta_id = sta_id;
 
        if (enable_queue) {
-               if (cfg->tid != IWL_MAX_TID_COUNT)
+               if (tid != IWL_MAX_TID_COUNT)
                        mvm->queue_info[queue].mac80211_ac =
-                               tid_to_mac80211_ac[cfg->tid];
+                               tid_to_mac80211_ac[tid];
                else
                        mvm->queue_info[queue].mac80211_ac = IEEE80211_AC_VO;
 
-               mvm->queue_info[queue].txq_tid = cfg->tid;
+               mvm->queue_info[queue].txq_tid = tid;
        }
 
        IWL_DEBUG_TX_QUEUES(mvm,
                            "Enabling TXQ #%d refcount=%d (mac80211 map:0x%x)\n",
                            queue, mvm->queue_info[queue].hw_queue_refcount,
-                           mvm->queue_info[queue].hw_queue_to_mac80211);
+                           mvm->hw_queue_to_mac80211[queue]);
 
        spin_unlock_bh(&mvm->queue_info_lock);
 
+       return enable_queue;
+}
+
+int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue,
+                           u8 sta_id, u8 tid, unsigned int timeout)
+{
+       struct iwl_tx_queue_cfg_cmd cmd = {
+               .flags = cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE),
+               .sta_id = sta_id,
+               .tid = tid,
+       };
+       int queue;
+
+       if (cmd.tid == IWL_MAX_TID_COUNT)
+               cmd.tid = IWL_MGMT_TID;
+       queue = iwl_trans_txq_alloc(mvm->trans, (void *)&cmd,
+                                   SCD_QUEUE_CFG, timeout);
+
+       if (queue < 0) {
+               IWL_DEBUG_TX_QUEUES(mvm,
+                                   "Failed allocating TXQ for sta %d tid %d, ret: %d\n",
+                                   sta_id, tid, queue);
+               return queue;
+       }
+
+       IWL_DEBUG_TX_QUEUES(mvm, "Enabling TXQ #%d for sta %d tid %d\n",
+                           queue, sta_id, tid);
+
+       mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue);
+       IWL_DEBUG_TX_QUEUES(mvm,
+                           "Enabling TXQ #%d (mac80211 map:0x%x)\n",
+                           queue, mvm->hw_queue_to_mac80211[queue]);
+
+       return queue;
+}
+
+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)
+{
+       if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
+               return;
+
        /* Send the enabling command if we need to */
-       if (enable_queue) {
+       if (iwl_mvm_update_txq_mapping(mvm, queue, mac80211_queue,
+                                      cfg->sta_id, cfg->tid)) {
                struct iwl_scd_txq_cfg_cmd cmd = {
                        .scd_queue = queue,
                        .action = SCD_CFG_ENABLE_QUEUE,
@@ -701,7 +753,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
 
                iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL,
                                         wdg_timeout);
-               WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd),
+               WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0,
+                                         sizeof(struct iwl_scd_txq_cfg_cmd),
                                          &cmd),
                     "Failed to configure queue %d on FIFO %d\n", queue,
                     cfg->fifo);
@@ -718,6 +771,16 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
        bool remove_mac_queue = true;
        int ret;
 
+       if (iwl_mvm_has_new_tx_api(mvm)) {
+               spin_lock_bh(&mvm->queue_info_lock);
+               mvm->hw_queue_to_mac80211[queue] &= ~BIT(mac80211_queue);
+               spin_unlock_bh(&mvm->queue_info_lock);
+
+               iwl_trans_txq_free(mvm->trans, queue);
+
+               return 0;
+       }
+
        spin_lock_bh(&mvm->queue_info_lock);
 
        if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) {
@@ -744,7 +807,7 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
        }
 
        if (remove_mac_queue)
-               mvm->queue_info[queue].hw_queue_to_mac80211 &=
+               mvm->hw_queue_to_mac80211[queue] &=
                        ~BIT(mac80211_queue);
        mvm->queue_info[queue].hw_queue_refcount--;
 
@@ -757,7 +820,7 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
                            "Disabling TXQ #%d refcount=%d (mac80211 map:0x%x)\n",
                            queue,
                            mvm->queue_info[queue].hw_queue_refcount,
-                           mvm->queue_info[queue].hw_queue_to_mac80211);
+                           mvm->hw_queue_to_mac80211[queue]);
 
        /* If the queue is still enabled - nothing left to do in this func */
        if (cmd.action == SCD_CFG_ENABLE_QUEUE) {
@@ -771,16 +834,16 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
        /* Make sure queue info is correct even though we overwrite it */
        WARN(mvm->queue_info[queue].hw_queue_refcount ||
             mvm->queue_info[queue].tid_bitmap ||
-            mvm->queue_info[queue].hw_queue_to_mac80211,
+            mvm->hw_queue_to_mac80211[queue],
             "TXQ #%d info out-of-sync - refcount=%d, mac map=0x%x, tid=0x%x\n",
             queue, mvm->queue_info[queue].hw_queue_refcount,
-            mvm->queue_info[queue].hw_queue_to_mac80211,
+            mvm->hw_queue_to_mac80211[queue],
             mvm->queue_info[queue].tid_bitmap);
 
        /* If we are here - the queue is freed and we can zero out these vals */
        mvm->queue_info[queue].hw_queue_refcount = 0;
        mvm->queue_info[queue].tid_bitmap = 0;
-       mvm->queue_info[queue].hw_queue_to_mac80211 = 0;
+       mvm->hw_queue_to_mac80211[queue] = 0;
 
        /* Regardless if this is a reserved TXQ for a STA - mark it as false */
        mvm->queue_info[queue].reserved = false;
@@ -789,11 +852,11 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
 
        iwl_trans_txq_disable(mvm->trans, queue, false);
        ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags,
-                                  sizeof(cmd), &cmd);
+                                  sizeof(struct iwl_scd_txq_cfg_cmd), &cmd);
+
        if (ret)
                IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
                        queue, ret);
-
        return ret;
 }
 
@@ -816,7 +879,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
                .data = { lq, },
        };
 
-       if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
+       if (WARN_ON(lq->sta_id == IWL_MVM_INVALID_STA))
                return -EINVAL;
 
        return iwl_mvm_send_cmd(mvm, &cmd);
@@ -1006,6 +1069,35 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm)
        return bss_iter_data.vif;
 }
 
+struct iwl_sta_iter_data {
+       bool assoc;
+};
+
+static void iwl_mvm_sta_iface_iterator(void *_data, u8 *mac,
+                                      struct ieee80211_vif *vif)
+{
+       struct iwl_sta_iter_data *data = _data;
+
+       if (vif->type != NL80211_IFTYPE_STATION)
+               return;
+
+       if (vif->bss_conf.assoc)
+               data->assoc = true;
+}
+
+bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm)
+{
+       struct iwl_sta_iter_data data = {
+               .assoc = false,
+       };
+
+       ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+                                                  IEEE80211_IFACE_ITER_NORMAL,
+                                                  iwl_mvm_sta_iface_iterator,
+                                                  &data);
+       return data.assoc;
+}
+
 unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif,
                                    bool tdls, bool cmd_q)
@@ -1088,6 +1180,9 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
        lockdep_assert_held(&mvmsta->lock);
        lockdep_assert_held(&mvm->queue_info_lock);
 
+       if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
+               return;
+
        /* Go over all non-active TIDs, incl. IWL_MAX_TID_COUNT (for mgmt) */
        for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) {
                /* If some TFDs are still queued - don't mark TID as inactive */
@@ -1114,8 +1209,8 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
        for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) {
                int mac_queue = mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]];
 
-               mvmsta->tid_data[tid].txq_id = IEEE80211_INVAL_HW_QUEUE;
-               mvm->queue_info[queue].hw_queue_to_mac80211 &= ~BIT(mac_queue);
+               mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE;
+               mvm->hw_queue_to_mac80211[queue] &= ~BIT(mac_queue);
                mvm->queue_info[queue].hw_queue_refcount--;
                mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
                mvmsta->tid_data[tid].is_tid_active = false;
@@ -1135,7 +1230,7 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
         */
        tid_bitmap = mvm->queue_info[queue].tid_bitmap;
        for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) {
-               mvm->queue_info[queue].hw_queue_to_mac80211 |=
+               mvm->hw_queue_to_mac80211[queue] |=
                        BIT(mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]]);
        }
 
@@ -1154,6 +1249,9 @@ void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
        unsigned long now = jiffies;
        int i;
 
+       if (iwl_mvm_has_new_tx_api(mvm))
+               return;
+
        spin_lock_bh(&mvm->queue_info_lock);
        for (i = 0; i < IWL_MAX_HW_QUEUES; i++)
                if (mvm->queue_info[i].hw_queue_refcount > 0)