aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/scan.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-06-25 15:29:03 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-06-25 15:29:03 -0400
commit5f4ef7197db98a40e43904806612a8ccf609c0a3 (patch)
treef637867461ac228db910989299c11509ed0ea129 /drivers/net/wireless/iwlwifi/mvm/scan.c
parent855df36de365fb3b49eb06c352015e3d215b43fe (diff)
parentc47af22ad630e03053f3eeefd19bd8274989ffbb (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c115
1 files changed, 50 insertions, 65 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 3206fa097255..f2dde5604a80 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -275,7 +275,7 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
275 275
276static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, 276static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
277 struct ieee80211_vif *vif, 277 struct ieee80211_vif *vif,
278 int n_ssids, 278 int n_ssids, u32 flags,
279 struct iwl_mvm_scan_params *params) 279 struct iwl_mvm_scan_params *params)
280{ 280{
281 bool global_bound = false; 281 bool global_bound = false;
@@ -297,6 +297,9 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
297 params->max_out_time = 250; 297 params->max_out_time = 250;
298 } 298 }
299 299
300 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
301 params->max_out_time = 200;
302
300not_bound: 303not_bound:
301 304
302 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 305 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
@@ -333,16 +336,14 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
333 336
334 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n"); 337 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
335 mvm->scan_status = IWL_MVM_SCAN_OS; 338 mvm->scan_status = IWL_MVM_SCAN_OS;
336 memset(cmd, 0, sizeof(struct iwl_scan_cmd) + 339 memset(cmd, 0, ksize(cmd));
337 mvm->fw->ucode_capa.max_probe_length +
338 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
339 340
340 cmd->channel_count = (u8)req->n_channels; 341 cmd->channel_count = (u8)req->n_channels;
341 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 342 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
342 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 343 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
343 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 344 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
344 345
345 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params); 346 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, &params);
346 cmd->max_out_time = cpu_to_le32(params.max_out_time); 347 cmd->max_out_time = cpu_to_le32(params.max_out_time);
347 cmd->suspend_time = cpu_to_le32(params.suspend_time); 348 cmd->suspend_time = cpu_to_le32(params.suspend_time);
348 if (params.passive_fragmented) 349 if (params.passive_fragmented)
@@ -597,9 +598,7 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
597 struct iwl_scan_offload_cmd *scan, 598 struct iwl_scan_offload_cmd *scan,
598 struct iwl_mvm_scan_params *params) 599 struct iwl_mvm_scan_params *params)
599{ 600{
600 scan->channel_count = 601 scan->channel_count = req->n_channels;
601 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
602 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
603 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 602 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
604 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 603 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
605 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 604 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
@@ -676,68 +675,50 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
676 675
677static void iwl_build_channel_cfg(struct iwl_mvm *mvm, 676static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
678 struct cfg80211_sched_scan_request *req, 677 struct cfg80211_sched_scan_request *req,
679 struct iwl_scan_channel_cfg *channels, 678 u8 *channels_buffer,
680 enum ieee80211_band band, 679 enum ieee80211_band band,
681 int *head, int *tail, 680 int *head,
682 u32 ssid_bitmap, 681 u32 ssid_bitmap,
683 struct iwl_mvm_scan_params *params) 682 struct iwl_mvm_scan_params *params)
684{ 683{
685 struct ieee80211_supported_band *s_band; 684 u32 n_channels = mvm->fw->ucode_capa.n_scan_channels;
686 int n_channels = req->n_channels; 685 __le32 *type = (__le32 *)channels_buffer;
687 int i, j, index = 0; 686 __le16 *channel_number = (__le16 *)(type + n_channels);
688 bool partial; 687 __le16 *iter_count = channel_number + n_channels;
688 __le32 *iter_interval = (__le32 *)(iter_count + n_channels);
689 u8 *active_dwell = (u8 *)(iter_interval + n_channels);
690 u8 *passive_dwell = active_dwell + n_channels;
691 int i, index = 0;
692
693 for (i = 0; i < req->n_channels; i++) {
694 struct ieee80211_channel *chan = req->channels[i];
695
696 if (chan->band != band)
697 continue;
689 698
690 /* 699 index = *head;
691 * We have to configure all supported channels, even if we don't want to 700 (*head)++;
692 * scan on them, but we have to send channels in the order that we want 701
693 * to scan. So add requested channels to head of the list and others to 702 channel_number[index] = cpu_to_le16(chan->hw_value);
694 * the end. 703 active_dwell[index] = params->dwell[band].active;
695 */ 704 passive_dwell[index] = params->dwell[band].passive;
696 s_band = &mvm->nvm_data->bands[band];
697
698 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) {
699 partial = false;
700 for (j = 0; j < n_channels; j++)
701 if (s_band->channels[i].center_freq ==
702 req->channels[j]->center_freq) {
703 index = *head;
704 (*head)++;
705 /*
706 * Channels that came with the request will be
707 * in partial scan .
708 */
709 partial = true;
710 break;
711 }
712 if (!partial) {
713 index = *tail;
714 (*tail)--;
715 }
716 channels->channel_number[index] =
717 cpu_to_le16(ieee80211_frequency_to_channel(
718 s_band->channels[i].center_freq));
719 channels->dwell_time[index][0] = params->dwell[band].active;
720 channels->dwell_time[index][1] = params->dwell[band].passive;
721 705
722 channels->iter_count[index] = cpu_to_le16(1); 706 iter_count[index] = cpu_to_le16(1);
723 channels->iter_interval[index] = 0; 707 iter_interval[index] = 0;
724 708
725 if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR)) 709 if (!(chan->flags & IEEE80211_CHAN_NO_IR))
726 channels->type[index] |= 710 type[index] |=
727 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); 711 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
728 712
729 channels->type[index] |= 713 type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL |
730 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL); 714 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
731 if (partial)
732 channels->type[index] |=
733 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
734 715
735 if (s_band->channels[i].flags & IEEE80211_CHAN_NO_HT40) 716 if (chan->flags & IEEE80211_CHAN_NO_HT40)
736 channels->type[index] |= 717 type[index] |=
737 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW); 718 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
738 719
739 /* scan for all SSIDs from req->ssids */ 720 /* scan for all SSIDs from req->ssids */
740 channels->type[index] |= cpu_to_le32(ssid_bitmap); 721 type[index] |= cpu_to_le32(ssid_bitmap);
741 } 722 }
742} 723}
743 724
@@ -749,10 +730,10 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
749 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; 730 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
750 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 731 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
751 int head = 0; 732 int head = 0;
752 int tail = band_2ghz + band_5ghz - 1;
753 u32 ssid_bitmap; 733 u32 ssid_bitmap;
754 int cmd_len; 734 int cmd_len;
755 int ret; 735 int ret;
736 u8 *probes;
756 737
757 struct iwl_scan_offload_cfg *scan_cfg; 738 struct iwl_scan_offload_cfg *scan_cfg;
758 struct iwl_host_cmd cmd = { 739 struct iwl_host_cmd cmd = {
@@ -763,13 +744,17 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
763 lockdep_assert_held(&mvm->mutex); 744 lockdep_assert_held(&mvm->mutex);
764 745
765 cmd_len = sizeof(struct iwl_scan_offload_cfg) + 746 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
747 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE +
766 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE; 748 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
767 749
768 scan_cfg = kzalloc(cmd_len, GFP_KERNEL); 750 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
769 if (!scan_cfg) 751 if (!scan_cfg)
770 return -ENOMEM; 752 return -ENOMEM;
771 753
772 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params); 754 probes = scan_cfg->data +
755 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE;
756
757 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
773 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params); 758 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
774 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len); 759 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
775 760
@@ -779,19 +764,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
779 iwl_scan_offload_build_tx_cmd(mvm, vif, ies, 764 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
780 IEEE80211_BAND_2GHZ, 765 IEEE80211_BAND_2GHZ,
781 &scan_cfg->scan_cmd.tx_cmd[0], 766 &scan_cfg->scan_cmd.tx_cmd[0],
782 scan_cfg->data); 767 probes);
783 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 768 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
784 IEEE80211_BAND_2GHZ, &head, &tail, 769 IEEE80211_BAND_2GHZ, &head,
785 ssid_bitmap, &params); 770 ssid_bitmap, &params);
786 } 771 }
787 if (band_5ghz) { 772 if (band_5ghz) {
788 iwl_scan_offload_build_tx_cmd(mvm, vif, ies, 773 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
789 IEEE80211_BAND_5GHZ, 774 IEEE80211_BAND_5GHZ,
790 &scan_cfg->scan_cmd.tx_cmd[1], 775 &scan_cfg->scan_cmd.tx_cmd[1],
791 scan_cfg->data + 776 probes +
792 SCAN_OFFLOAD_PROBE_REQ_SIZE); 777 SCAN_OFFLOAD_PROBE_REQ_SIZE);
793 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 778 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
794 IEEE80211_BAND_5GHZ, &head, &tail, 779 IEEE80211_BAND_5GHZ, &head,
795 ssid_bitmap, &params); 780 ssid_bitmap, &params);
796 } 781 }
797 782