diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/scan.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/scan.c | 79 |
1 files changed, 66 insertions, 13 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 09545f23b24f..cb85e63c20aa 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -339,6 +339,55 @@ not_bound: | |||
339 | } | 339 | } |
340 | } | 340 | } |
341 | 341 | ||
342 | static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm) | ||
343 | { | ||
344 | /* require rrm scan whenever the fw supports it */ | ||
345 | return mvm->fw->ucode_capa.capa[0] & | ||
346 | IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT; | ||
347 | } | ||
348 | |||
349 | static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm, | ||
350 | bool is_sched_scan) | ||
351 | { | ||
352 | int max_probe_len; | ||
353 | |||
354 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) | ||
355 | max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE; | ||
356 | else | ||
357 | max_probe_len = mvm->fw->ucode_capa.max_probe_length; | ||
358 | |||
359 | /* we create the 802.11 header and SSID element */ | ||
360 | max_probe_len -= 24 + 2; | ||
361 | |||
362 | /* basic ssid is added only for hw_scan with and old api */ | ||
363 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) && | ||
364 | !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) && | ||
365 | !is_sched_scan) | ||
366 | max_probe_len -= 32; | ||
367 | |||
368 | return max_probe_len; | ||
369 | } | ||
370 | |||
371 | int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan) | ||
372 | { | ||
373 | int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan); | ||
374 | |||
375 | if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) | ||
376 | return max_ie_len; | ||
377 | |||
378 | /* TODO: [BUG] This function should return the maximum allowed size of | ||
379 | * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs | ||
380 | * in the same command. So the correct implementation of this function | ||
381 | * is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan | ||
382 | * command has only 512 bytes and it would leave us with about 240 | ||
383 | * bytes for scan IEs, which is clearly not enough. So meanwhile | ||
384 | * we will report an incorrect value. This may result in a failure to | ||
385 | * issue a scan in unified_scan_lmac and unified_sched_scan_lmac | ||
386 | * functions with -ENOBUFS, if a large enough probe will be provided. | ||
387 | */ | ||
388 | return max_ie_len; | ||
389 | } | ||
390 | |||
342 | int iwl_mvm_scan_request(struct iwl_mvm *mvm, | 391 | int iwl_mvm_scan_request(struct iwl_mvm *mvm, |
343 | struct ieee80211_vif *vif, | 392 | struct ieee80211_vif *vif, |
344 | struct cfg80211_scan_request *req) | 393 | struct cfg80211_scan_request *req) |
@@ -1153,6 +1202,10 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, | |||
1153 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | 1202 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | |
1154 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | 1203 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); |
1155 | } | 1204 | } |
1205 | |||
1206 | if (iwl_mvm_rrm_scan_needed(mvm)) | ||
1207 | cmd->scan_flags |= | ||
1208 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); | ||
1156 | } | 1209 | } |
1157 | 1210 | ||
1158 | int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, | 1211 | int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, |
@@ -1180,13 +1233,12 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, | |||
1180 | if (WARN_ON(mvm->scan_cmd == NULL)) | 1233 | if (WARN_ON(mvm->scan_cmd == NULL)) |
1181 | return -ENOMEM; | 1234 | return -ENOMEM; |
1182 | 1235 | ||
1183 | if (WARN_ON_ONCE(req->req.n_ssids > PROBE_OPTION_MAX || | 1236 | if (req->req.n_ssids > PROBE_OPTION_MAX || |
1184 | req->ies.common_ie_len + req->ies.len[0] + | 1237 | req->ies.common_ie_len + req->ies.len[NL80211_BAND_2GHZ] + |
1185 | req->ies.len[1] + 24 + 2 > | 1238 | req->ies.len[NL80211_BAND_5GHZ] > |
1186 | SCAN_OFFLOAD_PROBE_REQ_SIZE || | 1239 | iwl_mvm_max_scan_ie_fw_cmd_room(mvm, false) || |
1187 | req->req.n_channels > | 1240 | req->req.n_channels > mvm->fw->ucode_capa.n_scan_channels) |
1188 | mvm->fw->ucode_capa.n_scan_channels)) | 1241 | return -ENOBUFS; |
1189 | return -1; | ||
1190 | 1242 | ||
1191 | mvm->scan_status = IWL_MVM_SCAN_OS; | 1243 | mvm->scan_status = IWL_MVM_SCAN_OS; |
1192 | 1244 | ||
@@ -1208,7 +1260,7 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, | |||
1208 | if (req->req.n_ssids == 0) | 1260 | if (req->req.n_ssids == 0) |
1209 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; | 1261 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; |
1210 | 1262 | ||
1211 | cmd->scan_flags = cpu_to_le32(flags); | 1263 | cmd->scan_flags |= cpu_to_le32(flags); |
1212 | 1264 | ||
1213 | cmd->flags = iwl_mvm_scan_rxon_flags(req->req.channels[0]->band); | 1265 | cmd->flags = iwl_mvm_scan_rxon_flags(req->req.channels[0]->band); |
1214 | cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | | 1266 | cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | |
@@ -1274,10 +1326,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
1274 | if (WARN_ON(mvm->scan_cmd == NULL)) | 1326 | if (WARN_ON(mvm->scan_cmd == NULL)) |
1275 | return -ENOMEM; | 1327 | return -ENOMEM; |
1276 | 1328 | ||
1277 | if (WARN_ON_ONCE(req->n_ssids > PROBE_OPTION_MAX || | 1329 | if (req->n_ssids > PROBE_OPTION_MAX || |
1278 | ies->common_ie_len + ies->len[0] + ies->len[1] + 24 + 2 | 1330 | ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + |
1279 | > SCAN_OFFLOAD_PROBE_REQ_SIZE || | 1331 | ies->len[NL80211_BAND_5GHZ] > |
1280 | req->n_channels > mvm->fw->ucode_capa.n_scan_channels)) | 1332 | iwl_mvm_max_scan_ie_fw_cmd_room(mvm, true) || |
1333 | req->n_channels > mvm->fw->ucode_capa.n_scan_channels) | ||
1281 | return -ENOBUFS; | 1334 | return -ENOBUFS; |
1282 | 1335 | ||
1283 | iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, ¶ms); | 1336 | iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, ¶ms); |
@@ -1305,7 +1358,7 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
1305 | if (req->n_ssids == 0) | 1358 | if (req->n_ssids == 0) |
1306 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; | 1359 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; |
1307 | 1360 | ||
1308 | cmd->scan_flags = cpu_to_le32(flags); | 1361 | cmd->scan_flags |= cpu_to_le32(flags); |
1309 | 1362 | ||
1310 | cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); | 1363 | cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); |
1311 | cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | | 1364 | cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | |