Commit 110cf810 authored by Johannes Berg's avatar Johannes Berg Committed by Emmanuel Grumbach

iwlwifi: mvm: use iwl_mvm_mac_get_queues_mask() more

There are a few places that can call the function
iwl_mvm_mac_get_queues_mask() instead of open-coding the
equivalent, so do that. This requires changing it to return
the multicast queue as part of the bitmap, which broke GO
mode because including it in the broadcast station queues
seems to confuse the firmware, so work around that.

Also, the API defines that the CAB queue shouldn't be
included in the TFD queue mask, adjust the comment
accordingly (not a bug).
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 9e848010
......@@ -75,9 +75,6 @@
#include "fw-api-coex.h"
#include "fw-api-scan.h"
/* maximal number of Tx queues in any platform */
#define IWL_MVM_MAX_QUEUES 20
/* Tx queue numbers */
enum {
IWL_MVM_OFFCHANNEL_QUEUE = 8,
......
......@@ -83,7 +83,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_MAX_QUEUES)];
u32 used_hw_queues;
enum iwl_tsf_id preferred_tsf;
bool found_vif;
};
......@@ -194,12 +194,31 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
data->preferred_tsf = NUM_TSF_IDS;
}
/*
* Get the mask of the queues used by the vif
*/
u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
u32 qmask = 0, ac;
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
qmask |= BIT(vif->hw_queue[ac]);
if (vif->type == NL80211_IFTYPE_AP)
qmask |= BIT(vif->cab_queue);
return qmask;
}
static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
struct iwl_mvm_mac_iface_iterator_data *data = _data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 ac;
/* Iterator may already find the interface being added -- skip it */
if (vif == data->vif) {
......@@ -208,12 +227,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
}
/* Mark the queues used by the vif */
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
__set_bit(vif->hw_queue[ac], data->used_hw_queues);
if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
__set_bit(vif->cab_queue, data->used_hw_queues);
data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif);
/* Mark MAC IDs as used by clearing the available bit, and
* (below) mark TSFs as used if their existing use is not
......@@ -227,24 +241,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
}
/*
* Get the mask of the queus used by the vif
*/
u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
u32 qmask = 0, ac;
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
qmask |= BIT(vif->hw_queue[ac]);
return qmask;
}
void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
......@@ -279,15 +275,15 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
.available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
/* no preference yet */
.preferred_tsf = NUM_TSF_IDS,
.used_hw_queues = {
.used_hw_queues =
BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
BIT(mvm->aux_queue) |
BIT(IWL_MVM_CMD_QUEUE)
},
BIT(IWL_MVM_CMD_QUEUE),
.found_vif = false,
};
u32 ac;
int ret, i;
unsigned long used_hw_queues;
/*
* Allocate a MAC ID and a TSF for this MAC, along with the queues
......@@ -370,9 +366,11 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
return 0;
}
used_hw_queues = data.used_hw_queues;
/* 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,
u8 queue = find_first_zero_bit(&used_hw_queues,
mvm->first_agg_queue);
if (queue >= mvm->first_agg_queue) {
......@@ -381,13 +379,13 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
goto exit_fail;
}
__set_bit(queue, data.used_hw_queues);
__set_bit(queue, &used_hw_queues);
vif->hw_queue[ac] = queue;
}
/* 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,
u8 queue = find_first_zero_bit(&used_hw_queues,
mvm->first_agg_queue);
if (queue >= mvm->first_agg_queue) {
......
......@@ -972,6 +972,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_ADHOC) {
u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
/*
* The firmware defines the TFD queue mask to only be relevant
* for *unicast* queues, so the multicast (CAB) queue should
* be excluded.
*/
if (vif->type == NL80211_IFTYPE_AP)
qmask &= ~BIT(vif->cab_queue);
ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
qmask,
ieee80211_vif_type_p2p(vif));
......@@ -1063,14 +1072,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
u32 tfd_msk = 0, ac;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
tfd_msk |= BIT(vif->hw_queue[ac]);
if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
tfd_msk |= BIT(vif->cab_queue);
u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif);
if (tfd_msk) {
mutex_lock(&mvm->mutex);
......
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