aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c120
1 files changed, 92 insertions, 28 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 348b9c4b694a..7e9aa3cb3254 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -173,15 +173,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
173 * already included in the probe template, so we need to set only 173 * already included in the probe template, so we need to set only
174 * req->n_ssids - 1 bits in addition to the first bit. 174 * req->n_ssids - 1 bits in addition to the first bit.
175 */ 175 */
176static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 176static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm,
177 enum ieee80211_band band, int n_ssids)
177{ 178{
179 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
180 return 10;
178 if (band == IEEE80211_BAND_2GHZ) 181 if (band == IEEE80211_BAND_2GHZ)
179 return 20 + 3 * (n_ssids + 1); 182 return 20 + 3 * (n_ssids + 1);
180 return 10 + 2 * (n_ssids + 1); 183 return 10 + 2 * (n_ssids + 1);
181} 184}
182 185
183static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) 186static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm,
187 enum ieee80211_band band)
184{ 188{
189 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
190 return 110;
185 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
186} 192}
187 193
@@ -309,18 +315,18 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
309 goto not_bound; 315 goto not_bound;
310 316
311 params->suspend_time = 30; 317 params->suspend_time = 30;
312 params->max_out_time = 170; 318 params->max_out_time = 120;
313 319
314 if (iwl_mvm_low_latency(mvm)) { 320 if (iwl_mvm_low_latency(mvm)) {
315 if (mvm->fw->ucode_capa.api[0] & 321 if (mvm->fw->ucode_capa.api[0] &
316 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { 322 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
317 params->suspend_time = 105; 323 params->suspend_time = 105;
318 params->max_out_time = 70;
319 /* 324 /*
320 * If there is more than one active interface make 325 * If there is more than one active interface make
321 * passive scan more fragmented. 326 * passive scan more fragmented.
322 */ 327 */
323 frag_passive_dwell = (global_cnt < 2) ? 40 : 20; 328 frag_passive_dwell = (global_cnt < 2) ? 40 : 20;
329 params->max_out_time = frag_passive_dwell;
324 } else { 330 } else {
325 params->suspend_time = 120; 331 params->suspend_time = 120;
326 params->max_out_time = 120; 332 params->max_out_time = 120;
@@ -337,7 +343,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
337 */ 343 */
338 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 344 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
339 u32 passive_dwell = 345 u32 passive_dwell =
340 iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); 346 iwl_mvm_get_passive_dwell(mvm,
347 IEEE80211_BAND_2GHZ);
341 params->max_out_time = passive_dwell; 348 params->max_out_time = passive_dwell;
342 } else { 349 } else {
343 params->passive_fragmented = true; 350 params->passive_fragmented = true;
@@ -354,8 +361,8 @@ not_bound:
354 params->dwell[band].passive = frag_passive_dwell; 361 params->dwell[band].passive = frag_passive_dwell;
355 else 362 else
356 params->dwell[band].passive = 363 params->dwell[band].passive =
357 iwl_mvm_get_passive_dwell(band); 364 iwl_mvm_get_passive_dwell(mvm, band);
358 params->dwell[band].active = iwl_mvm_get_active_dwell(band, 365 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,
359 n_ssids); 366 n_ssids);
360 } 367 }
361} 368}
@@ -536,6 +543,19 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
536 return 0; 543 return 0;
537} 544}
538 545
546int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
547 struct iwl_rx_cmd_buffer *rxb,
548 struct iwl_device_cmd *cmd)
549{
550 struct iwl_rx_packet *pkt = rxb_addr(rxb);
551 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
552
553 IWL_DEBUG_SCAN(mvm,
554 "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
555 notif->status, notif->scanned_channels);
556 return 0;
557}
558
539int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 559int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
540 struct iwl_device_cmd *cmd) 560 struct iwl_device_cmd *cmd)
541{ 561{
@@ -684,7 +704,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
684 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
685 } 705 }
686 706
687 mvm->last_ebs_successful = !ebs_status; 707 if (ebs_status)
708 mvm->last_ebs_successful = false;
688 709
689 return 0; 710 return 0;
690} 711}
@@ -1104,6 +1125,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1104 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, 1125 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN,
1105 notify); 1126 notify);
1106 1127
1128 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1129 return 0;
1130
1131 if (iwl_mvm_is_radio_killed(mvm))
1132 goto out;
1133
1107 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 1134 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
1108 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || 1135 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1109 mvm->scan_status != IWL_MVM_SCAN_OS)) { 1136 mvm->scan_status != IWL_MVM_SCAN_OS)) {
@@ -1140,6 +1167,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1140 if (mvm->scan_status == IWL_MVM_SCAN_OS) 1167 if (mvm->scan_status == IWL_MVM_SCAN_OS)
1141 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1168 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1142 1169
1170out:
1143 mvm->scan_status = IWL_MVM_SCAN_NONE; 1171 mvm->scan_status = IWL_MVM_SCAN_NONE;
1144 1172
1145 if (notify) { 1173 if (notify) {
@@ -1296,22 +1324,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1296 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1324 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
1297 cmd->iter_num = cpu_to_le32(1); 1325 cmd->iter_num = cpu_to_le32(1);
1298 1326
1299 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1300 mvm->last_ebs_successful) {
1301 cmd->channel_opt[0].flags =
1302 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1303 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1304 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1305 cmd->channel_opt[0].non_ebs_ratio =
1306 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1307 cmd->channel_opt[1].flags =
1308 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1309 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1310 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1311 cmd->channel_opt[1].non_ebs_ratio =
1312 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1313 }
1314
1315 if (iwl_mvm_rrm_scan_needed(mvm)) 1327 if (iwl_mvm_rrm_scan_needed(mvm))
1316 cmd->scan_flags |= 1328 cmd->scan_flags |=
1317 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); 1329 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED);
@@ -1386,6 +1398,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
1386 cmd->schedule[1].iterations = 0; 1398 cmd->schedule[1].iterations = 0;
1387 cmd->schedule[1].full_scan_mul = 0; 1399 cmd->schedule[1].full_scan_mul = 0;
1388 1400
1401 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
1402 mvm->last_ebs_successful) {
1403 cmd->channel_opt[0].flags =
1404 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1405 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1406 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1407 cmd->channel_opt[0].non_ebs_ratio =
1408 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1409 cmd->channel_opt[1].flags =
1410 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1411 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1412 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1413 cmd->channel_opt[1].non_ebs_ratio =
1414 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1415 }
1416
1389 for (i = 1; i <= req->req.n_ssids; i++) 1417 for (i = 1; i <= req->req.n_ssids; i++)
1390 ssid_bitmap |= BIT(i); 1418 ssid_bitmap |= BIT(i);
1391 1419
@@ -1458,6 +1486,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1458 1486
1459 if (iwl_mvm_scan_pass_all(mvm, req)) 1487 if (iwl_mvm_scan_pass_all(mvm, req))
1460 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; 1488 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
1489 else
1490 flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;
1461 1491
1462 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) 1492 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)
1463 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; 1493 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
@@ -1468,6 +1498,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1468 if (req->n_ssids == 0) 1498 if (req->n_ssids == 0)
1469 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; 1499 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
1470 1500
1501#ifdef CONFIG_IWLWIFI_DEBUGFS
1502 if (mvm->scan_iter_notif_enabled)
1503 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
1504#endif
1505
1471 cmd->scan_flags |= cpu_to_le32(flags); 1506 cmd->scan_flags |= cpu_to_le32(flags);
1472 1507
1473 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); 1508 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
@@ -1484,6 +1519,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1484 cmd->schedule[1].iterations = 0xff; 1519 cmd->schedule[1].iterations = 0xff;
1485 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; 1520 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER;
1486 1521
1522 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1523 mvm->last_ebs_successful) {
1524 cmd->channel_opt[0].flags =
1525 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1526 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1527 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1528 cmd->channel_opt[0].non_ebs_ratio =
1529 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1530 cmd->channel_opt[1].flags =
1531 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1532 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1533 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1534 cmd->channel_opt[1].non_ebs_ratio =
1535 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1536 }
1537
1487 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, 1538 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels,
1488 ssid_bitmap, cmd); 1539 ssid_bitmap, cmd);
1489 1540
@@ -1632,10 +1683,10 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1632 1683
1633 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 1684 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
1634 for (i = 0; i < band->n_channels; i++, j++) 1685 for (i = 0; i < band->n_channels; i++, j++)
1635 scan_config->channel_array[j] = band->channels[i].center_freq; 1686 scan_config->channel_array[j] = band->channels[i].hw_value;
1636 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 1687 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
1637 for (i = 0; i < band->n_channels; i++, j++) 1688 for (i = 0; i < band->n_channels; i++, j++)
1638 scan_config->channel_array[j] = band->channels[i].center_freq; 1689 scan_config->channel_array[j] = band->channels[i].hw_value;
1639 1690
1640 cmd.data[0] = scan_config; 1691 cmd.data[0] = scan_config;
1641 cmd.len[0] = cmd_size; 1692 cmd.len[0] = cmd_size;
@@ -1812,6 +1863,13 @@ int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1812 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; 1863 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL;
1813 1864
1814 cmd->general_flags = cpu_to_le32(flags); 1865 cmd->general_flags = cpu_to_le32(flags);
1866
1867 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
1868 mvm->last_ebs_successful)
1869 cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS |
1870 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1871 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
1872
1815 cmd->n_channels = req->req.n_channels; 1873 cmd->n_channels = req->req.n_channels;
1816 1874
1817 for (i = 0; i < req->req.n_ssids; i++) 1875 for (i = 0; i < req->req.n_ssids; i++)
@@ -1975,7 +2033,9 @@ int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
1975 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? 2033 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
1976 "success" : "failed"); 2034 "success" : "failed");
1977 2035
1978 mvm->last_ebs_successful = !notif->ebs_status; 2036 if (notif->ebs_status)
2037 mvm->last_ebs_successful = false;
2038
1979 mvm->scan_uid[uid_idx] = 0; 2039 mvm->scan_uid[uid_idx] = 0;
1980 2040
1981 if (!sched) { 2041 if (!sched) {
@@ -2008,10 +2068,14 @@ static bool iwl_scan_umac_done_check(struct iwl_notif_wait_data *notif_wait,
2008 2068
2009 /* 2069 /*
2010 * Clear scan uid of scans that was aborted from above and completed 2070 * Clear scan uid of scans that was aborted from above and completed
2011 * in FW so the RX handler does nothing. 2071 * in FW so the RX handler does nothing. Set last_ebs_successful here if
2072 * needed.
2012 */ 2073 */
2013 scan_done->mvm->scan_uid[uid_idx] = 0; 2074 scan_done->mvm->scan_uid[uid_idx] = 0;
2014 2075
2076 if (notif->ebs_status)
2077 scan_done->mvm->last_ebs_successful = false;
2078
2015 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type); 2079 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type);
2016} 2080}
2017 2081