diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-06-25 15:29:03 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-06-25 15:29:03 -0400 |
commit | 5f4ef7197db98a40e43904806612a8ccf609c0a3 (patch) | |
tree | f637867461ac228db910989299c11509ed0ea129 /drivers/net/wireless/iwlwifi/mvm/scan.c | |
parent | 855df36de365fb3b49eb06c352015e3d215b43fe (diff) | |
parent | c47af22ad630e03053f3eeefd19bd8274989ffbb (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.c | 115 |
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 | ||
276 | static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | 276 | static 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 | |||
300 | not_bound: | 303 | not_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, ¶ms); | 346 | iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, ¶ms); |
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 | ||
677 | static void iwl_build_channel_cfg(struct iwl_mvm *mvm, | 676 | static 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, ¶ms); | 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, ¶ms); | ||
773 | iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, ¶ms); | 758 | iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, ¶ms); |
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, ¶ms); | 770 | ssid_bitmap, ¶ms); |
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, ¶ms); | 780 | ssid_bitmap, ¶ms); |
796 | } | 781 | } |
797 | 782 | ||