aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlexander Bondar <alexander.bondar@intel.com>2014-03-12 14:30:51 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-03-18 15:15:39 -0400
commit50df8a3065404b9b953b1ae1455dd991e04a9ab7 (patch)
treefbb0d793eed0a5474608d24f3c653e6e5f07b4e3 /drivers/net
parent8a110d9be1c14a95f502343b8b4783eb3228e1e3 (diff)
iwlwifi: mvm: configure low latency dependent scan parameters
In case of system low latency configure passive scan to be fragmented. Set the following scan parameters for both immediate and scheduled scan: - passive scan fragment duration = 20ms - out-of-channel time = 70ms - suspend time = 105ms Restructure channel's active/passive dwell time configuration to better suit the above change. The idea is that under low latency traffic passive scan is fragmented, i.e. that dwell on a particular channel will be fragmented. Each fragment dwell time is 20ms and fragments period is 105ms. Skipping to next channel will be delayed by the same period (105ms). So suspend_time parameter describing both fragments and channels skipping periods is set to 105ms. This value is chosen so that overall passive scan duration will not be too long. Max_out_time in this case is set to 70ms, so for active scanning operating channel will be left for 70ms while for passive still for 20ms (fragment dwell). Signed-off-by: Alexander Bondar <alexander.bondar@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c108
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c19
3 files changed, 101 insertions, 28 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index d58118241d61..abfa5676762b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -984,6 +984,8 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
984/* Low latency */ 984/* Low latency */
985int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 985int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
986 bool value); 986 bool value);
987/* get SystemLowLatencyMode - only needed for beacon threshold? */
988bool iwl_mvm_low_latency(struct iwl_mvm *mvm);
987/* get VMACLowLatencyMode */ 989/* get VMACLowLatencyMode */
988static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif) 990static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
989{ 991{
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index ee3f67f5e42b..c91dc8498852 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -74,6 +74,11 @@
74struct iwl_mvm_scan_params { 74struct iwl_mvm_scan_params {
75 u32 max_out_time; 75 u32 max_out_time;
76 u32 suspend_time; 76 u32 suspend_time;
77 bool passive_fragmented;
78 struct _dwell {
79 u16 passive;
80 u16 active;
81 } dwell[IEEE80211_NUM_BANDS];
77}; 82};
78 83
79static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 84static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
@@ -165,15 +170,14 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
165 170
166static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, 171static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
167 struct cfg80211_scan_request *req, 172 struct cfg80211_scan_request *req,
168 bool basic_ssid) 173 bool basic_ssid,
174 struct iwl_mvm_scan_params *params)
169{ 175{
170 u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band);
171 u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band,
172 req->n_ssids);
173 struct iwl_scan_channel *chan = (struct iwl_scan_channel *) 176 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
174 (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); 177 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
175 int i; 178 int i;
176 int type = BIT(req->n_ssids) - 1; 179 int type = BIT(req->n_ssids) - 1;
180 enum ieee80211_band band = req->channels[0]->band;
177 181
178 if (!basic_ssid) 182 if (!basic_ssid)
179 type |= BIT(req->n_ssids); 183 type |= BIT(req->n_ssids);
@@ -183,8 +187,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
183 chan->type = cpu_to_le32(type); 187 chan->type = cpu_to_le32(type);
184 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) 188 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
185 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 189 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
186 chan->active_dwell = cpu_to_le16(active_dwell); 190 chan->active_dwell = cpu_to_le16(params->dwell[band].active);
187 chan->passive_dwell = cpu_to_le16(passive_dwell); 191 chan->passive_dwell = cpu_to_le16(params->dwell[band].passive);
188 chan->iteration_count = cpu_to_le16(1); 192 chan->iteration_count = cpu_to_le16(1);
189 chan++; 193 chan++;
190 } 194 }
@@ -262,19 +266,65 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
262} 266}
263 267
264static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, 268static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
269 struct ieee80211_vif *vif,
270 int n_ssids,
265 struct iwl_mvm_scan_params *params) 271 struct iwl_mvm_scan_params *params)
266{ 272{
267 bool global_bound = false; 273 bool global_bound = false;
274 enum ieee80211_band band;
268 275
269 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 276 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
270 IEEE80211_IFACE_ITER_NORMAL, 277 IEEE80211_IFACE_ITER_NORMAL,
271 iwl_mvm_scan_condition_iterator, 278 iwl_mvm_scan_condition_iterator,
272 &global_bound); 279 &global_bound);
273 if (!global_bound) 280 /*
274 return; 281 * Under low latency traffic passive scan is fragmented meaning
282 * that dwell on a particular channel will be fragmented. Each fragment
283 * dwell time is 20ms and fragments period is 105ms. Skipping to next
284 * channel will be delayed by the same period - 105ms. So suspend_time
285 * parameter describing both fragments and channels skipping periods is
286 * set to 105ms. This value is chosen so that overall passive scan
287 * duration will not be too long. Max_out_time in this case is set to
288 * 70ms, so for active scanning operating channel will be left for 70ms
289 * while for passive still for 20ms (fragment dwell).
290 */
291 if (global_bound) {
292 if (!iwl_mvm_low_latency(mvm)) {
293 params->suspend_time = ieee80211_tu_to_usec(100);
294 params->max_out_time = ieee80211_tu_to_usec(600);
295 } else {
296 params->suspend_time = ieee80211_tu_to_usec(105);
297 /* P2P doesn't support fragmented passive scan, so
298 * configure max_out_time to be at least longest dwell
299 * time for passive scan.
300 */
301 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
302 params->max_out_time = ieee80211_tu_to_usec(70);
303 params->passive_fragmented = true;
304 } else {
305 u32 passive_dwell;
306
307 /*
308 * Use band G so that passive channel dwell time
309 * will be assigned with maximum value.
310 */
311 band = IEEE80211_BAND_2GHZ;
312 passive_dwell = iwl_mvm_get_passive_dwell(band);
313 params->max_out_time =
314 ieee80211_tu_to_usec(passive_dwell);
315 }
316 }
317 }
275 318
276 params->suspend_time = ieee80211_tu_to_usec(100); 319 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
277 params->max_out_time = ieee80211_tu_to_usec(600); 320 if (params->passive_fragmented)
321 params->dwell[band].passive = 20;
322 else
323 params->dwell[band].passive =
324 iwl_mvm_get_passive_dwell(band);
325 params->dwell[band].active = iwl_mvm_get_active_dwell(band,
326 n_ssids);
327 }
278} 328}
279 329
280int iwl_mvm_scan_request(struct iwl_mvm *mvm, 330int iwl_mvm_scan_request(struct iwl_mvm *mvm,
@@ -311,9 +361,11 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
311 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 361 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
312 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 362 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
313 363
314 iwl_mvm_scan_calc_params(mvm, &params); 364 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params);
315 cmd->max_out_time = cpu_to_le32(params.max_out_time); 365 cmd->max_out_time = cpu_to_le32(params.max_out_time);
316 cmd->suspend_time = cpu_to_le32(params.suspend_time); 366 cmd->suspend_time = cpu_to_le32(params.suspend_time);
367 if (params.passive_fragmented)
368 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
317 369
318 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 370 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
319 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 371 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
@@ -360,7 +412,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
360 req->ie, req->ie_len, 412 req->ie, req->ie_len,
361 mvm->fw->ucode_capa.max_probe_length)); 413 mvm->fw->ucode_capa.max_probe_length));
362 414
363 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid); 415 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
364 416
365 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + 417 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
366 le16_to_cpu(cmd->tx_cmd.len) + 418 le16_to_cpu(cmd->tx_cmd.len) +
@@ -554,10 +606,9 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
554static void iwl_build_scan_cmd(struct iwl_mvm *mvm, 606static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
555 struct ieee80211_vif *vif, 607 struct ieee80211_vif *vif,
556 struct cfg80211_sched_scan_request *req, 608 struct cfg80211_sched_scan_request *req,
557 struct iwl_scan_offload_cmd *scan) 609 struct iwl_scan_offload_cmd *scan,
610 struct iwl_mvm_scan_params *params)
558{ 611{
559 struct iwl_mvm_scan_params params = {};
560
561 scan->channel_count = 612 scan->channel_count =
562 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 613 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
563 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 614 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -566,14 +617,16 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
566 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 617 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
567 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); 618 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
568 619
569 iwl_mvm_scan_calc_params(mvm, &params); 620 scan->max_out_time = cpu_to_le32(params->max_out_time);
570 scan->max_out_time = cpu_to_le32(params.max_out_time); 621 scan->suspend_time = cpu_to_le32(params->suspend_time);
571 scan->suspend_time = cpu_to_le32(params.suspend_time);
572 622
573 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 623 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
574 MAC_FILTER_IN_BEACON); 624 MAC_FILTER_IN_BEACON);
575 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); 625 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
576 scan->rep_count = cpu_to_le32(1); 626 scan->rep_count = cpu_to_le32(1);
627
628 if (params->passive_fragmented)
629 scan->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
577} 630}
578 631
579static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) 632static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
@@ -638,12 +691,11 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
638 struct iwl_scan_channel_cfg *channels, 691 struct iwl_scan_channel_cfg *channels,
639 enum ieee80211_band band, 692 enum ieee80211_band band,
640 int *head, int *tail, 693 int *head, int *tail,
641 u32 ssid_bitmap) 694 u32 ssid_bitmap,
695 struct iwl_mvm_scan_params *params)
642{ 696{
643 struct ieee80211_supported_band *s_band; 697 struct ieee80211_supported_band *s_band;
644 int n_probes = req->n_ssids;
645 int n_channels = req->n_channels; 698 int n_channels = req->n_channels;
646 u8 active_dwell, passive_dwell;
647 int i, j, index = 0; 699 int i, j, index = 0;
648 bool partial; 700 bool partial;
649 701
@@ -653,8 +705,6 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
653 * to scan. So add requested channels to head of the list and others to 705 * to scan. So add requested channels to head of the list and others to
654 * the end. 706 * the end.
655 */ 707 */
656 active_dwell = iwl_mvm_get_active_dwell(band, n_probes);
657 passive_dwell = iwl_mvm_get_passive_dwell(band);
658 s_band = &mvm->nvm_data->bands[band]; 708 s_band = &mvm->nvm_data->bands[band];
659 709
660 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) { 710 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) {
@@ -678,8 +728,8 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
678 channels->channel_number[index] = 728 channels->channel_number[index] =
679 cpu_to_le16(ieee80211_frequency_to_channel( 729 cpu_to_le16(ieee80211_frequency_to_channel(
680 s_band->channels[i].center_freq)); 730 s_band->channels[i].center_freq));
681 channels->dwell_time[index][0] = active_dwell; 731 channels->dwell_time[index][0] = params->dwell[band].active;
682 channels->dwell_time[index][1] = passive_dwell; 732 channels->dwell_time[index][1] = params->dwell[band].passive;
683 733
684 channels->iter_count[index] = cpu_to_le16(1); 734 channels->iter_count[index] = cpu_to_le16(1);
685 channels->iter_interval[index] = 0; 735 channels->iter_interval[index] = 0;
@@ -721,6 +771,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
721 .id = SCAN_OFFLOAD_CONFIG_CMD, 771 .id = SCAN_OFFLOAD_CONFIG_CMD,
722 .flags = CMD_SYNC, 772 .flags = CMD_SYNC,
723 }; 773 };
774 struct iwl_mvm_scan_params params = {};
724 775
725 lockdep_assert_held(&mvm->mutex); 776 lockdep_assert_held(&mvm->mutex);
726 777
@@ -731,7 +782,8 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
731 if (!scan_cfg) 782 if (!scan_cfg)
732 return -ENOMEM; 783 return -ENOMEM;
733 784
734 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd); 785 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params);
786 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
735 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len); 787 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
736 788
737 iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap); 789 iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap);
@@ -743,7 +795,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
743 scan_cfg->data); 795 scan_cfg->data);
744 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 796 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
745 IEEE80211_BAND_2GHZ, &head, &tail, 797 IEEE80211_BAND_2GHZ, &head, &tail,
746 ssid_bitmap); 798 ssid_bitmap, &params);
747 } 799 }
748 if (band_5ghz) { 800 if (band_5ghz) {
749 iwl_scan_offload_build_tx_cmd(mvm, vif, ies, 801 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
@@ -753,7 +805,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
753 SCAN_OFFLOAD_PROBE_REQ_SIZE); 805 SCAN_OFFLOAD_PROBE_REQ_SIZE);
754 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 806 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
755 IEEE80211_BAND_5GHZ, &head, &tail, 807 IEEE80211_BAND_5GHZ, &head, &tail,
756 ssid_bitmap); 808 ssid_bitmap, &params);
757 } 809 }
758 810
759 cmd.data[0] = scan_cfg; 811 cmd.data[0] = scan_cfg;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index e9de033d6b9e..c28da90cd347 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -622,3 +622,22 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
622 622
623 return iwl_mvm_power_update_mac(mvm, vif); 623 return iwl_mvm_power_update_mac(mvm, vif);
624} 624}
625
626static void iwl_mvm_ll_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
627{
628 bool *result = _data;
629
630 if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(vif)))
631 *result = true;
632}
633
634bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
635{
636 bool result = false;
637
638 ieee80211_iterate_active_interfaces_atomic(
639 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
640 iwl_mvm_ll_iter, &result);
641
642 return result;
643}