diff options
author | Arik Nemtsov <arik@wizery.com> | 2014-09-21 12:07:30 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-11-24 01:30:21 -0500 |
commit | a74346d75de0f69f0843b4bfa8f95eccaf7c0edf (patch) | |
tree | 6896591b0e9cff0c80f4f4202d4ffc265a443dcd | |
parent | 307e47235a103191e9bf83cdeb8e50c713feae56 (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.c | 65 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 |
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 | ||
90 | struct iwl_mvm_hw_queues_iface_iterator_data { | ||
91 | struct ieee80211_vif *exclude_vif; | ||
92 | unsigned long used_hw_queues; | ||
93 | }; | ||
94 | |||
91 | static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, | 95 | static 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 | ||
220 | static 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 | |||
232 | static 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 | |||
242 | unsigned 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 | |||
216 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | 268 | static 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); |
938 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, | 938 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, |
939 | struct ieee80211_vif *vif); | 939 | struct ieee80211_vif *vif); |
940 | unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, | ||
941 | struct ieee80211_vif *exclude_vif); | ||
940 | 942 | ||
941 | /* Bindings */ | 943 | /* Bindings */ |
942 | int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 944 | int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |