Lines Matching +full:scan +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2024-2025 Intel Corporation
8 #include "scan.h"
14 #include "fw/api/scan.h"
21 /* adaptive dwell max budget time [TU] for full scan */
24 /* adaptive dwell max budget time [TU] for directed scan */
50 /* minimal number of 2GHz and 5GHz channels in the regular scan request */
93 u16 delay; member
128 if (vif == data->current_vif) in iwl_mld_scan_respect_p2p_go_iter()
133 iwl_mld_vif_from_mac80211(vif)->ap_ibss_active) in iwl_mld_scan_respect_p2p_go_iter()
134 data->p2p_go = true; in iwl_mld_scan_respect_p2p_go_iter()
149 ieee80211_iterate_active_interfaces_mtx(mld->hw, in iwl_mld_get_respect_p2p_go()
168 struct ieee80211_vif *curr_vif = data->current_vif; in iwl_mld_scan_iterator()
174 data->global_low_latency |= iwl_mld_vif_low_latency(mld_vif); in iwl_mld_scan_iterator()
176 if ((ieee80211_vif_is_mld(vif) && vif->active_links) || in iwl_mld_scan_iterator()
177 (vif->type != NL80211_IFTYPE_P2P_DEVICE && in iwl_mld_scan_iterator()
178 mld_vif->deflink.active)) in iwl_mld_scan_iterator()
179 data->active_vif = true; in iwl_mld_scan_iterator()
191 ieee80211_vif_is_mld(curr_vif) ? curr_vif->active_links : 1; in iwl_mld_scan_iterator()
203 if (rcu_access_pointer(curr_mld_link->chan_ctx) && in iwl_mld_scan_iterator()
204 rcu_access_pointer(mld_vif->deflink.chan_ctx) != in iwl_mld_scan_iterator()
205 rcu_access_pointer(curr_mld_link->chan_ctx)) { in iwl_mld_scan_iterator()
206 data->is_dcm_with_p2p_go = true; in iwl_mld_scan_iterator()
217 enum iwl_mld_traffic_load load = mld->scan.traffic_load.status; in iwl_mld_get_scan_type()
221 * Force a non-fragmented scan in that case. in iwl_mld_get_scan_type()
226 if (!data->active_vif) in iwl_mld_get_scan_type()
229 if ((load == IWL_MLD_TRAFFIC_HIGH || data->global_low_latency) && in iwl_mld_get_scan_type()
230 vif->type != NL80211_IFTYPE_P2P_DEVICE) in iwl_mld_get_scan_type()
233 /* In case of DCM with P2P GO set all scan requests as in iwl_mld_get_scan_type()
234 * fast-balance scan in iwl_mld_get_scan_type()
236 if (vif->type == NL80211_IFTYPE_STATION && in iwl_mld_get_scan_type()
237 data->is_dcm_with_p2p_go) in iwl_mld_get_scan_type()
240 if (load >= IWL_MLD_TRAFFIC_MEDIUM || data->global_low_latency) in iwl_mld_get_scan_type()
272 memcpy(newpos, ies + offs, len - offs); in iwl_mld_scan_add_2ghz_elems()
273 newpos += len - offs; in iwl_mld_scan_add_2ghz_elems()
282 pos[1] = WFA_TPC_IE_LEN - 2; in iwl_mld_scan_add_tpc_report_elem()
288 /* pos[7] - tx power will be inserted by the FW */ in iwl_mld_scan_add_tpc_report_elem()
307 return params->n_scan_plans == 1 && in iwl_mld_scan_is_regular()
308 params->scan_plans[0].iterations == 1; in iwl_mld_scan_is_regular()
321 for (int i = 0; i < ARRAY_SIZE(mld->scan.uid_status); i++) in iwl_mld_scan_uid_by_status()
322 if (mld->scan.uid_status[i] == status) in iwl_mld_scan_uid_by_status()
325 return -ENOENT; in iwl_mld_scan_uid_by_status()
348 return -1; in iwl_mld_scan_ssid_exist()
354 return -1; in iwl_mld_scan_ssid_exist()
362 (n_channels <= mld->fw->ucode_capa.n_scan_channels) & in iwl_mld_scan_fits()
363 (ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + in iwl_mld_scan_fits()
364 ies->len[NL80211_BAND_5GHZ] + ies->len[NL80211_BAND_6GHZ] <= in iwl_mld_scan_fits()
373 struct ieee80211_mgmt *frame = (void *)params->preq.buf; in iwl_mld_scan_build_probe_req()
375 const u8 *mac_addr = params->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? in iwl_mld_scan_build_probe_req()
376 params->mac_addr : NULL; in iwl_mld_scan_build_probe_req()
379 get_random_mask_addr(frame->sa, mac_addr, in iwl_mld_scan_build_probe_req()
380 params->mac_addr_mask); in iwl_mld_scan_build_probe_req()
382 memcpy(frame->sa, vif->addr, ETH_ALEN); in iwl_mld_scan_build_probe_req()
384 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); in iwl_mld_scan_build_probe_req()
385 eth_broadcast_addr(frame->da); in iwl_mld_scan_build_probe_req()
386 ether_addr_copy(frame->bssid, params->bssid); in iwl_mld_scan_build_probe_req()
387 frame->seq_ctrl = 0; in iwl_mld_scan_build_probe_req()
389 pos = frame->u.probe_req.variable; in iwl_mld_scan_build_probe_req()
393 params->preq.mac_header.offset = 0; in iwl_mld_scan_build_probe_req()
394 params->preq.mac_header.len = cpu_to_le16(24 + 2); in iwl_mld_scan_build_probe_req()
398 ies->ies[NL80211_BAND_2GHZ], in iwl_mld_scan_build_probe_req()
399 ies->len[NL80211_BAND_2GHZ], in iwl_mld_scan_build_probe_req()
401 params->preq.band_data[0].offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
402 params->preq.band_data[0].len = cpu_to_le16(newpos - pos); in iwl_mld_scan_build_probe_req()
405 memcpy(pos, ies->ies[NL80211_BAND_5GHZ], in iwl_mld_scan_build_probe_req()
406 ies->len[NL80211_BAND_5GHZ]); in iwl_mld_scan_build_probe_req()
407 params->preq.band_data[1].offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
408 params->preq.band_data[1].len = in iwl_mld_scan_build_probe_req()
409 cpu_to_le16(ies->len[NL80211_BAND_5GHZ]); in iwl_mld_scan_build_probe_req()
410 pos += ies->len[NL80211_BAND_5GHZ]; in iwl_mld_scan_build_probe_req()
412 memcpy(pos, ies->ies[NL80211_BAND_6GHZ], in iwl_mld_scan_build_probe_req()
413 ies->len[NL80211_BAND_6GHZ]); in iwl_mld_scan_build_probe_req()
414 params->preq.band_data[2].offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
415 params->preq.band_data[2].len = in iwl_mld_scan_build_probe_req()
416 cpu_to_le16(ies->len[NL80211_BAND_6GHZ]); in iwl_mld_scan_build_probe_req()
417 pos += ies->len[NL80211_BAND_6GHZ]; in iwl_mld_scan_build_probe_req()
419 memcpy(pos, ies->common_ies, ies->common_ie_len); in iwl_mld_scan_build_probe_req()
420 params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf); in iwl_mld_scan_build_probe_req()
422 iwl_mld_scan_add_tpc_report_elem(pos + ies->common_ie_len); in iwl_mld_scan_build_probe_req()
423 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len + in iwl_mld_scan_build_probe_req()
435 /* If no direct SSIDs are provided perform a passive scan. Otherwise, in iwl_mld_scan_get_cmd_gen_flags()
437 * that the scan is intended for roaming purposes and thus enable Rx on in iwl_mld_scan_get_cmd_gen_flags()
440 if (params->n_ssids == 0) in iwl_mld_scan_get_cmd_gen_flags()
442 else if (params->n_ssids == 1 && params->ssids[0].ssid_len) in iwl_mld_scan_get_cmd_gen_flags()
445 if (params->pass_all) in iwl_mld_scan_get_cmd_gen_flags()
450 if (iwl_mld_scan_is_fragmented(params->type)) in iwl_mld_scan_get_cmd_gen_flags()
456 if (params->iter_notif || in iwl_mld_scan_get_cmd_gen_flags()
457 mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_ENABLED) in iwl_mld_scan_get_cmd_gen_flags()
464 if (params->flags & (NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP | in iwl_mld_scan_get_cmd_gen_flags()
471 params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) in iwl_mld_scan_get_cmd_gen_flags()
474 if (params->enable_6ghz_passive) in iwl_mld_scan_get_cmd_gen_flags()
490 if (params->respect_p2p_go) in iwl_mld_scan_get_cmd_gen_flags2()
494 if (params->scan_6ghz) in iwl_mld_scan_get_cmd_gen_flags2()
506 &scan_timing[params->type]; in iwl_mld_scan_cmd_set_dwell()
508 gp->adwell_default_social_chn = in iwl_mld_scan_cmd_set_dwell()
510 gp->adwell_default_2g = IWL_SCAN_ADWELL_DEFAULT_LB_N_APS; in iwl_mld_scan_cmd_set_dwell()
511 gp->adwell_default_5g = IWL_SCAN_ADWELL_DEFAULT_HB_N_APS; in iwl_mld_scan_cmd_set_dwell()
513 if (params->n_ssids && params->ssids[0].ssid_len) in iwl_mld_scan_cmd_set_dwell()
514 gp->adwell_max_budget = in iwl_mld_scan_cmd_set_dwell()
517 gp->adwell_max_budget = in iwl_mld_scan_cmd_set_dwell()
520 gp->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); in iwl_mld_scan_cmd_set_dwell()
522 gp->max_out_of_time[SCAN_LB_LMAC_IDX] = cpu_to_le32(timing->max_out_time); in iwl_mld_scan_cmd_set_dwell()
523 gp->suspend_time[SCAN_LB_LMAC_IDX] = cpu_to_le32(timing->suspend_time); in iwl_mld_scan_cmd_set_dwell()
525 gp->active_dwell[SCAN_LB_LMAC_IDX] = IWL_SCAN_DWELL_ACTIVE; in iwl_mld_scan_cmd_set_dwell()
526 gp->passive_dwell[SCAN_LB_LMAC_IDX] = IWL_SCAN_DWELL_PASSIVE; in iwl_mld_scan_cmd_set_dwell()
527 gp->active_dwell[SCAN_HB_LMAC_IDX] = IWL_SCAN_DWELL_ACTIVE; in iwl_mld_scan_cmd_set_dwell()
528 gp->passive_dwell[SCAN_HB_LMAC_IDX] = IWL_SCAN_DWELL_PASSIVE; in iwl_mld_scan_cmd_set_dwell()
531 "Scan: adwell_max_budget=%d max_out_of_time=%d suspend_time=%d\n", in iwl_mld_scan_cmd_set_dwell()
532 gp->adwell_max_budget, in iwl_mld_scan_cmd_set_dwell()
533 gp->max_out_of_time[SCAN_LB_LMAC_IDX], in iwl_mld_scan_cmd_set_dwell()
534 gp->suspend_time[SCAN_LB_LMAC_IDX]); in iwl_mld_scan_cmd_set_dwell()
552 gp->flags = cpu_to_le16(gen_flags); in iwl_mld_scan_cmd_set_gen_params()
553 gp->flags2 = gen_flags2; in iwl_mld_scan_cmd_set_gen_params()
558 gp->num_of_fragments[SCAN_LB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS; in iwl_mld_scan_cmd_set_gen_params()
560 if (params->fw_link_id != IWL_MLD_INVALID_FW_ID) in iwl_mld_scan_cmd_set_gen_params()
561 gp->scan_start_mac_or_link_id = params->fw_link_id; in iwl_mld_scan_cmd_set_gen_params()
567 __le16 *delay) in iwl_mld_scan_cmd_set_sched_params() argument
569 if (WARN_ON(!params->n_scan_plans || in iwl_mld_scan_cmd_set_sched_params()
570 params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS)) in iwl_mld_scan_cmd_set_sched_params()
571 return -EINVAL; in iwl_mld_scan_cmd_set_sched_params()
573 for (int i = 0; i < params->n_scan_plans; i++) { in iwl_mld_scan_cmd_set_sched_params()
575 ¶ms->scan_plans[i]; in iwl_mld_scan_cmd_set_sched_params()
577 schedule[i].iter_count = scan_plan->iterations; in iwl_mld_scan_cmd_set_sched_params()
579 cpu_to_le16(scan_plan->interval); in iwl_mld_scan_cmd_set_sched_params()
582 /* If the number of iterations of the last scan plan is set to zero, in iwl_mld_scan_cmd_set_sched_params()
584 * For example, when regular scan is requested the driver sets one scan in iwl_mld_scan_cmd_set_sched_params()
587 if (!schedule[params->n_scan_plans - 1].iter_count) in iwl_mld_scan_cmd_set_sched_params()
588 schedule[params->n_scan_plans - 1].iter_count = 0xff; in iwl_mld_scan_cmd_set_sched_params()
590 *delay = cpu_to_le16(params->delay); in iwl_mld_scan_cmd_set_sched_params()
609 for (i = 0, j = params->n_match_sets - 1; in iwl_mld_scan_cmd_build_ssids()
611 i++, j--) { in iwl_mld_scan_cmd_build_ssids()
613 if (!params->match_sets[j].ssid.ssid_len) in iwl_mld_scan_cmd_build_ssids()
617 ssids[i].len = params->match_sets[j].ssid.ssid_len; in iwl_mld_scan_cmd_build_ssids()
618 memcpy(ssids[i].ssid, params->match_sets[j].ssid.ssid, in iwl_mld_scan_cmd_build_ssids()
622 /* add SSIDs from scan SSID list */ in iwl_mld_scan_cmd_build_ssids()
623 for (j = params->n_ssids - 1; in iwl_mld_scan_cmd_build_ssids()
625 i++, j--) { in iwl_mld_scan_cmd_build_ssids()
626 index = iwl_mld_scan_ssid_exist(params->ssids[j].ssid, in iwl_mld_scan_cmd_build_ssids()
627 params->ssids[j].ssid_len, in iwl_mld_scan_cmd_build_ssids()
631 ssids[i].len = params->ssids[j].ssid_len; in iwl_mld_scan_cmd_build_ssids()
632 memcpy(ssids[i].ssid, params->ssids[j].ssid, in iwl_mld_scan_cmd_build_ssids()
650 params->scan_6ghz_params; in iwl_mld_scan_fill_6g_chan_list()
653 j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE; in iwl_mld_scan_fill_6g_chan_list()
655 if (!params->ssids[j].ssid_len) in iwl_mld_scan_fill_6g_chan_list()
658 pp->short_ssid[idex_s] = in iwl_mld_scan_fill_6g_chan_list()
659 cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid, in iwl_mld_scan_fill_6g_chan_list()
660 params->ssids[j].ssid_len)); in iwl_mld_scan_fill_6g_chan_list()
662 /* hidden 6ghz scan */ in iwl_mld_scan_fill_6g_chan_list()
663 pp->direct_scan[idex_s].id = WLAN_EID_SSID; in iwl_mld_scan_fill_6g_chan_list()
664 pp->direct_scan[idex_s].len = params->ssids[j].ssid_len; in iwl_mld_scan_fill_6g_chan_list()
665 memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid, in iwl_mld_scan_fill_6g_chan_list()
666 params->ssids[j].ssid_len); in iwl_mld_scan_fill_6g_chan_list()
675 for (j = 0; j < params->n_6ghz_params; j++) { in iwl_mld_scan_fill_6g_chan_list()
681 if (pp->short_ssid[k] == in iwl_mld_scan_fill_6g_chan_list()
687 pp->short_ssid[idex_s++] = in iwl_mld_scan_fill_6g_chan_list()
694 if (!memcmp(&pp->bssid_array[k], in iwl_mld_scan_fill_6g_chan_list()
701 "scan: invalid BSSID at index %u, index_b=%u\n", in iwl_mld_scan_fill_6g_chan_list()
703 memcpy(&pp->bssid_array[idex_b++], in iwl_mld_scan_fill_6g_chan_list()
708 pp->short_ssid_num = idex_s; in iwl_mld_scan_fill_6g_chan_list()
709 pp->bssid_num = idex_b; in iwl_mld_scan_fill_6g_chan_list()
717 pp->preq = params->preq; in iwl_mld_scan_cmd_set_probe_params()
719 if (params->scan_6ghz) { in iwl_mld_scan_cmd_set_probe_params()
724 /* relevant only for 2.4 GHz /5 GHz scan */ in iwl_mld_scan_cmd_set_probe_params()
725 iwl_mld_scan_cmd_build_ssids(params, pp->direct_scan, bitmap_ssid); in iwl_mld_scan_cmd_set_probe_params()
732 const struct iwl_ucode_capabilities *capa = &mld->fw->ucode_capa; in iwl_mld_scan_use_ebs()
740 * 5. the VIF is not an AP interface (scan wants survey results) in iwl_mld_scan_use_ebs()
742 return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) && in iwl_mld_scan_use_ebs()
743 !mld->scan.last_ebs_failed && in iwl_mld_scan_use_ebs()
744 vif->type != NL80211_IFTYPE_P2P_DEVICE && in iwl_mld_scan_use_ebs()
764 /* set fragmented ebs for fragmented scan */ in iwl_mld_scan_cmd_set_chan_flags()
765 if (iwl_mld_scan_is_fragmented(params->type)) in iwl_mld_scan_cmd_set_chan_flags()
768 /* Force EBS in case the scan is a fragmented and there is a need in iwl_mld_scan_cmd_set_chan_flags()
769 * to take P2P GO operation into consideration during scan operation. in iwl_mld_scan_cmd_set_chan_flags()
772 if (iwl_mld_scan_is_fragmented(params->type) && in iwl_mld_scan_cmd_set_chan_flags()
773 params->respect_p2p_go) { in iwl_mld_scan_cmd_set_chan_flags()
815 enum nl80211_band band = channels[i]->band; in iwl_mld_scan_cmd_set_channels()
816 struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i]; in iwl_mld_scan_cmd_set_channels()
820 channels[i]->hw_value); in iwl_mld_scan_cmd_set_channels()
825 cfg->flags = cpu_to_le32(flags | n_aps_flag); in iwl_mld_scan_cmd_set_channels()
826 cfg->channel_num = channels[i]->hw_value; in iwl_mld_scan_cmd_set_channels()
828 cfg->flags = 0; in iwl_mld_scan_cmd_set_channels()
831 /* 6 GHz channels should only appear in a scan request in iwl_mld_scan_cmd_set_channels()
833 * scan, which has to be passive. in iwl_mld_scan_cmd_set_channels()
835 WARN_ON_ONCE(cfg->flags != 0); in iwl_mld_scan_cmd_set_channels()
836 cfg->flags = in iwl_mld_scan_cmd_set_channels()
840 cfg->v2.iter_count = 1; in iwl_mld_scan_cmd_set_channels()
841 cfg->v2.iter_interval = 0; in iwl_mld_scan_cmd_set_channels()
842 cfg->flags |= cpu_to_le32(iwl_band << in iwl_mld_scan_cmd_set_channels()
856 params->scan_6ghz_params; in iwl_mld_scan_cfg_channels_6g()
860 for (i = 0, ch_cnt = 0; i < params->n_channels; i++) { in iwl_mld_scan_cfg_channels_6g()
862 &cp->channel_config[ch_cnt]; in iwl_mld_scan_cfg_channels_6g()
871 /* Avoid performing passive scan on non PSC channels unless the in iwl_mld_scan_cfg_channels_6g()
872 * scan is specifically a passive scan, i.e., no SSIDs in iwl_mld_scan_cfg_channels_6g()
873 * configured in the scan command. in iwl_mld_scan_cfg_channels_6g()
875 if (!cfg80211_channel_is_psc(params->channels[i]) && in iwl_mld_scan_cfg_channels_6g()
876 !params->n_6ghz_params && params->n_ssids) in iwl_mld_scan_cfg_channels_6g()
879 cfg->channel_num = params->channels[i]->hw_value; in iwl_mld_scan_cfg_channels_6g()
880 cfg->flags |= in iwl_mld_scan_cfg_channels_6g()
883 cfg->v5.iter_count = 1; in iwl_mld_scan_cfg_channels_6g()
884 cfg->v5.iter_interval = 0; in iwl_mld_scan_cfg_channels_6g()
886 for (u32 j = 0; j < params->n_6ghz_params; j++) { in iwl_mld_scan_cfg_channels_6g()
909 /* In the following cases apply passive scan: in iwl_mld_scan_cfg_channels_6g()
910 * 1. Non fragmented scan: in iwl_mld_scan_cfg_channels_6g()
911 * - PSC channel with NO_LISTEN_FLAG on should be treated in iwl_mld_scan_cfg_channels_6g()
913 * - Non PSC channel with more than 3 short SSIDs or more in iwl_mld_scan_cfg_channels_6g()
915 * - Non PSC Channel with unsolicited probe response and in iwl_mld_scan_cfg_channels_6g()
917 * - PSC channel with more than 2 short SSIDs or more than in iwl_mld_scan_cfg_channels_6g()
919 * 2. Fragmented scan: in iwl_mld_scan_cfg_channels_6g()
920 * - PSC channel with more than 1 SSID or 3 BSSIDs. in iwl_mld_scan_cfg_channels_6g()
921 * - Non PSC channel with more than 2 SSIDs or 6 BSSIDs. in iwl_mld_scan_cfg_channels_6g()
922 * - Non PSC channel with unsolicited probe response and in iwl_mld_scan_cfg_channels_6g()
925 if (!iwl_mld_scan_is_fragmented(params->type)) { in iwl_mld_scan_cfg_channels_6g()
926 if (!cfg80211_channel_is_psc(params->channels[i]) || in iwl_mld_scan_cfg_channels_6g()
939 } else if (cfg80211_channel_is_psc(params->channels[i])) { in iwl_mld_scan_cfg_channels_6g()
952 /* To optimize the scan time, i.e., reduce the scan dwell time in iwl_mld_scan_cfg_channels_6g()
957 for (u32 j = 0; j < params->n_6ghz_params; j++) { in iwl_mld_scan_cfg_channels_6g()
964 k < pp->short_ssid_num && n_s_ssids < max_s_ssids; in iwl_mld_scan_cfg_channels_6g()
967 le32_to_cpu(pp->short_ssid[k]) == in iwl_mld_scan_cfg_channels_6g()
983 !pp->direct_scan[k].len) in iwl_mld_scan_cfg_channels_6g()
986 /* Hidden AP, cannot do passive scan */ in iwl_mld_scan_cfg_channels_6g()
987 if (pp->direct_scan[k].len) in iwl_mld_scan_cfg_channels_6g()
1000 for (k = 0; k < pp->bssid_num; k++) { in iwl_mld_scan_cfg_channels_6g()
1001 if (memcmp(&pp->bssid_array[k], in iwl_mld_scan_cfg_channels_6g()
1020 if (cfg80211_channel_is_psc(params->channels[i]) && in iwl_mld_scan_cfg_channels_6g()
1029 !cfg80211_channel_is_psc(params->channels[i]))) in iwl_mld_scan_cfg_channels_6g()
1034 cfg->flags |= cpu_to_le32(flags); in iwl_mld_scan_cfg_channels_6g()
1035 cfg->v5.psd_20 = psd_20; in iwl_mld_scan_cfg_channels_6g()
1040 if (params->n_channels > ch_cnt) in iwl_mld_scan_cfg_channels_6g()
1042 "6GHz: reducing number channels: (%u->%u)\n", in iwl_mld_scan_cfg_channels_6g()
1043 params->n_channels, ch_cnt); in iwl_mld_scan_cfg_channels_6g()
1055 struct iwl_scan_channel_params_v7 *chan_p = &scan_p->channel_params; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1056 struct iwl_scan_probe_params_v4 *probe_p = &scan_p->probe_params; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1058 chan_p->flags = iwl_mld_scan_get_cmd_gen_flags(mld, params, vif, in iwl_mld_scan_cmd_set_6ghz_chan_params()
1060 chan_p->count = iwl_mld_scan_cfg_channels_6g(mld, params, in iwl_mld_scan_cmd_set_6ghz_chan_params()
1061 params->n_channels, in iwl_mld_scan_cmd_set_6ghz_chan_params()
1063 vif->type); in iwl_mld_scan_cmd_set_6ghz_chan_params()
1064 if (!chan_p->count) in iwl_mld_scan_cmd_set_6ghz_chan_params()
1065 return -EINVAL; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1067 if (!params->n_ssids || in iwl_mld_scan_cmd_set_6ghz_chan_params()
1068 (params->n_ssids == 1 && !params->ssids[0].ssid_len)) in iwl_mld_scan_cmd_set_6ghz_chan_params()
1069 chan_p->flags |= IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER; in iwl_mld_scan_cmd_set_6ghz_chan_params()
1083 struct iwl_scan_channel_params_v7 *cp = &scan_p->channel_params; in iwl_mld_scan_cmd_set_chan_params()
1085 &mld->nvm_data->bands[NL80211_BAND_6GHZ]; in iwl_mld_scan_cmd_set_chan_params()
1087 cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY; in iwl_mld_scan_cmd_set_chan_params()
1088 cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS; in iwl_mld_scan_cmd_set_chan_params()
1091 cp->n_aps_override[0] = IWL_MLD_ADAPTIVE_DWELL_NUM_APS_OVERRIDE; in iwl_mld_scan_cmd_set_chan_params()
1093 if (params->scan_6ghz) in iwl_mld_scan_cmd_set_chan_params()
1098 /* relevant only for 2.4 GHz/5 GHz scan */ in iwl_mld_scan_cmd_set_chan_params()
1099 cp->flags = iwl_mld_scan_cmd_set_chan_flags(mld, params, vif, in iwl_mld_scan_cmd_set_chan_params()
1101 cp->count = params->n_channels; in iwl_mld_scan_cmd_set_chan_params()
1103 iwl_mld_scan_cmd_set_channels(mld, params->channels, cp, in iwl_mld_scan_cmd_set_chan_params()
1104 params->n_channels, channel_cfg_flags, in iwl_mld_scan_cmd_set_chan_params()
1105 vif->type); in iwl_mld_scan_cmd_set_chan_params()
1107 if (!params->enable_6ghz_passive) in iwl_mld_scan_cmd_set_chan_params()
1110 /* fill 6 GHz passive scan cfg */ in iwl_mld_scan_cmd_set_chan_params()
1111 for (int i = 0; i < sband->n_channels; i++) { in iwl_mld_scan_cmd_set_chan_params()
1113 &sband->channels[i]; in iwl_mld_scan_cmd_set_chan_params()
1115 &cp->channel_config[cp->count]; in iwl_mld_scan_cmd_set_chan_params()
1120 cfg->channel_num = channel->hw_value; in iwl_mld_scan_cmd_set_chan_params()
1121 cfg->v5.iter_count = 1; in iwl_mld_scan_cmd_set_chan_params()
1122 cfg->v5.iter_interval = 0; in iwl_mld_scan_cmd_set_chan_params()
1123 cfg->v5.psd_20 = in iwl_mld_scan_cmd_set_chan_params()
1125 cfg->flags = cpu_to_le32(PHY_BAND_6 << in iwl_mld_scan_cmd_set_chan_params()
1127 cp->count++; in iwl_mld_scan_cmd_set_chan_params()
1139 struct iwl_scan_req_umac_v17 *cmd = mld->scan.cmd; in iwl_mld_scan_build_cmd()
1140 struct iwl_scan_req_params_v17 *scan_p = &cmd->scan_params; in iwl_mld_scan_build_cmd()
1144 memset(mld->scan.cmd, 0, mld->scan.cmd_size); in iwl_mld_scan_build_cmd()
1151 cmd->uid = cpu_to_le32(uid); in iwl_mld_scan_build_cmd()
1152 cmd->ooc_priority = in iwl_mld_scan_build_cmd()
1156 &scan_p->general_params, scan_status); in iwl_mld_scan_build_cmd()
1159 scan_p->periodic_params.schedule, in iwl_mld_scan_build_cmd()
1160 &scan_p->periodic_params.delay); in iwl_mld_scan_build_cmd()
1164 iwl_mld_scan_cmd_set_probe_params(params, &scan_p->probe_params, in iwl_mld_scan_build_cmd()
1180 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { in iwl_mld_scan_pass_all()
1182 "Sending scheduled scan with filtering, n_match_sets %d\n", in iwl_mld_scan_pass_all()
1183 req->n_match_sets); in iwl_mld_scan_pass_all()
1184 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_scan_pass_all()
1188 IWL_DEBUG_SCAN(mld, "Sending Scheduled scan without filtering\n"); in iwl_mld_scan_pass_all()
1189 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_ENABLED; in iwl_mld_scan_pass_all()
1211 if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES_V2)) in iwl_mld_config_sched_scan_profiles()
1212 return -EIO; in iwl_mld_config_sched_scan_profiles()
1216 return -ENOMEM; in iwl_mld_config_sched_scan_profiles()
1225 cfg_data = &profile_cfg->data; in iwl_mld_config_sched_scan_profiles()
1226 cfg_data->num_profiles = req->n_match_sets; in iwl_mld_config_sched_scan_profiles()
1227 cfg_data->active_clients = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1228 cfg_data->pass_match = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1229 cfg_data->match_notify = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1231 if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) in iwl_mld_config_sched_scan_profiles()
1232 cfg_data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1234 for (int i = 0; i < req->n_match_sets; i++) { in iwl_mld_config_sched_scan_profiles()
1235 profile = &profile_cfg->profiles[i]; in iwl_mld_config_sched_scan_profiles()
1238 profile->unicast_cipher = 0xff; in iwl_mld_config_sched_scan_profiles()
1239 profile->auth_alg = IWL_AUTH_ALGO_UNSUPPORTED | in iwl_mld_config_sched_scan_profiles()
1243 profile->network_type = IWL_NETWORK_TYPE_ANY; in iwl_mld_config_sched_scan_profiles()
1244 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY; in iwl_mld_config_sched_scan_profiles()
1245 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN; in iwl_mld_config_sched_scan_profiles()
1246 profile->ssid_index = i; in iwl_mld_config_sched_scan_profiles()
1250 "Sending scheduled scan profile config (n_match_sets=%u)\n", in iwl_mld_config_sched_scan_profiles()
1251 req->n_match_sets); in iwl_mld_config_sched_scan_profiles()
1268 for (i = 0; i < params->n_channels; i++) { in iwl_mld_sched_scan_handle_non_psc_channels()
1269 struct ieee80211_channel *channel = params->channels[i]; in iwl_mld_sched_scan_handle_non_psc_channels()
1271 if (channel->band == NL80211_BAND_6GHZ && in iwl_mld_sched_scan_handle_non_psc_channels()
1281 params->channels = in iwl_mld_sched_scan_handle_non_psc_channels()
1282 kmemdup(params->channels, in iwl_mld_sched_scan_handle_non_psc_channels()
1283 sizeof(params->channels[0]) * params->n_channels, in iwl_mld_sched_scan_handle_non_psc_channels()
1285 if (!params->channels) in iwl_mld_sched_scan_handle_non_psc_channels()
1286 return -ENOMEM; in iwl_mld_sched_scan_handle_non_psc_channels()
1288 for (i = j = 0; i < params->n_channels; i++) { in iwl_mld_sched_scan_handle_non_psc_channels()
1289 if (params->channels[i]->band == NL80211_BAND_6GHZ && in iwl_mld_sched_scan_handle_non_psc_channels()
1290 !cfg80211_channel_is_psc(params->channels[i])) in iwl_mld_sched_scan_handle_non_psc_channels()
1292 params->channels[j++] = params->channels[i]; in iwl_mld_sched_scan_handle_non_psc_channels()
1295 params->n_channels = j; in iwl_mld_sched_scan_handle_non_psc_channels()
1306 &mld->nvm_data->bands[NL80211_BAND_6GHZ]; in iwl_mld_scan_6ghz_passive_scan()
1309 params->enable_6ghz_passive = false; in iwl_mld_scan_6ghz_passive_scan()
1311 /* 6 GHz passive scan may be enabled in the first 2.4 GHz/5 GHz scan in iwl_mld_scan_6ghz_passive_scan()
1313 * we're in the 6 GHz scan phase. in iwl_mld_scan_6ghz_passive_scan()
1315 if (params->scan_6ghz) in iwl_mld_scan_6ghz_passive_scan()
1318 /* 6 GHz passive scan allowed only on station interface */ in iwl_mld_scan_6ghz_passive_scan()
1319 if (vif->type != NL80211_IFTYPE_STATION) { in iwl_mld_scan_6ghz_passive_scan()
1321 "6GHz passive scan: not station interface\n"); in iwl_mld_scan_6ghz_passive_scan()
1325 /* 6 GHz passive scan is allowed in a defined time interval following in iwl_mld_scan_6ghz_passive_scan()
1327 * interval has passed since the last 6 GHz passive scan. in iwl_mld_scan_6ghz_passive_scan()
1329 if ((vif->cfg.assoc || in iwl_mld_scan_6ghz_passive_scan()
1330 time_after(mld->scan.last_6ghz_passive_jiffies + in iwl_mld_scan_6ghz_passive_scan()
1332 (time_before(mld->scan.last_start_time_jiffies + in iwl_mld_scan_6ghz_passive_scan()
1335 IWL_DEBUG_SCAN(mld, "6GHz passive scan: %s\n", in iwl_mld_scan_6ghz_passive_scan()
1336 vif->cfg.assoc ? "associated" : in iwl_mld_scan_6ghz_passive_scan()
1341 /* not enough channels in the regular scan request */ in iwl_mld_scan_6ghz_passive_scan()
1342 if (params->n_channels < IWL_MLD_6GHZ_PASSIVE_SCAN_MIN_CHANS) { in iwl_mld_scan_6ghz_passive_scan()
1344 "6GHz passive scan: not enough channels %d\n", in iwl_mld_scan_6ghz_passive_scan()
1345 params->n_channels); in iwl_mld_scan_6ghz_passive_scan()
1349 for (i = 0; i < params->n_ssids; i++) { in iwl_mld_scan_6ghz_passive_scan()
1350 if (!params->ssids[i].ssid_len) in iwl_mld_scan_6ghz_passive_scan()
1354 /* not a wildcard scan, so cannot enable passive 6 GHz scan */ in iwl_mld_scan_6ghz_passive_scan()
1355 if (i == params->n_ssids) { in iwl_mld_scan_6ghz_passive_scan()
1357 "6GHz passive scan: no wildcard SSID\n"); in iwl_mld_scan_6ghz_passive_scan()
1361 if (!sband || !sband->n_channels) { in iwl_mld_scan_6ghz_passive_scan()
1363 "6GHz passive scan: no 6GHz channels\n"); in iwl_mld_scan_6ghz_passive_scan()
1367 for (i = 0, n_disabled = 0; i < sband->n_channels; i++) { in iwl_mld_scan_6ghz_passive_scan()
1368 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED)) in iwl_mld_scan_6ghz_passive_scan()
1373 * passive scan in iwl_mld_scan_6ghz_passive_scan()
1375 if (n_disabled != sband->n_channels) { in iwl_mld_scan_6ghz_passive_scan()
1377 "6GHz passive scan: 6GHz channels enabled\n"); in iwl_mld_scan_6ghz_passive_scan()
1381 /* all conditions to enable 6 GHz passive scan are satisfied */ in iwl_mld_scan_6ghz_passive_scan()
1382 IWL_DEBUG_SCAN(mld, "6GHz passive scan: can be enabled\n"); in iwl_mld_scan_6ghz_passive_scan()
1383 params->enable_6ghz_passive = true; in iwl_mld_scan_6ghz_passive_scan()
1396 if (vif->active_links) in iwl_mld_scan_set_link_id()
1397 tsf_report_link_id = __ffs(vif->active_links); in iwl_mld_scan_set_link_id()
1404 params->fw_link_id = link->fw_id; in iwl_mld_scan_set_link_id()
1405 /* we to store fw_link_id only for regular scan, in iwl_mld_scan_set_link_id()
1406 * and use it in scan complete notif in iwl_mld_scan_set_link_id()
1409 mld->scan.fw_link_id = link->fw_id; in iwl_mld_scan_set_link_id()
1411 mld->scan.fw_link_id = IWL_MLD_INVALID_FW_ID; in iwl_mld_scan_set_link_id()
1412 params->fw_link_id = IWL_MLD_INVALID_FW_ID; in iwl_mld_scan_set_link_id()
1424 .len = { mld->scan.cmd_size, }, in _iwl_mld_single_scan_start()
1425 .data = { mld->scan.cmd, }, in _iwl_mld_single_scan_start()
1436 if (WARN_ON(!mld->scan.cmd)) in _iwl_mld_single_scan_start()
1437 return -ENOMEM; in _iwl_mld_single_scan_start()
1439 if (!iwl_mld_scan_fits(mld, req->n_ssids, ies, req->n_channels)) in _iwl_mld_single_scan_start()
1440 return -ENOBUFS; in _iwl_mld_single_scan_start()
1442 ieee80211_iterate_active_interfaces_mtx(mld->hw, in _iwl_mld_single_scan_start()
1448 params.n_ssids = req->n_ssids; in _iwl_mld_single_scan_start()
1449 params.flags = req->flags; in _iwl_mld_single_scan_start()
1450 params.n_channels = req->n_channels; in _iwl_mld_single_scan_start()
1451 params.delay = 0; in _iwl_mld_single_scan_start()
1452 params.ssids = req->ssids; in _iwl_mld_single_scan_start()
1453 params.channels = req->channels; in _iwl_mld_single_scan_start()
1454 params.mac_addr = req->mac_addr; in _iwl_mld_single_scan_start()
1455 params.mac_addr_mask = req->mac_addr_mask; in _iwl_mld_single_scan_start()
1456 params.no_cck = req->no_cck; in _iwl_mld_single_scan_start()
1463 params.n_6ghz_params = req->n_6ghz_params; in _iwl_mld_single_scan_start()
1464 params.scan_6ghz_params = req->scan_6ghz_params; in _iwl_mld_single_scan_start()
1465 params.scan_6ghz = req->scan_6ghz; in _iwl_mld_single_scan_start()
1467 ether_addr_copy(params.bssid, req->bssid); in _iwl_mld_single_scan_start()
1468 /* TODO: CDB - per-band flag */ in _iwl_mld_single_scan_start()
1473 if (req->duration) in _iwl_mld_single_scan_start()
1476 iwl_mld_scan_set_link_id(mld, vif, ¶ms, req->tsf_report_link_id, in _iwl_mld_single_scan_start()
1490 IWL_ERR(mld, "Scan failed! ret %d\n", ret); in _iwl_mld_single_scan_start()
1494 IWL_DEBUG_SCAN(mld, "Scan request send success: status=%u, uid=%u\n", in _iwl_mld_single_scan_start()
1497 mld->scan.uid_status[uid] = scan_status; in _iwl_mld_single_scan_start()
1498 mld->scan.status |= scan_status; in _iwl_mld_single_scan_start()
1501 mld->scan.last_6ghz_passive_jiffies = jiffies; in _iwl_mld_single_scan_start()
1531 "Scan Abort: unexpected response length %d\n", in iwl_mld_scan_send_abort_cmd_status()
1533 ret = -EIO; in iwl_mld_scan_send_abort_cmd_status()
1537 resp = (void *)pkt->data; in iwl_mld_scan_send_abort_cmd_status()
1538 *status = le32_to_cpu(resp->status); in iwl_mld_scan_send_abort_cmd_status()
1553 IWL_DEBUG_SCAN(mld, "Sending scan abort, uid %u\n", uid); in iwl_mld_scan_abort()
1557 IWL_DEBUG_SCAN(mld, "Scan abort: ret=%d status=%u\n", ret, status); in iwl_mld_scan_abort()
1559 /* We don't need to wait to scan complete in the following cases: in iwl_mld_scan_abort()
1560 * 1. Driver failed to send the scan abort cmd. in iwl_mld_scan_abort()
1561 * 2. The FW is no longer familiar with the scan that needs to be in iwl_mld_scan_abort()
1562 * stopped. It is expected that the scan complete notification was in iwl_mld_scan_abort()
1566 * scan was really aborted. in iwl_mld_scan_abort()
1582 iwl_init_notification_wait(&mld->notif_wait, &wait_scan_done, in iwl_mld_scan_stop_wait()
1587 IWL_DEBUG_SCAN(mld, "Preparing to stop scan, type=%x\n", type); in iwl_mld_scan_stop_wait()
1591 IWL_DEBUG_SCAN(mld, "couldn't stop scan type=%d\n", type); in iwl_mld_scan_stop_wait()
1596 IWL_DEBUG_SCAN(mld, "no need to wait for scan type=%d\n", type); in iwl_mld_scan_stop_wait()
1600 return iwl_wait_notification(&mld->notif_wait, &wait_scan_done, HZ); in iwl_mld_scan_stop_wait()
1603 iwl_remove_notification(&mld->notif_wait, &wait_scan_done); in iwl_mld_scan_stop_wait()
1615 .len = { mld->scan.cmd_size, }, in iwl_mld_sched_scan_start()
1616 .data = { mld->scan.cmd, }, in iwl_mld_sched_scan_start()
1627 if (WARN_ON(!mld->scan.cmd)) in iwl_mld_sched_scan_start()
1628 return -ENOMEM; in iwl_mld_sched_scan_start()
1630 /* FW supports only a single periodic scan */ in iwl_mld_sched_scan_start()
1631 if (mld->scan.status & (IWL_MLD_SCAN_SCHED | IWL_MLD_SCAN_NETDETECT)) in iwl_mld_sched_scan_start()
1632 return -EBUSY; in iwl_mld_sched_scan_start()
1634 ieee80211_iterate_active_interfaces_mtx(mld->hw, in iwl_mld_sched_scan_start()
1640 params.flags = req->flags; in iwl_mld_sched_scan_start()
1641 params.n_ssids = req->n_ssids; in iwl_mld_sched_scan_start()
1642 params.ssids = req->ssids; in iwl_mld_sched_scan_start()
1643 params.n_channels = req->n_channels; in iwl_mld_sched_scan_start()
1644 params.channels = req->channels; in iwl_mld_sched_scan_start()
1645 params.mac_addr = req->mac_addr; in iwl_mld_sched_scan_start()
1646 params.mac_addr_mask = req->mac_addr_mask; in iwl_mld_sched_scan_start()
1649 params.n_match_sets = req->n_match_sets; in iwl_mld_sched_scan_start()
1650 params.match_sets = req->match_sets; in iwl_mld_sched_scan_start()
1651 params.n_scan_plans = req->n_scan_plans; in iwl_mld_sched_scan_start()
1652 params.scan_plans = req->scan_plans; in iwl_mld_sched_scan_start()
1653 /* TODO: CDB - per-band flag */ in iwl_mld_sched_scan_start()
1658 /* UMAC scan supports up to 16-bit delays, trim it down to 16-bits */ in iwl_mld_sched_scan_start()
1659 params.delay = req->delay > U16_MAX ? U16_MAX : req->delay; in iwl_mld_sched_scan_start()
1674 if (!iwl_mld_scan_fits(mld, req->n_ssids, ies, params.n_channels)) { in iwl_mld_sched_scan_start()
1675 ret = -ENOBUFS; in iwl_mld_sched_scan_start()
1689 "Sched scan request send success: type=%u, uid=%u\n", in iwl_mld_sched_scan_start()
1691 mld->scan.uid_status[uid] = type; in iwl_mld_sched_scan_start()
1692 mld->scan.status |= type; in iwl_mld_sched_scan_start()
1694 IWL_ERR(mld, "Sched scan failed! ret %d\n", ret); in iwl_mld_sched_scan_start()
1695 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_sched_scan_start()
1709 "Request to stop scan: type=0x%x, status=0x%x\n", in iwl_mld_scan_stop()
1710 type, mld->scan.status); in iwl_mld_scan_stop()
1712 if (!(mld->scan.status & type)) in iwl_mld_scan_stop()
1722 IWL_DEBUG_SCAN(mld, "Failed to stop scan\n"); in iwl_mld_scan_stop()
1724 /* Clear the scan status so the next scan requests will in iwl_mld_scan_stop()
1725 * succeed and mark the scan as stopping, so that the Rx in iwl_mld_scan_stop()
1726 * handler doesn't do anything, as the scan was stopped from in iwl_mld_scan_stop()
1728 * erroneously after a new scan starts, for example. in iwl_mld_scan_stop()
1730 mld->scan.status &= ~type; in iwl_mld_scan_stop()
1731 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_scan_stop()
1741 ieee80211_scan_completed(mld->hw, &info); in iwl_mld_scan_stop()
1744 ieee80211_sched_scan_stopped(mld->hw); in iwl_mld_scan_stop()
1745 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_scan_stop()
1769 IWL_DEBUG_SCAN(mld, "Starting Internal MLO scan: n_channels=%zu\n", in iwl_mld_int_mlo_scan_start()
1779 req->channels[i] = channels[i]; in iwl_mld_int_mlo_scan_start()
1781 req->n_channels = n_channels; in iwl_mld_int_mlo_scan_start()
1785 if (mld->wiphy->bands[i]) in iwl_mld_int_mlo_scan_start()
1786 req->rates[i] = in iwl_mld_int_mlo_scan_start()
1787 (1 << mld->wiphy->bands[i]->n_bitrates) - 1; in iwl_mld_int_mlo_scan_start()
1789 req->wdev = ieee80211_vif_to_wdev(vif); in iwl_mld_int_mlo_scan_start()
1790 req->wiphy = mld->wiphy; in iwl_mld_int_mlo_scan_start()
1791 req->scan_start = jiffies; in iwl_mld_int_mlo_scan_start()
1792 req->tsf_report_link_id = -1; in iwl_mld_int_mlo_scan_start()
1798 mld->scan.last_mlo_scan_time = ktime_get_boottime_ns(); in iwl_mld_int_mlo_scan_start()
1800 IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret); in iwl_mld_int_mlo_scan_start()
1810 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_int_mlo_scan()
1812 if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif) || in iwl_mld_int_mlo_scan()
1813 hweight16(vif->valid_links) == 1) in iwl_mld_int_mlo_scan()
1816 if (mld->scan.status & IWL_MLD_SCAN_INT_MLO) { in iwl_mld_int_mlo_scan()
1817 IWL_DEBUG_SCAN(mld, "Internal MLO scan is already running\n"); in iwl_mld_int_mlo_scan()
1828 channels[n_channels++] = link_conf->chanreq.oper.chan; in iwl_mld_int_mlo_scan()
1840 struct iwl_umac_scan_iter_complete_notif *notif = (void *)pkt->data; in iwl_mld_handle_scan_iter_complete_notif()
1841 u32 uid = __le32_to_cpu(notif->uid); in iwl_mld_handle_scan_iter_complete_notif()
1843 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status), in iwl_mld_handle_scan_iter_complete_notif()
1844 "FW reports out-of-range scan UID %d\n", uid)) in iwl_mld_handle_scan_iter_complete_notif()
1847 if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_REGULAR) in iwl_mld_handle_scan_iter_complete_notif()
1848 mld->scan.start_tsf = le64_to_cpu(notif->start_tsf); in iwl_mld_handle_scan_iter_complete_notif()
1851 "UMAC Scan iteration complete: status=0x%x scanned_channels=%d\n", in iwl_mld_handle_scan_iter_complete_notif()
1852 notif->status, notif->scanned_channels); in iwl_mld_handle_scan_iter_complete_notif()
1854 if (mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_FOUND) { in iwl_mld_handle_scan_iter_complete_notif()
1855 IWL_DEBUG_SCAN(mld, "Pass all scheduled scan results found\n"); in iwl_mld_handle_scan_iter_complete_notif()
1856 ieee80211_sched_scan_results(mld->hw); in iwl_mld_handle_scan_iter_complete_notif()
1857 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_ENABLED; in iwl_mld_handle_scan_iter_complete_notif()
1861 "UMAC Scan iteration complete: scan started at %llu (TSF)\n", in iwl_mld_handle_scan_iter_complete_notif()
1862 le64_to_cpu(notif->start_tsf)); in iwl_mld_handle_scan_iter_complete_notif()
1868 IWL_DEBUG_SCAN(mld, "Scheduled scan results\n"); in iwl_mld_handle_match_found_notif()
1869 ieee80211_sched_scan_results(mld->hw); in iwl_mld_handle_match_found_notif()
1875 struct iwl_umac_scan_complete *notif = (void *)pkt->data; in iwl_mld_handle_scan_complete_notif()
1876 bool aborted = (notif->status == IWL_SCAN_OFFLOAD_ABORTED); in iwl_mld_handle_scan_complete_notif()
1877 u32 uid = __le32_to_cpu(notif->uid); in iwl_mld_handle_scan_complete_notif()
1879 if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status), in iwl_mld_handle_scan_complete_notif()
1880 "FW reports out-of-range scan UID %d\n", uid)) in iwl_mld_handle_scan_complete_notif()
1884 "Scan completed: uid=%u type=%u, status=%s, EBS=%s\n", in iwl_mld_handle_scan_complete_notif()
1885 uid, mld->scan.uid_status[uid], in iwl_mld_handle_scan_complete_notif()
1886 notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? in iwl_mld_handle_scan_complete_notif()
1888 iwl_mld_scan_ebs_status_str(notif->ebs_status)); in iwl_mld_handle_scan_complete_notif()
1889 IWL_DEBUG_SCAN(mld, "Scan completed: scan_status=0x%x\n", in iwl_mld_handle_scan_complete_notif()
1890 mld->scan.status); in iwl_mld_handle_scan_complete_notif()
1892 "Scan completed: line=%u, iter=%u, elapsed time=%u\n", in iwl_mld_handle_scan_complete_notif()
1893 notif->last_schedule, notif->last_iter, in iwl_mld_handle_scan_complete_notif()
1894 __le32_to_cpu(notif->time_from_last_iter)); in iwl_mld_handle_scan_complete_notif()
1896 if (IWL_FW_CHECK(mld, !(mld->scan.uid_status[uid] & mld->scan.status), in iwl_mld_handle_scan_complete_notif()
1897 "FW reports scan UID %d we didn't trigger\n", uid)) in iwl_mld_handle_scan_complete_notif()
1900 /* if the scan is already stopping, we don't need to notify mac80211 */ in iwl_mld_handle_scan_complete_notif()
1901 if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_REGULAR) { in iwl_mld_handle_scan_complete_notif()
1904 .scan_start_tsf = mld->scan.start_tsf, in iwl_mld_handle_scan_complete_notif()
1906 int fw_link_id = mld->scan.fw_link_id; in iwl_mld_handle_scan_complete_notif()
1911 wiphy_dereference(mld->wiphy, in iwl_mld_handle_scan_complete_notif()
1912 mld->fw_id_to_bss_conf[fw_link_id]); in iwl_mld_handle_scan_complete_notif()
1914 /* It is possible that by the time the scan is complete the in iwl_mld_handle_scan_complete_notif()
1918 ether_addr_copy(info.tsf_bssid, link_conf->bssid); in iwl_mld_handle_scan_complete_notif()
1920 IWL_DEBUG_SCAN(mld, "Scan link is no longer valid\n"); in iwl_mld_handle_scan_complete_notif()
1922 ieee80211_scan_completed(mld->hw, &info); in iwl_mld_handle_scan_complete_notif()
1923 } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_SCHED) { in iwl_mld_handle_scan_complete_notif()
1924 ieee80211_sched_scan_stopped(mld->hw); in iwl_mld_handle_scan_complete_notif()
1925 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_handle_scan_complete_notif()
1926 } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_INT_MLO) { in iwl_mld_handle_scan_complete_notif()
1927 IWL_DEBUG_SCAN(mld, "Internal MLO scan completed\n"); in iwl_mld_handle_scan_complete_notif()
1936 mld->scan.status &= ~mld->scan.uid_status[uid]; in iwl_mld_handle_scan_complete_notif()
1938 IWL_DEBUG_SCAN(mld, "Scan completed: after update: scan_status=0x%x\n", in iwl_mld_handle_scan_complete_notif()
1939 mld->scan.status); in iwl_mld_handle_scan_complete_notif()
1941 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_handle_scan_complete_notif()
1943 if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS && in iwl_mld_handle_scan_complete_notif()
1944 notif->ebs_status != IWL_SCAN_EBS_INACTIVE) in iwl_mld_handle_scan_complete_notif()
1945 mld->scan.last_ebs_failed = true; in iwl_mld_handle_scan_complete_notif()
1961 ieee80211_scan_completed(mld->hw, &info); in iwl_mld_report_scan_aborted()
1962 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_report_scan_aborted()
1967 mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; in iwl_mld_report_scan_aborted()
1968 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_report_scan_aborted()
1970 /* sched scan will be restarted by mac80211 in reconfig. in iwl_mld_report_scan_aborted()
1971 * report to mac80211 that sched scan stopped only if we won't in iwl_mld_report_scan_aborted()
1975 ieee80211_sched_scan_stopped(mld->hw); in iwl_mld_report_scan_aborted()
1980 IWL_DEBUG_SCAN(mld, "Internal MLO scan aborted\n"); in iwl_mld_report_scan_aborted()
1981 mld->scan.uid_status[uid] = IWL_MLD_SCAN_NONE; in iwl_mld_report_scan_aborted()
1985 memset(mld->scan.uid_status, 0, sizeof(mld->scan.uid_status)); in iwl_mld_report_scan_aborted()
1990 u8 scan_cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, SCAN_REQ_UMAC, in iwl_mld_alloc_scan_cmd()
1997 IWL_ERR(mld, "Unexpected scan cmd version %d\n", scan_cmd_ver); in iwl_mld_alloc_scan_cmd()
1998 return -EINVAL; in iwl_mld_alloc_scan_cmd()
2001 mld->scan.cmd = kmalloc(scan_cmd_size, GFP_KERNEL); in iwl_mld_alloc_scan_cmd()
2002 if (!mld->scan.cmd) in iwl_mld_alloc_scan_cmd()
2003 return -ENOMEM; in iwl_mld_alloc_scan_cmd()
2005 mld->scan.cmd_size = scan_cmd_size; in iwl_mld_alloc_scan_cmd()