]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/mvm/scan.c
Merge tag 'iommu-updates-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / mvm / scan.c
index 844bf7c4c8def639dbc65329fe9f4e157715cbdf..7e9aa3cb325401fcf4105e278294b11657a90df1 100644 (file)
@@ -99,7 +99,7 @@ static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
 {
        if (mvm->scan_rx_ant != ANT_NONE)
                return mvm->scan_rx_ant;
-       return mvm->fw->valid_rx_ant;
+       return iwl_mvm_get_valid_rx_ant(mvm);
 }
 
 static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
@@ -130,7 +130,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
        u32 tx_ant;
 
        mvm->scan_last_antenna_idx =
-               iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
+               iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
                                     mvm->scan_last_antenna_idx);
        tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
 
@@ -290,11 +290,11 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
                                            struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       bool *global_bound = data;
+       int *global_cnt = data;
 
        if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
            mvmvif->phy_ctxt->id < MAX_PHYS)
-               *global_bound = true;
+               *global_cnt += 1;
 }
 
 static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
@@ -302,27 +302,31 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
                                     int n_ssids, u32 flags,
                                     struct iwl_mvm_scan_params *params)
 {
-       bool global_bound = false;
+       int global_cnt = 0;
        enum ieee80211_band band;
        u8 frag_passive_dwell = 0;
 
        ieee80211_iterate_active_interfaces_atomic(mvm->hw,
                                            IEEE80211_IFACE_ITER_NORMAL,
                                            iwl_mvm_scan_condition_iterator,
-                                           &global_bound);
+                                           &global_cnt);
 
-       if (!global_bound)
+       if (!global_cnt)
                goto not_bound;
 
        params->suspend_time = 30;
-       params->max_out_time = 170;
+       params->max_out_time = 120;
 
        if (iwl_mvm_low_latency(mvm)) {
                if (mvm->fw->ucode_capa.api[0] &
                    IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
                        params->suspend_time = 105;
-                       params->max_out_time = 70;
-                       frag_passive_dwell = 20;
+                       /*
+                        * If there is more than one active interface make
+                        * passive scan more fragmented.
+                        */
+                       frag_passive_dwell = (global_cnt < 2) ? 40 : 20;
+                       params->max_out_time = frag_passive_dwell;
                } else {
                        params->suspend_time = 120;
                        params->max_out_time = 120;
@@ -539,6 +543,19 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
        return 0;
 }
 
+int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
+                                               struct iwl_rx_cmd_buffer *rxb,
+                                               struct iwl_device_cmd *cmd)
+{
+       struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_scan_complete_notif *notif = (void *)pkt->data;
+
+       IWL_DEBUG_SCAN(mvm,
+                      "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
+                      notif->status, notif->scanned_channels);
+       return 0;
+}
+
 int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
                          struct iwl_device_cmd *cmd)
 {
@@ -687,7 +704,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
                iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
        }
 
-       mvm->last_ebs_successful = !ebs_status;
+       if (ebs_status)
+               mvm->last_ebs_successful = false;
 
        return 0;
 }
@@ -1480,6 +1498,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
        if (req->n_ssids == 0)
                flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       if (mvm->scan_iter_notif_enabled)
+               flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
+#endif
+
        cmd->scan_flags |= cpu_to_le32(flags);
 
        cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
@@ -1641,7 +1664,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
                                         SCAN_CONFIG_FLAG_SET_MAC_ADDR |
                                         SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
                                         SCAN_CONFIG_N_CHANNELS(num_channels));
-       scan_config->tx_chains = cpu_to_le32(mvm->fw->valid_tx_ant);
+       scan_config->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
        scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
        scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm);
        scan_config->out_of_channel_time = cpu_to_le32(170);
@@ -1660,10 +1683,10 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
 
        band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
        for (i = 0; i < band->n_channels; i++, j++)
-               scan_config->channel_array[j] = band->channels[i].center_freq;
+               scan_config->channel_array[j] = band->channels[i].hw_value;
        band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
        for (i = 0; i < band->n_channels; i++, j++)
-               scan_config->channel_array[j] = band->channels[i].center_freq;
+               scan_config->channel_array[j] = band->channels[i].hw_value;
 
        cmd.data[0] = scan_config;
        cmd.len[0] = cmd_size;
@@ -1840,6 +1863,13 @@ int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL;
 
        cmd->general_flags = cpu_to_le32(flags);
+
+       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
+           mvm->last_ebs_successful)
+               cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS |
+                                    IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+                                    IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
+
        cmd->n_channels = req->req.n_channels;
 
        for (i = 0; i < req->req.n_ssids; i++)
@@ -2003,7 +2033,9 @@ int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
                       notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
                                "success" : "failed");
 
-       mvm->last_ebs_successful = !notif->ebs_status;
+       if (notif->ebs_status)
+               mvm->last_ebs_successful = false;
+
        mvm->scan_uid[uid_idx] = 0;
 
        if (!sched) {
@@ -2036,10 +2068,14 @@ static bool iwl_scan_umac_done_check(struct iwl_notif_wait_data *notif_wait,
 
        /*
         * Clear scan uid of scans that was aborted from above and completed
-        * in FW so the RX handler does nothing.
+        * in FW so the RX handler does nothing. Set last_ebs_successful here if
+        * needed.
         */
        scan_done->mvm->scan_uid[uid_idx] = 0;
 
+       if (notif->ebs_status)
+               scan_done->mvm->last_ebs_successful = false;
+
        return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type);
 }