1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * DOC: wlan_cm_roam_offload.c 22 * 23 * Implementation for the common roaming offload api interfaces. 24 */ 25 26 #include "wlan_mlme_main.h" 27 #include "wlan_cm_roam_offload.h" 28 #include "wlan_cm_tgt_if_tx_api.h" 29 #include "wlan_cm_roam_api.h" 30 #include "wlan_mlme_vdev_mgr_interface.h" 31 #include "wlan_crypto_global_api.h" 32 #include "wlan_psoc_mlme_api.h" 33 #include "pld_common.h" 34 #include "wlan_dlm_api.h" 35 #include "wlan_scan_api.h" 36 #include "wlan_vdev_mgr_ucfg_api.h" 37 #include "wlan_p2p_cfg_api.h" 38 #include "wlan_cm_vdev_api.h" 39 #include "cfg_nan_api.h" 40 #include "wlan_mlme_api.h" 41 #include "connection_mgr/core/src/wlan_cm_roam.h" 42 #include "connection_mgr/core/src/wlan_cm_main.h" 43 #include "connection_mgr/core/src/wlan_cm_sm.h" 44 #include "wlan_reg_ucfg_api.h" 45 #include "wlan_connectivity_logging.h" 46 #include "wlan_if_mgr_roam.h" 47 #include "wlan_roam_debug.h" 48 #include "wlan_mlo_mgr_roam.h" 49 #include "wlan_mlo_mgr_sta.h" 50 #include "wlan_mlme_api.h" 51 #include "wlan_policy_mgr_api.h" 52 #include "wlan_mlo_mgr_link_switch.h" 53 #include "wlan_mlo_mgr_sta.h" 54 55 #ifdef WLAN_FEATURE_SAE 56 #define CM_IS_FW_FT_SAE_SUPPORTED(fw_akm_bitmap) \ 57 (((fw_akm_bitmap) & (1 << AKM_FT_SAE)) ? true : false) 58 59 #define CM_IS_FW_SAE_ROAM_SUPPORTED(fw_akm_bitmap) \ 60 (((fw_akm_bitmap) & (1 << AKM_SAE)) ? true : false) 61 62 #define CM_IS_FW_SAE_EXT_ROAM_SUPPORTED(fw_akm_bitmap) \ 63 (((fw_akm_bitmap) & (1 << AKM_SAE_EXT)) ? true : false) 64 #else 65 #define CM_IS_FW_FT_SAE_SUPPORTED(fw_akm_bitmap) (false) 66 67 #define CM_IS_FW_SAE_ROAM_SUPPORTED(fw_akm_bitmap) (false) 68 69 #define CM_IS_FW_SAE_EXT_SUPPORTED(fw_akm_bitmap) (false) 70 #endif 71 72 /** 73 * cm_roam_scan_bmiss_cnt() - set roam beacon miss count 74 * @psoc: psoc pointer 75 * @vdev_id: vdev id 76 * @params: roam beacon miss count parameters 77 * 78 * This function is used to set roam beacon miss count parameters 79 * 80 * Return: None 81 */ 82 static void 83 cm_roam_scan_bmiss_cnt(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 84 struct wlan_roam_beacon_miss_cnt *params) 85 { 86 uint8_t beacon_miss_count; 87 88 params->vdev_id = vdev_id; 89 90 wlan_mlme_get_roam_bmiss_first_bcnt(psoc, &beacon_miss_count); 91 params->roam_bmiss_first_bcnt = beacon_miss_count; 92 93 wlan_mlme_get_roam_bmiss_final_bcnt(psoc, &beacon_miss_count); 94 params->roam_bmiss_final_bcnt = beacon_miss_count; 95 } 96 97 /** 98 * cm_roam_scan_bmiss_timeout() - set connection bmiss timeout 99 * @psoc: psoc pointer 100 * @vdev_id: vdev id 101 * @params: roam bmiss timeout parameters 102 * 103 * This function is used to set roam conbmiss timeout parameters 104 * 105 * Return: None 106 */ 107 static void 108 cm_roam_scan_bmiss_timeout(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 109 struct wlan_roam_bmiss_timeout *params) 110 { 111 uint8_t bmiss_timeout; 112 113 params->vdev_id = vdev_id; 114 115 wlan_mlme_get_bmiss_timeout_on_wakeup(psoc, &bmiss_timeout); 116 params->bmiss_timeout_onwakeup = bmiss_timeout; 117 118 wlan_mlme_get_bmiss_timeout_on_sleep(psoc, &bmiss_timeout); 119 params->bmiss_timeout_onsleep = bmiss_timeout; 120 } 121 122 QDF_STATUS 123 cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 124 struct wlan_roam_rssi_change_params *params) 125 { 126 struct cm_roam_values_copy temp; 127 128 params->vdev_id = vdev_id; 129 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 130 RSSI_CHANGE_THRESHOLD, &temp); 131 params->rssi_change_thresh = temp.int_value; 132 133 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 134 BEACON_RSSI_WEIGHT, &temp); 135 params->bcn_rssi_weight = temp.uint_value; 136 137 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 138 HI_RSSI_DELAY_BTW_SCANS, &temp); 139 params->hirssi_delay_btw_scans = temp.uint_value; 140 141 return QDF_STATUS_SUCCESS; 142 } 143 144 /** 145 * cm_roam_is_per_roam_allowed() - Check if PER roam trigger needs to be 146 * disabled based on the current connected rates. 147 * @psoc: Pointer to the psoc object 148 * @vdev_id: Vdev id 149 * 150 * Return: true if PER roam trigger is allowed 151 */ 152 static bool 153 cm_roam_is_per_roam_allowed(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 154 { 155 struct qdf_mac_addr connected_bssid = {0}; 156 struct wlan_objmgr_vdev *vdev; 157 enum wlan_phymode peer_phymode = WLAN_PHYMODE_AUTO; 158 QDF_STATUS status; 159 160 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 161 WLAN_MLME_CM_ID); 162 if (!vdev) { 163 mlme_err("Vdev is null for vdev_id:%d", vdev_id); 164 return false; 165 } 166 167 status = wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid); 168 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 169 170 if (QDF_IS_STATUS_ERROR(status)) 171 return false; 172 173 mlme_get_peer_phymode(psoc, connected_bssid.bytes, &peer_phymode); 174 if (peer_phymode < WLAN_PHYMODE_11NA_HT20) { 175 mlme_debug("vdev:%d PER roam trigger disabled for phymode:%d", 176 peer_phymode, vdev_id); 177 return false; 178 } 179 180 return true; 181 } 182 183 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 184 /** 185 * cm_roam_reason_vsie() - set roam reason vsie 186 * @psoc: psoc pointer 187 * @vdev_id: vdev id 188 * @params: roam reason vsie parameters 189 * 190 * This function is used to set roam reason vsie parameters 191 * 192 * Return: None 193 */ 194 static void 195 cm_roam_reason_vsie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 196 struct wlan_roam_reason_vsie_enable *params) 197 { 198 uint8_t enable_roam_reason_vsie; 199 200 params->vdev_id = vdev_id; 201 202 wlan_mlme_get_roam_reason_vsie_status(psoc, &enable_roam_reason_vsie); 203 params->enable_roam_reason_vsie = enable_roam_reason_vsie; 204 } 205 206 /** 207 * cm_is_only_2g_band_supported() - Check if BTC trigger and IDLE trigger needs 208 * to be disabled based on the current connected band. 209 * @psoc: Pointer to the psoc object 210 * @vdev_id: Vdev id 211 * 212 * Return: true if BTC trigger and IDLE trigger are allowed or not 213 */ 214 static bool 215 cm_is_only_2g_band_supported(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 216 { 217 struct wlan_objmgr_vdev *vdev; 218 struct wlan_objmgr_pdev *pdev; 219 bool only_2g_band_supported = false; 220 uint32_t band_bitmap; 221 222 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 223 WLAN_MLME_CM_ID); 224 if (!vdev) { 225 mlme_err("Vdev is null for vdev_id:%d", vdev_id); 226 return false; 227 } 228 229 pdev = wlan_vdev_get_pdev(vdev); 230 if (!pdev) { 231 mlme_err("pdev is null for vdev_id:%d", vdev_id); 232 goto release; 233 } 234 235 if (QDF_IS_STATUS_ERROR(ucfg_reg_get_band(pdev, &band_bitmap))) { 236 mlme_debug("Failed to get band"); 237 goto release; 238 } 239 240 mlme_debug("Current band bitmap:%d", band_bitmap); 241 242 if (band_bitmap & BIT(REG_BAND_2G) && 243 !(band_bitmap & BIT(REG_BAND_5G)) && 244 !(band_bitmap & BIT(REG_BAND_6G))) 245 only_2g_band_supported = true; 246 247 248 release: 249 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 250 return only_2g_band_supported; 251 } 252 253 /** 254 * cm_roam_triggers() - set roam triggers 255 * @psoc: psoc pointer 256 * @vdev_id: vdev id 257 * @params: roam triggers parameters 258 * 259 * This function is used to set roam triggers parameters 260 * 261 * Return: None 262 */ 263 static void 264 cm_roam_triggers(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 265 struct wlan_roam_triggers *params) 266 { 267 bool is_per_roam_enabled; 268 269 params->vdev_id = vdev_id; 270 params->trigger_bitmap = 271 mlme_get_roam_trigger_bitmap(psoc, vdev_id); 272 273 /* 274 * Disable PER trigger for phymode less than 11n to avoid 275 * frequent roams as the PER rate threshold is greater than 276 * 11a/b/g rates 277 */ 278 is_per_roam_enabled = cm_roam_is_per_roam_allowed(psoc, vdev_id); 279 if (!is_per_roam_enabled) 280 params->trigger_bitmap &= ~BIT(ROAM_TRIGGER_REASON_PER); 281 282 /* 283 * Enable BTC trigger and IDLE trigger only when DUT is dual band 284 * capable(2g + 5g/6g) 285 */ 286 if (cm_is_only_2g_band_supported(psoc, vdev_id)) { 287 params->trigger_bitmap &= ~BIT(ROAM_TRIGGER_REASON_IDLE); 288 params->trigger_bitmap &= ~BIT(ROAM_TRIGGER_REASON_BTC); 289 } 290 291 mlme_debug("[ROAM_TRIGGER] trigger_bitmap:%d", params->trigger_bitmap); 292 293 params->roam_scan_scheme_bitmap = 294 wlan_cm_get_roam_scan_scheme_bitmap(psoc, vdev_id); 295 wlan_cm_roam_get_vendor_btm_params(psoc, ¶ms->vendor_btm_param); 296 wlan_cm_roam_get_score_delta_params(psoc, params); 297 wlan_cm_roam_get_min_rssi_params(psoc, params); 298 } 299 300 /** 301 * cm_roam_bss_load_config() - set bss load config 302 * @psoc: psoc pointer 303 * @vdev_id: vdev id 304 * @params: bss load config parameters 305 * 306 * This function is used to set bss load config parameters 307 * 308 * Return: None 309 */ 310 static void 311 cm_roam_bss_load_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 312 struct wlan_roam_bss_load_config *params) 313 { 314 params->vdev_id = vdev_id; 315 wlan_mlme_get_bss_load_threshold(psoc, ¶ms->bss_load_threshold); 316 wlan_mlme_get_bss_load_sample_time(psoc, ¶ms->bss_load_sample_time); 317 wlan_mlme_get_bss_load_rssi_threshold_6ghz( 318 psoc, ¶ms->rssi_threshold_6ghz); 319 wlan_mlme_get_bss_load_rssi_threshold_5ghz( 320 psoc, ¶ms->rssi_threshold_5ghz); 321 wlan_mlme_get_bss_load_rssi_threshold_24ghz( 322 psoc, ¶ms->rssi_threshold_24ghz); 323 } 324 325 /** 326 * cm_roam_disconnect_params() - set disconnect roam parameters 327 * @psoc: psoc pointer 328 * @vdev_id: vdev id 329 * @params: disconnect roam parameters 330 * 331 * This function is used to set disconnect roam parameters 332 * 333 * Return: None 334 */ 335 static void 336 cm_roam_disconnect_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 337 struct wlan_roam_disconnect_params *params) 338 { 339 params->vdev_id = vdev_id; 340 wlan_mlme_get_enable_disconnect_roam_offload(psoc, ¶ms->enable); 341 } 342 343 /** 344 * cm_roam_idle_params() - set roam idle parameters 345 * @psoc: psoc pointer 346 * @vdev_id: vdev id 347 * @params: roam idle parameters 348 * 349 * This function is used to set roam idle parameters 350 * 351 * Return: None 352 */ 353 static void 354 cm_roam_idle_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 355 struct wlan_roam_idle_params *params) 356 { 357 params->vdev_id = vdev_id; 358 wlan_mlme_get_enable_idle_roam(psoc, ¶ms->enable); 359 wlan_mlme_get_idle_roam_rssi_delta(psoc, ¶ms->conn_ap_rssi_delta); 360 wlan_mlme_get_idle_roam_inactive_time(psoc, ¶ms->inactive_time); 361 wlan_mlme_get_idle_data_packet_count(psoc, ¶ms->data_pkt_count); 362 wlan_mlme_get_idle_roam_min_rssi(psoc, ¶ms->conn_ap_min_rssi); 363 wlan_mlme_get_idle_roam_band(psoc, ¶ms->band); 364 } 365 366 #define RSN_CAPS_SHIFT 16 367 368 #ifdef WLAN_ADAPTIVE_11R 369 static inline void 370 cm_update_rso_adaptive_11r(struct wlan_rso_11r_params *dst, 371 struct rso_config *rso_cfg) 372 { 373 dst->is_adaptive_11r = rso_cfg->is_adaptive_11r_connection; 374 } 375 #else 376 static inline void 377 cm_update_rso_adaptive_11r(struct wlan_rso_11r_params *dst, 378 struct rso_config *rso_cfg) 379 {} 380 #endif 381 382 #ifdef FEATURE_WLAN_ESE 383 static void 384 cm_update_rso_ese_info(struct rso_config *rso_cfg, 385 struct wlan_roam_scan_offload_params *rso_config) 386 { 387 rso_config->rso_ese_info.is_ese_assoc = rso_cfg->is_ese_assoc; 388 rso_config->rso_11r_info.is_11r_assoc = rso_cfg->is_11r_assoc; 389 if (rso_cfg->is_ese_assoc) { 390 qdf_mem_copy(rso_config->rso_ese_info.krk, rso_cfg->krk, 391 WMI_KRK_KEY_LEN); 392 qdf_mem_copy(rso_config->rso_ese_info.btk, rso_cfg->btk, 393 WMI_BTK_KEY_LEN); 394 rso_config->rso_11i_info.fw_okc = 0; 395 rso_config->rso_11i_info.fw_pmksa_cache = 0; 396 rso_config->rso_11i_info.pmk_len = 0; 397 qdf_mem_zero(&rso_config->rso_11i_info.psk_pmk[0], 398 sizeof(rso_config->rso_11i_info.psk_pmk)); 399 } 400 } 401 #else 402 static inline void 403 cm_update_rso_ese_info(struct rso_config *rso_cfg, 404 struct wlan_roam_scan_offload_params *rso_config) 405 {} 406 #endif 407 408 #ifdef WLAN_SAE_SINGLE_PMK 409 static bool 410 cm_fill_rso_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, 411 struct wlan_mlme_psoc_ext_obj *mlme_obj, 412 struct wlan_roam_scan_offload_params *rso_cfg) 413 { 414 struct wlan_mlme_sae_single_pmk single_pmk = {0}; 415 struct wlan_rso_11i_params *rso_11i_info = &rso_cfg->rso_11i_info; 416 uint64_t time_expired; 417 418 wlan_mlme_get_sae_single_pmk_info(vdev, &single_pmk); 419 420 if (single_pmk.pmk_info.pmk_len && single_pmk.sae_single_pmk_ap && 421 mlme_obj->cfg.lfr.sae_single_pmk_feature_enabled) { 422 423 rso_11i_info->pmk_len = single_pmk.pmk_info.pmk_len; 424 /* Update sae same pmk info in rso */ 425 qdf_mem_copy(rso_11i_info->psk_pmk, single_pmk.pmk_info.pmk, 426 rso_11i_info->pmk_len); 427 rso_11i_info->is_sae_same_pmk = single_pmk.sae_single_pmk_ap; 428 429 /* get the time expired in seconds */ 430 time_expired = (qdf_get_system_timestamp() - 431 single_pmk.pmk_info.spmk_timestamp) / 1000; 432 433 rso_cfg->sae_offload_params.spmk_timeout = 0; 434 if (time_expired < single_pmk.pmk_info.spmk_timeout_period) 435 rso_cfg->sae_offload_params.spmk_timeout = 436 (single_pmk.pmk_info.spmk_timeout_period - 437 time_expired); 438 439 mlme_debug("Update spmk with len:%d is_spmk_ap:%d time_exp:%lld time left:%d", 440 single_pmk.pmk_info.pmk_len, 441 single_pmk.sae_single_pmk_ap, time_expired, 442 rso_cfg->sae_offload_params.spmk_timeout); 443 444 return true; 445 } 446 447 return false; 448 } 449 #else 450 static inline bool 451 cm_fill_rso_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, 452 struct wlan_mlme_psoc_ext_obj *mlme_obj, 453 struct wlan_roam_scan_offload_params *rso_cfg) 454 { 455 return false; 456 } 457 #endif 458 459 static QDF_STATUS 460 cm_roam_scan_offload_fill_lfr3_config(struct wlan_objmgr_vdev *vdev, 461 struct rso_config *rso_cfg, 462 struct wlan_roam_scan_offload_params *rso_config, 463 struct wlan_mlme_psoc_ext_obj *mlme_obj, 464 uint8_t command, uint32_t *mode) 465 { 466 tSirMacCapabilityInfo self_caps; 467 tSirMacQosInfoStation sta_qos_info; 468 uint16_t *final_caps_val; 469 uint8_t *qos_cfg_val, temp_val; 470 uint32_t pmkid_modes = mlme_obj->cfg.sta.pmkid_modes; 471 uint32_t val = 0; 472 uint8_t vdev_id = wlan_vdev_get_id(vdev); 473 qdf_size_t val_len; 474 QDF_STATUS status; 475 uint16_t rsn_caps = 0; 476 int32_t uccipher, authmode, akm; 477 struct wlan_objmgr_pdev *pdev; 478 struct wlan_objmgr_psoc *psoc; 479 struct cm_roam_values_copy roam_config; 480 struct mlme_legacy_priv *mlme_priv; 481 uint8_t uapsd_mask; 482 483 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 484 if (!mlme_priv) 485 return QDF_STATUS_E_FAILURE; 486 487 pdev = wlan_vdev_get_pdev(vdev); 488 if (!pdev) 489 return QDF_STATUS_E_INVAL; 490 psoc = wlan_pdev_get_psoc(pdev); 491 if (!psoc) 492 return QDF_STATUS_E_INVAL; 493 494 rso_config->roam_offload_enabled = 495 mlme_obj->cfg.lfr.lfr3_roaming_offload; 496 if (!rso_config->roam_offload_enabled) 497 return QDF_STATUS_SUCCESS; 498 499 /* FILL LFR3 specific roam scan mode TLV parameters */ 500 rso_config->rso_lfr3_params.roam_rssi_cat_gap = 501 mlme_obj->cfg.lfr.rso_user_config.cat_rssi_offset; 502 rso_config->rso_lfr3_params.prefer_5ghz = 503 mlme_obj->cfg.lfr.roam_prefer_5ghz; 504 rso_config->rso_lfr3_params.select_5ghz_margin = 505 mlme_obj->cfg.gen.select_5ghz_margin; 506 rso_config->rso_lfr3_params.reassoc_failure_timeout = 507 mlme_obj->cfg.timeouts.reassoc_failure_timeout; 508 rso_config->rso_lfr3_params.ho_delay_for_rx = 509 mlme_obj->cfg.lfr.ho_delay_for_rx; 510 rso_config->rso_lfr3_params.roam_retry_count = 511 mlme_obj->cfg.lfr.roam_preauth_retry_count; 512 rso_config->rso_lfr3_params.roam_preauth_no_ack_timeout = 513 mlme_obj->cfg.lfr.roam_preauth_no_ack_timeout; 514 rso_config->rso_lfr3_params.rct_validity_timer = 515 mlme_obj->cfg.btm.rct_validity_timer; 516 rso_config->rso_lfr3_params.disable_self_roam = 517 !mlme_obj->cfg.lfr.enable_self_bss_roam; 518 if (!rso_cfg->roam_control_enable && 519 mlme_obj->cfg.lfr.roam_force_rssi_trigger) 520 *mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; 521 /* 522 * Self rsn caps aren't sent to firmware, so in case of PMF required, 523 * the firmware connects to a non PMF AP advertising PMF not required 524 * in the re-assoc request which violates protocol. 525 * So send self RSN caps to firmware in roam SCAN offload command to 526 * let it configure the params in the re-assoc request too. 527 * Instead of making another infra, send the RSN-CAPS in MSB of 528 * beacon Caps. 529 */ 530 /* RSN caps with global user MFP which can be used for cross-AKM roam */ 531 rsn_caps = rso_cfg->rso_rsn_caps; 532 533 /* Fill LFR3 specific self capabilities for roam scan mode TLV */ 534 self_caps.ess = 1; 535 self_caps.ibss = 0; 536 537 val = mlme_obj->cfg.wep_params.is_privacy_enabled; 538 if (val) 539 self_caps.privacy = 1; 540 541 if (mlme_obj->cfg.ht_caps.short_preamble) 542 self_caps.shortPreamble = 1; 543 544 self_caps.criticalUpdateFlag = 0; 545 self_caps.channelAgility = 0; 546 547 if (mlme_obj->cfg.feature_flags.enable_short_slot_time_11g) 548 self_caps.shortSlotTime = 1; 549 550 if (mlme_obj->cfg.gen.enabled_11h) 551 self_caps.spectrumMgt = 1; 552 553 if (mlme_obj->cfg.wmm_params.qos_enabled) 554 self_caps.qos = 1; 555 556 if (mlme_obj->cfg.roam_scoring.apsd_enabled) 557 self_caps.apsd = 1; 558 559 self_caps.rrm = mlme_obj->cfg.rrm_config.rrm_enabled; 560 561 val = mlme_obj->cfg.feature_flags.enable_block_ack; 562 self_caps.delayedBA = 563 (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1); 564 self_caps.immediateBA = 565 (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); 566 final_caps_val = (uint16_t *)&self_caps; 567 568 rso_config->rso_lfr3_caps.capability = 569 (rsn_caps << RSN_CAPS_SHIFT) | ((*final_caps_val) & 0xFFFF); 570 571 rso_config->rso_lfr3_caps.ht_caps_info = 572 *(uint16_t *)&mlme_obj->cfg.ht_caps.ht_cap_info; 573 rso_config->rso_lfr3_caps.ampdu_param = 574 *(uint8_t *)&mlme_obj->cfg.ht_caps.ampdu_params; 575 rso_config->rso_lfr3_caps.ht_ext_cap = 576 *(uint16_t *)&mlme_obj->cfg.ht_caps.ext_cap_info; 577 578 temp_val = (uint8_t)mlme_obj->cfg.vht_caps.vht_cap_info.tx_bf_cap; 579 rso_config->rso_lfr3_caps.ht_txbf = temp_val & 0xFF; 580 temp_val = (uint8_t)mlme_obj->cfg.vht_caps.vht_cap_info.as_cap; 581 rso_config->rso_lfr3_caps.asel_cap = temp_val & 0xFF; 582 583 qdf_mem_zero(&sta_qos_info, sizeof(tSirMacQosInfoStation)); 584 sta_qos_info.maxSpLen = 585 (uint8_t)mlme_obj->cfg.wmm_params.max_sp_length; 586 sta_qos_info.moreDataAck = 0; 587 sta_qos_info.qack = 0; 588 wlan_cm_roam_cfg_get_value(psoc, vdev_id, UAPSD_MASK, &roam_config); 589 uapsd_mask = roam_config.uint_value; 590 sta_qos_info.acbe_uapsd = SIR_UAPSD_GET(ACBE, uapsd_mask); 591 sta_qos_info.acbk_uapsd = SIR_UAPSD_GET(ACBK, uapsd_mask); 592 sta_qos_info.acvi_uapsd = SIR_UAPSD_GET(ACVI, uapsd_mask); 593 sta_qos_info.acvo_uapsd = SIR_UAPSD_GET(ACVO, uapsd_mask); 594 qos_cfg_val = (uint8_t *)&sta_qos_info; 595 rso_config->rso_lfr3_caps.qos_caps = (*qos_cfg_val) & 0xFF; 596 if (rso_config->rso_lfr3_caps.qos_caps) 597 rso_config->rso_lfr3_caps.qos_enabled = true; 598 599 rso_config->rso_lfr3_caps.wmm_caps = 0x4; 600 601 val_len = ROAM_OFFLOAD_NUM_MCS_SET; 602 status = 603 wlan_mlme_get_cfg_str((uint8_t *)rso_config->rso_lfr3_caps.mcsset, 604 &mlme_obj->cfg.rates.supported_mcs_set, 605 &val_len); 606 if (QDF_IS_STATUS_ERROR(status)) { 607 mlme_err("Failed to get CFG_SUPPORTED_MCS_SET"); 608 return QDF_STATUS_E_FAILURE; 609 } 610 611 /* Update 11i TLV related Fields */ 612 rso_config->rso_11i_info.roam_key_mgmt_offload_enabled = 613 mlme_obj->cfg.lfr.lfr3_roaming_offload; 614 rso_config->rso_11i_info.fw_okc = 615 (pmkid_modes & CFG_PMKID_MODES_OKC) ? 1 : 0; 616 rso_config->rso_11i_info.fw_pmksa_cache = 617 (pmkid_modes & CFG_PMKID_MODES_PMKSA_CACHING) ? 1 : 0; 618 619 /* Check whether to send psk_pmk or sae_single pmk info */ 620 if (!cm_fill_rso_sae_single_pmk_info(vdev, mlme_obj, rso_config)) { 621 rso_config->rso_11i_info.is_sae_same_pmk = false; 622 wlan_cm_get_psk_pmk(pdev, vdev_id, 623 rso_config->rso_11i_info.psk_pmk, 624 &rso_config->rso_11i_info.pmk_len); 625 } 626 627 rso_config->rso_11r_info.enable_ft_im_roaming = 628 mlme_obj->cfg.lfr.enable_ft_im_roaming; 629 rso_config->rso_11r_info.mdid.mdie_present = 630 rso_cfg->mdid.mdie_present; 631 rso_config->rso_11r_info.mdid.mobility_domain = 632 rso_cfg->mdid.mobility_domain; 633 rso_config->rso_11r_info.r0kh_id_length = 634 mlme_priv->connect_info.ft_info.r0kh_id_len; 635 qdf_mem_copy(rso_config->rso_11r_info.r0kh_id, 636 mlme_priv->connect_info.ft_info.r0kh_id, 637 mlme_priv->connect_info.ft_info.r0kh_id_len); 638 wlan_cm_get_psk_pmk(pdev, vdev_id, 639 rso_config->rso_11r_info.psk_pmk, 640 &rso_config->rso_11r_info.pmk_len); 641 rso_config->rso_11r_info.enable_ft_over_ds = 642 mlme_obj->cfg.lfr.enable_ft_over_ds; 643 644 cm_update_rso_adaptive_11r(&rso_config->rso_11r_info, rso_cfg); 645 cm_update_rso_ese_info(rso_cfg, rso_config); 646 uccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_UCAST_CIPHER); 647 authmode = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE); 648 akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 649 650 rso_config->akm = 651 cm_crypto_authmode_to_wmi_authmode(authmode, akm, uccipher); 652 653 return QDF_STATUS_SUCCESS; 654 } 655 656 bool 657 cm_roam_is_change_in_band_allowed(struct wlan_objmgr_psoc *psoc, 658 uint8_t vdev_id, uint32_t roam_band_mask) 659 { 660 struct wlan_objmgr_vdev *vdev; 661 bool sta_concurrency_is_with_different_mac; 662 struct wlan_channel *chan; 663 664 if (policy_mgr_is_hw_sbs_capable(psoc)) 665 return true; 666 667 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 668 WLAN_MLME_NB_ID); 669 if (!vdev) { 670 mlme_err("vdev is NULL"); 671 return false; 672 } 673 674 chan = wlan_vdev_get_active_channel(vdev); 675 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 676 if (!chan) { 677 mlme_err("no active channel"); 678 return false; 679 } 680 681 sta_concurrency_is_with_different_mac = 682 policy_mgr_concurrent_sta_on_different_mac(psoc); 683 if (!sta_concurrency_is_with_different_mac) 684 return true; 685 686 mlme_debug("sta concurrency on different mac, ch freq %d, roam band:%d", 687 chan->ch_freq, roam_band_mask); 688 689 if (wlan_reg_freq_to_band(chan->ch_freq) == REG_BAND_2G && 690 (!(roam_band_mask & BIT(REG_BAND_2G)))) { 691 mlme_debug("Change in band (2G to 5G/6G) not allowed"); 692 return false; 693 } 694 695 if ((wlan_reg_freq_to_band(chan->ch_freq) == REG_BAND_5G || 696 wlan_reg_freq_to_band(chan->ch_freq) == REG_BAND_6G) && 697 (!(roam_band_mask & BIT(REG_BAND_5G)) && 698 !(roam_band_mask & BIT(REG_BAND_6G)))) { 699 mlme_debug("Change in band (5G/6G to 2G) not allowed"); 700 return false; 701 } 702 703 return true; 704 } 705 706 /** 707 * cm_roam_send_rt_stats_config() - set roam stats parameters 708 * @psoc: psoc pointer 709 * @vdev_id: vdev id 710 * @param_value: roam stats param value 711 * 712 * This function is used to set roam event stats parameters 713 * 714 * Return: QDF_STATUS 715 */ 716 QDF_STATUS 717 cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, 718 uint8_t vdev_id, uint8_t param_value) 719 { 720 struct roam_disable_cfg *req; 721 QDF_STATUS status; 722 723 req = qdf_mem_malloc(sizeof(*req)); 724 if (!req) 725 return QDF_STATUS_E_NOMEM; 726 727 req->vdev_id = vdev_id; 728 req->cfg = param_value; 729 730 status = wlan_cm_tgt_send_roam_rt_stats_config(psoc, req); 731 if (QDF_IS_STATUS_ERROR(status)) 732 mlme_debug("fail to send roam rt stats config"); 733 734 qdf_mem_free(req); 735 736 return status; 737 } 738 739 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 740 bool 741 cm_roam_is_vendor_handoff_control_enable(struct wlan_objmgr_psoc *psoc) 742 { 743 bool ini_flag, handoff_control_support; 744 struct wlan_mlme_psoc_ext_obj *mlme_obj; 745 746 mlme_obj = mlme_get_psoc_ext_obj(psoc); 747 748 if (!mlme_obj) 749 return false; 750 751 ini_flag = mlme_obj->cfg.connection_roaming_ini_flag; 752 753 handoff_control_support = 754 wlan_mlme_get_vendor_handoff_control_caps(psoc); 755 756 mlme_debug("ini flag:%d, fw caps:%d", ini_flag, 757 handoff_control_support); 758 759 if (ini_flag && handoff_control_support) 760 return true; 761 762 return false; 763 } 764 765 QDF_STATUS 766 cm_roam_send_vendor_handoff_param_req(struct wlan_objmgr_psoc *psoc, 767 uint8_t vdev_id, 768 uint32_t param_id, 769 void *vendor_handoff_context) 770 { 771 struct vendor_handoff_cfg *req; 772 QDF_STATUS status; 773 struct mlme_legacy_priv *mlme_priv; 774 struct wlan_objmgr_vdev *vdev; 775 776 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 777 WLAN_MLME_CM_ID); 778 if (!vdev) { 779 mlme_err("get vdev failed"); 780 return QDF_STATUS_E_FAILURE; 781 } 782 783 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 784 if (!mlme_priv) { 785 status = QDF_STATUS_E_FAILURE; 786 goto error; 787 } 788 789 if (mlme_priv->cm_roam.vendor_handoff_param.req_in_progress) { 790 mlme_debug("vendor handoff request is already in progress"); 791 status = QDF_STATUS_E_FAILURE; 792 goto error; 793 } else { 794 mlme_debug("Set vendor handoff req in progress context"); 795 mlme_priv->cm_roam.vendor_handoff_param.req_in_progress = true; 796 mlme_priv->cm_roam.vendor_handoff_param.vendor_handoff_context = 797 vendor_handoff_context; 798 } 799 800 req = qdf_mem_malloc(sizeof(*req)); 801 if (!req) { 802 status = QDF_STATUS_E_NOMEM; 803 goto error; 804 } 805 806 req->vdev_id = vdev_id; 807 req->param_id = param_id; 808 809 status = wlan_cm_tgt_send_roam_vendor_handoff_config(psoc, req); 810 if (QDF_IS_STATUS_ERROR(status)) 811 mlme_debug("fail to send roam rt stats config"); 812 813 qdf_mem_free(req); 814 815 error: 816 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 817 return status; 818 } 819 820 QDF_STATUS cm_roam_update_vendor_handoff_config(struct wlan_objmgr_psoc *psoc, 821 struct roam_vendor_handoff_params *list) 822 { 823 struct wlan_objmgr_vdev *vdev; 824 struct rso_config *rso_cfg; 825 struct rso_cfg_params *cfg_params; 826 uint8_t vdev_id; 827 QDF_STATUS status = QDF_STATUS_SUCCESS; 828 uint32_t param_value, i; 829 enum vendor_control_roam_param param_id; 830 831 vdev_id = list->vdev_id; 832 833 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 834 WLAN_MLME_SB_ID); 835 if (!vdev) { 836 mlme_err("vdev object is NULL"); 837 return QDF_STATUS_E_FAILURE; 838 } 839 840 rso_cfg = wlan_cm_get_rso_config(vdev); 841 if (!rso_cfg) { 842 status = QDF_STATUS_E_FAILURE; 843 goto error; 844 } 845 846 cfg_params = &rso_cfg->cfg_param; 847 848 mlme_debug("received vendor handoff event from FW with num_entries %d", 849 list->num_entries); 850 851 for (i = 0; i < list->num_entries; i++) { 852 param_id = list->param_info[i].param_id; 853 param_value = list->param_info[i].param_value; 854 mlme_debug("param id:%d, param value:%d", param_id, 855 param_value); 856 switch (param_id) { 857 case VENDOR_CONTROL_PARAM_ROAM_TRIGGER: 858 cfg_params->neighbor_lookup_threshold = 859 abs(param_value); 860 break; 861 case VENDOR_CONTROL_PARAM_ROAM_DELTA: 862 cfg_params->roam_rssi_diff = param_value; 863 break; 864 case VENDOR_CONTROL_PARAM_ROAM_FULL_SCANPERIOD: 865 cfg_params->full_roam_scan_period = param_value; 866 break; 867 case VENDOR_CONTROL_PARAM_ROAM_PARTIAL_SCANPERIOD: 868 cfg_params->empty_scan_refresh_period = 869 param_value * 1000; 870 break; 871 case VENDOR_CONTROL_PARAM_ROAM_ACTIVE_CH_DWELLTIME: 872 cfg_params->max_chan_scan_time = param_value; 873 break; 874 case VENDOR_CONTROL_PARAM_ROAM_PASSIVE_CH_DWELLTIME: 875 cfg_params->passive_max_chan_time = param_value; 876 break; 877 case VENDOR_CONTROL_PARAM_ROAM_HOME_CH_TIME: 878 cfg_params->neighbor_scan_period = param_value; 879 break; 880 case VENDOR_CONTROL_PARAM_ROAM_AWAY_TIME: 881 cfg_params->roam_scan_home_away_time = param_value; 882 break; 883 default: 884 mlme_debug("Invalid param id"); 885 status = QDF_STATUS_E_FAILURE; 886 goto error; 887 } 888 } 889 error: 890 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID); 891 return status; 892 } 893 894 #endif 895 #else 896 static inline void 897 cm_roam_reason_vsie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 898 struct wlan_roam_reason_vsie_enable *params) 899 { 900 } 901 902 static inline void 903 cm_roam_triggers(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 904 struct wlan_roam_triggers *params) 905 { 906 } 907 908 static void 909 cm_roam_bss_load_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 910 struct wlan_roam_bss_load_config *params) 911 { 912 } 913 914 static void 915 cm_roam_disconnect_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 916 struct wlan_roam_disconnect_params *params) 917 { 918 } 919 920 static void 921 cm_roam_idle_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 922 struct wlan_roam_idle_params *params) 923 { 924 } 925 static inline QDF_STATUS 926 cm_roam_scan_offload_fill_lfr3_config(struct wlan_objmgr_vdev *vdev, 927 struct rso_config *rso_cfg, 928 struct wlan_roam_scan_offload_params *rso_config, 929 struct wlan_mlme_psoc_ext_obj *mlme_obj, 930 uint8_t command, uint32_t *mode) 931 { 932 if (mlme_obj->cfg.lfr.roam_force_rssi_trigger) 933 *mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; 934 935 return QDF_STATUS_SUCCESS; 936 } 937 #endif 938 939 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_FILS_SK) 940 static QDF_STATUS 941 cm_roam_scan_offload_add_fils_params(struct wlan_objmgr_psoc *psoc, 942 struct wlan_roam_scan_offload_params *rso_cfg, 943 uint8_t vdev_id) 944 { 945 QDF_STATUS status; 946 uint32_t usr_name_len; 947 struct wlan_fils_connection_info *fils_info; 948 struct wlan_roam_fils_params *fils_roam_config = 949 &rso_cfg->fils_roam_config; 950 951 fils_info = wlan_cm_get_fils_connection_info(psoc, vdev_id); 952 if (!fils_info) 953 return QDF_STATUS_SUCCESS; 954 955 if (fils_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH || 956 fils_info->r_rk_length > WLAN_FILS_MAX_RRK_LENGTH) { 957 mlme_err("Fils info len error: keyname nai len(%d) rrk len(%d)", 958 fils_info->key_nai_length, fils_info->r_rk_length); 959 return QDF_STATUS_E_FAILURE; 960 } 961 962 fils_roam_config->next_erp_seq_num = fils_info->erp_sequence_number; 963 964 usr_name_len = 965 qdf_str_copy_all_before_char(fils_info->keyname_nai, 966 sizeof(fils_info->keyname_nai), 967 fils_roam_config->username, 968 sizeof(fils_roam_config->username), 969 '@'); 970 if (fils_info->key_nai_length <= usr_name_len) { 971 mlme_err("Fils info len error: key nai len %d, user name len %d", 972 fils_info->key_nai_length, usr_name_len); 973 return QDF_STATUS_E_INVAL; 974 } 975 976 fils_roam_config->username_length = usr_name_len; 977 qdf_mem_copy(fils_roam_config->rrk, fils_info->r_rk, 978 fils_info->r_rk_length); 979 fils_roam_config->rrk_length = fils_info->r_rk_length; 980 fils_roam_config->realm_len = fils_info->key_nai_length - 981 fils_roam_config->username_length - 1; 982 qdf_mem_copy(fils_roam_config->realm, 983 (fils_info->keyname_nai + 984 fils_roam_config->username_length + 1), 985 fils_roam_config->realm_len); 986 987 /* 988 * Set add FILS tlv true for initial FULL EAP connection and subsequent 989 * FILS connection. 990 */ 991 rso_cfg->add_fils_tlv = true; 992 mlme_debug("Fils: next_erp_seq_num %d rrk_len %d realm_len:%d", 993 fils_info->erp_sequence_number, 994 fils_info->r_rk_length, 995 fils_info->realm_len); 996 if (!fils_info->is_fils_connection) 997 return QDF_STATUS_SUCCESS; 998 999 /* Update rik from crypto to fils roam config buffer */ 1000 status = wlan_crypto_create_fils_rik(fils_info->r_rk, 1001 fils_info->r_rk_length, 1002 fils_info->rik, 1003 &fils_info->rik_length); 1004 qdf_mem_copy(fils_roam_config->rik, fils_info->rik, 1005 fils_info->rik_length); 1006 fils_roam_config->rik_length = fils_info->rik_length; 1007 1008 fils_roam_config->fils_ft_len = fils_info->fils_ft_len; 1009 qdf_mem_copy(fils_roam_config->fils_ft, fils_info->fils_ft, 1010 fils_info->fils_ft_len); 1011 1012 return status; 1013 } 1014 #else 1015 static inline 1016 QDF_STATUS cm_roam_scan_offload_add_fils_params(struct wlan_objmgr_psoc *psoc, 1017 struct wlan_roam_scan_offload_params *rso_cfg, 1018 uint8_t vdev_id) 1019 { 1020 return QDF_STATUS_SUCCESS; 1021 } 1022 #endif 1023 1024 /** 1025 * cm_roam_mawc_params() - set roam mawc parameters 1026 * @psoc: psoc pointer 1027 * @vdev_id: vdev id 1028 * @params: roam mawc parameters 1029 * 1030 * This function is used to set roam mawc parameters 1031 * 1032 * Return: None 1033 */ 1034 static void 1035 cm_roam_mawc_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 1036 struct wlan_roam_mawc_params *params) 1037 { 1038 bool mawc_enabled; 1039 bool mawc_roam_enabled; 1040 1041 params->vdev_id = vdev_id; 1042 wlan_mlme_get_mawc_enabled(psoc, &mawc_enabled); 1043 wlan_mlme_get_mawc_roam_enabled(psoc, &mawc_roam_enabled); 1044 params->enable = mawc_enabled && mawc_roam_enabled; 1045 wlan_mlme_get_mawc_roam_traffic_threshold( 1046 psoc, ¶ms->traffic_load_threshold); 1047 wlan_mlme_get_mawc_roam_ap_rssi_threshold( 1048 psoc, ¶ms->best_ap_rssi_threshold); 1049 wlan_mlme_get_mawc_roam_rssi_high_adjust( 1050 psoc, ¶ms->rssi_stationary_high_adjust); 1051 wlan_mlme_get_mawc_roam_rssi_low_adjust( 1052 psoc, ¶ms->rssi_stationary_low_adjust); 1053 } 1054 1055 QDF_STATUS 1056 cm_roam_send_disable_config(struct wlan_objmgr_psoc *psoc, 1057 uint8_t vdev_id, uint8_t cfg) 1058 { 1059 struct roam_disable_cfg *req; 1060 QDF_STATUS status; 1061 1062 req = qdf_mem_malloc(sizeof(*req)); 1063 if (!req) 1064 return QDF_STATUS_E_NOMEM; 1065 1066 req->vdev_id = vdev_id; 1067 req->cfg = cfg; 1068 1069 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 1070 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 1071 status = QDF_STATUS_E_FAILURE; 1072 goto end; 1073 } 1074 1075 status = wlan_cm_tgt_send_roam_disable_config(psoc, vdev_id, req); 1076 if (QDF_IS_STATUS_ERROR(status)) 1077 mlme_debug("fail to send roam disable config"); 1078 1079 end: 1080 qdf_mem_free(req); 1081 1082 return status; 1083 } 1084 1085 /** 1086 * cm_roam_init_req() - roam init request handling 1087 * @psoc: psoc pointer 1088 * @vdev_id: vdev id 1089 * @enable: should the offload be enabled 1090 * 1091 * Return: QDF_STATUS 1092 */ 1093 static QDF_STATUS 1094 cm_roam_init_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, bool enable) 1095 { 1096 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 1097 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 1098 return QDF_STATUS_SUCCESS; 1099 } 1100 1101 return wlan_cm_tgt_send_roam_offload_init(psoc, vdev_id, enable); 1102 } 1103 1104 QDF_STATUS cm_rso_set_roam_trigger(struct wlan_objmgr_pdev *pdev, 1105 uint8_t vdev_id, 1106 struct wlan_roam_triggers *trigger) 1107 { 1108 QDF_STATUS status; 1109 uint8_t reason = REASON_SUPPLICANT_DE_INIT_ROAMING; 1110 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 1111 1112 if (!psoc) 1113 return QDF_STATUS_E_INVAL; 1114 1115 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 1116 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 1117 return QDF_STATUS_SUCCESS; 1118 } 1119 1120 mlme_set_roam_trigger_bitmap(psoc, trigger->vdev_id, 1121 trigger->trigger_bitmap); 1122 1123 if (trigger->trigger_bitmap) 1124 reason = REASON_SUPPLICANT_INIT_ROAMING; 1125 1126 status = cm_roam_state_change(pdev, vdev_id, 1127 trigger->trigger_bitmap ? WLAN_ROAM_RSO_ENABLED : 1128 WLAN_ROAM_DEINIT, 1129 reason, NULL, false); 1130 if (QDF_IS_STATUS_ERROR(status)) 1131 return status; 1132 1133 return wlan_cm_tgt_send_roam_triggers(psoc, vdev_id, trigger); 1134 } 1135 1136 static void cm_roam_set_roam_reason_better_ap(struct wlan_objmgr_psoc *psoc, 1137 uint8_t vdev_id, bool set) 1138 { 1139 struct wlan_objmgr_vdev *vdev; 1140 1141 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1142 WLAN_MLME_NB_ID); 1143 if (!vdev) 1144 return; 1145 mlme_set_roam_reason_better_ap(vdev, set); 1146 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 1147 } 1148 1149 /** 1150 * cm_roam_scan_offload_rssi_thresh() - set roam offload scan rssi 1151 * parameters 1152 * @psoc: psoc ctx 1153 * @vdev_id: vdev id 1154 * @params: roam offload scan rssi related parameters 1155 * @rso_cfg: rso config 1156 * 1157 * This function is used to set roam offload scan rssi related parameters 1158 * 1159 * Return: None 1160 */ 1161 static void 1162 cm_roam_scan_offload_rssi_thresh(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 1163 struct wlan_roam_offload_scan_rssi_params *params, 1164 struct rso_config *rso_cfg) 1165 { 1166 struct wlan_mlme_psoc_ext_obj *mlme_obj; 1167 struct wlan_mlme_lfr_cfg *lfr_cfg; 1168 struct rso_config_params *rso_config; 1169 struct wlan_objmgr_vdev *vdev; 1170 1171 mlme_obj = mlme_get_psoc_ext_obj(psoc); 1172 if (!mlme_obj) 1173 return; 1174 rso_config = &mlme_obj->cfg.lfr.rso_user_config; 1175 1176 lfr_cfg = &mlme_obj->cfg.lfr; 1177 1178 if (rso_config->alert_rssi_threshold) { 1179 params->rssi_thresh = rso_config->alert_rssi_threshold; 1180 } else { 1181 mlme_debug("lookup_threshold:%d", 1182 rso_cfg->cfg_param.neighbor_lookup_threshold); 1183 params->rssi_thresh = 1184 (int8_t)rso_cfg->cfg_param.neighbor_lookup_threshold * 1185 (-1); 1186 } 1187 1188 params->vdev_id = vdev_id; 1189 params->rssi_thresh_diff = 1190 rso_cfg->cfg_param.opportunistic_threshold_diff & 0x000000ff; 1191 params->hi_rssi_scan_max_count = 1192 rso_cfg->cfg_param.hi_rssi_scan_max_count; 1193 /* 1194 * If the current operation channel is 5G frequency band, then 1195 * there is no need to enable the HI_RSSI feature. This feature 1196 * is useful only if we are connected to a 2.4 GHz AP and we wish 1197 * to connect to a better 5GHz AP is available. 1198 */ 1199 if (rso_cfg->disable_hi_rssi) 1200 params->hi_rssi_scan_rssi_delta = 0; 1201 else 1202 params->hi_rssi_scan_rssi_delta = 1203 rso_cfg->cfg_param.hi_rssi_scan_rssi_delta; 1204 /* 1205 * When the STA operating band is 2.4/5 GHz and if the high RSSI delta 1206 * is configured through vendor command then the priority should be 1207 * given to it and the high RSSI delta value will be overridden with it. 1208 */ 1209 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1210 WLAN_MLME_CM_ID); 1211 if (!vdev) { 1212 mlme_err("Cannot set high RSSI offset as vdev object is NULL for vdev %d", 1213 vdev_id); 1214 } else { 1215 qdf_freq_t op_freq; 1216 1217 op_freq = wlan_get_operation_chan_freq(vdev); 1218 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(op_freq)) { 1219 uint8_t roam_high_rssi_delta; 1220 1221 roam_high_rssi_delta = 1222 wlan_cm_get_roam_scan_high_rssi_offset(psoc); 1223 if (roam_high_rssi_delta) 1224 params->hi_rssi_scan_rssi_delta = 1225 roam_high_rssi_delta; 1226 /* 1227 * Firmware will use this flag to enable 5 to 6 GHz 1228 * high RSSI roam 1229 */ 1230 if (roam_high_rssi_delta && 1231 WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) 1232 params->flags |= 1233 ROAM_SCAN_RSSI_THRESHOLD_FLAG_ROAM_HI_RSSI_EN_ON_5G; 1234 } 1235 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 1236 } 1237 1238 params->hi_rssi_scan_rssi_ub = 1239 rso_cfg->cfg_param.hi_rssi_scan_rssi_ub; 1240 params->raise_rssi_thresh_5g = lfr_cfg->rssi_boost_threshold_5g; 1241 params->dense_rssi_thresh_offset = lfr_cfg->roam_dense_rssi_thre_offset; 1242 params->dense_min_aps_cnt = lfr_cfg->roam_dense_min_aps; 1243 params->traffic_threshold = lfr_cfg->roam_dense_traffic_threshold; 1244 1245 /* Set initial dense roam status */ 1246 if (rso_cfg->roam_candidate_count > params->dense_min_aps_cnt) 1247 params->initial_dense_status = true; 1248 1249 params->bg_scan_bad_rssi_thresh = 1250 lfr_cfg->roam_bg_scan_bad_rssi_threshold; 1251 params->bg_scan_client_bitmap = lfr_cfg->roam_bg_scan_client_bitmap; 1252 params->roam_bad_rssi_thresh_offset_2g = 1253 lfr_cfg->roam_bg_scan_bad_rssi_offset_2g; 1254 params->roam_data_rssi_threshold_triggers = 1255 lfr_cfg->roam_data_rssi_threshold_triggers; 1256 params->roam_data_rssi_threshold = lfr_cfg->roam_data_rssi_threshold; 1257 params->rx_data_inactivity_time = lfr_cfg->rx_data_inactivity_time; 1258 1259 params->drop_rssi_thresh_5g = lfr_cfg->rssi_penalize_threshold_5g; 1260 1261 params->raise_factor_5g = lfr_cfg->rssi_boost_factor_5g; 1262 params->drop_factor_5g = lfr_cfg->rssi_penalize_factor_5g; 1263 params->max_raise_rssi_5g = lfr_cfg->max_rssi_boost_5g; 1264 params->max_drop_rssi_5g = lfr_cfg->max_rssi_penalize_5g; 1265 1266 if (rso_config->good_rssi_roam) 1267 params->good_rssi_threshold = NOISE_FLOOR_DBM_DEFAULT; 1268 else 1269 params->good_rssi_threshold = 0; 1270 1271 params->early_stop_scan_enable = lfr_cfg->early_stop_scan_enable; 1272 if (params->early_stop_scan_enable) { 1273 params->roam_earlystop_thres_min = 1274 lfr_cfg->early_stop_scan_min_threshold; 1275 params->roam_earlystop_thres_max = 1276 lfr_cfg->early_stop_scan_max_threshold; 1277 } 1278 1279 params->rssi_thresh_offset_5g = 1280 rso_cfg->cfg_param.rssi_thresh_offset_5g; 1281 } 1282 1283 /** 1284 * cm_roam_scan_offload_scan_period() - set roam offload scan period 1285 * parameters 1286 * @vdev_id: vdev id 1287 * @params: roam offload scan period related parameters 1288 * @rso_cfg: rso config 1289 * 1290 * This function is used to set roam offload scan period related parameters 1291 * 1292 * Return: None 1293 */ 1294 static void 1295 cm_roam_scan_offload_scan_period(uint8_t vdev_id, 1296 struct wlan_roam_scan_period_params *params, 1297 struct rso_config *rso_cfg) 1298 { 1299 struct rso_cfg_params *cfg_params; 1300 1301 cfg_params = &rso_cfg->cfg_param; 1302 1303 params->vdev_id = vdev_id; 1304 params->empty_scan_refresh_period = 1305 cfg_params->empty_scan_refresh_period; 1306 params->scan_period = params->empty_scan_refresh_period; 1307 params->scan_age = (3 * params->empty_scan_refresh_period); 1308 params->roam_scan_inactivity_time = 1309 cfg_params->roam_scan_inactivity_time; 1310 params->roam_inactive_data_packet_count = 1311 cfg_params->roam_inactive_data_packet_count; 1312 params->full_scan_period = 1313 cfg_params->full_roam_scan_period; 1314 mlme_debug("full_scan_period:%d, empty_scan_refresh_period:%d", 1315 params->full_scan_period, params->empty_scan_refresh_period); 1316 } 1317 1318 static void 1319 cm_roam_fill_11w_params(struct wlan_objmgr_vdev *vdev, 1320 struct ap_profile *profile) 1321 { 1322 uint32_t group_mgmt_cipher; 1323 bool peer_rmf_capable = false; 1324 uint32_t keymgmt; 1325 uint16_t rsn_caps; 1326 1327 /* 1328 * Get rsn cap of link, intersection of self cap and bss cap, 1329 * Only set PMF flags when both STA and current AP has MFP enabled 1330 */ 1331 rsn_caps = (uint16_t)wlan_crypto_get_param(vdev, 1332 WLAN_CRYPTO_PARAM_RSN_CAP); 1333 if (wlan_crypto_vdev_has_mgmtcipher(vdev, 1334 (1 << WLAN_CRYPTO_CIPHER_AES_GMAC) | 1335 (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256) | 1336 (1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) && 1337 (rsn_caps & 1338 WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) 1339 peer_rmf_capable = true; 1340 1341 keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MGMT_CIPHER); 1342 1343 if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) 1344 group_mgmt_cipher = WMI_CIPHER_AES_CMAC; 1345 else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC)) 1346 group_mgmt_cipher = WMI_CIPHER_AES_GMAC; 1347 else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256)) 1348 group_mgmt_cipher = WMI_CIPHER_BIP_GMAC_256; 1349 else 1350 group_mgmt_cipher = WMI_CIPHER_NONE; 1351 1352 if (peer_rmf_capable) { 1353 profile->rsn_mcastmgmtcipherset = group_mgmt_cipher; 1354 profile->flags |= WMI_AP_PROFILE_FLAG_PMF; 1355 } else { 1356 profile->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE; 1357 } 1358 } 1359 1360 #ifdef WLAN_FEATURE_11BE_MLO 1361 static void 1362 cm_update_mlo_score_params(struct scoring_param *req_score_params, 1363 struct weight_cfg *weight_config) 1364 { 1365 req_score_params->eht_caps_weightage = 1366 weight_config->eht_caps_weightage; 1367 req_score_params->mlo_weightage = 1368 weight_config->mlo_weightage; 1369 } 1370 #else 1371 static void 1372 cm_update_mlo_score_params(struct scoring_param *req_score_params, 1373 struct weight_cfg *weight_config) 1374 { 1375 } 1376 #endif 1377 1378 void cm_update_owe_info(struct wlan_objmgr_vdev *vdev, 1379 struct wlan_cm_connect_resp *rsp, uint8_t vdev_id) 1380 { 1381 struct rso_config *rso_cfg; 1382 struct owe_transition_mode_info *owe_info; 1383 uint8_t *ie_ptr; 1384 uint32_t ie_len, akm; 1385 const uint8_t *owe_transition_ie = NULL; 1386 uint8_t length; 1387 1388 rso_cfg = wlan_cm_get_rso_config(vdev); 1389 if (!rso_cfg) 1390 return; 1391 owe_info = &rso_cfg->owe_info; 1392 1393 akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 1394 if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE)) 1395 goto reset; 1396 1397 mlme_debug("[OWE_TRANSITION]:Update the owe open bss's ssid"); 1398 1399 if (!rsp->connect_ies.bcn_probe_rsp.ptr || 1400 !rsp->connect_ies.bcn_probe_rsp.len || 1401 (rsp->connect_ies.bcn_probe_rsp.len <= 1402 (sizeof(struct wlan_frame_hdr) + 1403 offsetof(struct wlan_bcn_frame, ie)))) { 1404 mlme_debug("invalid beacon probe rsp len %d", 1405 rsp->connect_ies.bcn_probe_rsp.len); 1406 goto reset; 1407 } 1408 1409 ie_len = (rsp->connect_ies.bcn_probe_rsp.len - 1410 sizeof(struct wlan_frame_hdr) - 1411 offsetof(struct wlan_bcn_frame, ie)); 1412 ie_ptr = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr + 1413 sizeof(struct wlan_frame_hdr) + 1414 offsetof(struct wlan_bcn_frame, ie)); 1415 1416 owe_transition_ie = wlan_get_vendor_ie_ptr_from_oui( 1417 OWE_TRANSITION_OUI_TYPE, 1418 OWE_TRANSITION_OUI_SIZE, ie_ptr, ie_len); 1419 if (!owe_transition_ie || owe_transition_ie[1] <= OWE_SSID_OFFSET) { 1420 mlme_debug("[OWE_TRANSITION]: Invalid owe transition ie"); 1421 goto reset; 1422 } 1423 1424 owe_info->is_owe_transition_conn = true; 1425 1426 length = *(owe_transition_ie + OWE_SSID_LEN_OFFSET); 1427 if (length > WLAN_SSID_MAX_LEN) { 1428 mlme_debug("[OWE_TRANSITION] Invalid ssid len %d", length); 1429 goto reset; 1430 } 1431 owe_info->ssid.length = length; 1432 qdf_mem_copy(owe_info->ssid.ssid, owe_transition_ie + OWE_SSID_OFFSET, 1433 owe_info->ssid.length); 1434 1435 mlme_debug("[OWE_TRANSITION] open bss ssid: \"" QDF_SSID_FMT "\"", 1436 QDF_SSID_REF(owe_info->ssid.length, owe_info->ssid.ssid)); 1437 return; 1438 1439 reset: 1440 if (owe_info->is_owe_transition_conn) 1441 owe_info->is_owe_transition_conn = false; 1442 1443 return; 1444 } 1445 1446 /** 1447 * cm_update_owe_ap_profile() - set owe ap profile 1448 * @params: roam offload scan period related parameters 1449 * @rso_cfg: rso config 1450 * 1451 * This function is used to set OPEN SSID value when STA is connected to OWE 1452 * transition AP in OWE security 1453 * 1454 * Return: None 1455 */ 1456 static void cm_update_owe_ap_profile(struct ap_profile_params *params, 1457 struct rso_config *rso_cfg) 1458 { 1459 struct owe_transition_mode_info *owe_ap_profile; 1460 bool is_owe_transition_conn; 1461 1462 owe_ap_profile = ¶ms->owe_ap_profile; 1463 is_owe_transition_conn = rso_cfg->owe_info.is_owe_transition_conn; 1464 mlme_debug("set owe ap profile:%d", is_owe_transition_conn); 1465 owe_ap_profile->is_owe_transition_conn = is_owe_transition_conn; 1466 owe_ap_profile->ssid.length = rso_cfg->owe_info.ssid.length; 1467 qdf_mem_copy(owe_ap_profile->ssid.ssid, rso_cfg->owe_info.ssid.ssid, 1468 rso_cfg->owe_info.ssid.length); 1469 } 1470 1471 static void cm_update_score_params(struct wlan_objmgr_psoc *psoc, 1472 struct wlan_mlme_psoc_ext_obj *mlme_obj, 1473 struct scoring_param *req_score_params, 1474 struct rso_config *rso_cfg) 1475 { 1476 struct wlan_mlme_roam_scoring_cfg *roam_score_params; 1477 struct weight_cfg *weight_config; 1478 struct psoc_mlme_obj *mlme_psoc_obj; 1479 struct scoring_cfg *score_config; 1480 struct dual_sta_policy *dual_sta_policy; 1481 1482 mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc); 1483 if (!mlme_psoc_obj) 1484 return; 1485 1486 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 1487 1488 score_config = &mlme_psoc_obj->psoc_cfg.score_config; 1489 roam_score_params = &mlme_obj->cfg.roam_scoring; 1490 weight_config = &score_config->weight_config; 1491 1492 if (!rso_cfg->cfg_param.enable_scoring_for_roam) 1493 req_score_params->disable_bitmap = 1494 WLAN_ROAM_SCORING_DISABLE_ALL; 1495 1496 req_score_params->rssi_weightage = weight_config->rssi_weightage; 1497 req_score_params->ht_weightage = weight_config->ht_caps_weightage; 1498 req_score_params->vht_weightage = weight_config->vht_caps_weightage; 1499 req_score_params->he_weightage = weight_config->he_caps_weightage; 1500 req_score_params->bw_weightage = weight_config->chan_width_weightage; 1501 req_score_params->band_weightage = weight_config->chan_band_weightage; 1502 req_score_params->nss_weightage = weight_config->nss_weightage; 1503 req_score_params->security_weightage = 1504 weight_config->security_weightage; 1505 req_score_params->esp_qbss_weightage = 1506 weight_config->channel_congestion_weightage; 1507 req_score_params->beamforming_weightage = 1508 weight_config->beamforming_cap_weightage; 1509 1510 /* 1511 * Don’t consider pcl weightage for STA connection, 1512 * if primary interface is configured. 1513 */ 1514 if (policy_mgr_is_pcl_weightage_required(psoc)) 1515 req_score_params->pcl_weightage = weight_config->pcl_weightage; 1516 1517 req_score_params->oce_wan_weightage = weight_config->oce_wan_weightage; 1518 req_score_params->oce_ap_tx_pwr_weightage = 1519 weight_config->oce_ap_tx_pwr_weightage; 1520 req_score_params->oce_subnet_id_weightage = 1521 weight_config->oce_subnet_id_weightage; 1522 req_score_params->sae_pk_ap_weightage = 1523 weight_config->sae_pk_ap_weightage; 1524 1525 cm_update_mlo_score_params(req_score_params, weight_config); 1526 1527 /* TODO: update scoring params corresponding to ML scoring */ 1528 req_score_params->bw_index_score = 1529 score_config->bandwidth_weight_per_index[0]; 1530 req_score_params->band_index_score = 1531 score_config->band_weight_per_index; 1532 req_score_params->nss_index_score = 1533 score_config->nss_weight_per_index[0]; 1534 req_score_params->security_index_score = 1535 score_config->security_weight_per_index; 1536 req_score_params->vendor_roam_score_algorithm = 1537 score_config->vendor_roam_score_algorithm; 1538 1539 req_score_params->roam_score_delta = 1540 roam_score_params->roam_score_delta; 1541 req_score_params->roam_trigger_bitmap = 1542 roam_score_params->roam_trigger_bitmap; 1543 1544 qdf_mem_copy(&req_score_params->rssi_scoring, &score_config->rssi_score, 1545 sizeof(struct rssi_config_score)); 1546 qdf_mem_copy(&req_score_params->esp_qbss_scoring, 1547 &score_config->esp_qbss_scoring, 1548 sizeof(struct per_slot_score)); 1549 qdf_mem_copy(&req_score_params->oce_wan_scoring, 1550 &score_config->oce_wan_scoring, 1551 sizeof(struct per_slot_score)); 1552 req_score_params->cand_min_roam_score_delta = 1553 roam_score_params->min_roam_score_delta; 1554 } 1555 1556 static uint32_t cm_crpto_cipher_wmi_cipher(int32_t cipherset) 1557 { 1558 1559 if (!cipherset || cipherset < 0) 1560 return WMI_CIPHER_NONE; 1561 1562 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM) || 1563 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM_256)) 1564 return WMI_CIPHER_AES_GCM; 1565 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM) || 1566 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_OCB) || 1567 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM_256)) 1568 return WMI_CIPHER_AES_CCM; 1569 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_TKIP)) 1570 return WMI_CIPHER_TKIP; 1571 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC) || 1572 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC_256)) 1573 return WMI_CIPHER_AES_CMAC; 1574 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_GCM4) || 1575 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_SMS4)) 1576 return WMI_CIPHER_WAPI; 1577 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC) || 1578 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC_256)) 1579 return WMI_CIPHER_AES_GMAC; 1580 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP) || 1581 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_40) || 1582 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_104)) 1583 return WMI_CIPHER_WEP; 1584 1585 return WMI_CIPHER_NONE; 1586 } 1587 1588 static uint32_t cm_get_rsn_wmi_auth_type(int32_t akm) 1589 { 1590 /* Try the more preferred ones first. */ 1591 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384)) 1592 return WMI_AUTH_FT_RSNA_FILS_SHA384; 1593 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256)) 1594 return WMI_AUTH_FT_RSNA_FILS_SHA256; 1595 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384)) 1596 return WMI_AUTH_RSNA_FILS_SHA384; 1597 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256)) 1598 return WMI_AUTH_RSNA_FILS_SHA256; 1599 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) 1600 return WMI_AUTH_FT_RSNA_SAE_SHA384; 1601 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY)) 1602 return WMI_AUTH_WPA3_SAE_SHA384; 1603 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE)) 1604 return WMI_AUTH_FT_RSNA_SAE; 1605 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE)) 1606 return WMI_AUTH_WPA3_SAE; 1607 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE)) 1608 return WMI_AUTH_WPA3_OWE; 1609 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X)) 1610 return WMI_AUTH_FT_RSNA; 1611 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK)) 1612 return WMI_AUTH_FT_RSNA_PSK; 1613 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) 1614 return WMI_AUTH_RSNA; 1615 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK)) 1616 return WMI_AUTH_RSNA_PSK; 1617 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) 1618 return WMI_AUTH_CCKM_RSNA; 1619 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) 1620 return WMI_AUTH_RSNA_PSK_SHA256; 1621 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) 1622 return WMI_AUTH_RSNA_8021X_SHA256; 1623 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B)) 1624 return WMI_AUTH_RSNA_SUITE_B_8021X_SHA256; 1625 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192)) 1626 return WMI_AUTH_RSNA_SUITE_B_8021X_SHA384; 1627 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384)) 1628 return WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384; 1629 else 1630 return WMI_AUTH_NONE; 1631 } 1632 1633 static uint32_t cm_get_wpa_wmi_auth_type(int32_t akm) 1634 { 1635 /* Try the more preferred ones first. */ 1636 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) 1637 return WMI_AUTH_WPA; 1638 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK)) 1639 return WMI_AUTH_WPA_PSK; 1640 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) 1641 return WMI_AUTH_CCKM_WPA; 1642 else 1643 return WMI_AUTH_NONE; 1644 } 1645 1646 static uint32_t cm_get_wapi_wmi_auth_type(int32_t akm) 1647 { 1648 /* Try the more preferred ones first. */ 1649 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT)) 1650 return WMI_AUTH_WAPI; 1651 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK)) 1652 return WMI_AUTH_WAPI_PSK; 1653 else 1654 return WMI_AUTH_NONE; 1655 } 1656 1657 uint32_t cm_crypto_authmode_to_wmi_authmode(int32_t authmodeset, 1658 int32_t akm, int32_t ucastcipherset) 1659 { 1660 if (!authmodeset || authmodeset < 0) 1661 return WMI_AUTH_OPEN; 1662 1663 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_OPEN)) 1664 return WMI_AUTH_OPEN; 1665 1666 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_AUTO) || 1667 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_NONE)) { 1668 if ((QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) || 1669 QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) || 1670 QDF_HAS_PARAM(ucastcipherset, 1671 WLAN_CRYPTO_CIPHER_WEP_104) || 1672 QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_TKIP) || 1673 QDF_HAS_PARAM(ucastcipherset, 1674 WLAN_CRYPTO_CIPHER_AES_GCM) || 1675 QDF_HAS_PARAM(ucastcipherset, 1676 WLAN_CRYPTO_CIPHER_AES_GCM_256) || 1677 QDF_HAS_PARAM(ucastcipherset, 1678 WLAN_CRYPTO_CIPHER_AES_CCM) || 1679 QDF_HAS_PARAM(ucastcipherset, 1680 WLAN_CRYPTO_CIPHER_AES_OCB) || 1681 QDF_HAS_PARAM(ucastcipherset, 1682 WLAN_CRYPTO_CIPHER_AES_CCM_256))) 1683 return WMI_AUTH_OPEN; 1684 else 1685 return WMI_AUTH_NONE; 1686 } 1687 1688 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SHARED)) 1689 return WMI_AUTH_SHARED; 1690 1691 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_8021X) || 1692 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_RSNA) || 1693 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_CCKM) || 1694 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SAE) || 1695 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_FILS_SK)) 1696 return cm_get_rsn_wmi_auth_type(akm); 1697 1698 1699 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WPA)) 1700 return cm_get_wpa_wmi_auth_type(akm); 1701 1702 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WAPI)) 1703 return cm_get_wapi_wmi_auth_type(akm); 1704 1705 return WMI_AUTH_OPEN; 1706 } 1707 1708 static void cm_update_crypto_params(struct wlan_objmgr_vdev *vdev, 1709 struct ap_profile *profile) 1710 { 1711 int32_t keymgmt, connected_akm, authmode, uccipher, mccipher; 1712 enum wlan_crypto_key_mgmt i; 1713 int32_t num_allowed_authmode = 0; 1714 struct rso_config *rso_cfg; 1715 1716 rso_cfg = wlan_cm_get_rso_config(vdev); 1717 if (!rso_cfg) 1718 return; 1719 1720 /* Pairwise cipher suite */ 1721 uccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_UCAST_CIPHER); 1722 profile->rsn_ucastcipherset = cm_crpto_cipher_wmi_cipher(uccipher); 1723 1724 /* Group cipher suite */ 1725 mccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MCAST_CIPHER); 1726 profile->rsn_mcastcipherset = cm_crpto_cipher_wmi_cipher(mccipher); 1727 1728 /* Group management cipher suite */ 1729 cm_roam_fill_11w_params(vdev, profile); 1730 1731 authmode = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE); 1732 /* Get connected akm */ 1733 connected_akm = wlan_crypto_get_param(vdev, 1734 WLAN_CRYPTO_PARAM_KEY_MGMT); 1735 profile->rsn_authmode = 1736 cm_crypto_authmode_to_wmi_authmode(authmode, 1737 connected_akm, 1738 uccipher); 1739 /* Get keymgmt from self security info */ 1740 keymgmt = rso_cfg->orig_sec_info.key_mgmt; 1741 1742 for (i = 0; i < WLAN_CRYPTO_KEY_MGMT_MAX; i++) { 1743 /* 1744 * Send AKM in allowed list which are not present in connected 1745 * akm 1746 */ 1747 if (QDF_HAS_PARAM(keymgmt, i) && 1748 num_allowed_authmode < WLAN_CRYPTO_AUTH_MAX) { 1749 profile->allowed_authmode[num_allowed_authmode++] = 1750 cm_crypto_authmode_to_wmi_authmode(authmode, 1751 (keymgmt & (1 << i)), 1752 uccipher); 1753 } 1754 } 1755 1756 profile->num_allowed_authmode = num_allowed_authmode; 1757 } 1758 1759 /** 1760 * cm_roam_scan_offload_ap_profile() - set roam ap profile parameters 1761 * @psoc: psoc ctx 1762 * @vdev: vdev id 1763 * @rso_cfg: rso config 1764 * @params: roam ap profile related parameters 1765 * 1766 * This function is used to set roam ap profile related parameters 1767 * 1768 * Return: None 1769 */ 1770 static void 1771 cm_roam_scan_offload_ap_profile(struct wlan_objmgr_psoc *psoc, 1772 struct wlan_objmgr_vdev *vdev, 1773 struct rso_config *rso_cfg, 1774 struct ap_profile_params *params) 1775 { 1776 struct wlan_mlme_psoc_ext_obj *mlme_obj; 1777 uint8_t vdev_id = wlan_vdev_get_id(vdev); 1778 struct ap_profile *profile = ¶ms->profile; 1779 1780 mlme_obj = mlme_get_psoc_ext_obj(psoc); 1781 if (!mlme_obj) 1782 return; 1783 1784 params->vdev_id = vdev_id; 1785 wlan_vdev_mlme_get_ssid(vdev, profile->ssid.ssid, 1786 &profile->ssid.length); 1787 1788 cm_update_crypto_params(vdev, profile); 1789 1790 profile->rssi_threshold = rso_cfg->cfg_param.roam_rssi_diff; 1791 mlme_debug("profile->rssi_threshold:%d", profile->rssi_threshold); 1792 profile->bg_rssi_threshold = rso_cfg->cfg_param.bg_rssi_threshold; 1793 /* 1794 * rssi_diff which is updated via framework is equivalent to the 1795 * INI RoamRssiDiff parameter and hence should be updated. 1796 */ 1797 if (mlme_obj->cfg.lfr.rso_user_config.rssi_diff) 1798 profile->rssi_threshold = 1799 mlme_obj->cfg.lfr.rso_user_config.rssi_diff; 1800 1801 profile->rssi_abs_thresh = 1802 mlme_obj->cfg.lfr.roam_rssi_abs_threshold; 1803 1804 if (rso_cfg->owe_info.is_owe_transition_conn) 1805 cm_update_owe_ap_profile(params, rso_cfg); 1806 1807 cm_update_score_params(psoc, mlme_obj, ¶ms->param, rso_cfg); 1808 1809 params->min_rssi_params[DEAUTH_MIN_RSSI] = 1810 mlme_obj->cfg.trig_min_rssi[DEAUTH_MIN_RSSI]; 1811 params->min_rssi_params[BMISS_MIN_RSSI] = 1812 mlme_obj->cfg.trig_min_rssi[BMISS_MIN_RSSI]; 1813 params->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM] = 1814 mlme_obj->cfg.trig_min_rssi[MIN_RSSI_2G_TO_5G_ROAM]; 1815 1816 params->score_delta_param[IDLE_ROAM_TRIGGER] = 1817 mlme_obj->cfg.trig_score_delta[IDLE_ROAM_TRIGGER]; 1818 params->score_delta_param[BTM_ROAM_TRIGGER] = 1819 mlme_obj->cfg.trig_score_delta[BTM_ROAM_TRIGGER]; 1820 } 1821 1822 static bool 1823 cm_check_band_freq_match(enum band_info band, qdf_freq_t freq) 1824 { 1825 if (band == BAND_ALL) 1826 return true; 1827 1828 if (band == BAND_2G && WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 1829 return true; 1830 1831 if (band == BAND_5G && WLAN_REG_IS_5GHZ_CH_FREQ(freq)) 1832 return true; 1833 1834 /* 1835 * Not adding the band check for now as band_info will be soon 1836 * replaced with reg_wifi_band enum 1837 */ 1838 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) 1839 return true; 1840 1841 return false; 1842 } 1843 1844 /** 1845 * cm_is_dfs_unsafe_extra_band_chan() - check if dfs unsafe or extra band 1846 * channel 1847 * @vdev: vdev 1848 * @mlme_obj: psoc mlme obj 1849 * @freq: channel freq to check 1850 * @band: band for intra band check 1851 .*. 1852 * Return: bool if match else false 1853 */ 1854 static bool 1855 cm_is_dfs_unsafe_extra_band_chan(struct wlan_objmgr_vdev *vdev, 1856 struct wlan_mlme_psoc_ext_obj *mlme_obj, 1857 qdf_freq_t freq, 1858 enum band_info band) 1859 { 1860 uint16_t unsafe_chan[NUM_CHANNELS]; 1861 uint16_t unsafe_chan_cnt = 0; 1862 uint16_t cnt = 0; 1863 bool is_unsafe_chan; 1864 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 1865 struct rso_roam_policy_params *roam_policy; 1866 struct wlan_objmgr_pdev *pdev; 1867 1868 if (!qdf_ctx) 1869 return true; 1870 1871 pdev = wlan_vdev_get_pdev(vdev); 1872 if (!pdev) 1873 return true; 1874 1875 roam_policy = &mlme_obj->cfg.lfr.rso_user_config.policy_params; 1876 if ((mlme_obj->cfg.lfr.roaming_dfs_channel == 1877 ROAMING_DFS_CHANNEL_DISABLED || 1878 roam_policy->dfs_mode == STA_ROAM_POLICY_DFS_DISABLED) && 1879 (wlan_reg_is_dfs_for_freq(pdev, freq))) 1880 return true; 1881 1882 pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, 1883 &unsafe_chan_cnt, 1884 sizeof(unsafe_chan)); 1885 if (roam_policy->skip_unsafe_channels && unsafe_chan_cnt) { 1886 is_unsafe_chan = false; 1887 for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) { 1888 if (unsafe_chan[cnt] == freq) { 1889 is_unsafe_chan = true; 1890 mlme_debug("ignoring unsafe channel freq %d", 1891 freq); 1892 return true; 1893 } 1894 } 1895 } 1896 if (!cm_check_band_freq_match(band, freq)) { 1897 mlme_debug("ignoring non-intra band freq %d", freq); 1898 return true; 1899 } 1900 1901 return false; 1902 } 1903 1904 /** 1905 * cm_populate_roam_chan_list() - Populate roam channel list 1906 * parameters 1907 * @vdev: vdev 1908 * @mlme_obj: mlme_obj 1909 * @dst: Destination roam channel buf to populate the roam chan list 1910 * @src: Source channel list 1911 * 1912 * Return: QDF_STATUS enumeration 1913 */ 1914 static QDF_STATUS 1915 cm_populate_roam_chan_list(struct wlan_objmgr_vdev *vdev, 1916 struct wlan_mlme_psoc_ext_obj *mlme_obj, 1917 struct wlan_roam_scan_channel_list *dst, 1918 struct rso_chan_info *src) 1919 { 1920 enum band_info band; 1921 uint32_t band_cap; 1922 uint8_t i = 0; 1923 uint8_t num_channels = 0; 1924 qdf_freq_t *freq_lst = src->freq_list; 1925 1926 /* 1927 * The INI channels need to be filtered with respect to the current band 1928 * that is supported. 1929 */ 1930 band_cap = mlme_obj->cfg.gen.band_capability; 1931 if (!band_cap) { 1932 mlme_err("Invalid band_cap(%d), roam scan offload req aborted", 1933 band_cap); 1934 return QDF_STATUS_E_FAILURE; 1935 } 1936 1937 band = wlan_reg_band_bitmap_to_band_info(band_cap); 1938 num_channels = dst->chan_count; 1939 for (i = 0; i < src->num_chan; i++) { 1940 if (wlan_is_channel_present_in_list(dst->chan_freq_list, 1941 num_channels, *freq_lst)) { 1942 freq_lst++; 1943 continue; 1944 } 1945 if (cm_is_dfs_unsafe_extra_band_chan(vdev, mlme_obj, 1946 *freq_lst, band)) { 1947 freq_lst++; 1948 continue; 1949 } 1950 dst->chan_freq_list[num_channels++] = *freq_lst; 1951 freq_lst++; 1952 } 1953 dst->chan_count = num_channels; 1954 1955 return QDF_STATUS_SUCCESS; 1956 } 1957 1958 void 1959 cm_update_tried_candidate_freq_list(struct wlan_objmgr_psoc *psoc, 1960 struct wlan_objmgr_vdev *vdev, 1961 struct wlan_cm_connect_resp *connect_rsp) 1962 { 1963 struct wlan_mlme_psoc_ext_obj *mlme_obj; 1964 struct rso_config *rso_cfg; 1965 struct wlan_chan_list *tried_freq_list; 1966 enum band_info band; 1967 uint32_t band_cap; 1968 1969 if (!connect_rsp->freq || (connect_rsp->reason != CM_JOIN_TIMEOUT && 1970 connect_rsp->reason != CM_AUTH_TIMEOUT && 1971 connect_rsp->reason != CM_ASSOC_TIMEOUT)) 1972 return; 1973 1974 mlme_obj = mlme_get_psoc_ext_obj(psoc); 1975 if (!mlme_obj) 1976 return; 1977 1978 band_cap = mlme_obj->cfg.gen.band_capability; 1979 if (!band_cap) { 1980 mlme_err("vdev: %d Invalid band_cap(%d)", connect_rsp->vdev_id, 1981 band_cap); 1982 return; 1983 } 1984 1985 band = wlan_reg_band_bitmap_to_band_info(band_cap); 1986 if (cm_is_dfs_unsafe_extra_band_chan(vdev, mlme_obj, 1987 connect_rsp->freq, band)) 1988 return; 1989 1990 rso_cfg = wlan_cm_get_rso_config(vdev); 1991 if (!rso_cfg) 1992 return; 1993 1994 tried_freq_list = &rso_cfg->tried_candidate_freq_list; 1995 1996 if (tried_freq_list->num_chan >= CFG_VALID_CHANNEL_LIST_LEN) 1997 return; 1998 1999 if (wlan_is_channel_present_in_list(tried_freq_list->freq_list, 2000 tried_freq_list->num_chan, 2001 connect_rsp->freq)) 2002 return; 2003 2004 tried_freq_list->freq_list[tried_freq_list->num_chan++] = 2005 connect_rsp->freq; 2006 2007 mlme_debug("vdev: %d added freq:%d, total num freq %d", 2008 connect_rsp->vdev_id, connect_rsp->freq, 2009 tried_freq_list->num_chan); 2010 } 2011 2012 static QDF_STATUS 2013 cm_fetch_ch_lst_from_ini(struct wlan_objmgr_vdev *vdev, 2014 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2015 struct wlan_roam_scan_channel_list *chan_info, 2016 struct rso_chan_info *specific_chan_info) 2017 { 2018 QDF_STATUS status; 2019 2020 status = cm_populate_roam_chan_list(vdev, mlme_obj, chan_info, 2021 specific_chan_info); 2022 if (QDF_IS_STATUS_ERROR(status)) { 2023 mlme_err("Failed to copy channels to roam list"); 2024 return status; 2025 } 2026 chan_info->chan_cache_type = CHANNEL_LIST_STATIC; 2027 2028 return QDF_STATUS_SUCCESS; 2029 } 2030 2031 static void 2032 cm_fetch_ch_lst_from_occupied_lst(struct wlan_objmgr_vdev *vdev, 2033 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2034 struct rso_config *rso_cfg, 2035 struct wlan_roam_scan_channel_list *chan_info, 2036 uint8_t reason) 2037 { 2038 uint8_t i = 0; 2039 uint8_t num_channels = 0; 2040 qdf_freq_t op_freq; 2041 enum band_info band = BAND_ALL; 2042 struct wlan_chan_list *occupied_channels; 2043 2044 occupied_channels = &rso_cfg->occupied_chan_lst; 2045 op_freq = wlan_get_operation_chan_freq(vdev); 2046 if (mlme_obj->cfg.lfr.roam_intra_band) { 2047 if (WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) 2048 band = BAND_5G; 2049 else if (WLAN_REG_IS_24GHZ_CH_FREQ(op_freq)) 2050 band = BAND_2G; 2051 else 2052 band = BAND_UNKNOWN; 2053 } 2054 2055 for (i = 0; i < occupied_channels->num_chan && 2056 occupied_channels->num_chan < CFG_VALID_CHANNEL_LIST_LEN; i++) { 2057 if (cm_is_dfs_unsafe_extra_band_chan(vdev, mlme_obj, 2058 occupied_channels->freq_list[i], band)) 2059 continue; 2060 2061 chan_info->chan_freq_list[num_channels++] = 2062 occupied_channels->freq_list[i]; 2063 } 2064 chan_info->chan_count = num_channels; 2065 chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; 2066 } 2067 2068 /** 2069 * cm_add_ch_lst_from_roam_scan_list() - channel from roam scan chan list 2070 * parameters 2071 * @vdev: vdev 2072 * @mlme_obj: mlme_obj 2073 * @chan_info: RSO channel info 2074 * @rso_cfg: rso config 2075 * 2076 * Return: QDF_STATUS 2077 */ 2078 static QDF_STATUS 2079 cm_add_ch_lst_from_roam_scan_list(struct wlan_objmgr_vdev *vdev, 2080 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2081 struct wlan_roam_scan_channel_list *chan_info, 2082 struct rso_config *rso_cfg) 2083 { 2084 QDF_STATUS status; 2085 struct rso_chan_info *pref_chan_info = 2086 &rso_cfg->cfg_param.pref_chan_info; 2087 2088 if (!pref_chan_info->num_chan) 2089 return QDF_STATUS_SUCCESS; 2090 2091 status = cm_populate_roam_chan_list(vdev, mlme_obj, chan_info, 2092 pref_chan_info); 2093 if (QDF_IS_STATUS_ERROR(status)) { 2094 mlme_err("Failed to copy channels to roam list"); 2095 return status; 2096 } 2097 cm_dump_freq_list(pref_chan_info); 2098 chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; 2099 2100 return QDF_STATUS_SUCCESS; 2101 } 2102 2103 #ifdef FEATURE_WLAN_ESE 2104 static void 2105 cm_fetch_ch_lst_from_received_list(struct wlan_objmgr_vdev *vdev, 2106 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2107 struct rso_config *rso_cfg, 2108 struct wlan_roam_scan_channel_list *chan_info) 2109 { 2110 uint8_t i = 0; 2111 uint8_t num_channels = 0; 2112 qdf_freq_t *freq_lst = NULL; 2113 enum band_info band = BAND_ALL; 2114 struct rso_chan_info *curr_ch_lst_info = &rso_cfg->roam_scan_freq_lst; 2115 2116 if (curr_ch_lst_info->num_chan == 0) 2117 return; 2118 2119 freq_lst = curr_ch_lst_info->freq_list; 2120 for (i = 0; i < curr_ch_lst_info->num_chan; i++) { 2121 if (cm_is_dfs_unsafe_extra_band_chan(vdev, mlme_obj, 2122 freq_lst[i], band)) 2123 continue; 2124 2125 chan_info->chan_freq_list[num_channels++] = freq_lst[i]; 2126 } 2127 chan_info->chan_count = num_channels; 2128 chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; 2129 } 2130 2131 static inline bool cm_is_ese_assoc(struct rso_config *rso_cfg) 2132 { 2133 return rso_cfg->is_ese_assoc; 2134 } 2135 static void cm_esr_populate_version_ie( 2136 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2137 struct wlan_roam_scan_offload_params *rso_mode_cfg) 2138 { 2139 static const uint8_t ese_ie[] = {0x0, 0x40, 0x96, 0x3, 2140 ESE_VERSION_SUPPORTED}; 2141 2142 /* Append ESE version IE if isEseIniFeatureEnabled INI is enabled */ 2143 if (mlme_obj->cfg.lfr.ese_enabled) 2144 wlan_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_VENDOR, 2145 sizeof(ese_ie), ese_ie); 2146 } 2147 2148 #else 2149 static inline void 2150 cm_fetch_ch_lst_from_received_list(struct wlan_objmgr_vdev *vdev, 2151 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2152 struct rso_config *rso_cfg, 2153 struct wlan_roam_scan_channel_list *chan_info) 2154 {} 2155 static inline bool cm_is_ese_assoc(struct rso_config *rso_cfg) 2156 { 2157 return false; 2158 } 2159 static inline void cm_esr_populate_version_ie( 2160 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2161 struct wlan_roam_scan_offload_params *rso_mode_cfg) 2162 {} 2163 #endif 2164 2165 /** 2166 * cm_fetch_valid_ch_lst() - fetch channel list from valid channel list and 2167 * update rso req msg parameters 2168 * @vdev: vdev 2169 * @mlme_obj: mlme_obj 2170 * @chan_info: channel info 2171 * 2172 * Return: QDF_STATUS 2173 */ 2174 static QDF_STATUS 2175 cm_fetch_valid_ch_lst(struct wlan_objmgr_vdev *vdev, 2176 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2177 struct wlan_roam_scan_channel_list *chan_info) 2178 { 2179 qdf_freq_t *ch_freq_list = NULL; 2180 uint8_t i = 0, num_channels = 0; 2181 enum band_info band = BAND_ALL; 2182 qdf_freq_t op_freq; 2183 2184 op_freq = wlan_get_operation_chan_freq(vdev); 2185 if (mlme_obj->cfg.lfr.roam_intra_band) { 2186 if (WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) 2187 band = BAND_5G; 2188 else if (WLAN_REG_IS_24GHZ_CH_FREQ(op_freq)) 2189 band = BAND_2G; 2190 else 2191 band = BAND_UNKNOWN; 2192 } 2193 2194 ch_freq_list = mlme_obj->cfg.reg.valid_channel_freq_list; 2195 for (i = 0; i < mlme_obj->cfg.reg.valid_channel_list_num; i++) { 2196 if (wlan_reg_is_dsrc_freq(ch_freq_list[i])) 2197 continue; 2198 if (cm_is_dfs_unsafe_extra_band_chan(vdev, mlme_obj, 2199 ch_freq_list[i], 2200 band)) 2201 continue; 2202 chan_info->chan_freq_list[num_channels++] = ch_freq_list[i]; 2203 } 2204 chan_info->chan_count = num_channels; 2205 chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; 2206 2207 return QDF_STATUS_SUCCESS; 2208 } 2209 2210 static void 2211 cm_update_rso_freq_list(struct rso_config *rso_cfg, 2212 struct wlan_roam_scan_channel_list *chan_info) 2213 { 2214 struct wlan_chan_list *tried_freq_list; 2215 uint8_t i; 2216 2217 tried_freq_list = &rso_cfg->tried_candidate_freq_list; 2218 2219 if (!tried_freq_list->num_chan) 2220 return; 2221 2222 for (i = 0; i < tried_freq_list->num_chan && 2223 chan_info->chan_count < CFG_VALID_CHANNEL_LIST_LEN; i++) { 2224 if (wlan_is_channel_present_in_list(chan_info->chan_freq_list, 2225 chan_info->chan_count, 2226 tried_freq_list->freq_list[i])) 2227 continue; 2228 chan_info->chan_freq_list[chan_info->chan_count++] = 2229 tried_freq_list->freq_list[i]; 2230 } 2231 } 2232 2233 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 2234 static void cm_update_rso_freq_list_from_partner_link( 2235 struct wlan_objmgr_vdev *vdev, 2236 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2237 struct wlan_roam_scan_channel_list *chan_info) 2238 { 2239 struct mlo_link_info *mlo_link_info; 2240 uint8_t link_info_iter = 0; 2241 qdf_freq_t chan_freq; 2242 2243 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) 2244 return; 2245 2246 mlo_link_info = &vdev->mlo_dev_ctx->link_ctx->links_info[0]; 2247 for (link_info_iter = 0; link_info_iter < WLAN_MAX_ML_BSS_LINKS; 2248 link_info_iter++, mlo_link_info++) { 2249 if (qdf_is_macaddr_zero(&mlo_link_info->ap_link_addr) || 2250 mlo_link_info->link_id == WLAN_INVALID_LINK_ID) 2251 continue; 2252 chan_freq = mlo_link_info->link_chan_info->ch_freq; 2253 if (wlan_is_channel_present_in_list(chan_info->chan_freq_list, 2254 chan_info->chan_count, 2255 chan_freq)) 2256 continue; 2257 chan_info->chan_freq_list[chan_info->chan_count++] = 2258 chan_freq; 2259 mlme_debug("link_id: %d added freq:%d ", 2260 mlo_link_info->link_id, 2261 mlo_link_info->link_chan_info->ch_freq); 2262 } 2263 } 2264 2265 #else 2266 static void cm_update_rso_freq_list_from_partner_link( 2267 struct wlan_objmgr_vdev *vdev, 2268 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2269 struct wlan_roam_scan_channel_list *chan_info) 2270 { 2271 } 2272 #endif 2273 2274 static void 2275 cm_fill_rso_channel_list(struct wlan_objmgr_psoc *psoc, 2276 struct wlan_objmgr_vdev *vdev, 2277 struct rso_config *rso_cfg, 2278 struct wlan_roam_scan_channel_list *chan_info, 2279 uint8_t reason) 2280 { 2281 QDF_STATUS status; 2282 uint8_t ch_cache_str[128] = {0}; 2283 uint8_t i, j; 2284 struct rso_chan_info *specific_chan_info; 2285 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2286 uint8_t vdev_id = wlan_vdev_get_id(vdev); 2287 2288 mlme_obj = mlme_get_psoc_ext_obj(psoc); 2289 if (!mlme_obj) 2290 return; 2291 2292 specific_chan_info = &rso_cfg->cfg_param.specific_chan_info; 2293 chan_info->vdev_id = vdev_id; 2294 if (cm_is_ese_assoc(rso_cfg) || 2295 rso_cfg->roam_scan_freq_lst.num_chan == 0) { 2296 /* 2297 * Retrieve the Channel Cache either from ini or from 2298 * the occupied channels list along with preferred 2299 * channel list configured by the client. 2300 * Give Preference to INI Channels 2301 */ 2302 if (specific_chan_info->num_chan) { 2303 status = cm_fetch_ch_lst_from_ini(vdev, mlme_obj, 2304 chan_info, 2305 specific_chan_info); 2306 if (QDF_IS_STATUS_ERROR(status)) { 2307 mlme_err("Fetch channel list from ini failed"); 2308 return; 2309 } 2310 } else if (reason == REASON_FLUSH_CHANNEL_LIST) { 2311 chan_info->chan_cache_type = CHANNEL_LIST_STATIC; 2312 chan_info->chan_count = 0; 2313 } else { 2314 cm_fetch_ch_lst_from_occupied_lst(vdev, mlme_obj, 2315 rso_cfg, 2316 chan_info, reason); 2317 /* Add the preferred channel list configured by 2318 * client to the roam channel list along with 2319 * occupied channel list. 2320 */ 2321 cm_add_ch_lst_from_roam_scan_list(vdev, mlme_obj, 2322 chan_info, rso_cfg); 2323 2324 /* 2325 * update channel list for non assoc link 2326 */ 2327 cm_update_rso_freq_list_from_partner_link( 2328 vdev, mlme_obj, chan_info); 2329 2330 /* 2331 * update the roam channel list on the top of entries 2332 * present in the scan db which gets stored in the rso 2333 * config during connect resp failure in 2334 * wlan_cm_send_connect_rsp 2335 */ 2336 cm_update_rso_freq_list(rso_cfg, chan_info); 2337 } 2338 } else { 2339 /* 2340 * If ESE is enabled, and a neighbor Report is received, 2341 * then Ignore the INI Channels or the Occupied Channel 2342 * List. Consider the channels in the neighbor list sent 2343 * by the ESE AP 2344 */ 2345 cm_fetch_ch_lst_from_received_list(vdev, mlme_obj, rso_cfg, 2346 chan_info); 2347 } 2348 2349 if (!chan_info->chan_count && 2350 reason != REASON_FLUSH_CHANNEL_LIST) { 2351 /* Maintain the Valid Channels List */ 2352 status = cm_fetch_valid_ch_lst(vdev, mlme_obj, chan_info); 2353 if (QDF_IS_STATUS_ERROR(status)) { 2354 mlme_err("Fetch channel list fail"); 2355 return; 2356 } 2357 } 2358 2359 for (i = 0, j = 0; i < chan_info->chan_count; i++) { 2360 if (j < sizeof(ch_cache_str)) 2361 j += snprintf(ch_cache_str + j, 2362 sizeof(ch_cache_str) - j, " %d", 2363 chan_info->chan_freq_list[i]); 2364 else 2365 break; 2366 } 2367 2368 mlme_debug("chan_cache_type:%d, No of chan:%d, chan: %s", 2369 chan_info->chan_cache_type, 2370 chan_info->chan_count, ch_cache_str); 2371 } 2372 2373 static void 2374 cm_add_denylist_ap_list(struct wlan_objmgr_pdev *pdev, 2375 struct roam_scan_filter_params *params) 2376 { 2377 int i = 0; 2378 struct reject_ap_config_params *reject_list; 2379 2380 reject_list = qdf_mem_malloc(sizeof(*reject_list) * 2381 MAX_RSSI_AVOID_BSSID_LIST); 2382 if (!reject_list) 2383 return; 2384 2385 params->num_bssid_deny_list = 2386 wlan_dlm_get_bssid_reject_list(pdev, reject_list, 2387 MAX_RSSI_AVOID_BSSID_LIST, 2388 USERSPACE_DENYLIST_TYPE); 2389 if (!params->num_bssid_deny_list) { 2390 qdf_mem_free(reject_list); 2391 return; 2392 } 2393 2394 for (i = 0; i < params->num_bssid_deny_list; i++) { 2395 qdf_copy_macaddr(¶ms->bssid_avoid_list[i], 2396 &reject_list[i].bssid); 2397 mlme_debug("Denylist bssid[%d]:" QDF_MAC_ADDR_FMT, i, 2398 QDF_MAC_ADDR_REF(params->bssid_avoid_list[i].bytes)); 2399 } 2400 2401 qdf_mem_free(reject_list); 2402 } 2403 2404 /** 2405 * cm_roam_scan_filter() - set roam scan filter parameters 2406 * @psoc: psoc 2407 * @pdev: pdev 2408 * @vdev_id: vdev id 2409 * @command: rso command 2410 * @reason: reason to roam 2411 * @scan_filter_params: roam scan filter related parameters 2412 * 2413 * There are filters such as allowlist, denylist and preferred 2414 * list that need to be applied to the scan results to form the 2415 * probable candidates for roaming. 2416 * 2417 * Return: None 2418 */ 2419 static void 2420 cm_roam_scan_filter(struct wlan_objmgr_psoc *psoc, 2421 struct wlan_objmgr_pdev *pdev, 2422 uint8_t vdev_id, uint8_t command, uint8_t reason, 2423 struct wlan_roam_scan_filter_params *scan_filter_params) 2424 { 2425 int i; 2426 uint32_t num_ssid_allow_list = 0, num_bssid_preferred_list = 0; 2427 uint32_t op_bitmap = 0; 2428 struct roam_scan_filter_params *params; 2429 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2430 struct rso_config_params *rso_usr_cfg; 2431 struct rso_user_config *rso_usr_config; 2432 struct wlan_objmgr_vdev *vdev; 2433 2434 mlme_obj = mlme_get_psoc_ext_obj(psoc); 2435 if (!mlme_obj) 2436 return; 2437 2438 scan_filter_params->reason = reason; 2439 params = &scan_filter_params->filter_params; 2440 rso_usr_cfg = &mlme_obj->cfg.lfr.rso_user_config; 2441 2442 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 2443 WLAN_MLME_CM_ID); 2444 if (!vdev) 2445 return; 2446 2447 rso_usr_config = wlan_cm_get_rso_user_config(vdev); 2448 if (!rso_usr_config) 2449 goto end; 2450 2451 if (command != ROAM_SCAN_OFFLOAD_STOP) { 2452 switch (reason) { 2453 case REASON_ROAM_SET_DENYLIST_BSSID: 2454 op_bitmap |= ROAM_FILTER_OP_BITMAP_BLACK_LIST; 2455 cm_add_denylist_ap_list(pdev, params); 2456 break; 2457 case REASON_ROAM_SET_SSID_ALLOWED: 2458 op_bitmap |= ROAM_FILTER_OP_BITMAP_WHITE_LIST; 2459 num_ssid_allow_list = 2460 rso_usr_config->num_ssid_allowed_list; 2461 break; 2462 case REASON_ROAM_SET_FAVORED_BSSID: 2463 op_bitmap |= ROAM_FILTER_OP_BITMAP_PREFER_BSSID; 2464 num_bssid_preferred_list = 2465 rso_usr_cfg->num_bssid_favored; 2466 break; 2467 case REASON_CTX_INIT: 2468 if (command == ROAM_SCAN_OFFLOAD_START) { 2469 num_ssid_allow_list = 2470 rso_usr_config->num_ssid_allowed_list; 2471 if (num_ssid_allow_list) 2472 op_bitmap |= 2473 ROAM_FILTER_OP_BITMAP_WHITE_LIST; 2474 cm_add_denylist_ap_list(pdev, params); 2475 if (params->num_bssid_deny_list) 2476 op_bitmap |= 2477 ROAM_FILTER_OP_BITMAP_BLACK_LIST; 2478 2479 params->lca_disallow_config_present = true; 2480 /* 2481 * If rssi disallow bssid list have any member 2482 * fill it and send it to firmware so that 2483 * firmware does not try to roam to these BSS 2484 * until RSSI OR time condition are matched. 2485 */ 2486 params->num_rssi_rejection_ap = 2487 wlan_dlm_get_bssid_reject_list(pdev, 2488 params->rssi_rejection_ap, 2489 MAX_RSSI_AVOID_BSSID_LIST, 2490 DRIVER_RSSI_REJECT_TYPE); 2491 } else { 2492 mlme_debug("Roam Filter need not be sent, no need to fill parameters"); 2493 goto end; 2494 } 2495 break; 2496 default: 2497 if (command == ROAM_SCAN_OFFLOAD_START) { 2498 num_ssid_allow_list = 2499 rso_usr_config->num_ssid_allowed_list; 2500 if (num_ssid_allow_list) 2501 op_bitmap |= 2502 ROAM_FILTER_OP_BITMAP_WHITE_LIST; 2503 cm_add_denylist_ap_list(pdev, params); 2504 if (params->num_bssid_deny_list) 2505 op_bitmap |= 2506 ROAM_FILTER_OP_BITMAP_BLACK_LIST; 2507 } 2508 if (!op_bitmap) { 2509 mlme_debug("Roam Filter need not be sent, no need to fill parameters"); 2510 goto end; 2511 } 2512 break; 2513 } 2514 } else { 2515 /* In case of STOP command, reset all the variables 2516 * except for denylist BSSID which should be retained 2517 * across connections. 2518 */ 2519 op_bitmap = ROAM_FILTER_OP_BITMAP_WHITE_LIST | 2520 ROAM_FILTER_OP_BITMAP_PREFER_BSSID; 2521 if (reason == REASON_ROAM_SET_SSID_ALLOWED) 2522 num_ssid_allow_list = 2523 rso_usr_config->num_ssid_allowed_list; 2524 num_bssid_preferred_list = rso_usr_cfg->num_bssid_favored; 2525 } 2526 2527 /* fill in fixed values */ 2528 params->vdev_id = vdev_id; 2529 params->op_bitmap = op_bitmap; 2530 params->num_ssid_allow_list = num_ssid_allow_list; 2531 params->num_bssid_preferred_list = num_bssid_preferred_list; 2532 params->delta_rssi = 2533 wlan_dlm_get_rssi_denylist_threshold(pdev); 2534 2535 for (i = 0; i < num_ssid_allow_list; i++) { 2536 qdf_mem_copy(params->ssid_allowed_list[i].ssid, 2537 rso_usr_config->ssid_allowed_list[i].ssid, 2538 rso_usr_config->ssid_allowed_list[i].length); 2539 params->ssid_allowed_list[i].length = 2540 rso_usr_config->ssid_allowed_list[i].length; 2541 mlme_debug("SSID %d: " QDF_SSID_FMT, i, 2542 QDF_SSID_REF(params->ssid_allowed_list[i].length, 2543 params->ssid_allowed_list[i].ssid)); 2544 } 2545 2546 if (params->num_bssid_preferred_list) { 2547 qdf_mem_copy(params->bssid_favored, rso_usr_cfg->bssid_favored, 2548 MAX_BSSID_FAVORED * sizeof(struct qdf_mac_addr)); 2549 qdf_mem_copy(params->bssid_favored_factor, 2550 rso_usr_cfg->bssid_favored_factor, 2551 MAX_BSSID_FAVORED); 2552 } 2553 for (i = 0; i < params->num_rssi_rejection_ap; i++) 2554 mlme_debug("RSSI reject BSSID "QDF_MAC_ADDR_FMT" expected rssi %d remaining duration %d", 2555 QDF_MAC_ADDR_REF(params->rssi_rejection_ap[i].bssid.bytes), 2556 params->rssi_rejection_ap[i].expected_rssi, 2557 params->rssi_rejection_ap[i].reject_duration); 2558 2559 for (i = 0; i < params->num_bssid_preferred_list; i++) 2560 mlme_debug("Preferred Bssid[%d]:"QDF_MAC_ADDR_FMT" score: %d", i, 2561 QDF_MAC_ADDR_REF(params->bssid_favored[i].bytes), 2562 params->bssid_favored_factor[i]); 2563 2564 if (params->lca_disallow_config_present) { 2565 params->disallow_duration 2566 = mlme_obj->cfg.lfr.lfr3_disallow_duration; 2567 params->rssi_channel_penalization 2568 = mlme_obj->cfg.lfr.lfr3_rssi_channel_penalization; 2569 params->num_disallowed_aps 2570 = mlme_obj->cfg.lfr.lfr3_num_disallowed_aps; 2571 mlme_debug("disallow_dur %d rssi_chan_pen %d num_disallowed_aps %d", 2572 params->disallow_duration, 2573 params->rssi_channel_penalization, 2574 params->num_disallowed_aps); 2575 } 2576 2577 end: 2578 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 2579 return; 2580 } 2581 2582 #ifdef CONFIG_BAND_6GHZ 2583 static void 2584 cm_fill_6ghz_dwell_times(struct wlan_objmgr_psoc *psoc, 2585 struct wlan_roam_scan_params *scan_params) 2586 { 2587 wlan_scan_cfg_get_active_6g_dwelltime( 2588 psoc, 2589 &scan_params->dwell_time_active_6ghz); 2590 2591 wlan_scan_cfg_get_passive_6g_dwelltime( 2592 psoc, 2593 &scan_params->dwell_time_passive_6ghz); 2594 } 2595 #else 2596 static inline void 2597 cm_fill_6ghz_dwell_times(struct wlan_objmgr_psoc *psoc, 2598 struct wlan_roam_scan_params *scan_params) 2599 {} 2600 #endif 2601 2602 static void 2603 cm_roam_scan_offload_fill_scan_params(struct wlan_objmgr_psoc *psoc, 2604 struct rso_config *rso_cfg, 2605 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2606 struct wlan_roam_scan_offload_params *rso_mode_cfg, 2607 struct wlan_roam_scan_channel_list *rso_chan_info, 2608 uint8_t command) 2609 { 2610 struct wlan_roam_scan_params *scan_params = 2611 &rso_mode_cfg->rso_scan_params; 2612 uint8_t channels_per_burst = 0; 2613 uint16_t roam_scan_home_away_time; 2614 enum roaming_dfs_channel_type allow_dfs_ch_roam; 2615 struct rso_cfg_params *cfg_params; 2616 2617 qdf_mem_zero(scan_params, sizeof(*scan_params)); 2618 if (command == ROAM_SCAN_OFFLOAD_STOP) 2619 return; 2620 2621 cfg_params = &rso_cfg->cfg_param; 2622 2623 /* Parameters updated after association is complete */ 2624 scan_params->dwell_time_passive = cfg_params->passive_max_chan_time; 2625 2626 wlan_scan_cfg_get_min_dwelltime_6g(psoc, 2627 &scan_params->min_dwell_time_6ghz); 2628 /* 2629 * Here is the formula, 2630 * T(HomeAway) = N * T(dwell) + (N+1) * T(cs) 2631 * where N is number of channels scanned in single burst 2632 */ 2633 scan_params->dwell_time_active = cfg_params->max_chan_scan_time; 2634 2635 roam_scan_home_away_time = cfg_params->roam_scan_home_away_time; 2636 2637 if (roam_scan_home_away_time < 2638 (scan_params->dwell_time_active + 2639 (2 * ROAM_SCAN_CHANNEL_SWITCH_TIME))) { 2640 mlme_debug("Disable Home away time(%d) as it is less than (2*RF switching time + channel max time)(%d)", 2641 roam_scan_home_away_time, 2642 (scan_params->dwell_time_active + 2643 (2 * ROAM_SCAN_CHANNEL_SWITCH_TIME))); 2644 roam_scan_home_away_time = 0; 2645 } 2646 2647 if (roam_scan_home_away_time < (2 * ROAM_SCAN_CHANNEL_SWITCH_TIME)) { 2648 /* clearly we can't follow home away time. 2649 * Make it a split scan. 2650 */ 2651 scan_params->burst_duration = 0; 2652 } else { 2653 channels_per_burst = 2654 (roam_scan_home_away_time - ROAM_SCAN_CHANNEL_SWITCH_TIME) / 2655 (scan_params->dwell_time_active + ROAM_SCAN_CHANNEL_SWITCH_TIME); 2656 2657 if (channels_per_burst < 1) { 2658 /* dwell time and home away time conflicts */ 2659 /* we will override dwell time */ 2660 scan_params->dwell_time_active = 2661 roam_scan_home_away_time - 2662 (2 * ROAM_SCAN_CHANNEL_SWITCH_TIME); 2663 scan_params->burst_duration = 2664 scan_params->dwell_time_active; 2665 } else { 2666 scan_params->burst_duration = 2667 channels_per_burst * 2668 scan_params->dwell_time_active; 2669 } 2670 } 2671 2672 allow_dfs_ch_roam = mlme_obj->cfg.lfr.roaming_dfs_channel; 2673 /* Roaming on DFS channels is supported and it is not 2674 * app channel list. It is ok to override homeAwayTime 2675 * to accommodate DFS dwell time in burst 2676 * duration. 2677 */ 2678 if (allow_dfs_ch_roam == ROAMING_DFS_CHANNEL_ENABLED_NORMAL && 2679 roam_scan_home_away_time > 0 && 2680 rso_chan_info->chan_cache_type != CHANNEL_LIST_STATIC) 2681 scan_params->burst_duration = 2682 QDF_MAX(scan_params->burst_duration, 2683 scan_params->dwell_time_passive); 2684 2685 scan_params->min_rest_time = cfg_params->neighbor_scan_min_period; 2686 scan_params->max_rest_time = cfg_params->neighbor_scan_period; 2687 scan_params->repeat_probe_time = 2688 (cfg_params->roam_scan_n_probes > 0) ? 2689 QDF_MAX(scan_params->dwell_time_active / 2690 cfg_params->roam_scan_n_probes, 1) : 0; 2691 scan_params->probe_spacing_time = 0; 2692 scan_params->probe_delay = 0; 2693 /* 30 seconds for full scan cycle */ 2694 scan_params->max_scan_time = ROAM_SCAN_HW_DEF_SCAN_MAX_DURATION; 2695 scan_params->idle_time = scan_params->min_rest_time; 2696 scan_params->n_probes = cfg_params->roam_scan_n_probes; 2697 2698 if (allow_dfs_ch_roam == ROAMING_DFS_CHANNEL_DISABLED) { 2699 scan_params->scan_ctrl_flags |= WMI_SCAN_BYPASS_DFS_CHN; 2700 } else { 2701 /* Roaming scan on DFS channel is allowed. 2702 * No need to change any flags for default 2703 * allowDFSChannelRoam = 1. 2704 * Special case where static channel list is given by\ 2705 * application that contains DFS channels. 2706 * Assume that the application has knowledge of matching 2707 * APs being active and that probe request transmission 2708 * is permitted on those channel. 2709 * Force active scans on those channels. 2710 */ 2711 2712 if (allow_dfs_ch_roam == 2713 ROAMING_DFS_CHANNEL_ENABLED_ACTIVE && 2714 rso_chan_info->chan_cache_type == CHANNEL_LIST_STATIC && 2715 rso_chan_info->chan_count) 2716 scan_params->scan_ctrl_flags |= 2717 WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2718 } 2719 2720 scan_params->rso_adaptive_dwell_mode = 2721 mlme_obj->cfg.lfr.adaptive_roamscan_dwell_mode; 2722 2723 cm_fill_6ghz_dwell_times(psoc, scan_params); 2724 2725 mlme_debug("dwell time passive:%d, active:%d, home_away_time:%d, burst_duration:%d, max_rest_time:%d", 2726 scan_params->dwell_time_passive, 2727 scan_params->dwell_time_active, roam_scan_home_away_time, 2728 scan_params->burst_duration, scan_params->max_rest_time); 2729 } 2730 2731 void wlan_cm_append_assoc_ies(struct wlan_roam_scan_offload_params *rso_mode_cfg, 2732 uint8_t ie_id, uint8_t ie_len, 2733 const uint8_t *ie_data) 2734 { 2735 uint32_t curr_length = rso_mode_cfg->assoc_ie_length; 2736 2737 if ((MAC_MAX_ADD_IE_LENGTH - curr_length) < ie_len) { 2738 mlme_err("Appending IE id: %d failed", ie_id); 2739 return; 2740 } 2741 2742 rso_mode_cfg->assoc_ie[curr_length] = ie_id; 2743 rso_mode_cfg->assoc_ie[curr_length + 1] = ie_len; 2744 qdf_mem_copy(&rso_mode_cfg->assoc_ie[curr_length + 2], ie_data, ie_len); 2745 rso_mode_cfg->assoc_ie_length += (ie_len + 2); 2746 } 2747 2748 void wlan_add_supported_5Ghz_channels(struct wlan_objmgr_psoc *psoc, 2749 struct wlan_objmgr_pdev *pdev, 2750 uint8_t *chan_list, 2751 uint8_t *num_chnl, 2752 bool supp_chan_ie) 2753 { 2754 uint16_t i, j = 0; 2755 uint32_t size = 0; 2756 uint32_t *freq_list; 2757 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2758 2759 mlme_obj = mlme_get_psoc_ext_obj(psoc); 2760 if (!mlme_obj) 2761 return; 2762 2763 if (!chan_list) { 2764 mlme_err("chan_list buffer NULL"); 2765 *num_chnl = 0; 2766 return; 2767 } 2768 size = mlme_obj->cfg.reg.valid_channel_list_num; 2769 freq_list = mlme_obj->cfg.reg.valid_channel_freq_list; 2770 for (i = 0, j = 0; i < size; i++) { 2771 if (wlan_reg_is_dsrc_freq(freq_list[i])) 2772 continue; 2773 /* Only add 5ghz channels.*/ 2774 if (WLAN_REG_IS_5GHZ_CH_FREQ(freq_list[i])) { 2775 chan_list[j] = 2776 wlan_reg_freq_to_chan(pdev, 2777 freq_list[i]); 2778 j++; 2779 2780 if (supp_chan_ie) { 2781 chan_list[j] = 1; 2782 j++; 2783 } 2784 } 2785 } 2786 *num_chnl = (uint8_t)j; 2787 } 2788 2789 static void cm_update_driver_assoc_ies(struct wlan_objmgr_psoc *psoc, 2790 struct wlan_objmgr_vdev *vdev, 2791 struct rso_config *rso_cfg, 2792 struct wlan_mlme_psoc_ext_obj *mlme_obj, 2793 struct wlan_roam_scan_offload_params *rso_mode_cfg) 2794 { 2795 bool power_caps_populated = false; 2796 uint8_t *rrm_cap_ie_data; 2797 uint8_t vdev_id = wlan_vdev_get_id(vdev); 2798 uint8_t power_cap_ie_data[DOT11F_IE_POWERCAPS_MAX_LEN] = { 2799 MIN_TX_PWR_CAP, MAX_TX_PWR_CAP}; 2800 uint8_t max_tx_pwr_cap = 0; 2801 struct wlan_objmgr_pdev *pdev; 2802 uint8_t supp_chan_ie[DOT11F_IE_SUPPCHANNELS_MAX_LEN], supp_chan_ie_len; 2803 static const uint8_t qcn_ie[] = {0x8C, 0xFD, 0xF0, 0x1, 2804 QCN_IE_VERSION_SUBATTR_ID, 2805 QCN_IE_VERSION_SUBATTR_DATA_LEN, 2806 QCN_IE_VERSION_SUPPORTED, 2807 QCN_IE_SUBVERSION_SUPPORTED}; 2808 2809 pdev = wlan_vdev_get_pdev(vdev); 2810 if (!pdev) 2811 return; 2812 2813 rrm_cap_ie_data = wlan_cm_get_rrm_cap_ie_data(); 2814 /* Re-Assoc IE TLV parameters */ 2815 rso_mode_cfg->assoc_ie_length = rso_cfg->assoc_ie.len; 2816 qdf_mem_copy(rso_mode_cfg->assoc_ie, rso_cfg->assoc_ie.ptr, 2817 rso_mode_cfg->assoc_ie_length); 2818 2819 max_tx_pwr_cap = wlan_get_cfg_max_tx_power(psoc, pdev, 2820 wlan_get_operation_chan_freq(vdev)); 2821 2822 if (max_tx_pwr_cap && max_tx_pwr_cap < MAX_TX_PWR_CAP) 2823 power_cap_ie_data[1] = max_tx_pwr_cap; 2824 else 2825 power_cap_ie_data[1] = MAX_TX_PWR_CAP; 2826 2827 if (mlme_obj->cfg.gen.enabled_11h) { 2828 /* Append power cap IE */ 2829 wlan_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_PWRCAP, 2830 DOT11F_IE_POWERCAPS_MAX_LEN, 2831 power_cap_ie_data); 2832 power_caps_populated = true; 2833 2834 /* Append Supported channels IE */ 2835 wlan_add_supported_5Ghz_channels(psoc, pdev, supp_chan_ie, 2836 &supp_chan_ie_len, true); 2837 2838 wlan_cm_append_assoc_ies(rso_mode_cfg, 2839 WLAN_ELEMID_SUPPCHAN, 2840 supp_chan_ie_len, supp_chan_ie); 2841 } 2842 2843 cm_esr_populate_version_ie(mlme_obj, rso_mode_cfg); 2844 2845 if (mlme_obj->cfg.rrm_config.rrm_enabled) { 2846 /* Append RRM IE */ 2847 if (rrm_cap_ie_data) 2848 wlan_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_RRM, 2849 DOT11F_IE_RRMENABLEDCAP_MAX_LEN, 2850 rrm_cap_ie_data); 2851 2852 /* Append Power cap IE if not appended already */ 2853 if (!power_caps_populated) 2854 wlan_cm_append_assoc_ies(rso_mode_cfg, 2855 WLAN_ELEMID_PWRCAP, 2856 DOT11F_IE_POWERCAPS_MAX_LEN, 2857 power_cap_ie_data); 2858 } 2859 2860 wlan_cm_ese_populate_additional_ies(pdev, mlme_obj, vdev_id, 2861 rso_mode_cfg); 2862 2863 /* Append QCN IE if g_support_qcn_ie INI is enabled */ 2864 if (mlme_obj->cfg.sta.qcn_ie_support) 2865 wlan_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_VENDOR, 2866 sizeof(qcn_ie), qcn_ie); 2867 } 2868 2869 static void 2870 cm_roam_scan_offload_fill_rso_configs(struct wlan_objmgr_psoc *psoc, 2871 struct wlan_objmgr_vdev *vdev, 2872 struct rso_config *rso_cfg, 2873 struct wlan_roam_scan_offload_params *rso_mode_cfg, 2874 struct wlan_roam_scan_channel_list *rso_chan_info, 2875 uint8_t command, uint16_t reason) 2876 { 2877 uint32_t mode = 0; 2878 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2879 uint8_t vdev_id = wlan_vdev_get_id(vdev); 2880 2881 mlme_obj = mlme_get_psoc_ext_obj(psoc); 2882 if (!mlme_obj) 2883 return; 2884 2885 qdf_mem_zero(rso_mode_cfg, sizeof(*rso_mode_cfg)); 2886 rso_mode_cfg->vdev_id = vdev_id; 2887 rso_mode_cfg->is_rso_stop = (command == ROAM_SCAN_OFFLOAD_STOP); 2888 rso_mode_cfg->roaming_scan_policy = 2889 mlme_obj->cfg.lfr.roaming_scan_policy; 2890 2891 /* Fill ROAM SCAN mode TLV parameters */ 2892 if (rso_cfg->cfg_param.empty_scan_refresh_period) 2893 mode |= WMI_ROAM_SCAN_MODE_PERIODIC; 2894 2895 rso_mode_cfg->rso_mode_info.min_delay_btw_scans = 2896 mlme_obj->cfg.lfr.min_delay_btw_roam_scans; 2897 rso_mode_cfg->rso_mode_info.min_delay_roam_trigger_bitmask = 2898 mlme_obj->cfg.lfr.roam_trigger_reason_bitmask; 2899 2900 if (command == ROAM_SCAN_OFFLOAD_STOP) { 2901 if (reason == REASON_ROAM_STOP_ALL || 2902 reason == REASON_DISCONNECTED || 2903 reason == REASON_ROAM_SYNCH_FAILED || 2904 reason == REASON_ROAM_SET_PRIMARY) { 2905 mode = WMI_ROAM_SCAN_MODE_NONE; 2906 } else { 2907 if (wlan_is_roam_offload_enabled(mlme_obj->cfg.lfr)) 2908 mode = WMI_ROAM_SCAN_MODE_NONE | 2909 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 2910 else 2911 mode = WMI_ROAM_SCAN_MODE_NONE; 2912 } 2913 } 2914 2915 rso_mode_cfg->rso_mode_info.roam_scan_mode = mode; 2916 if (command == ROAM_SCAN_OFFLOAD_STOP) 2917 return; 2918 2919 cm_roam_scan_offload_fill_lfr3_config(vdev, rso_cfg, rso_mode_cfg, 2920 mlme_obj, command, &mode); 2921 rso_mode_cfg->rso_mode_info.roam_scan_mode = mode; 2922 cm_roam_scan_offload_fill_scan_params(psoc, rso_cfg, mlme_obj, 2923 rso_mode_cfg, rso_chan_info, 2924 command); 2925 cm_update_driver_assoc_ies(psoc, vdev, rso_cfg, mlme_obj, rso_mode_cfg); 2926 cm_roam_scan_offload_add_fils_params(psoc, rso_mode_cfg, vdev_id); 2927 } 2928 2929 /** 2930 * cm_update_btm_offload_config() - Update btm config param to fw 2931 * @psoc: psoc 2932 * @vdev: vdev 2933 * @command: Roam offload command 2934 * @btm_offload_config: btm offload config 2935 * 2936 * Return: None 2937 */ 2938 static void 2939 cm_update_btm_offload_config(struct wlan_objmgr_psoc *psoc, 2940 struct wlan_objmgr_vdev *vdev, 2941 uint8_t command, uint32_t *btm_offload_config) 2942 2943 { 2944 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2945 struct wlan_mlme_btm *btm_cfg; 2946 struct wlan_objmgr_peer *peer; 2947 uint8_t bssid[QDF_MAC_ADDR_SIZE]; 2948 struct cm_roam_values_copy temp; 2949 bool is_hs_20_ap, is_pmf_enabled, is_open_connection = false; 2950 uint8_t vdev_id; 2951 uint32_t mbo_oce_enabled_ap; 2952 bool abridge_flag; 2953 2954 mlme_obj = mlme_get_psoc_ext_obj(psoc); 2955 if (!mlme_obj) 2956 return; 2957 2958 btm_cfg = &mlme_obj->cfg.btm; 2959 *btm_offload_config = btm_cfg->btm_offload_config; 2960 2961 /* Return if INI is disabled */ 2962 if (!(*btm_offload_config)) 2963 return; 2964 2965 if (!wlan_cm_get_assoc_btm_cap(vdev)) { 2966 mlme_debug("BTM not supported, disable BTM offload"); 2967 *btm_offload_config = 0; 2968 return; 2969 } 2970 2971 vdev_id = wlan_vdev_get_id(vdev); 2972 wlan_cm_roam_cfg_get_value(psoc, vdev_id, HS_20_AP, &temp); 2973 is_hs_20_ap = temp.bool_value; 2974 2975 /* 2976 * For RSO Stop/Passpoint R2 cert test case 5.11(when STA is connected 2977 * to Hotspot-2.0 AP), disable BTM offload to firmware 2978 */ 2979 if (command == ROAM_SCAN_OFFLOAD_STOP || is_hs_20_ap) { 2980 mlme_debug("RSO cmd: %d is_hs_20_ap:%d", command, 2981 is_hs_20_ap); 2982 *btm_offload_config = 0; 2983 return; 2984 } 2985 2986 ucfg_wlan_vdev_mgr_get_param_bssid(vdev, bssid); 2987 peer = wlan_objmgr_get_peer(psoc, 2988 wlan_objmgr_pdev_get_pdev_id( 2989 wlan_vdev_get_pdev(vdev)), 2990 bssid, 2991 WLAN_MLME_CM_ID); 2992 if (!peer) { 2993 mlme_debug("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", 2994 QDF_MAC_ADDR_REF(bssid)); 2995 return; 2996 } 2997 2998 is_pmf_enabled = mlme_get_peer_pmf_status(peer); 2999 3000 wlan_objmgr_peer_release_ref(peer, WLAN_MLME_CM_ID); 3001 3002 if (cm_is_open_mode(vdev)) 3003 is_open_connection = true; 3004 3005 wlan_cm_roam_cfg_get_value(psoc, vdev_id, MBO_OCE_ENABLED_AP, &temp); 3006 mbo_oce_enabled_ap = temp.uint_value; 3007 3008 abridge_flag = wlan_mlme_get_btm_abridge_flag(psoc); 3009 if (!abridge_flag) 3010 MLME_CLEAR_BIT(*btm_offload_config, 3011 BTM_OFFLOAD_CONFIG_BIT_7); 3012 mlme_debug("Abridge flag: %d, btm offload: %u", abridge_flag, 3013 *btm_offload_config); 3014 3015 /* 3016 * If peer does not support PMF in case of OCE/MBO 3017 * Connection, Disable BTM offload to firmware. 3018 */ 3019 if (mbo_oce_enabled_ap && (!is_pmf_enabled && !is_open_connection)) 3020 *btm_offload_config = 0; 3021 3022 mlme_debug("is_open:%d is_pmf_enabled %d btm_offload_cfg:%d for "QDF_MAC_ADDR_FMT, 3023 is_open_connection, is_pmf_enabled, *btm_offload_config, 3024 QDF_MAC_ADDR_REF(bssid)); 3025 } 3026 3027 /** 3028 * cm_roam_scan_btm_offload() - set roam scan btm offload parameters 3029 * @psoc: psoc ctx 3030 * @vdev: vdev 3031 * @params: roam scan btm offload parameters 3032 * @rso_cfg: rso config 3033 * 3034 * This function is used to set roam scan btm offload related parameters 3035 * 3036 * Return: None 3037 */ 3038 static void 3039 cm_roam_scan_btm_offload(struct wlan_objmgr_psoc *psoc, 3040 struct wlan_objmgr_vdev *vdev, 3041 struct wlan_roam_btm_config *params, 3042 struct rso_config *rso_cfg) 3043 { 3044 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3045 struct wlan_mlme_btm *btm_cfg; 3046 3047 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3048 if (!mlme_obj) 3049 return; 3050 3051 btm_cfg = &mlme_obj->cfg.btm; 3052 params->vdev_id = wlan_vdev_get_id(vdev); 3053 cm_update_btm_offload_config(psoc, vdev, ROAM_SCAN_OFFLOAD_START, 3054 ¶ms->btm_offload_config); 3055 params->btm_solicited_timeout = btm_cfg->btm_solicited_timeout; 3056 params->btm_max_attempt_cnt = btm_cfg->btm_max_attempt_cnt; 3057 params->btm_sticky_time = btm_cfg->btm_sticky_time; 3058 params->disassoc_timer_threshold = btm_cfg->disassoc_timer_threshold; 3059 params->btm_query_bitmask = btm_cfg->btm_query_bitmask; 3060 params->btm_candidate_min_score = btm_cfg->btm_trig_min_candidate_score; 3061 } 3062 3063 #ifdef WLAN_FEATURE_11BE_MLO 3064 /** 3065 * cm_roam_mlo_config() - set roam mlo offload parameters 3066 * @psoc: psoc ctx 3067 * @vdev: vdev 3068 * @start_req: request to fill 3069 * 3070 * This function is used to set roam mlo offload related parameters 3071 * 3072 * Return: None 3073 */ 3074 static void 3075 cm_roam_mlo_config(struct wlan_objmgr_psoc *psoc, 3076 struct wlan_objmgr_vdev *vdev, 3077 struct wlan_roam_start_config *start_req) 3078 { 3079 struct wlan_roam_mlo_config *roam_mlo_params; 3080 struct rso_config *rso_cfg; 3081 3082 roam_mlo_params = &start_req->roam_mlo_params; 3083 roam_mlo_params->vdev_id = wlan_vdev_get_id(vdev); 3084 roam_mlo_params->support_link_num = 3085 wlan_mlme_get_sta_mlo_conn_max_num(psoc); 3086 roam_mlo_params->support_link_band = 3087 wlan_mlme_get_sta_mlo_conn_band_bmp(psoc); 3088 3089 /* 3090 * Update the supported link band based on roam_band_bitmap 3091 * Roam band bitmap is modified during NCHO mode enable, disable and 3092 * regulatory supported band changes. 3093 */ 3094 rso_cfg = wlan_cm_get_rso_config(vdev); 3095 if (!rso_cfg) 3096 return; 3097 3098 roam_mlo_params->support_link_band &= 3099 rso_cfg->roam_band_bitmask; 3100 } 3101 #else 3102 static void 3103 cm_roam_mlo_config(struct wlan_objmgr_psoc *psoc, 3104 struct wlan_objmgr_vdev *vdev, 3105 struct wlan_roam_start_config *start_req) 3106 { 3107 } 3108 #endif 3109 3110 /** 3111 * cm_roam_offload_11k_params() - set roam 11k offload parameters 3112 * @psoc: psoc ctx 3113 * @vdev: vdev 3114 * @params: roam 11k offload parameters 3115 * @enabled: 11k offload enabled/disabled 3116 * 3117 * This function is used to set roam 11k offload related parameters 3118 * 3119 * Return: None 3120 */ 3121 static void 3122 cm_roam_offload_11k_params(struct wlan_objmgr_psoc *psoc, 3123 struct wlan_objmgr_vdev *vdev, 3124 struct wlan_roam_11k_offload_params *params, 3125 bool enabled) 3126 { 3127 struct cm_roam_neighbor_report_offload_params *neighbor_report_offload; 3128 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3129 3130 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3131 if (!mlme_obj) 3132 return; 3133 3134 neighbor_report_offload = 3135 &mlme_obj->cfg.lfr.rso_user_config.neighbor_report_offload; 3136 3137 params->vdev_id = wlan_vdev_get_id(vdev); 3138 3139 if (enabled) { 3140 params->offload_11k_bitmask = 3141 neighbor_report_offload->offload_11k_enable_bitmask; 3142 } else { 3143 params->offload_11k_bitmask = 0; 3144 return; 3145 } 3146 3147 /* 3148 * If none of the parameters are enabled, then set the 3149 * offload_11k_bitmask to 0, so that we don't send the command 3150 * to the FW and drop it in WMA 3151 */ 3152 if ((neighbor_report_offload->params_bitmask & 3153 NEIGHBOR_REPORT_PARAMS_ALL) == 0) { 3154 mlme_err("No valid neighbor report offload params %x", 3155 neighbor_report_offload->params_bitmask); 3156 params->offload_11k_bitmask = 0; 3157 return; 3158 } 3159 3160 /* 3161 * First initialize all params to NEIGHBOR_REPORT_PARAM_INVALID 3162 * Then set the values that are enabled 3163 */ 3164 params->neighbor_report_params.time_offset = 3165 NEIGHBOR_REPORT_PARAM_INVALID; 3166 params->neighbor_report_params.low_rssi_offset = 3167 NEIGHBOR_REPORT_PARAM_INVALID; 3168 params->neighbor_report_params.bmiss_count_trigger = 3169 NEIGHBOR_REPORT_PARAM_INVALID; 3170 params->neighbor_report_params.per_threshold_offset = 3171 NEIGHBOR_REPORT_PARAM_INVALID; 3172 params->neighbor_report_params.neighbor_report_cache_timeout = 3173 NEIGHBOR_REPORT_PARAM_INVALID; 3174 params->neighbor_report_params.max_neighbor_report_req_cap = 3175 NEIGHBOR_REPORT_PARAM_INVALID; 3176 3177 if (neighbor_report_offload->params_bitmask & 3178 NEIGHBOR_REPORT_PARAMS_TIME_OFFSET) 3179 params->neighbor_report_params.time_offset = 3180 neighbor_report_offload->time_offset; 3181 3182 if (neighbor_report_offload->params_bitmask & 3183 NEIGHBOR_REPORT_PARAMS_LOW_RSSI_OFFSET) 3184 params->neighbor_report_params.low_rssi_offset = 3185 neighbor_report_offload->low_rssi_offset; 3186 3187 if (neighbor_report_offload->params_bitmask & 3188 NEIGHBOR_REPORT_PARAMS_BMISS_COUNT_TRIGGER) 3189 params->neighbor_report_params.bmiss_count_trigger = 3190 neighbor_report_offload->bmiss_count_trigger; 3191 3192 if (neighbor_report_offload->params_bitmask & 3193 NEIGHBOR_REPORT_PARAMS_PER_THRESHOLD_OFFSET) 3194 params->neighbor_report_params.per_threshold_offset = 3195 neighbor_report_offload->per_threshold_offset; 3196 3197 if (neighbor_report_offload->params_bitmask & 3198 NEIGHBOR_REPORT_PARAMS_CACHE_TIMEOUT) 3199 params->neighbor_report_params.neighbor_report_cache_timeout = 3200 neighbor_report_offload->neighbor_report_cache_timeout; 3201 3202 if (neighbor_report_offload->params_bitmask & 3203 NEIGHBOR_REPORT_PARAMS_MAX_REQ_CAP) 3204 params->neighbor_report_params.max_neighbor_report_req_cap = 3205 neighbor_report_offload->max_neighbor_report_req_cap; 3206 3207 wlan_vdev_mlme_get_ssid(vdev, params->neighbor_report_params.ssid.ssid, 3208 ¶ms->neighbor_report_params.ssid.length); 3209 } 3210 3211 /** 3212 * cm_roam_start_req() - roam start request handling 3213 * @psoc: psoc pointer 3214 * @vdev_id: vdev id 3215 * @reason: reason for changing roam state for the requested vdev id 3216 * 3217 * Return: QDF_STATUS 3218 */ 3219 static QDF_STATUS 3220 cm_roam_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3221 uint8_t reason) 3222 { 3223 struct wlan_roam_start_config *start_req; 3224 QDF_STATUS status = QDF_STATUS_E_INVAL; 3225 struct rso_config *rso_cfg; 3226 struct wlan_objmgr_vdev *vdev; 3227 struct wlan_objmgr_pdev *pdev; 3228 struct cm_roam_values_copy temp; 3229 3230 start_req = qdf_mem_malloc(sizeof(*start_req)); 3231 if (!start_req) 3232 return QDF_STATUS_E_NOMEM; 3233 3234 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3235 WLAN_MLME_CM_ID); 3236 if (!vdev) { 3237 mlme_err("vdev object is NULL for vdev %d", vdev_id); 3238 goto free_mem; 3239 } 3240 rso_cfg = wlan_cm_get_rso_config(vdev); 3241 if (!rso_cfg) 3242 goto rel_vdev_ref; 3243 3244 pdev = wlan_vdev_get_pdev(vdev); 3245 if (!pdev) 3246 goto rel_vdev_ref; 3247 3248 cm_roam_set_roam_reason_better_ap(psoc, vdev_id, false); 3249 /* fill from mlme directly */ 3250 cm_roam_scan_bmiss_cnt(psoc, vdev_id, &start_req->beacon_miss_cnt); 3251 cm_roam_scan_bmiss_timeout(psoc, vdev_id, &start_req->bmiss_timeout); 3252 cm_roam_reason_vsie(psoc, vdev_id, &start_req->reason_vsie_enable); 3253 cm_roam_triggers(psoc, vdev_id, &start_req->roam_triggers); 3254 cm_roam_fill_rssi_change_params(psoc, vdev_id, 3255 &start_req->rssi_change_params); 3256 cm_roam_mawc_params(psoc, vdev_id, &start_req->mawc_params); 3257 cm_roam_bss_load_config(psoc, vdev_id, &start_req->bss_load_config); 3258 cm_roam_disconnect_params(psoc, vdev_id, &start_req->disconnect_params); 3259 cm_roam_idle_params(psoc, vdev_id, &start_req->idle_params); 3260 if (!(BIT(ROAM_TRIGGER_REASON_IDLE) & 3261 start_req->roam_triggers.trigger_bitmap)) 3262 start_req->idle_params.enable = false; 3263 3264 cm_roam_scan_offload_rssi_thresh(psoc, vdev_id, 3265 &start_req->rssi_params, rso_cfg); 3266 cm_roam_scan_offload_scan_period(vdev_id, 3267 &start_req->scan_period_params, 3268 rso_cfg); 3269 cm_roam_scan_offload_ap_profile(psoc, vdev, rso_cfg, 3270 &start_req->profile_params); 3271 cm_fill_rso_channel_list(psoc, vdev, rso_cfg, &start_req->rso_chan_info, 3272 reason); 3273 cm_roam_scan_filter(psoc, pdev, vdev_id, ROAM_SCAN_OFFLOAD_START, 3274 reason, &start_req->scan_filter_params); 3275 cm_roam_scan_offload_fill_rso_configs(psoc, vdev, rso_cfg, 3276 &start_req->rso_config, 3277 &start_req->rso_chan_info, 3278 ROAM_SCAN_OFFLOAD_START, 3279 reason); 3280 cm_roam_scan_btm_offload(psoc, vdev, &start_req->btm_config, rso_cfg); 3281 cm_roam_offload_11k_params(psoc, vdev, &start_req->roam_11k_params, 3282 true); 3283 start_req->wlan_roam_rt_stats_config = 3284 wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); 3285 cm_roam_mlo_config(psoc, vdev, start_req); 3286 3287 start_req->wlan_roam_ho_delay_config = 3288 wlan_cm_roam_get_ho_delay_config(psoc); 3289 3290 start_req->wlan_exclude_rm_partial_scan_freq = 3291 wlan_cm_get_exclude_rm_partial_scan_freq(psoc); 3292 3293 start_req->wlan_roam_full_scan_6ghz_on_disc = 3294 wlan_cm_roam_get_full_scan_6ghz_on_disc(psoc); 3295 3296 wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_RSSI_DIFF_6GHZ, &temp); 3297 start_req->wlan_roam_rssi_diff_6ghz = temp.uint_value; 3298 3299 status = wlan_cm_tgt_send_roam_start_req(psoc, vdev_id, start_req); 3300 if (QDF_IS_STATUS_ERROR(status)) 3301 mlme_debug("fail to send roam start"); 3302 3303 rel_vdev_ref: 3304 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3305 free_mem: 3306 qdf_mem_free(start_req); 3307 3308 return status; 3309 } 3310 3311 /** 3312 * cm_roam_update_config_req() - roam update config request handling 3313 * @psoc: psoc pointer 3314 * @vdev_id: vdev id 3315 * @reason: reason for changing roam state for the requested vdev id 3316 * 3317 * Return: QDF_STATUS 3318 */ 3319 static QDF_STATUS 3320 cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3321 uint8_t reason) 3322 { 3323 struct wlan_roam_update_config *update_req; 3324 QDF_STATUS status = QDF_STATUS_E_INVAL; 3325 struct rso_config *rso_cfg; 3326 struct wlan_objmgr_vdev *vdev; 3327 struct wlan_objmgr_pdev *pdev; 3328 struct cm_roam_values_copy temp; 3329 3330 cm_roam_set_roam_reason_better_ap(psoc, vdev_id, false); 3331 3332 update_req = qdf_mem_malloc(sizeof(*update_req)); 3333 if (!update_req) 3334 return QDF_STATUS_E_NOMEM; 3335 3336 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3337 WLAN_MLME_CM_ID); 3338 if (!vdev) { 3339 mlme_err("vdev object is NULL for vdev %d", vdev_id); 3340 goto free_mem; 3341 } 3342 rso_cfg = wlan_cm_get_rso_config(vdev); 3343 if (!rso_cfg) 3344 goto rel_vdev_ref; 3345 3346 pdev = wlan_vdev_get_pdev(vdev); 3347 if (!pdev) 3348 goto rel_vdev_ref; 3349 3350 /* fill from mlme directly */ 3351 cm_roam_scan_bmiss_cnt(psoc, vdev_id, &update_req->beacon_miss_cnt); 3352 cm_roam_scan_bmiss_timeout(psoc, vdev_id, &update_req->bmiss_timeout); 3353 cm_roam_fill_rssi_change_params(psoc, vdev_id, 3354 &update_req->rssi_change_params); 3355 if (MLME_IS_ROAM_STATE_RSO_ENABLED(psoc, vdev_id)) { 3356 cm_roam_disconnect_params(psoc, vdev_id, 3357 &update_req->disconnect_params); 3358 cm_roam_triggers(psoc, vdev_id, 3359 &update_req->roam_triggers); 3360 cm_roam_idle_params(psoc, vdev_id, 3361 &update_req->idle_params); 3362 if (!(BIT(ROAM_TRIGGER_REASON_IDLE) & 3363 update_req->roam_triggers.trigger_bitmap)) 3364 update_req->idle_params.enable = false; 3365 } 3366 cm_roam_scan_offload_rssi_thresh(psoc, vdev_id, 3367 &update_req->rssi_params, rso_cfg); 3368 cm_roam_scan_offload_scan_period(vdev_id, 3369 &update_req->scan_period_params, 3370 rso_cfg); 3371 cm_roam_scan_offload_ap_profile(psoc, vdev, rso_cfg, 3372 &update_req->profile_params); 3373 cm_fill_rso_channel_list(psoc, vdev, rso_cfg, 3374 &update_req->rso_chan_info, reason); 3375 cm_roam_scan_filter(psoc, pdev, vdev_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG, 3376 reason, &update_req->scan_filter_params); 3377 cm_roam_scan_offload_fill_rso_configs(psoc, vdev, rso_cfg, 3378 &update_req->rso_config, 3379 &update_req->rso_chan_info, 3380 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 3381 reason); 3382 update_req->wlan_roam_rt_stats_config = 3383 wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); 3384 3385 update_req->wlan_roam_ho_delay_config = 3386 wlan_cm_roam_get_ho_delay_config(psoc); 3387 3388 update_req->wlan_exclude_rm_partial_scan_freq = 3389 wlan_cm_get_exclude_rm_partial_scan_freq(psoc); 3390 3391 update_req->wlan_roam_full_scan_6ghz_on_disc = 3392 wlan_cm_roam_get_full_scan_6ghz_on_disc(psoc); 3393 3394 wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_RSSI_DIFF_6GHZ, &temp); 3395 update_req->wlan_roam_rssi_diff_6ghz = temp.uint_value; 3396 3397 status = wlan_cm_tgt_send_roam_update_req(psoc, vdev_id, update_req); 3398 if (QDF_IS_STATUS_ERROR(status)) 3399 mlme_debug("fail to send update config"); 3400 3401 rel_vdev_ref: 3402 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3403 free_mem: 3404 qdf_mem_free(update_req); 3405 3406 return status; 3407 } 3408 3409 /** 3410 * cm_roam_restart_req() - roam restart req for LFR2 3411 * @psoc: psoc pointer 3412 * @vdev_id: vdev id 3413 * @reason: reason for changing roam state for the requested vdev id 3414 * 3415 * Return: QDF_STATUS 3416 */ 3417 static QDF_STATUS 3418 cm_roam_restart_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3419 uint8_t reason) 3420 { 3421 3422 struct wlan_objmgr_vdev *vdev; 3423 3424 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3425 WLAN_MLME_NB_ID); 3426 if (!vdev) 3427 return QDF_STATUS_E_INVAL; 3428 3429 /* Rome offload engine does not stop after any scan. 3430 * If this command is sent because all preauth attempts failed 3431 * and WMI_ROAM_REASON_SUITABLE_AP event was received earlier, 3432 * now it is time to call it heartbeat failure. 3433 */ 3434 if ((reason == REASON_PREAUTH_FAILED_FOR_ALL || 3435 reason == REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW) && 3436 mlme_get_roam_reason_better_ap(vdev)) { 3437 mlme_err("Sending heartbeat failure, reason %d", reason); 3438 wlan_cm_send_beacon_miss(vdev_id, mlme_get_hb_ap_rssi(vdev)); 3439 mlme_set_roam_reason_better_ap(vdev, false); 3440 } 3441 3442 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 3443 3444 return QDF_STATUS_SUCCESS; 3445 } 3446 3447 /** 3448 * cm_roam_abort_req() - roam scan abort req 3449 * @psoc: psoc pointer 3450 * @vdev_id: vdev id 3451 * @reason: reason for changing roam state for the requested vdev id 3452 * 3453 * Return: QDF_STATUS 3454 */ 3455 static QDF_STATUS 3456 cm_roam_abort_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3457 uint8_t reason) 3458 { 3459 QDF_STATUS status; 3460 3461 status = wlan_cm_tgt_send_roam_abort_req(psoc, vdev_id); 3462 if (QDF_IS_STATUS_ERROR(status)) 3463 mlme_debug("fail to send abort start"); 3464 3465 return status; 3466 } 3467 3468 static void cm_fill_stop_reason(struct wlan_roam_stop_config *stop_req, 3469 uint8_t reason) 3470 { 3471 if (reason == REASON_ROAM_SYNCH_FAILED) 3472 stop_req->reason = REASON_ROAM_SYNCH_FAILED; 3473 else if (reason == REASON_DRIVER_DISABLED) 3474 stop_req->reason = REASON_ROAM_STOP_ALL; 3475 else if (reason == REASON_SUPPLICANT_DISABLED_ROAMING) 3476 stop_req->reason = REASON_SUPPLICANT_DISABLED_ROAMING; 3477 else if (reason == REASON_DISCONNECTED) 3478 stop_req->reason = REASON_DISCONNECTED; 3479 else if (reason == REASON_OS_REQUESTED_ROAMING_NOW) 3480 stop_req->reason = REASON_OS_REQUESTED_ROAMING_NOW; 3481 else if (reason == REASON_ROAM_SET_PRIMARY) 3482 stop_req->reason = REASON_ROAM_SET_PRIMARY; 3483 else 3484 stop_req->reason = REASON_SME_ISSUED; 3485 } 3486 3487 QDF_STATUS 3488 cm_roam_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3489 uint8_t reason, bool *send_resp, bool start_timer) 3490 { 3491 struct wlan_roam_stop_config *stop_req; 3492 QDF_STATUS status; 3493 struct rso_config *rso_cfg; 3494 struct wlan_objmgr_vdev *vdev; 3495 struct wlan_objmgr_pdev *pdev; 3496 3497 cm_roam_set_roam_reason_better_ap(psoc, vdev_id, false); 3498 stop_req = qdf_mem_malloc(sizeof(*stop_req)); 3499 if (!stop_req) 3500 return QDF_STATUS_E_NOMEM; 3501 3502 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3503 WLAN_MLME_CM_ID); 3504 if (!vdev) { 3505 mlme_err("vdev object is NULL for vdev %d", vdev_id); 3506 goto free_mem; 3507 } 3508 3509 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 3510 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 3511 goto rel_vdev_ref; 3512 } 3513 3514 rso_cfg = wlan_cm_get_rso_config(vdev); 3515 if (!rso_cfg) 3516 goto rel_vdev_ref; 3517 3518 pdev = wlan_vdev_get_pdev(vdev); 3519 if (!pdev) 3520 goto rel_vdev_ref; 3521 3522 stop_req->btm_config.vdev_id = vdev_id; 3523 MLME_SET_BIT(stop_req->btm_config.btm_offload_config, 3524 BTM_OFFLOAD_CONFIG_BIT_0); 3525 stop_req->disconnect_params.vdev_id = vdev_id; 3526 stop_req->idle_params.vdev_id = vdev_id; 3527 stop_req->roam_triggers.vdev_id = vdev_id; 3528 stop_req->rssi_params.vdev_id = vdev_id; 3529 stop_req->roam_11k_params.vdev_id = vdev_id; 3530 cm_fill_stop_reason(stop_req, reason); 3531 if (wlan_cm_host_roam_in_progress(psoc, vdev_id)) 3532 stop_req->middle_of_roaming = 1; 3533 if (send_resp) 3534 stop_req->send_rso_stop_resp = *send_resp; 3535 stop_req->start_rso_stop_timer = start_timer; 3536 /* 3537 * If roam synch propagation is in progress and an user space 3538 * disconnect is requested, then there is no need to send the 3539 * RSO STOP to firmware, since the roaming is already complete. 3540 * If the RSO STOP is sent to firmware, then an HO_FAIL will be 3541 * generated and the expectation from firmware would be to 3542 * clean up the peer context on the host and not send down any 3543 * WMI PEER DELETE commands to firmware. But, if the user space 3544 * disconnect gets processed first, then there is a chance to 3545 * send down the PEER DELETE commands. Hence, if we do not 3546 * receive the HO_FAIL, and we complete the roam sync 3547 * propagation, then the host and firmware will be in sync with 3548 * respect to the peer and then the user space disconnect can 3549 * be handled gracefully in a normal way. 3550 * 3551 * Ensure to check the reason code since the RSO Stop might 3552 * come when roam sync failed as well and at that point it 3553 * should go through to the firmware and receive HO_FAIL 3554 * and clean up. 3555 */ 3556 if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id) && 3557 stop_req->reason == REASON_ROAM_STOP_ALL) { 3558 mlme_info("vdev_id:%d : Drop RSO stop during roam sync", 3559 vdev_id); 3560 goto rel_vdev_ref; 3561 } 3562 3563 wlan_mlme_defer_pmk_set_in_roaming(psoc, vdev_id, false); 3564 3565 cm_roam_scan_filter(psoc, pdev, vdev_id, ROAM_SCAN_OFFLOAD_STOP, 3566 reason, &stop_req->scan_filter_params); 3567 cm_roam_scan_offload_fill_rso_configs(psoc, vdev, rso_cfg, 3568 &stop_req->rso_config, 3569 NULL, ROAM_SCAN_OFFLOAD_STOP, 3570 stop_req->reason); 3571 3572 status = wlan_cm_tgt_send_roam_stop_req(psoc, vdev_id, stop_req); 3573 if (QDF_IS_STATUS_ERROR(status)) { 3574 mlme_debug("fail to send roam stop"); 3575 } 3576 if (send_resp) 3577 *send_resp = stop_req->send_rso_stop_resp; 3578 3579 rel_vdev_ref: 3580 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3581 free_mem: 3582 qdf_mem_free(stop_req); 3583 3584 return QDF_STATUS_SUCCESS; 3585 } 3586 3587 /** 3588 * cm_roam_fill_per_roam_request() - create PER roam offload config request 3589 * @psoc: psoc context 3590 * @req: request to fill 3591 * 3592 * Return: QDF_STATUS 3593 */ 3594 static QDF_STATUS 3595 cm_roam_fill_per_roam_request(struct wlan_objmgr_psoc *psoc, 3596 struct wlan_per_roam_config_req *req) 3597 { 3598 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3599 3600 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3601 if (!mlme_obj) 3602 return QDF_STATUS_E_FAILURE; 3603 3604 req->per_config.enable = mlme_obj->cfg.lfr.per_roam_enable; 3605 req->per_config.tx_high_rate_thresh = 3606 mlme_obj->cfg.lfr.per_roam_config_high_rate_th; 3607 req->per_config.rx_high_rate_thresh = 3608 mlme_obj->cfg.lfr.per_roam_config_high_rate_th; 3609 req->per_config.tx_low_rate_thresh = 3610 mlme_obj->cfg.lfr.per_roam_config_low_rate_th; 3611 req->per_config.rx_low_rate_thresh = 3612 mlme_obj->cfg.lfr.per_roam_config_low_rate_th; 3613 req->per_config.per_rest_time = mlme_obj->cfg.lfr.per_roam_rest_time; 3614 req->per_config.tx_per_mon_time = 3615 mlme_obj->cfg.lfr.per_roam_monitor_time; 3616 req->per_config.rx_per_mon_time = 3617 mlme_obj->cfg.lfr.per_roam_monitor_time; 3618 req->per_config.tx_rate_thresh_percnt = 3619 mlme_obj->cfg.lfr.per_roam_config_rate_th_percent; 3620 req->per_config.rx_rate_thresh_percnt = 3621 mlme_obj->cfg.lfr.per_roam_config_rate_th_percent; 3622 req->per_config.min_candidate_rssi = 3623 mlme_obj->cfg.lfr.per_roam_min_candidate_rssi; 3624 3625 mlme_debug("PER based roaming configuration enable: %d vdev: %d high_rate_thresh: %d low_rate_thresh: %d rate_thresh_percnt: %d per_rest_time: %d monitor_time: %d min cand rssi: %d", 3626 req->per_config.enable, req->vdev_id, 3627 req->per_config.tx_high_rate_thresh, 3628 req->per_config.tx_low_rate_thresh, 3629 req->per_config.tx_rate_thresh_percnt, 3630 req->per_config.per_rest_time, 3631 req->per_config.tx_per_mon_time, 3632 req->per_config.min_candidate_rssi); 3633 3634 return QDF_STATUS_SUCCESS; 3635 } 3636 3637 /** 3638 * cm_roam_offload_per_config() - populates roam offload scan request and sends 3639 * to fw 3640 * @psoc: psoc context 3641 * @vdev_id: vdev id 3642 * 3643 * Return: QDF_STATUS 3644 */ 3645 static QDF_STATUS 3646 cm_roam_offload_per_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3647 { 3648 struct wlan_per_roam_config_req *req; 3649 bool is_per_roam_enabled; 3650 QDF_STATUS status; 3651 3652 /* 3653 * Disable PER trigger for phymode less than 11n to avoid 3654 * frequent roams as the PER rate threshold is greater than 3655 * 11a/b/g rates 3656 */ 3657 is_per_roam_enabled = cm_roam_is_per_roam_allowed(psoc, vdev_id); 3658 if (!is_per_roam_enabled) 3659 return QDF_STATUS_SUCCESS; 3660 3661 req = qdf_mem_malloc(sizeof(*req)); 3662 if (!req) 3663 return QDF_STATUS_E_NOMEM; 3664 3665 req->vdev_id = vdev_id; 3666 status = cm_roam_fill_per_roam_request(psoc, req); 3667 if (QDF_IS_STATUS_ERROR(status)) { 3668 qdf_mem_free(req); 3669 mlme_debug("fail to fill per config"); 3670 return status; 3671 } 3672 3673 status = wlan_cm_tgt_send_roam_per_config(psoc, vdev_id, req); 3674 if (QDF_IS_STATUS_ERROR(status)) 3675 mlme_debug("fail to send roam stop"); 3676 3677 qdf_mem_free(req); 3678 3679 return status; 3680 } 3681 3682 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 3683 QDF_STATUS 3684 cm_akm_roam_allowed(struct wlan_objmgr_psoc *psoc, 3685 struct wlan_objmgr_vdev *vdev) 3686 { 3687 int32_t akm; 3688 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3689 uint32_t fw_akm_bitmap; 3690 3691 akm = wlan_crypto_get_param(vdev, 3692 WLAN_CRYPTO_PARAM_KEY_MGMT); 3693 mlme_debug("akm %x", akm); 3694 3695 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3696 if (!mlme_obj) 3697 return QDF_STATUS_E_FAILURE; 3698 3699 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384) || 3700 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256)) && 3701 !mlme_obj->cfg.lfr.rso_user_config.is_fils_roaming_supported) { 3702 mlme_info("FILS Roaming not suppprted by fw"); 3703 return QDF_STATUS_E_NOSUPPORT; 3704 } 3705 fw_akm_bitmap = mlme_obj->cfg.lfr.fw_akm_bitmap; 3706 /* Roaming is not supported currently for OWE akm */ 3707 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE) && 3708 !(fw_akm_bitmap & (1 << AKM_OWE))) { 3709 mlme_info("OWE Roaming not suppprted by fw"); 3710 return QDF_STATUS_E_NOSUPPORT; 3711 } 3712 3713 /* Roaming is not supported for SAE authentication */ 3714 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE) && 3715 !CM_IS_FW_SAE_ROAM_SUPPORTED(fw_akm_bitmap)) { 3716 mlme_info("Roaming not suppprted for SAE connection"); 3717 return QDF_STATUS_E_NOSUPPORT; 3718 } 3719 3720 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY) || 3721 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) && 3722 !CM_IS_FW_SAE_EXT_ROAM_SUPPORTED(fw_akm_bitmap)) { 3723 mlme_info("Roaming not supported for SAE EXT akm"); 3724 return QDF_STATUS_E_NOSUPPORT; 3725 } 3726 3727 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B) || 3728 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192)) && 3729 !(fw_akm_bitmap & (1 << AKM_SUITEB))) { 3730 mlme_info("Roaming not supported for SUITEB connection"); 3731 return QDF_STATUS_E_NOSUPPORT; 3732 } 3733 3734 /* 3735 * If fw doesn't advertise FT SAE, FT-FILS or FT-Suite-B capability, 3736 * don't support roaming to that profile 3737 */ 3738 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) && 3739 !CM_IS_FW_FT_SAE_SUPPORTED(fw_akm_bitmap)) { 3740 mlme_info("Roaming not suppprted for FT SAE akm"); 3741 return QDF_STATUS_E_NOSUPPORT; 3742 } 3743 3744 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) && 3745 !(fw_akm_bitmap & (1 << AKM_FT_SUITEB_SHA384))) { 3746 mlme_info("Roaming not suppprted for FT Suite-B akm"); 3747 return QDF_STATUS_E_NOSUPPORT; 3748 } 3749 3750 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384) || 3751 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256)) && 3752 !(fw_akm_bitmap & (1 << AKM_FT_FILS))) { 3753 mlme_info("Roaming not suppprted for FT FILS akm"); 3754 return QDF_STATUS_E_NOSUPPORT; 3755 } 3756 3757 return QDF_STATUS_SUCCESS; 3758 } 3759 3760 QDF_STATUS cm_set_roam_scan_high_rssi_offset(struct wlan_objmgr_psoc *psoc, 3761 uint8_t vdev_id, 3762 uint8_t param_value) 3763 { 3764 struct rso_config *rso_cfg; 3765 struct wlan_objmgr_vdev *vdev; 3766 struct wlan_roam_offload_scan_rssi_params *roam_rssi_params; 3767 QDF_STATUS status = QDF_STATUS_E_INVAL; 3768 qdf_freq_t op_freq; 3769 3770 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3771 WLAN_MLME_CM_ID); 3772 if (!vdev) { 3773 mlme_err("vdev object is NULL for vdev %d", vdev_id); 3774 return QDF_STATUS_E_FAILURE; 3775 } 3776 3777 op_freq = wlan_get_operation_chan_freq(vdev); 3778 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(op_freq)) { 3779 mlme_err("vdev:%d High RSSI offset can't be set in 6 GHz band", 3780 vdev_id); 3781 goto rel_vdev_ref; 3782 } 3783 3784 rso_cfg = wlan_cm_get_rso_config(vdev); 3785 if (!rso_cfg) 3786 goto rel_vdev_ref; 3787 3788 roam_rssi_params = qdf_mem_malloc(sizeof(*roam_rssi_params)); 3789 if (!roam_rssi_params) 3790 goto rel_vdev_ref; 3791 3792 wlan_cm_set_roam_scan_high_rssi_offset(psoc, param_value); 3793 qdf_mem_zero(roam_rssi_params, sizeof(*roam_rssi_params)); 3794 cm_roam_scan_offload_rssi_thresh(psoc, vdev_id, 3795 roam_rssi_params, rso_cfg); 3796 mlme_debug("vdev:%d Configured high RSSI delta=%d, 5 GHZ roam flag=%d", 3797 vdev_id, roam_rssi_params->hi_rssi_scan_rssi_delta, 3798 (roam_rssi_params->flags & 3799 ROAM_SCAN_RSSI_THRESHOLD_FLAG_ROAM_HI_RSSI_EN_ON_5G)); 3800 3801 status = wlan_cm_tgt_send_roam_scan_offload_rssi_params( 3802 vdev, roam_rssi_params); 3803 if (QDF_IS_STATUS_ERROR(status)) 3804 mlme_err("fail to set roam scan high RSSI offset"); 3805 3806 qdf_mem_free(roam_rssi_params); 3807 rel_vdev_ref: 3808 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3809 3810 return status; 3811 } 3812 #endif 3813 3814 #ifdef WLAN_ADAPTIVE_11R 3815 static bool 3816 cm_is_adaptive_11r_roam_supported(struct wlan_mlme_psoc_ext_obj *mlme_obj, 3817 struct rso_config *rso_cfg) 3818 { 3819 if (rso_cfg->is_adaptive_11r_connection) 3820 return mlme_obj->cfg.lfr.tgt_adaptive_11r_cap; 3821 3822 return true; 3823 } 3824 #else 3825 static bool 3826 cm_is_adaptive_11r_roam_supported(struct wlan_mlme_psoc_ext_obj *mlme_obj, 3827 struct rso_config *rso_cfg) 3828 3829 { 3830 return true; 3831 } 3832 #endif 3833 3834 static QDF_STATUS 3835 cm_roam_cmd_allowed(struct wlan_objmgr_psoc *psoc, 3836 struct wlan_objmgr_vdev *vdev, 3837 uint8_t command, uint8_t reason) 3838 { 3839 uint8_t vdev_id = wlan_vdev_get_id(vdev); 3840 struct rso_config *rso_cfg; 3841 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3842 bool p2p_disable_sta_roaming = 0, nan_disable_sta_roaming = 0; 3843 QDF_STATUS status; 3844 3845 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3846 if (!mlme_obj) 3847 return QDF_STATUS_E_FAILURE; 3848 3849 rso_cfg = wlan_cm_get_rso_config(vdev); 3850 if (!rso_cfg) 3851 return QDF_STATUS_E_FAILURE; 3852 3853 mlme_debug("RSO Command %d, vdev %d, Reason %d", 3854 command, vdev_id, reason); 3855 3856 if (!cm_is_vdev_connected(vdev) && 3857 (command == ROAM_SCAN_OFFLOAD_UPDATE_CFG || 3858 command == ROAM_SCAN_OFFLOAD_START || 3859 command == ROAM_SCAN_OFFLOAD_RESTART)) { 3860 mlme_debug("vdev not in connected state and command %d ", 3861 command); 3862 return QDF_STATUS_E_FAILURE; 3863 } 3864 3865 if (!cm_is_adaptive_11r_roam_supported(mlme_obj, rso_cfg)) { 3866 mlme_info("Adaptive 11r Roaming not suppprted by fw"); 3867 return QDF_STATUS_E_NOSUPPORT; 3868 } 3869 3870 status = cm_akm_roam_allowed(psoc, vdev); 3871 if (QDF_IS_STATUS_ERROR(status)) 3872 return status; 3873 3874 p2p_disable_sta_roaming = 3875 (cfg_p2p_is_roam_config_disabled(psoc) && 3876 (policy_mgr_mode_specific_connection_count( 3877 psoc, PM_P2P_CLIENT_MODE, NULL) || 3878 policy_mgr_mode_specific_connection_count( 3879 psoc, PM_P2P_GO_MODE, NULL))); 3880 nan_disable_sta_roaming = 3881 (cfg_nan_is_roam_config_disabled(psoc) && 3882 policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE, NULL)); 3883 3884 if ((command == ROAM_SCAN_OFFLOAD_START || 3885 command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) && 3886 (p2p_disable_sta_roaming || nan_disable_sta_roaming)) { 3887 mlme_info("roaming not supported for active %s connection", 3888 p2p_disable_sta_roaming ? "p2p" : "ndi"); 3889 return QDF_STATUS_E_FAILURE; 3890 } 3891 3892 /* 3893 * The Dynamic Config Items Update may happen even if the state is in 3894 * INIT. It is important to ensure that the command is passed down to 3895 * the FW only if the Infra Station is in a connected state. A connected 3896 * station could also be in a PREAUTH or REASSOC states. 3897 * 1) Block all CMDs that are not STOP in INIT State. For STOP always 3898 * inform firmware irrespective of state. 3899 * 2) Block update cfg CMD if its for REASON_ROAM_SET_DENYLIST_BSSID, 3900 * because we need to inform firmware of denylisted AP for PNO in 3901 * all states. 3902 */ 3903 if ((cm_is_vdev_disconnecting(vdev) || 3904 cm_is_vdev_disconnected(vdev)) && 3905 (command != ROAM_SCAN_OFFLOAD_STOP) && 3906 (reason != REASON_ROAM_SET_DENYLIST_BSSID)) { 3907 mlme_info("Scan Command not sent to FW and cmd=%d", command); 3908 return QDF_STATUS_E_FAILURE; 3909 } 3910 3911 return QDF_STATUS_SUCCESS; 3912 } 3913 3914 static QDF_STATUS cm_is_rso_allowed(struct wlan_objmgr_psoc *psoc, 3915 uint8_t vdev_id, uint8_t command, 3916 uint8_t reason) 3917 { 3918 struct wlan_objmgr_vdev *vdev; 3919 QDF_STATUS status; 3920 3921 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3922 WLAN_MLME_CM_ID); 3923 if (!vdev) { 3924 mlme_err("vdev_id: %d: vdev not found", vdev_id); 3925 return QDF_STATUS_E_FAILURE; 3926 } 3927 status = cm_roam_cmd_allowed(psoc, vdev, command, reason); 3928 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3929 3930 return status; 3931 } 3932 3933 void cm_handle_sta_sta_roaming_enablement(struct wlan_objmgr_psoc *psoc, 3934 uint8_t curr_vdev_id) 3935 { 3936 struct wlan_objmgr_vdev *vdev; 3937 struct wlan_objmgr_pdev *pdev; 3938 uint32_t sta_count, conn_idx = 0; 3939 struct dual_sta_policy *dual_sta_policy; 3940 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3941 uint8_t temp_vdev_id; 3942 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3943 3944 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3945 if (!mlme_obj) 3946 return; 3947 3948 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, curr_vdev_id, 3949 WLAN_MLME_CM_ID); 3950 if (!vdev) { 3951 mlme_debug("vdev object is NULL"); 3952 return; 3953 } 3954 3955 pdev = wlan_vdev_get_pdev(vdev); 3956 if (!pdev) 3957 goto rel_ref; 3958 3959 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 3960 sta_count = policy_mgr_get_mode_specific_conn_info(psoc, NULL, 3961 vdev_id_list, 3962 PM_STA_MODE); 3963 3964 if (!(wlan_mlme_get_dual_sta_roaming_enabled(psoc) && sta_count >= 2)) { 3965 mlme_debug("Dual sta roaming is not enabled or count:%d", 3966 sta_count); 3967 goto rel_ref; 3968 } 3969 3970 if (policy_mgr_concurrent_sta_on_different_mac(psoc)) { 3971 mlme_debug("After roam on vdev_id:%d, sta concurrency on different mac:%d", 3972 curr_vdev_id, sta_count); 3973 for (conn_idx = 0; conn_idx < sta_count; conn_idx++) { 3974 temp_vdev_id = vdev_id_list[conn_idx]; 3975 wlan_cm_roam_activate_pcl_per_vdev(psoc, 3976 temp_vdev_id, 3977 true); 3978 /* Set PCL after sending roam complete */ 3979 policy_mgr_set_pcl_for_existing_combo(psoc, 3980 PM_STA_MODE, 3981 temp_vdev_id); 3982 if (temp_vdev_id != curr_vdev_id) { 3983 /* Enable roaming on secondary vdev */ 3984 if_mgr_enable_roaming(pdev, vdev, RSO_SET_PCL); 3985 } 3986 } 3987 } else { 3988 mlme_debug("After roam STA + STA concurrency is in MCC/SCC"); 3989 } 3990 rel_ref: 3991 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3992 } 3993 3994 QDF_STATUS cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc, 3995 uint8_t vdev_id, uint8_t rso_command, 3996 uint8_t reason) 3997 { 3998 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3999 4000 status = cm_is_rso_allowed(psoc, vdev_id, rso_command, reason); 4001 4002 if (status == QDF_STATUS_E_NOSUPPORT) 4003 return QDF_STATUS_SUCCESS; 4004 if (QDF_IS_STATUS_ERROR(status)) { 4005 mlme_debug("ROAM: not allowed"); 4006 return status; 4007 } 4008 4009 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 4010 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 4011 return QDF_STATUS_SUCCESS; 4012 } 4013 4014 /* 4015 * Update PER config to FW. No need to update in case of stop command, 4016 * FW takes care of stopping this internally 4017 */ 4018 if (rso_command != ROAM_SCAN_OFFLOAD_STOP) 4019 cm_roam_offload_per_config(psoc, vdev_id); 4020 4021 if (rso_command == ROAM_SCAN_OFFLOAD_START) 4022 status = cm_roam_start_req(psoc, vdev_id, reason); 4023 else if (rso_command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) 4024 status = cm_roam_update_config_req(psoc, vdev_id, reason); 4025 else if (rso_command == ROAM_SCAN_OFFLOAD_RESTART) 4026 status = cm_roam_restart_req(psoc, vdev_id, reason); 4027 else if (rso_command == ROAM_SCAN_OFFLOAD_ABORT_SCAN) 4028 status = cm_roam_abort_req(psoc, vdev_id, reason); 4029 else 4030 mlme_debug("ROAM: invalid RSO command %d", rso_command); 4031 4032 return status; 4033 } 4034 4035 /** 4036 * cm_roam_switch_to_rso_stop() - roam state handling for rso stop 4037 * @pdev: pdev pointer 4038 * @vdev_id: vdev id 4039 * @reason: reason for changing roam state for the requested vdev id 4040 * @send_resp: 4041 * @start_timer: 4042 * 4043 * This function is used for WLAN_ROAM_RSO_STOPPED roam state handling 4044 * 4045 * Return: QDF_STATUS 4046 */ 4047 static QDF_STATUS 4048 cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev, 4049 uint8_t vdev_id, 4050 uint8_t reason, bool *send_resp, bool start_timer) 4051 { 4052 enum roam_offload_state cur_state; 4053 QDF_STATUS status; 4054 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4055 4056 cur_state = mlme_get_roam_state(psoc, vdev_id); 4057 switch (cur_state) { 4058 case WLAN_ROAM_RSO_ENABLED: 4059 case WLAN_ROAMING_IN_PROG: 4060 case WLAN_ROAM_SYNCH_IN_PROG: 4061 status = cm_roam_stop_req(psoc, vdev_id, reason, 4062 send_resp, start_timer); 4063 if (QDF_IS_STATUS_ERROR(status)) { 4064 mlme_err("ROAM: Unable to switch to RSO STOP State"); 4065 return QDF_STATUS_E_FAILURE; 4066 } 4067 break; 4068 4069 case WLAN_ROAM_DEINIT: 4070 case WLAN_ROAM_RSO_STOPPED: 4071 case WLAN_ROAM_INIT: 4072 /* 4073 * Already the roaming module is initialized at fw, 4074 * nothing to do here 4075 */ 4076 default: 4077 return QDF_STATUS_SUCCESS; 4078 } 4079 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED); 4080 4081 return QDF_STATUS_SUCCESS; 4082 } 4083 4084 /** 4085 * cm_roam_switch_to_deinit() - roam state handling for roam deinit 4086 * @pdev: pdev pointer 4087 * @vdev_id: vdev id 4088 * @reason: reason for changing roam state for the requested vdev id 4089 * 4090 * This function is used for WLAN_ROAM_DEINIT roam state handling 4091 * 4092 * Return: QDF_STATUS 4093 */ 4094 static QDF_STATUS 4095 cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev, 4096 uint8_t vdev_id, 4097 uint8_t reason) 4098 { 4099 QDF_STATUS status; 4100 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4101 enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); 4102 bool sup_disabled_roam; 4103 4104 switch (cur_state) { 4105 /* 4106 * If RSO stop is not done already, send RSO stop first and 4107 * then post deinit. 4108 */ 4109 case WLAN_ROAM_RSO_ENABLED: 4110 case WLAN_ROAMING_IN_PROG: 4111 case WLAN_ROAM_SYNCH_IN_PROG: 4112 cm_roam_switch_to_rso_stop(pdev, vdev_id, reason, NULL, false); 4113 break; 4114 case WLAN_ROAM_RSO_STOPPED: 4115 /* 4116 * When Supplicant disabled roaming is set and roam invoke 4117 * command is received from userspace, fw starts to roam. 4118 * But meanwhile if a disassoc/deauth is received from AP or if 4119 * NB disconnect is initiated while supplicant disabled roam, 4120 * RSO stop with ROAM scan mode as 0 is not sent to firmware 4121 * since the previous state was RSO_STOPPED. This could lead 4122 * to firmware not sending peer unmap event for the current 4123 * AP. To avoid this, if previous RSO stop was sent with 4124 * ROAM scan mode as 4, send RSO stop with Roam scan mode as 0 4125 * and then switch to ROAM_DEINIT. 4126 */ 4127 sup_disabled_roam = 4128 mlme_get_supplicant_disabled_roaming(psoc, 4129 vdev_id); 4130 if (sup_disabled_roam) { 4131 mlme_err("vdev[%d]: supplicant disabled roam. clear roam scan mode", 4132 vdev_id); 4133 status = cm_roam_stop_req(psoc, vdev_id, 4134 REASON_DISCONNECTED, 4135 NULL, false); 4136 if (QDF_IS_STATUS_ERROR(status)) 4137 mlme_err("ROAM: Unable to clear roam scan mode"); 4138 } 4139 break; 4140 case WLAN_ROAM_INIT: 4141 break; 4142 4143 case WLAN_MLO_ROAM_SYNCH_IN_PROG: 4144 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4145 break; 4146 4147 case WLAN_ROAM_DEINIT: 4148 /* 4149 * Already the roaming module is de-initialized at fw, 4150 * do nothing here 4151 */ 4152 default: 4153 return QDF_STATUS_SUCCESS; 4154 } 4155 4156 status = cm_roam_init_req(psoc, vdev_id, false); 4157 if (QDF_IS_STATUS_ERROR(status)) 4158 return status; 4159 4160 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4161 mlme_clear_operations_bitmap(psoc, vdev_id); 4162 wlan_cm_roam_activate_pcl_per_vdev(psoc, vdev_id, false); 4163 4164 /* In case of roaming getting disabled due to 4165 * REASON_ROAM_SET_PRIMARY reason, don't enable roaming on 4166 * the other vdev as that is taken care by the caller once roaming 4167 * on this "vdev_id" is disabled. 4168 */ 4169 if (reason != REASON_SUPPLICANT_INIT_ROAMING && 4170 reason != REASON_ROAM_SET_PRIMARY) { 4171 mlme_debug("vdev_id:%d enable roaming on other connected sta - reason:%d", 4172 vdev_id, reason); 4173 wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id); 4174 } 4175 4176 return QDF_STATUS_SUCCESS; 4177 } 4178 4179 /** 4180 * cm_roam_switch_to_init() - roam state handling for roam init 4181 * @pdev: pdev pointer 4182 * @vdev_id: vdev id 4183 * @reason: reason for changing roam state for the requested vdev id 4184 * 4185 * This function is used for WLAN_ROAM_INIT roam state handling 4186 * 4187 * Return: QDF_STATUS 4188 */ 4189 static QDF_STATUS 4190 cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev, 4191 uint8_t vdev_id, 4192 uint8_t reason) 4193 { 4194 enum roam_offload_state cur_state; 4195 uint8_t temp_vdev_id, roam_enabled_vdev_id; 4196 uint32_t roaming_bitmap; 4197 bool dual_sta_roam_active, usr_disabled_roaming; 4198 bool sta_concurrency_is_with_different_mac; 4199 QDF_STATUS status; 4200 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4201 struct wlan_mlme_psoc_ext_obj *mlme_obj; 4202 struct dual_sta_policy *dual_sta_policy; 4203 struct wlan_objmgr_vdev *vdev; 4204 4205 if (!psoc) 4206 return QDF_STATUS_E_FAILURE; 4207 4208 mlme_obj = mlme_get_psoc_ext_obj(psoc); 4209 if (!mlme_obj) 4210 return QDF_STATUS_E_FAILURE; 4211 4212 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 4213 dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc); 4214 sta_concurrency_is_with_different_mac = 4215 policy_mgr_concurrent_sta_on_different_mac(psoc); 4216 cur_state = mlme_get_roam_state(psoc, vdev_id); 4217 4218 mlme_info("dual_sta_roam_active:%d, sta concurrency on different mac:%d, state:%d", 4219 dual_sta_roam_active, sta_concurrency_is_with_different_mac, 4220 cur_state); 4221 4222 switch (cur_state) { 4223 case WLAN_ROAM_DEINIT: 4224 roaming_bitmap = mlme_get_roam_trigger_bitmap(psoc, vdev_id); 4225 if (!roaming_bitmap) { 4226 mlme_info("CM_RSO: Cannot change to INIT state for vdev[%d]", 4227 vdev_id); 4228 return QDF_STATUS_E_FAILURE; 4229 } 4230 4231 /* 4232 * Enable roaming on other interface only if STA + STA 4233 * concurrency on different mac. 4234 */ 4235 if (dual_sta_roam_active && 4236 sta_concurrency_is_with_different_mac) { 4237 mlme_info("sta concurrency on different mac"); 4238 break; 4239 } 4240 4241 /* 4242 * If dual sta roaming is not supported, do not enable 4243 * the RSO on the second STA interface, even if the 4244 * primary interface config is present via dual sta policy 4245 */ 4246 temp_vdev_id = policy_mgr_get_roam_enabled_sta_session_id( 4247 psoc, vdev_id); 4248 if (!dual_sta_roam_active && 4249 temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 4250 mlme_debug("Do not enable RSO on %d, RSO is enabled on %d", 4251 vdev_id, temp_vdev_id); 4252 return QDF_STATUS_E_FAILURE; 4253 } 4254 4255 /* 4256 * set_primary_vdev usecase is to use that 4257 * interface(e.g. wlan0) over the other 4258 * interface(i.e. wlan1) for data transfer. Non-primary 4259 * vdev use case is to check the quality of that link 4260 * and decide if data can be switched to it and make it 4261 * primary. 4262 * Enabling roaming on non-primary vdev also in this 4263 * context would always helps to find better AP. 4264 */ 4265 if (wlan_mlme_is_primary_interface_configured(psoc) && 4266 (reason != REASON_SUPPLICANT_INIT_ROAMING)) { 4267 mlme_info("STA + STA concurrency with a primary iface, have roaming enabled on both interfaces"); 4268 break; 4269 } 4270 4271 /* 4272 * Disable roaming on the enabled sta if supplicant wants to 4273 * enable roaming on this vdev id 4274 */ 4275 if (temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 4276 /* 4277 * Roam init state can be requested as part of 4278 * initial connection or due to enable from 4279 * supplicant via vendor command. This check will 4280 * ensure roaming does not get enabled on this STA 4281 * vdev id if it is not an explicit enable from 4282 * supplicant. 4283 */ 4284 mlme_debug("Interface vdev_id: %d, roaming enabled on vdev_id: %d, reason:%d", 4285 vdev_id, temp_vdev_id, 4286 reason); 4287 4288 if (reason == REASON_SUPPLICANT_INIT_ROAMING) { 4289 cm_roam_state_change(pdev, temp_vdev_id, 4290 WLAN_ROAM_DEINIT, 4291 reason, 4292 NULL, false); 4293 } else { 4294 mlme_info("CM_RSO: Roam module already initialized on vdev:[%d]", 4295 temp_vdev_id); 4296 return QDF_STATUS_E_FAILURE; 4297 } 4298 } 4299 break; 4300 4301 case WLAN_ROAM_SYNCH_IN_PROG: 4302 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_INIT); 4303 return QDF_STATUS_SUCCESS; 4304 4305 case WLAN_ROAM_INIT: 4306 case WLAN_ROAM_RSO_STOPPED: 4307 case WLAN_ROAM_RSO_ENABLED: 4308 case WLAN_ROAMING_IN_PROG: 4309 /* 4310 * Already the roaming module is initialized at fw, 4311 * just return from here 4312 */ 4313 default: 4314 return QDF_STATUS_SUCCESS; 4315 } 4316 4317 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 4318 WLAN_MLME_NB_ID); 4319 if (!vdev) { 4320 mlme_err("CM_RSO: vdev is null"); 4321 return QDF_STATUS_E_INVAL; 4322 } 4323 4324 if (cm_is_vdev_disconnecting(vdev) || 4325 cm_is_vdev_disconnected(vdev)) { 4326 mlme_debug("CM_RSO: RSO Init received in disconnected state"); 4327 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4328 return QDF_STATUS_E_INVAL; 4329 } 4330 4331 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4332 4333 status = cm_roam_init_req(psoc, vdev_id, true); 4334 4335 if (QDF_IS_STATUS_ERROR(status)) 4336 return status; 4337 4338 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_INIT); 4339 4340 roam_enabled_vdev_id = 4341 policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id); 4342 4343 /* Send PDEV pcl command if only one STA is in connected state 4344 * If there is another STA connection exist, then set the 4345 * PCL type to vdev level 4346 */ 4347 if (roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX && 4348 dual_sta_roam_active && sta_concurrency_is_with_different_mac) 4349 wlan_cm_roam_activate_pcl_per_vdev(psoc, vdev_id, true); 4350 4351 /* Set PCL before sending RSO start */ 4352 policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, vdev_id); 4353 4354 wlan_mlme_get_usr_disabled_roaming(psoc, &usr_disabled_roaming); 4355 if (usr_disabled_roaming) { 4356 status = 4357 cm_roam_send_disable_config( 4358 psoc, vdev_id, 4359 WMI_VDEV_ROAM_11KV_CTRL_DISABLE_FW_TRIGGER_ROAMING); 4360 4361 if (!QDF_IS_STATUS_SUCCESS(status)) 4362 mlme_err("ROAM: fast roaming disable failed. status %d", 4363 status); 4364 } 4365 4366 return QDF_STATUS_SUCCESS; 4367 } 4368 4369 /** 4370 * cm_roam_switch_to_rso_enable() - roam state handling for rso started 4371 * @pdev: pdev pointer 4372 * @vdev_id: vdev id 4373 * @reason: reason for changing roam state for the requested vdev id 4374 * 4375 * This function is used for WLAN_ROAM_RSO_ENABLED roam state handling 4376 * 4377 * Return: QDF_STATUS 4378 */ 4379 static QDF_STATUS 4380 cm_roam_switch_to_rso_enable(struct wlan_objmgr_pdev *pdev, 4381 uint8_t vdev_id, 4382 uint8_t reason) 4383 { 4384 enum roam_offload_state cur_state, new_roam_state; 4385 QDF_STATUS status; 4386 uint8_t control_bitmap; 4387 bool sup_disabled_roaming; 4388 bool rso_allowed; 4389 uint8_t rso_command = ROAM_SCAN_OFFLOAD_START; 4390 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4391 4392 wlan_mlme_get_roam_scan_offload_enabled(psoc, &rso_allowed); 4393 sup_disabled_roaming = mlme_get_supplicant_disabled_roaming(psoc, 4394 vdev_id); 4395 control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id); 4396 4397 cur_state = mlme_get_roam_state(psoc, vdev_id); 4398 mlme_debug("CM_RSO: vdev%d: cur_state : %d reason:%d control_bmap:0x%x sup_disabled_roam:%d", 4399 vdev_id, cur_state, reason, control_bitmap, 4400 sup_disabled_roaming); 4401 4402 switch (cur_state) { 4403 case WLAN_ROAM_INIT: 4404 case WLAN_ROAM_RSO_STOPPED: 4405 break; 4406 4407 case WLAN_ROAM_DEINIT: 4408 status = cm_roam_switch_to_init(pdev, vdev_id, reason); 4409 if (QDF_IS_STATUS_ERROR(status)) 4410 return status; 4411 4412 break; 4413 case WLAN_ROAM_RSO_ENABLED: 4414 /* 4415 * Send RSO update config if roaming already enabled 4416 */ 4417 rso_command = ROAM_SCAN_OFFLOAD_UPDATE_CFG; 4418 break; 4419 case WLAN_ROAMING_IN_PROG: 4420 /* 4421 * When roam abort happens, the roam offload 4422 * state machine moves to RSO_ENABLED state. 4423 * But if Supplicant disabled roaming is set in case 4424 * of roam invoke or if roaming was disabled due to 4425 * other reasons like SAP start/connect on other vdev, 4426 * the state should be transitioned to RSO STOPPED. 4427 */ 4428 if (sup_disabled_roaming || control_bitmap) 4429 new_roam_state = WLAN_ROAM_RSO_STOPPED; 4430 else 4431 new_roam_state = WLAN_ROAM_RSO_ENABLED; 4432 4433 mlme_set_roam_state(psoc, vdev_id, new_roam_state); 4434 4435 return QDF_STATUS_SUCCESS; 4436 case WLAN_ROAM_SYNCH_IN_PROG: 4437 if (reason == REASON_ROAM_ABORT) { 4438 mlme_debug("Roam synch in progress, drop Roam abort"); 4439 return QDF_STATUS_SUCCESS; 4440 } 4441 /* 4442 * After roam sych propagation is complete, send 4443 * RSO start command to firmware to update AP profile, 4444 * new PCL. 4445 * If this is roam invoke case and supplicant has already 4446 * disabled firmware roaming, then move to RSO stopped state 4447 * instead of RSO enabled. 4448 */ 4449 if (sup_disabled_roaming || control_bitmap) { 4450 new_roam_state = WLAN_ROAM_RSO_STOPPED; 4451 mlme_set_roam_state(psoc, vdev_id, new_roam_state); 4452 4453 return QDF_STATUS_SUCCESS; 4454 } 4455 4456 break; 4457 default: 4458 return QDF_STATUS_SUCCESS; 4459 } 4460 4461 if (!rso_allowed) { 4462 mlme_debug("ROAM: RSO disabled via INI"); 4463 return QDF_STATUS_E_FAILURE; 4464 } 4465 4466 if (control_bitmap) { 4467 mlme_debug("ROAM: RSO Disabled internally: vdev[%d] bitmap[0x%x]", 4468 vdev_id, control_bitmap); 4469 return QDF_STATUS_E_FAILURE; 4470 } 4471 4472 status = cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason); 4473 if (QDF_IS_STATUS_ERROR(status)) { 4474 mlme_err("ROAM: vdev:%d RSO start failed", vdev_id); 4475 return status; 4476 } 4477 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_ENABLED); 4478 4479 /* If the set_key for the connected bssid was received during Roam sync 4480 * in progress, then the RSO update to the FW will be rejected. The RSO 4481 * start which might be in progress during set_key could send stale pmk 4482 * to the FW. Therefore, once RSO is enabled, send the RSO update with 4483 * the PMK received from the __wlan_hdd_cfg80211_keymgmt_set_key. 4484 */ 4485 if (wlan_mlme_is_pmk_set_deferred(psoc, vdev_id)) { 4486 cm_roam_send_rso_cmd(psoc, vdev_id, 4487 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 4488 REASON_ROAM_PSK_PMK_CHANGED); 4489 wlan_mlme_defer_pmk_set_in_roaming(psoc, vdev_id, false); 4490 } 4491 4492 /* 4493 * If supplicant disabled roaming, driver does not send 4494 * RSO cmd to fw. This causes roam invoke to fail in FW 4495 * since RSO start never happened at least once to 4496 * configure roaming engine in FW. So send RSO start followed 4497 * by RSO stop if supplicant disabled roaming is true. 4498 */ 4499 if (!sup_disabled_roaming) 4500 return QDF_STATUS_SUCCESS; 4501 4502 mlme_debug("ROAM: RSO disabled by Supplicant on vdev[%d]", vdev_id); 4503 return cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STOPPED, 4504 REASON_SUPPLICANT_DISABLED_ROAMING, 4505 NULL, false); 4506 } 4507 4508 /** 4509 * cm_roam_switch_to_roam_start() - roam state handling for ROAMING_IN_PROG 4510 * @pdev: pdev pointer 4511 * @vdev_id: vdev id 4512 * @reason: reason for changing roam state for the requested vdev id 4513 * 4514 * This function is used for WLAN_ROAMING_IN_PROG roam state handling 4515 * 4516 * Return: QDF_STATUS 4517 */ 4518 static QDF_STATUS 4519 cm_roam_switch_to_roam_start(struct wlan_objmgr_pdev *pdev, 4520 uint8_t vdev_id, 4521 uint8_t reason) 4522 { 4523 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4524 enum roam_offload_state cur_state = 4525 mlme_get_roam_state(psoc, vdev_id); 4526 switch (cur_state) { 4527 case WLAN_ROAMING_IN_PROG: 4528 mlme_debug("Roam started already on vdev[%d]", vdev_id); 4529 break; 4530 case WLAN_ROAM_RSO_ENABLED: 4531 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAMING_IN_PROG); 4532 break; 4533 4534 case WLAN_ROAM_RSO_STOPPED: 4535 /* 4536 * When supplicant has disabled roaming, roam invoke triggered 4537 * from supplicant can cause firmware to send roam start 4538 * notification. Allow roam start in this condition. 4539 */ 4540 if (mlme_get_supplicant_disabled_roaming(psoc, vdev_id) && 4541 4542 wlan_cm_roaming_in_progress(pdev, vdev_id)) { 4543 mlme_set_roam_state(psoc, vdev_id, 4544 WLAN_ROAMING_IN_PROG); 4545 break; 4546 } 4547 fallthrough; 4548 case WLAN_ROAM_INIT: 4549 case WLAN_ROAM_DEINIT: 4550 case WLAN_ROAM_SYNCH_IN_PROG: 4551 default: 4552 mlme_err("ROAM: Roaming start received in invalid state: %d", 4553 cur_state); 4554 return QDF_STATUS_E_FAILURE; 4555 } 4556 4557 return QDF_STATUS_SUCCESS; 4558 } 4559 4560 /** 4561 * cm_roam_switch_to_roam_sync() - roam state handling for roam sync 4562 * @pdev: pdev pointer 4563 * @vdev_id: vdev id 4564 * @reason: reason for changing roam state for the requested vdev id 4565 * 4566 * This function is used for WLAN_ROAM_SYNCH_IN_PROG roam state handling 4567 * 4568 * Return: QDF_STATUS 4569 */ 4570 static QDF_STATUS 4571 cm_roam_switch_to_roam_sync(struct wlan_objmgr_pdev *pdev, 4572 uint8_t vdev_id, 4573 uint8_t reason) 4574 { 4575 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4576 enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); 4577 4578 switch (cur_state) { 4579 case WLAN_ROAM_RSO_ENABLED: 4580 /* 4581 * Roam synch can come directly without roam start 4582 * after waking up from power save mode or in case of 4583 * deauth roam trigger to stop data path queues 4584 */ 4585 case WLAN_ROAMING_IN_PROG: 4586 if (!cm_is_vdevid_active(pdev, vdev_id)) { 4587 mlme_err("ROAM: STA not in connected state"); 4588 return QDF_STATUS_E_FAILURE; 4589 } 4590 4591 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_SYNCH_IN_PROG); 4592 break; 4593 case WLAN_ROAM_RSO_STOPPED: 4594 /* 4595 * If roaming is disabled by Supplicant and if this transition 4596 * is due to roaming invoked by the supplicant, then allow 4597 * this state transition 4598 */ 4599 if (mlme_get_supplicant_disabled_roaming(psoc, vdev_id) && 4600 wlan_cm_roaming_in_progress(pdev, vdev_id)) { 4601 mlme_set_roam_state(psoc, vdev_id, 4602 WLAN_ROAM_SYNCH_IN_PROG); 4603 break; 4604 } 4605 /* 4606 * transition to WLAN_ROAM_SYNCH_IN_PROG not allowed otherwise 4607 * if we're already RSO stopped, fall through to return failure 4608 */ 4609 fallthrough; 4610 case WLAN_ROAM_INIT: 4611 case WLAN_ROAM_DEINIT: 4612 case WLAN_ROAM_SYNCH_IN_PROG: 4613 default: 4614 mlme_err("ROAM: Roam synch not allowed in [%d] state", 4615 cur_state); 4616 return QDF_STATUS_E_FAILURE; 4617 } 4618 4619 return QDF_STATUS_SUCCESS; 4620 } 4621 4622 #ifdef FEATURE_ROAM_DEBUG 4623 /** 4624 * union rso_rec_arg1 - argument 1 record rso state change 4625 * @value: aggregate value of the structured param 4626 * @request_st: requested rso state 4627 * @cur_st: current rso state 4628 * @new_st: new rso state 4629 * @status: qdf status for the request 4630 */ 4631 union rso_rec_arg1 { 4632 uint32_t value; 4633 struct { 4634 uint32_t request_st:4, 4635 cur_st:4, 4636 new_st:4, 4637 status:8; 4638 }; 4639 }; 4640 4641 /** 4642 * get_rso_arg1 - get argument 1 record rso state change 4643 * @request_st: requested rso state 4644 * @cur_st: current rso state 4645 * @new_st: new rso state 4646 * @status: qdf status for the request 4647 * 4648 * Return: u32 value of rso information 4649 */ 4650 static uint32_t get_rso_arg1(enum roam_offload_state request_st, 4651 enum roam_offload_state cur_st, 4652 enum roam_offload_state new_st, 4653 QDF_STATUS status) 4654 { 4655 union rso_rec_arg1 rso_arg1; 4656 4657 rso_arg1.value = 0; 4658 rso_arg1.request_st = request_st; 4659 rso_arg1.cur_st = cur_st; 4660 rso_arg1.new_st = new_st; 4661 rso_arg1.status = status; 4662 4663 return rso_arg1.value; 4664 } 4665 4666 /** 4667 * union rso_rec_arg2 - argument 2 record rso state change 4668 * @value: aggregate value of the structured param 4669 * @is_up: vdev is up 4670 * @supp_dis_roam: supplicant disable roam 4671 * @roam_progress: roam in progress 4672 * @ctrl_bitmap: control bitmap 4673 * @reason: reason code 4674 * 4675 * Return: u32 value of rso information 4676 */ 4677 union rso_rec_arg2 { 4678 uint32_t value; 4679 struct { 4680 uint32_t is_up: 1, 4681 supp_dis_roam:1, 4682 roam_progress:1, 4683 ctrl_bitmap:8, 4684 reason:8; 4685 }; 4686 }; 4687 4688 /** 4689 * get_rso_arg2 - get argument 2 record rso state change 4690 * @is_up: vdev is up 4691 * @supp_dis_roam: supplicant disable roam 4692 * @roam_progress: roam in progress 4693 * @ctrl_bitmap: control bitmap 4694 * @reason: reason code 4695 */ 4696 static uint32_t get_rso_arg2(bool is_up, 4697 bool supp_dis_roam, 4698 bool roam_progress, 4699 uint8_t ctrl_bitmap, 4700 uint8_t reason) 4701 { 4702 union rso_rec_arg2 rso_arg2; 4703 4704 rso_arg2.value = 0; 4705 if (is_up) 4706 rso_arg2.is_up = 1; 4707 if (supp_dis_roam) 4708 rso_arg2.supp_dis_roam = 1; 4709 if (roam_progress) 4710 rso_arg2.roam_progress = 1; 4711 rso_arg2.ctrl_bitmap = ctrl_bitmap; 4712 rso_arg2.reason = reason; 4713 4714 return rso_arg2.value; 4715 } 4716 4717 /** 4718 * cm_record_state_change() - record rso state change to roam history log 4719 * @pdev: pdev object 4720 * @vdev_id: vdev id 4721 * @cur_st: current state 4722 * @requested_state: requested state 4723 * @reason: reason 4724 * @is_up: vdev is up 4725 * @status: request result code 4726 * 4727 * This function will record the RSO state change to roam history log. 4728 * 4729 * Return: void 4730 */ 4731 static void 4732 cm_record_state_change(struct wlan_objmgr_pdev *pdev, 4733 uint8_t vdev_id, 4734 enum roam_offload_state cur_st, 4735 enum roam_offload_state requested_state, 4736 uint8_t reason, 4737 bool is_up, 4738 QDF_STATUS status) 4739 { 4740 enum roam_offload_state new_state; 4741 bool supp_dis_roam; 4742 bool roam_progress; 4743 uint8_t control_bitmap; 4744 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4745 4746 if (!psoc) 4747 return; 4748 4749 new_state = mlme_get_roam_state(psoc, vdev_id); 4750 control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id); 4751 supp_dis_roam = mlme_get_supplicant_disabled_roaming(psoc, vdev_id); 4752 roam_progress = wlan_cm_roaming_in_progress(pdev, vdev_id); 4753 wlan_rec_conn_info(vdev_id, DEBUG_CONN_RSO, 4754 NULL, 4755 get_rso_arg1(requested_state, cur_st, 4756 new_state, status), 4757 get_rso_arg2(is_up, 4758 supp_dis_roam, roam_progress, 4759 control_bitmap, reason)); 4760 } 4761 #else 4762 static inline void 4763 cm_record_state_change(struct wlan_objmgr_pdev *pdev, 4764 uint8_t vdev_id, 4765 enum roam_offload_state cur_st, 4766 enum roam_offload_state requested_state, 4767 uint8_t reason, 4768 bool is_up, 4769 QDF_STATUS status) 4770 { 4771 } 4772 #endif 4773 4774 #ifdef WLAN_FEATURE_11BE_MLO 4775 /** 4776 * cm_mlo_roam_switch_for_link() - roam state handling during mlo roam 4777 * for link/s. 4778 * @pdev: pdev pointer 4779 * @vdev_id: vdev id 4780 * @reason: reason for changing roam state for the requested vdev id 4781 * 4782 * This function is used for WLAN_MLO_ROAM_SYNCH_IN_PROG roam state handling 4783 * 4784 * Return: QDF_STATUS 4785 */ 4786 static QDF_STATUS 4787 cm_mlo_roam_switch_for_link(struct wlan_objmgr_pdev *pdev, 4788 uint8_t vdev_id, uint8_t reason) 4789 { 4790 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4791 enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); 4792 4793 if (reason != REASON_ROAM_HANDOFF_DONE && 4794 reason != REASON_ROAM_ABORT && 4795 reason != REASON_ROAM_LINK_SWITCH_ASSOC_VDEV_CHANGE) { 4796 mlo_debug("CM_RSO: link vdev:%d state switch received with invalid reason:%d", 4797 vdev_id, reason); 4798 return QDF_STATUS_E_FAILURE; 4799 } 4800 4801 /* 4802 * change roam state to deinit for assoc vdev that has now changed to 4803 * link vdev 4804 */ 4805 if (reason == REASON_ROAM_LINK_SWITCH_ASSOC_VDEV_CHANGE) { 4806 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4807 return QDF_STATUS_SUCCESS; 4808 } 4809 4810 switch (cur_state) { 4811 case WLAN_ROAM_DEINIT: 4812 /* Only used for link vdev during MLO roaming */ 4813 mlme_set_roam_state(psoc, vdev_id, WLAN_MLO_ROAM_SYNCH_IN_PROG); 4814 break; 4815 case WLAN_MLO_ROAM_SYNCH_IN_PROG: 4816 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4817 break; 4818 default: 4819 mlme_err("ROAM: vdev:%d MLO Roam synch not allowed in [%d] state reason:%d", 4820 vdev_id, cur_state, reason); 4821 return QDF_STATUS_E_FAILURE; 4822 } 4823 4824 return QDF_STATUS_SUCCESS; 4825 } 4826 4827 QDF_STATUS 4828 cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id, 4829 enum roam_offload_state requested_state, 4830 uint8_t reason, bool *is_rso_skip) 4831 { 4832 QDF_STATUS status = QDF_STATUS_SUCCESS; 4833 struct wlan_objmgr_vdev *vdev; 4834 struct wlan_objmgr_vdev *assoc_vdev = NULL; 4835 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4836 4837 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, *vdev_id, 4838 WLAN_MLME_NB_ID); 4839 if (!vdev) 4840 return QDF_STATUS_E_FAILURE; 4841 4842 /* 4843 * When link switch is in progress, the MLO link flag would be reset and 4844 * set back on assoc vdev, so avoid any state transition during link 4845 * switch. 4846 */ 4847 if (wlan_vdev_mlme_get_is_mlo_vdev(psoc, *vdev_id) && 4848 mlo_mgr_is_link_switch_in_progress(vdev)) { 4849 mlme_debug("MLO ROAM: Link switch in prog! skip RSO cmd:%d on vdev %d", 4850 requested_state, *vdev_id); 4851 *is_rso_skip = true; 4852 goto end; 4853 } 4854 4855 if (wlan_vdev_mlme_get_is_mlo_vdev(psoc, *vdev_id) && 4856 cm_is_vdev_disconnecting(vdev) && 4857 (reason == REASON_DISCONNECTED || 4858 reason == REASON_DRIVER_DISABLED)) { 4859 /* 4860 * Processing disconnect on assoc vdev but roaming is still 4861 * enabled. It's either due to single ML usecase or failed to 4862 * connect to second link. 4863 */ 4864 if (!wlan_vdev_mlme_get_is_mlo_link(psoc, *vdev_id) && 4865 wlan_is_roaming_enabled(pdev, *vdev_id)) { 4866 mlme_debug("MLO ROAM: Process RSO cmd:%d on assoc vdev : %d", 4867 requested_state, *vdev_id); 4868 *is_rso_skip = false; 4869 } else { 4870 mlme_debug("MLO ROAM: skip RSO cmd:%d on assoc vdev %d", 4871 requested_state, *vdev_id); 4872 *is_rso_skip = true; 4873 } 4874 } 4875 4876 if (!wlan_vdev_mlme_get_is_mlo_link(wlan_pdev_get_psoc(pdev), 4877 *vdev_id)) 4878 goto end; 4879 4880 if (reason == REASON_ROAM_HANDOFF_DONE || reason == REASON_ROAM_ABORT) { 4881 status = cm_mlo_roam_switch_for_link(pdev, *vdev_id, reason); 4882 mlme_debug("MLO ROAM: update rso state on link vdev %d", 4883 *vdev_id); 4884 *is_rso_skip = true; 4885 } else if ((reason == REASON_DISCONNECTED || 4886 reason == REASON_DRIVER_DISABLED) && 4887 cm_is_vdev_disconnecting(vdev)) { 4888 assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev); 4889 4890 if (!assoc_vdev) { 4891 mlme_err("Assoc vdev is NULL"); 4892 status = QDF_STATUS_E_FAILURE; 4893 goto end; 4894 } 4895 /* Update the vdev id to send RSO stop on assoc vdev */ 4896 *vdev_id = wlan_vdev_get_id(assoc_vdev); 4897 *is_rso_skip = false; 4898 mlme_debug("MLO ROAM: process RSO stop on assoc vdev %d", 4899 *vdev_id); 4900 goto end; 4901 } else { 4902 mlme_debug("MLO ROAM: skip RSO cmd on link vdev %d", *vdev_id); 4903 *is_rso_skip = true; 4904 } 4905 end: 4906 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4907 return status; 4908 } 4909 #endif 4910 4911 QDF_STATUS 4912 cm_roam_state_change(struct wlan_objmgr_pdev *pdev, 4913 uint8_t vdev_id, 4914 enum roam_offload_state requested_state, 4915 uint8_t reason, bool *send_resp, bool start_timer) 4916 { 4917 QDF_STATUS status = QDF_STATUS_SUCCESS; 4918 struct wlan_objmgr_vdev *vdev; 4919 bool is_up; 4920 bool is_rso_skip = false; 4921 enum roam_offload_state cur_state; 4922 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4923 4924 if (!psoc) 4925 return QDF_STATUS_E_INVAL; 4926 4927 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 4928 WLAN_MLME_NB_ID); 4929 if (!vdev) 4930 return status; 4931 4932 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) 4933 is_up = mlo_check_if_all_vdev_up(vdev); 4934 else 4935 is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev)); 4936 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4937 4938 if (requested_state != WLAN_ROAM_DEINIT && !is_up) { 4939 mlme_debug("ROAM: roam state(%d) change requested in non-connected state", 4940 requested_state); 4941 goto end; 4942 } 4943 4944 status = cm_handle_mlo_rso_state_change(pdev, &vdev_id, requested_state, 4945 reason, &is_rso_skip); 4946 if (is_rso_skip) 4947 return status; 4948 4949 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 4950 WLAN_MLME_CM_ID); 4951 if (!vdev) { 4952 mlme_err("Invalid vdev:%d", vdev_id); 4953 goto end; 4954 } 4955 4956 status = cm_roam_acquire_lock(vdev); 4957 if (QDF_IS_STATUS_ERROR(status)) { 4958 mlme_err("Fail to acquire lock, status: %d", status); 4959 goto release_ref; 4960 } 4961 4962 switch (requested_state) { 4963 case WLAN_ROAM_DEINIT: 4964 status = cm_roam_switch_to_deinit(pdev, vdev_id, reason); 4965 break; 4966 case WLAN_ROAM_INIT: 4967 status = cm_roam_switch_to_init(pdev, vdev_id, reason); 4968 break; 4969 case WLAN_ROAM_RSO_ENABLED: 4970 status = cm_roam_switch_to_rso_enable(pdev, vdev_id, reason); 4971 break; 4972 case WLAN_ROAM_RSO_STOPPED: 4973 status = cm_roam_switch_to_rso_stop(pdev, vdev_id, reason, 4974 send_resp, start_timer); 4975 break; 4976 case WLAN_ROAMING_IN_PROG: 4977 status = cm_roam_switch_to_roam_start(pdev, vdev_id, reason); 4978 break; 4979 case WLAN_ROAM_SYNCH_IN_PROG: 4980 status = cm_roam_switch_to_roam_sync(pdev, vdev_id, reason); 4981 break; 4982 default: 4983 mlme_debug("ROAM: Invalid roam state %d", requested_state); 4984 break; 4985 } 4986 4987 cm_roam_release_lock(vdev); 4988 4989 release_ref: 4990 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 4991 end: 4992 cur_state = mlme_get_roam_state(psoc, vdev_id); 4993 cm_record_state_change(pdev, vdev_id, cur_state, requested_state, 4994 reason, is_up, status); 4995 4996 return status; 4997 } 4998 4999 #ifdef FEATURE_WLAN_ESE 5000 static QDF_STATUS 5001 cm_roam_channels_filter_by_current_band(struct wlan_objmgr_pdev *pdev, 5002 uint8_t vdev_id, 5003 qdf_freq_t *in_chan_freq_list, 5004 uint8_t in_num_chan, 5005 qdf_freq_t *out_chan_freq_list, 5006 uint8_t *merged_num_chan) 5007 { 5008 uint8_t i = 0; 5009 uint8_t num_chan = 0; 5010 uint32_t curr_ap_op_chan_freq = 5011 wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id); 5012 5013 /* Check for NULL pointer */ 5014 if (!in_chan_freq_list) 5015 return QDF_STATUS_E_INVAL; 5016 5017 /* Check for NULL pointer */ 5018 if (!out_chan_freq_list) 5019 return QDF_STATUS_E_INVAL; 5020 5021 if (in_num_chan > CFG_VALID_CHANNEL_LIST_LEN) { 5022 mlme_err("Wrong Number of Input Channels %d", in_num_chan); 5023 return QDF_STATUS_E_INVAL; 5024 } 5025 for (i = 0; i < in_num_chan; i++) { 5026 if (WLAN_REG_IS_SAME_BAND_FREQS(curr_ap_op_chan_freq, 5027 in_chan_freq_list[i])) { 5028 out_chan_freq_list[num_chan] = in_chan_freq_list[i]; 5029 num_chan++; 5030 } 5031 } 5032 5033 /* Return final number of channels */ 5034 *merged_num_chan = num_chan; 5035 5036 return QDF_STATUS_SUCCESS; 5037 } 5038 5039 static QDF_STATUS cm_roam_merge_channel_lists(qdf_freq_t *in_chan_freq_list, 5040 uint8_t in_num_chan, 5041 qdf_freq_t *out_chan_freq_list, 5042 uint8_t out_num_chan, 5043 uint8_t *merged_num_chan) 5044 { 5045 uint8_t i = 0; 5046 uint8_t j = 0; 5047 uint8_t num_chan = out_num_chan; 5048 5049 /* Check for NULL pointer */ 5050 if (!in_chan_freq_list) 5051 return QDF_STATUS_E_INVAL; 5052 5053 /* Check for NULL pointer */ 5054 if (!out_chan_freq_list) 5055 return QDF_STATUS_E_INVAL; 5056 5057 if (in_num_chan > CFG_VALID_CHANNEL_LIST_LEN) { 5058 mlme_err("Wrong Number of Input Channels %d", in_num_chan); 5059 return QDF_STATUS_E_INVAL; 5060 } 5061 if (out_num_chan >= CFG_VALID_CHANNEL_LIST_LEN) { 5062 mlme_err("Wrong Number of Output Channels %d", out_num_chan); 5063 return QDF_STATUS_E_INVAL; 5064 } 5065 /* Add the "new" channels in the input list to the end of the 5066 * output list. 5067 */ 5068 for (i = 0; i < in_num_chan; i++) { 5069 for (j = 0; j < out_num_chan; j++) { 5070 if (in_chan_freq_list[i] == out_chan_freq_list[j]) 5071 break; 5072 } 5073 if (j == out_num_chan) { 5074 if (in_chan_freq_list[i]) { 5075 mlme_debug("Adding extra %d to roam channel list", 5076 in_chan_freq_list[i]); 5077 out_chan_freq_list[num_chan] = 5078 in_chan_freq_list[i]; 5079 num_chan++; 5080 } 5081 } 5082 if (num_chan >= CFG_VALID_CHANNEL_LIST_LEN) { 5083 mlme_debug("Merge Neighbor channel list reached Max limit %d", 5084 in_num_chan); 5085 break; 5086 } 5087 } 5088 5089 /* Return final number of channels */ 5090 *merged_num_chan = num_chan; 5091 5092 return QDF_STATUS_SUCCESS; 5093 } 5094 5095 QDF_STATUS cm_create_roam_scan_channel_list(struct wlan_objmgr_pdev *pdev, 5096 struct rso_config *rso_cfg, 5097 uint8_t vdev_id, 5098 qdf_freq_t *chan_freq_list, 5099 uint8_t num_chan, 5100 const enum band_info band) 5101 { 5102 QDF_STATUS status = QDF_STATUS_SUCCESS; 5103 uint8_t out_num_chan = 0; 5104 uint8_t in_chan_num = num_chan; 5105 qdf_freq_t *in_ptr = chan_freq_list; 5106 uint8_t i = 0; 5107 qdf_freq_t *freq_list; 5108 qdf_freq_t *tmp_chan_freq_list; 5109 uint8_t merged_out_chan_num = 0; 5110 struct rso_chan_info *chan_lst; 5111 struct wlan_objmgr_psoc *psoc; 5112 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5113 struct wlan_mlme_reg *reg; 5114 5115 psoc = wlan_pdev_get_psoc(pdev); 5116 if (!psoc) 5117 return QDF_STATUS_E_INVAL; 5118 5119 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5120 if (!mlme_obj) 5121 return QDF_STATUS_E_INVAL; 5122 5123 reg = &mlme_obj->cfg.reg; 5124 chan_lst = &rso_cfg->roam_scan_freq_lst; 5125 /* 5126 * Create a Union of occupied channel list learnt by the DUT along 5127 * with the Neighbor report Channels. This increases the chances of 5128 * the DUT to get a candidate AP while roaming even if the Neighbor 5129 * Report is not able to provide sufficient information. 5130 */ 5131 if (rso_cfg->occupied_chan_lst.num_chan) { 5132 cm_roam_merge_channel_lists(rso_cfg->occupied_chan_lst.freq_list, 5133 rso_cfg->occupied_chan_lst.num_chan, 5134 in_ptr, in_chan_num, 5135 &merged_out_chan_num); 5136 in_chan_num = merged_out_chan_num; 5137 } 5138 5139 freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN * 5140 sizeof(qdf_freq_t)); 5141 if (!freq_list) 5142 return QDF_STATUS_E_NOMEM; 5143 5144 if (band == BAND_2G) { 5145 for (i = 0; i < in_chan_num; i++) { 5146 if (WLAN_REG_IS_24GHZ_CH_FREQ(in_ptr[i]) && 5147 wlan_roam_is_channel_valid(reg, in_ptr[i])) { 5148 freq_list[out_num_chan++] = in_ptr[i]; 5149 } 5150 } 5151 } else if (band == BAND_5G) { 5152 for (i = 0; i < in_chan_num; i++) { 5153 /* Add 5G Non-DFS channel */ 5154 if (WLAN_REG_IS_5GHZ_CH_FREQ(in_ptr[i]) && 5155 wlan_roam_is_channel_valid(reg, in_ptr[i]) && 5156 !wlan_reg_is_dfs_for_freq(pdev, in_ptr[i])) { 5157 freq_list[out_num_chan++] = in_ptr[i]; 5158 } 5159 } 5160 } else if (band == BAND_ALL) { 5161 for (i = 0; i < in_chan_num; i++) { 5162 if (wlan_roam_is_channel_valid(reg, in_ptr[i]) && 5163 !wlan_reg_is_dfs_for_freq(pdev, in_ptr[i])) { 5164 freq_list[out_num_chan++] = in_ptr[i]; 5165 } 5166 } 5167 } else { 5168 mlme_warn("Invalid band, No operation carried out (Band %d)", 5169 band); 5170 qdf_mem_free(freq_list); 5171 return QDF_STATUS_E_INVAL; 5172 } 5173 5174 tmp_chan_freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN * 5175 sizeof(qdf_freq_t)); 5176 if (!tmp_chan_freq_list) { 5177 qdf_mem_free(freq_list); 5178 return QDF_STATUS_E_NOMEM; 5179 } 5180 5181 /* 5182 * if roaming within band is enabled, then select only the 5183 * in band channels . 5184 * This is required only if the band capability is set to ALL, 5185 * E.g., if band capability is only 2.4G then all the channels in the 5186 * list are already filtered for 2.4G channels, hence ignore this check 5187 */ 5188 if ((band == BAND_ALL) && mlme_obj->cfg.lfr.roam_intra_band) 5189 cm_roam_channels_filter_by_current_band(pdev, vdev_id, 5190 freq_list, out_num_chan, 5191 tmp_chan_freq_list, 5192 &out_num_chan); 5193 5194 /* Prepare final roam scan channel list */ 5195 if (out_num_chan) { 5196 /* Clear the channel list first */ 5197 cm_flush_roam_channel_list(chan_lst); 5198 chan_lst->freq_list = 5199 qdf_mem_malloc(out_num_chan * sizeof(qdf_freq_t)); 5200 if (!chan_lst->freq_list) { 5201 chan_lst->num_chan = 0; 5202 status = QDF_STATUS_E_NOMEM; 5203 goto error; 5204 } 5205 for (i = 0; i < out_num_chan; i++) 5206 chan_lst->freq_list[i] = tmp_chan_freq_list[i]; 5207 5208 chan_lst->num_chan = out_num_chan; 5209 } 5210 5211 error: 5212 qdf_mem_free(tmp_chan_freq_list); 5213 qdf_mem_free(freq_list); 5214 5215 return status; 5216 } 5217 #endif 5218 5219 static const char *cm_get_config_item_string(uint8_t reason) 5220 { 5221 switch (reason) { 5222 CASE_RETURN_STRING(REASON_LOOKUP_THRESH_CHANGED); 5223 CASE_RETURN_STRING(REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED); 5224 CASE_RETURN_STRING(REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED); 5225 CASE_RETURN_STRING(REASON_ROAM_BMISS_FIRST_BCNT_CHANGED); 5226 CASE_RETURN_STRING(REASON_ROAM_BMISS_FINAL_BCNT_CHANGED); 5227 default: 5228 return "unknown"; 5229 } 5230 } 5231 5232 QDF_STATUS cm_neighbor_roam_update_config(struct wlan_objmgr_pdev *pdev, 5233 uint8_t vdev_id, uint8_t value, 5234 uint8_t reason) 5235 { 5236 uint8_t old_value; 5237 struct wlan_objmgr_vdev *vdev; 5238 struct rso_config *rso_cfg; 5239 struct rso_cfg_params *cfg_params; 5240 struct wlan_objmgr_psoc *psoc; 5241 5242 psoc = wlan_pdev_get_psoc(pdev); 5243 if (!psoc) 5244 return QDF_STATUS_E_FAILURE; 5245 5246 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 5247 WLAN_MLME_CM_ID); 5248 if (!vdev) { 5249 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5250 return QDF_STATUS_E_FAILURE; 5251 } 5252 rso_cfg = wlan_cm_get_rso_config(vdev); 5253 if (!rso_cfg) { 5254 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5255 return QDF_STATUS_E_FAILURE; 5256 } 5257 cfg_params = &rso_cfg->cfg_param; 5258 switch (reason) { 5259 case REASON_LOOKUP_THRESH_CHANGED: 5260 old_value = cfg_params->neighbor_lookup_threshold; 5261 cfg_params->neighbor_lookup_threshold = value; 5262 break; 5263 case REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED: 5264 old_value = cfg_params->opportunistic_threshold_diff; 5265 cfg_params->opportunistic_threshold_diff = value; 5266 break; 5267 case REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED: 5268 old_value = cfg_params->roam_rescan_rssi_diff; 5269 cfg_params->roam_rescan_rssi_diff = value; 5270 rso_cfg->rescan_rssi_delta = value; 5271 break; 5272 case REASON_ROAM_BMISS_FIRST_BCNT_CHANGED: 5273 old_value = cfg_params->roam_bmiss_first_bcn_cnt; 5274 cfg_params->roam_bmiss_first_bcn_cnt = value; 5275 break; 5276 case REASON_ROAM_BMISS_FINAL_BCNT_CHANGED: 5277 old_value = cfg_params->roam_bmiss_final_cnt; 5278 cfg_params->roam_bmiss_final_cnt = value; 5279 break; 5280 default: 5281 mlme_debug("Unknown update cfg reason"); 5282 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5283 return QDF_STATUS_E_FAILURE; 5284 } 5285 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5286 mlme_debug("CONNECTED, send update cfg cmd"); 5287 wlan_roam_update_cfg(psoc, vdev_id, reason); 5288 5289 mlme_debug("LFR config for %s changed from %d to %d", 5290 cm_get_config_item_string(reason), old_value, value); 5291 5292 return QDF_STATUS_SUCCESS; 5293 } 5294 5295 void cm_flush_roam_channel_list(struct rso_chan_info *channel_info) 5296 { 5297 /* Free up the memory first (if required) */ 5298 if (channel_info->freq_list) { 5299 qdf_mem_free(channel_info->freq_list); 5300 channel_info->freq_list = NULL; 5301 channel_info->num_chan = 0; 5302 } 5303 } 5304 5305 static void 5306 cm_restore_default_roaming_params(struct wlan_mlme_psoc_ext_obj *mlme_obj, 5307 struct wlan_objmgr_vdev *vdev) 5308 { 5309 struct rso_config *rso_cfg; 5310 struct rso_cfg_params *cfg_params; 5311 uint32_t current_band = REG_BAND_MASK_ALL; 5312 5313 rso_cfg = wlan_cm_get_rso_config(vdev); 5314 if (!rso_cfg) 5315 return; 5316 cfg_params = &rso_cfg->cfg_param; 5317 cfg_params->enable_scoring_for_roam = 5318 mlme_obj->cfg.roam_scoring.enable_scoring_for_roam; 5319 cfg_params->empty_scan_refresh_period = 5320 mlme_obj->cfg.lfr.empty_scan_refresh_period; 5321 cfg_params->full_roam_scan_period = 5322 mlme_obj->cfg.lfr.roam_full_scan_period; 5323 cfg_params->neighbor_scan_period = 5324 mlme_obj->cfg.lfr.neighbor_scan_timer_period; 5325 cfg_params->neighbor_lookup_threshold = 5326 mlme_obj->cfg.lfr.neighbor_lookup_rssi_threshold; 5327 cfg_params->roam_rssi_diff = 5328 mlme_obj->cfg.lfr.roam_rssi_diff; 5329 cfg_params->roam_rssi_diff_6ghz = 5330 mlme_obj->cfg.lfr.roam_rssi_diff_6ghz; 5331 cfg_params->bg_rssi_threshold = 5332 mlme_obj->cfg.lfr.bg_rssi_threshold; 5333 5334 cfg_params->max_chan_scan_time = 5335 mlme_obj->cfg.lfr.neighbor_scan_max_chan_time; 5336 cfg_params->passive_max_chan_time = 5337 mlme_obj->cfg.lfr.passive_max_channel_time; 5338 cfg_params->roam_scan_home_away_time = 5339 mlme_obj->cfg.lfr.roam_scan_home_away_time; 5340 cfg_params->roam_scan_n_probes = 5341 mlme_obj->cfg.lfr.roam_scan_n_probes; 5342 cfg_params->roam_scan_inactivity_time = 5343 mlme_obj->cfg.lfr.roam_scan_inactivity_time; 5344 cfg_params->roam_inactive_data_packet_count = 5345 mlme_obj->cfg.lfr.roam_inactive_data_packet_count; 5346 ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), ¤t_band); 5347 rso_cfg->roam_band_bitmask = current_band; 5348 } 5349 5350 QDF_STATUS cm_roam_control_restore_default_config(struct wlan_objmgr_pdev *pdev, 5351 uint8_t vdev_id) 5352 { 5353 QDF_STATUS status = QDF_STATUS_E_INVAL; 5354 struct rso_chan_info *chan_info; 5355 struct wlan_objmgr_vdev *vdev; 5356 struct rso_config *rso_cfg; 5357 struct rso_cfg_params *cfg_params; 5358 struct wlan_objmgr_psoc *psoc; 5359 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5360 5361 psoc = wlan_pdev_get_psoc(pdev); 5362 if (!psoc) 5363 goto out; 5364 5365 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5366 if (!mlme_obj) 5367 goto out; 5368 5369 if (!mlme_obj->cfg.lfr.roam_scan_offload_enabled) { 5370 mlme_err("roam_scan_offload_enabled is not supported"); 5371 goto out; 5372 } 5373 5374 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 5375 WLAN_MLME_CM_ID); 5376 if (!vdev) { 5377 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5378 goto out; 5379 } 5380 rso_cfg = wlan_cm_get_rso_config(vdev); 5381 if (!rso_cfg) { 5382 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5383 goto out; 5384 } 5385 cfg_params = &rso_cfg->cfg_param; 5386 5387 chan_info = &cfg_params->pref_chan_info; 5388 cm_flush_roam_channel_list(chan_info); 5389 5390 chan_info = &cfg_params->specific_chan_info; 5391 cm_flush_roam_channel_list(chan_info); 5392 5393 mlme_reinit_control_config_lfr_params(psoc, &mlme_obj->cfg.lfr); 5394 5395 cm_restore_default_roaming_params(mlme_obj, vdev); 5396 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5397 5398 if (MLME_IS_ROAM_STATE_RSO_ENABLED(psoc, vdev_id)) { 5399 cm_roam_send_rso_cmd(psoc, vdev_id, 5400 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 5401 REASON_FLUSH_CHANNEL_LIST); 5402 cm_roam_send_rso_cmd(psoc, vdev_id, 5403 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 5404 REASON_SCORING_CRITERIA_CHANGED); 5405 } 5406 5407 status = QDF_STATUS_SUCCESS; 5408 out: 5409 return status; 5410 } 5411 5412 void cm_update_pmk_cache_ft(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 5413 struct wlan_crypto_pmksa *pmk_cache) 5414 { 5415 QDF_STATUS status = QDF_STATUS_E_INVAL; 5416 struct wlan_objmgr_vdev *vdev; 5417 struct wlan_crypto_pmksa pmksa; 5418 enum QDF_OPMODE vdev_mode; 5419 struct cm_roam_values_copy src_cfg; 5420 5421 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5422 WLAN_MLME_CM_ID); 5423 if (!vdev) { 5424 mlme_err("vdev is NULL"); 5425 return; 5426 } 5427 5428 vdev_mode = wlan_vdev_mlme_get_opmode(vdev); 5429 /* If vdev mode is STA then proceed further */ 5430 if (vdev_mode != QDF_STA_MODE) { 5431 mlme_err("vdev mode is not STA"); 5432 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5433 return; 5434 } 5435 5436 /* 5437 * In FT connection fetch the MDID from Session or scan result whichever 5438 * and send it to crypto so that it will update the crypto PMKSA table 5439 * with the MDID for the matching BSSID or SSID PMKSA entry. And delete 5440 * the old/stale PMK cache entries for the same mobility domain as of 5441 * the newly added entry to avoid multiple PMK cache entries for the 5442 * same MDID. 5443 */ 5444 wlan_vdev_get_bss_peer_mac_for_pmksa(vdev, &pmksa.bssid); 5445 wlan_vdev_mlme_get_ssid(vdev, pmksa.ssid, &pmksa.ssid_len); 5446 wlan_cm_roam_cfg_get_value(psoc, vdev_id, MOBILITY_DOMAIN, &src_cfg); 5447 5448 if (pmk_cache) 5449 qdf_mem_copy(pmksa.cache_id, pmk_cache->cache_id, 5450 WLAN_CACHE_ID_LEN); 5451 5452 if (src_cfg.bool_value) { 5453 pmksa.mdid.mdie_present = 1; 5454 pmksa.mdid.mobility_domain = src_cfg.uint_value; 5455 mlme_debug("MDID:0x%x copied to PMKSA", src_cfg.uint_value); 5456 5457 status = wlan_crypto_update_pmk_cache_ft(vdev, &pmksa); 5458 if (QDF_IS_STATUS_ERROR(status)) 5459 mlme_debug("Failed to update the crypto table"); 5460 } 5461 5462 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5463 } 5464 5465 bool cm_lookup_pmkid_using_bssid(struct wlan_objmgr_psoc *psoc, 5466 uint8_t vdev_id, 5467 struct wlan_crypto_pmksa *pmk_cache) 5468 { 5469 struct wlan_crypto_pmksa *pmksa; 5470 struct wlan_objmgr_vdev *vdev; 5471 5472 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5473 WLAN_MLME_CM_ID); 5474 if (!vdev) { 5475 mlme_err("Invalid vdev"); 5476 return false; 5477 } 5478 5479 pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache->bssid); 5480 if (!pmksa) { 5481 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5482 return false; 5483 } 5484 qdf_mem_copy(pmk_cache->pmkid, pmksa->pmkid, sizeof(pmk_cache->pmkid)); 5485 qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len); 5486 pmk_cache->pmk_len = pmksa->pmk_len; 5487 pmk_cache->pmk_lifetime = pmksa->pmk_lifetime; 5488 pmk_cache->pmk_lifetime_threshold = pmksa->pmk_lifetime_threshold; 5489 pmk_cache->pmk_entry_ts = pmksa->pmk_entry_ts; 5490 5491 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5492 5493 return true; 5494 } 5495 5496 void cm_roam_restore_default_config(struct wlan_objmgr_pdev *pdev, 5497 uint8_t vdev_id) 5498 { 5499 struct cm_roam_values_copy src_config = {}; 5500 struct wlan_objmgr_psoc *psoc; 5501 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5502 uint32_t roam_trigger_bitmap; 5503 5504 psoc = wlan_pdev_get_psoc(pdev); 5505 if (!psoc) 5506 return; 5507 5508 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5509 if (!mlme_obj) 5510 return; 5511 5512 if (mlme_obj->cfg.lfr.roam_scan_offload_enabled) { 5513 /* 5514 * When vendor handoff is enabled and disconnection is received, 5515 * then restore the roam trigger bitmap from the ini 5516 * configuration 5517 */ 5518 wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_CONFIG_ENABLE, 5519 &src_config); 5520 if (src_config.bool_value) { 5521 roam_trigger_bitmap = 5522 wlan_mlme_get_roaming_triggers(psoc); 5523 mlme_set_roam_trigger_bitmap(psoc, vdev_id, 5524 roam_trigger_bitmap); 5525 } 5526 5527 src_config.bool_value = 0; 5528 wlan_cm_roam_cfg_set_value(psoc, vdev_id, ROAM_CONFIG_ENABLE, 5529 &src_config); 5530 } 5531 5532 cm_roam_control_restore_default_config(pdev, vdev_id); 5533 } 5534 5535 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 5536 void 5537 cm_store_sae_single_pmk_to_global_cache(struct wlan_objmgr_psoc *psoc, 5538 struct wlan_objmgr_pdev *pdev, 5539 struct wlan_objmgr_vdev *vdev) 5540 { 5541 struct mlme_pmk_info *pmk_info; 5542 struct wlan_crypto_pmksa *pmksa; 5543 struct cm_roam_values_copy src_cfg; 5544 struct qdf_mac_addr bssid; 5545 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5546 int32_t akm; 5547 5548 akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 5549 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 5550 IS_SINGLE_PMK, &src_cfg); 5551 if (!src_cfg.bool_value || 5552 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE)) 5553 return; 5554 /* 5555 * Mark the AP as single PMK capable in Crypto Table 5556 */ 5557 wlan_vdev_get_bss_peer_mac_for_pmksa(vdev, &bssid); 5558 wlan_crypto_set_sae_single_pmk_bss_cap(vdev, &bssid, true); 5559 5560 pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); 5561 if (!pmk_info) 5562 return; 5563 5564 wlan_cm_get_psk_pmk(pdev, vdev_id, pmk_info->pmk, &pmk_info->pmk_len); 5565 5566 pmksa = wlan_crypto_get_pmksa(vdev, &bssid); 5567 if (pmksa) { 5568 pmk_info->spmk_timeout_period = 5569 (pmksa->pmk_lifetime * 5570 pmksa->pmk_lifetime_threshold / 100); 5571 pmk_info->spmk_timestamp = pmksa->pmk_entry_ts; 5572 mlme_debug("spmk_ts:%ld spmk_timeout_prd:%d secs", 5573 pmk_info->spmk_timestamp, 5574 pmk_info->spmk_timeout_period); 5575 } else { 5576 mlme_debug("PMK entry not found for bss:" QDF_MAC_ADDR_FMT, 5577 QDF_MAC_ADDR_REF(bssid.bytes)); 5578 } 5579 5580 wlan_mlme_update_sae_single_pmk(vdev, pmk_info); 5581 5582 qdf_mem_zero(pmk_info, sizeof(*pmk_info)); 5583 qdf_mem_free(pmk_info); 5584 } 5585 5586 void cm_check_and_set_sae_single_pmk_cap(struct wlan_objmgr_psoc *psoc, 5587 uint8_t vdev_id, uint8_t *psk_pmk, 5588 uint8_t pmk_len) 5589 { 5590 struct wlan_objmgr_vdev *vdev; 5591 struct mlme_pmk_info *pmk_info; 5592 struct wlan_crypto_pmksa *pmkid_cache, *roam_sync_pmksa; 5593 int32_t keymgmt; 5594 bool lookup_success; 5595 QDF_STATUS status; 5596 struct qdf_mac_addr bssid = QDF_MAC_ADDR_ZERO_INIT; 5597 5598 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5599 WLAN_MLME_CM_ID); 5600 if (!vdev) { 5601 mlme_err("get vdev failed"); 5602 return; 5603 } 5604 status = wlan_vdev_get_bss_peer_mac_for_pmksa(vdev, &bssid); 5605 if (QDF_IS_STATUS_ERROR(status)) { 5606 mlme_err("Failed to find connected bssid"); 5607 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5608 return; 5609 } 5610 keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 5611 if (keymgmt < 0) { 5612 mlme_err("Invalid mgmt cipher"); 5613 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5614 return; 5615 } 5616 5617 if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE)) { 5618 struct cm_roam_values_copy src_cfg; 5619 5620 wlan_cm_roam_cfg_get_value(psoc, vdev_id, IS_SINGLE_PMK, 5621 &src_cfg); 5622 wlan_mlme_set_sae_single_pmk_bss_cap(psoc, vdev_id, 5623 src_cfg.bool_value); 5624 if (!src_cfg.bool_value) 5625 goto end; 5626 5627 roam_sync_pmksa = qdf_mem_malloc(sizeof(*roam_sync_pmksa)); 5628 if (roam_sync_pmksa) { 5629 qdf_copy_macaddr(&roam_sync_pmksa->bssid, &bssid); 5630 roam_sync_pmksa->single_pmk_supported = true; 5631 roam_sync_pmksa->pmk_len = pmk_len; 5632 qdf_mem_copy(roam_sync_pmksa->pmk, psk_pmk, 5633 roam_sync_pmksa->pmk_len); 5634 mlme_debug("SPMK received for " QDF_MAC_ADDR_FMT "pmk_len:%d", 5635 QDF_MAC_ADDR_REF(roam_sync_pmksa->bssid.bytes), 5636 roam_sync_pmksa->pmk_len); 5637 /* update single pmk info for roamed ap to pmk table */ 5638 wlan_crypto_set_sae_single_pmk_info(vdev, 5639 roam_sync_pmksa); 5640 5641 qdf_mem_zero(roam_sync_pmksa, sizeof(*roam_sync_pmksa)); 5642 qdf_mem_free(roam_sync_pmksa); 5643 } else { 5644 goto end; 5645 } 5646 5647 pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); 5648 if (!pmkid_cache) 5649 goto end; 5650 5651 qdf_copy_macaddr(&pmkid_cache->bssid, &bssid); 5652 /* 5653 * In SAE single pmk roaming case, there will 5654 * be no PMK entry found for the AP in pmk cache. 5655 * So if the lookup is successful, then we have done 5656 * a FULL sae here. In that case, clear all other 5657 * single pmk entries. 5658 */ 5659 lookup_success = 5660 cm_lookup_pmkid_using_bssid(psoc, vdev_id, pmkid_cache); 5661 if (lookup_success) { 5662 wlan_crypto_selective_clear_sae_single_pmk_entries(vdev, 5663 &bssid); 5664 5665 pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); 5666 if (!pmk_info) { 5667 qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); 5668 qdf_mem_free(pmkid_cache); 5669 goto end; 5670 } 5671 5672 qdf_mem_copy(pmk_info->pmk, pmkid_cache->pmk, 5673 pmkid_cache->pmk_len); 5674 pmk_info->pmk_len = pmkid_cache->pmk_len; 5675 pmk_info->spmk_timestamp = pmkid_cache->pmk_entry_ts; 5676 pmk_info->spmk_timeout_period = 5677 (pmkid_cache->pmk_lifetime * 5678 pmkid_cache->pmk_lifetime_threshold / 100); 5679 5680 wlan_mlme_update_sae_single_pmk(vdev, pmk_info); 5681 5682 qdf_mem_zero(pmk_info, sizeof(*pmk_info)); 5683 qdf_mem_free(pmk_info); 5684 } 5685 5686 qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); 5687 qdf_mem_free(pmkid_cache); 5688 } 5689 5690 end: 5691 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5692 } 5693 #endif 5694 5695 bool cm_is_auth_type_11r(struct wlan_mlme_psoc_ext_obj *mlme_obj, 5696 struct wlan_objmgr_vdev *vdev, 5697 bool mdie_present) 5698 { 5699 int32_t akm; 5700 5701 akm = wlan_crypto_get_param(vdev, 5702 WLAN_CRYPTO_PARAM_KEY_MGMT); 5703 5704 if (cm_is_open_mode(vdev)) { 5705 if (mdie_present && mlme_obj->cfg.lfr.enable_ftopen) 5706 return true; 5707 } else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384) || 5708 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) || 5709 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) || 5710 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) || 5711 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK) || 5712 QDF_HAS_PARAM(akm, 5713 WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) || 5714 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) { 5715 return true; 5716 } 5717 5718 return false; 5719 } 5720 5721 #ifdef FEATURE_WLAN_ESE 5722 bool 5723 cm_ese_open_present(struct wlan_objmgr_vdev *vdev, 5724 struct wlan_mlme_psoc_ext_obj *mlme_obj, 5725 bool ese_version_present) 5726 { 5727 if (cm_is_open_mode(vdev) && ese_version_present && 5728 mlme_obj->cfg.lfr.ese_enabled) 5729 return true; 5730 5731 return false; 5732 } 5733 5734 bool 5735 cm_is_ese_connection(struct wlan_objmgr_vdev *vdev, bool ese_version_present) 5736 { 5737 int32_t akm; 5738 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5739 struct wlan_objmgr_psoc *psoc; 5740 5741 psoc = wlan_vdev_get_psoc(vdev); 5742 if (!psoc) { 5743 mlme_err("psoc not found"); 5744 return false; 5745 } 5746 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5747 if (!mlme_obj) 5748 return false; 5749 5750 if (!mlme_obj->cfg.lfr.ese_enabled) 5751 return false; 5752 5753 akm = wlan_crypto_get_param(vdev, 5754 WLAN_CRYPTO_PARAM_KEY_MGMT); 5755 5756 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) 5757 return true; 5758 5759 /* 5760 * A profile can not be both ESE and 11R. But an 802.11R AP 5761 * may be advertising support for ESE as well. So if we are 5762 * associating Open or explicitly ESE then we will get ESE. 5763 * If we are associating explicitly 11R only then we will get 5764 * 11R. 5765 */ 5766 return cm_ese_open_present(vdev, mlme_obj, ese_version_present); 5767 } 5768 #endif 5769 5770 static void cm_roam_start_init(struct wlan_objmgr_psoc *psoc, 5771 struct wlan_objmgr_pdev *pdev, 5772 struct wlan_objmgr_vdev *vdev) 5773 { 5774 struct cm_roam_values_copy src_cfg = {}; 5775 bool mdie_present; 5776 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5777 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5778 enum QDF_OPMODE opmode; 5779 5780 opmode = wlan_vdev_mlme_get_opmode(vdev); 5781 if (opmode != QDF_STA_MODE) { 5782 mlme_debug("Wrong opmode %d", opmode); 5783 return; 5784 } 5785 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5786 if (!mlme_obj) 5787 return; 5788 5789 wlan_cm_init_occupied_ch_freq_list(pdev, psoc, vdev_id); 5790 5791 /* 5792 * Update RSSI change params to vdev 5793 */ 5794 src_cfg.uint_value = mlme_obj->cfg.lfr.roam_rescan_rssi_diff; 5795 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5796 RSSI_CHANGE_THRESHOLD, &src_cfg); 5797 5798 src_cfg.uint_value = mlme_obj->cfg.lfr.roam_scan_hi_rssi_delay; 5799 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5800 HI_RSSI_DELAY_BTW_SCANS, &src_cfg); 5801 5802 wlan_cm_update_roam_scan_scheme_bitmap(psoc, vdev_id, 5803 DEFAULT_ROAM_SCAN_SCHEME_BITMAP); 5804 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 5805 MOBILITY_DOMAIN, &src_cfg); 5806 5807 mdie_present = src_cfg.bool_value; 5808 /* Based on the auth scheme tell if we are 11r */ 5809 if (cm_is_auth_type_11r(mlme_obj, vdev, mdie_present)) { 5810 src_cfg.bool_value = true; 5811 } else { 5812 src_cfg.bool_value = false; 5813 } 5814 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5815 IS_11R_CONNECTION, &src_cfg); 5816 5817 src_cfg.uint_value = mlme_obj->cfg.lfr.roam_rssi_diff_6ghz; 5818 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5819 ROAM_RSSI_DIFF_6GHZ, &src_cfg); 5820 5821 if (!mlme_obj->cfg.lfr.roam_scan_offload_enabled) 5822 return; 5823 /* 5824 * Store the current PMK info of the AP 5825 * to the single pmk global cache if the BSS allows 5826 * single pmk roaming capable. 5827 */ 5828 cm_store_sae_single_pmk_to_global_cache(psoc, pdev, vdev); 5829 5830 if (!MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id)) { 5831 wlan_clear_sae_auth_logs_cache(psoc, vdev_id); 5832 wlan_cm_roam_state_change(pdev, vdev_id, 5833 WLAN_ROAM_RSO_ENABLED, 5834 REASON_CTX_INIT); 5835 } 5836 } 5837 5838 void cm_roam_start_init_on_connect(struct wlan_objmgr_pdev *pdev, 5839 uint8_t vdev_id) 5840 { 5841 struct wlan_objmgr_vdev *vdev; 5842 struct wlan_objmgr_psoc *psoc; 5843 5844 psoc = wlan_pdev_get_psoc(pdev); 5845 if (!psoc) 5846 return; 5847 5848 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 5849 WLAN_MLME_CM_ID); 5850 if (!vdev) { 5851 mlme_err("vdev_id: %d: vdev not found", vdev_id); 5852 return; 5853 } 5854 cm_roam_start_init(psoc, pdev, vdev); 5855 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5856 } 5857 5858 void cm_update_session_assoc_ie(struct wlan_objmgr_psoc *psoc, 5859 uint8_t vdev_id, 5860 struct element_info *assoc_ie) 5861 { 5862 struct rso_config *rso_cfg; 5863 struct wlan_objmgr_vdev *vdev; 5864 5865 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5866 WLAN_MLME_CM_ID); 5867 if (!vdev) { 5868 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5869 return; 5870 } 5871 rso_cfg = wlan_cm_get_rso_config(vdev); 5872 if (!rso_cfg) 5873 goto rel_vdev_ref; 5874 5875 if (rso_cfg->assoc_ie.ptr) { 5876 qdf_mem_free(rso_cfg->assoc_ie.ptr); 5877 rso_cfg->assoc_ie.ptr = NULL; 5878 rso_cfg->assoc_ie.len = 0; 5879 } 5880 if (!assoc_ie->len) { 5881 sme_debug("Assoc IE len 0"); 5882 goto rel_vdev_ref; 5883 } 5884 rso_cfg->assoc_ie.ptr = qdf_mem_malloc(assoc_ie->len); 5885 if (!rso_cfg->assoc_ie.ptr) 5886 goto rel_vdev_ref; 5887 5888 rso_cfg->assoc_ie.len = assoc_ie->len; 5889 qdf_mem_copy(rso_cfg->assoc_ie.ptr, assoc_ie->ptr, assoc_ie->len); 5890 rel_vdev_ref: 5891 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5892 } 5893 5894 /** 5895 * cm_dlm_is_bssid_in_reject_list() - Check whether a BSSID is present in 5896 * reject list or not 5897 * @psoc: psoc pointer 5898 * @bssid: bssid to check 5899 * @vdev_id: vdev id 5900 * 5901 * Return: true if BSSID is present in reject list 5902 */ 5903 static bool cm_dlm_is_bssid_in_reject_list(struct wlan_objmgr_psoc *psoc, 5904 struct qdf_mac_addr *bssid, 5905 uint8_t vdev_id) 5906 { 5907 struct wlan_objmgr_vdev *vdev; 5908 struct wlan_objmgr_pdev *pdev; 5909 bool is_bssid_in_reject_list = false; 5910 5911 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5912 WLAN_MLME_CM_ID); 5913 if (!vdev) { 5914 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5915 return is_bssid_in_reject_list; 5916 } 5917 5918 pdev = wlan_vdev_get_pdev(vdev); 5919 if (!pdev) 5920 goto rel_vdev_ref; 5921 5922 is_bssid_in_reject_list = 5923 wlan_dlm_is_bssid_in_reject_list(pdev, bssid); 5924 5925 rel_vdev_ref: 5926 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5927 5928 return is_bssid_in_reject_list; 5929 } 5930 5931 QDF_STATUS cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc, 5932 struct wlan_objmgr_vdev *vdev, 5933 struct qdf_mac_addr *bssid, 5934 qdf_freq_t chan_freq, 5935 enum wlan_cm_source source) 5936 { 5937 struct cm_req *cm_req; 5938 QDF_STATUS status; 5939 uint8_t roam_control_bitmap; 5940 struct qdf_mac_addr connected_bssid; 5941 uint8_t vdev_id = vdev->vdev_objmgr.vdev_id; 5942 bool roam_offload_enabled = cm_roam_offload_enabled(psoc); 5943 struct rso_config *rso_cfg; 5944 5945 roam_control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id); 5946 if (roam_offload_enabled && (roam_control_bitmap || 5947 !MLME_IS_ROAM_INITIALIZED(psoc, vdev_id))) { 5948 mlme_debug("ROAM: RSO Disabled internally: vdev[%d] bitmap[0x%x]", 5949 vdev_id, roam_control_bitmap); 5950 return QDF_STATUS_E_FAILURE; 5951 } 5952 5953 cm_req = qdf_mem_malloc(sizeof(*cm_req)); 5954 if (!cm_req) 5955 return QDF_STATUS_E_NOMEM; 5956 5957 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 5958 mlme_err("MLO ROAM: Invalid Roam req on link vdev %d", vdev_id); 5959 qdf_mem_free(cm_req); 5960 return QDF_STATUS_E_FAILURE; 5961 } 5962 5963 rso_cfg = wlan_cm_get_rso_config(vdev); 5964 if (!rso_cfg) 5965 return QDF_STATUS_E_NULL_VALUE; 5966 5967 /* Ignore BSSID and channel validation for FW host roam */ 5968 if (source == CM_ROAMING_FW) 5969 goto send_evt; 5970 if (source == CM_ROAMING_LINK_REMOVAL) { 5971 cm_req->roam_req.req.forced_roaming = true; 5972 goto send_evt; 5973 } 5974 5975 if (cm_dlm_is_bssid_in_reject_list(psoc, bssid, vdev_id)) { 5976 mlme_debug("BSSID is in reject list, aborting roam invoke"); 5977 qdf_mem_free(cm_req); 5978 return QDF_STATUS_E_FAILURE; 5979 } 5980 5981 if (qdf_is_macaddr_zero(bssid)) { 5982 if (!wlan_mlme_is_data_stall_recovery_fw_supported(psoc)) { 5983 mlme_debug("FW does not support data stall recovery, aborting roam invoke"); 5984 qdf_mem_free(cm_req); 5985 return QDF_STATUS_E_NOSUPPORT; 5986 } 5987 5988 cm_req->roam_req.req.forced_roaming = true; 5989 if (source == CM_ROAMING_HOST || source == CM_ROAMING_USER) 5990 rso_cfg->is_forced_roaming = true; 5991 source = CM_ROAMING_NUD_FAILURE; 5992 goto send_evt; 5993 } 5994 5995 if (qdf_is_macaddr_broadcast(bssid)) { 5996 qdf_copy_macaddr(&cm_req->roam_req.req.bssid, bssid); 5997 qdf_copy_macaddr(&rso_cfg->roam_invoke_bssid, bssid); 5998 mlme_debug("Roam only if better candidate found else stick to current AP"); 5999 goto send_evt; 6000 } 6001 6002 wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid); 6003 if (qdf_is_macaddr_equal(bssid, &connected_bssid)) { 6004 mlme_debug("Reassoc BSSID is same as currently associated AP"); 6005 chan_freq = wlan_get_operation_chan_freq(vdev); 6006 } 6007 6008 if (!chan_freq || qdf_is_macaddr_zero(bssid)) { 6009 mlme_debug("bssid " QDF_MAC_ADDR_FMT " chan_freq %d", 6010 QDF_MAC_ADDR_REF(bssid->bytes), chan_freq); 6011 qdf_mem_free(cm_req); 6012 return QDF_STATUS_E_FAILURE; 6013 } 6014 6015 qdf_copy_macaddr(&cm_req->roam_req.req.bssid, bssid); 6016 cm_req->roam_req.req.chan_freq = chan_freq; 6017 6018 send_evt: 6019 cm_req->roam_req.req.source = source; 6020 6021 /* Storing source information in rso cfg as if FW aborts 6022 * roam host will delete roam req from queue. 6023 * In roam invoke failure, host will read rso cfg params 6024 * information and disconnect if needed. 6025 */ 6026 if (source == CM_ROAMING_HOST || 6027 source == CM_ROAMING_NUD_FAILURE || 6028 source == CM_ROAMING_LINK_REMOVAL || 6029 source == CM_ROAMING_USER) 6030 rso_cfg->roam_invoke_source = source; 6031 6032 cm_req->roam_req.req.vdev_id = vdev_id; 6033 /* 6034 * For LFR3 WLAN_CM_SM_EV_ROAM_REQ will be converted to 6035 * WLAN_CM_SM_EV_ROAM_INVOKE. 6036 */ 6037 status = cm_sm_deliver_event(vdev, WLAN_CM_SM_EV_ROAM_REQ, 6038 sizeof(*cm_req), cm_req); 6039 6040 if (QDF_IS_STATUS_ERROR(status)) 6041 qdf_mem_free(cm_req); 6042 6043 return status; 6044 } 6045 6046 #if (defined(CONNECTIVITY_DIAG_EVENT) || \ 6047 defined(WLAN_FEATURE_CONNECTIVITY_LOGGING)) && \ 6048 defined(WLAN_FEATURE_ROAM_OFFLOAD) 6049 static 6050 bool wlan_is_valid_frequency(uint32_t freq, uint32_t band_capability, 6051 uint32_t band_mask) 6052 { 6053 if ((band_capability == BIT(REG_BAND_5G) || 6054 band_mask == BIT(REG_BAND_5G) || 6055 band_capability == BIT(REG_BAND_6G) || 6056 band_mask == BIT(REG_BAND_6G)) && 6057 WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 6058 return false; 6059 6060 if ((band_capability == BIT(REG_BAND_2G) || 6061 band_mask == BIT(REG_BAND_2G)) && 6062 !WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 6063 return false; 6064 6065 return true; 6066 } 6067 6068 static 6069 void cm_roam_send_beacon_loss_event(struct wlan_objmgr_psoc *psoc, 6070 struct qdf_mac_addr bssid, 6071 uint8_t vdev_id, 6072 uint8_t trig_reason, 6073 uint8_t is_roam_success, 6074 bool is_full_scan, 6075 uint8_t roam_fail_reason) 6076 { 6077 bool bmiss_skip_full_scan = false; 6078 6079 /* 6080 * When roam trigger reason is Beacon Miss, 2 roam scan 6081 * stats TLV will be received with reason as BMISS. 6082 * 1. First TLV is for partial roam scan data and 6083 * 2. Second TLV is for the full scan data when there is no candidate 6084 * found in the partial scan. 6085 * When bmiss_skip_full_scan flag is disabled, prints for 1 & 2 will be 6086 * seen. 6087 * when bmiss_skip_full_scan flag is enabled, only print for 1st TLV 6088 * will be seen. 6089 * 6090 * 1. BMISS_DISCONN event should be triggered only once for BMISS roam 6091 * trigger if roam result is failure after full scan TLV is received and 6092 * bmiss_skip_full_scan is disabled. 6093 * 6094 * 2. But if bmiss_skip_full_scan is enabled, then trigger 6095 * BMISS_DISCONN event after partial scan TLV is received 6096 * 6097 * 3. In some cases , Keepalive ACK from AP might come after the 6098 * final BMISS and FW can choose to stay connected to the current AP. 6099 * In this case, don't send discon event. 6100 */ 6101 6102 wlan_mlme_get_bmiss_skip_full_scan_value(psoc, &bmiss_skip_full_scan); 6103 6104 if (trig_reason == ROAM_TRIGGER_REASON_BMISS && 6105 !is_roam_success && 6106 ((!bmiss_skip_full_scan && is_full_scan) || 6107 (bmiss_skip_full_scan && !is_full_scan)) && 6108 (roam_fail_reason == 6109 ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT || 6110 roam_fail_reason == 6111 ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT)) 6112 cm_roam_beacon_loss_disconnect_event(psoc, bssid, vdev_id); 6113 } 6114 #endif 6115 6116 #if defined(CONNECTIVITY_DIAG_EVENT) && \ 6117 defined(WLAN_FEATURE_ROAM_OFFLOAD) 6118 static enum diag_roam_reason 6119 cm_get_diag_roam_reason(enum roam_trigger_reason roam_reason) 6120 { 6121 switch (roam_reason) { 6122 case ROAM_TRIGGER_REASON_PER: 6123 return DIAG_ROAM_REASON_PER; 6124 case ROAM_TRIGGER_REASON_BMISS: 6125 return DIAG_ROAM_REASON_BEACON_MISS; 6126 case ROAM_TRIGGER_REASON_LOW_RSSI: 6127 return DIAG_ROAM_REASON_POOR_RSSI; 6128 case ROAM_TRIGGER_REASON_HIGH_RSSI: 6129 return DIAG_ROAM_REASON_BETTER_RSSI; 6130 case ROAM_TRIGGER_REASON_PERIODIC: 6131 return DIAG_ROAM_REASON_PERIODIC_TIMER; 6132 case ROAM_TRIGGER_REASON_DENSE: 6133 return DIAG_ROAM_REASON_CONGESTION; 6134 case ROAM_TRIGGER_REASON_BACKGROUND: 6135 return DIAG_ROAM_REASON_BACKGROUND_SCAN; 6136 case ROAM_TRIGGER_REASON_FORCED: 6137 return DIAG_ROAM_REASON_USER_TRIGGER; 6138 case ROAM_TRIGGER_REASON_BTM: 6139 return DIAG_ROAM_REASON_BTM; 6140 case ROAM_TRIGGER_REASON_BSS_LOAD: 6141 return DIAG_ROAM_REASON_BSS_LOAD; 6142 case ROAM_TRIGGER_REASON_DEAUTH: 6143 return DIAG_ROAM_REASON_DISCONNECTION; 6144 case ROAM_TRIGGER_REASON_IDLE: 6145 return DIAG_ROAM_REASON_IDLE; 6146 case ROAM_TRIGGER_REASON_WTC_BTM: 6147 return DIAG_ROAM_REASON_WTC; 6148 case ROAM_TRIGGER_REASON_BTC: 6149 return DIAG_ROAM_REASON_BT_ACTIVITY; 6150 default: 6151 break; 6152 } 6153 6154 return DIAG_ROAM_REASON_UNKNOWN; 6155 } 6156 6157 static enum diag_roam_sub_reason 6158 cm_get_diag_roam_sub_reason(enum roam_trigger_sub_reason sub_reason) 6159 { 6160 switch (sub_reason) { 6161 case ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 6162 return DIAG_ROAM_SUB_REASON_PERIODIC_TIMER; 6163 6164 case ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI: 6165 return DIAG_ROAM_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 6166 6167 case ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 6168 return DIAG_ROAM_SUB_REASON_BTM_DI_TIMER; 6169 6170 case ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 6171 return DIAG_ROAM_SUB_REASON_FULL_SCAN; 6172 6173 case ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 6174 return DIAG_ROAM_SUB_REASON_LOW_RSSI_PERIODIC; 6175 6176 case ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 6177 return DIAG_ROAM_SUB_REASON_CU_PERIODIC; 6178 6179 case ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 6180 return DIAG_ROAM_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_LOW_RSSI; 6181 6182 case ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 6183 return DIAG_ROAM_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 6184 6185 case ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 6186 return DIAG_ROAM_SUB_REASON_INACTIVITY_TIMER_CU; 6187 6188 default: 6189 break; 6190 } 6191 6192 return DIAG_ROAM_SUB_REASON_UNKNOWN; 6193 } 6194 6195 6196 static void populate_diag_cmn(struct wlan_connectivity_log_diag_cmn *cmn, 6197 uint8_t vdev_id, uint64_t fw_timestamp, 6198 struct qdf_mac_addr *bssid) 6199 { 6200 cmn->vdev_id = vdev_id; 6201 cmn->timestamp_us = qdf_get_time_of_the_day_us(); 6202 cmn->ktime_us = qdf_ktime_to_us(qdf_ktime_get()); 6203 cmn->fw_timestamp = fw_timestamp * 1000; 6204 6205 if (!bssid) 6206 return; 6207 6208 qdf_mem_copy(cmn->bssid, bssid->bytes, QDF_MAC_ADDR_SIZE); 6209 } 6210 6211 void cm_roam_scan_info_event(struct wlan_objmgr_psoc *psoc, 6212 struct wmi_roam_scan_data *scan, uint8_t vdev_id) 6213 { 6214 int i; 6215 struct wmi_roam_candidate_info *ap = scan->ap; 6216 uint32_t *chan_freq = NULL; 6217 uint8_t count = 0, status, num_chan; 6218 uint32_t band_capability = 0, band_mask = 0; 6219 struct wlan_diag_roam_scan_done *wlan_diag_event = NULL; 6220 6221 wlan_diag_event = qdf_mem_malloc(sizeof(*wlan_diag_event)); 6222 if (!wlan_diag_event) { 6223 mlme_err("Mem malloc failed for wlan_diag_event"); 6224 return; 6225 } 6226 6227 chan_freq = qdf_mem_malloc(sizeof(uint32_t) * NUM_CHANNELS); 6228 if (!chan_freq) { 6229 qdf_mem_free(wlan_diag_event); 6230 mlme_err("Mem malloc failed for chan_freq"); 6231 return; 6232 } 6233 6234 populate_diag_cmn(&wlan_diag_event->diag_cmn, vdev_id, 6235 (uint64_t)scan->scan_complete_timestamp, &ap->bssid); 6236 6237 wlan_diag_event->version = DIAG_SCAN_DONE_VERSION; 6238 6239 /* 6240 * scan->num_ap includes current connected AP also 6241 * so subtract 1 from the count to get total candidate APs 6242 */ 6243 6244 if (scan->num_ap) 6245 wlan_diag_event->cand_ap_count = scan->num_ap - 1; 6246 6247 if (scan->type == ROAM_STATS_SCAN_TYPE_FULL && scan->present) { 6248 status = mlme_get_fw_scan_channels(psoc, chan_freq, &num_chan); 6249 if (QDF_IS_STATUS_ERROR(status)) 6250 goto out; 6251 if (num_chan > NUM_CHANNELS) { 6252 mlme_err("unexpected num chan %d", num_chan); 6253 goto out; 6254 } 6255 6256 status = wlan_mlme_get_band_capability(psoc, &band_capability); 6257 if (QDF_IS_STATUS_ERROR(status)) 6258 goto out; 6259 6260 band_mask = 6261 policy_mgr_get_connected_roaming_vdev_band_mask(psoc, 6262 vdev_id); 6263 6264 num_chan = QDF_MIN(WLAN_MAX_LOGGING_FREQ, NUM_CHANNELS); 6265 6266 for (i = 0; i < num_chan; i++) { 6267 if (!wlan_is_valid_frequency(chan_freq[i], 6268 band_capability, 6269 band_mask)) 6270 continue; 6271 6272 wlan_diag_event->scan_freq[count] = chan_freq[i]; 6273 count++; 6274 } 6275 6276 wlan_diag_event->num_scanned_freq = count; 6277 } else { 6278 if (scan->num_chan > MAX_ROAM_SCAN_CHAN) 6279 scan->num_chan = MAX_ROAM_SCAN_CHAN; 6280 6281 wlan_diag_event->num_scanned_freq = scan->num_chan; 6282 for (i = 0; i < scan->num_chan; i++) 6283 wlan_diag_event->scan_freq[i] = scan->chan_freq[i]; 6284 } 6285 6286 wlan_diag_event->btcoex_active = scan->is_btcoex_active; 6287 6288 out: 6289 WLAN_HOST_DIAG_EVENT_REPORT(wlan_diag_event, 6290 EVENT_WLAN_ROAM_SCAN_DONE); 6291 qdf_mem_free(chan_freq); 6292 qdf_mem_free(wlan_diag_event); 6293 } 6294 6295 void cm_roam_trigger_info_event(struct wmi_roam_trigger_info *data, 6296 struct wmi_roam_scan_data *scan_data, 6297 uint8_t vdev_id, bool is_full_scan) 6298 { 6299 uint8_t i; 6300 6301 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6302 struct wlan_diag_roam_scan_start); 6303 6304 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6305 6306 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6307 (uint64_t)data->timestamp, NULL); 6308 6309 wlan_diag_event.trigger_reason = 6310 cm_get_diag_roam_reason(data->trigger_reason); 6311 6312 wlan_diag_event.trigger_sub_reason = 6313 cm_get_diag_roam_sub_reason(data->trigger_sub_reason); 6314 6315 wlan_diag_event.version = DIAG_ROAM_SCAN_START_VERSION_V2; 6316 6317 /* 6318 * Get the current AP rssi & CU load from the 6319 * wmi_roam_ap_info tlv in roam scan results 6320 */ 6321 if (scan_data->present) { 6322 for (i = 0; i < scan_data->num_ap; i++) { 6323 if (i >= MAX_ROAM_CANDIDATE_AP) 6324 break; 6325 6326 if (scan_data->ap[i].type == 6327 WLAN_ROAM_SCAN_CURRENT_AP) { 6328 wlan_diag_event.rssi = 6329 (-1) * scan_data->ap[i].rssi; 6330 wlan_diag_event.cu = 6331 scan_data->ap[i].cu_load; 6332 break; 6333 } 6334 } 6335 } 6336 6337 if (data->trigger_reason == ROAM_TRIGGER_REASON_PERIODIC || 6338 data->trigger_reason == ROAM_TRIGGER_REASON_LOW_RSSI) { 6339 if (data->common_roam) 6340 wlan_diag_event.rssi_thresh = 6341 (-1) * data->low_rssi_trig_data.roam_rssi_threshold; 6342 else 6343 wlan_diag_event.rssi_thresh = 6344 (-1) * data->rssi_trig_data.threshold; 6345 } 6346 6347 wlan_diag_event.is_full_scan = is_full_scan; 6348 wlan_diag_event.band = scan_data->band; 6349 6350 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, 6351 EVENT_WLAN_ROAM_SCAN_START); 6352 } 6353 6354 #define ETP_MAX_VALUE 10000000 6355 6356 void cm_roam_candidate_info_event(struct wmi_roam_candidate_info *ap, 6357 uint8_t cand_ap_idx) 6358 { 6359 uint32_t etp; 6360 6361 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6362 struct wlan_diag_roam_candidate_info); 6363 6364 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6365 6366 populate_diag_cmn(&wlan_diag_event.diag_cmn, 0, (uint64_t)ap->timestamp, 6367 &ap->bssid); 6368 6369 wlan_diag_event.is_current_ap = (ap->type == 1); 6370 if (wlan_diag_event.is_current_ap) 6371 wlan_diag_event.subtype = 6372 WLAN_CONN_DIAG_ROAM_SCORE_CUR_AP_EVENT; 6373 else 6374 wlan_diag_event.subtype = 6375 WLAN_CONN_DIAG_ROAM_SCORE_CAND_AP_EVENT; 6376 6377 wlan_diag_event.version = DIAG_ROAM_CAND_VERSION_V2; 6378 wlan_diag_event.rssi = (-1) * ap->rssi; 6379 wlan_diag_event.cu_load = ap->cu_load; 6380 wlan_diag_event.total_score = ap->total_score; 6381 6382 etp = ap->etp * 1000; 6383 6384 if (etp > ETP_MAX_VALUE) 6385 wlan_diag_event.etp = ETP_MAX_VALUE; 6386 else 6387 wlan_diag_event.etp = etp; 6388 6389 wlan_diag_event.idx = cand_ap_idx; 6390 wlan_diag_event.freq = ap->freq; 6391 wlan_diag_event.is_mlo = ap->is_mlo; 6392 6393 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, 6394 EVENT_WLAN_ROAM_CAND_INFO); 6395 } 6396 6397 #define WLAN_ROAM_SCAN_TYPE_PARTIAL_SCAN 0 6398 #define WLAN_ROAM_SCAN_TYPE_FULL_SCAN 1 6399 6400 #ifdef WLAN_FEATURE_11BE_MLO 6401 static void 6402 cm_populate_roam_success_mlo_param(struct wlan_objmgr_psoc *psoc, 6403 struct wlan_diag_roam_result *event, 6404 uint8_t vdev_id) 6405 { 6406 struct wlan_objmgr_vdev *vdev = NULL; 6407 struct wlan_objmgr_vdev *assoc_vdev = NULL; 6408 struct qdf_mac_addr bss_peer; 6409 QDF_STATUS status; 6410 6411 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 6412 WLAN_MLME_CM_ID); 6413 if (!vdev) { 6414 mlme_err("vdev: %d not found", vdev_id); 6415 return; 6416 } 6417 6418 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) 6419 goto out; 6420 6421 event->is_mlo = true; 6422 6423 assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev); 6424 if (!assoc_vdev) { 6425 mlme_err("assoc vdev not found"); 6426 goto out; 6427 } 6428 6429 status = wlan_vdev_get_bss_peer_mac(assoc_vdev, 6430 &bss_peer); 6431 if (QDF_IS_STATUS_ERROR(status)) { 6432 mlme_err("vdev: %d bss peer not found", 6433 wlan_vdev_get_id(assoc_vdev)); 6434 goto out; 6435 } 6436 6437 qdf_mem_copy(event->diag_cmn.bssid, 6438 bss_peer.bytes, QDF_MAC_ADDR_SIZE); 6439 6440 out: 6441 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 6442 } 6443 #else 6444 static void 6445 cm_populate_roam_success_mlo_param(struct wlan_objmgr_psoc *psoc, 6446 struct wlan_diag_roam_result *event, 6447 uint8_t vdev_id) 6448 { 6449 } 6450 #endif 6451 6452 void cm_roam_result_info_event(struct wlan_objmgr_psoc *psoc, 6453 struct wmi_roam_trigger_info *trigger, 6454 struct wmi_roam_result *res, 6455 struct wmi_roam_scan_data *scan_data, 6456 uint8_t vdev_id) 6457 { 6458 uint8_t i; 6459 struct qdf_mac_addr bssid = {0}; 6460 bool ap_found_in_roam_scan = false; 6461 bool roam_abort = (res->fail_reason == ROAM_FAIL_REASON_SYNC || 6462 res->fail_reason == ROAM_FAIL_REASON_DISCONNECT || 6463 res->fail_reason == ROAM_FAIL_REASON_HOST || 6464 res->fail_reason == 6465 ROAM_FAIL_REASON_INTERNAL_ABORT || 6466 res->fail_reason == 6467 ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO); 6468 bool is_full_scan = (scan_data->present && 6469 scan_data->type == WLAN_ROAM_SCAN_TYPE_FULL_SCAN); 6470 6471 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6472 struct wlan_diag_roam_result); 6473 6474 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6475 6476 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6477 (uint64_t)res->timestamp, NULL); 6478 6479 for (i = 0; i < scan_data->num_ap && scan_data->present; i++) { 6480 if (i >= MAX_ROAM_CANDIDATE_AP) 6481 break; 6482 6483 if (scan_data->ap[i].type == WLAN_ROAM_SCAN_ROAMED_AP || 6484 scan_data->ap[i].type == WLAN_ROAM_SCAN_CANDIDATE_AP) { 6485 ap_found_in_roam_scan = true; 6486 break; 6487 } 6488 } 6489 6490 wlan_diag_event.version = DIAG_ROAM_RESULT_VERSION; 6491 wlan_diag_event.roam_fail_reason = res->fail_reason; 6492 /* 6493 * Print ROAM if: 6494 * 1. Roaming is successful to AP 6495 * 2. Atleast one candidate AP found during scan 6496 * 6497 * Print NO_ROAM only if: 6498 * 1. No candidate AP found(even though other APs are found in scan) 6499 */ 6500 wlan_diag_event.is_roam_successful = (res->status == 0) || 6501 (ap_found_in_roam_scan && 6502 res->fail_reason != ROAM_FAIL_REASON_NO_CAND_AP_FOUND); 6503 6504 for (i = 0; i < scan_data->num_ap; i++) { 6505 if (i >= MAX_ROAM_CANDIDATE_AP) 6506 break; 6507 if (scan_data->ap[i].type == 6508 WLAN_ROAM_SCAN_CURRENT_AP) { 6509 qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, 6510 scan_data->ap[i].bssid.bytes, 6511 QDF_MAC_ADDR_SIZE); 6512 bssid = scan_data->ap[i].bssid; 6513 break; 6514 } 6515 } 6516 6517 if (!qdf_is_macaddr_zero(&res->fail_bssid)) { 6518 qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, 6519 res->fail_bssid.bytes, 6520 QDF_MAC_ADDR_SIZE); 6521 } 6522 6523 if (!wlan_diag_event.is_roam_successful) 6524 cm_populate_roam_success_mlo_param(psoc, &wlan_diag_event, 6525 vdev_id); 6526 6527 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_ROAM_RESULT); 6528 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6529 6530 if (roam_abort) { 6531 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6532 (uint64_t)res->timestamp, NULL); 6533 6534 wlan_diag_event.roam_fail_reason = res->fail_reason; 6535 6536 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, 6537 EVENT_WLAN_ROAM_CANCEL); 6538 } 6539 6540 cm_roam_send_beacon_loss_event(psoc, bssid, vdev_id, 6541 trigger->trigger_reason, 6542 wlan_diag_event.is_roam_successful, 6543 is_full_scan, res->fail_reason); 6544 6545 } 6546 6547 #endif 6548 6549 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6550 static QDF_STATUS 6551 cm_find_roam_candidate(struct wlan_objmgr_pdev *pdev, 6552 struct cnx_mgr *cm_ctx, 6553 struct cm_roam_req *roam_req, 6554 struct roam_invoke_req *roam_invoke_req) 6555 { 6556 struct scan_filter *filter; 6557 qdf_list_t *candidate_list; 6558 uint32_t num_bss = 0; 6559 qdf_list_node_t *cur_node = NULL; 6560 struct scan_cache_node *candidate = NULL; 6561 6562 if (!roam_invoke_req) 6563 return QDF_STATUS_E_FAILURE; 6564 6565 if (qdf_is_macaddr_zero(&roam_invoke_req->target_bssid) || 6566 !roam_invoke_req->ch_freq) 6567 return QDF_STATUS_E_FAILURE; 6568 6569 filter = qdf_mem_malloc(sizeof(*filter)); 6570 if (!filter) 6571 return QDF_STATUS_E_NOMEM; 6572 6573 filter->num_of_bssid = 1; 6574 qdf_copy_macaddr(&filter->bssid_list[0], 6575 &roam_invoke_req->target_bssid); 6576 filter->num_of_channels = 1; 6577 filter->chan_freq_list[0] = roam_invoke_req->ch_freq; 6578 6579 candidate_list = wlan_scan_get_result(pdev, filter); 6580 if (candidate_list) { 6581 num_bss = qdf_list_size(candidate_list); 6582 mlme_debug(CM_PREFIX_FMT "num_entries found %d", 6583 CM_PREFIX_REF(roam_req->req.vdev_id, 6584 roam_req->cm_id), 6585 num_bss); 6586 } 6587 qdf_mem_free(filter); 6588 6589 if (!candidate_list || !qdf_list_size(candidate_list)) { 6590 if (candidate_list) 6591 wlan_scan_purge_results(candidate_list); 6592 mlme_info(CM_PREFIX_FMT "no valid candidate found, num_bss %d", 6593 CM_PREFIX_REF(roam_req->req.vdev_id, 6594 roam_req->cm_id), 6595 num_bss); 6596 6597 return QDF_STATUS_E_EMPTY; 6598 } 6599 6600 qdf_list_peek_front(candidate_list, &cur_node); 6601 candidate = qdf_container_of(cur_node, 6602 struct scan_cache_node, 6603 node); 6604 6605 roam_invoke_req->frame_len = candidate->entry->raw_frame.len; 6606 6607 if (!roam_invoke_req->frame_len) 6608 return QDF_STATUS_E_INVAL; 6609 6610 roam_invoke_req->frame_buf = qdf_mem_malloc(roam_invoke_req->frame_len); 6611 6612 if (!roam_invoke_req->frame_buf) { 6613 roam_invoke_req->frame_len = 0; 6614 return QDF_STATUS_E_NOMEM; 6615 } 6616 6617 qdf_mem_copy(roam_invoke_req->frame_buf, 6618 candidate->entry->raw_frame.ptr, 6619 roam_invoke_req->frame_len); 6620 6621 wlan_scan_purge_results(candidate_list); 6622 6623 return QDF_STATUS_SUCCESS; 6624 } 6625 6626 QDF_STATUS 6627 cm_send_roam_invoke_req(struct cnx_mgr *cm_ctx, struct cm_req *req) 6628 { 6629 QDF_STATUS status; 6630 struct qdf_mac_addr connected_bssid; 6631 struct cm_roam_req *roam_req; 6632 struct wlan_objmgr_pdev *pdev; 6633 struct wlan_objmgr_psoc *psoc; 6634 struct roam_invoke_req *roam_invoke_req = NULL; 6635 wlan_cm_id cm_id; 6636 uint8_t vdev_id; 6637 uint8_t enable_self_bss_roam = false; 6638 6639 if (!req) 6640 return QDF_STATUS_E_FAILURE; 6641 6642 roam_req = &req->roam_req; 6643 cm_id = req->cm_id; 6644 vdev_id = roam_req->req.vdev_id; 6645 6646 pdev = wlan_vdev_get_pdev(cm_ctx->vdev); 6647 if (!pdev) { 6648 mlme_err(CM_PREFIX_FMT "Failed to find pdev", 6649 CM_PREFIX_REF(vdev_id, cm_id)); 6650 status = QDF_STATUS_E_FAILURE; 6651 goto roam_err; 6652 } 6653 6654 psoc = wlan_pdev_get_psoc(pdev); 6655 if (!psoc) { 6656 mlme_err(CM_PREFIX_FMT "Failed to find psoc", 6657 CM_PREFIX_REF(vdev_id, cm_id)); 6658 status = QDF_STATUS_E_FAILURE; 6659 goto roam_err; 6660 } 6661 6662 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 6663 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 6664 status = QDF_STATUS_E_FAILURE; 6665 goto roam_err; 6666 } 6667 6668 wlan_vdev_get_bss_peer_mac(cm_ctx->vdev, &connected_bssid); 6669 wlan_mlme_get_self_bss_roam(psoc, &enable_self_bss_roam); 6670 if (!enable_self_bss_roam && 6671 qdf_is_macaddr_equal(&roam_req->req.bssid, &connected_bssid)) { 6672 mlme_err(CM_PREFIX_FMT "self bss roam disabled", 6673 CM_PREFIX_REF(vdev_id, cm_id)); 6674 status = QDF_STATUS_E_FAILURE; 6675 goto roam_err; 6676 } 6677 6678 roam_invoke_req = qdf_mem_malloc(sizeof(*roam_invoke_req)); 6679 if (!roam_invoke_req) { 6680 status = QDF_STATUS_E_NOMEM; 6681 goto roam_err; 6682 } 6683 6684 roam_invoke_req->vdev_id = vdev_id; 6685 if (roam_req->req.forced_roaming) { 6686 roam_invoke_req->forced_roaming = true; 6687 goto send_cmd; 6688 } 6689 6690 if (qdf_is_macaddr_broadcast(&roam_req->req.bssid)) { 6691 qdf_copy_macaddr(&roam_invoke_req->target_bssid, 6692 &roam_req->req.bssid); 6693 goto send_cmd; 6694 } 6695 if (qdf_is_macaddr_equal(&roam_req->req.bssid, &connected_bssid)) 6696 roam_invoke_req->is_same_bssid = true; 6697 6698 qdf_copy_macaddr(&roam_invoke_req->target_bssid, &roam_req->req.bssid); 6699 roam_invoke_req->ch_freq = roam_req->req.chan_freq; 6700 6701 status = cm_find_roam_candidate(pdev, cm_ctx, roam_req, 6702 roam_invoke_req); 6703 6704 if (QDF_IS_STATUS_ERROR(status)) { 6705 mlme_err(CM_PREFIX_FMT "No Candidate found, send roam invoke req, fw will perform scan", 6706 CM_PREFIX_REF(vdev_id, cm_id)); 6707 } 6708 6709 if (wlan_cm_get_ese_assoc(pdev, vdev_id)) { 6710 mlme_debug(CM_PREFIX_FMT "Beacon is not required for ESE", 6711 CM_PREFIX_REF(vdev_id, cm_id)); 6712 if (roam_invoke_req->frame_len) { 6713 qdf_mem_free(roam_invoke_req->frame_buf); 6714 roam_invoke_req->frame_buf = NULL; 6715 roam_invoke_req->frame_len = 0; 6716 } 6717 } 6718 send_cmd: 6719 status = wlan_cm_tgt_send_roam_invoke_req(psoc, roam_invoke_req); 6720 6721 roam_err: 6722 if (QDF_IS_STATUS_ERROR(status)) { 6723 mlme_debug(CM_PREFIX_FMT "fail to send roam invoke req", 6724 CM_PREFIX_REF(vdev_id, cm_id)); 6725 status = cm_sm_deliver_event_sync(cm_ctx, 6726 WLAN_CM_SM_EV_ROAM_INVOKE_FAIL, 6727 sizeof(wlan_cm_id), 6728 &cm_id); 6729 if (QDF_IS_STATUS_ERROR(status)) 6730 cm_remove_cmd(cm_ctx, &cm_id); 6731 } 6732 6733 if (roam_invoke_req) { 6734 if (roam_invoke_req->frame_len) 6735 qdf_mem_free(roam_invoke_req->frame_buf); 6736 qdf_mem_free(roam_invoke_req); 6737 } 6738 6739 return status; 6740 } 6741 6742 bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc) 6743 { 6744 bool val; 6745 6746 wlan_mlme_get_roaming_offload(psoc, &val); 6747 6748 return val; 6749 } 6750 6751 #if defined(WLAN_FEATURE_CONNECTIVITY_LOGGING) || \ 6752 defined(CONNECTIVITY_DIAG_EVENT) 6753 static enum wlan_main_tag 6754 cm_roam_get_tag(enum mgmt_subtype subtype, bool is_tx) 6755 { 6756 switch (subtype) { 6757 case MGMT_SUBTYPE_ASSOC_REQ: 6758 return WLAN_ASSOC_REQ; 6759 case MGMT_SUBTYPE_ASSOC_RESP: 6760 return WLAN_ASSOC_RSP; 6761 case MGMT_SUBTYPE_REASSOC_REQ: 6762 return WLAN_REASSOC_REQ; 6763 case MGMT_SUBTYPE_REASSOC_RESP: 6764 return WLAN_REASSOC_RSP; 6765 case MGMT_SUBTYPE_DISASSOC: 6766 if (is_tx) 6767 return WLAN_DISASSOC_TX; 6768 else 6769 return WLAN_DISASSOC_RX; 6770 break; 6771 case MGMT_SUBTYPE_AUTH: 6772 if (is_tx) 6773 return WLAN_AUTH_REQ; 6774 else 6775 return WLAN_AUTH_RESP; 6776 break; 6777 case MGMT_SUBTYPE_DEAUTH: 6778 if (is_tx) 6779 return WLAN_DEAUTH_TX; 6780 else 6781 return WLAN_DEAUTH_RX; 6782 default: 6783 break; 6784 } 6785 6786 return WLAN_TAG_MAX; 6787 } 6788 6789 static enum wlan_main_tag 6790 cm_roam_get_eapol_tag(enum wlan_roam_frame_subtype subtype) 6791 { 6792 switch (subtype) { 6793 case ROAM_FRAME_SUBTYPE_M1: 6794 return WLAN_EAPOL_M1; 6795 case ROAM_FRAME_SUBTYPE_M2: 6796 return WLAN_EAPOL_M2; 6797 case ROAM_FRAME_SUBTYPE_M3: 6798 return WLAN_EAPOL_M3; 6799 case ROAM_FRAME_SUBTYPE_M4: 6800 return WLAN_EAPOL_M4; 6801 case ROAM_FRAME_SUBTYPE_GTK_M1: 6802 return WLAN_GTK_M1; 6803 case ROAM_FRAME_SUBTYPE_GTK_M2: 6804 return WLAN_GTK_M2; 6805 default: 6806 break; 6807 } 6808 6809 return WLAN_TAG_MAX; 6810 } 6811 #endif 6812 6813 #if defined(CONNECTIVITY_DIAG_EVENT) 6814 QDF_STATUS 6815 cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data, 6816 uint8_t vdev_id) 6817 { 6818 QDF_STATUS status = QDF_STATUS_SUCCESS; 6819 6820 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 6821 6822 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6823 6824 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6825 (uint64_t)btm_data->timestamp, NULL); 6826 6827 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_QUERY_EVENT; 6828 wlan_diag_event.version = DIAG_BTM_VERSION_2; 6829 wlan_diag_event.token = btm_data->btm_query_token; 6830 wlan_diag_event.reason = btm_data->btm_query_reason; 6831 wlan_diag_event.band = btm_data->band; 6832 6833 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 6834 6835 return status; 6836 } 6837 6838 void 6839 cm_roam_neigh_rpt_req_event(struct wmi_neighbor_report_data *neigh_rpt, 6840 struct wlan_objmgr_vdev *vdev) 6841 { 6842 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_nbr_rpt); 6843 6844 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6845 6846 populate_diag_cmn(&wlan_diag_event.diag_cmn, wlan_vdev_get_id(vdev), 6847 (uint64_t)neigh_rpt->timestamp, NULL); 6848 6849 wlan_diag_event.subtype = WLAN_CONN_DIAG_NBR_RPT_REQ_EVENT; 6850 wlan_diag_event.version = DIAG_NBR_RPT_VERSION_2; 6851 wlan_diag_event.token = neigh_rpt->req_token; 6852 wlan_diag_event.band = neigh_rpt->band; 6853 6854 wlan_vdev_mlme_get_ssid(vdev, wlan_diag_event.ssid, 6855 (uint8_t *)&wlan_diag_event.ssid_len); 6856 6857 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_NBR_RPT); 6858 } 6859 6860 void 6861 cm_roam_neigh_rpt_resp_event(struct wmi_neighbor_report_data *neigh_rpt, 6862 uint8_t vdev_id) 6863 { 6864 uint8_t i; 6865 6866 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_nbr_rpt); 6867 6868 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6869 6870 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6871 (uint64_t)neigh_rpt->timestamp, NULL); 6872 6873 wlan_diag_event.subtype = WLAN_CONN_DIAG_NBR_RPT_RESP_EVENT; 6874 wlan_diag_event.version = DIAG_NBR_RPT_VERSION_2; 6875 wlan_diag_event.token = neigh_rpt->resp_token; 6876 wlan_diag_event.num_freq = neigh_rpt->num_freq; 6877 6878 for (i = 0; i < neigh_rpt->num_freq; i++) 6879 wlan_diag_event.freq[i] = neigh_rpt->freq[i]; 6880 6881 wlan_diag_event.num_rpt = neigh_rpt->num_rpt; 6882 wlan_diag_event.band = neigh_rpt->band; 6883 6884 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_NBR_RPT); 6885 } 6886 6887 #define WTC_BTM_RESPONSE_SUBCODE 0xFF 6888 static void 6889 cm_roam_wtc_btm_event(struct wmi_roam_trigger_info *trigger_info, 6890 struct roam_btm_response_data *btm_data, 6891 uint8_t vdev_id, bool is_wtc) 6892 { 6893 struct wmi_roam_wtc_btm_trigger_data *wtc_data = 6894 &trigger_info->wtc_btm_trig_data; 6895 6896 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 6897 6898 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6899 6900 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6901 (uint64_t)trigger_info->timestamp, NULL); 6902 6903 wlan_diag_event.version = DIAG_BTM_VERSION; 6904 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_WTC_EVENT; 6905 6906 if (is_wtc) { 6907 wlan_diag_event.reason = wtc_data->vsie_trigger_reason; 6908 wlan_diag_event.sub_reason = wtc_data->sub_code; 6909 wlan_diag_event.wtc_duration = wtc_data->duration; 6910 } else { 6911 if (!btm_data) 6912 return; 6913 6914 wlan_diag_event.reason = btm_data->vsie_reason; 6915 wlan_diag_event.sub_reason = WTC_BTM_RESPONSE_SUBCODE; 6916 } 6917 6918 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 6919 } 6920 6921 QDF_STATUS 6922 cm_roam_btm_resp_event(struct wmi_roam_trigger_info *trigger_info, 6923 struct roam_btm_response_data *btm_data, 6924 uint8_t vdev_id, bool is_wtc) 6925 { 6926 QDF_STATUS status = QDF_STATUS_SUCCESS; 6927 6928 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 6929 6930 if (is_wtc) { 6931 cm_roam_wtc_btm_event(trigger_info, btm_data, vdev_id, is_wtc); 6932 return status; 6933 } 6934 6935 if (!btm_data) { 6936 mlme_err("vdev_id:%d btm data is NULL", vdev_id); 6937 return QDF_STATUS_E_FAILURE; 6938 } 6939 6940 if (btm_data->vsie_reason) 6941 cm_roam_wtc_btm_event(trigger_info, btm_data, vdev_id, is_wtc); 6942 6943 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6944 6945 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6946 (uint64_t)trigger_info->timestamp, 6947 &btm_data->target_bssid); 6948 6949 wlan_diag_event.version = DIAG_BTM_VERSION_2; 6950 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_RESP_EVENT; 6951 wlan_diag_event.token = btm_data->btm_resp_dialog_token; 6952 wlan_diag_event.status = btm_data->btm_status; 6953 wlan_diag_event.delay = btm_data->btm_delay; 6954 wlan_diag_event.band = btm_data->band; 6955 6956 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 6957 6958 return status; 6959 } 6960 6961 /** 6962 * cm_roam_btm_candidate_event() - Send BTM roam candidate logging event 6963 * @btm_data: BTM data 6964 * @vdev_id: Vdev id 6965 * @idx: Candidate instance 6966 * 6967 * Return: QDF_STATUS 6968 */ 6969 static QDF_STATUS 6970 cm_roam_btm_candidate_event(struct wmi_btm_req_candidate_info *btm_data, 6971 uint8_t vdev_id, uint8_t idx) 6972 { 6973 QDF_STATUS status = QDF_STATUS_SUCCESS; 6974 6975 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6976 struct wlan_diag_btm_cand_info); 6977 6978 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6979 6980 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6981 (uint64_t)btm_data->timestamp, 6982 &btm_data->candidate_bssid); 6983 6984 wlan_diag_event.version = DIAG_BTM_CAND_VERSION; 6985 wlan_diag_event.preference = btm_data->preference; 6986 wlan_diag_event.idx = idx; 6987 6988 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM_CAND); 6989 6990 return status; 6991 } 6992 6993 QDF_STATUS 6994 cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data, 6995 struct wmi_roam_trigger_info *trigger_info, 6996 uint8_t vdev_id, bool is_wtc) 6997 { 6998 uint8_t i; 6999 QDF_STATUS status = QDF_STATUS_SUCCESS; 7000 7001 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 7002 7003 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 7004 7005 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 7006 (uint64_t)btm_data->timestamp, 7007 NULL); 7008 7009 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_REQ_EVENT; 7010 wlan_diag_event.version = DIAG_BTM_VERSION_2; 7011 wlan_diag_event.token = btm_data->token; 7012 wlan_diag_event.mode = btm_data->btm_request_mode; 7013 /* 7014 * Diassoc Timer and Validity interval are in secs in the frame 7015 * firmware sends it in millisecs to the host. 7016 * Send it in secs to the userspace. 7017 */ 7018 wlan_diag_event.disassoc_tim = btm_data->disassoc_timer / 1000; 7019 wlan_diag_event.validity_timer = 7020 btm_data->validity_interval / 1000; 7021 wlan_diag_event.cand_lst_cnt = btm_data->candidate_list_count; 7022 wlan_diag_event.band = btm_data->band; 7023 7024 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 7025 7026 if (is_wtc) 7027 cm_roam_wtc_btm_event(trigger_info, NULL, vdev_id, true); 7028 7029 for (i = 0; i < btm_data->candidate_list_count; i++) 7030 cm_roam_btm_candidate_event(&btm_data->btm_cand[i], vdev_id, i); 7031 7032 return status; 7033 } 7034 7035 static enum wlan_diag_wifi_band 7036 wlan_convert_bitmap_to_band(uint8_t bitmap) 7037 { 7038 uint8_t i; 7039 enum wlan_diag_wifi_band band = WLAN_INVALID_BAND; 7040 7041 for (i = WLAN_24GHZ_BAND; i <= WLAN_6GHZ_BAND; i++) { 7042 if (qdf_test_bit(i, (unsigned long *)&bitmap)) { 7043 band = i; 7044 break; 7045 } 7046 } 7047 7048 return band; 7049 } 7050 7051 QDF_STATUS 7052 cm_roam_mgmt_frame_event(struct wlan_objmgr_vdev *vdev, 7053 struct roam_frame_info *frame_data, 7054 struct wmi_roam_scan_data *scan_data) 7055 { 7056 QDF_STATUS status = QDF_STATUS_SUCCESS; 7057 uint8_t i; 7058 uint16_t diag_event; 7059 7060 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info); 7061 7062 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 7063 7064 populate_diag_cmn(&wlan_diag_event.diag_cmn, wlan_vdev_get_id(vdev), 7065 (uint64_t)frame_data->timestamp, 7066 &frame_data->bssid); 7067 7068 wlan_diag_event.version = DIAG_MGMT_VERSION_V2; 7069 wlan_diag_event.sn = frame_data->seq_num; 7070 wlan_diag_event.auth_algo = frame_data->auth_algo; 7071 wlan_diag_event.rssi = frame_data->rssi; 7072 wlan_diag_event.tx_status = 7073 wlan_get_diag_tx_status(frame_data->tx_status); 7074 wlan_diag_event.status = frame_data->status_code; 7075 wlan_diag_event.assoc_id = frame_data->assoc_id; 7076 7077 if (scan_data->present) { 7078 for (i = 0; i < scan_data->num_ap; i++) { 7079 if (i >= MAX_ROAM_CANDIDATE_AP) 7080 break; 7081 if (scan_data->ap[i].type == WLAN_ROAM_SCAN_ROAMED_AP) { 7082 wlan_diag_event.rssi = 7083 (-1) * scan_data->ap[i].rssi; 7084 7085 qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, 7086 scan_data->ap[i].bssid.bytes, 7087 QDF_MAC_ADDR_SIZE); 7088 break; 7089 } else if (!memcmp(wlan_diag_event.diag_cmn.bssid, 7090 scan_data->ap[i].bssid.bytes, 7091 QDF_MAC_ADDR_SIZE)) { 7092 wlan_diag_event.rssi = 7093 (-1) * scan_data->ap[i].rssi; 7094 break; 7095 } 7096 } 7097 } 7098 7099 if (frame_data->type == ROAM_FRAME_INFO_FRAME_TYPE_EXT) { 7100 wlan_diag_event.subtype = 7101 (uint8_t)cm_roam_get_eapol_tag(frame_data->subtype); 7102 diag_event = EVENT_WLAN_CONN_DP; 7103 wlan_diag_event.supported_links = 7104 wlan_convert_bitmap_to_band(frame_data->band); 7105 7106 } else { 7107 wlan_diag_event.subtype = 7108 (uint8_t)cm_roam_get_tag(frame_data->subtype, 7109 !frame_data->is_rsp); 7110 diag_event = EVENT_WLAN_MGMT; 7111 7112 wlan_diag_event.supported_links = frame_data->band; 7113 7114 status = 7115 wlan_populate_mlo_mgmt_event_param(vdev, 7116 &wlan_diag_event, 7117 wlan_diag_event.subtype); 7118 if (QDF_IS_STATUS_ERROR(status)) { 7119 mlme_err("vdev: %d Unable to populate MLO parameter", 7120 wlan_vdev_get_id(vdev)); 7121 return status; 7122 } 7123 } 7124 7125 if (wlan_diag_event.subtype > WLAN_CONN_DIAG_REASSOC_RESP_EVENT && 7126 wlan_diag_event.subtype < WLAN_CONN_DIAG_BMISS_EVENT) 7127 wlan_diag_event.reason = frame_data->status_code; 7128 7129 if (wlan_diag_event.subtype == WLAN_CONN_DIAG_DEAUTH_RX_EVENT || 7130 wlan_diag_event.subtype == WLAN_CONN_DIAG_DISASSOC_RX_EVENT) 7131 wlan_populate_vsie(vdev, &wlan_diag_event, false); 7132 7133 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, diag_event); 7134 if (wlan_diag_event.subtype == WLAN_CONN_DIAG_REASSOC_RESP_EVENT || 7135 wlan_diag_event.subtype == WLAN_CONN_DIAG_ASSOC_RESP_EVENT) 7136 wlan_connectivity_mlo_setup_event(vdev); 7137 7138 return status; 7139 } 7140 7141 QDF_STATUS 7142 cm_roam_beacon_loss_disconnect_event(struct wlan_objmgr_psoc *psoc, 7143 struct qdf_mac_addr bssid, uint8_t vdev_id) 7144 { 7145 struct wlan_objmgr_vdev *vdev = NULL; 7146 QDF_STATUS status = QDF_STATUS_SUCCESS; 7147 7148 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info); 7149 7150 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 7151 WLAN_MLME_CM_ID); 7152 if (!vdev) { 7153 mlme_err("Vdev[%d] is null", vdev_id); 7154 return QDF_STATUS_E_FAILURE; 7155 } 7156 7157 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) { 7158 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 7159 return status; 7160 } 7161 7162 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 7163 7164 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 7165 0, &bssid); 7166 7167 wlan_diag_event.subtype = WLAN_CONN_DIAG_BMISS_EVENT; 7168 wlan_diag_event.version = DIAG_MGMT_VERSION; 7169 wlan_diag_event.rssi = mlme_get_hb_ap_rssi(vdev); 7170 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 7171 7172 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MGMT); 7173 7174 return status; 7175 } 7176 #endif 7177 7178 QDF_STATUS 7179 cm_send_rso_stop(struct wlan_objmgr_vdev *vdev) 7180 { 7181 bool send_resp = true, start_timer; 7182 7183 if (!vdev) { 7184 mlme_err("vdev is NULL"); 7185 return QDF_STATUS_E_INVAL; 7186 } 7187 start_timer = cm_roam_offload_enabled(wlan_vdev_get_psoc(vdev)); 7188 7189 cm_roam_state_change(wlan_vdev_get_pdev(vdev), wlan_vdev_get_id(vdev), 7190 WLAN_ROAM_RSO_STOPPED, REASON_DISCONNECTED, 7191 &send_resp, start_timer); 7192 /* 7193 * RSO stop resp is not supported or RSO STOP timer/req failed, 7194 * send QDF_STATUS_E_NOSUPPORT so that we continue from the caller 7195 */ 7196 if (send_resp) 7197 return QDF_STATUS_E_NOSUPPORT; 7198 7199 return QDF_STATUS_SUCCESS; 7200 } 7201 7202 QDF_STATUS 7203 cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, 7204 uint8_t vdev_id, uint16_t param_value) 7205 { 7206 QDF_STATUS status; 7207 7208 wlan_cm_roam_set_ho_delay_config(psoc, param_value); 7209 status = wlan_cm_tgt_send_roam_ho_delay_config(psoc, 7210 vdev_id, param_value); 7211 if (QDF_IS_STATUS_ERROR(status)) 7212 mlme_debug("fail to send roam HO delay config"); 7213 7214 return status; 7215 } 7216 7217 QDF_STATUS 7218 cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, 7219 uint8_t vdev_id, uint8_t param_value) 7220 { 7221 QDF_STATUS status; 7222 7223 wlan_cm_set_exclude_rm_partial_scan_freq(psoc, param_value); 7224 status = wlan_cm_tgt_exclude_rm_partial_scan_freq(psoc, vdev_id, 7225 param_value); 7226 if (QDF_IS_STATUS_ERROR(status)) 7227 mlme_debug("fail to exclude roam partial scan channels"); 7228 7229 return status; 7230 } 7231 7232 QDF_STATUS cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, 7233 uint8_t vdev_id, 7234 uint8_t param_value) 7235 { 7236 QDF_STATUS status; 7237 7238 wlan_cm_roam_set_full_scan_6ghz_on_disc(psoc, param_value); 7239 status = wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc(psoc, vdev_id, 7240 param_value); 7241 if (QDF_IS_STATUS_ERROR(status)) 7242 mlme_debug("fail to send 6 GHz channels inclusion in full scan"); 7243 7244 return status; 7245 } 7246 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 7247