Lines Matching defs:mvm
11 #include "mvm.h"
110 static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm)
112 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
114 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
117 if (iwl_mvm_is_adaptive_dwell_supported(mvm))
120 if (iwl_mvm_cdb_scan_api(mvm))
127 iwl_mvm_get_scan_req_umac_channel(struct iwl_mvm *mvm)
129 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
131 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
134 if (iwl_mvm_is_adaptive_dwell_supported(mvm))
137 if (iwl_mvm_cdb_scan_api(mvm))
143 static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
145 if (mvm->scan_rx_ant != ANT_NONE)
146 return mvm->scan_rx_ant;
147 return iwl_mvm_get_valid_rx_ant(mvm);
150 static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
155 rx_ant = iwl_mvm_scan_rx_ant(mvm);
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;
179 static enum iwl_mvm_traffic_load iwl_mvm_get_traffic_load(struct iwl_mvm *mvm)
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];
220 iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
239 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
247 if (fw_has_api(&mvm->fw->ucode_capa,
269 iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
275 load = iwl_mvm_get_traffic_load(mvm);
276 low_latency = iwl_mvm_low_latency(mvm);
278 return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
282 iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
289 load = iwl_mvm_get_traffic_load_band(mvm, band);
290 low_latency = iwl_mvm_low_latency_band(mvm, band);
292 return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
295 static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm)
298 return fw_has_capa(&mvm->fw->ucode_capa,
302 static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm)
312 if (iwl_mvm_rrm_scan_needed(mvm))
318 int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
320 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm);
335 void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
341 IWL_DEBUG_SCAN(mvm,
345 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
346 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
347 ieee80211_sched_scan_results(mvm->hw);
348 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
352 void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
355 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
356 ieee80211_sched_scan_results(mvm->hw);
373 void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
383 if (WARN_ON_ONCE(fw_has_capa(&mvm->fw->ucode_capa,
388 lockdep_assert_held(&mvm->mutex);
400 if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_SCHED) {
401 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR);
403 IWL_DEBUG_SCAN(mvm, "Scheduled scan %s, EBS status %s\n",
406 IWL_DEBUG_SCAN(mvm,
412 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_SCHED;
413 } else if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR) {
414 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s\n",
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);
422 IWL_DEBUG_SCAN(mvm, "Scheduled scan %s, EBS status %s\n",
425 IWL_DEBUG_SCAN(mvm,
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) {
439 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n",
443 mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
444 ieee80211_scan_completed(mvm->hw, &info);
445 cancel_delayed_work(&mvm->scan_timeout_dwork);
446 iwl_mvm_resume_tcm(mvm);
448 IWL_ERR(mvm,
452 mvm->last_ebs_successful =
525 iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
532 int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
548 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
599 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n");
601 ret = iwl_mvm_send_cmd(mvm, &cmd);
609 static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
613 IWL_DEBUG_SCAN(mvm,
616 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
620 IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n");
622 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
626 static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm)
634 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
646 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status);
653 static void iwl_mvm_scan_fill_tx_cmd(struct iwl_mvm *mvm,
659 tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
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;
679 tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
685 iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm,
704 static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies,
716 if (!iwl_mvm_rrm_scan_needed(mvm)) {
755 iwl_mvm_build_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
789 newpos = iwl_mvm_copy_and_insert_ds_elem(mvm,
813 if (iwl_mvm_rrm_scan_needed(mvm) &&
814 !fw_has_capa(&mvm->fw->ucode_capa,
824 static void iwl_mvm_scan_lmac_dwell(struct iwl_mvm *mvm,
837 static inline bool iwl_mvm_scan_fits(struct iwl_mvm *mvm, int n_ssids,
842 (n_channels <= mvm->fw->ucode_capa.n_scan_channels) &
846 iwl_mvm_max_scan_ie_fw_cmd_room(mvm)));
849 static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm *mvm,
852 const struct iwl_ucode_capabilities *capa = &mvm->fw->ucode_capa;
855 if (iwl_mvm_is_cdb_supported(mvm))
856 low_latency = iwl_mvm_low_latency_band(mvm, NL80211_BAND_5GHZ);
858 low_latency = iwl_mvm_low_latency(mvm);
870 mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS &&
872 (!low_latency || iwl_mvm_is_frag_ebs_supported(mvm)) &&
888 static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
903 if (iwl_mvm_rrm_scan_needed(mvm) &&
904 fw_has_capa(&mvm->fw->ucode_capa,
914 if (mvm->scan_iter_notif_enabled)
918 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
942 static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
945 struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
948 mvm->fw->ucode_capa.n_scan_channels);
956 iwl_mvm_scan_lmac_dwell(mvm, cmd, params);
958 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
964 cmd->scan_flags = cpu_to_le32(iwl_mvm_scan_lmac_flags(mvm, params,
971 iwl_mvm_scan_fill_tx_cmd(mvm, cmd->tx_cmd, params->no_cck);
996 if (iwl_mvm_scan_use_ebs(mvm, vif)) {
1011 iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
1039 static __le32 iwl_mvm_scan_config_rates(struct iwl_mvm *mvm)
1045 band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
1048 band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
1058 static void iwl_mvm_fill_scan_dwell(struct iwl_mvm *mvm,
1067 static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels,
1073 band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
1076 band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
1081 static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
1085 enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL);
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);
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;
1105 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1108 static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config,
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);
1119 if (iwl_mvm_is_cdb_supported(mvm)) {
1122 lb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
1124 hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
1138 iwl_mvm_get_scan_type(mvm, NULL);
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;
1156 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1159 static int iwl_mvm_legacy_config_scan(struct iwl_mvm *mvm)
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;
1177 if (iwl_mvm_is_cdb_supported(mvm)) {
1178 type = iwl_mvm_get_scan_type_band(mvm, NULL,
1180 hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
1182 if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
1185 type = iwl_mvm_get_scan_type(mvm, NULL);
1186 if (type == mvm->scan_type)
1190 if (iwl_mvm_cdb_scan_api(mvm))
1194 cmd_size += mvm->fw->ucode_capa.n_scan_channels;
1223 if (iwl_mvm_cdb_scan_api(mvm)) {
1224 if (iwl_mvm_is_cdb_supported(mvm))
1228 iwl_mvm_fill_scan_config_v2(mvm, cfg, flags, channel_flags,
1231 iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags,
1239 IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
1241 ret = iwl_mvm_send_cmd(mvm, &cmd);
1243 mvm->scan_type = type;
1244 mvm->hb_scan_type = hb_type;
1251 int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1261 if (!iwl_mvm_is_reduced_config_scan_supported(mvm))
1262 return iwl_mvm_legacy_config_scan(mvm);
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) {
1276 cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1277 cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1279 IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
1281 return iwl_mvm_send_cmd(mvm, &cmd);
1284 static int iwl_mvm_scan_uid_by_status(struct iwl_mvm *mvm, int status)
1288 for (i = 0; i < mvm->max_scans; i++)
1289 if (mvm->scan_uid_status[i] == status)
1295 static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm,
1306 if (iwl_mvm_is_adaptive_dwell_supported(mvm)) {
1312 if (iwl_mvm_is_adwell_hb_ap_num_supported(mvm))
1333 if (iwl_mvm_is_cdb_supported(mvm)) {
1342 if (!iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
1349 if (iwl_mvm_is_cdb_supported(mvm)) {
1362 if (iwl_mvm_is_cdb_supported(mvm)) {
1371 if (iwl_mvm_cdb_scan_api(mvm)) {
1405 iwl_mvm_scan_umac_dwell_v11(struct iwl_mvm *mvm,
1592 iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
1602 if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
1617 iwl_mvm_umac_scan_cfg_channels_v4(struct iwl_mvm *mvm,
1646 iwl_mvm_umac_scan_cfg_channels_v7(struct iwl_mvm *mvm,
1688 iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm *mvm,
1695 bool hidden_supported = fw_has_capa(&mvm->fw->ucode_capa,
1763 iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
1963 IWL_DEBUG_SCAN(mvm,
1970 static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
1978 if (iwl_mvm_scan_use_ebs(mvm, vif))
1984 if ((!iwl_mvm_is_cdb_supported(mvm) &&
1986 (iwl_mvm_is_cdb_supported(mvm) &&
1994 if ((!iwl_mvm_is_cdb_supported(mvm) &&
1996 (iwl_mvm_is_cdb_supported(mvm) &&
1999 IWL_DEBUG_SCAN(mvm, "Respect P2P GO. Force EBS\n");
2006 static void iwl_mvm_scan_6ghz_passive_scan(struct iwl_mvm *mvm,
2011 &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
2019 if (!fw_has_capa(&mvm->fw->ucode_capa,
2021 IWL_DEBUG_SCAN(mvm,
2028 IWL_DEBUG_SCAN(mvm,
2039 time_after(mvm->last_6ghz_passive_scan_jiffies +
2041 (time_before(mvm->last_reset_or_resume_time_jiffies +
2044 IWL_DEBUG_SCAN(mvm, "6GHz passive scan: %s\n",
2052 IWL_DEBUG_SCAN(mvm,
2064 IWL_DEBUG_SCAN(mvm,
2070 IWL_DEBUG_SCAN(mvm,
2085 IWL_DEBUG_SCAN(mvm,
2091 IWL_DEBUG_SCAN(mvm, "6GHz passive scan: can be enabled\n");
2095 static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
2128 mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
2144 if (iwl_mvm_is_oce_supported(mvm) &&
2153 static u8 iwl_mvm_scan_umac_flags2(struct iwl_mvm *mvm,
2160 if (iwl_mvm_is_cdb_supported(mvm)) {
2172 fw_has_capa(&mvm->fw->ucode_capa,
2179 iwl_fw_lookup_notif_ver(mvm->fw, SCAN_GROUP, CHANNEL_SURVEY_NOTIF,
2186 static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
2201 if (iwl_mvm_is_cdb_supported(mvm) &&
2205 if (iwl_mvm_rrm_scan_needed(mvm) &&
2206 fw_has_capa(&mvm->fw->ucode_capa,
2222 if (mvm->scan_iter_notif_enabled)
2226 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
2229 if (iwl_mvm_is_adaptive_dwell_supported(mvm) && IWL_MVM_ADWELL_ENABLE)
2240 !iwl_mvm_is_adaptive_dwell_supported(mvm) &&
2241 !iwl_mvm_is_oce_supported(mvm))
2244 if (iwl_mvm_is_oce_supported(mvm)) {
2255 !WARN_ON_ONCE(!iwl_mvm_is_adaptive_dwell_supported(mvm)))
2297 static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2301 struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
2303 void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
2305 mvm->fw->ucode_capa.n_scan_channels;
2316 chan_param = iwl_mvm_get_scan_req_umac_channel(mvm);
2318 iwl_mvm_scan_umac_dwell(mvm, cmd, params);
2321 gen_flags = iwl_mvm_scan_umac_flags(mvm, params, vif);
2323 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
2340 if (iwl_mvm_scan_use_ebs(mvm, vif)) {
2346 if (iwl_mvm_is_frag_ebs_supported(mvm)) {
2349 (!iwl_mvm_is_cdb_supported(mvm) &&
2363 if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
2373 iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
2380 iwl_mvm_scan_umac_fill_general_p_v12(struct iwl_mvm *mvm,
2389 iwl_mvm_scan_umac_dwell_v11(mvm, gp, params);
2391 IWL_DEBUG_SCAN(mvm, "General: flags=0x%x, flags2=0x%x\n",
2402 mvm->scan_link_id = 0;
2410 mvm->scan_link_id = params->tsf_report_link_id;
2435 iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm,
2441 cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
2445 iwl_mvm_umac_scan_cfg_channels_v4(mvm, params->channels, cp,
2452 iwl_mvm_scan_umac_fill_ch_p_v7(struct iwl_mvm *mvm,
2459 cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
2464 iwl_mvm_umac_scan_cfg_channels_v7(mvm, params->channels, cp,
2471 &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
2502 static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2506 struct iwl_scan_req_umac_v12 *cmd = mvm->scan_cmd;
2514 gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
2515 iwl_mvm_scan_umac_fill_general_p_v12(mvm, params, vif,
2526 iwl_mvm_scan_umac_fill_ch_p_v4(mvm, params, vif,
2532 static int iwl_mvm_scan_umac_v14_and_above(struct iwl_mvm *mvm,
2537 struct iwl_scan_req_umac_v17 *cmd = mvm->scan_cmd;
2549 gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
2552 gen_flags2 = iwl_mvm_scan_umac_flags2(mvm, params, vif, type,
2557 iwl_mvm_scan_umac_fill_general_p_v12(mvm, params, vif,
2571 iwl_mvm_scan_umac_fill_ch_p_v7(mvm, params, vif,
2580 cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
2584 iwl_mvm_umac_scan_fill_6g_chan_list(mvm, params, pb);
2586 cp->count = iwl_mvm_umac_scan_cfg_channels_v7_6g(mvm, params,
2600 static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2604 return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 14);
2607 static int iwl_mvm_scan_umac_v15(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2611 return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 15);
2614 static int iwl_mvm_scan_umac_v16(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2618 return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 16);
2621 static int iwl_mvm_scan_umac_v17(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2625 return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 17);
2628 static int iwl_mvm_num_scans(struct iwl_mvm *mvm)
2630 return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK);
2633 static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
2635 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
2650 mvm->scan_status & (IWL_MVM_SCAN_SCHED | IWL_MVM_SCAN_NETDETECT))
2653 if (iwl_mvm_num_scans(mvm) < mvm->max_scans)
2661 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
2663 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
2665 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
2667 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
2683 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
2684 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR,
2686 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
2687 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED,
2706 struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm,
2709 IWL_ERR(mvm, "regular scan timed out\n");
2711 iwl_force_nmi(mvm->trans);
2714 static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
2718 if (iwl_mvm_is_cdb_supported(mvm)) {
2720 iwl_mvm_get_scan_type_band(mvm, vif,
2723 iwl_mvm_get_scan_type_band(mvm, vif,
2726 params->type = iwl_mvm_get_scan_type(mvm, vif);
2732 int (*handler)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2754 struct iwl_mvm *mvm =
2760 mutex_lock(&mvm->mutex);
2761 info = iwl_mvm_get_csme_conn_info(mvm);
2763 mutex_unlock(&mvm->mutex);
2769 ieee80211_rx_irqsafe(mvm->hw, skb);
2785 static void iwl_mvm_mei_limited_scan(struct iwl_mvm *mvm,
2788 struct iwl_mvm_csme_conn_info *info = iwl_mvm_get_csme_conn_info(mvm);
2794 IWL_DEBUG_SCAN(mvm, "mei_limited_scan: no connection info\n");
2805 mvm->mei_scan_filter.is_mei_limited_scan = true;
2807 chan = ieee80211_get_channel(mvm->hw->wiphy,
2811 IWL_DEBUG_SCAN(mvm,
2826 IWL_DEBUG_SCAN(mvm, "Mei scan: num iterations=%u\n", scan_iters);
2833 static int iwl_mvm_build_scan_cmd(struct iwl_mvm *mvm,
2842 lockdep_assert_held(&mvm->mutex);
2843 memset(mvm->scan_cmd, 0, mvm->scan_cmd_size);
2845 iwl_mvm_mei_limited_scan(mvm, params);
2847 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
2850 return iwl_mvm_scan_lmac(mvm, vif, params);
2853 uid = iwl_mvm_scan_uid_by_status(mvm, 0);
2859 scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC,
2869 err = ver_handler->handler(mvm, vif, params, type, uid);
2873 err = iwl_mvm_scan_umac(mvm, vif, params, type, uid);
2915 static bool _iwl_mvm_get_respect_p2p_go(struct iwl_mvm *mvm,
2929 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
2937 static bool iwl_mvm_get_respect_p2p_go_band(struct iwl_mvm *mvm,
2941 bool low_latency = iwl_mvm_low_latency_band(mvm, band);
2943 return _iwl_mvm_get_respect_p2p_go(mvm, vif, low_latency, band);
2946 static bool iwl_mvm_get_respect_p2p_go(struct iwl_mvm *mvm,
2949 bool low_latency = iwl_mvm_low_latency(mvm);
2951 return _iwl_mvm_get_respect_p2p_go(mvm, vif, low_latency,
2955 static void iwl_mvm_fill_respect_p2p_go(struct iwl_mvm *mvm,
2959 if (iwl_mvm_is_cdb_supported(mvm)) {
2961 iwl_mvm_get_respect_p2p_go_band(mvm, vif,
2964 iwl_mvm_get_respect_p2p_go_band(mvm, vif,
2967 params->respect_p2p_go = iwl_mvm_get_respect_p2p_go(mvm, vif);
2971 static int _iwl_mvm_single_scan_start(struct iwl_mvm *mvm,
2978 .len = { iwl_mvm_scan_size(mvm), },
2979 .data = { mvm->scan_cmd, },
2986 lockdep_assert_held(&mvm->mutex);
2988 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
2989 IWL_ERR(mvm, "scan while LAR regdomain is not set\n");
2993 ret = iwl_mvm_check_running_scans(mvm, type);
2998 if (WARN_ON(!mvm->scan_cmd))
3001 if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, req->n_channels))
3024 iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
3025 iwl_mvm_fill_respect_p2p_go(mvm, ¶ms, vif);
3038 iwl_mvm_build_scan_probe(mvm, vif, ies, ¶ms);
3040 iwl_mvm_scan_6ghz_passive_scan(mvm, ¶ms, vif);
3042 uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, ¶ms, type);
3047 iwl_mvm_pause_tcm(mvm, false);
3049 ret = iwl_mvm_send_cmd(mvm, &hcmd);
3055 IWL_ERR(mvm, "Scan failed! ret %d\n", ret);
3056 iwl_mvm_resume_tcm(mvm);
3060 IWL_DEBUG_SCAN(mvm, "Scan request send success: type=%u, uid=%u\n",
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;
3078 int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
3082 return _iwl_mvm_single_scan_start(mvm, vif, req, ies,
3086 int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
3093 .len = { iwl_mvm_scan_size(mvm), },
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");
3109 ret = iwl_mvm_check_running_scans(mvm, type);
3114 if (WARN_ON(!mvm->scan_cmd))
3126 params.pass_all = iwl_mvm_scan_pass_all(mvm, req);
3136 iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
3137 iwl_mvm_fill_respect_p2p_go(mvm, ¶ms, vif);
3145 IWL_DEBUG_SCAN(mvm,
3152 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
3156 iwl_mvm_build_scan_probe(mvm, vif, ies, ¶ms);
3186 if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, params.n_channels)) {
3191 uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, ¶ms, type);
3197 ret = iwl_mvm_send_cmd(mvm, &hcmd);
3199 IWL_DEBUG_SCAN(mvm,
3202 mvm->scan_uid_status[uid] = type;
3203 mvm->scan_status |= type;
3209 IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret);
3210 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
3219 void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
3228 mvm->mei_scan_filter.is_mei_limited_scan = false;
3230 IWL_DEBUG_SCAN(mvm,
3232 uid, mvm->scan_uid_status[uid],
3237 IWL_DEBUG_SCAN(mvm, "Scan completed: scan_status=0x%x\n",
3238 mvm->scan_status);
3240 IWL_DEBUG_SCAN(mvm,
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];
3264 IWL_DEBUG_SCAN(mvm, "Scan link is no longer valid\n");
3266 ieee80211_scan_completed(mvm->hw, &info);
3267 mvm->scan_vif = NULL;
3268 cancel_delayed_work(&mvm->scan_timeout_dwork);
3269 iwl_mvm_resume_tcm(mvm);
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) {
3274 IWL_DEBUG_SCAN(mvm, "Internal MLO scan completed\n");
3282 mvm->scan_status &= ~mvm->scan_uid_status[uid];
3284 IWL_DEBUG_SCAN(mvm, "Scan completed: after update: scan_status=0x%x\n",
3285 mvm->scan_status);
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);
3297 void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
3303 mvm->scan_start = le64_to_cpu(notif->start_tsf);
3305 IWL_DEBUG_SCAN(mvm,
3309 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
3310 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
3311 ieee80211_sched_scan_results(mvm->hw);
3312 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
3315 IWL_DEBUG_SCAN(mvm,
3317 mvm->scan_start);
3320 static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
3325 lockdep_assert_held(&mvm->mutex);
3331 uid = iwl_mvm_scan_uid_by_status(mvm, type);
3337 IWL_DEBUG_SCAN(mvm, "Sending scan abort, uid %u\n", uid);
3339 ret = iwl_mvm_send_cmd_pdu(mvm,
3343 mvm->scan_uid_status[uid] = type << IWL_MVM_SCAN_STOPPING_SHIFT;
3345 IWL_DEBUG_SCAN(mvm, "Scan abort: ret=%d\n", ret);
3349 static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
3356 lockdep_assert_held(&mvm->mutex);
3358 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
3363 IWL_DEBUG_SCAN(mvm, "Preparing to stop scan, type %x\n", type);
3365 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
3366 ret = iwl_mvm_umac_scan_abort(mvm, type);
3368 ret = iwl_mvm_lmac_scan_abort(mvm);
3371 IWL_DEBUG_SCAN(mvm, "couldn't stop scan type %d\n", type);
3372 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
3376 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_done,
3395 size_t iwl_mvm_scan_size(struct iwl_mvm *mvm)
3398 u8 scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC,
3406 if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
3408 else if (iwl_mvm_is_adaptive_dwell_supported(mvm))
3410 else if (iwl_mvm_cdb_scan_api(mvm))
3415 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
3416 if (iwl_mvm_is_scan_ext_chan_supported(mvm))
3423 mvm->fw->ucode_capa.n_scan_channels +
3428 mvm->fw->ucode_capa.n_scan_channels +
3436 void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
3438 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
3441 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_REGULAR);
3447 cancel_delayed_work(&mvm->scan_timeout_dwork);
3449 ieee80211_scan_completed(mvm->hw, &info);
3450 mvm->scan_uid_status[uid] = 0;
3452 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED);
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;
3463 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_INT_MLO);
3465 IWL_DEBUG_SCAN(mvm, "Internal MLO scan aborted\n");
3466 mvm->scan_uid_status[uid] = 0;
3469 uid = iwl_mvm_scan_uid_by_status(mvm,
3472 mvm->scan_uid_status[uid] = 0;
3474 uid = iwl_mvm_scan_uid_by_status(mvm,
3477 mvm->scan_uid_status[uid] = 0;
3479 uid = iwl_mvm_scan_uid_by_status(mvm,
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;
3516 int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
3520 IWL_DEBUG_SCAN(mvm,
3522 type, mvm->scan_status);
3524 if (!(mvm->scan_status & type))
3527 if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) {
3532 ret = iwl_mvm_scan_stop_wait(mvm, type);
3534 mvm->scan_status |= type << IWL_MVM_SCAN_STOPPING_SHIFT;
3536 IWL_DEBUG_SCAN(mvm, "Failed to stop scan\n");
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;
3563 static int iwl_mvm_int_mlo_scan_start(struct iwl_mvm *mvm,
3573 lockdep_assert_held(&mvm->mutex);
3575 IWL_DEBUG_SCAN(mvm, "Starting Internal MLO scan: n_channels=%zu\n",
3594 if (mvm->hw->wiphy->bands[i])
3596 (1 << mvm->hw->wiphy->bands[i]->n_bitrates) - 1;
3599 req->wiphy = mvm->hw->wiphy;
3603 ret = _iwl_mvm_single_scan_start(mvm, vif, req, &ies,
3607 IWL_DEBUG_SCAN(mvm, "Internal MLO scan: ret=%d\n", ret);
3611 int iwl_mvm_int_mlo_scan(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
3618 lockdep_assert_held(&mvm->mutex);
3620 if (mvm->scan_status & IWL_MVM_SCAN_INT_MLO) {
3621 IWL_DEBUG_SCAN(mvm, "Internal MLO scan is already running\n");
3642 return iwl_mvm_int_mlo_scan_start(mvm, vif, channels, n_channels);
3645 static int iwl_mvm_chanidx_from_phy(struct iwl_mvm *mvm,
3649 struct ieee80211_supported_band *sband = mvm->hw->wiphy->bands[band];
3776 void iwl_mvm_rx_channel_survey_notif(struct iwl_mvm *mvm,
3786 lockdep_assert_held(&mvm->mutex);
3788 if (!mvm->acs_survey) {
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;
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;
3818 chan_idx = iwl_mvm_chanidx_from_phy(mvm, band,
3823 IWL_DEBUG_SCAN(mvm, "channel survey received for freq %d\n",
3824 mvm->hw->wiphy->bands[band]->channels[chan_idx].center_freq);
3826 info = &mvm->acs_survey->bands[band][chan_idx];