iwlwifi: mvm: add support for NICs which have only 16 Tx queues.
authorEytan Lifshitz <eytan.lifshitz@intel.com>
Mon, 9 Sep 2013 11:30:15 +0000 (13:30 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 11 Oct 2013 07:56:58 +0000 (09:56 +0200)
Some NICs embedded in platforms that have only 16 Tx queues,
this affect the mapping of the Tx queues.

Signed-off-by: Eytan Lifshitz <eytan.lifshitz@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/tx.c

index c42424c..bad5a55 100644 (file)
 #include "fw-api-d3.h"
 #include "fw-api-bt-coex.h"
 
-/* queue and FIFO numbers by usage */
+/* maximal number of Tx queues in any platform */
+#define IWL_MVM_MAX_QUEUES     20
+
+/* Tx queue numbers */
 enum {
        IWL_MVM_OFFCHANNEL_QUEUE = 8,
        IWL_MVM_CMD_QUEUE = 9,
-       IWL_MVM_AUX_QUEUE = 15,
-       IWL_MVM_FIRST_AGG_QUEUE = 16,
-       IWL_MVM_NUM_QUEUES = 20,
-       IWL_MVM_LAST_AGG_QUEUE = IWL_MVM_NUM_QUEUES - 1,
-       IWL_MVM_CMD_FIFO = 7
 };
 
+#define IWL_MVM_CMD_FIFO       7
+
 #define IWL_MVM_STATION_COUNT  16
 
 /* commands */
index f171dca..83fc5ca 100644 (file)
@@ -199,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
         */
 
        for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
-               if (i < IWL_MVM_FIRST_AGG_QUEUE && i != IWL_MVM_CMD_QUEUE)
+               if (i < mvm->first_agg_queue && i != IWL_MVM_CMD_QUEUE)
                        mvm->queue_to_mac80211[i] = i;
                else
                        mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
index c01cf17..196c4eb 100644 (file)
@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data {
        struct ieee80211_vif *vif;
        unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
        unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
-       unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_FIRST_AGG_QUEUE)];
+       unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)];
        enum iwl_tsf_id preferred_tsf;
        bool found_vif;
 };
@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
                .preferred_tsf = NUM_TSF_IDS,
                .used_hw_queues = {
                        BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
-                       BIT(IWL_MVM_AUX_QUEUE) |
+                       BIT(mvm->aux_queue) |
                        BIT(IWL_MVM_CMD_QUEUE)
                },
                .found_vif = false,
@@ -302,9 +302,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
        /* Find available queues, and allocate them to the ACs */
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
                u8 queue = find_first_zero_bit(data.used_hw_queues,
-                                              IWL_MVM_FIRST_AGG_QUEUE);
+                                              mvm->first_agg_queue);
 
-               if (queue >= IWL_MVM_FIRST_AGG_QUEUE) {
+               if (queue >= mvm->first_agg_queue) {
                        IWL_ERR(mvm, "Failed to allocate queue\n");
                        ret = -EIO;
                        goto exit_fail;
@@ -317,9 +317,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
        /* Allocate the CAB queue for softAP and GO interfaces */
        if (vif->type == NL80211_IFTYPE_AP) {
                u8 queue = find_first_zero_bit(data.used_hw_queues,
-                                              IWL_MVM_FIRST_AGG_QUEUE);
+                                              mvm->first_agg_queue);
 
-               if (queue >= IWL_MVM_FIRST_AGG_QUEUE) {
+               if (queue >= mvm->first_agg_queue) {
                        IWL_ERR(mvm, "Failed to allocate cab queue\n");
                        ret = -EIO;
                        goto exit_fail;
index a42c6bb..f9eb708 100644 (file)
@@ -167,7 +167,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                    IEEE80211_HW_SUPPORTS_STATIC_SMPS |
                    IEEE80211_HW_SUPPORTS_UAPSD;
 
-       hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
+       hw->queues = mvm->first_agg_queue;
        hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
        hw->rate_control_algorithm = "iwl-mvm-rs";
 
index 6bce6e1..3e29d3c 100644 (file)
@@ -547,6 +547,11 @@ struct iwl_mvm {
        u32 noa_duration;
        struct ieee80211_vif *noa_vif;
 #endif
+
+       /* Tx queues */
+       u8 aux_queue;
+       u8 first_agg_queue;
+       u8 last_agg_queue;
 };
 
 /* Extract MVM priv from op_mode and _hw */
index d232e83..59b7cb3 100644 (file)
@@ -352,6 +352,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
 
        mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0;
 
+       mvm->aux_queue = 15;
+       mvm->first_agg_queue = 16;
+       mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1;
+       if (mvm->cfg->base_params->num_of_queues == 16) {
+               mvm->aux_queue = 11;
+               mvm->first_agg_queue = 12;
+       }
+
        mutex_init(&mvm->mutex);
        spin_lock_init(&mvm->async_handlers_lock);
        INIT_LIST_HEAD(&mvm->time_event_list);
index fa900c7..b320350 100644 (file)
@@ -847,13 +847,13 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        lockdep_assert_held(&mvm->mutex);
 
-       for (txq_id = IWL_MVM_FIRST_AGG_QUEUE;
-            txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++)
+       for (txq_id = mvm->first_agg_queue;
+            txq_id <= mvm->last_agg_queue; txq_id++)
                if (mvm->queue_to_mac80211[txq_id] ==
                    IWL_INVALID_MAC80211_QUEUE)
                        break;
 
-       if (txq_id > IWL_MVM_LAST_AGG_QUEUE) {
+       if (txq_id > mvm->last_agg_queue) {
                IWL_ERR(mvm, "Failed to allocate agg queue\n");
                return -EIO;
        }
index 1606e1d..43d97c3 100644 (file)
@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        spin_unlock(&mvmsta->lock);
 
-       if (txq_id < IWL_MVM_FIRST_AGG_QUEUE)
+       if (txq_id < mvm->first_agg_queue)
                atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
 
        return 0;
@@ -613,7 +613,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
                                            info);
 
                /* Single frame failure in an AMPDU queue => send BAR */
-               if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE &&
+               if (txq_id >= mvm->first_agg_queue &&
                    !(info->flags & IEEE80211_TX_STAT_ACK))
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 
@@ -626,7 +626,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
                ieee80211_tx_status_ni(mvm->hw, skb);
        }
 
-       if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) {
+       if (txq_id >= mvm->first_agg_queue) {
                /* If this is an aggregation queue, we use the ssn since:
                 * ssn = wifi seq_num % 256.
                 * The seq_ctl is the sequence control of the packet to which
@@ -684,7 +684,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
         * If the txq is not an AMPDU queue, there is no chance we freed
         * several skbs. Check that out...
         */
-       if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) &&
+       if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) &&
            atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
                if (mvmsta) {
                        /*
@@ -780,7 +780,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        struct ieee80211_sta *sta;
 
-       if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE))
+       if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < mvm->first_agg_queue))
                return;
 
        if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))