From 19e737c98479f040e23987e50596a861e5e88b92 Mon Sep 17 00:00:00 2001 From: Eytan Lifshitz Date: Mon, 9 Sep 2013 13:30:15 +0200 Subject: [PATCH] iwlwifi: mvm: add support for NICs which have only 16 Tx queues. Some NICs embedded in platforms that have only 16 Tx queues, this affect the mapping of the Tx queues. Signed-off-by: Eytan Lifshitz Reviewed-by: Emmanuel Grumbach Reviewed-by: Gregory Greenman Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 12 ++++++------ drivers/net/wireless/iwlwifi/mvm/fw.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 12 ++++++------ drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 5 +++++ drivers/net/wireless/iwlwifi/mvm/ops.c | 8 ++++++++ drivers/net/wireless/iwlwifi/mvm/sta.c | 6 +++--- drivers/net/wireless/iwlwifi/mvm/tx.c | 10 +++++----- 8 files changed, 35 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index c42424c69183..bad5a552dd8d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -72,17 +72,17 @@ #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 */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index f171dca83cd2..83fc5ca04433 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -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; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index c01cf17eedb2..196c4ebb186f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -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; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index a42c6bb1b0e8..f9eb708d2c33 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -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"; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 6bce6e168ae4..3e29d3c91617 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -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 */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index d232e83994df..59b7cb3c6134 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -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); diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index fa900c75c509..b320350e0226 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -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; } diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 1606e1da5b0c..43d97c33a75a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -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)) -- 2.30.2