Lines Matching +full:out +full:- +full:of +full:- +full:band

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
13 #include "iwl-io.h"
28 /* adaptive dwell default high band APs number */
30 /* adaptive dwell default low band APs number */
34 /* number of scan channels */
36 /* adaptive dwell number of APs override mask for p2p friendly GO */
38 /* adaptive dwell number of APs override mask for social channels */
40 /* adaptive dwell number of APs override for p2p friendly GO channels */
42 /* adaptive dwell number of APs override for social channels */
45 /* minimal number of 2GHz and 5GHz channels in the regular scan request */
48 /* Number of iterations on the channel for mei filtered scan */
82 /* For CDB this is low band scan type, for non-CDB - type. */
112 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
115 return (void *)&cmd->v8.data;
118 return (void *)&cmd->v7.data;
121 return (void *)&cmd->v6.data;
123 return (void *)&cmd->v1.data;
129 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
132 return &cmd->v8.channel;
135 return &cmd->v7.channel;
138 return &cmd->v6.channel;
140 return &cmd->v1.channel;
145 if (mvm->scan_rx_ant != ANT_NONE)
146 return mvm->scan_rx_ant;
164 iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum nl80211_band band,
169 iwl_mvm_toggle_tx_ant(mvm, &mvm->scan_last_antenna_idx);
170 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
172 if (band == NL80211_BAND_2GHZ && !no_cck)
181 return mvm->tcm.result.global_load;
185 iwl_mvm_get_traffic_load_band(struct iwl_mvm *mvm, enum nl80211_band band)
187 return mvm->tcm.result.band_load[band];
203 if (vif->type != NL80211_IFTYPE_P2P_DEVICE &&
204 mvmvif->deflink.phy_ctxt &&
205 mvmvif->deflink.phy_ctxt->id < NUM_PHY_CTX)
206 data->global_cnt += 1;
208 if (!data->current_vif || vif == data->current_vif)
211 curr_mvmvif = iwl_mvm_vif_from_mac80211(data->current_vif);
214 mvmvif->deflink.phy_ctxt && curr_mvmvif->deflink.phy_ctxt &&
215 mvmvif->deflink.phy_ctxt->id != curr_mvmvif->deflink.phy_ctxt->id)
216 data->is_dcm_with_p2p_go = true;
234 * Force a non-fragmented scan in that case.
239 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
247 if (fw_has_api(&mvm->fw->ucode_capa,
250 (!vif || vif->type != NL80211_IFTYPE_P2P_DEVICE))
254 * in case of DCM with P2P GO set all scan requests as
255 * fast-balance scan
257 if (vif && vif->type == NL80211_IFTYPE_STATION &&
284 enum nl80211_band band)
289 load = iwl_mvm_get_traffic_load_band(mvm, band);
290 low_latency = iwl_mvm_low_latency_band(mvm, band);
298 return fw_has_capa(&mvm->fw->ucode_capa,
309 max_probe_len -= 24 + 2 + WFA_TPC_IE_LEN;
311 /* DS parameter set element is added on 2.4GHZ band if required */
313 max_probe_len -= 3;
322 /* TODO: [BUG] This function should return the maximum allowed size of
324 * in the same command. So the correct implementation of this function
330 * functions with -ENOBUFS, if a large enough probe will be provided.
339 struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data;
343 notif->status, notif->scanned_channels);
345 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
347 ieee80211_sched_scan_results(mvm->hw);
348 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
356 ieee80211_sched_scan_results(mvm->hw);
377 struct iwl_periodic_scan_complete *scan_notif = (void *)pkt->data;
378 bool aborted = (scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
381 * notification during UMAC scans -- warn and ignore it.
383 if (WARN_ON_ONCE(fw_has_capa(&mvm->fw->ucode_capa,
388 lockdep_assert_held(&mvm->mutex);
395 * simultaneously, but we can't have two different types of
400 if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_SCHED) {
401 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR);
405 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
408 scan_notif->last_schedule_line,
409 scan_notif->last_schedule_iteration,
410 __le32_to_cpu(scan_notif->time_after_last_iter));
412 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_SCHED;
413 } else if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR) {
416 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
418 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_REGULAR;
419 } else if (mvm->scan_status & IWL_MVM_SCAN_SCHED) {
420 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_REGULAR);
424 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
427 scan_notif->last_schedule_line,
428 scan_notif->last_schedule_iteration,
429 __le32_to_cpu(scan_notif->time_after_last_iter));
431 mvm->scan_status &= ~IWL_MVM_SCAN_SCHED;
432 ieee80211_sched_scan_stopped(mvm->hw);
433 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
434 } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
441 iwl_mvm_ebs_status_str(scan_notif->ebs_status));
443 mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
444 ieee80211_scan_completed(mvm->hw, &info);
445 cancel_delayed_work(&mvm->scan_timeout_dwork);
452 mvm->last_ebs_successful =
453 scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ||
454 scan_notif->ebs_status == IWL_SCAN_EBS_INACTIVE;
466 !memcmp(ssid_list->ssid, ssid, ssid_len))
472 return -1;
488 * iwl_config_sched_scan_profiles() uses the order of these ssids to
491 for (i = 0, j = params->n_match_sets - 1;
493 i++, j--) {
495 if (!params->match_sets[j].ssid.ssid_len)
498 ssids[i].len = params->match_sets[j].ssid.ssid_len;
499 memcpy(ssids[i].ssid, params->match_sets[j].ssid.ssid,
504 for (j = params->n_ssids - 1;
506 i++, j--) {
507 index = iwl_ssid_exist(params->ssids[j].ssid,
508 params->ssids[j].ssid_len,
512 ssids[i].len = params->ssids[j].ssid_len;
513 memcpy(ssids[i].ssid, params->ssids[j].ssid,
532 int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
545 if (WARN_ON(req->n_match_sets > max_profiles))
546 return -EIO;
548 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
555 return -ENOMEM;
559 ret = -ENOMEM;
572 data = &profile_cfg->data;
574 data = &profile_cfg_v1->data;
578 data->num_profiles = req->n_match_sets;
579 data->active_clients = SCAN_CLIENT_SCHED_SCAN;
580 data->pass_match = SCAN_CLIENT_SCHED_SCAN;
581 data->match_notify = SCAN_CLIENT_SCHED_SCAN;
583 if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
584 data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
586 for (i = 0; i < req->n_match_sets; i++) {
587 profile = &profile_cfg_v1->profiles[i];
588 profile->ssid_index = i;
590 profile->unicast_cipher = 0xff;
591 profile->auth_alg = IWL_AUTH_ALGO_UNSUPPORTED |
594 profile->network_type = IWL_NETWORK_TYPE_ANY;
595 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY;
596 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN;
612 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
615 req->n_match_sets);
616 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
622 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
647 ret = -ENOENT;
663 if (!iwl_mvm_has_new_station_api(mvm->fw)) {
664 tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
665 tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
690 struct iwl_scan_channel_cfg_lmac *channel_cfg = (void *)&cmd->data;
695 cpu_to_le16(channels[i]->hw_value);
734 memcpy(newpos, ies + offs, len - offs);
735 newpos += len - offs;
743 pos[1] = WFA_TPC_IE_LEN - 2;
749 /* pos[7] - tx power will be inserted by the FW */
759 struct ieee80211_mgmt *frame = (void *)params->preq.buf;
761 const u8 *mac_addr = params->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ?
762 params->mac_addr : NULL;
771 get_random_mask_addr(frame->sa, mac_addr,
772 params->mac_addr_mask);
774 memcpy(frame->sa, vif->addr, ETH_ALEN);
776 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
777 eth_broadcast_addr(frame->da);
778 ether_addr_copy(frame->bssid, params->bssid);
779 frame->seq_ctrl = 0;
781 pos = frame->u.probe_req.variable;
785 params->preq.mac_header.offset = 0;
786 params->preq.mac_header.len = cpu_to_le16(24 + 2);
788 /* Insert ds parameter set element on 2.4 GHz band */
790 ies->ies[NL80211_BAND_2GHZ],
791 ies->len[NL80211_BAND_2GHZ],
793 params->preq.band_data[0].offset = cpu_to_le16(pos - params->preq.buf);
794 params->preq.band_data[0].len = cpu_to_le16(newpos - pos);
797 memcpy(pos, ies->ies[NL80211_BAND_5GHZ],
798 ies->len[NL80211_BAND_5GHZ]);
799 params->preq.band_data[1].offset = cpu_to_le16(pos - params->preq.buf);
800 params->preq.band_data[1].len =
801 cpu_to_le16(ies->len[NL80211_BAND_5GHZ]);
802 pos += ies->len[NL80211_BAND_5GHZ];
804 memcpy(pos, ies->ies[NL80211_BAND_6GHZ],
805 ies->len[NL80211_BAND_6GHZ]);
806 params->preq.band_data[2].offset = cpu_to_le16(pos - params->preq.buf);
807 params->preq.band_data[2].len =
808 cpu_to_le16(ies->len[NL80211_BAND_6GHZ]);
809 pos += ies->len[NL80211_BAND_6GHZ];
810 memcpy(pos, ies->common_ies, ies->common_ie_len);
811 params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf);
814 !fw_has_capa(&mvm->fw->ucode_capa,
816 iwl_mvm_add_tpc_report_ie(pos + ies->common_ie_len);
817 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len +
820 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len);
828 cmd->active_dwell = IWL_SCAN_DWELL_ACTIVE;
829 cmd->passive_dwell = IWL_SCAN_DWELL_PASSIVE;
830 cmd->fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
831 cmd->extended_dwell = IWL_SCAN_DWELL_EXTENDED;
832 cmd->max_out_time = cpu_to_le32(scan_timing[params->type].max_out_time);
833 cmd->suspend_time = cpu_to_le32(scan_timing[params->type].suspend_time);
834 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
842 (n_channels <= mvm->fw->ucode_capa.n_scan_channels) &
843 (ies->common_ie_len +
844 ies->len[NL80211_BAND_2GHZ] + ies->len[NL80211_BAND_5GHZ] +
845 ies->len[NL80211_BAND_6GHZ] <=
852 const struct iwl_ucode_capabilities *capa = &mvm->fw->ucode_capa;
869 return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
870 mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS &&
871 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
878 return params->n_scan_plans == 1 &&
879 params->scan_plans[0].iterations == 1;
894 if (params->n_ssids == 0)
897 if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
900 if (iwl_mvm_is_scan_fragmented(params->type))
904 fw_has_capa(&mvm->fw->ucode_capa,
908 if (params->pass_all)
914 if (mvm->scan_iter_notif_enabled)
918 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
922 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
923 !iwl_mvm_is_scan_fragmented(params->type))
935 p_req->mac_header = src_p_req->mac_header;
937 p_req->band_data[i] = src_p_req->band_data[i];
938 p_req->common_data = src_p_req->common_data;
939 memcpy(p_req->buf, src_p_req->buf, sizeof(p_req->buf));
945 struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
947 (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) *
948 mvm->fw->ucode_capa.n_scan_channels);
951 u8 band;
953 if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
954 return -EINVAL;
958 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
959 cmd->iter_num = cpu_to_le32(1);
960 cmd->n_channels = (u8)params->n_channels;
962 cmd->delay = cpu_to_le32(params->delay);
964 cmd->scan_flags = cpu_to_le32(iwl_mvm_scan_lmac_flags(mvm, params,
967 band = iwl_mvm_phy_band_from_nl80211(params->channels[0]->band);
968 cmd->flags = cpu_to_le32(band);
969 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
971 iwl_mvm_scan_fill_tx_cmd(mvm, cmd->tx_cmd, params->no_cck);
972 iwl_scan_build_ssids(params, cmd->direct_scan, &ssid_bitmap);
974 /* this API uses bits 1-20 instead of 0-19 */
977 for (i = 0; i < params->n_scan_plans; i++) {
979 &params->scan_plans[i];
981 cmd->schedule[i].delay =
982 cpu_to_le16(scan_plan->interval);
983 cmd->schedule[i].iterations = scan_plan->iterations;
984 cmd->schedule[i].full_scan_mul = 1;
988 * If the number of iterations of the last scan plan is set to
993 if (!cmd->schedule[i - 1].iterations)
994 cmd->schedule[i - 1].iterations = 0xff;
997 cmd->channel_opt[0].flags =
1001 cmd->channel_opt[0].non_ebs_ratio =
1003 cmd->channel_opt[1].flags =
1007 cmd->channel_opt[1].non_ebs_ratio =
1011 iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
1012 params->n_channels, ssid_bitmap, cmd);
1014 iwl_mvm_scan_set_legacy_probe_req(preq, &params->preq);
1041 struct ieee80211_supported_band *band;
1045 band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
1046 for (i = 0; i < band->n_bitrates; i++)
1047 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value);
1048 band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
1049 for (i = 0; i < band->n_bitrates; i++)
1050 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value);
1061 dwell->active = IWL_SCAN_DWELL_ACTIVE;
1062 dwell->passive = IWL_SCAN_DWELL_PASSIVE;
1063 dwell->fragmented = IWL_SCAN_DWELL_FRAGMENTED;
1064 dwell->extended = IWL_SCAN_DWELL_EXTENDED;
1070 struct ieee80211_supported_band *band;
1073 band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
1074 for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
1075 channels[j] = band->channels[i].hw_value;
1076 band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
1077 for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
1078 channels[j] = band->channels[i].hw_value;
1088 cfg->flags = cpu_to_le32(flags);
1089 cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1090 cfg->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1091 cfg->legacy_rates = iwl_mvm_scan_config_rates(mvm);
1092 cfg->out_of_channel_time = cpu_to_le32(scan_timing[type].max_out_time);
1093 cfg->suspend_time = cpu_to_le32(scan_timing[type].suspend_time);
1095 iwl_mvm_fill_scan_dwell(mvm, &cfg->dwell);
1097 memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
1100 WARN_ON_ONCE(iwl_mvm_has_new_station_api(mvm->fw));
1102 cfg->bcast_sta_id = mvm->aux_sta.sta_id;
1103 cfg->channel_flags = channel_flags;
1105 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1114 cfg->flags = cpu_to_le32(flags);
1115 cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1116 cfg->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1117 cfg->legacy_rates = iwl_mvm_scan_config_rates(mvm);
1127 cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
1129 cfg->suspend_time[SCAN_LB_LMAC_IDX] =
1132 cfg->out_of_channel_time[SCAN_HB_LMAC_IDX] =
1134 cfg->suspend_time[SCAN_HB_LMAC_IDX] =
1140 cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
1142 cfg->suspend_time[SCAN_LB_LMAC_IDX] =
1146 iwl_mvm_fill_scan_dwell(mvm, &cfg->dwell);
1148 memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
1151 WARN_ON_ONCE(iwl_mvm_has_new_station_api(mvm->fw));
1153 cfg->bcast_sta_id = mvm->aux_sta.sta_id;
1154 cfg->channel_flags = channel_flags;
1156 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1169 mvm->nvm_data->bands[NL80211_BAND_2GHZ].n_channels +
1170 mvm->nvm_data->bands[NL80211_BAND_5GHZ].n_channels;
1174 if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels))
1175 num_channels = mvm->fw->ucode_capa.n_scan_channels;
1182 if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
1186 if (type == mvm->scan_type)
1194 cmd_size += mvm->fw->ucode_capa.n_scan_channels;
1198 return -ENOMEM;
1220 * Check for fragmented scan on LMAC2 - high band.
1221 * LMAC1 - low band is checked above.
1243 mvm->scan_type = type;
1244 mvm->hb_scan_type = hb_type;
1266 if (!iwl_mvm_has_new_station_api(mvm->fw)) {
1267 cfg.bcast_sta_id = mvm->aux_sta.sta_id;
1268 } else if (iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_CFG_CMD, 0) < 5) {
1288 for (i = 0; i < mvm->max_scans; i++)
1289 if (mvm->scan_uid_status[i] == status)
1292 return -ENOENT;
1302 timing = &scan_timing[params->type];
1307 cmd->v7.adwell_default_n_aps_social =
1309 cmd->v7.adwell_default_n_aps =
1313 cmd->v9.adwell_default_hb_n_aps =
1318 cmd->v7.adwell_max_budget =
1320 else if (params->n_ssids && params->ssids[0].ssid_len)
1321 cmd->v7.adwell_max_budget =
1324 cmd->v7.adwell_max_budget =
1327 cmd->v7.scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1328 cmd->v7.max_out_time[SCAN_LB_LMAC_IDX] =
1329 cpu_to_le32(timing->max_out_time);
1330 cmd->v7.suspend_time[SCAN_LB_LMAC_IDX] =
1331 cpu_to_le32(timing->suspend_time);
1334 hb_timing = &scan_timing[params->hb_type];
1336 cmd->v7.max_out_time[SCAN_HB_LMAC_IDX] =
1337 cpu_to_le32(hb_timing->max_out_time);
1338 cmd->v7.suspend_time[SCAN_HB_LMAC_IDX] =
1339 cpu_to_le32(hb_timing->suspend_time);
1343 cmd->v7.active_dwell = active_dwell;
1344 cmd->v7.passive_dwell = passive_dwell;
1345 cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
1347 cmd->v8.active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
1348 cmd->v8.passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
1350 cmd->v8.active_dwell[SCAN_HB_LMAC_IDX] =
1352 cmd->v8.passive_dwell[SCAN_HB_LMAC_IDX] =
1357 cmd->v1.extended_dwell = IWL_SCAN_DWELL_EXTENDED;
1358 cmd->v1.active_dwell = active_dwell;
1359 cmd->v1.passive_dwell = passive_dwell;
1360 cmd->v1.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
1363 hb_timing = &scan_timing[params->hb_type];
1365 cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] =
1366 cpu_to_le32(hb_timing->max_out_time);
1367 cmd->v6.suspend_time[SCAN_HB_LMAC_IDX] =
1368 cpu_to_le32(hb_timing->suspend_time);
1372 cmd->v6.scan_priority =
1374 cmd->v6.max_out_time[SCAN_LB_LMAC_IDX] =
1375 cpu_to_le32(timing->max_out_time);
1376 cmd->v6.suspend_time[SCAN_LB_LMAC_IDX] =
1377 cpu_to_le32(timing->suspend_time);
1379 cmd->v1.scan_priority =
1381 cmd->v1.max_out_time =
1382 cpu_to_le32(timing->max_out_time);
1383 cmd->v1.suspend_time =
1384 cpu_to_le32(timing->suspend_time);
1389 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1391 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
1412 timing = &scan_timing[params->type];
1416 general_params->adwell_default_social_chn =
1418 general_params->adwell_default_2g = IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
1419 general_params->adwell_default_5g = IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;
1423 general_params->adwell_max_budget =
1425 else if (params->n_ssids && params->ssids[0].ssid_len)
1426 general_params->adwell_max_budget =
1429 general_params->adwell_max_budget =
1432 general_params->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
1433 general_params->max_out_of_time[SCAN_LB_LMAC_IDX] =
1434 cpu_to_le32(timing->max_out_time);
1435 general_params->suspend_time[SCAN_LB_LMAC_IDX] =
1436 cpu_to_le32(timing->suspend_time);
1438 hb_timing = &scan_timing[params->hb_type];
1440 general_params->max_out_of_time[SCAN_HB_LMAC_IDX] =
1441 cpu_to_le32(hb_timing->max_out_time);
1442 general_params->suspend_time[SCAN_HB_LMAC_IDX] =
1443 cpu_to_le32(hb_timing->suspend_time);
1445 general_params->active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
1446 general_params->passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
1447 general_params->active_dwell[SCAN_HB_LMAC_IDX] = active_dwell;
1448 general_params->passive_dwell[SCAN_HB_LMAC_IDX] = passive_dwell;
1457 u8 band;
1467 .band = PHY_BAND_24
1475 .band = PHY_BAND_5
1483 .band = PHY_BAND_5
1491 .band = PHY_BAND_6
1495 static int iwl_mvm_scan_ch_and_band_to_idx(u8 channel_id, u8 band)
1500 return -EINVAL;
1507 if (ch_segment->band != band ||
1508 ch_segment->first_channel_id > channel_id ||
1509 ch_segment->last_channel_id < channel_id)
1512 ch_offset = (channel_id - ch_segment->first_channel_id) >>
1513 ch_segment->channel_spacing_shift;
1522 return -EINVAL;
1534 u8 ch_id, u8 band, u8 *ch_bitmap,
1546 ch_idx = iwl_mvm_scan_ch_and_band_to_idx(ch_id, band);
1568 goto out;
1578 goto out;
1587 out:
1601 channel_cfg[i].v1.channel_num = channels[i]->hw_value;
1603 enum nl80211_band band = channels[i]->band;
1605 channel_cfg[i].v2.band =
1606 iwl_mvm_phy_band_from_nl80211(band);
1623 u8 *bitmap = cp->adwell_ch_override_bitmap;
1624 size_t bitmap_n_entries = ARRAY_SIZE(cp->adwell_ch_override_bitmap);
1628 enum nl80211_band band = channels[i]->band;
1630 &cp->channel_config[i];
1632 cfg->flags = cpu_to_le32(flags);
1633 cfg->v2.channel_num = channels[i]->hw_value;
1634 cfg->v2.band = iwl_mvm_phy_band_from_nl80211(band);
1635 cfg->v2.iter_count = 1;
1636 cfg->v2.iter_interval = 0;
1639 cfg->v2.channel_num,
1640 cfg->v2.band, bitmap,
1655 enum nl80211_band band = channels[i]->band;
1656 struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i];
1659 channels[i]->hw_value);
1660 u8 iwl_band = iwl_mvm_phy_band_from_nl80211(band);
1662 cfg->flags = cpu_to_le32(flags | n_aps_flag);
1663 cfg->v2.channel_num = channels[i]->hw_value;
1665 cfg->flags = 0;
1667 if (band == NL80211_BAND_6GHZ) {
1672 WARN_ON_ONCE(cfg->flags != 0);
1673 cfg->flags =
1677 cfg->v2.iter_count = 1;
1678 cfg->v2.iter_interval = 0;
1680 cfg->v2.band = iwl_band;
1682 cfg->flags |= cpu_to_le32((iwl_band <<
1694 params->scan_6ghz_params;
1695 bool hidden_supported = fw_has_capa(&mvm->fw->ucode_capa,
1698 for (j = 0; j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE;
1700 if (!params->ssids[j].ssid_len)
1703 pp->short_ssid[idex_s] =
1704 cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
1705 params->ssids[j].ssid_len));
1708 pp->direct_scan[idex_s].id = WLAN_EID_SSID;
1709 pp->direct_scan[idex_s].len = params->ssids[j].ssid_len;
1710 memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid,
1711 params->ssids[j].ssid_len);
1717 * Populate the arrays of the short SSIDs and the BSSIDs using the 6GHz
1720 * that some entries would be left out.
1724 for (j = 0; j < params->n_6ghz_params; j++) {
1730 if (pp->short_ssid[k] ==
1736 pp->short_ssid[idex_s++] =
1743 if (!memcmp(&pp->bssid_array[k],
1752 memcpy(&pp->bssid_array[idex_b++],
1757 pp->short_ssid_num = idex_s;
1758 pp->bssid_num = idex_b;
1773 params->scan_6ghz_params;
1776 for (i = 0, ch_cnt = 0; i < params->n_channels; i++) {
1778 &cp->channel_config[ch_cnt];
1792 if (!cfg80211_channel_is_psc(params->channels[i]) &&
1793 !params->n_6ghz_params && params->n_ssids)
1796 cfg->v1.channel_num = params->channels[i]->hw_value;
1798 cfg->v2.band = PHY_BAND_6;
1800 cfg->flags |= cpu_to_le32(PHY_BAND_6 <<
1803 cfg->v5.iter_count = 1;
1804 cfg->v5.iter_interval = 0;
1806 for (j = 0; j < params->n_6ghz_params; j++) {
1832 * - PSC channel with NO_LISTEN_FLAG on should be treated
1834 * - Non PSC channel with more than 3 short SSIDs or more
1836 * - Non PSC Channel with unsolicited probe response and
1838 * - PSC channel with more than 2 short SSIDs or more than
1841 * - PSC channel with more than 1 SSID or 3 BSSIDs.
1842 * - Non PSC channel with more than 2 SSIDs or 6 BSSIDs.
1843 * - Non PSC channel with unsolicited probe response and
1846 if (!iwl_mvm_is_scan_fragmented(params->type)) {
1847 if (!cfg80211_channel_is_psc(params->channels[i]) ||
1860 } else if (cfg80211_channel_is_psc(params->channels[i])) {
1880 for (j = 0; j < params->n_6ghz_params; j++) {
1887 k < pp->short_ssid_num && n_s_ssids < max_s_ssids;
1890 le32_to_cpu(pp->short_ssid[k]) ==
1907 !pp->direct_scan[k].len)
1911 if (pp->direct_scan[k].len)
1924 for (k = 0; k < pp->bssid_num; k++) {
1925 if (!memcmp(&pp->bssid_array[k],
1941 if (cfg80211_channel_is_psc(params->channels[i]) &&
1950 !cfg80211_channel_is_psc(params->channels[i])))
1955 cfg->flags |= cpu_to_le32(flags);
1957 cfg->v5.psd_20 = psd_20;
1962 if (params->n_channels > ch_cnt)
1964 "6GHz: reducing number channels: (%u->%u)\n",
1965 params->n_channels, ch_cnt);
1985 iwl_mvm_is_scan_fragmented(params->type)) ||
1987 iwl_mvm_is_scan_fragmented(params->hb_type)))
1995 iwl_mvm_is_scan_fragmented(params->type) && params->respect_p2p_go) ||
1997 iwl_mvm_is_scan_fragmented(params->hb_type) &&
1998 params->respect_p2p_go_hb)) {
2011 &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
2014 params->enable_6ghz_passive = false;
2016 if (params->scan_6ghz)
2019 if (!fw_has_capa(&mvm->fw->ucode_capa,
2027 if (vif->type != NL80211_IFTYPE_STATION) {
2038 if ((vif->cfg.assoc ||
2039 time_after(mvm->last_6ghz_passive_scan_jiffies +
2041 (time_before(mvm->last_reset_or_resume_time_jiffies +
2045 vif->cfg.assoc ? "associated" :
2051 if (params->n_channels < IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS) {
2057 for (i = 0; i < params->n_ssids; i++) {
2058 if (!params->ssids[i].ssid_len)
2063 if (i == params->n_ssids) {
2069 if (!sband || !sband->n_channels) {
2075 for (i = 0, n_disabled = 0; i < sband->n_channels; i++) {
2076 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED))
2084 if (n_disabled != sband->n_channels) {
2092 params->enable_6ghz_passive = true;
2106 * all chains to improve chances of hearing the beacons/probe responses.
2108 if (params->n_ssids == 0)
2110 else if (params->n_ssids == 1 && params->ssids[0].ssid_len)
2113 if (iwl_mvm_is_scan_fragmented(params->type))
2116 if (iwl_mvm_is_scan_fragmented(params->hb_type))
2119 if (params->pass_all)
2127 if (params->iter_notif ||
2128 mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
2138 params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ)
2141 if (params->enable_6ghz_passive)
2145 (params->flags & (NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP |
2161 if (params->respect_p2p_go)
2163 if (params->respect_p2p_go_hb)
2166 if (params->respect_p2p_go)
2171 if (params->scan_6ghz &&
2172 fw_has_capa(&mvm->fw->ucode_capa,
2176 /* Passive and AP interface -> ACS (automatic channel selection) */
2179 iwl_fw_lookup_notif_ver(mvm->fw, SCAN_GROUP, CHANNEL_SURVEY_NOTIF,
2192 if (params->n_ssids == 0)
2195 if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
2198 if (iwl_mvm_is_scan_fragmented(params->type))
2202 iwl_mvm_is_scan_fragmented(params->hb_type))
2206 fw_has_capa(&mvm->fw->ucode_capa,
2210 if (params->pass_all)
2218 if (params->iter_notif)
2222 if (mvm->scan_iter_notif_enabled)
2226 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
2233 * Extended dwell is relevant only for low band to start with, as it is
2235 * only scan type on low band also for CDB.
2238 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
2239 !iwl_mvm_is_scan_fragmented(params->type) &&
2245 if ((params->flags &
2253 if ((params->flags &
2257 if ((params->flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME))
2270 if (WARN_ON(!params->n_scan_plans ||
2271 params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
2272 return -EINVAL;
2274 for (i = 0; i < params->n_scan_plans; i++) {
2276 &params->scan_plans[i];
2278 schedule[i].iter_count = scan_plan->iterations;
2280 cpu_to_le16(scan_plan->interval);
2284 * If the number of iterations of the last scan plan is set to
2289 if (!schedule[params->n_scan_plans - 1].iter_count)
2290 schedule[params->n_scan_plans - 1].iter_count = 0xff;
2292 *delay = cpu_to_le16(params->delay);
2301 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
2305 mvm->fw->ucode_capa.n_scan_channels;
2320 cmd->uid = cpu_to_le32(uid);
2322 cmd->general_flags = cpu_to_le16(gen_flags);
2325 cmd->v8.num_of_fragments[SCAN_LB_LMAC_IDX] =
2328 cmd->v8.num_of_fragments[SCAN_HB_LMAC_IDX] =
2331 cmd->v8.general_flags2 =
2335 cmd->scan_start_mac_id = scan_vif->id;
2338 cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE);
2355 chan_param->flags = channel_flags;
2356 chan_param->count = params->n_channels;
2358 ret = iwl_mvm_fill_scan_sched_params(params, tail_v2->schedule,
2359 &tail_v2->delay);
2364 tail_v2->preq = params->preq;
2365 direct_scan = tail_v2->direct_scan;
2368 iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq,
2369 &params->preq);
2370 direct_scan = tail_v1->direct_scan;
2373 iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
2374 params->n_channels, ssid_bitmap,
2394 gp->flags = cpu_to_le16(gen_flags);
2395 gp->flags2 = gen_flags2;
2398 gp->num_of_fragments[SCAN_LB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
2400 gp->num_of_fragments[SCAN_HB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
2402 mvm->scan_link_id = 0;
2405 gp->scan_start_mac_or_link_id = scan_vif->id;
2408 scan_vif->link[params->tsf_report_link_id];
2410 mvm->scan_link_id = params->tsf_report_link_id;
2412 gp->scan_start_mac_or_link_id = link_info->fw_link_id;
2420 pp->preq = params->preq;
2421 pp->ssid_num = params->n_ssids;
2422 iwl_scan_build_ssids(params, pp->direct_scan, NULL);
2430 pp->preq = params->preq;
2431 iwl_scan_build_ssids(params, pp->direct_scan, bitmap_ssid);
2441 cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
2442 cp->count = params->n_channels;
2443 cp->num_of_aps_override = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
2445 iwl_mvm_umac_scan_cfg_channels_v4(mvm, params->channels, cp,
2446 params->n_channels,
2448 vif->type);
2459 cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
2460 cp->count = params->n_channels;
2461 cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
2462 cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
2464 iwl_mvm_umac_scan_cfg_channels_v7(mvm, params->channels, cp,
2465 params->n_channels,
2467 vif->type, version);
2469 if (params->enable_6ghz_passive) {
2471 &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
2474 for (i = 0; i < sband->n_channels; i++) {
2476 &sband->channels[i];
2479 &cp->channel_config[cp->count];
2484 cfg->v5.channel_num = channel->hw_value;
2485 cfg->v5.iter_count = 1;
2486 cfg->v5.iter_interval = 0;
2489 cfg->flags = 0;
2490 cfg->v2.band = PHY_BAND_6;
2492 cfg->flags = cpu_to_le32(PHY_BAND_6 <<
2494 cfg->v5.psd_20 =
2497 cp->count++;
2506 struct iwl_scan_req_umac_v12 *cmd = mvm->scan_cmd;
2507 struct iwl_scan_req_params_v12 *scan_p = &cmd->scan_params;
2511 cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type));
2512 cmd->uid = cpu_to_le32(uid);
2516 &scan_p->general_params,
2520 scan_p->periodic_params.schedule,
2521 &scan_p->periodic_params.delay);
2525 iwl_mvm_scan_umac_fill_probe_p_v3(params, &scan_p->probe_params);
2527 &scan_p->channel_params, 0);
2537 struct iwl_scan_req_umac_v17 *cmd = mvm->scan_cmd;
2538 struct iwl_scan_req_params_v17 *scan_p = &cmd->scan_params;
2539 struct iwl_scan_channel_params_v7 *cp = &scan_p->channel_params;
2540 struct iwl_scan_probe_params_v4 *pb = &scan_p->probe_params;
2546 cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type));
2547 cmd->uid = cpu_to_le32(uid);
2558 &scan_p->general_params,
2562 scan_p->periodic_params.schedule,
2563 &scan_p->periodic_params.delay);
2567 if (!params->scan_6ghz) {
2569 &scan_p->probe_params,
2572 &scan_p->channel_params,
2577 pb->preq = params->preq;
2580 cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
2581 cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
2582 cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
2586 cp->count = iwl_mvm_umac_scan_cfg_channels_v7_6g(mvm, params,
2587 params->n_channels,
2588 pb, cp, vif->type,
2590 if (!cp->count)
2591 return -EINVAL;
2593 if (!params->n_ssids ||
2594 (params->n_ssids == 1 && !params->ssids[0].ssid_len))
2595 cp->flags |= IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER;
2630 return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK);
2635 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
2639 * out of possible simultaneous scans and the userspace is
2641 * return -EBUSY. But if the userspace wants to start a
2642 * different type of scan, we stop the opposite type to make
2650 mvm->scan_status & (IWL_MVM_SCAN_SCHED | IWL_MVM_SCAN_NETDETECT))
2651 return -EBUSY;
2653 if (iwl_mvm_num_scans(mvm) < mvm->max_scans)
2661 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
2662 return -EBUSY;
2665 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
2666 return -EBUSY;
2669 /* For non-unified images, there's no need to stop
2670 * anything for net-detect since the firmware is
2677 /* If this is a unified image and we ran out of scans,
2683 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
2686 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
2690 * ran out of scans.
2698 return -EIO;
2709 IWL_ERR(mvm, "regular scan timed out\n");
2711 iwl_force_nmi(mvm->trans);
2719 params->type =
2722 params->hb_type =
2726 params->type = iwl_mvm_get_scan_type(mvm, vif);
2760 mutex_lock(&mvm->mutex);
2762 memcpy(bssid, info->conn_info.bssid, ETH_ALEN);
2763 mutex_unlock(&mvm->mutex);
2765 while ((skb = skb_dequeue(&scan_filter->scan_res))) {
2766 struct ieee80211_mgmt *mgmt = (void *)skb->data;
2768 if (!memcmp(mgmt->bssid, bssid, ETH_ALEN))
2769 ieee80211_rx_irqsafe(mvm->hw, skb);
2777 skb_queue_head_init(&mei_scan_filter->scan_res);
2778 INIT_WORK(&mei_scan_filter->scan_work, iwl_mvm_mei_scan_work);
2798 conn_info = &info->conn_info;
2799 if (!info->conn_info.lp_state || !info->conn_info.ssid_len)
2802 if (!params->n_channels || !params->n_ssids)
2805 mvm->mei_scan_filter.is_mei_limited_scan = true;
2807 chan = ieee80211_get_channel(mvm->hw->wiphy,
2808 ieee80211_channel_to_frequency(conn_info->channel,
2809 conn_info->band));
2812 "Failed to get CSME channel (chan=%u band=%u)\n",
2813 conn_info->channel, conn_info->band);
2821 scan_iters = min(IWL_MEI_SCAN_NUM_ITER, params->n_channels);
2822 params->n_channels = scan_iters;
2824 params->channels[i] = chan;
2828 params->n_ssids = 1;
2829 params->ssids[0].ssid_len = conn_info->ssid_len;
2830 memcpy(params->ssids[0].ssid, conn_info->ssid, conn_info->ssid_len);
2842 lockdep_assert_held(&mvm->mutex);
2843 memset(mvm->scan_cmd, 0, mvm->scan_cmd_size);
2847 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
2848 hcmd->id = SCAN_OFFLOAD_REQUEST_CMD;
2857 hcmd->id = WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_REQ_UMAC);
2859 scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC,
2866 if (ver_handler->version != scan_ver)
2869 err = ver_handler->handler(mvm, vif, params, type, uid);
2883 enum nl80211_band band;
2893 if (vif == data->current_vif)
2900 link_id < ARRAY_SIZE(mvmvif->link);
2903 mvmvif->link[link_id];
2905 if (link && link->phy_ctxt->id < NUM_PHY_CTX &&
2906 (data->band == NUM_NL80211_BANDS ||
2907 link->phy_ctxt->channel->band == data->band)) {
2908 data->p2p_go = true;
2918 enum nl80211_band band)
2923 .band = band,
2929 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
2939 enum nl80211_band band)
2941 bool low_latency = iwl_mvm_low_latency_band(mvm, band);
2943 return _iwl_mvm_get_respect_p2p_go(mvm, vif, low_latency, band);
2960 params->respect_p2p_go =
2963 params->respect_p2p_go_hb =
2967 params->respect_p2p_go = iwl_mvm_get_respect_p2p_go(mvm, vif);
2979 .data = { mvm->scan_cmd, },
2986 lockdep_assert_held(&mvm->mutex);
2988 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
2990 return -EBUSY;
2998 if (WARN_ON(!mvm->scan_cmd))
2999 return -ENOMEM;
3001 if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, req->n_channels))
3002 return -ENOBUFS;
3004 params.n_ssids = req->n_ssids;
3005 params.flags = req->flags;
3006 params.n_channels = req->n_channels;
3008 params.ssids = req->ssids;
3009 params.channels = req->channels;
3010 params.mac_addr = req->mac_addr;
3011 params.mac_addr_mask = req->mac_addr_mask;
3012 params.no_cck = req->no_cck;
3016 ether_addr_copy(params.bssid, req->bssid);
3021 params.n_6ghz_params = req->n_6ghz_params;
3022 params.scan_6ghz_params = req->scan_6ghz_params;
3023 params.scan_6ghz = req->scan_6ghz;
3027 if (req->duration)
3030 params.tsf_report_link_id = req->tsf_report_link_id;
3032 if (vif->active_links)
3033 params.tsf_report_link_id = __ffs(vif->active_links);
3063 mvm->scan_uid_status[uid] = type;
3064 mvm->scan_status |= type;
3067 mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
3068 schedule_delayed_work(&mvm->scan_timeout_dwork,
3073 mvm->last_6ghz_passive_scan_jiffies = jiffies;
3094 .data = { mvm->scan_cmd, },
3102 lockdep_assert_held(&mvm->mutex);
3104 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
3105 IWL_ERR(mvm, "sched-scan while LAR regdomain is not set\n");
3106 return -EBUSY;
3114 if (WARN_ON(!mvm->scan_cmd))
3115 return -ENOMEM;
3118 params.n_ssids = req->n_ssids;
3119 params.flags = req->flags;
3120 params.n_channels = req->n_channels;
3121 params.ssids = req->ssids;
3122 params.channels = req->channels;
3123 params.mac_addr = req->mac_addr;
3124 params.mac_addr_mask = req->mac_addr_mask;
3127 params.n_match_sets = req->n_match_sets;
3128 params.match_sets = req->match_sets;
3130 if (!req->n_scan_plans)
3131 return -EINVAL;
3133 params.n_scan_plans = req->n_scan_plans;
3134 params.scan_plans = req->scan_plans;
3139 /* In theory, LMAC scans can handle a 32-bit delay, but since
3142 * 16-bit delays), trim it down to 16-bits.
3144 if (req->delay > U16_MAX) {
3146 "delay value is > 16-bits, set to max possible\n");
3149 params.delay = req->delay;
3158 /* for 6 GHZ band only PSC channels need to be added */
3162 if (channel->band == NL80211_BAND_6GHZ &&
3175 return -ENOMEM;
3178 if (params.channels[i]->band == NL80211_BAND_6GHZ &&
3186 if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, params.n_channels)) {
3187 ret = -ENOBUFS;
3188 goto out;
3194 goto out;
3202 mvm->scan_uid_status[uid] = type;
3203 mvm->scan_status |= type;
3210 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
3213 out:
3223 struct iwl_umac_scan_complete *notif = (void *)pkt->data;
3224 u32 uid = __le32_to_cpu(notif->uid);
3225 bool aborted = (notif->status == IWL_SCAN_OFFLOAD_ABORTED);
3228 mvm->mei_scan_filter.is_mei_limited_scan = false;
3232 uid, mvm->scan_uid_status[uid],
3233 notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
3235 iwl_mvm_ebs_status_str(notif->ebs_status));
3238 mvm->scan_status);
3242 notif->last_schedule, notif->last_iter,
3243 __le32_to_cpu(notif->time_from_last_iter));
3245 if (WARN_ON(!(mvm->scan_uid_status[uid] & mvm->scan_status)))
3249 if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
3252 .scan_start_tsf = mvm->scan_start,
3254 struct iwl_mvm_vif *scan_vif = mvm->scan_vif;
3256 scan_vif->link[mvm->scan_link_id];
3262 memcpy(info.tsf_bssid, link_info->bssid, ETH_ALEN);
3266 ieee80211_scan_completed(mvm->hw, &info);
3267 mvm->scan_vif = NULL;
3268 cancel_delayed_work(&mvm->scan_timeout_dwork);
3270 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
3271 ieee80211_sched_scan_stopped(mvm->hw);
3272 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
3273 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_INT_MLO) {
3279 select_links = notif->status == IWL_SCAN_OFFLOAD_COMPLETED;
3282 mvm->scan_status &= ~mvm->scan_uid_status[uid];
3285 mvm->scan_status);
3287 if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS &&
3288 notif->ebs_status != IWL_SCAN_EBS_INACTIVE)
3289 mvm->last_ebs_successful = false;
3291 mvm->scan_uid_status[uid] = 0;
3294 wiphy_work_queue(mvm->hw->wiphy, &mvm->trig_link_selection_wk);
3301 struct iwl_umac_scan_iter_complete_notif *notif = (void *)pkt->data;
3303 mvm->scan_start = le64_to_cpu(notif->start_tsf);
3307 notif->status, notif->scanned_channels);
3309 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
3311 ieee80211_sched_scan_results(mvm->hw);
3312 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
3317 mvm->scan_start);
3325 lockdep_assert_held(&mvm->mutex);
3328 * checked that this type of scan was running in the generic
3343 mvm->scan_uid_status[uid] = type << IWL_MVM_SCAN_STOPPING_SHIFT;
3356 lockdep_assert_held(&mvm->mutex);
3358 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
3365 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
3372 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
3376 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_done,
3398 u8 scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC,
3415 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
3423 mvm->fw->ucode_capa.n_scan_channels +
3428 mvm->fw->ucode_capa.n_scan_channels +
3438 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
3447 cancel_delayed_work(&mvm->scan_timeout_dwork);
3449 ieee80211_scan_completed(mvm->hw, &info);
3450 mvm->scan_uid_status[uid] = 0;
3458 if (!mvm->fw_restart)
3459 ieee80211_sched_scan_stopped(mvm->hw);
3460 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
3461 mvm->scan_uid_status[uid] = 0;
3466 mvm->scan_uid_status[uid] = 0;
3472 mvm->scan_uid_status[uid] = 0;
3477 mvm->scan_uid_status[uid] = 0;
3482 mvm->scan_uid_status[uid] = 0;
3488 for (i = 0; i < mvm->max_scans; i++) {
3489 if (WARN_ONCE(mvm->scan_uid_status[i],
3492 mvm->scan_uid_status[i] = 0;
3495 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
3500 cancel_delayed_work(&mvm->scan_timeout_dwork);
3501 ieee80211_scan_completed(mvm->hw, &info);
3508 if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) &&
3509 !mvm->fw_restart) {
3510 ieee80211_sched_scan_stopped(mvm->hw);
3511 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
3522 type, mvm->scan_status);
3524 if (!(mvm->scan_status & type))
3527 if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) {
3529 goto out;
3534 mvm->scan_status |= type << IWL_MVM_SCAN_STOPPING_SHIFT;
3538 out:
3544 mvm->scan_status &= ~type;
3547 cancel_delayed_work(&mvm->scan_timeout_dwork);
3553 ieee80211_scan_completed(mvm->hw, &info);
3556 ieee80211_sched_scan_stopped(mvm->hw);
3557 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
3573 lockdep_assert_held(&mvm->mutex);
3578 if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif))
3579 return -EINVAL;
3584 return -ENOMEM;
3588 req->channels[i] = channels[i];
3590 req->n_channels = n_channels;
3594 if (mvm->hw->wiphy->bands[i])
3595 req->rates[i] =
3596 (1 << mvm->hw->wiphy->bands[i]->n_bitrates) - 1;
3598 req->wdev = ieee80211_vif_to_wdev(vif);
3599 req->wiphy = mvm->hw->wiphy;
3600 req->scan_start = jiffies;
3601 req->tsf_report_link_id = -1;
3618 lockdep_assert_held(&mvm->mutex);
3620 if (mvm->scan_status & IWL_MVM_SCAN_INT_MLO) {
3622 return -EBUSY;
3629 rcu_dereference(vif->link_conf[link_id]);
3634 channels[n_channels++] = link_conf->chanreq.oper.chan;
3640 return -EINVAL;
3646 enum nl80211_band band,
3649 struct ieee80211_supported_band *sband = mvm->hw->wiphy->bands[band];
3653 return -EINVAL;
3655 for (chan_idx = 0; chan_idx < sband->n_channels; chan_idx++) {
3656 struct ieee80211_channel *channel = &sband->channels[chan_idx];
3658 if (channel->hw_value == phy_chan_num)
3662 return -EINVAL;
3669 * at 10 dB and looping instead of using a much larger table.
3682 value = (((u64)value) * db_to_val[change - 1]) >> 32;
3684 db -= change;
3695 s8 sum_magnitude = -128;
3701 * we need to do the math in linear space. Doing a linear average of
3702 * dB (dBm) values is a bit annoying though due to the large range of
3703 * at least -10 to -110 dBm that will not fit into a 32 bit integer.
3709 * So, lets not deal with that and instead do much of the calculation
3711 * gives us plenty of head-room for adding up a few values and even
3713 * (1/2^16 is somewhere around -48 dB, so effectively zero).
3715 * i.e. the real value of sum is:
3725 for (i = 0; i < ARRAY_SIZE(notif->noise); i++) {
3729 if (notif->noise[i] == 0xff)
3733 val_magnitude = -notif->noise[i];
3736 u8 div_db = sum_magnitude - val_magnitude;
3741 u8 div_db = val_magnitude - sum_magnitude;
3761 * average_factor is between -0.5 dB and 0.5 dB.
3763 * Just do -1 dB steps and find the point where
3764 * -0.5 dB * -i dB = 0x10000 * 10^(-0.5/10) / i dB
3772 return average_magnitude - i;
3781 (void *)pkt->data;
3783 enum nl80211_band band;
3786 lockdep_assert_held(&mvm->mutex);
3788 if (!mvm->acs_survey) {
3791 for (band = 0; band < NUM_NL80211_BANDS; band++) {
3792 if (!mvm->hw->wiphy->bands[band])
3795 n_channels += mvm->hw->wiphy->bands[band]->n_channels;
3798 mvm->acs_survey = kzalloc(struct_size(mvm->acs_survey,
3802 if (!mvm->acs_survey)
3805 mvm->acs_survey->n_channels = n_channels;
3807 for (band = 0; band < NUM_NL80211_BANDS; band++) {
3808 if (!mvm->hw->wiphy->bands[band])
3811 mvm->acs_survey->bands[band] =
3812 &mvm->acs_survey->channels[n_channels];
3813 n_channels += mvm->hw->wiphy->bands[band]->n_channels;
3817 band = iwl_mvm_nl80211_band_from_phy(le32_to_cpu(notif->band));
3818 chan_idx = iwl_mvm_chanidx_from_phy(mvm, band,
3819 le32_to_cpu(notif->channel));
3824 mvm->hw->wiphy->bands[band]->channels[chan_idx].center_freq);
3826 info = &mvm->acs_survey->bands[band][chan_idx];
3829 info->time = le32_to_cpu(notif->active_time);
3830 info->time_busy = le32_to_cpu(notif->busy_time);
3831 info->time_rx = le32_to_cpu(notif->rx_time);
3832 info->time_tx = le32_to_cpu(notif->tx_time);
3833 info->noise = iwl_mvm_average_dbm_values(notif);