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;
};
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) {
}
/* 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
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)
{
.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
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) {
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) {
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));
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);