aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2014-09-21 12:07:30 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-24 01:30:21 -0500
commita74346d75de0f69f0843b4bfa8f95eccaf7c0edf (patch)
tree6896591b0e9cff0c80f4f4202d4ffc265a443dcd
parent307e47235a103191e9bf83cdeb8e50c713feae56 (diff)
iwlwifi: mvm: allow private per-STA TFD queues
TDLS stations will have private queues, so consider them as well when allocating a new one. Consolidate the HW-queue iterating code into a single exported function, to be used by the TDLS code in the future. Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c65
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
2 files changed, 57 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index b8ab4a108720..a1dc9b86c2d1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -83,11 +83,15 @@ 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 u32 used_hw_queues;
87 enum iwl_tsf_id preferred_tsf; 86 enum iwl_tsf_id preferred_tsf;
88 bool found_vif; 87 bool found_vif;
89}; 88};
90 89
90struct iwl_mvm_hw_queues_iface_iterator_data {
91 struct ieee80211_vif *exclude_vif;
92 unsigned long used_hw_queues;
93};
94
91static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, 95static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
92 struct ieee80211_vif *vif) 96 struct ieee80211_vif *vif)
93{ 97{
@@ -213,6 +217,54 @@ u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif)
213 return qmask; 217 return qmask;
214} 218}
215 219
220static void iwl_mvm_iface_hw_queues_iter(void *_data, u8 *mac,
221 struct ieee80211_vif *vif)
222{
223 struct iwl_mvm_hw_queues_iface_iterator_data *data = _data;
224
225 /* exclude the given vif */
226 if (vif == data->exclude_vif)
227 return;
228
229 data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif);
230}
231
232static void iwl_mvm_mac_sta_hw_queues_iter(void *_data,
233 struct ieee80211_sta *sta)
234{
235 struct iwl_mvm_hw_queues_iface_iterator_data *data = _data;
236 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
237
238 /* Mark the queues used by the sta */
239 data->used_hw_queues |= mvmsta->tfd_queue_msk;
240}
241
242unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
243 struct ieee80211_vif *exclude_vif)
244{
245 struct iwl_mvm_hw_queues_iface_iterator_data data = {
246 .exclude_vif = exclude_vif,
247 .used_hw_queues =
248 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
249 BIT(mvm->aux_queue) |
250 BIT(IWL_MVM_CMD_QUEUE),
251 };
252
253 lockdep_assert_held(&mvm->mutex);
254
255 /* mark all VIF used hw queues */
256 ieee80211_iterate_active_interfaces_atomic(
257 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
258 iwl_mvm_iface_hw_queues_iter, &data);
259
260 /* don't assign the same hw queues as TDLS stations */
261 ieee80211_iterate_stations_atomic(mvm->hw,
262 iwl_mvm_mac_sta_hw_queues_iter,
263 &data);
264
265 return data.used_hw_queues;
266}
267
216static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, 268static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
217 struct ieee80211_vif *vif) 269 struct ieee80211_vif *vif)
218{ 270{
@@ -225,9 +277,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
225 return; 277 return;
226 } 278 }
227 279
228 /* Mark the queues used by the vif */
229 data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif);
230
231 /* Mark MAC IDs as used by clearing the available bit, and 280 /* Mark MAC IDs as used by clearing the available bit, and
232 * (below) mark TSFs as used if their existing use is not 281 * (below) mark TSFs as used if their existing use is not
233 * compatible with the new interface type. 282 * compatible with the new interface type.
@@ -274,10 +323,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
274 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, 323 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
275 /* no preference yet */ 324 /* no preference yet */
276 .preferred_tsf = NUM_TSF_IDS, 325 .preferred_tsf = NUM_TSF_IDS,
277 .used_hw_queues =
278 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
279 BIT(mvm->aux_queue) |
280 BIT(IWL_MVM_CMD_QUEUE),
281 .found_vif = false, 326 .found_vif = false,
282 }; 327 };
283 u32 ac; 328 u32 ac;
@@ -316,6 +361,8 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
316 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 361 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
317 iwl_mvm_mac_iface_iterator, &data); 362 iwl_mvm_mac_iface_iterator, &data);
318 363
364 used_hw_queues = iwl_mvm_get_used_hw_queues(mvm, vif);
365
319 /* 366 /*
320 * In the case we're getting here during resume, it's similar to 367 * In the case we're getting here during resume, it's similar to
321 * firmware restart, and with RESUME_ALL the iterator will find 368 * firmware restart, and with RESUME_ALL the iterator will find
@@ -365,8 +412,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
365 return 0; 412 return 0;
366 } 413 }
367 414
368 used_hw_queues = data.used_hw_queues;
369
370 /* Find available queues, and allocate them to the ACs */ 415 /* Find available queues, and allocate them to the ACs */
371 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 416 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
372 u8 queue = find_first_zero_bit(&used_hw_queues, 417 u8 queue = find_first_zero_bit(&used_hw_queues,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index be0285d34fd4..363be83e283e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -937,6 +937,8 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
937 struct iwl_device_cmd *cmd); 937 struct iwl_device_cmd *cmd);
938void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, 938void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
939 struct ieee80211_vif *vif); 939 struct ieee80211_vif *vif);
940unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
941 struct ieee80211_vif *exclude_vif);
940 942
941/* Bindings */ 943/* Bindings */
942int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 944int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);