diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/scan.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/scan.c | 72 |
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 | ||
76 | struct iwl_mvm_scan_params { | 78 | struct 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 | */ |
174 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) | 176 | static 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 | ||
181 | static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) | 186 | static 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 | ||
1152 | out: | ||
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 | ||