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.c72
1 files changed, 55 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index e5294d01181e..844bf7c4c8de 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -72,6 +72,8 @@
72 72
73#define IWL_PLCP_QUIET_THRESH 1 73#define IWL_PLCP_QUIET_THRESH 1
74#define IWL_ACTIVE_QUIET_TIME 10 74#define IWL_ACTIVE_QUIET_TIME 10
75#define IWL_DENSE_EBS_SCAN_RATIO 5
76#define IWL_SPARSE_EBS_SCAN_RATIO 1
75 77
76struct iwl_mvm_scan_params { 78struct iwl_mvm_scan_params {
77 u32 max_out_time; 79 u32 max_out_time;
@@ -171,15 +173,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
171 * 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
172 * req->n_ssids - 1 bits in addition to the first bit. 174 * req->n_ssids - 1 bits in addition to the first bit.
173 */ 175 */
174static 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)
175{ 178{
179 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
180 return 10;
176 if (band == IEEE80211_BAND_2GHZ) 181 if (band == IEEE80211_BAND_2GHZ)
177 return 20 + 3 * (n_ssids + 1); 182 return 20 + 3 * (n_ssids + 1);
178 return 10 + 2 * (n_ssids + 1); 183 return 10 + 2 * (n_ssids + 1);
179} 184}
180 185
181static 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)
182{ 188{
189 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
190 return 110;
183 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
184} 192}
185 193
@@ -331,7 +339,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
331 */ 339 */
332 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 340 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
333 u32 passive_dwell = 341 u32 passive_dwell =
334 iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); 342 iwl_mvm_get_passive_dwell(mvm,
343 IEEE80211_BAND_2GHZ);
335 params->max_out_time = passive_dwell; 344 params->max_out_time = passive_dwell;
336 } else { 345 } else {
337 params->passive_fragmented = true; 346 params->passive_fragmented = true;
@@ -348,8 +357,8 @@ not_bound:
348 params->dwell[band].passive = frag_passive_dwell; 357 params->dwell[band].passive = frag_passive_dwell;
349 else 358 else
350 params->dwell[band].passive = 359 params->dwell[band].passive =
351 iwl_mvm_get_passive_dwell(band); 360 iwl_mvm_get_passive_dwell(mvm, band);
352 params->dwell[band].active = iwl_mvm_get_active_dwell(band, 361 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,
353 n_ssids); 362 n_ssids);
354 } 363 }
355} 364}
@@ -1098,6 +1107,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1098 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, 1107 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN,
1099 notify); 1108 notify);
1100 1109
1110 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1111 return 0;
1112
1113 if (iwl_mvm_is_radio_killed(mvm))
1114 goto out;
1115
1101 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 1116 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
1102 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || 1117 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1103 mvm->scan_status != IWL_MVM_SCAN_OS)) { 1118 mvm->scan_status != IWL_MVM_SCAN_OS)) {
@@ -1134,6 +1149,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1134 if (mvm->scan_status == IWL_MVM_SCAN_OS) 1149 if (mvm->scan_status == IWL_MVM_SCAN_OS)
1135 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1150 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1136 1151
1152out:
1137 mvm->scan_status = IWL_MVM_SCAN_NONE; 1153 mvm->scan_status = IWL_MVM_SCAN_NONE;
1138 1154
1139 if (notify) { 1155 if (notify) {
@@ -1290,18 +1306,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1290 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1306 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
1291 cmd->iter_num = cpu_to_le32(1); 1307 cmd->iter_num = cpu_to_le32(1);
1292 1308
1293 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1294 mvm->last_ebs_successful) {
1295 cmd->channel_opt[0].flags =
1296 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1297 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1298 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1299 cmd->channel_opt[1].flags =
1300 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1301 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1302 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1303 }
1304
1305 if (iwl_mvm_rrm_scan_needed(mvm)) 1309 if (iwl_mvm_rrm_scan_needed(mvm))
1306 cmd->scan_flags |= 1310 cmd->scan_flags |=
1307 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); 1311 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED);
@@ -1376,6 +1380,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
1376 cmd->schedule[1].iterations = 0; 1380 cmd->schedule[1].iterations = 0;
1377 cmd->schedule[1].full_scan_mul = 0; 1381 cmd->schedule[1].full_scan_mul = 0;
1378 1382
1383 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
1384 mvm->last_ebs_successful) {
1385 cmd->channel_opt[0].flags =
1386 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1387 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1388 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1389 cmd->channel_opt[0].non_ebs_ratio =
1390 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1391 cmd->channel_opt[1].flags =
1392 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1393 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1394 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1395 cmd->channel_opt[1].non_ebs_ratio =
1396 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1397 }
1398
1379 for (i = 1; i <= req->req.n_ssids; i++) 1399 for (i = 1; i <= req->req.n_ssids; i++)
1380 ssid_bitmap |= BIT(i); 1400 ssid_bitmap |= BIT(i);
1381 1401
@@ -1448,6 +1468,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1448 1468
1449 if (iwl_mvm_scan_pass_all(mvm, req)) 1469 if (iwl_mvm_scan_pass_all(mvm, req))
1450 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; 1470 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
1471 else
1472 flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;
1451 1473
1452 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) 1474 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)
1453 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; 1475 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
@@ -1474,6 +1496,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1474 cmd->schedule[1].iterations = 0xff; 1496 cmd->schedule[1].iterations = 0xff;
1475 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; 1497 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER;
1476 1498
1499 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1500 mvm->last_ebs_successful) {
1501 cmd->channel_opt[0].flags =
1502 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1503 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1504 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1505 cmd->channel_opt[0].non_ebs_ratio =
1506 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1507 cmd->channel_opt[1].flags =
1508 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1509 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1510 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1511 cmd->channel_opt[1].non_ebs_ratio =
1512 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1513 }
1514
1477 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, 1515 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels,
1478 ssid_bitmap, cmd); 1516 ssid_bitmap, cmd);
1479 1517