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 <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>
This commit is contained in:
committed by
Johannes Berg
parent
81a67e32c4
commit
19e737c984
@@ -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,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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 {
|
|||||||
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,
|
|||||||
.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,
|
|||||||
/* 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,
|
|||||||
/* 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)
|
|||||||
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 {
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
* 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,
|
|||||||
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))
|
||||||
|
|||||||
Reference in New Issue
Block a user