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.c79
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
342static 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
349static 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
371int 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
342int iwl_mvm_scan_request(struct iwl_mvm *mvm, 391int 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
1158int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, 1211int 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, &params); 1336 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
@@ -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 |