Commit 19e737c9 authored by Eytan Lifshitz's avatar Eytan Lifshitz Committed by Johannes Berg

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: default avatarEytan Lifshitz <eytan.lifshitz@intel.com>
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 81a67e32
...@@ -72,17 +72,17 @@ ...@@ -72,17 +72,17 @@
#include "fw-api-d3.h" #include "fw-api-d3.h"
#include "fw-api-bt-coex.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 { enum {
IWL_MVM_OFFCHANNEL_QUEUE = 8, IWL_MVM_OFFCHANNEL_QUEUE = 8,
IWL_MVM_CMD_QUEUE = 9, 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 #define IWL_MVM_STATION_COUNT 16
/* commands */ /* commands */
......
...@@ -199,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, ...@@ -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++) { 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; mvm->queue_to_mac80211[i] = i;
else else
mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
......
...@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data { ...@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data {
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; 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 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; enum iwl_tsf_id preferred_tsf;
bool found_vif; bool found_vif;
}; };
...@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
.preferred_tsf = NUM_TSF_IDS, .preferred_tsf = NUM_TSF_IDS,
.used_hw_queues = { .used_hw_queues = {
BIT(IWL_MVM_OFFCHANNEL_QUEUE) | BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
BIT(IWL_MVM_AUX_QUEUE) | BIT(mvm->aux_queue) |
BIT(IWL_MVM_CMD_QUEUE) BIT(IWL_MVM_CMD_QUEUE)
}, },
.found_vif = false, .found_vif = false,
...@@ -302,9 +302,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -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 */ /* Find available queues, and allocate them to the ACs */
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
u8 queue = find_first_zero_bit(data.used_hw_queues, 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"); IWL_ERR(mvm, "Failed to allocate queue\n");
ret = -EIO; ret = -EIO;
goto exit_fail; goto exit_fail;
...@@ -317,9 +317,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -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 */ /* Allocate the CAB queue for softAP and GO interfaces */
if (vif->type == NL80211_IFTYPE_AP) { if (vif->type == NL80211_IFTYPE_AP) {
u8 queue = find_first_zero_bit(data.used_hw_queues, 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"); IWL_ERR(mvm, "Failed to allocate cab queue\n");
ret = -EIO; ret = -EIO;
goto exit_fail; goto exit_fail;
......
...@@ -167,7 +167,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ...@@ -167,7 +167,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IEEE80211_HW_SUPPORTS_STATIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS |
IEEE80211_HW_SUPPORTS_UAPSD; 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->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
hw->rate_control_algorithm = "iwl-mvm-rs"; hw->rate_control_algorithm = "iwl-mvm-rs";
......
...@@ -547,6 +547,11 @@ struct iwl_mvm { ...@@ -547,6 +547,11 @@ struct iwl_mvm {
u32 noa_duration; u32 noa_duration;
struct ieee80211_vif *noa_vif; struct ieee80211_vif *noa_vif;
#endif #endif
/* Tx queues */
u8 aux_queue;
u8 first_agg_queue;
u8 last_agg_queue;
}; };
/* Extract MVM priv from op_mode and _hw */ /* Extract MVM priv from op_mode and _hw */
......
...@@ -352,6 +352,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -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->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); mutex_init(&mvm->mutex);
spin_lock_init(&mvm->async_handlers_lock); spin_lock_init(&mvm->async_handlers_lock);
INIT_LIST_HEAD(&mvm->time_event_list); INIT_LIST_HEAD(&mvm->time_event_list);
......
...@@ -847,13 +847,13 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -847,13 +847,13 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
for (txq_id = IWL_MVM_FIRST_AGG_QUEUE; for (txq_id = mvm->first_agg_queue;
txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++) txq_id <= mvm->last_agg_queue; txq_id++)
if (mvm->queue_to_mac80211[txq_id] == if (mvm->queue_to_mac80211[txq_id] ==
IWL_INVALID_MAC80211_QUEUE) IWL_INVALID_MAC80211_QUEUE)
break; 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"); IWL_ERR(mvm, "Failed to allocate agg queue\n");
return -EIO; return -EIO;
} }
......
...@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
spin_unlock(&mvmsta->lock); 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]); atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
return 0; return 0;
...@@ -613,7 +613,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -613,7 +613,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
info); info);
/* Single frame failure in an AMPDU queue => send BAR */ /* 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_ACK))
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
...@@ -626,7 +626,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -626,7 +626,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
ieee80211_tx_status_ni(mvm->hw, skb); 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: /* If this is an aggregation queue, we use the ssn since:
* ssn = wifi seq_num % 256. * ssn = wifi seq_num % 256.
* The seq_ctl is the sequence control of the packet to which * 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, ...@@ -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 * If the txq is not an AMPDU queue, there is no chance we freed
* several skbs. Check that out... * 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])) { atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
if (mvmsta) { if (mvmsta) {
/* /*
...@@ -780,7 +780,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, ...@@ -780,7 +780,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
u16 sequence = le16_to_cpu(pkt->hdr.sequence); u16 sequence = le16_to_cpu(pkt->hdr.sequence);
struct ieee80211_sta *sta; 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; return;
if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment