Lines Matching +full:scan +full:- +full:interval +full:- +full:ms

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2024-2025 Intel Corporation
7 #include "iwl-utils.h"
10 #include "scan.h"
16 #include "fw/api/scan.h"
23 /* adaptive dwell max budget time [TU] for full scan */
26 /* adaptive dwell max budget time [TU] for directed scan */
52 /* minimal number of 2GHz and 5GHz channels in the regular scan request */
130 if (vif == data->current_vif) in iwl_mld_scan_respect_p2p_go_iter()
135 iwl_mld_vif_from_mac80211(vif)->ap_ibss_active) in iwl_mld_scan_respect_p2p_go_iter()
136 data->p2p_go = true; in iwl_mld_scan_respect_p2p_go_iter()
151 ieee80211_iterate_active_interfaces_mtx(mld->hw, in iwl_mld_get_respect_p2p_go()
170 struct ieee80211_vif *curr_vif = data->current_vif; in iwl_mld_scan_iterator()
176 data->global_low_latency |= iwl_mld_vif_low_latency(mld_vif); in iwl_mld_scan_iterator()
178 if ((ieee80211_vif_is_mld(vif) && vif->active_links) || in iwl_mld_scan_iterator()
179 (vif->type != NL80211_IFTYPE_P2P_DEVICE && in iwl_mld_scan_iterator()
180 mld_vif->deflink.active)) in iwl_mld_scan_iterator()
181 data->active_vif = true; in iwl_mld_scan_iterator()
193 ieee80211_vif_is_mld(curr_vif) ? curr_vif->active_links : 1; in iwl_mld_scan_iterator()
205 if (rcu_access_pointer(curr_mld_link->chan_ctx) && in iwl_mld_scan_iterator()
206 rcu_access_pointer(mld_vif->deflink.chan_ctx) != in iwl_mld_scan_iterator()
207 rcu_access_pointer(curr_mld_link->chan_ctx)) { in iwl_mld_scan_iterator()
208 data->is_dcm_with_p2p_go = true; in iwl_mld_scan_iterator()
219 enum iwl_mld_traffic_load load = mld->scan.traffic_load.status; in iwl_mld_get_scan_type()
223 * Force a non-fragmented scan in that case. in iwl_mld_get_scan_type()
228 if (!data->active_vif) in iwl_mld_get_scan_type()
231 if ((load == IWL_MLD_TRAFFIC_HIGH || data->global_low_latency) && in iwl_mld_get_scan_type()
232 vif->type != NL80211_IFTYPE_P2P_DEVICE) in iwl_mld_get_scan_type()
235 /* In case of DCM with P2P GO set all scan requests as in iwl_mld_get_scan_type()
236 * fast-balance scan in iwl_mld_get_scan_type()
238 if (vif->type == NL80211_IFTYPE_STATION && in iwl_mld_get_scan_type()
239 data->is_dcm_with_p2p_go) in iwl_mld_get_scan_type()
242 if (load >= IWL_MLD_TRAFFIC_MEDIUM || data->global_low_latency) in iwl_mld_get_scan_type()
274 memcpy(newpos, ies + offs, len - offs); in iwl_mld_scan_add_2ghz_elems()
275 newpos += len - offs; in iwl_mld_scan_add_2ghz_elems()
284 pos[1] = WFA_TPC_IE_LEN - 2; in iwl_mld_scan_add_tpc_report_elem()
290 /* pos[7] - tx power will be inserted by the FW */ in iwl_mld_scan_add_tpc_report_elem()
309 return params->n_scan_plans == 1 && in iwl_mld_scan_is_regular()
310 params->scan_plans[0].iterations == 1; in iwl_mld_scan_is_regular()
323 for (int i = 0; i < ARRAY_SIZE(mld->scan.uid_status); i++) in iwl_mld_scan_uid_by_status()
324 if (mld->scan.uid_status[i] == status) in iwl_mld_scan_uid_by_status()
327 return -ENOENT; in iwl_mld_scan_uid_by_status()
350 return -1; in iwl_mld_scan_ssid_exist()
356 return -1; in iwl_mld_scan_ssid_exist()
364 (n_channels <= mld->fw->ucode_capa.n_scan_channels) && in iwl_mld_scan_fits()
365 (ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + in iwl_mld_scan_fits()
366 ies->len[NL80211_BAND_5GHZ] + ies->len[NL80211_BAND_6GHZ] <= in iwl_mld_scan_fits()
375 struct ieee80211_mgmt *frame = (void *)params->preq.buf; in iwl_mld_scan_build_probe_req()
377 const u8 *mac_addr = params->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? in iwl_mld_scan_build_probe_req()
378 params->mac_addr : NULL; in iwl_mld_scan_build_probe_req()
381 get_random_mask_addr(frame->sa, mac_addr, in iwl_mld_scan_build_probe_req()
382 params->mac_addr_mask); in iwl_mld_scan_build_probe_req()
384 memcpy(frame->sa, vif->addr, ETH_ALEN); in iwl_mld_scan_build_probe_req()
386 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); in iwl_mld_scan_build_probe_req()
387 eth_broadcast_addr(frame->da); in iwl_mld_scan_build_probe_req()
388 ether_addr_copy(frame->bssid, params->bssid); in iwl_mld_scan_build_probe_req()
389 frame->seq_ctrl = 0; in iwl_mld_scan_build_probe_req()
391 pos = frame->u.probe_req.variable; in iwl_mld_scan_build_probe_req()
395 params->preq.mac_header.offset = 0; in iwl_mld_scan_build_probe_req()
396 params->preq.mac_header.len = cpu_to_le16(24 + 2); in iwl_mld_scan_build_probe_req()
400 ies->ies[NL80211_BAND_2GHZ], in iwl_mld_scan_build_probe_req()
401 ies->len[NL80211_BAND_2GHZ], in iwl_mld_scan_build_probe_req()
403 params->preq.band_data[0].offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
404 params->preq.band_data[0].len = cpu_to_le16(newpos - pos); in iwl_mld_scan_build_probe_req()
407 memcpy(pos, ies->ies[NL80211_BAND_5GHZ], in iwl_mld_scan_build_probe_req()
408 ies->len[NL80211_BAND_5GHZ]); in iwl_mld_scan_build_probe_req()
409 params->preq.band_data[1].offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
410 params->preq.band_data[1].len = in iwl_mld_scan_build_probe_req()
411 cpu_to_le16(ies->len[NL80211_BAND_5GHZ]); in iwl_mld_scan_build_probe_req()
412 pos += ies->len[NL80211_BAND_5GHZ]; in iwl_mld_scan_build_probe_req()
414 memcpy(pos, ies->ies[NL80211_BAND_6GHZ], in iwl_mld_scan_build_probe_req()
415 ies->len[NL80211_BAND_6GHZ]); in iwl_mld_scan_build_probe_req()
416 params->preq.band_data[2].offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
417 params->preq.band_data[2].len = in iwl_mld_scan_build_probe_req()
418 cpu_to_le16(ies->len[NL80211_BAND_6GHZ]); in iwl_mld_scan_build_probe_req()
419 pos += ies->len[NL80211_BAND_6GHZ]; in iwl_mld_scan_build_probe_req()
421 memcpy(pos, ies->common_ies, ies->common_ie_len); in iwl_mld_scan_build_probe_req()
422 params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
424 iwl_mld_scan_add_tpc_report_elem(pos + ies->common_ie_len); in iwl_mld_scan_build_probe_req()
425 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len + in iwl_mld_scan_build_probe_req()
437 /* If no direct SSIDs are provided perform a passive scan. Otherwise, in iwl_mld_scan_get_cmd_gen_flags()
439 * that the scan is intended for roaming purposes and thus enable Rx on in iwl_mld_scan_get_cmd_gen_flags()
442 if (params->n_ssids == 0) in iwl_mld_scan_get_cmd_gen_flags()
444 else if (params->n_ssids == 1 && params->ssids[0].ssid_len) in iwl_mld_scan_get_cmd_gen_flags()
447 if (params->pass_all) in iwl_mld_scan_get_cmd_gen_flags()
452 if (iwl_mld_scan_is_fragmented(params->type)) in iwl_mld_scan_get_cmd_gen_flags()
458 if (params->iter_notif || in iwl_mld_scan_get_cmd_gen_flags()
459 mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_ENABLED) in iwl_mld_scan_get_cmd_gen_flags()
466 if (params->flags & (NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP | in iwl_mld_scan_get_cmd_gen_flags()
473 params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) in iwl_mld_scan_get_cmd_gen_flags()
476 if (params->enable_6ghz_passive) in iwl_mld_scan_get_cmd_gen_flags()
494 if (params->respect_p2p_go) in iwl_mld_scan_get_cmd_gen_flags2()
498 if (params->scan_6ghz) in iwl_mld_scan_get_cmd_gen_flags2()
502 * it is supported. For non-AP interfaces, EBS will be enabled and in iwl_mld_scan_get_cmd_gen_flags2()
508 iwl_fw_lookup_notif_ver(mld->fw, SCAN_GROUP, in iwl_mld_scan_get_cmd_gen_flags2()
521 &scan_timing[params->type]; in iwl_mld_scan_cmd_set_dwell()
523 gp->adwell_default_social_chn = in iwl_mld_scan_cmd_set_dwell()
525 gp->adwell_default_2g = IWL_SCAN_ADWELL_DEFAULT_LB_N_APS; in iwl_mld_scan_cmd_set_dwell()
526 gp->adwell_default_5g = IWL_SCAN_ADWELL_DEFAULT_HB_N_APS; in iwl_mld_scan_cmd_set_dwell()
528 if (params->n_ssids && params->ssids[0].ssid_len) in iwl_mld_scan_cmd_set_dwell()
529 gp->adwell_max_budget = in iwl_mld_scan_cmd_set_dwell()
532 gp->adwell_max_budget = in iwl_mld_scan_cmd_set_dwell()
535 gp->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); in iwl_mld_scan_cmd_set_dwell()
537 gp->max_out_of_time[SCAN_LB_LMAC_IDX] = cpu_to_le32(timing->max_out_time); in iwl_mld_scan_cmd_set_dwell()
538 gp->suspend_time[SCAN_LB_LMAC_IDX] = cpu_to_le32(timing->suspend_time); in iwl_mld_scan_cmd_set_dwell()
540 gp->active_dwell[SCAN_LB_LMAC_IDX] = IWL_SCAN_DWELL_ACTIVE; in iwl_mld_scan_cmd_set_dwell()
541 gp->passive_dwell[SCAN_LB_LMAC_IDX] = IWL_SCAN_DWELL_PASSIVE; in iwl_mld_scan_cmd_set_dwell()
542 gp->active_dwell[SCAN_HB_LMAC_IDX] = IWL_SCAN_DWELL_ACTIVE; in iwl_mld_scan_cmd_set_dwell()
543 gp->passive_dwell[SCAN_HB_LMAC_IDX] = IWL_SCAN_DWELL_PASSIVE; in iwl_mld_scan_cmd_set_dwell()
546 "Scan: adwell_max_budget=%d max_out_of_time=%d suspend_time=%d\n", in iwl_mld_scan_cmd_set_dwell()
547 gp->adwell_max_budget, in iwl_mld_scan_cmd_set_dwell()
548 gp->max_out_of_time[SCAN_LB_LMAC_IDX], in iwl_mld_scan_cmd_set_dwell()
549 gp->suspend_time[SCAN_LB_LMAC_IDX]); in iwl_mld_scan_cmd_set_dwell()
568 gp->flags = cpu_to_le16(gen_flags); in iwl_mld_scan_cmd_set_gen_params()
569 gp->flags2 = gen_flags2; in iwl_mld_scan_cmd_set_gen_params()
574 gp->num_of_fragments[SCAN_LB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS; in iwl_mld_scan_cmd_set_gen_params()
576 if (params->fw_link_id != IWL_MLD_INVALID_FW_ID) in iwl_mld_scan_cmd_set_gen_params()
577 gp->scan_start_mac_or_link_id = params->fw_link_id; in iwl_mld_scan_cmd_set_gen_params()
585 if (WARN_ON(!params->n_scan_plans || in iwl_mld_scan_cmd_set_sched_params()
586 params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS)) in iwl_mld_scan_cmd_set_sched_params()
587 return -EINVAL; in iwl_mld_scan_cmd_set_sched_params()
589 for (int i = 0; i < params->n_scan_plans; i++) { in iwl_mld_scan_cmd_set_sched_params()
591 &params->scan_plans[i]; in iwl_mld_scan_cmd_set_sched_params()
593 schedule[i].iter_count = scan_plan->iterations; in iwl_mld_scan_cmd_set_sched_params()
594 schedule[i].interval = in iwl_mld_scan_cmd_set_sched_params()
595 cpu_to_le16(scan_plan->interval); in iwl_mld_scan_cmd_set_sched_params()
598 /* If the number of iterations of the last scan plan is set to zero, in iwl_mld_scan_cmd_set_sched_params()
600 * For example, when regular scan is requested the driver sets one scan in iwl_mld_scan_cmd_set_sched_params()
603 if (!schedule[params->n_scan_plans - 1].iter_count) in iwl_mld_scan_cmd_set_sched_params()
604 schedule[params->n_scan_plans - 1].iter_count = 0xff; in iwl_mld_scan_cmd_set_sched_params()
606 *delay = cpu_to_le16(params->delay); in iwl_mld_scan_cmd_set_sched_params()
625 for (i = 0, j = params->n_match_sets - 1; in iwl_mld_scan_cmd_build_ssids()
627 i++, j--) { in iwl_mld_scan_cmd_build_ssids()
629 if (!params->match_sets[j].ssid.ssid_len) in iwl_mld_scan_cmd_build_ssids()
633 ssids[i].len = params->match_sets[j].ssid.ssid_len; in iwl_mld_scan_cmd_build_ssids()
634 memcpy(ssids[i].ssid, params->match_sets[j].ssid.ssid, in iwl_mld_scan_cmd_build_ssids()
638 /* add SSIDs from scan SSID list */ in iwl_mld_scan_cmd_build_ssids()
639 for (j = params->n_ssids - 1; in iwl_mld_scan_cmd_build_ssids()
641 i++, j--) { in iwl_mld_scan_cmd_build_ssids()
642 index = iwl_mld_scan_ssid_exist(params->ssids[j].ssid, in iwl_mld_scan_cmd_build_ssids()
643 params->ssids[j].ssid_len, in iwl_mld_scan_cmd_build_ssids()
647 ssids[i].len = params->ssids[j].ssid_len; in iwl_mld_scan_cmd_build_ssids()
648 memcpy(ssids[i].ssid, params->ssids[j].ssid, in iwl_mld_scan_cmd_build_ssids()
666 params->scan_6ghz_params; in iwl_mld_scan_fill_6g_chan_list()
669 j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE; in iwl_mld_scan_fill_6g_chan_list()
671 if (!params->ssids[j].ssid_len) in iwl_mld_scan_fill_6g_chan_list()
674 pp->short_ssid[idex_s] = in iwl_mld_scan_fill_6g_chan_list()
675 cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid, in iwl_mld_scan_fill_6g_chan_list()
676 params->ssids[j].ssid_len)); in iwl_mld_scan_fill_6g_chan_list()
678 /* hidden 6ghz scan */ in iwl_mld_scan_fill_6g_chan_list()
679 pp->direct_scan[idex_s].id = WLAN_EID_SSID; in iwl_mld_scan_fill_6g_chan_list()
680 pp->direct_scan[idex_s].len = params->ssids[j].ssid_len; in iwl_mld_scan_fill_6g_chan_list()
681 memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid, in iwl_mld_scan_fill_6g_chan_list()
682 params->ssids[j].ssid_len); in iwl_mld_scan_fill_6g_chan_list()
691 for (j = 0; j < params->n_6ghz_params; j++) { in iwl_mld_scan_fill_6g_chan_list()
697 if (pp->short_ssid[k] == in iwl_mld_scan_fill_6g_chan_list()
703 pp->short_ssid[idex_s++] = in iwl_mld_scan_fill_6g_chan_list()
710 if (!memcmp(&pp->bssid_array[k], in iwl_mld_scan_fill_6g_chan_list()
717 "scan: invalid BSSID at index %u, index_b=%u\n", in iwl_mld_scan_fill_6g_chan_list()
719 memcpy(&pp->bssid_array[idex_b++], in iwl_mld_scan_fill_6g_chan_list()
724 pp->short_ssid_num = idex_s; in iwl_mld_scan_fill_6g_chan_list()
725 pp->bssid_num = idex_b; in iwl_mld_scan_fill_6g_chan_list()
733 pp->preq = params->preq; in iwl_mld_scan_cmd_set_probe_params()
735 if (params->scan_6ghz) { in iwl_mld_scan_cmd_set_probe_params()
740 /* relevant only for 2.4 GHz /5 GHz scan */ in iwl_mld_scan_cmd_set_probe_params()
741 iwl_mld_scan_cmd_build_ssids(params, pp->direct_scan, bitmap_ssid); in iwl_mld_scan_cmd_set_probe_params()
748 const struct iwl_ucode_capabilities *capa = &mld->fw->ucode_capa; in iwl_mld_scan_use_ebs()
756 * 5. the VIF is not an AP interface (scan wants survey results) in iwl_mld_scan_use_ebs()
758 return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) && in iwl_mld_scan_use_ebs()
759 !mld->scan.last_ebs_failed && in iwl_mld_scan_use_ebs()
760 vif->type != NL80211_IFTYPE_P2P_DEVICE && in iwl_mld_scan_use_ebs()
780 /* set fragmented ebs for fragmented scan */ in iwl_mld_scan_cmd_set_chan_flags()
781 if (iwl_mld_scan_is_fragmented(params->type)) in iwl_mld_scan_cmd_set_chan_flags()
784 /* Force EBS in case the scan is a fragmented and there is a need in iwl_mld_scan_cmd_set_chan_flags()
785 * to take P2P GO operation into consideration during scan operation. in iwl_mld_scan_cmd_set_chan_flags()
788 if (iwl_mld_scan_is_fragmented(params->type) && in iwl_mld_scan_cmd_set_chan_flags()
789 params->respect_p2p_go) { in iwl_mld_scan_cmd_set_chan_flags()
831 enum nl80211_band band = channels[i]->band; in iwl_mld_scan_cmd_set_channels()
832 struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i]; in iwl_mld_scan_cmd_set_channels()
836 channels[i]->hw_value); in iwl_mld_scan_cmd_set_channels()
841 cfg->flags = cpu_to_le32(flags | n_aps_flag); in iwl_mld_scan_cmd_set_channels()
842 cfg->channel_num = channels[i]->hw_value; in iwl_mld_scan_cmd_set_channels()
844 cfg->flags = 0; in iwl_mld_scan_cmd_set_channels()
847 /* 6 GHz channels should only appear in a scan request in iwl_mld_scan_cmd_set_channels()
849 * scan, which has to be passive. in iwl_mld_scan_cmd_set_channels()
851 WARN_ON_ONCE(cfg->flags != 0); in iwl_mld_scan_cmd_set_channels()
852 cfg->flags = in iwl_mld_scan_cmd_set_channels()
856 cfg->v2.iter_count = 1; in iwl_mld_scan_cmd_set_channels()
857 cfg->v2.iter_interval = 0; in iwl_mld_scan_cmd_set_channels()
858 cfg->flags |= cpu_to_le32(iwl_band << in iwl_mld_scan_cmd_set_channels()
872 params->scan_6ghz_params; in iwl_mld_scan_cfg_channels_6g()
876 for (i = 0, ch_cnt = 0; i < params->n_channels; i++) { in iwl_mld_scan_cfg_channels_6g()
878 &cp->channel_config[ch_cnt]; in iwl_mld_scan_cfg_channels_6g()
887 /* Avoid performing passive scan on non PSC channels unless the in iwl_mld_scan_cfg_channels_6g()
888 * scan is specifically a passive scan, i.e., no SSIDs in iwl_mld_scan_cfg_channels_6g()
889 * configured in the scan command. in iwl_mld_scan_cfg_channels_6g()
891 if (!cfg80211_channel_is_psc(params->channels[i]) && in iwl_mld_scan_cfg_channels_6g()
892 !params->n_6ghz_params && params->n_ssids) in iwl_mld_scan_cfg_channels_6g()
895 cfg->channel_num = params->channels[i]->hw_value; in iwl_mld_scan_cfg_channels_6g()
896 cfg->flags |= in iwl_mld_scan_cfg_channels_6g()
899 cfg->v5.iter_count = 1; in iwl_mld_scan_cfg_channels_6g()
900 cfg->v5.iter_interval = 0; in iwl_mld_scan_cfg_channels_6g()
902 for (u32 j = 0; j < params->n_6ghz_params; j++) { in iwl_mld_scan_cfg_channels_6g()
925 /* In the following cases apply passive scan: in iwl_mld_scan_cfg_channels_6g()
926 * 1. Non fragmented scan: in iwl_mld_scan_cfg_channels_6g()
927 * - PSC channel with NO_LISTEN_FLAG on should be treated in iwl_mld_scan_cfg_channels_6g()
929 * - Non PSC channel with more than 3 short SSIDs or more in iwl_mld_scan_cfg_channels_6g()
931 * - Non PSC Channel with unsolicited probe response and in iwl_mld_scan_cfg_channels_6g()
933 * - PSC channel with more than 2 short SSIDs or more than in iwl_mld_scan_cfg_channels_6g()
935 * 2. Fragmented scan: in iwl_mld_scan_cfg_channels_6g()
936 * - PSC channel with more than 1 SSID or 3 BSSIDs. in iwl_mld_scan_cfg_channels_6g()
937 * - Non PSC channel with more than 2 SSIDs or 6 BSSIDs. in iwl_mld_scan_cfg_channels_6g()
938 * - Non PSC channel with unsolicited probe response and in iwl_mld_scan_cfg_channels_6g()
941 if (!iwl_mld_scan_is_fragmented(params->type)) { in iwl_mld_scan_cfg_channels_6g()
942 if (!cfg80211_channel_is_psc(params->channels[i]) || in iwl_mld_scan_cfg_channels_6g()
955 } else if (cfg80211_channel_is_psc(params->channels[i])) { in iwl_mld_scan_cfg_channels_6g()
968 /* To optimize the scan time, i.e., reduce the scan dwell time in iwl_mld_scan_cfg_channels_6g()
973 for (u32 j = 0; j < params->n_6ghz_params; j++) { in iwl_mld_scan_cfg_channels_6g()
980 k < pp->short_ssid_num && n_s_ssids < max_s_ssids; in iwl_mld_scan_cfg_channels_6g()
983 le32_to_cpu(pp->short_ssid[k]) == in iwl_mld_scan_cfg_channels_6g()
999 !pp->direct_scan[k].len) in iwl_mld_scan_cfg_channels_6g()
1002 /* Hidden AP, cannot do passive scan */ in iwl_mld_scan_cfg_channels_6g()
1003 if (pp->direct_scan[k].len) in iwl_mld_scan_cfg_channels_6g()
1016 for (k = 0; k < pp->bssid_num; k++) { in iwl_mld_scan_cfg_channels_6g()
1017 if (memcmp(&pp->bssid_array[k], in iwl_mld_scan_cfg_channels_6g()
1036 if (cfg80211_channel_is_psc(params->channels[i]) && in iwl_mld_scan_cfg_channels_6g()
1045 !cfg80211_channel_is_psc(params->channels[i]))) in iwl_mld_scan_cfg_channels_6g()
1050 cfg->flags |= cpu_to_le32(flags); in iwl_mld_scan_cfg_channels_6g()
1051 cfg->v5.psd_20 = psd_20; in iwl_mld_scan_cfg_channels_6g()
1056 if (params->n_channels > ch_cnt) in iwl_mld_scan_cfg_channels_6g()
1058 "6GHz: reducing number channels: (%u->%u)\n", in iwl_mld_scan_cfg_channels_6g()
1059 params->n_channels, ch_cnt); in iwl_mld_scan_cfg_channels_6g()
1071 struct iwl_scan_channel_params_v7 *chan_p = &scan_p->channel_params; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1072 struct iwl_scan_probe_params_v4 *probe_p = &scan_p->probe_params; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1074 chan_p->flags = iwl_mld_scan_get_cmd_gen_flags(mld, params, vif, in iwl_mld_scan_cmd_set_6ghz_chan_params()
1076 chan_p->count = iwl_mld_scan_cfg_channels_6g(mld, params, in iwl_mld_scan_cmd_set_6ghz_chan_params()
1077 params->n_channels, in iwl_mld_scan_cmd_set_6ghz_chan_params()
1079 vif->type); in iwl_mld_scan_cmd_set_6ghz_chan_params()
1080 if (!chan_p->count) in iwl_mld_scan_cmd_set_6ghz_chan_params()
1081 return -EINVAL; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1083 if (!params->n_ssids || in iwl_mld_scan_cmd_set_6ghz_chan_params()
1084 (params->n_ssids == 1 && !params->ssids[0].ssid_len)) in iwl_mld_scan_cmd_set_6ghz_chan_params()
1085 chan_p->flags |= IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1099 struct iwl_scan_channel_params_v7 *cp = &scan_p->channel_params; in iwl_mld_scan_cmd_set_chan_params()
1101 &mld->nvm_data->bands[NL80211_BAND_6GHZ]; in iwl_mld_scan_cmd_set_chan_params()
1103 cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY; in iwl_mld_scan_cmd_set_chan_params()
1104 cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS; in iwl_mld_scan_cmd_set_chan_params()
1107 cp->n_aps_override[0] = IWL_MLD_ADAPTIVE_DWELL_NUM_APS_OVERRIDE; in iwl_mld_scan_cmd_set_chan_params()
1109 if (params->scan_6ghz) in iwl_mld_scan_cmd_set_chan_params()
1114 /* relevant only for 2.4 GHz/5 GHz scan */ in iwl_mld_scan_cmd_set_chan_params()
1115 cp->flags = iwl_mld_scan_cmd_set_chan_flags(mld, params, vif, in iwl_mld_scan_cmd_set_chan_params()
1117 cp->count = params->n_channels; in iwl_mld_scan_cmd_set_chan_params()
1119 iwl_mld_scan_cmd_set_channels(mld, params->channels, cp, in iwl_mld_scan_cmd_set_chan_params()
1120 params->n_channels, channel_cfg_flags, in iwl_mld_scan_cmd_set_chan_params()
1121 vif->type); in iwl_mld_scan_cmd_set_chan_params()
1123 if (!params->enable_6ghz_passive) in iwl_mld_scan_cmd_set_chan_params()
1126 /* fill 6 GHz passive scan cfg */ in iwl_mld_scan_cmd_set_chan_params()
1127 for (int i = 0; i < sband->n_channels; i++) { in iwl_mld_scan_cmd_set_chan_params()
1129 &sband->channels[i]; in iwl_mld_scan_cmd_set_chan_params()
1131 &cp->channel_config[cp->count]; in iwl_mld_scan_cmd_set_chan_params()
1136 cfg->channel_num = channel->hw_value; in iwl_mld_scan_cmd_set_chan_params()
1137 cfg->v5.iter_count = 1; in iwl_mld_scan_cmd_set_chan_params()
1138 cfg->v5.iter_interval = 0; in iwl_mld_scan_cmd_set_chan_params()
1139 cfg->v5.psd_20 = in iwl_mld_scan_cmd_set_chan_params()
1141 cfg->flags = cpu_to_le32(PHY_BAND_6 << in iwl_mld_scan_cmd_set_chan_params()
1143 cp->count++; in iwl_mld_scan_cmd_set_chan_params()
1155 struct iwl_scan_req_umac_v17 *cmd = mld->scan.cmd; in iwl_mld_scan_build_cmd()
1156 struct iwl_scan_req_params_v17 *scan_p = &cmd->scan_params; in iwl_mld_scan_build_cmd()
1160 memset(mld->scan.cmd, 0, mld->scan.cmd_size); in iwl_mld_scan_build_cmd()
1167 cmd->uid = cpu_to_le32(uid); in iwl_mld_scan_build_cmd()
1168 cmd->ooc_priority = in iwl_mld_scan_build_cmd()
1172 &scan_p->general_params, scan_status); in iwl_mld_scan_build_cmd()
1175 scan_p->periodic_params.schedule, in iwl_mld_scan_build_cmd()
1176 &scan_p->periodic_params.delay); in iwl_mld_scan_build_cmd()
1180 iwl_mld_scan_cmd_set_probe_params(params, &scan_p->probe_params, in iwl_mld_scan_build_cmd()
1196 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { in iwl_mld_scan_pass_all()
1198 "Sending scheduled scan with filtering, n_match_sets %d\n", in iwl_mld_scan_pass_all()
1199 req->n_match_sets); in iwl_mld_scan_pass_all()
1200 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_scan_pass_all()
1204 IWL_DEBUG_SCAN(mld, "Sending Scheduled scan without filtering\n"); in iwl_mld_scan_pass_all()
1205 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_ENABLED; in iwl_mld_scan_pass_all()
1227 if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES_V2)) in iwl_mld_config_sched_scan_profiles()
1228 return -EIO; in iwl_mld_config_sched_scan_profiles()
1232 return -ENOMEM; in iwl_mld_config_sched_scan_profiles()
1241 cfg_data = &profile_cfg->data; in iwl_mld_config_sched_scan_profiles()
1242 cfg_data->num_profiles = req->n_match_sets; in iwl_mld_config_sched_scan_profiles()
1243 cfg_data->active_clients = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1244 cfg_data->pass_match = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1245 cfg_data->match_notify = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1247 if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) in iwl_mld_config_sched_scan_profiles()
1248 cfg_data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1250 for (int i = 0; i < req->n_match_sets; i++) { in iwl_mld_config_sched_scan_profiles()
1251 profile = &profile_cfg->profiles[i]; in iwl_mld_config_sched_scan_profiles()
1254 profile->unicast_cipher = 0xff; in iwl_mld_config_sched_scan_profiles()
1255 profile->auth_alg = IWL_AUTH_ALGO_UNSUPPORTED | in iwl_mld_config_sched_scan_profiles()
1259 profile->network_type = IWL_NETWORK_TYPE_ANY; in iwl_mld_config_sched_scan_profiles()
1260 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY; in iwl_mld_config_sched_scan_profiles()
1261 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1262 profile->ssid_index = i; in iwl_mld_config_sched_scan_profiles()
1266 "Sending scheduled scan profile config (n_match_sets=%u)\n", in iwl_mld_config_sched_scan_profiles()
1267 req->n_match_sets); in iwl_mld_config_sched_scan_profiles()
1284 for (i = 0; i < params->n_channels; i++) { in iwl_mld_sched_scan_handle_non_psc_channels()
1285 struct ieee80211_channel *channel = params->channels[i]; in iwl_mld_sched_scan_handle_non_psc_channels()
1287 if (channel->band == NL80211_BAND_6GHZ && in iwl_mld_sched_scan_handle_non_psc_channels()
1297 params->channels = in iwl_mld_sched_scan_handle_non_psc_channels()
1298 kmemdup(params->channels, in iwl_mld_sched_scan_handle_non_psc_channels()
1299 sizeof(params->channels[0]) * params->n_channels, in iwl_mld_sched_scan_handle_non_psc_channels()
1301 if (!params->channels) in iwl_mld_sched_scan_handle_non_psc_channels()
1302 return -ENOMEM; in iwl_mld_sched_scan_handle_non_psc_channels()
1304 for (i = j = 0; i < params->n_channels; i++) { in iwl_mld_sched_scan_handle_non_psc_channels()
1305 if (params->channels[i]->band == NL80211_BAND_6GHZ && in iwl_mld_sched_scan_handle_non_psc_channels()
1306 !cfg80211_channel_is_psc(params->channels[i])) in iwl_mld_sched_scan_handle_non_psc_channels()
1308 params->channels[j++] = params->channels[i]; in iwl_mld_sched_scan_handle_non_psc_channels()
1311 params->n_channels = j; in iwl_mld_sched_scan_handle_non_psc_channels()
1322 &mld->nvm_data->bands[NL80211_BAND_6GHZ]; in iwl_mld_scan_6ghz_passive_scan()
1325 params->enable_6ghz_passive = false; in iwl_mld_scan_6ghz_passive_scan()
1327 /* 6 GHz passive scan may be enabled in the first 2.4 GHz/5 GHz scan in iwl_mld_scan_6ghz_passive_scan()
1329 * we're in the 6 GHz scan phase. in iwl_mld_scan_6ghz_passive_scan()
1331 if (params->scan_6ghz) in iwl_mld_scan_6ghz_passive_scan()
1334 /* 6 GHz passive scan allowed only on station interface */ in iwl_mld_scan_6ghz_passive_scan()
1335 if (vif->type != NL80211_IFTYPE_STATION) { in iwl_mld_scan_6ghz_passive_scan()
1337 "6GHz passive scan: not station interface\n"); in iwl_mld_scan_6ghz_passive_scan()
1341 /* 6 GHz passive scan is allowed in a defined time interval following in iwl_mld_scan_6ghz_passive_scan()
1343 * interval has passed since the last 6 GHz passive scan. in iwl_mld_scan_6ghz_passive_scan()
1345 if ((vif->cfg.assoc || in iwl_mld_scan_6ghz_passive_scan()
1346 time_after(mld->scan.last_6ghz_passive_jiffies + in iwl_mld_scan_6ghz_passive_scan()
1348 (time_before(mld->scan.last_start_time_jiffies + in iwl_mld_scan_6ghz_passive_scan()
1351 IWL_DEBUG_SCAN(mld, "6GHz passive scan: %s\n", in iwl_mld_scan_6ghz_passive_scan()
1352 vif->cfg.assoc ? "associated" : in iwl_mld_scan_6ghz_passive_scan()
1357 /* not enough channels in the regular scan request */ in iwl_mld_scan_6ghz_passive_scan()
1358 if (params->n_channels < IWL_MLD_6GHZ_PASSIVE_SCAN_MIN_CHANS) { in iwl_mld_scan_6ghz_passive_scan()
1360 "6GHz passive scan: not enough channels %d\n", in iwl_mld_scan_6ghz_passive_scan()
1361 params->n_channels); in iwl_mld_scan_6ghz_passive_scan()
1365 for (i = 0; i < params->n_ssids; i++) { in iwl_mld_scan_6ghz_passive_scan()
1366 if (!params->ssids[i].ssid_len) in iwl_mld_scan_6ghz_passive_scan()
1370 /* not a wildcard scan, so cannot enable passive 6 GHz scan */ in iwl_mld_scan_6ghz_passive_scan()
1371 if (i == params->n_ssids) { in iwl_mld_scan_6ghz_passive_scan()
1373 "6GHz passive scan: no wildcard SSID\n"); in iwl_mld_scan_6ghz_passive_scan()
1377 if (!sband || !sband->n_channels) { in iwl_mld_scan_6ghz_passive_scan()
1379 "6GHz passive scan: no 6GHz channels\n"); in iwl_mld_scan_6ghz_passive_scan()
1383 for (i = 0, n_disabled = 0; i < sband->n_channels; i++) { in iwl_mld_scan_6ghz_passive_scan()
1384 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED)) in iwl_mld_scan_6ghz_passive_scan()
1389 * passive scan in iwl_mld_scan_6ghz_passive_scan()
1391 if (n_disabled != sband->n_channels) { in iwl_mld_scan_6ghz_passive_scan()
1393 "6GHz passive scan: 6GHz channels enabled\n"); in iwl_mld_scan_6ghz_passive_scan()
1397 /* all conditions to enable 6 GHz passive scan are satisfied */ in iwl_mld_scan_6ghz_passive_scan()
1398 IWL_DEBUG_SCAN(mld, "6GHz passive scan: can be enabled\n"); in iwl_mld_scan_6ghz_passive_scan()
1399 params->enable_6ghz_passive = true; in iwl_mld_scan_6ghz_passive_scan()
1412 if (vif->active_links) in iwl_mld_scan_set_link_id()
1413 tsf_report_link_id = __ffs(vif->active_links); in iwl_mld_scan_set_link_id()
1420 params->fw_link_id = link->fw_id; in iwl_mld_scan_set_link_id()
1421 /* we to store fw_link_id only for regular scan, in iwl_mld_scan_set_link_id()
1422 * and use it in scan complete notif in iwl_mld_scan_set_link_id()
1425 mld->scan.fw_link_id = link->fw_id; in iwl_mld_scan_set_link_id()
1427 mld->scan.fw_link_id = IWL_MLD_INVALID_FW_ID; in iwl_mld_scan_set_link_id()
1428 params->fw_link_id = IWL_MLD_INVALID_FW_ID; in iwl_mld_scan_set_link_id()
1440 .len = { mld->scan.cmd_size, }, in _iwl_mld_single_scan_start()
1441 .data = { mld->scan.cmd, }, in _iwl_mld_single_scan_start()
1452 if (WARN_ON(!mld->scan.cmd)) in _iwl_mld_single_scan_start()
1453 return -ENOMEM; in _iwl_mld_single_scan_start()
1455 if (!iwl_mld_scan_fits(mld, req->n_ssids, ies, req->n_channels)) in _iwl_mld_single_scan_start()
1456 return -ENOBUFS; in _iwl_mld_single_scan_start()
1458 ieee80211_iterate_active_interfaces_mtx(mld->hw, in _iwl_mld_single_scan_start()
1464 params.n_ssids = req->n_ssids; in _iwl_mld_single_scan_start()
1465 params.flags = req->flags; in _iwl_mld_single_scan_start()
1466 params.n_channels = req->n_channels; in _iwl_mld_single_scan_start()
1468 params.ssids = req->ssids; in _iwl_mld_single_scan_start()
1469 params.channels = req->channels; in _iwl_mld_single_scan_start()
1470 params.mac_addr = req->mac_addr; in _iwl_mld_single_scan_start()
1471 params.mac_addr_mask = req->mac_addr_mask; in _iwl_mld_single_scan_start()
1472 params.no_cck = req->no_cck; in _iwl_mld_single_scan_start()
1479 params.n_6ghz_params = req->n_6ghz_params; in _iwl_mld_single_scan_start()
1480 params.scan_6ghz_params = req->scan_6ghz_params; in _iwl_mld_single_scan_start()
1481 params.scan_6ghz = req->scan_6ghz; in _iwl_mld_single_scan_start()
1483 ether_addr_copy(params.bssid, req->bssid); in _iwl_mld_single_scan_start()
1484 /* TODO: CDB - per-band flag */ in _iwl_mld_single_scan_start()
1489 if (req->duration) in _iwl_mld_single_scan_start()
1492 iwl_mld_scan_set_link_id(mld, vif, &params, req->tsf_report_link_id, in _iwl_mld_single_scan_start()
1506 IWL_ERR(mld, "Scan failed! ret %d\n", ret); in _iwl_mld_single_scan_start()
1510 IWL_DEBUG_SCAN(mld, "Scan request send success: status=%u, uid=%u\n", in _iwl_mld_single_scan_start()
1513 mld->scan.uid_status[uid] = scan_status; in _iwl_mld_single_scan_start()
1514 mld->scan.status |= scan_status; in _iwl_mld_single_scan_start()
1517 mld->scan.last_6ghz_passive_jiffies = jiffies; in _iwl_mld_single_scan_start()
1547 "Scan Abort: unexpected response length %d\n", in iwl_mld_scan_send_abort_cmd_status()
1549 ret = -EIO; in iwl_mld_scan_send_abort_cmd_status()
1553 resp = (void *)pkt->data; in iwl_mld_scan_send_abort_cmd_status()
1554 *status = le32_to_cpu(resp->status); in iwl_mld_scan_send_abort_cmd_status()
1569 IWL_DEBUG_SCAN(mld, "Sending scan abort, uid %u\n", uid); in iwl_mld_scan_abort()
1573 IWL_DEBUG_SCAN(mld, "Scan abort: ret=%d status=%u\n", ret, status); in iwl_mld_scan_abort()
1575 /* We don't need to wait to scan complete in the following cases: in iwl_mld_scan_abort()
1576 * 1. Driver failed to send the scan abort cmd. in iwl_mld_scan_abort()
1577 * 2. The FW is no longer familiar with the scan that needs to be in iwl_mld_scan_abort()
1578 * stopped. It is expected that the scan complete notification was in iwl_mld_scan_abort()
1582 * scan was really aborted. in iwl_mld_scan_abort()
1598 iwl_init_notification_wait(&mld->notif_wait, &wait_scan_done, in iwl_mld_scan_stop_wait()
1603 IWL_DEBUG_SCAN(mld, "Preparing to stop scan, type=%x\n", type); in iwl_mld_scan_stop_wait()
1607 IWL_DEBUG_SCAN(mld, "couldn't stop scan type=%d\n", type); in iwl_mld_scan_stop_wait()
1612 IWL_DEBUG_SCAN(mld, "no need to wait for scan type=%d\n", type); in iwl_mld_scan_stop_wait()
1616 return iwl_wait_notification(&mld->notif_wait, &wait_scan_done, HZ); in iwl_mld_scan_stop_wait()
1619 iwl_remove_notification(&mld->notif_wait, &wait_scan_done); in iwl_mld_scan_stop_wait()
1631 .len = { mld->scan.cmd_size, }, in iwl_mld_sched_scan_start()
1632 .data = { mld->scan.cmd, }, in iwl_mld_sched_scan_start()
1643 if (WARN_ON(!mld->scan.cmd)) in iwl_mld_sched_scan_start()
1644 return -ENOMEM; in iwl_mld_sched_scan_start()
1646 /* FW supports only a single periodic scan */ in iwl_mld_sched_scan_start()
1647 if (mld->scan.status & (IWL_MLD_SCAN_SCHED | IWL_MLD_SCAN_NETDETECT)) in iwl_mld_sched_scan_start()
1648 return -EBUSY; in iwl_mld_sched_scan_start()
1650 ieee80211_iterate_active_interfaces_mtx(mld->hw, in iwl_mld_sched_scan_start()
1656 params.flags = req->flags; in iwl_mld_sched_scan_start()
1657 params.n_ssids = req->n_ssids; in iwl_mld_sched_scan_start()
1658 params.ssids = req->ssids; in iwl_mld_sched_scan_start()
1659 params.n_channels = req->n_channels; in iwl_mld_sched_scan_start()
1660 params.channels = req->channels; in iwl_mld_sched_scan_start()
1661 params.mac_addr = req->mac_addr; in iwl_mld_sched_scan_start()
1662 params.mac_addr_mask = req->mac_addr_mask; in iwl_mld_sched_scan_start()
1665 params.n_match_sets = req->n_match_sets; in iwl_mld_sched_scan_start()
1666 params.match_sets = req->match_sets; in iwl_mld_sched_scan_start()
1667 params.n_scan_plans = req->n_scan_plans; in iwl_mld_sched_scan_start()
1668 params.scan_plans = req->scan_plans; in iwl_mld_sched_scan_start()
1669 /* TODO: CDB - per-band flag */ in iwl_mld_sched_scan_start()
1674 /* UMAC scan supports up to 16-bit delays, trim it down to 16-bits */ in iwl_mld_sched_scan_start()
1675 params.delay = req->delay > U16_MAX ? U16_MAX : req->delay; in iwl_mld_sched_scan_start()
1690 if (!iwl_mld_scan_fits(mld, req->n_ssids, ies, params.n_channels)) { in iwl_mld_sched_scan_start()
1691 ret = -ENOBUFS; in iwl_mld_sched_scan_start()
1705 "Sched scan request send success: type=%u, uid=%u\n", in iwl_mld_sched_scan_start()
1707 mld->scan.uid_status[uid] = type; in iwl_mld_sched_scan_start()
1708 mld->scan.status |= type; in iwl_mld_sched_scan_start()
1710 IWL_ERR(mld, "Sched scan failed! ret %d\n", ret); in iwl_mld_sched_scan_start()
1711 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_sched_scan_start()
1725 "Request to stop scan: type=0x%x, status=0x%x\n", in iwl_mld_scan_stop()
1726 type, mld->scan.status); in iwl_mld_scan_stop()
1728 if (!(mld->scan.status & type)) in iwl_mld_scan_stop()
1738 IWL_DEBUG_SCAN(mld, "Failed to stop scan\n"); in iwl_mld_scan_stop()
1740 /* Clear the scan status so the next scan requests will in iwl_mld_scan_stop()
1741 * succeed and mark the scan as stopping, so that the Rx in iwl_mld_scan_stop()
1742 * handler doesn't do anything, as the scan was stopped from in iwl_mld_scan_stop()
1744 * erroneously after a new scan starts, for example. in iwl_mld_scan_stop()
1746 mld->scan.status &= ~type; in iwl_mld_scan_stop()
1747 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_scan_stop()
1757 ieee80211_scan_completed(mld->hw, &info); in iwl_mld_scan_stop()
1760 ieee80211_sched_scan_stopped(mld->hw); in iwl_mld_scan_stop()
1761 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_scan_stop()
1771 /* Clear survey data when starting the first part of a regular scan */ in iwl_mld_regular_scan_start()
1772 if (req->first_part && mld->channel_survey) in iwl_mld_regular_scan_start()
1773 memset(mld->channel_survey->channels, 0, in iwl_mld_regular_scan_start()
1774 sizeof(mld->channel_survey->channels[0]) * in iwl_mld_regular_scan_start()
1775 mld->channel_survey->n_channels); in iwl_mld_regular_scan_start()
1777 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) in iwl_mld_regular_scan_start()
1794 IWL_DEBUG_SCAN(mld, "Starting Internal MLO scan: n_channels=%zu\n", in iwl_mld_int_mlo_scan_start()
1804 req->channels[i] = channels[i]; in iwl_mld_int_mlo_scan_start()
1806 req->n_channels = n_channels; in iwl_mld_int_mlo_scan_start()
1810 if (mld->wiphy->bands[i]) in iwl_mld_int_mlo_scan_start()
1811 req->rates[i] = in iwl_mld_int_mlo_scan_start()
1812 (1 << mld->wiphy->bands[i]->n_bitrates) - 1; in iwl_mld_int_mlo_scan_start()
1814 req->wdev = ieee80211_vif_to_wdev(vif); in iwl_mld_int_mlo_scan_start()
1815 req->wiphy = mld->wiphy; in iwl_mld_int_mlo_scan_start()
1816 req->scan_start = jiffies; in iwl_mld_int_mlo_scan_start()
1817 req->tsf_report_link_id = -1; in iwl_mld_int_mlo_scan_start()
1823 mld->scan.last_mlo_scan_time = ktime_get_boottime_ns(); in iwl_mld_int_mlo_scan_start()
1825 IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret); in iwl_mld_int_mlo_scan_start()
1838 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_int_mlo_scan()
1840 if (!IWL_MLD_AUTO_EML_ENABLE || !vif->cfg.assoc || in iwl_mld_int_mlo_scan()
1841 !ieee80211_vif_is_mld(vif) || hweight16(vif->valid_links) == 1) in iwl_mld_int_mlo_scan()
1844 if (mld->scan.status & IWL_MLD_SCAN_INT_MLO) { in iwl_mld_int_mlo_scan()
1845 IWL_DEBUG_SCAN(mld, "Internal MLO scan is already running\n"); in iwl_mld_int_mlo_scan()
1849 if (mld_vif->last_link_activation_time > ktime_get_boottime_seconds() - in iwl_mld_int_mlo_scan()
1852 wiphy_delayed_work_queue(mld->wiphy, in iwl_mld_int_mlo_scan()
1853 &mld_vif->mlo_scan_start_wk, in iwl_mld_int_mlo_scan()
1865 channels[n_channels++] = link_conf->chanreq.oper.chan; in iwl_mld_int_mlo_scan()
1877 struct iwl_umac_scan_iter_complete_notif *notif = (void *)pkt->data; in iwl_mld_handle_scan_iter_complete_notif()
1878 u32 uid = __le32_to_cpu(notif->uid); in iwl_mld_handle_scan_iter_complete_notif()
1880 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status), in iwl_mld_handle_scan_iter_complete_notif()
1881 "FW reports out-of-range scan UID %d\n", uid)) in iwl_mld_handle_scan_iter_complete_notif()
1884 if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_REGULAR) in iwl_mld_handle_scan_iter_complete_notif()
1885 mld->scan.start_tsf = le64_to_cpu(notif->start_tsf); in iwl_mld_handle_scan_iter_complete_notif()
1888 "UMAC Scan iteration complete: status=0x%x scanned_channels=%d\n", in iwl_mld_handle_scan_iter_complete_notif()
1889 notif->status, notif->scanned_channels); in iwl_mld_handle_scan_iter_complete_notif()
1891 if (mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_FOUND) { in iwl_mld_handle_scan_iter_complete_notif()
1892 IWL_DEBUG_SCAN(mld, "Pass all scheduled scan results found\n"); in iwl_mld_handle_scan_iter_complete_notif()
1893 ieee80211_sched_scan_results(mld->hw); in iwl_mld_handle_scan_iter_complete_notif()
1894 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_ENABLED; in iwl_mld_handle_scan_iter_complete_notif()
1898 "UMAC Scan iteration complete: scan started at %llu (TSF)\n", in iwl_mld_handle_scan_iter_complete_notif()
1899 le64_to_cpu(notif->start_tsf)); in iwl_mld_handle_scan_iter_complete_notif()
1905 IWL_DEBUG_SCAN(mld, "Scheduled scan results\n"); in iwl_mld_handle_match_found_notif()
1906 ieee80211_sched_scan_results(mld->hw); in iwl_mld_handle_match_found_notif()
1912 struct iwl_umac_scan_complete *notif = (void *)pkt->data; in iwl_mld_handle_scan_complete_notif()
1913 bool aborted = (notif->status == IWL_SCAN_OFFLOAD_ABORTED); in iwl_mld_handle_scan_complete_notif()
1914 u32 uid = __le32_to_cpu(notif->uid); in iwl_mld_handle_scan_complete_notif()
1916 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status), in iwl_mld_handle_scan_complete_notif()
1917 "FW reports out-of-range scan UID %d\n", uid)) in iwl_mld_handle_scan_complete_notif()
1921 "Scan completed: uid=%u type=%u, status=%s, EBS=%s\n", in iwl_mld_handle_scan_complete_notif()
1922 uid, mld->scan.uid_status[uid], in iwl_mld_handle_scan_complete_notif()
1923 notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? in iwl_mld_handle_scan_complete_notif()
1925 iwl_mld_scan_ebs_status_str(notif->ebs_status)); in iwl_mld_handle_scan_complete_notif()
1926 IWL_DEBUG_SCAN(mld, "Scan completed: scan_status=0x%x\n", in iwl_mld_handle_scan_complete_notif()
1927 mld->scan.status); in iwl_mld_handle_scan_complete_notif()
1929 "Scan completed: line=%u, iter=%u, elapsed time=%u\n", in iwl_mld_handle_scan_complete_notif()
1930 notif->last_schedule, notif->last_iter, in iwl_mld_handle_scan_complete_notif()
1931 __le32_to_cpu(notif->time_from_last_iter)); in iwl_mld_handle_scan_complete_notif()
1933 if (IWL_FW_CHECK(mld, !(mld->scan.uid_status[uid] & mld->scan.status), in iwl_mld_handle_scan_complete_notif()
1934 "FW reports scan UID %d we didn't trigger\n", uid)) in iwl_mld_handle_scan_complete_notif()
1937 /* if the scan is already stopping, we don't need to notify mac80211 */ in iwl_mld_handle_scan_complete_notif()
1938 if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_REGULAR) { in iwl_mld_handle_scan_complete_notif()
1941 .scan_start_tsf = mld->scan.start_tsf, in iwl_mld_handle_scan_complete_notif()
1943 int fw_link_id = mld->scan.fw_link_id; in iwl_mld_handle_scan_complete_notif()
1948 wiphy_dereference(mld->wiphy, in iwl_mld_handle_scan_complete_notif()
1949 mld->fw_id_to_bss_conf[fw_link_id]); in iwl_mld_handle_scan_complete_notif()
1951 /* It is possible that by the time the scan is complete the in iwl_mld_handle_scan_complete_notif()
1955 ether_addr_copy(info.tsf_bssid, link_conf->bssid); in iwl_mld_handle_scan_complete_notif()
1957 IWL_DEBUG_SCAN(mld, "Scan link is no longer valid\n"); in iwl_mld_handle_scan_complete_notif()
1959 ieee80211_scan_completed(mld->hw, &info); in iwl_mld_handle_scan_complete_notif()
1961 /* Scan is over, we can check again the tpt counters */ in iwl_mld_handle_scan_complete_notif()
1963 } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_SCHED) { in iwl_mld_handle_scan_complete_notif()
1964 ieee80211_sched_scan_stopped(mld->hw); in iwl_mld_handle_scan_complete_notif()
1965 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_handle_scan_complete_notif()
1966 } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_INT_MLO) { in iwl_mld_handle_scan_complete_notif()
1967 IWL_DEBUG_SCAN(mld, "Internal MLO scan completed\n"); in iwl_mld_handle_scan_complete_notif()
1976 mld->scan.status &= ~mld->scan.uid_status[uid]; in iwl_mld_handle_scan_complete_notif()
1978 IWL_DEBUG_SCAN(mld, "Scan completed: after update: scan_status=0x%x\n", in iwl_mld_handle_scan_complete_notif()
1979 mld->scan.status); in iwl_mld_handle_scan_complete_notif()
1981 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_handle_scan_complete_notif()
1983 if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS && in iwl_mld_handle_scan_complete_notif()
1984 notif->ebs_status != IWL_SCAN_EBS_INACTIVE) in iwl_mld_handle_scan_complete_notif()
1985 mld->scan.last_ebs_failed = true; in iwl_mld_handle_scan_complete_notif()
2001 ieee80211_scan_completed(mld->hw, &info); in iwl_mld_report_scan_aborted()
2002 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_report_scan_aborted()
2007 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_report_scan_aborted()
2008 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_report_scan_aborted()
2010 /* sched scan will be restarted by mac80211 in reconfig. in iwl_mld_report_scan_aborted()
2011 * report to mac80211 that sched scan stopped only if we won't in iwl_mld_report_scan_aborted()
2015 ieee80211_sched_scan_stopped(mld->hw); in iwl_mld_report_scan_aborted()
2020 IWL_DEBUG_SCAN(mld, "Internal MLO scan aborted\n"); in iwl_mld_report_scan_aborted()
2021 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_report_scan_aborted()
2025 memset(mld->scan.uid_status, 0, sizeof(mld->scan.uid_status)); in iwl_mld_report_scan_aborted()
2030 u8 scan_cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, SCAN_REQ_UMAC, in iwl_mld_alloc_scan_cmd()
2037 IWL_ERR(mld, "Unexpected scan cmd version %d\n", scan_cmd_ver); in iwl_mld_alloc_scan_cmd()
2038 return -EINVAL; in iwl_mld_alloc_scan_cmd()
2041 mld->scan.cmd = kmalloc(scan_cmd_size, GFP_KERNEL); in iwl_mld_alloc_scan_cmd()
2042 if (!mld->scan.cmd) in iwl_mld_alloc_scan_cmd()
2043 return -ENOMEM; in iwl_mld_alloc_scan_cmd()
2045 mld->scan.cmd_size = scan_cmd_size; in iwl_mld_alloc_scan_cmd()
2054 struct ieee80211_supported_band *sband = mld->wiphy->bands[band]; in iwl_mld_chanidx_from_phy()
2057 return -EINVAL; in iwl_mld_chanidx_from_phy()
2059 for (int chan_idx = 0; chan_idx < sband->n_channels; chan_idx++) { in iwl_mld_chanidx_from_phy()
2060 struct ieee80211_channel *channel = &sband->channels[chan_idx]; in iwl_mld_chanidx_from_phy()
2062 if (channel->hw_value == phy_chan_num) in iwl_mld_chanidx_from_phy()
2066 return -EINVAL; in iwl_mld_chanidx_from_phy()
2073 (void *)pkt->data; in iwl_mld_handle_channel_survey_notif()
2078 if (!mld->channel_survey) { in iwl_mld_handle_channel_survey_notif()
2082 if (!mld->wiphy->bands[band]) in iwl_mld_handle_channel_survey_notif()
2085 n_channels += mld->wiphy->bands[band]->n_channels; in iwl_mld_handle_channel_survey_notif()
2088 mld->channel_survey = kzalloc(struct_size(mld->channel_survey, in iwl_mld_handle_channel_survey_notif()
2092 if (!mld->channel_survey) in iwl_mld_handle_channel_survey_notif()
2095 mld->channel_survey->n_channels = n_channels; in iwl_mld_handle_channel_survey_notif()
2098 if (!mld->wiphy->bands[band]) in iwl_mld_handle_channel_survey_notif()
2101 mld->channel_survey->bands[band] = in iwl_mld_handle_channel_survey_notif()
2102 &mld->channel_survey->channels[n_channels]; in iwl_mld_handle_channel_survey_notif()
2103 n_channels += mld->wiphy->bands[band]->n_channels; in iwl_mld_handle_channel_survey_notif()
2107 band = iwl_mld_phy_band_to_nl80211(le32_to_cpu(notif->band)); in iwl_mld_handle_channel_survey_notif()
2109 le32_to_cpu(notif->channel)); in iwl_mld_handle_channel_survey_notif()
2114 mld->wiphy->bands[band]->channels[chan_idx].center_freq); in iwl_mld_handle_channel_survey_notif()
2116 info = &mld->channel_survey->bands[band][chan_idx]; in iwl_mld_handle_channel_survey_notif()
2118 /* Times are all in ms */ in iwl_mld_handle_channel_survey_notif()
2119 info->time = le32_to_cpu(notif->active_time); in iwl_mld_handle_channel_survey_notif()
2120 info->time_busy = le32_to_cpu(notif->busy_time); in iwl_mld_handle_channel_survey_notif()
2121 info->noise = in iwl_mld_handle_channel_survey_notif()
2122 iwl_average_neg_dbm(notif->noise, ARRAY_SIZE(notif->noise)); in iwl_mld_handle_channel_survey_notif()
2131 if (!mld->channel_survey) in iwl_mld_mac80211_get_survey()
2132 return -ENOENT; in iwl_mld_mac80211_get_survey()
2141 mld->wiphy->bands[band]; in iwl_mld_mac80211_get_survey()
2147 per_band_idx < sband->n_channels; in iwl_mld_mac80211_get_survey()
2150 &mld->channel_survey->bands[band][per_band_idx]; in iwl_mld_mac80211_get_survey()
2155 if (!info->time) in iwl_mld_mac80211_get_survey()
2167 survey->channel = &sband->channels[per_band_idx]; in iwl_mld_mac80211_get_survey()
2168 survey->filled = SURVEY_INFO_TIME | in iwl_mld_mac80211_get_survey()
2170 survey->time = info->time; in iwl_mld_mac80211_get_survey()
2171 survey->time_busy = info->time_busy; in iwl_mld_mac80211_get_survey()
2172 survey->noise = info->noise; in iwl_mld_mac80211_get_survey()
2173 if (survey->noise < 0) in iwl_mld_mac80211_get_survey()
2174 survey->filled |= SURVEY_INFO_NOISE_DBM; in iwl_mld_mac80211_get_survey()
2180 return -ENOENT; in iwl_mld_mac80211_get_survey()