aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-08-01 17:14:24 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-09-03 15:49:12 -0400
commit110cf810852f0f5333bcfb10065995006d8ecbbb (patch)
treec0a953c1977208d11e3e879be54f603900ce19a6
parent9e848010bfa1c0da21292afb7a98957b5c35622d (diff)
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: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c62
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c18
3 files changed, 40 insertions, 43 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 94342dbe69e9..9c975f9ecfcb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -75,9 +75,6 @@
75#include "fw-api-coex.h" 75#include "fw-api-coex.h"
76#include "fw-api-scan.h" 76#include "fw-api-scan.h"
77 77
78/* maximal number of Tx queues in any platform */
79#define IWL_MVM_MAX_QUEUES 20
80
81/* Tx queue numbers */ 78/* Tx queue numbers */
82enum { 79enum {
83 IWL_MVM_OFFCHANNEL_QUEUE = 8, 80 IWL_MVM_OFFCHANNEL_QUEUE = 8,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 115bb3656d91..9cbb192f680e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -83,7 +83,7 @@ struct iwl_mvm_mac_iface_iterator_data {
83 struct ieee80211_vif *vif; 83 struct ieee80211_vif *vif;
84 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; 84 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
85 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; 85 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
86 unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)]; 86 u32 used_hw_queues;
87 enum iwl_tsf_id preferred_tsf; 87 enum iwl_tsf_id preferred_tsf;
88 bool found_vif; 88 bool found_vif;
89}; 89};
@@ -194,12 +194,31 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
194 data->preferred_tsf = NUM_TSF_IDS; 194 data->preferred_tsf = NUM_TSF_IDS;
195} 195}
196 196
197/*
198 * Get the mask of the queues used by the vif
199 */
200u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
201 struct ieee80211_vif *vif)
202{
203 u32 qmask = 0, ac;
204
205 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
206 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
207
208 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
209 qmask |= BIT(vif->hw_queue[ac]);
210
211 if (vif->type == NL80211_IFTYPE_AP)
212 qmask |= BIT(vif->cab_queue);
213
214 return qmask;
215}
216
197static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, 217static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
198 struct ieee80211_vif *vif) 218 struct ieee80211_vif *vif)
199{ 219{
200 struct iwl_mvm_mac_iface_iterator_data *data = _data; 220 struct iwl_mvm_mac_iface_iterator_data *data = _data;
201 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 221 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
202 u32 ac;
203 222
204 /* Iterator may already find the interface being added -- skip it */ 223 /* Iterator may already find the interface being added -- skip it */
205 if (vif == data->vif) { 224 if (vif == data->vif) {
@@ -208,12 +227,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
208 } 227 }
209 228
210 /* Mark the queues used by the vif */ 229 /* Mark the queues used by the vif */
211 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 230 data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif);
212 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
213 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
214
215 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
216 __set_bit(vif->cab_queue, data->used_hw_queues);
217 231
218 /* Mark MAC IDs as used by clearing the available bit, and 232 /* Mark MAC IDs as used by clearing the available bit, and
219 * (below) mark TSFs as used if their existing use is not 233 * (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,
227 iwl_mvm_mac_tsf_id_iter(_data, mac, vif); 241 iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
228} 242}
229 243
230/*
231 * Get the mask of the queus used by the vif
232 */
233u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
234 struct ieee80211_vif *vif)
235{
236 u32 qmask = 0, ac;
237
238 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
239 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
240
241 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
242 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
243 qmask |= BIT(vif->hw_queue[ac]);
244
245 return qmask;
246}
247
248void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, 244void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
249 struct ieee80211_vif *vif) 245 struct ieee80211_vif *vif)
250{ 246{
@@ -279,15 +275,15 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
279 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, 275 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
280 /* no preference yet */ 276 /* no preference yet */
281 .preferred_tsf = NUM_TSF_IDS, 277 .preferred_tsf = NUM_TSF_IDS,
282 .used_hw_queues = { 278 .used_hw_queues =
283 BIT(IWL_MVM_OFFCHANNEL_QUEUE) | 279 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
284 BIT(mvm->aux_queue) | 280 BIT(mvm->aux_queue) |
285 BIT(IWL_MVM_CMD_QUEUE) 281 BIT(IWL_MVM_CMD_QUEUE),
286 },
287 .found_vif = false, 282 .found_vif = false,
288 }; 283 };
289 u32 ac; 284 u32 ac;
290 int ret, i; 285 int ret, i;
286 unsigned long used_hw_queues;
291 287
292 /* 288 /*
293 * Allocate a MAC ID and a TSF for this MAC, along with the queues 289 * 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,
370 return 0; 366 return 0;
371 } 367 }
372 368
369 used_hw_queues = data.used_hw_queues;
370
373 /* Find available queues, and allocate them to the ACs */ 371 /* Find available queues, and allocate them to the ACs */
374 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 372 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
375 u8 queue = find_first_zero_bit(data.used_hw_queues, 373 u8 queue = find_first_zero_bit(&used_hw_queues,
376 mvm->first_agg_queue); 374 mvm->first_agg_queue);
377 375
378 if (queue >= mvm->first_agg_queue) { 376 if (queue >= mvm->first_agg_queue) {
@@ -381,13 +379,13 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
381 goto exit_fail; 379 goto exit_fail;
382 } 380 }
383 381
384 __set_bit(queue, data.used_hw_queues); 382 __set_bit(queue, &used_hw_queues);
385 vif->hw_queue[ac] = queue; 383 vif->hw_queue[ac] = queue;
386 } 384 }
387 385
388 /* Allocate the CAB queue for softAP and GO interfaces */ 386 /* Allocate the CAB queue for softAP and GO interfaces */
389 if (vif->type == NL80211_IFTYPE_AP) { 387 if (vif->type == NL80211_IFTYPE_AP) {
390 u8 queue = find_first_zero_bit(data.used_hw_queues, 388 u8 queue = find_first_zero_bit(&used_hw_queues,
391 mvm->first_agg_queue); 389 mvm->first_agg_queue);
392 390
393 if (queue >= mvm->first_agg_queue) { 391 if (queue >= mvm->first_agg_queue) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index ea79f1ac3ecc..ac2b11a52b9f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -972,6 +972,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
972 if (vif->type == NL80211_IFTYPE_AP || 972 if (vif->type == NL80211_IFTYPE_AP ||
973 vif->type == NL80211_IFTYPE_ADHOC) { 973 vif->type == NL80211_IFTYPE_ADHOC) {
974 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); 974 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
975
976 /*
977 * The firmware defines the TFD queue mask to only be relevant
978 * for *unicast* queues, so the multicast (CAB) queue should
979 * be excluded.
980 */
981 if (vif->type == NL80211_IFTYPE_AP)
982 qmask &= ~BIT(vif->cab_queue);
983
975 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, 984 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
976 qmask, 985 qmask,
977 ieee80211_vif_type_p2p(vif)); 986 ieee80211_vif_type_p2p(vif));
@@ -1063,14 +1072,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1063static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, 1072static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
1064 struct ieee80211_vif *vif) 1073 struct ieee80211_vif *vif)
1065{ 1074{
1066 u32 tfd_msk = 0, ac; 1075 u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif);
1067
1068 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
1069 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
1070 tfd_msk |= BIT(vif->hw_queue[ac]);
1071
1072 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
1073 tfd_msk |= BIT(vif->cab_queue);
1074 1076
1075 if (tfd_msk) { 1077 if (tfd_msk) {
1076 mutex_lock(&mvm->mutex); 1078 mutex_lock(&mvm->mutex);