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 mlme_debug("vdev:%d process rso stop for reason: %d", vdev_id, reason); 3523 3524 stop_req->btm_config.vdev_id = vdev_id; 3525 if (reason == REASON_SUPPLICANT_DISABLED_ROAMING) 3526 MLME_SET_BIT(stop_req->btm_config.btm_offload_config, 3527 BTM_OFFLOAD_CONFIG_BIT_0); 3528 stop_req->disconnect_params.vdev_id = vdev_id; 3529 stop_req->idle_params.vdev_id = vdev_id; 3530 stop_req->roam_triggers.vdev_id = vdev_id; 3531 stop_req->rssi_params.vdev_id = vdev_id; 3532 stop_req->roam_11k_params.vdev_id = vdev_id; 3533 cm_fill_stop_reason(stop_req, reason); 3534 if (wlan_cm_host_roam_in_progress(psoc, vdev_id)) 3535 stop_req->middle_of_roaming = 1; 3536 if (send_resp) 3537 stop_req->send_rso_stop_resp = *send_resp; 3538 stop_req->start_rso_stop_timer = start_timer; 3539 /* 3540 * If roam synch propagation is in progress and an user space 3541 * disconnect is requested, then there is no need to send the 3542 * RSO STOP to firmware, since the roaming is already complete. 3543 * If the RSO STOP is sent to firmware, then an HO_FAIL will be 3544 * generated and the expectation from firmware would be to 3545 * clean up the peer context on the host and not send down any 3546 * WMI PEER DELETE commands to firmware. But, if the user space 3547 * disconnect gets processed first, then there is a chance to 3548 * send down the PEER DELETE commands. Hence, if we do not 3549 * receive the HO_FAIL, and we complete the roam sync 3550 * propagation, then the host and firmware will be in sync with 3551 * respect to the peer and then the user space disconnect can 3552 * be handled gracefully in a normal way. 3553 * 3554 * Ensure to check the reason code since the RSO Stop might 3555 * come when roam sync failed as well and at that point it 3556 * should go through to the firmware and receive HO_FAIL 3557 * and clean up. 3558 */ 3559 if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id) && 3560 stop_req->reason == REASON_ROAM_STOP_ALL) { 3561 mlme_info("vdev_id:%d : Drop RSO stop during roam sync", 3562 vdev_id); 3563 goto rel_vdev_ref; 3564 } 3565 3566 wlan_mlme_defer_pmk_set_in_roaming(psoc, vdev_id, false); 3567 3568 cm_roam_scan_filter(psoc, pdev, vdev_id, ROAM_SCAN_OFFLOAD_STOP, 3569 reason, &stop_req->scan_filter_params); 3570 cm_roam_scan_offload_fill_rso_configs(psoc, vdev, rso_cfg, 3571 &stop_req->rso_config, 3572 NULL, ROAM_SCAN_OFFLOAD_STOP, 3573 stop_req->reason); 3574 3575 status = wlan_cm_tgt_send_roam_stop_req(psoc, vdev_id, stop_req); 3576 if (QDF_IS_STATUS_ERROR(status)) { 3577 mlme_debug("fail to send roam stop"); 3578 } 3579 if (send_resp) 3580 *send_resp = stop_req->send_rso_stop_resp; 3581 3582 rel_vdev_ref: 3583 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3584 free_mem: 3585 qdf_mem_free(stop_req); 3586 3587 return QDF_STATUS_SUCCESS; 3588 } 3589 3590 /** 3591 * cm_roam_fill_per_roam_request() - create PER roam offload config request 3592 * @psoc: psoc context 3593 * @req: request to fill 3594 * 3595 * Return: QDF_STATUS 3596 */ 3597 static QDF_STATUS 3598 cm_roam_fill_per_roam_request(struct wlan_objmgr_psoc *psoc, 3599 struct wlan_per_roam_config_req *req) 3600 { 3601 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3602 3603 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3604 if (!mlme_obj) 3605 return QDF_STATUS_E_FAILURE; 3606 3607 req->per_config.enable = mlme_obj->cfg.lfr.per_roam_enable; 3608 req->per_config.tx_high_rate_thresh = 3609 mlme_obj->cfg.lfr.per_roam_config_high_rate_th; 3610 req->per_config.rx_high_rate_thresh = 3611 mlme_obj->cfg.lfr.per_roam_config_high_rate_th; 3612 req->per_config.tx_low_rate_thresh = 3613 mlme_obj->cfg.lfr.per_roam_config_low_rate_th; 3614 req->per_config.rx_low_rate_thresh = 3615 mlme_obj->cfg.lfr.per_roam_config_low_rate_th; 3616 req->per_config.per_rest_time = mlme_obj->cfg.lfr.per_roam_rest_time; 3617 req->per_config.tx_per_mon_time = 3618 mlme_obj->cfg.lfr.per_roam_monitor_time; 3619 req->per_config.rx_per_mon_time = 3620 mlme_obj->cfg.lfr.per_roam_monitor_time; 3621 req->per_config.tx_rate_thresh_percnt = 3622 mlme_obj->cfg.lfr.per_roam_config_rate_th_percent; 3623 req->per_config.rx_rate_thresh_percnt = 3624 mlme_obj->cfg.lfr.per_roam_config_rate_th_percent; 3625 req->per_config.min_candidate_rssi = 3626 mlme_obj->cfg.lfr.per_roam_min_candidate_rssi; 3627 3628 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", 3629 req->per_config.enable, req->vdev_id, 3630 req->per_config.tx_high_rate_thresh, 3631 req->per_config.tx_low_rate_thresh, 3632 req->per_config.tx_rate_thresh_percnt, 3633 req->per_config.per_rest_time, 3634 req->per_config.tx_per_mon_time, 3635 req->per_config.min_candidate_rssi); 3636 3637 return QDF_STATUS_SUCCESS; 3638 } 3639 3640 /** 3641 * cm_roam_offload_per_config() - populates roam offload scan request and sends 3642 * to fw 3643 * @psoc: psoc context 3644 * @vdev_id: vdev id 3645 * 3646 * Return: QDF_STATUS 3647 */ 3648 static QDF_STATUS 3649 cm_roam_offload_per_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3650 { 3651 struct wlan_per_roam_config_req *req; 3652 bool is_per_roam_enabled; 3653 QDF_STATUS status; 3654 3655 /* 3656 * Disable PER trigger for phymode less than 11n to avoid 3657 * frequent roams as the PER rate threshold is greater than 3658 * 11a/b/g rates 3659 */ 3660 is_per_roam_enabled = cm_roam_is_per_roam_allowed(psoc, vdev_id); 3661 if (!is_per_roam_enabled) 3662 return QDF_STATUS_SUCCESS; 3663 3664 req = qdf_mem_malloc(sizeof(*req)); 3665 if (!req) 3666 return QDF_STATUS_E_NOMEM; 3667 3668 req->vdev_id = vdev_id; 3669 status = cm_roam_fill_per_roam_request(psoc, req); 3670 if (QDF_IS_STATUS_ERROR(status)) { 3671 qdf_mem_free(req); 3672 mlme_debug("fail to fill per config"); 3673 return status; 3674 } 3675 3676 status = wlan_cm_tgt_send_roam_per_config(psoc, vdev_id, req); 3677 if (QDF_IS_STATUS_ERROR(status)) 3678 mlme_debug("fail to send roam stop"); 3679 3680 qdf_mem_free(req); 3681 3682 return status; 3683 } 3684 3685 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 3686 QDF_STATUS 3687 cm_akm_roam_allowed(struct wlan_objmgr_psoc *psoc, 3688 struct wlan_objmgr_vdev *vdev) 3689 { 3690 int32_t akm; 3691 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3692 uint32_t fw_akm_bitmap; 3693 3694 akm = wlan_crypto_get_param(vdev, 3695 WLAN_CRYPTO_PARAM_KEY_MGMT); 3696 mlme_debug("akm %x", akm); 3697 3698 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3699 if (!mlme_obj) 3700 return QDF_STATUS_E_FAILURE; 3701 3702 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384) || 3703 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256)) && 3704 !mlme_obj->cfg.lfr.rso_user_config.is_fils_roaming_supported) { 3705 mlme_info("FILS Roaming not suppprted by fw"); 3706 return QDF_STATUS_E_NOSUPPORT; 3707 } 3708 fw_akm_bitmap = mlme_obj->cfg.lfr.fw_akm_bitmap; 3709 /* Roaming is not supported currently for OWE akm */ 3710 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE) && 3711 !(fw_akm_bitmap & (1 << AKM_OWE))) { 3712 mlme_info("OWE Roaming not suppprted by fw"); 3713 return QDF_STATUS_E_NOSUPPORT; 3714 } 3715 3716 /* Roaming is not supported for SAE authentication */ 3717 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE) && 3718 !CM_IS_FW_SAE_ROAM_SUPPORTED(fw_akm_bitmap)) { 3719 mlme_info("Roaming not suppprted for SAE connection"); 3720 return QDF_STATUS_E_NOSUPPORT; 3721 } 3722 3723 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY) || 3724 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) && 3725 !CM_IS_FW_SAE_EXT_ROAM_SUPPORTED(fw_akm_bitmap)) { 3726 mlme_info("Roaming not supported for SAE EXT akm"); 3727 return QDF_STATUS_E_NOSUPPORT; 3728 } 3729 3730 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B) || 3731 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192)) && 3732 !(fw_akm_bitmap & (1 << AKM_SUITEB))) { 3733 mlme_info("Roaming not supported for SUITEB connection"); 3734 return QDF_STATUS_E_NOSUPPORT; 3735 } 3736 3737 /* 3738 * If fw doesn't advertise FT SAE, FT-FILS or FT-Suite-B capability, 3739 * don't support roaming to that profile 3740 */ 3741 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) && 3742 !CM_IS_FW_FT_SAE_SUPPORTED(fw_akm_bitmap)) { 3743 mlme_info("Roaming not suppprted for FT SAE akm"); 3744 return QDF_STATUS_E_NOSUPPORT; 3745 } 3746 3747 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) && 3748 !(fw_akm_bitmap & (1 << AKM_FT_SUITEB_SHA384))) { 3749 mlme_info("Roaming not suppprted for FT Suite-B akm"); 3750 return QDF_STATUS_E_NOSUPPORT; 3751 } 3752 3753 if ((QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384) || 3754 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256)) && 3755 !(fw_akm_bitmap & (1 << AKM_FT_FILS))) { 3756 mlme_info("Roaming not suppprted for FT FILS akm"); 3757 return QDF_STATUS_E_NOSUPPORT; 3758 } 3759 3760 return QDF_STATUS_SUCCESS; 3761 } 3762 3763 QDF_STATUS cm_set_roam_scan_high_rssi_offset(struct wlan_objmgr_psoc *psoc, 3764 uint8_t vdev_id, 3765 uint8_t param_value) 3766 { 3767 struct rso_config *rso_cfg; 3768 struct wlan_objmgr_vdev *vdev; 3769 struct wlan_roam_offload_scan_rssi_params *roam_rssi_params; 3770 QDF_STATUS status = QDF_STATUS_E_INVAL; 3771 qdf_freq_t op_freq; 3772 3773 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3774 WLAN_MLME_CM_ID); 3775 if (!vdev) { 3776 mlme_err("vdev object is NULL for vdev %d", vdev_id); 3777 return QDF_STATUS_E_FAILURE; 3778 } 3779 3780 op_freq = wlan_get_operation_chan_freq(vdev); 3781 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(op_freq)) { 3782 mlme_err("vdev:%d High RSSI offset can't be set in 6 GHz band", 3783 vdev_id); 3784 goto rel_vdev_ref; 3785 } 3786 3787 rso_cfg = wlan_cm_get_rso_config(vdev); 3788 if (!rso_cfg) 3789 goto rel_vdev_ref; 3790 3791 roam_rssi_params = qdf_mem_malloc(sizeof(*roam_rssi_params)); 3792 if (!roam_rssi_params) 3793 goto rel_vdev_ref; 3794 3795 wlan_cm_set_roam_scan_high_rssi_offset(psoc, param_value); 3796 qdf_mem_zero(roam_rssi_params, sizeof(*roam_rssi_params)); 3797 cm_roam_scan_offload_rssi_thresh(psoc, vdev_id, 3798 roam_rssi_params, rso_cfg); 3799 mlme_debug("vdev:%d Configured high RSSI delta=%d, 5 GHZ roam flag=%d", 3800 vdev_id, roam_rssi_params->hi_rssi_scan_rssi_delta, 3801 (roam_rssi_params->flags & 3802 ROAM_SCAN_RSSI_THRESHOLD_FLAG_ROAM_HI_RSSI_EN_ON_5G)); 3803 3804 status = wlan_cm_tgt_send_roam_scan_offload_rssi_params( 3805 vdev, roam_rssi_params); 3806 if (QDF_IS_STATUS_ERROR(status)) 3807 mlme_err("fail to set roam scan high RSSI offset"); 3808 3809 qdf_mem_free(roam_rssi_params); 3810 rel_vdev_ref: 3811 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3812 3813 return status; 3814 } 3815 #endif 3816 3817 #ifdef WLAN_ADAPTIVE_11R 3818 static bool 3819 cm_is_adaptive_11r_roam_supported(struct wlan_mlme_psoc_ext_obj *mlme_obj, 3820 struct rso_config *rso_cfg) 3821 { 3822 if (rso_cfg->is_adaptive_11r_connection) 3823 return mlme_obj->cfg.lfr.tgt_adaptive_11r_cap; 3824 3825 return true; 3826 } 3827 #else 3828 static bool 3829 cm_is_adaptive_11r_roam_supported(struct wlan_mlme_psoc_ext_obj *mlme_obj, 3830 struct rso_config *rso_cfg) 3831 3832 { 3833 return true; 3834 } 3835 #endif 3836 3837 static QDF_STATUS 3838 cm_roam_cmd_allowed(struct wlan_objmgr_psoc *psoc, 3839 struct wlan_objmgr_vdev *vdev, 3840 uint8_t command, uint8_t reason) 3841 { 3842 uint8_t vdev_id = wlan_vdev_get_id(vdev); 3843 struct rso_config *rso_cfg; 3844 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3845 bool p2p_disable_sta_roaming = 0, nan_disable_sta_roaming = 0; 3846 QDF_STATUS status; 3847 3848 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3849 if (!mlme_obj) 3850 return QDF_STATUS_E_FAILURE; 3851 3852 rso_cfg = wlan_cm_get_rso_config(vdev); 3853 if (!rso_cfg) 3854 return QDF_STATUS_E_FAILURE; 3855 3856 mlme_debug("RSO Command %d, vdev %d, Reason %d", 3857 command, vdev_id, reason); 3858 3859 if (!cm_is_vdev_connected(vdev) && 3860 (command == ROAM_SCAN_OFFLOAD_UPDATE_CFG || 3861 command == ROAM_SCAN_OFFLOAD_START || 3862 command == ROAM_SCAN_OFFLOAD_RESTART)) { 3863 mlme_debug("vdev not in connected state and command %d ", 3864 command); 3865 return QDF_STATUS_E_FAILURE; 3866 } 3867 3868 if (!cm_is_adaptive_11r_roam_supported(mlme_obj, rso_cfg)) { 3869 mlme_info("Adaptive 11r Roaming not suppprted by fw"); 3870 return QDF_STATUS_E_NOSUPPORT; 3871 } 3872 3873 status = cm_akm_roam_allowed(psoc, vdev); 3874 if (QDF_IS_STATUS_ERROR(status)) 3875 return status; 3876 3877 p2p_disable_sta_roaming = 3878 (cfg_p2p_is_roam_config_disabled(psoc) && 3879 (policy_mgr_mode_specific_connection_count( 3880 psoc, PM_P2P_CLIENT_MODE, NULL) || 3881 policy_mgr_mode_specific_connection_count( 3882 psoc, PM_P2P_GO_MODE, NULL))); 3883 nan_disable_sta_roaming = 3884 (cfg_nan_is_roam_config_disabled(psoc) && 3885 policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE, NULL)); 3886 3887 if ((command == ROAM_SCAN_OFFLOAD_START || 3888 command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) && 3889 (p2p_disable_sta_roaming || nan_disable_sta_roaming)) { 3890 mlme_info("roaming not supported for active %s connection", 3891 p2p_disable_sta_roaming ? "p2p" : "ndi"); 3892 return QDF_STATUS_E_FAILURE; 3893 } 3894 3895 /* 3896 * The Dynamic Config Items Update may happen even if the state is in 3897 * INIT. It is important to ensure that the command is passed down to 3898 * the FW only if the Infra Station is in a connected state. A connected 3899 * station could also be in a PREAUTH or REASSOC states. 3900 * 1) Block all CMDs that are not STOP in INIT State. For STOP always 3901 * inform firmware irrespective of state. 3902 * 2) Block update cfg CMD if its for REASON_ROAM_SET_DENYLIST_BSSID, 3903 * because we need to inform firmware of denylisted AP for PNO in 3904 * all states. 3905 */ 3906 if ((cm_is_vdev_disconnecting(vdev) || 3907 cm_is_vdev_disconnected(vdev)) && 3908 (command != ROAM_SCAN_OFFLOAD_STOP) && 3909 (reason != REASON_ROAM_SET_DENYLIST_BSSID)) { 3910 mlme_info("Scan Command not sent to FW and cmd=%d", command); 3911 return QDF_STATUS_E_FAILURE; 3912 } 3913 3914 return QDF_STATUS_SUCCESS; 3915 } 3916 3917 static QDF_STATUS cm_is_rso_allowed(struct wlan_objmgr_psoc *psoc, 3918 uint8_t vdev_id, uint8_t command, 3919 uint8_t reason) 3920 { 3921 struct wlan_objmgr_vdev *vdev; 3922 QDF_STATUS status; 3923 3924 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 3925 WLAN_MLME_CM_ID); 3926 if (!vdev) { 3927 mlme_err("vdev_id: %d: vdev not found", vdev_id); 3928 return QDF_STATUS_E_FAILURE; 3929 } 3930 status = cm_roam_cmd_allowed(psoc, vdev, command, reason); 3931 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3932 3933 return status; 3934 } 3935 3936 void cm_handle_sta_sta_roaming_enablement(struct wlan_objmgr_psoc *psoc, 3937 uint8_t curr_vdev_id) 3938 { 3939 struct wlan_objmgr_vdev *vdev; 3940 struct wlan_objmgr_pdev *pdev; 3941 uint32_t sta_count, conn_idx = 0; 3942 struct dual_sta_policy *dual_sta_policy; 3943 struct wlan_mlme_psoc_ext_obj *mlme_obj; 3944 uint8_t temp_vdev_id; 3945 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 3946 3947 mlme_obj = mlme_get_psoc_ext_obj(psoc); 3948 if (!mlme_obj) 3949 return; 3950 3951 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, curr_vdev_id, 3952 WLAN_MLME_CM_ID); 3953 if (!vdev) { 3954 mlme_debug("vdev object is NULL"); 3955 return; 3956 } 3957 3958 pdev = wlan_vdev_get_pdev(vdev); 3959 if (!pdev) 3960 goto rel_ref; 3961 3962 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 3963 sta_count = policy_mgr_get_mode_specific_conn_info(psoc, NULL, 3964 vdev_id_list, 3965 PM_STA_MODE); 3966 3967 if (!(wlan_mlme_get_dual_sta_roaming_enabled(psoc) && sta_count >= 2)) { 3968 mlme_debug("Dual sta roaming is not enabled or count:%d", 3969 sta_count); 3970 goto rel_ref; 3971 } 3972 3973 if (policy_mgr_concurrent_sta_on_different_mac(psoc)) { 3974 mlme_debug("After roam on vdev_id:%d, sta concurrency on different mac:%d", 3975 curr_vdev_id, sta_count); 3976 for (conn_idx = 0; conn_idx < sta_count; conn_idx++) { 3977 temp_vdev_id = vdev_id_list[conn_idx]; 3978 wlan_cm_roam_activate_pcl_per_vdev(psoc, 3979 temp_vdev_id, 3980 true); 3981 /* Set PCL after sending roam complete */ 3982 policy_mgr_set_pcl_for_existing_combo(psoc, 3983 PM_STA_MODE, 3984 temp_vdev_id); 3985 if (temp_vdev_id != curr_vdev_id) { 3986 /* Enable roaming on secondary vdev */ 3987 if_mgr_enable_roaming(pdev, vdev, RSO_SET_PCL); 3988 } 3989 } 3990 } else { 3991 mlme_debug("After roam STA + STA concurrency is in MCC/SCC"); 3992 } 3993 rel_ref: 3994 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 3995 } 3996 3997 QDF_STATUS cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc, 3998 uint8_t vdev_id, uint8_t rso_command, 3999 uint8_t reason) 4000 { 4001 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4002 4003 status = cm_is_rso_allowed(psoc, vdev_id, rso_command, reason); 4004 4005 if (status == QDF_STATUS_E_NOSUPPORT) 4006 return QDF_STATUS_SUCCESS; 4007 if (QDF_IS_STATUS_ERROR(status)) { 4008 mlme_debug("ROAM: not allowed"); 4009 return status; 4010 } 4011 4012 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 4013 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 4014 return QDF_STATUS_SUCCESS; 4015 } 4016 4017 /* 4018 * Update PER config to FW. No need to update in case of stop command, 4019 * FW takes care of stopping this internally 4020 */ 4021 if (rso_command != ROAM_SCAN_OFFLOAD_STOP) 4022 cm_roam_offload_per_config(psoc, vdev_id); 4023 4024 if (rso_command == ROAM_SCAN_OFFLOAD_START) 4025 status = cm_roam_start_req(psoc, vdev_id, reason); 4026 else if (rso_command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) 4027 status = cm_roam_update_config_req(psoc, vdev_id, reason); 4028 else if (rso_command == ROAM_SCAN_OFFLOAD_RESTART) 4029 status = cm_roam_restart_req(psoc, vdev_id, reason); 4030 else if (rso_command == ROAM_SCAN_OFFLOAD_ABORT_SCAN) 4031 status = cm_roam_abort_req(psoc, vdev_id, reason); 4032 else 4033 mlme_debug("ROAM: invalid RSO command %d", rso_command); 4034 4035 return status; 4036 } 4037 4038 /** 4039 * cm_roam_switch_to_rso_stop() - roam state handling for rso stop 4040 * @pdev: pdev pointer 4041 * @vdev_id: vdev id 4042 * @reason: reason for changing roam state for the requested vdev id 4043 * @send_resp: 4044 * @start_timer: 4045 * 4046 * This function is used for WLAN_ROAM_RSO_STOPPED roam state handling 4047 * 4048 * Return: QDF_STATUS 4049 */ 4050 static QDF_STATUS 4051 cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev, 4052 uint8_t vdev_id, 4053 uint8_t reason, bool *send_resp, bool start_timer) 4054 { 4055 enum roam_offload_state cur_state; 4056 QDF_STATUS status; 4057 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4058 4059 cur_state = mlme_get_roam_state(psoc, vdev_id); 4060 switch (cur_state) { 4061 case WLAN_ROAM_RSO_ENABLED: 4062 case WLAN_ROAMING_IN_PROG: 4063 case WLAN_ROAM_SYNCH_IN_PROG: 4064 status = cm_roam_stop_req(psoc, vdev_id, reason, 4065 send_resp, start_timer); 4066 if (QDF_IS_STATUS_ERROR(status)) { 4067 mlme_err("ROAM: Unable to switch to RSO STOP State"); 4068 return QDF_STATUS_E_FAILURE; 4069 } 4070 break; 4071 4072 case WLAN_ROAM_DEINIT: 4073 case WLAN_ROAM_RSO_STOPPED: 4074 case WLAN_ROAM_INIT: 4075 /* 4076 * Already the roaming module is initialized at fw, 4077 * nothing to do here 4078 */ 4079 default: 4080 return QDF_STATUS_SUCCESS; 4081 } 4082 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED); 4083 4084 return QDF_STATUS_SUCCESS; 4085 } 4086 4087 /** 4088 * cm_roam_switch_to_deinit() - roam state handling for roam deinit 4089 * @pdev: pdev pointer 4090 * @vdev_id: vdev id 4091 * @reason: reason for changing roam state for the requested vdev id 4092 * 4093 * This function is used for WLAN_ROAM_DEINIT roam state handling 4094 * 4095 * Return: QDF_STATUS 4096 */ 4097 static QDF_STATUS 4098 cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev, 4099 uint8_t vdev_id, 4100 uint8_t reason) 4101 { 4102 QDF_STATUS status; 4103 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4104 enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); 4105 bool sup_disabled_roam; 4106 4107 switch (cur_state) { 4108 /* 4109 * If RSO stop is not done already, send RSO stop first and 4110 * then post deinit. 4111 */ 4112 case WLAN_ROAM_RSO_ENABLED: 4113 case WLAN_ROAMING_IN_PROG: 4114 case WLAN_ROAM_SYNCH_IN_PROG: 4115 cm_roam_switch_to_rso_stop(pdev, vdev_id, reason, NULL, false); 4116 break; 4117 case WLAN_ROAM_RSO_STOPPED: 4118 /* 4119 * When Supplicant disabled roaming is set and roam invoke 4120 * command is received from userspace, fw starts to roam. 4121 * But meanwhile if a disassoc/deauth is received from AP or if 4122 * NB disconnect is initiated while supplicant disabled roam, 4123 * RSO stop with ROAM scan mode as 0 is not sent to firmware 4124 * since the previous state was RSO_STOPPED. This could lead 4125 * to firmware not sending peer unmap event for the current 4126 * AP. To avoid this, if previous RSO stop was sent with 4127 * ROAM scan mode as 4, send RSO stop with Roam scan mode as 0 4128 * and then switch to ROAM_DEINIT. 4129 */ 4130 sup_disabled_roam = 4131 mlme_get_supplicant_disabled_roaming(psoc, 4132 vdev_id); 4133 if (sup_disabled_roam) { 4134 mlme_err("vdev[%d]: supplicant disabled roam. clear roam scan mode", 4135 vdev_id); 4136 status = cm_roam_stop_req(psoc, vdev_id, 4137 REASON_DISCONNECTED, 4138 NULL, false); 4139 if (QDF_IS_STATUS_ERROR(status)) 4140 mlme_err("ROAM: Unable to clear roam scan mode"); 4141 } 4142 break; 4143 case WLAN_ROAM_INIT: 4144 break; 4145 4146 case WLAN_MLO_ROAM_SYNCH_IN_PROG: 4147 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4148 break; 4149 4150 case WLAN_ROAM_DEINIT: 4151 /* 4152 * Already the roaming module is de-initialized at fw, 4153 * do nothing here 4154 */ 4155 default: 4156 return QDF_STATUS_SUCCESS; 4157 } 4158 4159 status = cm_roam_init_req(psoc, vdev_id, false); 4160 if (QDF_IS_STATUS_ERROR(status)) 4161 return status; 4162 4163 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4164 mlme_clear_operations_bitmap(psoc, vdev_id); 4165 wlan_cm_roam_activate_pcl_per_vdev(psoc, vdev_id, false); 4166 4167 /* In case of roaming getting disabled due to 4168 * REASON_ROAM_SET_PRIMARY reason, don't enable roaming on 4169 * the other vdev as that is taken care by the caller once roaming 4170 * on this "vdev_id" is disabled. 4171 */ 4172 if (reason != REASON_SUPPLICANT_INIT_ROAMING && 4173 reason != REASON_ROAM_SET_PRIMARY) { 4174 mlme_debug("vdev_id:%d enable roaming on other connected sta - reason:%d", 4175 vdev_id, reason); 4176 wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id); 4177 } 4178 4179 return QDF_STATUS_SUCCESS; 4180 } 4181 4182 /** 4183 * cm_roam_switch_to_init() - roam state handling for roam init 4184 * @pdev: pdev pointer 4185 * @vdev_id: vdev id 4186 * @reason: reason for changing roam state for the requested vdev id 4187 * 4188 * This function is used for WLAN_ROAM_INIT roam state handling 4189 * 4190 * Return: QDF_STATUS 4191 */ 4192 static QDF_STATUS 4193 cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev, 4194 uint8_t vdev_id, 4195 uint8_t reason) 4196 { 4197 enum roam_offload_state cur_state; 4198 uint8_t temp_vdev_id, roam_enabled_vdev_id; 4199 uint32_t roaming_bitmap; 4200 bool dual_sta_roam_active, usr_disabled_roaming; 4201 bool sta_concurrency_is_with_different_mac; 4202 QDF_STATUS status; 4203 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4204 struct wlan_mlme_psoc_ext_obj *mlme_obj; 4205 struct dual_sta_policy *dual_sta_policy; 4206 struct wlan_objmgr_vdev *vdev; 4207 4208 if (!psoc) 4209 return QDF_STATUS_E_FAILURE; 4210 4211 mlme_obj = mlme_get_psoc_ext_obj(psoc); 4212 if (!mlme_obj) 4213 return QDF_STATUS_E_FAILURE; 4214 4215 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 4216 dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc); 4217 sta_concurrency_is_with_different_mac = 4218 policy_mgr_concurrent_sta_on_different_mac(psoc); 4219 cur_state = mlme_get_roam_state(psoc, vdev_id); 4220 4221 mlme_info("dual_sta_roam_active:%d, sta concurrency on different mac:%d, state:%d", 4222 dual_sta_roam_active, sta_concurrency_is_with_different_mac, 4223 cur_state); 4224 4225 switch (cur_state) { 4226 case WLAN_ROAM_DEINIT: 4227 roaming_bitmap = mlme_get_roam_trigger_bitmap(psoc, vdev_id); 4228 if (!roaming_bitmap) { 4229 mlme_info("CM_RSO: Cannot change to INIT state for vdev[%d]", 4230 vdev_id); 4231 return QDF_STATUS_E_FAILURE; 4232 } 4233 4234 /* 4235 * Enable roaming on other interface only if STA + STA 4236 * concurrency on different mac. 4237 */ 4238 if (dual_sta_roam_active && 4239 sta_concurrency_is_with_different_mac) { 4240 mlme_info("sta concurrency on different mac"); 4241 break; 4242 } 4243 4244 /* 4245 * If dual sta roaming is not supported, do not enable 4246 * the RSO on the second STA interface, even if the 4247 * primary interface config is present via dual sta policy 4248 */ 4249 temp_vdev_id = policy_mgr_get_roam_enabled_sta_session_id( 4250 psoc, vdev_id); 4251 if (!dual_sta_roam_active && 4252 temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 4253 mlme_debug("Do not enable RSO on %d, RSO is enabled on %d", 4254 vdev_id, temp_vdev_id); 4255 return QDF_STATUS_E_FAILURE; 4256 } 4257 4258 /* 4259 * set_primary_vdev usecase is to use that 4260 * interface(e.g. wlan0) over the other 4261 * interface(i.e. wlan1) for data transfer. Non-primary 4262 * vdev use case is to check the quality of that link 4263 * and decide if data can be switched to it and make it 4264 * primary. 4265 * Enabling roaming on non-primary vdev also in this 4266 * context would always helps to find better AP. 4267 */ 4268 if (wlan_mlme_is_primary_interface_configured(psoc) && 4269 (reason != REASON_SUPPLICANT_INIT_ROAMING)) { 4270 mlme_info("STA + STA concurrency with a primary iface, have roaming enabled on both interfaces"); 4271 break; 4272 } 4273 4274 /* 4275 * Disable roaming on the enabled sta if supplicant wants to 4276 * enable roaming on this vdev id 4277 */ 4278 if (temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 4279 /* 4280 * Roam init state can be requested as part of 4281 * initial connection or due to enable from 4282 * supplicant via vendor command. This check will 4283 * ensure roaming does not get enabled on this STA 4284 * vdev id if it is not an explicit enable from 4285 * supplicant. 4286 */ 4287 mlme_debug("Interface vdev_id: %d, roaming enabled on vdev_id: %d, reason:%d", 4288 vdev_id, temp_vdev_id, 4289 reason); 4290 4291 if (reason == REASON_SUPPLICANT_INIT_ROAMING) { 4292 cm_roam_state_change(pdev, temp_vdev_id, 4293 WLAN_ROAM_DEINIT, 4294 reason, 4295 NULL, false); 4296 } else { 4297 mlme_info("CM_RSO: Roam module already initialized on vdev:[%d]", 4298 temp_vdev_id); 4299 return QDF_STATUS_E_FAILURE; 4300 } 4301 } 4302 break; 4303 4304 case WLAN_ROAM_SYNCH_IN_PROG: 4305 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_INIT); 4306 return QDF_STATUS_SUCCESS; 4307 4308 case WLAN_ROAM_INIT: 4309 case WLAN_ROAM_RSO_STOPPED: 4310 case WLAN_ROAM_RSO_ENABLED: 4311 case WLAN_ROAMING_IN_PROG: 4312 /* 4313 * Already the roaming module is initialized at fw, 4314 * just return from here 4315 */ 4316 default: 4317 return QDF_STATUS_SUCCESS; 4318 } 4319 4320 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 4321 WLAN_MLME_NB_ID); 4322 if (!vdev) { 4323 mlme_err("CM_RSO: vdev is null"); 4324 return QDF_STATUS_E_INVAL; 4325 } 4326 4327 if (cm_is_vdev_disconnecting(vdev) || 4328 cm_is_vdev_disconnected(vdev)) { 4329 mlme_debug("CM_RSO: RSO Init received in disconnected state"); 4330 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4331 return QDF_STATUS_E_INVAL; 4332 } 4333 4334 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4335 4336 status = cm_roam_init_req(psoc, vdev_id, true); 4337 4338 if (QDF_IS_STATUS_ERROR(status)) 4339 return status; 4340 4341 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_INIT); 4342 4343 roam_enabled_vdev_id = 4344 policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id); 4345 4346 /* Send PDEV pcl command if only one STA is in connected state 4347 * If there is another STA connection exist, then set the 4348 * PCL type to vdev level 4349 */ 4350 if (roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX && 4351 dual_sta_roam_active && sta_concurrency_is_with_different_mac) 4352 wlan_cm_roam_activate_pcl_per_vdev(psoc, vdev_id, true); 4353 4354 /* Set PCL before sending RSO start */ 4355 policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, vdev_id); 4356 4357 wlan_mlme_get_usr_disabled_roaming(psoc, &usr_disabled_roaming); 4358 if (usr_disabled_roaming) { 4359 status = 4360 cm_roam_send_disable_config( 4361 psoc, vdev_id, 4362 WMI_VDEV_ROAM_11KV_CTRL_DISABLE_FW_TRIGGER_ROAMING); 4363 4364 if (!QDF_IS_STATUS_SUCCESS(status)) 4365 mlme_err("ROAM: fast roaming disable failed. status %d", 4366 status); 4367 } 4368 4369 return QDF_STATUS_SUCCESS; 4370 } 4371 4372 /** 4373 * cm_roam_switch_to_rso_enable() - roam state handling for rso started 4374 * @pdev: pdev pointer 4375 * @vdev_id: vdev id 4376 * @reason: reason for changing roam state for the requested vdev id 4377 * 4378 * This function is used for WLAN_ROAM_RSO_ENABLED roam state handling 4379 * 4380 * Return: QDF_STATUS 4381 */ 4382 static QDF_STATUS 4383 cm_roam_switch_to_rso_enable(struct wlan_objmgr_pdev *pdev, 4384 uint8_t vdev_id, 4385 uint8_t reason) 4386 { 4387 enum roam_offload_state cur_state, new_roam_state; 4388 QDF_STATUS status; 4389 uint8_t control_bitmap; 4390 bool sup_disabled_roaming; 4391 bool rso_allowed; 4392 uint8_t rso_command = ROAM_SCAN_OFFLOAD_START; 4393 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4394 4395 wlan_mlme_get_roam_scan_offload_enabled(psoc, &rso_allowed); 4396 sup_disabled_roaming = mlme_get_supplicant_disabled_roaming(psoc, 4397 vdev_id); 4398 control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id); 4399 4400 cur_state = mlme_get_roam_state(psoc, vdev_id); 4401 mlme_debug("CM_RSO: vdev%d: cur_state : %d reason:%d control_bmap:0x%x sup_disabled_roam:%d", 4402 vdev_id, cur_state, reason, control_bitmap, 4403 sup_disabled_roaming); 4404 4405 switch (cur_state) { 4406 case WLAN_ROAM_INIT: 4407 case WLAN_ROAM_RSO_STOPPED: 4408 break; 4409 4410 case WLAN_ROAM_DEINIT: 4411 status = cm_roam_switch_to_init(pdev, vdev_id, reason); 4412 if (QDF_IS_STATUS_ERROR(status)) 4413 return status; 4414 4415 break; 4416 case WLAN_ROAM_RSO_ENABLED: 4417 /* 4418 * Send RSO update config if roaming already enabled 4419 */ 4420 rso_command = ROAM_SCAN_OFFLOAD_UPDATE_CFG; 4421 break; 4422 case WLAN_ROAMING_IN_PROG: 4423 /* 4424 * When roam abort happens, the roam offload 4425 * state machine moves to RSO_ENABLED state. 4426 * But if Supplicant disabled roaming is set in case 4427 * of roam invoke or if roaming was disabled due to 4428 * other reasons like SAP start/connect on other vdev, 4429 * the state should be transitioned to RSO STOPPED. 4430 */ 4431 if (sup_disabled_roaming || control_bitmap) 4432 new_roam_state = WLAN_ROAM_RSO_STOPPED; 4433 else 4434 new_roam_state = WLAN_ROAM_RSO_ENABLED; 4435 4436 mlme_set_roam_state(psoc, vdev_id, new_roam_state); 4437 4438 return QDF_STATUS_SUCCESS; 4439 case WLAN_ROAM_SYNCH_IN_PROG: 4440 if (reason == REASON_ROAM_ABORT) { 4441 mlme_debug("Roam synch in progress, drop Roam abort"); 4442 return QDF_STATUS_SUCCESS; 4443 } 4444 /* 4445 * After roam sych propagation is complete, send 4446 * RSO start command to firmware to update AP profile, 4447 * new PCL. 4448 * If this is roam invoke case and supplicant has already 4449 * disabled firmware roaming, then move to RSO stopped state 4450 * instead of RSO enabled. 4451 */ 4452 if (sup_disabled_roaming || control_bitmap) { 4453 new_roam_state = WLAN_ROAM_RSO_STOPPED; 4454 mlme_set_roam_state(psoc, vdev_id, new_roam_state); 4455 4456 return QDF_STATUS_SUCCESS; 4457 } 4458 4459 break; 4460 default: 4461 return QDF_STATUS_SUCCESS; 4462 } 4463 4464 if (!rso_allowed) { 4465 mlme_debug("ROAM: RSO disabled via INI"); 4466 return QDF_STATUS_E_FAILURE; 4467 } 4468 4469 if (control_bitmap) { 4470 mlme_debug("ROAM: RSO Disabled internally: vdev[%d] bitmap[0x%x]", 4471 vdev_id, control_bitmap); 4472 return QDF_STATUS_E_FAILURE; 4473 } 4474 4475 status = cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason); 4476 if (QDF_IS_STATUS_ERROR(status)) { 4477 mlme_err("ROAM: vdev:%d RSO start failed", vdev_id); 4478 return status; 4479 } 4480 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_ENABLED); 4481 4482 /* If the set_key for the connected bssid was received during Roam sync 4483 * in progress, then the RSO update to the FW will be rejected. The RSO 4484 * start which might be in progress during set_key could send stale pmk 4485 * to the FW. Therefore, once RSO is enabled, send the RSO update with 4486 * the PMK received from the __wlan_hdd_cfg80211_keymgmt_set_key. 4487 */ 4488 if (wlan_mlme_is_pmk_set_deferred(psoc, vdev_id)) { 4489 cm_roam_send_rso_cmd(psoc, vdev_id, 4490 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 4491 REASON_ROAM_PSK_PMK_CHANGED); 4492 wlan_mlme_defer_pmk_set_in_roaming(psoc, vdev_id, false); 4493 } 4494 4495 /* 4496 * If supplicant disabled roaming, driver does not send 4497 * RSO cmd to fw. This causes roam invoke to fail in FW 4498 * since RSO start never happened at least once to 4499 * configure roaming engine in FW. So send RSO start followed 4500 * by RSO stop if supplicant disabled roaming is true. 4501 */ 4502 if (!sup_disabled_roaming) 4503 return QDF_STATUS_SUCCESS; 4504 4505 mlme_debug("ROAM: RSO disabled by Supplicant on vdev[%d]", vdev_id); 4506 return cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STOPPED, 4507 REASON_SUPPLICANT_DISABLED_ROAMING, 4508 NULL, false); 4509 } 4510 4511 /** 4512 * cm_roam_switch_to_roam_start() - roam state handling for ROAMING_IN_PROG 4513 * @pdev: pdev pointer 4514 * @vdev_id: vdev id 4515 * @reason: reason for changing roam state for the requested vdev id 4516 * 4517 * This function is used for WLAN_ROAMING_IN_PROG roam state handling 4518 * 4519 * Return: QDF_STATUS 4520 */ 4521 static QDF_STATUS 4522 cm_roam_switch_to_roam_start(struct wlan_objmgr_pdev *pdev, 4523 uint8_t vdev_id, 4524 uint8_t reason) 4525 { 4526 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4527 enum roam_offload_state cur_state = 4528 mlme_get_roam_state(psoc, vdev_id); 4529 switch (cur_state) { 4530 case WLAN_ROAMING_IN_PROG: 4531 mlme_debug("Roam started already on vdev[%d]", vdev_id); 4532 break; 4533 case WLAN_ROAM_RSO_ENABLED: 4534 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAMING_IN_PROG); 4535 break; 4536 4537 case WLAN_ROAM_RSO_STOPPED: 4538 /* 4539 * When supplicant has disabled roaming, roam invoke triggered 4540 * from supplicant can cause firmware to send roam start 4541 * notification. Allow roam start in this condition. 4542 */ 4543 if (mlme_get_supplicant_disabled_roaming(psoc, vdev_id) && 4544 4545 wlan_cm_roaming_in_progress(pdev, vdev_id)) { 4546 mlme_set_roam_state(psoc, vdev_id, 4547 WLAN_ROAMING_IN_PROG); 4548 break; 4549 } 4550 fallthrough; 4551 case WLAN_ROAM_INIT: 4552 case WLAN_ROAM_DEINIT: 4553 case WLAN_ROAM_SYNCH_IN_PROG: 4554 default: 4555 mlme_err("ROAM: Roaming start received in invalid state: %d", 4556 cur_state); 4557 return QDF_STATUS_E_FAILURE; 4558 } 4559 4560 return QDF_STATUS_SUCCESS; 4561 } 4562 4563 /** 4564 * cm_roam_switch_to_roam_sync() - roam state handling for roam sync 4565 * @pdev: pdev pointer 4566 * @vdev_id: vdev id 4567 * @reason: reason for changing roam state for the requested vdev id 4568 * 4569 * This function is used for WLAN_ROAM_SYNCH_IN_PROG roam state handling 4570 * 4571 * Return: QDF_STATUS 4572 */ 4573 static QDF_STATUS 4574 cm_roam_switch_to_roam_sync(struct wlan_objmgr_pdev *pdev, 4575 uint8_t vdev_id, 4576 uint8_t reason) 4577 { 4578 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4579 enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); 4580 4581 switch (cur_state) { 4582 case WLAN_ROAM_RSO_ENABLED: 4583 /* 4584 * Roam synch can come directly without roam start 4585 * after waking up from power save mode or in case of 4586 * deauth roam trigger to stop data path queues 4587 */ 4588 case WLAN_ROAMING_IN_PROG: 4589 if (!cm_is_vdevid_active(pdev, vdev_id)) { 4590 mlme_err("ROAM: STA not in connected state"); 4591 return QDF_STATUS_E_FAILURE; 4592 } 4593 4594 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_SYNCH_IN_PROG); 4595 break; 4596 case WLAN_ROAM_RSO_STOPPED: 4597 /* 4598 * If roaming is disabled by Supplicant and if this transition 4599 * is due to roaming invoked by the supplicant, then allow 4600 * this state transition 4601 */ 4602 if (mlme_get_supplicant_disabled_roaming(psoc, vdev_id) && 4603 wlan_cm_roaming_in_progress(pdev, vdev_id)) { 4604 mlme_set_roam_state(psoc, vdev_id, 4605 WLAN_ROAM_SYNCH_IN_PROG); 4606 break; 4607 } 4608 /* 4609 * transition to WLAN_ROAM_SYNCH_IN_PROG not allowed otherwise 4610 * if we're already RSO stopped, fall through to return failure 4611 */ 4612 fallthrough; 4613 case WLAN_ROAM_INIT: 4614 case WLAN_ROAM_DEINIT: 4615 case WLAN_ROAM_SYNCH_IN_PROG: 4616 default: 4617 mlme_err("ROAM: Roam synch not allowed in [%d] state", 4618 cur_state); 4619 return QDF_STATUS_E_FAILURE; 4620 } 4621 4622 return QDF_STATUS_SUCCESS; 4623 } 4624 4625 #ifdef FEATURE_ROAM_DEBUG 4626 /** 4627 * union rso_rec_arg1 - argument 1 record rso state change 4628 * @value: aggregate value of the structured param 4629 * @request_st: requested rso state 4630 * @cur_st: current rso state 4631 * @new_st: new rso state 4632 * @status: qdf status for the request 4633 */ 4634 union rso_rec_arg1 { 4635 uint32_t value; 4636 struct { 4637 uint32_t request_st:4, 4638 cur_st:4, 4639 new_st:4, 4640 status:8; 4641 }; 4642 }; 4643 4644 /** 4645 * get_rso_arg1 - get argument 1 record rso state change 4646 * @request_st: requested rso state 4647 * @cur_st: current rso state 4648 * @new_st: new rso state 4649 * @status: qdf status for the request 4650 * 4651 * Return: u32 value of rso information 4652 */ 4653 static uint32_t get_rso_arg1(enum roam_offload_state request_st, 4654 enum roam_offload_state cur_st, 4655 enum roam_offload_state new_st, 4656 QDF_STATUS status) 4657 { 4658 union rso_rec_arg1 rso_arg1; 4659 4660 rso_arg1.value = 0; 4661 rso_arg1.request_st = request_st; 4662 rso_arg1.cur_st = cur_st; 4663 rso_arg1.new_st = new_st; 4664 rso_arg1.status = status; 4665 4666 return rso_arg1.value; 4667 } 4668 4669 /** 4670 * union rso_rec_arg2 - argument 2 record rso state change 4671 * @value: aggregate value of the structured param 4672 * @is_up: vdev is up 4673 * @supp_dis_roam: supplicant disable roam 4674 * @roam_progress: roam in progress 4675 * @ctrl_bitmap: control bitmap 4676 * @reason: reason code 4677 * 4678 * Return: u32 value of rso information 4679 */ 4680 union rso_rec_arg2 { 4681 uint32_t value; 4682 struct { 4683 uint32_t is_up: 1, 4684 supp_dis_roam:1, 4685 roam_progress:1, 4686 ctrl_bitmap:8, 4687 reason:8; 4688 }; 4689 }; 4690 4691 /** 4692 * get_rso_arg2 - get argument 2 record rso state change 4693 * @is_up: vdev is up 4694 * @supp_dis_roam: supplicant disable roam 4695 * @roam_progress: roam in progress 4696 * @ctrl_bitmap: control bitmap 4697 * @reason: reason code 4698 */ 4699 static uint32_t get_rso_arg2(bool is_up, 4700 bool supp_dis_roam, 4701 bool roam_progress, 4702 uint8_t ctrl_bitmap, 4703 uint8_t reason) 4704 { 4705 union rso_rec_arg2 rso_arg2; 4706 4707 rso_arg2.value = 0; 4708 if (is_up) 4709 rso_arg2.is_up = 1; 4710 if (supp_dis_roam) 4711 rso_arg2.supp_dis_roam = 1; 4712 if (roam_progress) 4713 rso_arg2.roam_progress = 1; 4714 rso_arg2.ctrl_bitmap = ctrl_bitmap; 4715 rso_arg2.reason = reason; 4716 4717 return rso_arg2.value; 4718 } 4719 4720 /** 4721 * cm_record_state_change() - record rso state change to roam history log 4722 * @pdev: pdev object 4723 * @vdev_id: vdev id 4724 * @cur_st: current state 4725 * @requested_state: requested state 4726 * @reason: reason 4727 * @is_up: vdev is up 4728 * @status: request result code 4729 * 4730 * This function will record the RSO state change to roam history log. 4731 * 4732 * Return: void 4733 */ 4734 static void 4735 cm_record_state_change(struct wlan_objmgr_pdev *pdev, 4736 uint8_t vdev_id, 4737 enum roam_offload_state cur_st, 4738 enum roam_offload_state requested_state, 4739 uint8_t reason, 4740 bool is_up, 4741 QDF_STATUS status) 4742 { 4743 enum roam_offload_state new_state; 4744 bool supp_dis_roam; 4745 bool roam_progress; 4746 uint8_t control_bitmap; 4747 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4748 4749 if (!psoc) 4750 return; 4751 4752 new_state = mlme_get_roam_state(psoc, vdev_id); 4753 control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id); 4754 supp_dis_roam = mlme_get_supplicant_disabled_roaming(psoc, vdev_id); 4755 roam_progress = wlan_cm_roaming_in_progress(pdev, vdev_id); 4756 wlan_rec_conn_info(vdev_id, DEBUG_CONN_RSO, 4757 NULL, 4758 get_rso_arg1(requested_state, cur_st, 4759 new_state, status), 4760 get_rso_arg2(is_up, 4761 supp_dis_roam, roam_progress, 4762 control_bitmap, reason)); 4763 } 4764 #else 4765 static inline void 4766 cm_record_state_change(struct wlan_objmgr_pdev *pdev, 4767 uint8_t vdev_id, 4768 enum roam_offload_state cur_st, 4769 enum roam_offload_state requested_state, 4770 uint8_t reason, 4771 bool is_up, 4772 QDF_STATUS status) 4773 { 4774 } 4775 #endif 4776 4777 #ifdef WLAN_FEATURE_11BE_MLO 4778 /** 4779 * cm_mlo_roam_switch_for_link() - roam state handling during mlo roam 4780 * for link/s. 4781 * @pdev: pdev pointer 4782 * @vdev_id: vdev id 4783 * @reason: reason for changing roam state for the requested vdev id 4784 * 4785 * This function is used for WLAN_MLO_ROAM_SYNCH_IN_PROG roam state handling 4786 * 4787 * Return: QDF_STATUS 4788 */ 4789 static QDF_STATUS 4790 cm_mlo_roam_switch_for_link(struct wlan_objmgr_pdev *pdev, 4791 uint8_t vdev_id, uint8_t reason) 4792 { 4793 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4794 enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); 4795 4796 if (reason != REASON_ROAM_HANDOFF_DONE && 4797 reason != REASON_ROAM_ABORT && 4798 reason != REASON_ROAM_LINK_SWITCH_ASSOC_VDEV_CHANGE) { 4799 mlo_debug("CM_RSO: link vdev:%d state switch received with invalid reason:%d", 4800 vdev_id, reason); 4801 return QDF_STATUS_E_FAILURE; 4802 } 4803 4804 /* 4805 * change roam state to deinit for assoc vdev that has now changed to 4806 * link vdev 4807 */ 4808 if (reason == REASON_ROAM_LINK_SWITCH_ASSOC_VDEV_CHANGE) { 4809 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4810 return QDF_STATUS_SUCCESS; 4811 } 4812 4813 switch (cur_state) { 4814 case WLAN_ROAM_DEINIT: 4815 /* Only used for link vdev during MLO roaming */ 4816 mlme_set_roam_state(psoc, vdev_id, WLAN_MLO_ROAM_SYNCH_IN_PROG); 4817 break; 4818 case WLAN_MLO_ROAM_SYNCH_IN_PROG: 4819 mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT); 4820 break; 4821 default: 4822 mlme_err("ROAM: vdev:%d MLO Roam synch not allowed in [%d] state reason:%d", 4823 vdev_id, cur_state, reason); 4824 return QDF_STATUS_E_FAILURE; 4825 } 4826 4827 return QDF_STATUS_SUCCESS; 4828 } 4829 4830 QDF_STATUS 4831 cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id, 4832 enum roam_offload_state requested_state, 4833 uint8_t reason, bool *is_rso_skip) 4834 { 4835 QDF_STATUS status = QDF_STATUS_SUCCESS; 4836 struct wlan_objmgr_vdev *vdev; 4837 struct wlan_objmgr_vdev *assoc_vdev = NULL; 4838 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4839 4840 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, *vdev_id, 4841 WLAN_MLME_NB_ID); 4842 if (!vdev) 4843 return QDF_STATUS_E_FAILURE; 4844 4845 /* 4846 * When link switch is in progress, the MLO link flag would be reset and 4847 * set back on assoc vdev, so avoid any state transition during link 4848 * switch. 4849 */ 4850 if (wlan_vdev_mlme_get_is_mlo_vdev(psoc, *vdev_id) && 4851 mlo_mgr_is_link_switch_in_progress(vdev)) { 4852 mlme_debug("MLO ROAM: Link switch in prog! skip RSO cmd:%d on vdev %d", 4853 requested_state, *vdev_id); 4854 *is_rso_skip = true; 4855 goto end; 4856 } 4857 4858 if (wlan_vdev_mlme_get_is_mlo_vdev(psoc, *vdev_id) && 4859 cm_is_vdev_disconnecting(vdev) && 4860 (reason == REASON_DISCONNECTED || 4861 reason == REASON_DRIVER_DISABLED)) { 4862 /* 4863 * Processing disconnect on assoc vdev but roaming is still 4864 * enabled. It's either due to single ML usecase or failed to 4865 * connect to second link. 4866 */ 4867 if (!wlan_vdev_mlme_get_is_mlo_link(psoc, *vdev_id) && 4868 wlan_is_roaming_enabled(pdev, *vdev_id)) { 4869 mlme_debug("MLO ROAM: Process RSO cmd:%d on assoc vdev : %d", 4870 requested_state, *vdev_id); 4871 *is_rso_skip = false; 4872 } else { 4873 mlme_debug("MLO ROAM: skip RSO cmd:%d on assoc vdev %d", 4874 requested_state, *vdev_id); 4875 *is_rso_skip = true; 4876 } 4877 } 4878 4879 if (!wlan_vdev_mlme_get_is_mlo_link(wlan_pdev_get_psoc(pdev), 4880 *vdev_id)) 4881 goto end; 4882 4883 if (reason == REASON_ROAM_HANDOFF_DONE || reason == REASON_ROAM_ABORT) { 4884 status = cm_mlo_roam_switch_for_link(pdev, *vdev_id, reason); 4885 mlme_debug("MLO ROAM: update rso state on link vdev %d", 4886 *vdev_id); 4887 *is_rso_skip = true; 4888 } else if ((reason == REASON_DISCONNECTED || 4889 reason == REASON_DRIVER_DISABLED) && 4890 cm_is_vdev_disconnecting(vdev)) { 4891 assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev); 4892 4893 if (!assoc_vdev) { 4894 mlme_err("Assoc vdev is NULL"); 4895 status = QDF_STATUS_E_FAILURE; 4896 goto end; 4897 } 4898 /* Update the vdev id to send RSO stop on assoc vdev */ 4899 *vdev_id = wlan_vdev_get_id(assoc_vdev); 4900 *is_rso_skip = false; 4901 mlme_debug("MLO ROAM: process RSO stop on assoc vdev %d", 4902 *vdev_id); 4903 goto end; 4904 } else { 4905 mlme_debug("MLO ROAM: skip RSO cmd on link vdev %d", *vdev_id); 4906 *is_rso_skip = true; 4907 } 4908 end: 4909 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4910 return status; 4911 } 4912 #endif 4913 4914 QDF_STATUS 4915 cm_roam_state_change(struct wlan_objmgr_pdev *pdev, 4916 uint8_t vdev_id, 4917 enum roam_offload_state requested_state, 4918 uint8_t reason, bool *send_resp, bool start_timer) 4919 { 4920 QDF_STATUS status = QDF_STATUS_SUCCESS; 4921 struct wlan_objmgr_vdev *vdev; 4922 bool is_up; 4923 bool is_rso_skip = false; 4924 enum roam_offload_state cur_state; 4925 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 4926 4927 if (!psoc) 4928 return QDF_STATUS_E_INVAL; 4929 4930 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 4931 WLAN_MLME_NB_ID); 4932 if (!vdev) 4933 return status; 4934 4935 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) 4936 is_up = mlo_check_if_all_vdev_up(vdev); 4937 else 4938 is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev)); 4939 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 4940 4941 if (requested_state != WLAN_ROAM_DEINIT && !is_up) { 4942 mlme_debug("ROAM: roam state(%d) change requested in non-connected state", 4943 requested_state); 4944 goto end; 4945 } 4946 4947 status = cm_handle_mlo_rso_state_change(pdev, &vdev_id, requested_state, 4948 reason, &is_rso_skip); 4949 if (is_rso_skip) 4950 return status; 4951 4952 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 4953 WLAN_MLME_CM_ID); 4954 if (!vdev) { 4955 mlme_err("Invalid vdev:%d", vdev_id); 4956 goto end; 4957 } 4958 4959 status = cm_roam_acquire_lock(vdev); 4960 if (QDF_IS_STATUS_ERROR(status)) { 4961 mlme_err("Fail to acquire lock, status: %d", status); 4962 goto release_ref; 4963 } 4964 4965 switch (requested_state) { 4966 case WLAN_ROAM_DEINIT: 4967 status = cm_roam_switch_to_deinit(pdev, vdev_id, reason); 4968 break; 4969 case WLAN_ROAM_INIT: 4970 status = cm_roam_switch_to_init(pdev, vdev_id, reason); 4971 break; 4972 case WLAN_ROAM_RSO_ENABLED: 4973 status = cm_roam_switch_to_rso_enable(pdev, vdev_id, reason); 4974 break; 4975 case WLAN_ROAM_RSO_STOPPED: 4976 status = cm_roam_switch_to_rso_stop(pdev, vdev_id, reason, 4977 send_resp, start_timer); 4978 break; 4979 case WLAN_ROAMING_IN_PROG: 4980 status = cm_roam_switch_to_roam_start(pdev, vdev_id, reason); 4981 break; 4982 case WLAN_ROAM_SYNCH_IN_PROG: 4983 status = cm_roam_switch_to_roam_sync(pdev, vdev_id, reason); 4984 break; 4985 default: 4986 mlme_debug("ROAM: Invalid roam state %d", requested_state); 4987 break; 4988 } 4989 4990 cm_roam_release_lock(vdev); 4991 4992 release_ref: 4993 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 4994 end: 4995 cur_state = mlme_get_roam_state(psoc, vdev_id); 4996 cm_record_state_change(pdev, vdev_id, cur_state, requested_state, 4997 reason, is_up, status); 4998 4999 return status; 5000 } 5001 5002 #ifdef FEATURE_WLAN_ESE 5003 static QDF_STATUS 5004 cm_roam_channels_filter_by_current_band(struct wlan_objmgr_pdev *pdev, 5005 uint8_t vdev_id, 5006 qdf_freq_t *in_chan_freq_list, 5007 uint8_t in_num_chan, 5008 qdf_freq_t *out_chan_freq_list, 5009 uint8_t *merged_num_chan) 5010 { 5011 uint8_t i = 0; 5012 uint8_t num_chan = 0; 5013 uint32_t curr_ap_op_chan_freq = 5014 wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id); 5015 5016 /* Check for NULL pointer */ 5017 if (!in_chan_freq_list) 5018 return QDF_STATUS_E_INVAL; 5019 5020 /* Check for NULL pointer */ 5021 if (!out_chan_freq_list) 5022 return QDF_STATUS_E_INVAL; 5023 5024 if (in_num_chan > CFG_VALID_CHANNEL_LIST_LEN) { 5025 mlme_err("Wrong Number of Input Channels %d", in_num_chan); 5026 return QDF_STATUS_E_INVAL; 5027 } 5028 for (i = 0; i < in_num_chan; i++) { 5029 if (WLAN_REG_IS_SAME_BAND_FREQS(curr_ap_op_chan_freq, 5030 in_chan_freq_list[i])) { 5031 out_chan_freq_list[num_chan] = in_chan_freq_list[i]; 5032 num_chan++; 5033 } 5034 } 5035 5036 /* Return final number of channels */ 5037 *merged_num_chan = num_chan; 5038 5039 return QDF_STATUS_SUCCESS; 5040 } 5041 5042 static QDF_STATUS cm_roam_merge_channel_lists(qdf_freq_t *in_chan_freq_list, 5043 uint8_t in_num_chan, 5044 qdf_freq_t *out_chan_freq_list, 5045 uint8_t out_num_chan, 5046 uint8_t *merged_num_chan) 5047 { 5048 uint8_t i = 0; 5049 uint8_t j = 0; 5050 uint8_t num_chan = out_num_chan; 5051 5052 /* Check for NULL pointer */ 5053 if (!in_chan_freq_list) 5054 return QDF_STATUS_E_INVAL; 5055 5056 /* Check for NULL pointer */ 5057 if (!out_chan_freq_list) 5058 return QDF_STATUS_E_INVAL; 5059 5060 if (in_num_chan > CFG_VALID_CHANNEL_LIST_LEN) { 5061 mlme_err("Wrong Number of Input Channels %d", in_num_chan); 5062 return QDF_STATUS_E_INVAL; 5063 } 5064 if (out_num_chan >= CFG_VALID_CHANNEL_LIST_LEN) { 5065 mlme_err("Wrong Number of Output Channels %d", out_num_chan); 5066 return QDF_STATUS_E_INVAL; 5067 } 5068 /* Add the "new" channels in the input list to the end of the 5069 * output list. 5070 */ 5071 for (i = 0; i < in_num_chan; i++) { 5072 for (j = 0; j < out_num_chan; j++) { 5073 if (in_chan_freq_list[i] == out_chan_freq_list[j]) 5074 break; 5075 } 5076 if (j == out_num_chan) { 5077 if (in_chan_freq_list[i]) { 5078 mlme_debug("Adding extra %d to roam channel list", 5079 in_chan_freq_list[i]); 5080 out_chan_freq_list[num_chan] = 5081 in_chan_freq_list[i]; 5082 num_chan++; 5083 } 5084 } 5085 if (num_chan >= CFG_VALID_CHANNEL_LIST_LEN) { 5086 mlme_debug("Merge Neighbor channel list reached Max limit %d", 5087 in_num_chan); 5088 break; 5089 } 5090 } 5091 5092 /* Return final number of channels */ 5093 *merged_num_chan = num_chan; 5094 5095 return QDF_STATUS_SUCCESS; 5096 } 5097 5098 QDF_STATUS cm_create_roam_scan_channel_list(struct wlan_objmgr_pdev *pdev, 5099 struct rso_config *rso_cfg, 5100 uint8_t vdev_id, 5101 qdf_freq_t *chan_freq_list, 5102 uint8_t num_chan, 5103 const enum band_info band) 5104 { 5105 QDF_STATUS status = QDF_STATUS_SUCCESS; 5106 uint8_t out_num_chan = 0; 5107 uint8_t in_chan_num = num_chan; 5108 qdf_freq_t *in_ptr = chan_freq_list; 5109 uint8_t i = 0; 5110 qdf_freq_t *freq_list; 5111 qdf_freq_t *tmp_chan_freq_list; 5112 uint8_t merged_out_chan_num = 0; 5113 struct rso_chan_info *chan_lst; 5114 struct wlan_objmgr_psoc *psoc; 5115 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5116 struct wlan_mlme_reg *reg; 5117 5118 psoc = wlan_pdev_get_psoc(pdev); 5119 if (!psoc) 5120 return QDF_STATUS_E_INVAL; 5121 5122 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5123 if (!mlme_obj) 5124 return QDF_STATUS_E_INVAL; 5125 5126 reg = &mlme_obj->cfg.reg; 5127 chan_lst = &rso_cfg->roam_scan_freq_lst; 5128 /* 5129 * Create a Union of occupied channel list learnt by the DUT along 5130 * with the Neighbor report Channels. This increases the chances of 5131 * the DUT to get a candidate AP while roaming even if the Neighbor 5132 * Report is not able to provide sufficient information. 5133 */ 5134 if (rso_cfg->occupied_chan_lst.num_chan) { 5135 cm_roam_merge_channel_lists(rso_cfg->occupied_chan_lst.freq_list, 5136 rso_cfg->occupied_chan_lst.num_chan, 5137 in_ptr, in_chan_num, 5138 &merged_out_chan_num); 5139 in_chan_num = merged_out_chan_num; 5140 } 5141 5142 freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN * 5143 sizeof(qdf_freq_t)); 5144 if (!freq_list) 5145 return QDF_STATUS_E_NOMEM; 5146 5147 if (band == BAND_2G) { 5148 for (i = 0; i < in_chan_num; i++) { 5149 if (WLAN_REG_IS_24GHZ_CH_FREQ(in_ptr[i]) && 5150 wlan_roam_is_channel_valid(reg, in_ptr[i])) { 5151 freq_list[out_num_chan++] = in_ptr[i]; 5152 } 5153 } 5154 } else if (band == BAND_5G) { 5155 for (i = 0; i < in_chan_num; i++) { 5156 /* Add 5G Non-DFS channel */ 5157 if (WLAN_REG_IS_5GHZ_CH_FREQ(in_ptr[i]) && 5158 wlan_roam_is_channel_valid(reg, in_ptr[i]) && 5159 !wlan_reg_is_dfs_for_freq(pdev, in_ptr[i])) { 5160 freq_list[out_num_chan++] = in_ptr[i]; 5161 } 5162 } 5163 } else if (band == BAND_ALL) { 5164 for (i = 0; i < in_chan_num; i++) { 5165 if (wlan_roam_is_channel_valid(reg, in_ptr[i]) && 5166 !wlan_reg_is_dfs_for_freq(pdev, in_ptr[i])) { 5167 freq_list[out_num_chan++] = in_ptr[i]; 5168 } 5169 } 5170 } else { 5171 mlme_warn("Invalid band, No operation carried out (Band %d)", 5172 band); 5173 qdf_mem_free(freq_list); 5174 return QDF_STATUS_E_INVAL; 5175 } 5176 5177 tmp_chan_freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN * 5178 sizeof(qdf_freq_t)); 5179 if (!tmp_chan_freq_list) { 5180 qdf_mem_free(freq_list); 5181 return QDF_STATUS_E_NOMEM; 5182 } 5183 5184 /* 5185 * if roaming within band is enabled, then select only the 5186 * in band channels . 5187 * This is required only if the band capability is set to ALL, 5188 * E.g., if band capability is only 2.4G then all the channels in the 5189 * list are already filtered for 2.4G channels, hence ignore this check 5190 */ 5191 if ((band == BAND_ALL) && mlme_obj->cfg.lfr.roam_intra_band) 5192 cm_roam_channels_filter_by_current_band(pdev, vdev_id, 5193 freq_list, out_num_chan, 5194 tmp_chan_freq_list, 5195 &out_num_chan); 5196 5197 /* Prepare final roam scan channel list */ 5198 if (out_num_chan) { 5199 /* Clear the channel list first */ 5200 cm_flush_roam_channel_list(chan_lst); 5201 chan_lst->freq_list = 5202 qdf_mem_malloc(out_num_chan * sizeof(qdf_freq_t)); 5203 if (!chan_lst->freq_list) { 5204 chan_lst->num_chan = 0; 5205 status = QDF_STATUS_E_NOMEM; 5206 goto error; 5207 } 5208 for (i = 0; i < out_num_chan; i++) 5209 chan_lst->freq_list[i] = tmp_chan_freq_list[i]; 5210 5211 chan_lst->num_chan = out_num_chan; 5212 } 5213 5214 error: 5215 qdf_mem_free(tmp_chan_freq_list); 5216 qdf_mem_free(freq_list); 5217 5218 return status; 5219 } 5220 #endif 5221 5222 static const char *cm_get_config_item_string(uint8_t reason) 5223 { 5224 switch (reason) { 5225 CASE_RETURN_STRING(REASON_LOOKUP_THRESH_CHANGED); 5226 CASE_RETURN_STRING(REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED); 5227 CASE_RETURN_STRING(REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED); 5228 CASE_RETURN_STRING(REASON_ROAM_BMISS_FIRST_BCNT_CHANGED); 5229 CASE_RETURN_STRING(REASON_ROAM_BMISS_FINAL_BCNT_CHANGED); 5230 default: 5231 return "unknown"; 5232 } 5233 } 5234 5235 QDF_STATUS cm_neighbor_roam_update_config(struct wlan_objmgr_pdev *pdev, 5236 uint8_t vdev_id, uint8_t value, 5237 uint8_t reason) 5238 { 5239 uint8_t old_value; 5240 struct wlan_objmgr_vdev *vdev; 5241 struct rso_config *rso_cfg; 5242 struct rso_cfg_params *cfg_params; 5243 struct wlan_objmgr_psoc *psoc; 5244 5245 psoc = wlan_pdev_get_psoc(pdev); 5246 if (!psoc) 5247 return QDF_STATUS_E_FAILURE; 5248 5249 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 5250 WLAN_MLME_CM_ID); 5251 if (!vdev) { 5252 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5253 return QDF_STATUS_E_FAILURE; 5254 } 5255 rso_cfg = wlan_cm_get_rso_config(vdev); 5256 if (!rso_cfg) { 5257 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5258 return QDF_STATUS_E_FAILURE; 5259 } 5260 cfg_params = &rso_cfg->cfg_param; 5261 switch (reason) { 5262 case REASON_LOOKUP_THRESH_CHANGED: 5263 old_value = cfg_params->neighbor_lookup_threshold; 5264 cfg_params->neighbor_lookup_threshold = value; 5265 break; 5266 case REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED: 5267 old_value = cfg_params->opportunistic_threshold_diff; 5268 cfg_params->opportunistic_threshold_diff = value; 5269 break; 5270 case REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED: 5271 old_value = cfg_params->roam_rescan_rssi_diff; 5272 cfg_params->roam_rescan_rssi_diff = value; 5273 rso_cfg->rescan_rssi_delta = value; 5274 break; 5275 case REASON_ROAM_BMISS_FIRST_BCNT_CHANGED: 5276 old_value = cfg_params->roam_bmiss_first_bcn_cnt; 5277 cfg_params->roam_bmiss_first_bcn_cnt = value; 5278 break; 5279 case REASON_ROAM_BMISS_FINAL_BCNT_CHANGED: 5280 old_value = cfg_params->roam_bmiss_final_cnt; 5281 cfg_params->roam_bmiss_final_cnt = value; 5282 break; 5283 default: 5284 mlme_debug("Unknown update cfg reason"); 5285 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5286 return QDF_STATUS_E_FAILURE; 5287 } 5288 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5289 mlme_debug("CONNECTED, send update cfg cmd"); 5290 wlan_roam_update_cfg(psoc, vdev_id, reason); 5291 5292 mlme_debug("LFR config for %s changed from %d to %d", 5293 cm_get_config_item_string(reason), old_value, value); 5294 5295 return QDF_STATUS_SUCCESS; 5296 } 5297 5298 void cm_flush_roam_channel_list(struct rso_chan_info *channel_info) 5299 { 5300 /* Free up the memory first (if required) */ 5301 if (channel_info->freq_list) { 5302 qdf_mem_free(channel_info->freq_list); 5303 channel_info->freq_list = NULL; 5304 channel_info->num_chan = 0; 5305 } 5306 } 5307 5308 static void 5309 cm_restore_default_roaming_params(struct wlan_mlme_psoc_ext_obj *mlme_obj, 5310 struct wlan_objmgr_vdev *vdev) 5311 { 5312 struct rso_config *rso_cfg; 5313 struct rso_cfg_params *cfg_params; 5314 uint32_t current_band = REG_BAND_MASK_ALL; 5315 5316 rso_cfg = wlan_cm_get_rso_config(vdev); 5317 if (!rso_cfg) 5318 return; 5319 cfg_params = &rso_cfg->cfg_param; 5320 cfg_params->enable_scoring_for_roam = 5321 mlme_obj->cfg.roam_scoring.enable_scoring_for_roam; 5322 cfg_params->empty_scan_refresh_period = 5323 mlme_obj->cfg.lfr.empty_scan_refresh_period; 5324 cfg_params->full_roam_scan_period = 5325 mlme_obj->cfg.lfr.roam_full_scan_period; 5326 cfg_params->neighbor_scan_period = 5327 mlme_obj->cfg.lfr.neighbor_scan_timer_period; 5328 cfg_params->neighbor_lookup_threshold = 5329 mlme_obj->cfg.lfr.neighbor_lookup_rssi_threshold; 5330 cfg_params->roam_rssi_diff = 5331 mlme_obj->cfg.lfr.roam_rssi_diff; 5332 cfg_params->roam_rssi_diff_6ghz = 5333 mlme_obj->cfg.lfr.roam_rssi_diff_6ghz; 5334 cfg_params->bg_rssi_threshold = 5335 mlme_obj->cfg.lfr.bg_rssi_threshold; 5336 5337 cfg_params->max_chan_scan_time = 5338 mlme_obj->cfg.lfr.neighbor_scan_max_chan_time; 5339 cfg_params->passive_max_chan_time = 5340 mlme_obj->cfg.lfr.passive_max_channel_time; 5341 cfg_params->roam_scan_home_away_time = 5342 mlme_obj->cfg.lfr.roam_scan_home_away_time; 5343 cfg_params->roam_scan_n_probes = 5344 mlme_obj->cfg.lfr.roam_scan_n_probes; 5345 cfg_params->roam_scan_inactivity_time = 5346 mlme_obj->cfg.lfr.roam_scan_inactivity_time; 5347 cfg_params->roam_inactive_data_packet_count = 5348 mlme_obj->cfg.lfr.roam_inactive_data_packet_count; 5349 ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), ¤t_band); 5350 rso_cfg->roam_band_bitmask = current_band; 5351 } 5352 5353 QDF_STATUS cm_roam_control_restore_default_config(struct wlan_objmgr_pdev *pdev, 5354 uint8_t vdev_id) 5355 { 5356 QDF_STATUS status = QDF_STATUS_E_INVAL; 5357 struct rso_chan_info *chan_info; 5358 struct wlan_objmgr_vdev *vdev; 5359 struct rso_config *rso_cfg; 5360 struct rso_cfg_params *cfg_params; 5361 struct wlan_objmgr_psoc *psoc; 5362 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5363 5364 psoc = wlan_pdev_get_psoc(pdev); 5365 if (!psoc) 5366 goto out; 5367 5368 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5369 if (!mlme_obj) 5370 goto out; 5371 5372 if (!mlme_obj->cfg.lfr.roam_scan_offload_enabled) { 5373 mlme_err("roam_scan_offload_enabled is not supported"); 5374 goto out; 5375 } 5376 5377 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 5378 WLAN_MLME_CM_ID); 5379 if (!vdev) { 5380 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5381 goto out; 5382 } 5383 rso_cfg = wlan_cm_get_rso_config(vdev); 5384 if (!rso_cfg) { 5385 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5386 goto out; 5387 } 5388 cfg_params = &rso_cfg->cfg_param; 5389 5390 chan_info = &cfg_params->pref_chan_info; 5391 cm_flush_roam_channel_list(chan_info); 5392 5393 chan_info = &cfg_params->specific_chan_info; 5394 cm_flush_roam_channel_list(chan_info); 5395 5396 mlme_reinit_control_config_lfr_params(psoc, &mlme_obj->cfg.lfr); 5397 5398 cm_restore_default_roaming_params(mlme_obj, vdev); 5399 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5400 5401 if (MLME_IS_ROAM_STATE_RSO_ENABLED(psoc, vdev_id)) { 5402 cm_roam_send_rso_cmd(psoc, vdev_id, 5403 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 5404 REASON_FLUSH_CHANNEL_LIST); 5405 cm_roam_send_rso_cmd(psoc, vdev_id, 5406 ROAM_SCAN_OFFLOAD_UPDATE_CFG, 5407 REASON_SCORING_CRITERIA_CHANGED); 5408 } 5409 5410 status = QDF_STATUS_SUCCESS; 5411 out: 5412 return status; 5413 } 5414 5415 void cm_update_pmk_cache_ft(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 5416 struct wlan_crypto_pmksa *pmk_cache) 5417 { 5418 QDF_STATUS status = QDF_STATUS_E_INVAL; 5419 struct wlan_objmgr_vdev *vdev; 5420 struct wlan_crypto_pmksa pmksa; 5421 enum QDF_OPMODE vdev_mode; 5422 struct cm_roam_values_copy src_cfg; 5423 5424 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5425 WLAN_MLME_CM_ID); 5426 if (!vdev) { 5427 mlme_err("vdev is NULL"); 5428 return; 5429 } 5430 5431 vdev_mode = wlan_vdev_mlme_get_opmode(vdev); 5432 /* If vdev mode is STA then proceed further */ 5433 if (vdev_mode != QDF_STA_MODE) { 5434 mlme_err("vdev mode is not STA"); 5435 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5436 return; 5437 } 5438 5439 /* 5440 * In FT connection fetch the MDID from Session or scan result whichever 5441 * and send it to crypto so that it will update the crypto PMKSA table 5442 * with the MDID for the matching BSSID or SSID PMKSA entry. And delete 5443 * the old/stale PMK cache entries for the same mobility domain as of 5444 * the newly added entry to avoid multiple PMK cache entries for the 5445 * same MDID. 5446 */ 5447 wlan_vdev_get_bss_peer_mac_for_pmksa(vdev, &pmksa.bssid); 5448 wlan_vdev_mlme_get_ssid(vdev, pmksa.ssid, &pmksa.ssid_len); 5449 wlan_cm_roam_cfg_get_value(psoc, vdev_id, MOBILITY_DOMAIN, &src_cfg); 5450 5451 if (pmk_cache) 5452 qdf_mem_copy(pmksa.cache_id, pmk_cache->cache_id, 5453 WLAN_CACHE_ID_LEN); 5454 5455 if (src_cfg.bool_value) { 5456 pmksa.mdid.mdie_present = 1; 5457 pmksa.mdid.mobility_domain = src_cfg.uint_value; 5458 mlme_debug("MDID:0x%x copied to PMKSA", src_cfg.uint_value); 5459 5460 status = wlan_crypto_update_pmk_cache_ft(vdev, &pmksa); 5461 if (QDF_IS_STATUS_ERROR(status)) 5462 mlme_debug("Failed to update the crypto table"); 5463 } 5464 5465 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5466 } 5467 5468 bool cm_lookup_pmkid_using_bssid(struct wlan_objmgr_psoc *psoc, 5469 uint8_t vdev_id, 5470 struct wlan_crypto_pmksa *pmk_cache) 5471 { 5472 struct wlan_crypto_pmksa *pmksa; 5473 struct wlan_objmgr_vdev *vdev; 5474 5475 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5476 WLAN_MLME_CM_ID); 5477 if (!vdev) { 5478 mlme_err("Invalid vdev"); 5479 return false; 5480 } 5481 5482 pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache->bssid); 5483 if (!pmksa) { 5484 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5485 return false; 5486 } 5487 qdf_mem_copy(pmk_cache->pmkid, pmksa->pmkid, sizeof(pmk_cache->pmkid)); 5488 qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len); 5489 pmk_cache->pmk_len = pmksa->pmk_len; 5490 pmk_cache->pmk_lifetime = pmksa->pmk_lifetime; 5491 pmk_cache->pmk_lifetime_threshold = pmksa->pmk_lifetime_threshold; 5492 pmk_cache->pmk_entry_ts = pmksa->pmk_entry_ts; 5493 5494 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5495 5496 return true; 5497 } 5498 5499 void cm_roam_restore_default_config(struct wlan_objmgr_pdev *pdev, 5500 uint8_t vdev_id) 5501 { 5502 struct cm_roam_values_copy src_config = {}; 5503 struct wlan_objmgr_psoc *psoc; 5504 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5505 uint32_t roam_trigger_bitmap; 5506 5507 psoc = wlan_pdev_get_psoc(pdev); 5508 if (!psoc) 5509 return; 5510 5511 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5512 if (!mlme_obj) 5513 return; 5514 5515 if (mlme_obj->cfg.lfr.roam_scan_offload_enabled) { 5516 /* 5517 * When vendor handoff is enabled and disconnection is received, 5518 * then restore the roam trigger bitmap from the ini 5519 * configuration 5520 */ 5521 wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_CONFIG_ENABLE, 5522 &src_config); 5523 if (src_config.bool_value) { 5524 roam_trigger_bitmap = 5525 wlan_mlme_get_roaming_triggers(psoc); 5526 mlme_set_roam_trigger_bitmap(psoc, vdev_id, 5527 roam_trigger_bitmap); 5528 } 5529 5530 src_config.bool_value = 0; 5531 wlan_cm_roam_cfg_set_value(psoc, vdev_id, ROAM_CONFIG_ENABLE, 5532 &src_config); 5533 } 5534 5535 cm_roam_control_restore_default_config(pdev, vdev_id); 5536 } 5537 5538 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 5539 void 5540 cm_store_sae_single_pmk_to_global_cache(struct wlan_objmgr_psoc *psoc, 5541 struct wlan_objmgr_pdev *pdev, 5542 struct wlan_objmgr_vdev *vdev) 5543 { 5544 struct mlme_pmk_info *pmk_info; 5545 struct wlan_crypto_pmksa *pmksa; 5546 struct cm_roam_values_copy src_cfg; 5547 struct qdf_mac_addr bssid; 5548 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5549 int32_t akm; 5550 5551 akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 5552 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 5553 IS_SINGLE_PMK, &src_cfg); 5554 if (!src_cfg.bool_value || 5555 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE)) 5556 return; 5557 /* 5558 * Mark the AP as single PMK capable in Crypto Table 5559 */ 5560 wlan_vdev_get_bss_peer_mac_for_pmksa(vdev, &bssid); 5561 wlan_crypto_set_sae_single_pmk_bss_cap(vdev, &bssid, true); 5562 5563 pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); 5564 if (!pmk_info) 5565 return; 5566 5567 wlan_cm_get_psk_pmk(pdev, vdev_id, pmk_info->pmk, &pmk_info->pmk_len); 5568 5569 pmksa = wlan_crypto_get_pmksa(vdev, &bssid); 5570 if (pmksa) { 5571 pmk_info->spmk_timeout_period = 5572 (pmksa->pmk_lifetime * 5573 pmksa->pmk_lifetime_threshold / 100); 5574 pmk_info->spmk_timestamp = pmksa->pmk_entry_ts; 5575 mlme_debug("spmk_ts:%ld spmk_timeout_prd:%d secs", 5576 pmk_info->spmk_timestamp, 5577 pmk_info->spmk_timeout_period); 5578 } else { 5579 mlme_debug("PMK entry not found for bss:" QDF_MAC_ADDR_FMT, 5580 QDF_MAC_ADDR_REF(bssid.bytes)); 5581 } 5582 5583 wlan_mlme_update_sae_single_pmk(vdev, pmk_info); 5584 5585 qdf_mem_zero(pmk_info, sizeof(*pmk_info)); 5586 qdf_mem_free(pmk_info); 5587 } 5588 5589 void cm_check_and_set_sae_single_pmk_cap(struct wlan_objmgr_psoc *psoc, 5590 uint8_t vdev_id, uint8_t *psk_pmk, 5591 uint8_t pmk_len) 5592 { 5593 struct wlan_objmgr_vdev *vdev; 5594 struct mlme_pmk_info *pmk_info; 5595 struct wlan_crypto_pmksa *pmkid_cache, *roam_sync_pmksa; 5596 int32_t keymgmt; 5597 bool lookup_success; 5598 QDF_STATUS status; 5599 struct qdf_mac_addr bssid = QDF_MAC_ADDR_ZERO_INIT; 5600 5601 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5602 WLAN_MLME_CM_ID); 5603 if (!vdev) { 5604 mlme_err("get vdev failed"); 5605 return; 5606 } 5607 status = wlan_vdev_get_bss_peer_mac_for_pmksa(vdev, &bssid); 5608 if (QDF_IS_STATUS_ERROR(status)) { 5609 mlme_err("Failed to find connected bssid"); 5610 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5611 return; 5612 } 5613 keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 5614 if (keymgmt < 0) { 5615 mlme_err("Invalid mgmt cipher"); 5616 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5617 return; 5618 } 5619 5620 if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE)) { 5621 struct cm_roam_values_copy src_cfg; 5622 5623 wlan_cm_roam_cfg_get_value(psoc, vdev_id, IS_SINGLE_PMK, 5624 &src_cfg); 5625 wlan_mlme_set_sae_single_pmk_bss_cap(psoc, vdev_id, 5626 src_cfg.bool_value); 5627 if (!src_cfg.bool_value) 5628 goto end; 5629 5630 roam_sync_pmksa = qdf_mem_malloc(sizeof(*roam_sync_pmksa)); 5631 if (roam_sync_pmksa) { 5632 qdf_copy_macaddr(&roam_sync_pmksa->bssid, &bssid); 5633 roam_sync_pmksa->single_pmk_supported = true; 5634 roam_sync_pmksa->pmk_len = pmk_len; 5635 qdf_mem_copy(roam_sync_pmksa->pmk, psk_pmk, 5636 roam_sync_pmksa->pmk_len); 5637 mlme_debug("SPMK received for " QDF_MAC_ADDR_FMT "pmk_len:%d", 5638 QDF_MAC_ADDR_REF(roam_sync_pmksa->bssid.bytes), 5639 roam_sync_pmksa->pmk_len); 5640 /* update single pmk info for roamed ap to pmk table */ 5641 wlan_crypto_set_sae_single_pmk_info(vdev, 5642 roam_sync_pmksa); 5643 5644 qdf_mem_zero(roam_sync_pmksa, sizeof(*roam_sync_pmksa)); 5645 qdf_mem_free(roam_sync_pmksa); 5646 } else { 5647 goto end; 5648 } 5649 5650 pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); 5651 if (!pmkid_cache) 5652 goto end; 5653 5654 qdf_copy_macaddr(&pmkid_cache->bssid, &bssid); 5655 /* 5656 * In SAE single pmk roaming case, there will 5657 * be no PMK entry found for the AP in pmk cache. 5658 * So if the lookup is successful, then we have done 5659 * a FULL sae here. In that case, clear all other 5660 * single pmk entries. 5661 */ 5662 lookup_success = 5663 cm_lookup_pmkid_using_bssid(psoc, vdev_id, pmkid_cache); 5664 if (lookup_success) { 5665 wlan_crypto_selective_clear_sae_single_pmk_entries(vdev, 5666 &bssid); 5667 5668 pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); 5669 if (!pmk_info) { 5670 qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); 5671 qdf_mem_free(pmkid_cache); 5672 goto end; 5673 } 5674 5675 qdf_mem_copy(pmk_info->pmk, pmkid_cache->pmk, 5676 pmkid_cache->pmk_len); 5677 pmk_info->pmk_len = pmkid_cache->pmk_len; 5678 pmk_info->spmk_timestamp = pmkid_cache->pmk_entry_ts; 5679 pmk_info->spmk_timeout_period = 5680 (pmkid_cache->pmk_lifetime * 5681 pmkid_cache->pmk_lifetime_threshold / 100); 5682 5683 wlan_mlme_update_sae_single_pmk(vdev, pmk_info); 5684 5685 qdf_mem_zero(pmk_info, sizeof(*pmk_info)); 5686 qdf_mem_free(pmk_info); 5687 } 5688 5689 qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); 5690 qdf_mem_free(pmkid_cache); 5691 } 5692 5693 end: 5694 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5695 } 5696 #endif 5697 5698 bool cm_is_auth_type_11r(struct wlan_mlme_psoc_ext_obj *mlme_obj, 5699 struct wlan_objmgr_vdev *vdev, 5700 bool mdie_present) 5701 { 5702 int32_t akm; 5703 5704 akm = wlan_crypto_get_param(vdev, 5705 WLAN_CRYPTO_PARAM_KEY_MGMT); 5706 5707 if (cm_is_open_mode(vdev)) { 5708 if (mdie_present && mlme_obj->cfg.lfr.enable_ftopen) 5709 return true; 5710 } else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384) || 5711 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) || 5712 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) || 5713 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) || 5714 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK) || 5715 QDF_HAS_PARAM(akm, 5716 WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) || 5717 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) { 5718 return true; 5719 } 5720 5721 return false; 5722 } 5723 5724 #ifdef FEATURE_WLAN_ESE 5725 bool 5726 cm_ese_open_present(struct wlan_objmgr_vdev *vdev, 5727 struct wlan_mlme_psoc_ext_obj *mlme_obj, 5728 bool ese_version_present) 5729 { 5730 if (cm_is_open_mode(vdev) && ese_version_present && 5731 mlme_obj->cfg.lfr.ese_enabled) 5732 return true; 5733 5734 return false; 5735 } 5736 5737 bool 5738 cm_is_ese_connection(struct wlan_objmgr_vdev *vdev, bool ese_version_present) 5739 { 5740 int32_t akm; 5741 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5742 struct wlan_objmgr_psoc *psoc; 5743 5744 psoc = wlan_vdev_get_psoc(vdev); 5745 if (!psoc) { 5746 mlme_err("psoc not found"); 5747 return false; 5748 } 5749 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5750 if (!mlme_obj) 5751 return false; 5752 5753 if (!mlme_obj->cfg.lfr.ese_enabled) 5754 return false; 5755 5756 akm = wlan_crypto_get_param(vdev, 5757 WLAN_CRYPTO_PARAM_KEY_MGMT); 5758 5759 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) 5760 return true; 5761 5762 /* 5763 * A profile can not be both ESE and 11R. But an 802.11R AP 5764 * may be advertising support for ESE as well. So if we are 5765 * associating Open or explicitly ESE then we will get ESE. 5766 * If we are associating explicitly 11R only then we will get 5767 * 11R. 5768 */ 5769 return cm_ese_open_present(vdev, mlme_obj, ese_version_present); 5770 } 5771 #endif 5772 5773 static void cm_roam_start_init(struct wlan_objmgr_psoc *psoc, 5774 struct wlan_objmgr_pdev *pdev, 5775 struct wlan_objmgr_vdev *vdev) 5776 { 5777 struct cm_roam_values_copy src_cfg = {}; 5778 bool mdie_present; 5779 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5780 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5781 enum QDF_OPMODE opmode; 5782 5783 opmode = wlan_vdev_mlme_get_opmode(vdev); 5784 if (opmode != QDF_STA_MODE) { 5785 mlme_debug("Wrong opmode %d", opmode); 5786 return; 5787 } 5788 mlme_obj = mlme_get_psoc_ext_obj(psoc); 5789 if (!mlme_obj) 5790 return; 5791 5792 wlan_cm_init_occupied_ch_freq_list(pdev, psoc, vdev_id); 5793 5794 /* 5795 * Update RSSI change params to vdev 5796 */ 5797 src_cfg.uint_value = mlme_obj->cfg.lfr.roam_rescan_rssi_diff; 5798 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5799 RSSI_CHANGE_THRESHOLD, &src_cfg); 5800 5801 src_cfg.uint_value = mlme_obj->cfg.lfr.roam_scan_hi_rssi_delay; 5802 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5803 HI_RSSI_DELAY_BTW_SCANS, &src_cfg); 5804 5805 wlan_cm_update_roam_scan_scheme_bitmap(psoc, vdev_id, 5806 DEFAULT_ROAM_SCAN_SCHEME_BITMAP); 5807 wlan_cm_roam_cfg_get_value(psoc, vdev_id, 5808 MOBILITY_DOMAIN, &src_cfg); 5809 5810 mdie_present = src_cfg.bool_value; 5811 /* Based on the auth scheme tell if we are 11r */ 5812 if (cm_is_auth_type_11r(mlme_obj, vdev, mdie_present)) { 5813 src_cfg.bool_value = true; 5814 } else { 5815 src_cfg.bool_value = false; 5816 } 5817 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5818 IS_11R_CONNECTION, &src_cfg); 5819 5820 src_cfg.uint_value = mlme_obj->cfg.lfr.roam_rssi_diff_6ghz; 5821 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 5822 ROAM_RSSI_DIFF_6GHZ, &src_cfg); 5823 5824 if (!mlme_obj->cfg.lfr.roam_scan_offload_enabled) 5825 return; 5826 /* 5827 * Store the current PMK info of the AP 5828 * to the single pmk global cache if the BSS allows 5829 * single pmk roaming capable. 5830 */ 5831 cm_store_sae_single_pmk_to_global_cache(psoc, pdev, vdev); 5832 5833 if (!MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id)) { 5834 wlan_clear_sae_auth_logs_cache(psoc, vdev_id); 5835 wlan_cm_roam_state_change(pdev, vdev_id, 5836 WLAN_ROAM_RSO_ENABLED, 5837 REASON_CTX_INIT); 5838 } 5839 } 5840 5841 void cm_roam_start_init_on_connect(struct wlan_objmgr_pdev *pdev, 5842 uint8_t vdev_id) 5843 { 5844 struct wlan_objmgr_vdev *vdev; 5845 struct wlan_objmgr_psoc *psoc; 5846 5847 psoc = wlan_pdev_get_psoc(pdev); 5848 if (!psoc) 5849 return; 5850 5851 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, 5852 WLAN_MLME_CM_ID); 5853 if (!vdev) { 5854 mlme_err("vdev_id: %d: vdev not found", vdev_id); 5855 return; 5856 } 5857 cm_roam_start_init(psoc, pdev, vdev); 5858 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5859 } 5860 5861 void cm_update_session_assoc_ie(struct wlan_objmgr_psoc *psoc, 5862 uint8_t vdev_id, 5863 struct element_info *assoc_ie) 5864 { 5865 struct rso_config *rso_cfg; 5866 struct wlan_objmgr_vdev *vdev; 5867 5868 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5869 WLAN_MLME_CM_ID); 5870 if (!vdev) { 5871 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5872 return; 5873 } 5874 rso_cfg = wlan_cm_get_rso_config(vdev); 5875 if (!rso_cfg) 5876 goto rel_vdev_ref; 5877 5878 if (rso_cfg->assoc_ie.ptr) { 5879 qdf_mem_free(rso_cfg->assoc_ie.ptr); 5880 rso_cfg->assoc_ie.ptr = NULL; 5881 rso_cfg->assoc_ie.len = 0; 5882 } 5883 if (!assoc_ie->len) { 5884 sme_debug("Assoc IE len 0"); 5885 goto rel_vdev_ref; 5886 } 5887 rso_cfg->assoc_ie.ptr = qdf_mem_malloc(assoc_ie->len); 5888 if (!rso_cfg->assoc_ie.ptr) 5889 goto rel_vdev_ref; 5890 5891 rso_cfg->assoc_ie.len = assoc_ie->len; 5892 qdf_mem_copy(rso_cfg->assoc_ie.ptr, assoc_ie->ptr, assoc_ie->len); 5893 rel_vdev_ref: 5894 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5895 } 5896 5897 /** 5898 * cm_dlm_is_bssid_in_reject_list() - Check whether a BSSID is present in 5899 * reject list or not 5900 * @psoc: psoc pointer 5901 * @bssid: bssid to check 5902 * @vdev_id: vdev id 5903 * 5904 * Return: true if BSSID is present in reject list 5905 */ 5906 static bool cm_dlm_is_bssid_in_reject_list(struct wlan_objmgr_psoc *psoc, 5907 struct qdf_mac_addr *bssid, 5908 uint8_t vdev_id) 5909 { 5910 struct wlan_objmgr_vdev *vdev; 5911 struct wlan_objmgr_pdev *pdev; 5912 bool is_bssid_in_reject_list = false; 5913 5914 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5915 WLAN_MLME_CM_ID); 5916 if (!vdev) { 5917 mlme_err("vdev object is NULL for vdev %d", vdev_id); 5918 return is_bssid_in_reject_list; 5919 } 5920 5921 pdev = wlan_vdev_get_pdev(vdev); 5922 if (!pdev) 5923 goto rel_vdev_ref; 5924 5925 is_bssid_in_reject_list = 5926 wlan_dlm_is_bssid_in_reject_list(pdev, bssid); 5927 5928 rel_vdev_ref: 5929 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 5930 5931 return is_bssid_in_reject_list; 5932 } 5933 5934 QDF_STATUS cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc, 5935 struct wlan_objmgr_vdev *vdev, 5936 struct qdf_mac_addr *bssid, 5937 qdf_freq_t chan_freq, 5938 enum wlan_cm_source source) 5939 { 5940 struct cm_req *cm_req; 5941 QDF_STATUS status; 5942 uint8_t roam_control_bitmap; 5943 struct qdf_mac_addr connected_bssid; 5944 uint8_t vdev_id = vdev->vdev_objmgr.vdev_id; 5945 bool roam_offload_enabled = cm_roam_offload_enabled(psoc); 5946 struct rso_config *rso_cfg; 5947 5948 roam_control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id); 5949 if (roam_offload_enabled && (roam_control_bitmap || 5950 !MLME_IS_ROAM_INITIALIZED(psoc, vdev_id))) { 5951 mlme_debug("ROAM: RSO Disabled internally: vdev[%d] bitmap[0x%x]", 5952 vdev_id, roam_control_bitmap); 5953 return QDF_STATUS_E_FAILURE; 5954 } 5955 5956 cm_req = qdf_mem_malloc(sizeof(*cm_req)); 5957 if (!cm_req) 5958 return QDF_STATUS_E_NOMEM; 5959 5960 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 5961 mlme_err("MLO ROAM: Invalid Roam req on link vdev %d", vdev_id); 5962 qdf_mem_free(cm_req); 5963 return QDF_STATUS_E_FAILURE; 5964 } 5965 5966 rso_cfg = wlan_cm_get_rso_config(vdev); 5967 if (!rso_cfg) 5968 return QDF_STATUS_E_NULL_VALUE; 5969 5970 /* Ignore BSSID and channel validation for FW host roam */ 5971 if (source == CM_ROAMING_FW) 5972 goto send_evt; 5973 if (source == CM_ROAMING_LINK_REMOVAL) { 5974 cm_req->roam_req.req.forced_roaming = true; 5975 goto send_evt; 5976 } 5977 5978 if (cm_dlm_is_bssid_in_reject_list(psoc, bssid, vdev_id)) { 5979 mlme_debug("BSSID is in reject list, aborting roam invoke"); 5980 qdf_mem_free(cm_req); 5981 return QDF_STATUS_E_FAILURE; 5982 } 5983 5984 if (qdf_is_macaddr_zero(bssid)) { 5985 if (!wlan_mlme_is_data_stall_recovery_fw_supported(psoc)) { 5986 mlme_debug("FW does not support data stall recovery, aborting roam invoke"); 5987 qdf_mem_free(cm_req); 5988 return QDF_STATUS_E_NOSUPPORT; 5989 } 5990 5991 cm_req->roam_req.req.forced_roaming = true; 5992 if (source == CM_ROAMING_HOST || source == CM_ROAMING_USER) 5993 rso_cfg->is_forced_roaming = true; 5994 source = CM_ROAMING_NUD_FAILURE; 5995 goto send_evt; 5996 } 5997 5998 if (qdf_is_macaddr_broadcast(bssid)) { 5999 qdf_copy_macaddr(&cm_req->roam_req.req.bssid, bssid); 6000 qdf_copy_macaddr(&rso_cfg->roam_invoke_bssid, bssid); 6001 mlme_debug("Roam only if better candidate found else stick to current AP"); 6002 goto send_evt; 6003 } 6004 6005 wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid); 6006 if (qdf_is_macaddr_equal(bssid, &connected_bssid)) { 6007 mlme_debug("Reassoc BSSID is same as currently associated AP"); 6008 chan_freq = wlan_get_operation_chan_freq(vdev); 6009 } 6010 6011 if (!chan_freq || qdf_is_macaddr_zero(bssid)) { 6012 mlme_debug("bssid " QDF_MAC_ADDR_FMT " chan_freq %d", 6013 QDF_MAC_ADDR_REF(bssid->bytes), chan_freq); 6014 qdf_mem_free(cm_req); 6015 return QDF_STATUS_E_FAILURE; 6016 } 6017 6018 qdf_copy_macaddr(&cm_req->roam_req.req.bssid, bssid); 6019 cm_req->roam_req.req.chan_freq = chan_freq; 6020 6021 send_evt: 6022 cm_req->roam_req.req.source = source; 6023 6024 /* Storing source information in rso cfg as if FW aborts 6025 * roam host will delete roam req from queue. 6026 * In roam invoke failure, host will read rso cfg params 6027 * information and disconnect if needed. 6028 */ 6029 if (source == CM_ROAMING_HOST || 6030 source == CM_ROAMING_NUD_FAILURE || 6031 source == CM_ROAMING_LINK_REMOVAL || 6032 source == CM_ROAMING_USER) 6033 rso_cfg->roam_invoke_source = source; 6034 6035 cm_req->roam_req.req.vdev_id = vdev_id; 6036 /* 6037 * For LFR3 WLAN_CM_SM_EV_ROAM_REQ will be converted to 6038 * WLAN_CM_SM_EV_ROAM_INVOKE. 6039 */ 6040 status = cm_sm_deliver_event(vdev, WLAN_CM_SM_EV_ROAM_REQ, 6041 sizeof(*cm_req), cm_req); 6042 6043 if (QDF_IS_STATUS_ERROR(status)) 6044 qdf_mem_free(cm_req); 6045 6046 return status; 6047 } 6048 6049 #if (defined(CONNECTIVITY_DIAG_EVENT) || \ 6050 defined(WLAN_FEATURE_CONNECTIVITY_LOGGING)) && \ 6051 defined(WLAN_FEATURE_ROAM_OFFLOAD) 6052 static 6053 bool wlan_is_valid_frequency(uint32_t freq, uint32_t band_capability, 6054 uint32_t band_mask) 6055 { 6056 if ((band_capability == BIT(REG_BAND_5G) || 6057 band_mask == BIT(REG_BAND_5G) || 6058 band_capability == BIT(REG_BAND_6G) || 6059 band_mask == BIT(REG_BAND_6G)) && 6060 WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 6061 return false; 6062 6063 if ((band_capability == BIT(REG_BAND_2G) || 6064 band_mask == BIT(REG_BAND_2G)) && 6065 !WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 6066 return false; 6067 6068 return true; 6069 } 6070 6071 static 6072 void cm_roam_send_beacon_loss_event(struct wlan_objmgr_psoc *psoc, 6073 struct qdf_mac_addr bssid, 6074 uint8_t vdev_id, 6075 uint8_t trig_reason, 6076 uint8_t is_roam_success, 6077 bool is_full_scan, 6078 uint8_t roam_fail_reason) 6079 { 6080 bool bmiss_skip_full_scan = false; 6081 6082 /* 6083 * When roam trigger reason is Beacon Miss, 2 roam scan 6084 * stats TLV will be received with reason as BMISS. 6085 * 1. First TLV is for partial roam scan data and 6086 * 2. Second TLV is for the full scan data when there is no candidate 6087 * found in the partial scan. 6088 * When bmiss_skip_full_scan flag is disabled, prints for 1 & 2 will be 6089 * seen. 6090 * when bmiss_skip_full_scan flag is enabled, only print for 1st TLV 6091 * will be seen. 6092 * 6093 * 1. BMISS_DISCONN event should be triggered only once for BMISS roam 6094 * trigger if roam result is failure after full scan TLV is received and 6095 * bmiss_skip_full_scan is disabled. 6096 * 6097 * 2. But if bmiss_skip_full_scan is enabled, then trigger 6098 * BMISS_DISCONN event after partial scan TLV is received 6099 * 6100 * 3. In some cases , Keepalive ACK from AP might come after the 6101 * final BMISS and FW can choose to stay connected to the current AP. 6102 * In this case, don't send discon event. 6103 */ 6104 6105 wlan_mlme_get_bmiss_skip_full_scan_value(psoc, &bmiss_skip_full_scan); 6106 6107 if (trig_reason == ROAM_TRIGGER_REASON_BMISS && 6108 !is_roam_success && 6109 ((!bmiss_skip_full_scan && is_full_scan) || 6110 (bmiss_skip_full_scan && !is_full_scan)) && 6111 (roam_fail_reason == 6112 ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT || 6113 roam_fail_reason == 6114 ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT)) 6115 cm_roam_beacon_loss_disconnect_event(psoc, bssid, vdev_id); 6116 } 6117 #endif 6118 6119 #if defined(CONNECTIVITY_DIAG_EVENT) && \ 6120 defined(WLAN_FEATURE_ROAM_OFFLOAD) 6121 static enum diag_roam_reason 6122 cm_get_diag_roam_reason(enum roam_trigger_reason roam_reason) 6123 { 6124 switch (roam_reason) { 6125 case ROAM_TRIGGER_REASON_PER: 6126 return DIAG_ROAM_REASON_PER; 6127 case ROAM_TRIGGER_REASON_BMISS: 6128 return DIAG_ROAM_REASON_BEACON_MISS; 6129 case ROAM_TRIGGER_REASON_LOW_RSSI: 6130 return DIAG_ROAM_REASON_POOR_RSSI; 6131 case ROAM_TRIGGER_REASON_HIGH_RSSI: 6132 return DIAG_ROAM_REASON_BETTER_RSSI; 6133 case ROAM_TRIGGER_REASON_PERIODIC: 6134 return DIAG_ROAM_REASON_PERIODIC_TIMER; 6135 case ROAM_TRIGGER_REASON_DENSE: 6136 return DIAG_ROAM_REASON_CONGESTION; 6137 case ROAM_TRIGGER_REASON_BACKGROUND: 6138 return DIAG_ROAM_REASON_BACKGROUND_SCAN; 6139 case ROAM_TRIGGER_REASON_FORCED: 6140 return DIAG_ROAM_REASON_USER_TRIGGER; 6141 case ROAM_TRIGGER_REASON_BTM: 6142 return DIAG_ROAM_REASON_BTM; 6143 case ROAM_TRIGGER_REASON_BSS_LOAD: 6144 return DIAG_ROAM_REASON_BSS_LOAD; 6145 case ROAM_TRIGGER_REASON_DEAUTH: 6146 return DIAG_ROAM_REASON_DISCONNECTION; 6147 case ROAM_TRIGGER_REASON_IDLE: 6148 return DIAG_ROAM_REASON_IDLE; 6149 case ROAM_TRIGGER_REASON_WTC_BTM: 6150 return DIAG_ROAM_REASON_WTC; 6151 case ROAM_TRIGGER_REASON_BTC: 6152 return DIAG_ROAM_REASON_BT_ACTIVITY; 6153 default: 6154 break; 6155 } 6156 6157 return DIAG_ROAM_REASON_UNKNOWN; 6158 } 6159 6160 static enum diag_roam_sub_reason 6161 cm_get_diag_roam_sub_reason(enum roam_trigger_sub_reason sub_reason) 6162 { 6163 switch (sub_reason) { 6164 case ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 6165 return DIAG_ROAM_SUB_REASON_PERIODIC_TIMER; 6166 6167 case ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI: 6168 return DIAG_ROAM_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 6169 6170 case ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 6171 return DIAG_ROAM_SUB_REASON_BTM_DI_TIMER; 6172 6173 case ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 6174 return DIAG_ROAM_SUB_REASON_FULL_SCAN; 6175 6176 case ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 6177 return DIAG_ROAM_SUB_REASON_LOW_RSSI_PERIODIC; 6178 6179 case ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 6180 return DIAG_ROAM_SUB_REASON_CU_PERIODIC; 6181 6182 case ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 6183 return DIAG_ROAM_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_LOW_RSSI; 6184 6185 case ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 6186 return DIAG_ROAM_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 6187 6188 case ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 6189 return DIAG_ROAM_SUB_REASON_INACTIVITY_TIMER_CU; 6190 6191 default: 6192 break; 6193 } 6194 6195 return DIAG_ROAM_SUB_REASON_UNKNOWN; 6196 } 6197 6198 6199 static void populate_diag_cmn(struct wlan_connectivity_log_diag_cmn *cmn, 6200 uint8_t vdev_id, uint64_t fw_timestamp, 6201 struct qdf_mac_addr *bssid) 6202 { 6203 cmn->vdev_id = vdev_id; 6204 cmn->timestamp_us = qdf_get_time_of_the_day_us(); 6205 cmn->ktime_us = qdf_ktime_to_us(qdf_ktime_get()); 6206 cmn->fw_timestamp = fw_timestamp * 1000; 6207 6208 if (!bssid) 6209 return; 6210 6211 qdf_mem_copy(cmn->bssid, bssid->bytes, QDF_MAC_ADDR_SIZE); 6212 } 6213 6214 void cm_roam_scan_info_event(struct wlan_objmgr_psoc *psoc, 6215 struct wmi_roam_scan_data *scan, uint8_t vdev_id) 6216 { 6217 int i; 6218 struct wmi_roam_candidate_info *ap = scan->ap; 6219 uint32_t *chan_freq = NULL; 6220 uint8_t count = 0, status, num_chan; 6221 uint32_t band_capability = 0, band_mask = 0; 6222 struct wlan_diag_roam_scan_done *wlan_diag_event = NULL; 6223 6224 wlan_diag_event = qdf_mem_malloc(sizeof(*wlan_diag_event)); 6225 if (!wlan_diag_event) { 6226 mlme_err("Mem malloc failed for wlan_diag_event"); 6227 return; 6228 } 6229 6230 chan_freq = qdf_mem_malloc(sizeof(uint32_t) * NUM_CHANNELS); 6231 if (!chan_freq) { 6232 qdf_mem_free(wlan_diag_event); 6233 mlme_err("Mem malloc failed for chan_freq"); 6234 return; 6235 } 6236 6237 populate_diag_cmn(&wlan_diag_event->diag_cmn, vdev_id, 6238 (uint64_t)scan->scan_complete_timestamp, &ap->bssid); 6239 6240 wlan_diag_event->version = DIAG_SCAN_DONE_VERSION; 6241 6242 /* 6243 * scan->num_ap includes current connected AP also 6244 * so subtract 1 from the count to get total candidate APs 6245 */ 6246 6247 if (scan->num_ap) 6248 wlan_diag_event->cand_ap_count = scan->num_ap - 1; 6249 6250 if (scan->type == ROAM_STATS_SCAN_TYPE_FULL && scan->present) { 6251 status = mlme_get_fw_scan_channels(psoc, chan_freq, &num_chan); 6252 if (QDF_IS_STATUS_ERROR(status)) 6253 goto out; 6254 if (num_chan > NUM_CHANNELS) { 6255 mlme_err("unexpected num chan %d", num_chan); 6256 goto out; 6257 } 6258 6259 status = wlan_mlme_get_band_capability(psoc, &band_capability); 6260 if (QDF_IS_STATUS_ERROR(status)) 6261 goto out; 6262 6263 band_mask = 6264 policy_mgr_get_connected_roaming_vdev_band_mask(psoc, 6265 vdev_id); 6266 6267 num_chan = QDF_MIN(WLAN_MAX_LOGGING_FREQ, NUM_CHANNELS); 6268 6269 for (i = 0; i < num_chan; i++) { 6270 if (!wlan_is_valid_frequency(chan_freq[i], 6271 band_capability, 6272 band_mask)) 6273 continue; 6274 6275 wlan_diag_event->scan_freq[count] = chan_freq[i]; 6276 count++; 6277 } 6278 6279 wlan_diag_event->num_scanned_freq = count; 6280 } else { 6281 if (scan->num_chan > MAX_ROAM_SCAN_CHAN) 6282 scan->num_chan = MAX_ROAM_SCAN_CHAN; 6283 6284 wlan_diag_event->num_scanned_freq = scan->num_chan; 6285 for (i = 0; i < scan->num_chan; i++) 6286 wlan_diag_event->scan_freq[i] = scan->chan_freq[i]; 6287 } 6288 6289 wlan_diag_event->btcoex_active = scan->is_btcoex_active; 6290 6291 out: 6292 WLAN_HOST_DIAG_EVENT_REPORT(wlan_diag_event, 6293 EVENT_WLAN_ROAM_SCAN_DONE); 6294 qdf_mem_free(chan_freq); 6295 qdf_mem_free(wlan_diag_event); 6296 } 6297 6298 void cm_roam_trigger_info_event(struct wmi_roam_trigger_info *data, 6299 struct wmi_roam_scan_data *scan_data, 6300 uint8_t vdev_id, bool is_full_scan) 6301 { 6302 uint8_t i; 6303 6304 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6305 struct wlan_diag_roam_scan_start); 6306 6307 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6308 6309 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6310 (uint64_t)data->timestamp, NULL); 6311 6312 wlan_diag_event.trigger_reason = 6313 cm_get_diag_roam_reason(data->trigger_reason); 6314 6315 wlan_diag_event.trigger_sub_reason = 6316 cm_get_diag_roam_sub_reason(data->trigger_sub_reason); 6317 6318 wlan_diag_event.version = DIAG_ROAM_SCAN_START_VERSION_V2; 6319 6320 /* 6321 * Get the current AP rssi & CU load from the 6322 * wmi_roam_ap_info tlv in roam scan results 6323 */ 6324 if (scan_data->present) { 6325 for (i = 0; i < scan_data->num_ap; i++) { 6326 if (i >= MAX_ROAM_CANDIDATE_AP) 6327 break; 6328 6329 if (scan_data->ap[i].type == 6330 WLAN_ROAM_SCAN_CURRENT_AP) { 6331 wlan_diag_event.rssi = 6332 (-1) * scan_data->ap[i].rssi; 6333 wlan_diag_event.cu = 6334 scan_data->ap[i].cu_load; 6335 break; 6336 } 6337 } 6338 } 6339 6340 if (data->trigger_reason == ROAM_TRIGGER_REASON_PERIODIC || 6341 data->trigger_reason == ROAM_TRIGGER_REASON_LOW_RSSI) { 6342 if (data->common_roam) 6343 wlan_diag_event.rssi_thresh = 6344 (-1) * data->low_rssi_trig_data.roam_rssi_threshold; 6345 else 6346 wlan_diag_event.rssi_thresh = 6347 (-1) * data->rssi_trig_data.threshold; 6348 } 6349 6350 wlan_diag_event.is_full_scan = is_full_scan; 6351 wlan_diag_event.band = scan_data->band; 6352 6353 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, 6354 EVENT_WLAN_ROAM_SCAN_START); 6355 } 6356 6357 #define ETP_MAX_VALUE 10000000 6358 6359 void cm_roam_candidate_info_event(struct wmi_roam_candidate_info *ap, 6360 uint8_t cand_ap_idx) 6361 { 6362 uint32_t etp; 6363 6364 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6365 struct wlan_diag_roam_candidate_info); 6366 6367 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6368 6369 populate_diag_cmn(&wlan_diag_event.diag_cmn, 0, (uint64_t)ap->timestamp, 6370 &ap->bssid); 6371 6372 wlan_diag_event.is_current_ap = (ap->type == 1); 6373 if (wlan_diag_event.is_current_ap) 6374 wlan_diag_event.subtype = 6375 WLAN_CONN_DIAG_ROAM_SCORE_CUR_AP_EVENT; 6376 else 6377 wlan_diag_event.subtype = 6378 WLAN_CONN_DIAG_ROAM_SCORE_CAND_AP_EVENT; 6379 6380 wlan_diag_event.version = DIAG_ROAM_CAND_VERSION_V2; 6381 wlan_diag_event.rssi = (-1) * ap->rssi; 6382 wlan_diag_event.cu_load = ap->cu_load; 6383 wlan_diag_event.total_score = ap->total_score; 6384 6385 etp = ap->etp * 1000; 6386 6387 if (etp > ETP_MAX_VALUE) 6388 wlan_diag_event.etp = ETP_MAX_VALUE; 6389 else 6390 wlan_diag_event.etp = etp; 6391 6392 wlan_diag_event.idx = cand_ap_idx; 6393 wlan_diag_event.freq = ap->freq; 6394 wlan_diag_event.is_mlo = ap->is_mlo; 6395 6396 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, 6397 EVENT_WLAN_ROAM_CAND_INFO); 6398 } 6399 6400 #define WLAN_ROAM_SCAN_TYPE_PARTIAL_SCAN 0 6401 #define WLAN_ROAM_SCAN_TYPE_FULL_SCAN 1 6402 6403 #ifdef WLAN_FEATURE_11BE_MLO 6404 static void 6405 cm_populate_roam_success_mlo_param(struct wlan_objmgr_psoc *psoc, 6406 struct wlan_diag_roam_result *event, 6407 uint8_t vdev_id) 6408 { 6409 struct wlan_objmgr_vdev *vdev = NULL; 6410 struct wlan_objmgr_vdev *assoc_vdev = NULL; 6411 struct qdf_mac_addr bss_peer; 6412 QDF_STATUS status; 6413 6414 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 6415 WLAN_MLME_CM_ID); 6416 if (!vdev) { 6417 mlme_err("vdev: %d not found", vdev_id); 6418 return; 6419 } 6420 6421 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) 6422 goto out; 6423 6424 event->is_mlo = true; 6425 6426 assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev); 6427 if (!assoc_vdev) { 6428 mlme_err("assoc vdev not found"); 6429 goto out; 6430 } 6431 6432 status = wlan_vdev_get_bss_peer_mac(assoc_vdev, 6433 &bss_peer); 6434 if (QDF_IS_STATUS_ERROR(status)) { 6435 mlme_err("vdev: %d bss peer not found", 6436 wlan_vdev_get_id(assoc_vdev)); 6437 goto out; 6438 } 6439 6440 qdf_mem_copy(event->diag_cmn.bssid, 6441 bss_peer.bytes, QDF_MAC_ADDR_SIZE); 6442 6443 out: 6444 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 6445 } 6446 #else 6447 static void 6448 cm_populate_roam_success_mlo_param(struct wlan_objmgr_psoc *psoc, 6449 struct wlan_diag_roam_result *event, 6450 uint8_t vdev_id) 6451 { 6452 } 6453 #endif 6454 6455 void cm_roam_result_info_event(struct wlan_objmgr_psoc *psoc, 6456 struct wmi_roam_trigger_info *trigger, 6457 struct wmi_roam_result *res, 6458 struct wmi_roam_scan_data *scan_data, 6459 uint8_t vdev_id) 6460 { 6461 uint8_t i; 6462 struct qdf_mac_addr bssid = {0}; 6463 bool ap_found_in_roam_scan = false; 6464 bool roam_abort = (res->fail_reason == ROAM_FAIL_REASON_SYNC || 6465 res->fail_reason == ROAM_FAIL_REASON_DISCONNECT || 6466 res->fail_reason == ROAM_FAIL_REASON_HOST || 6467 res->fail_reason == 6468 ROAM_FAIL_REASON_INTERNAL_ABORT || 6469 res->fail_reason == 6470 ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO); 6471 bool is_full_scan = (scan_data->present && 6472 scan_data->type == WLAN_ROAM_SCAN_TYPE_FULL_SCAN); 6473 6474 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6475 struct wlan_diag_roam_result); 6476 6477 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6478 6479 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6480 (uint64_t)res->timestamp, NULL); 6481 6482 for (i = 0; i < scan_data->num_ap && scan_data->present; i++) { 6483 if (i >= MAX_ROAM_CANDIDATE_AP) 6484 break; 6485 6486 if (scan_data->ap[i].type == WLAN_ROAM_SCAN_ROAMED_AP || 6487 scan_data->ap[i].type == WLAN_ROAM_SCAN_CANDIDATE_AP) { 6488 ap_found_in_roam_scan = true; 6489 break; 6490 } 6491 } 6492 6493 wlan_diag_event.version = DIAG_ROAM_RESULT_VERSION; 6494 wlan_diag_event.roam_fail_reason = res->fail_reason; 6495 /* 6496 * Print ROAM if: 6497 * 1. Roaming is successful to AP 6498 * 2. Atleast one candidate AP found during scan 6499 * 6500 * Print NO_ROAM only if: 6501 * 1. No candidate AP found(even though other APs are found in scan) 6502 */ 6503 wlan_diag_event.is_roam_successful = (res->status == 0) || 6504 (ap_found_in_roam_scan && 6505 res->fail_reason != ROAM_FAIL_REASON_NO_CAND_AP_FOUND); 6506 6507 for (i = 0; i < scan_data->num_ap; i++) { 6508 if (i >= MAX_ROAM_CANDIDATE_AP) 6509 break; 6510 if (scan_data->ap[i].type == 6511 WLAN_ROAM_SCAN_CURRENT_AP) { 6512 qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, 6513 scan_data->ap[i].bssid.bytes, 6514 QDF_MAC_ADDR_SIZE); 6515 bssid = scan_data->ap[i].bssid; 6516 break; 6517 } 6518 } 6519 6520 if (!qdf_is_macaddr_zero(&res->fail_bssid)) { 6521 qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, 6522 res->fail_bssid.bytes, 6523 QDF_MAC_ADDR_SIZE); 6524 } 6525 6526 if (!wlan_diag_event.is_roam_successful) 6527 cm_populate_roam_success_mlo_param(psoc, &wlan_diag_event, 6528 vdev_id); 6529 6530 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_ROAM_RESULT); 6531 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6532 6533 if (roam_abort) { 6534 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6535 (uint64_t)res->timestamp, NULL); 6536 6537 wlan_diag_event.roam_fail_reason = res->fail_reason; 6538 6539 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, 6540 EVENT_WLAN_ROAM_CANCEL); 6541 } 6542 6543 cm_roam_send_beacon_loss_event(psoc, bssid, vdev_id, 6544 trigger->trigger_reason, 6545 wlan_diag_event.is_roam_successful, 6546 is_full_scan, res->fail_reason); 6547 6548 } 6549 6550 #endif 6551 6552 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6553 static QDF_STATUS 6554 cm_find_roam_candidate(struct wlan_objmgr_pdev *pdev, 6555 struct cnx_mgr *cm_ctx, 6556 struct cm_roam_req *roam_req, 6557 struct roam_invoke_req *roam_invoke_req) 6558 { 6559 struct scan_filter *filter; 6560 qdf_list_t *candidate_list; 6561 uint32_t num_bss = 0; 6562 qdf_list_node_t *cur_node = NULL; 6563 struct scan_cache_node *candidate = NULL; 6564 6565 if (!roam_invoke_req) 6566 return QDF_STATUS_E_FAILURE; 6567 6568 if (qdf_is_macaddr_zero(&roam_invoke_req->target_bssid) || 6569 !roam_invoke_req->ch_freq) 6570 return QDF_STATUS_E_FAILURE; 6571 6572 filter = qdf_mem_malloc(sizeof(*filter)); 6573 if (!filter) 6574 return QDF_STATUS_E_NOMEM; 6575 6576 filter->num_of_bssid = 1; 6577 qdf_copy_macaddr(&filter->bssid_list[0], 6578 &roam_invoke_req->target_bssid); 6579 filter->num_of_channels = 1; 6580 filter->chan_freq_list[0] = roam_invoke_req->ch_freq; 6581 6582 candidate_list = wlan_scan_get_result(pdev, filter); 6583 if (candidate_list) { 6584 num_bss = qdf_list_size(candidate_list); 6585 mlme_debug(CM_PREFIX_FMT "num_entries found %d", 6586 CM_PREFIX_REF(roam_req->req.vdev_id, 6587 roam_req->cm_id), 6588 num_bss); 6589 } 6590 qdf_mem_free(filter); 6591 6592 if (!candidate_list || !qdf_list_size(candidate_list)) { 6593 if (candidate_list) 6594 wlan_scan_purge_results(candidate_list); 6595 mlme_info(CM_PREFIX_FMT "no valid candidate found, num_bss %d", 6596 CM_PREFIX_REF(roam_req->req.vdev_id, 6597 roam_req->cm_id), 6598 num_bss); 6599 6600 return QDF_STATUS_E_EMPTY; 6601 } 6602 6603 qdf_list_peek_front(candidate_list, &cur_node); 6604 candidate = qdf_container_of(cur_node, 6605 struct scan_cache_node, 6606 node); 6607 6608 roam_invoke_req->frame_len = candidate->entry->raw_frame.len; 6609 6610 if (!roam_invoke_req->frame_len) 6611 return QDF_STATUS_E_INVAL; 6612 6613 roam_invoke_req->frame_buf = qdf_mem_malloc(roam_invoke_req->frame_len); 6614 6615 if (!roam_invoke_req->frame_buf) { 6616 roam_invoke_req->frame_len = 0; 6617 return QDF_STATUS_E_NOMEM; 6618 } 6619 6620 qdf_mem_copy(roam_invoke_req->frame_buf, 6621 candidate->entry->raw_frame.ptr, 6622 roam_invoke_req->frame_len); 6623 6624 wlan_scan_purge_results(candidate_list); 6625 6626 return QDF_STATUS_SUCCESS; 6627 } 6628 6629 QDF_STATUS 6630 cm_send_roam_invoke_req(struct cnx_mgr *cm_ctx, struct cm_req *req) 6631 { 6632 QDF_STATUS status; 6633 struct qdf_mac_addr connected_bssid; 6634 struct cm_roam_req *roam_req; 6635 struct wlan_objmgr_pdev *pdev; 6636 struct wlan_objmgr_psoc *psoc; 6637 struct roam_invoke_req *roam_invoke_req = NULL; 6638 wlan_cm_id cm_id; 6639 uint8_t vdev_id; 6640 uint8_t enable_self_bss_roam = false; 6641 6642 if (!req) 6643 return QDF_STATUS_E_FAILURE; 6644 6645 roam_req = &req->roam_req; 6646 cm_id = req->cm_id; 6647 vdev_id = roam_req->req.vdev_id; 6648 6649 pdev = wlan_vdev_get_pdev(cm_ctx->vdev); 6650 if (!pdev) { 6651 mlme_err(CM_PREFIX_FMT "Failed to find pdev", 6652 CM_PREFIX_REF(vdev_id, cm_id)); 6653 status = QDF_STATUS_E_FAILURE; 6654 goto roam_err; 6655 } 6656 6657 psoc = wlan_pdev_get_psoc(pdev); 6658 if (!psoc) { 6659 mlme_err(CM_PREFIX_FMT "Failed to find psoc", 6660 CM_PREFIX_REF(vdev_id, cm_id)); 6661 status = QDF_STATUS_E_FAILURE; 6662 goto roam_err; 6663 } 6664 6665 if (wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) { 6666 mlme_debug("MLO ROAM: skip RSO cmd for link vdev %d", vdev_id); 6667 status = QDF_STATUS_E_FAILURE; 6668 goto roam_err; 6669 } 6670 6671 wlan_vdev_get_bss_peer_mac(cm_ctx->vdev, &connected_bssid); 6672 wlan_mlme_get_self_bss_roam(psoc, &enable_self_bss_roam); 6673 if (!enable_self_bss_roam && 6674 qdf_is_macaddr_equal(&roam_req->req.bssid, &connected_bssid)) { 6675 mlme_err(CM_PREFIX_FMT "self bss roam disabled", 6676 CM_PREFIX_REF(vdev_id, cm_id)); 6677 status = QDF_STATUS_E_FAILURE; 6678 goto roam_err; 6679 } 6680 6681 roam_invoke_req = qdf_mem_malloc(sizeof(*roam_invoke_req)); 6682 if (!roam_invoke_req) { 6683 status = QDF_STATUS_E_NOMEM; 6684 goto roam_err; 6685 } 6686 6687 roam_invoke_req->vdev_id = vdev_id; 6688 if (roam_req->req.forced_roaming) { 6689 roam_invoke_req->forced_roaming = true; 6690 goto send_cmd; 6691 } 6692 6693 if (qdf_is_macaddr_broadcast(&roam_req->req.bssid)) { 6694 qdf_copy_macaddr(&roam_invoke_req->target_bssid, 6695 &roam_req->req.bssid); 6696 goto send_cmd; 6697 } 6698 if (qdf_is_macaddr_equal(&roam_req->req.bssid, &connected_bssid)) 6699 roam_invoke_req->is_same_bssid = true; 6700 6701 qdf_copy_macaddr(&roam_invoke_req->target_bssid, &roam_req->req.bssid); 6702 roam_invoke_req->ch_freq = roam_req->req.chan_freq; 6703 6704 status = cm_find_roam_candidate(pdev, cm_ctx, roam_req, 6705 roam_invoke_req); 6706 6707 if (QDF_IS_STATUS_ERROR(status)) { 6708 mlme_err(CM_PREFIX_FMT "No Candidate found, send roam invoke req, fw will perform scan", 6709 CM_PREFIX_REF(vdev_id, cm_id)); 6710 } 6711 6712 if (wlan_cm_get_ese_assoc(pdev, vdev_id)) { 6713 mlme_debug(CM_PREFIX_FMT "Beacon is not required for ESE", 6714 CM_PREFIX_REF(vdev_id, cm_id)); 6715 if (roam_invoke_req->frame_len) { 6716 qdf_mem_free(roam_invoke_req->frame_buf); 6717 roam_invoke_req->frame_buf = NULL; 6718 roam_invoke_req->frame_len = 0; 6719 } 6720 } 6721 send_cmd: 6722 status = wlan_cm_tgt_send_roam_invoke_req(psoc, roam_invoke_req); 6723 6724 roam_err: 6725 if (QDF_IS_STATUS_ERROR(status)) { 6726 mlme_debug(CM_PREFIX_FMT "fail to send roam invoke req", 6727 CM_PREFIX_REF(vdev_id, cm_id)); 6728 status = cm_sm_deliver_event_sync(cm_ctx, 6729 WLAN_CM_SM_EV_ROAM_INVOKE_FAIL, 6730 sizeof(wlan_cm_id), 6731 &cm_id); 6732 if (QDF_IS_STATUS_ERROR(status)) 6733 cm_remove_cmd(cm_ctx, &cm_id); 6734 } 6735 6736 if (roam_invoke_req) { 6737 if (roam_invoke_req->frame_len) 6738 qdf_mem_free(roam_invoke_req->frame_buf); 6739 qdf_mem_free(roam_invoke_req); 6740 } 6741 6742 return status; 6743 } 6744 6745 bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc) 6746 { 6747 bool val; 6748 6749 wlan_mlme_get_roaming_offload(psoc, &val); 6750 6751 return val; 6752 } 6753 6754 #if defined(WLAN_FEATURE_CONNECTIVITY_LOGGING) || \ 6755 defined(CONNECTIVITY_DIAG_EVENT) 6756 static enum wlan_main_tag 6757 cm_roam_get_tag(enum mgmt_subtype subtype, bool is_tx) 6758 { 6759 switch (subtype) { 6760 case MGMT_SUBTYPE_ASSOC_REQ: 6761 return WLAN_ASSOC_REQ; 6762 case MGMT_SUBTYPE_ASSOC_RESP: 6763 return WLAN_ASSOC_RSP; 6764 case MGMT_SUBTYPE_REASSOC_REQ: 6765 return WLAN_REASSOC_REQ; 6766 case MGMT_SUBTYPE_REASSOC_RESP: 6767 return WLAN_REASSOC_RSP; 6768 case MGMT_SUBTYPE_DISASSOC: 6769 if (is_tx) 6770 return WLAN_DISASSOC_TX; 6771 else 6772 return WLAN_DISASSOC_RX; 6773 break; 6774 case MGMT_SUBTYPE_AUTH: 6775 if (is_tx) 6776 return WLAN_AUTH_REQ; 6777 else 6778 return WLAN_AUTH_RESP; 6779 break; 6780 case MGMT_SUBTYPE_DEAUTH: 6781 if (is_tx) 6782 return WLAN_DEAUTH_TX; 6783 else 6784 return WLAN_DEAUTH_RX; 6785 default: 6786 break; 6787 } 6788 6789 return WLAN_TAG_MAX; 6790 } 6791 6792 static enum wlan_main_tag 6793 cm_roam_get_eapol_tag(enum wlan_roam_frame_subtype subtype) 6794 { 6795 switch (subtype) { 6796 case ROAM_FRAME_SUBTYPE_M1: 6797 return WLAN_EAPOL_M1; 6798 case ROAM_FRAME_SUBTYPE_M2: 6799 return WLAN_EAPOL_M2; 6800 case ROAM_FRAME_SUBTYPE_M3: 6801 return WLAN_EAPOL_M3; 6802 case ROAM_FRAME_SUBTYPE_M4: 6803 return WLAN_EAPOL_M4; 6804 case ROAM_FRAME_SUBTYPE_GTK_M1: 6805 return WLAN_GTK_M1; 6806 case ROAM_FRAME_SUBTYPE_GTK_M2: 6807 return WLAN_GTK_M2; 6808 default: 6809 break; 6810 } 6811 6812 return WLAN_TAG_MAX; 6813 } 6814 #endif 6815 6816 #if defined(CONNECTIVITY_DIAG_EVENT) 6817 QDF_STATUS 6818 cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data, 6819 uint8_t vdev_id) 6820 { 6821 QDF_STATUS status = QDF_STATUS_SUCCESS; 6822 6823 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 6824 6825 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6826 6827 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6828 (uint64_t)btm_data->timestamp, NULL); 6829 6830 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_QUERY_EVENT; 6831 wlan_diag_event.version = DIAG_BTM_VERSION_2; 6832 wlan_diag_event.token = btm_data->btm_query_token; 6833 wlan_diag_event.reason = btm_data->btm_query_reason; 6834 wlan_diag_event.band = btm_data->band; 6835 6836 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 6837 6838 return status; 6839 } 6840 6841 void 6842 cm_roam_neigh_rpt_req_event(struct wmi_neighbor_report_data *neigh_rpt, 6843 struct wlan_objmgr_vdev *vdev) 6844 { 6845 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_nbr_rpt); 6846 6847 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6848 6849 populate_diag_cmn(&wlan_diag_event.diag_cmn, wlan_vdev_get_id(vdev), 6850 (uint64_t)neigh_rpt->timestamp, NULL); 6851 6852 wlan_diag_event.subtype = WLAN_CONN_DIAG_NBR_RPT_REQ_EVENT; 6853 wlan_diag_event.version = DIAG_NBR_RPT_VERSION_2; 6854 wlan_diag_event.token = neigh_rpt->req_token; 6855 wlan_diag_event.band = neigh_rpt->band; 6856 6857 wlan_vdev_mlme_get_ssid(vdev, wlan_diag_event.ssid, 6858 (uint8_t *)&wlan_diag_event.ssid_len); 6859 6860 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_NBR_RPT); 6861 } 6862 6863 void 6864 cm_roam_neigh_rpt_resp_event(struct wmi_neighbor_report_data *neigh_rpt, 6865 uint8_t vdev_id) 6866 { 6867 uint8_t i; 6868 6869 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_nbr_rpt); 6870 6871 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6872 6873 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6874 (uint64_t)neigh_rpt->timestamp, NULL); 6875 6876 wlan_diag_event.subtype = WLAN_CONN_DIAG_NBR_RPT_RESP_EVENT; 6877 wlan_diag_event.version = DIAG_NBR_RPT_VERSION_2; 6878 wlan_diag_event.token = neigh_rpt->resp_token; 6879 wlan_diag_event.num_freq = neigh_rpt->num_freq; 6880 6881 for (i = 0; i < neigh_rpt->num_freq; i++) 6882 wlan_diag_event.freq[i] = neigh_rpt->freq[i]; 6883 6884 wlan_diag_event.num_rpt = neigh_rpt->num_rpt; 6885 wlan_diag_event.band = neigh_rpt->band; 6886 6887 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_NBR_RPT); 6888 } 6889 6890 #define WTC_BTM_RESPONSE_SUBCODE 0xFF 6891 static void 6892 cm_roam_wtc_btm_event(struct wmi_roam_trigger_info *trigger_info, 6893 struct roam_btm_response_data *btm_data, 6894 uint8_t vdev_id, bool is_wtc) 6895 { 6896 struct wmi_roam_wtc_btm_trigger_data *wtc_data = 6897 &trigger_info->wtc_btm_trig_data; 6898 6899 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 6900 6901 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6902 6903 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6904 (uint64_t)trigger_info->timestamp, NULL); 6905 6906 wlan_diag_event.version = DIAG_BTM_VERSION; 6907 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_WTC_EVENT; 6908 6909 if (is_wtc) { 6910 wlan_diag_event.reason = wtc_data->vsie_trigger_reason; 6911 wlan_diag_event.sub_reason = wtc_data->sub_code; 6912 wlan_diag_event.wtc_duration = wtc_data->duration; 6913 } else { 6914 if (!btm_data) 6915 return; 6916 6917 wlan_diag_event.reason = btm_data->vsie_reason; 6918 wlan_diag_event.sub_reason = WTC_BTM_RESPONSE_SUBCODE; 6919 } 6920 6921 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 6922 } 6923 6924 QDF_STATUS 6925 cm_roam_btm_resp_event(struct wmi_roam_trigger_info *trigger_info, 6926 struct roam_btm_response_data *btm_data, 6927 uint8_t vdev_id, bool is_wtc) 6928 { 6929 QDF_STATUS status = QDF_STATUS_SUCCESS; 6930 6931 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 6932 6933 if (is_wtc) { 6934 cm_roam_wtc_btm_event(trigger_info, btm_data, vdev_id, is_wtc); 6935 return status; 6936 } 6937 6938 if (!btm_data) { 6939 mlme_err("vdev_id:%d btm data is NULL", vdev_id); 6940 return QDF_STATUS_E_FAILURE; 6941 } 6942 6943 if (btm_data->vsie_reason) 6944 cm_roam_wtc_btm_event(trigger_info, btm_data, vdev_id, is_wtc); 6945 6946 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6947 6948 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6949 (uint64_t)trigger_info->timestamp, 6950 &btm_data->target_bssid); 6951 6952 wlan_diag_event.version = DIAG_BTM_VERSION_2; 6953 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_RESP_EVENT; 6954 wlan_diag_event.token = btm_data->btm_resp_dialog_token; 6955 wlan_diag_event.status = btm_data->btm_status; 6956 wlan_diag_event.delay = btm_data->btm_delay; 6957 wlan_diag_event.band = btm_data->band; 6958 6959 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 6960 6961 return status; 6962 } 6963 6964 /** 6965 * cm_roam_btm_candidate_event() - Send BTM roam candidate logging event 6966 * @btm_data: BTM data 6967 * @vdev_id: Vdev id 6968 * @idx: Candidate instance 6969 * 6970 * Return: QDF_STATUS 6971 */ 6972 static QDF_STATUS 6973 cm_roam_btm_candidate_event(struct wmi_btm_req_candidate_info *btm_data, 6974 uint8_t vdev_id, uint8_t idx) 6975 { 6976 QDF_STATUS status = QDF_STATUS_SUCCESS; 6977 6978 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, 6979 struct wlan_diag_btm_cand_info); 6980 6981 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 6982 6983 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 6984 (uint64_t)btm_data->timestamp, 6985 &btm_data->candidate_bssid); 6986 6987 wlan_diag_event.version = DIAG_BTM_CAND_VERSION; 6988 wlan_diag_event.preference = btm_data->preference; 6989 wlan_diag_event.idx = idx; 6990 6991 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM_CAND); 6992 6993 return status; 6994 } 6995 6996 QDF_STATUS 6997 cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data, 6998 struct wmi_roam_trigger_info *trigger_info, 6999 uint8_t vdev_id, bool is_wtc) 7000 { 7001 uint8_t i; 7002 QDF_STATUS status = QDF_STATUS_SUCCESS; 7003 7004 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_btm_info); 7005 7006 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 7007 7008 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 7009 (uint64_t)btm_data->timestamp, 7010 NULL); 7011 7012 wlan_diag_event.subtype = WLAN_CONN_DIAG_BTM_REQ_EVENT; 7013 wlan_diag_event.version = DIAG_BTM_VERSION_2; 7014 wlan_diag_event.token = btm_data->token; 7015 wlan_diag_event.mode = btm_data->btm_request_mode; 7016 /* 7017 * Diassoc Timer and Validity interval are in secs in the frame 7018 * firmware sends it in millisecs to the host. 7019 * Send it in secs to the userspace. 7020 */ 7021 wlan_diag_event.disassoc_tim = btm_data->disassoc_timer / 1000; 7022 wlan_diag_event.validity_timer = 7023 btm_data->validity_interval / 1000; 7024 wlan_diag_event.cand_lst_cnt = btm_data->candidate_list_count; 7025 wlan_diag_event.band = btm_data->band; 7026 7027 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_BTM); 7028 7029 if (is_wtc) 7030 cm_roam_wtc_btm_event(trigger_info, NULL, vdev_id, true); 7031 7032 for (i = 0; i < btm_data->candidate_list_count; i++) 7033 cm_roam_btm_candidate_event(&btm_data->btm_cand[i], vdev_id, i); 7034 7035 return status; 7036 } 7037 7038 static enum wlan_diag_wifi_band 7039 wlan_convert_bitmap_to_band(uint8_t bitmap) 7040 { 7041 uint8_t i; 7042 enum wlan_diag_wifi_band band = WLAN_INVALID_BAND; 7043 7044 for (i = WLAN_24GHZ_BAND; i <= WLAN_6GHZ_BAND; i++) { 7045 if (qdf_test_bit(i, (unsigned long *)&bitmap)) { 7046 band = i; 7047 break; 7048 } 7049 } 7050 7051 return band; 7052 } 7053 7054 QDF_STATUS 7055 cm_roam_mgmt_frame_event(struct wlan_objmgr_vdev *vdev, 7056 struct roam_frame_info *frame_data, 7057 struct wmi_roam_scan_data *scan_data) 7058 { 7059 QDF_STATUS status = QDF_STATUS_SUCCESS; 7060 uint8_t i; 7061 uint16_t diag_event; 7062 7063 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info); 7064 7065 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 7066 7067 populate_diag_cmn(&wlan_diag_event.diag_cmn, wlan_vdev_get_id(vdev), 7068 (uint64_t)frame_data->timestamp, 7069 &frame_data->bssid); 7070 7071 wlan_diag_event.version = DIAG_MGMT_VERSION_V2; 7072 wlan_diag_event.sn = frame_data->seq_num; 7073 wlan_diag_event.auth_algo = frame_data->auth_algo; 7074 wlan_diag_event.rssi = frame_data->rssi; 7075 wlan_diag_event.tx_status = 7076 wlan_get_diag_tx_status(frame_data->tx_status); 7077 wlan_diag_event.status = frame_data->status_code; 7078 wlan_diag_event.assoc_id = frame_data->assoc_id; 7079 7080 if (scan_data->present) { 7081 for (i = 0; i < scan_data->num_ap; i++) { 7082 if (i >= MAX_ROAM_CANDIDATE_AP) 7083 break; 7084 if (scan_data->ap[i].type == WLAN_ROAM_SCAN_ROAMED_AP) { 7085 wlan_diag_event.rssi = 7086 (-1) * scan_data->ap[i].rssi; 7087 7088 qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, 7089 scan_data->ap[i].bssid.bytes, 7090 QDF_MAC_ADDR_SIZE); 7091 break; 7092 } else if (!memcmp(wlan_diag_event.diag_cmn.bssid, 7093 scan_data->ap[i].bssid.bytes, 7094 QDF_MAC_ADDR_SIZE)) { 7095 wlan_diag_event.rssi = 7096 (-1) * scan_data->ap[i].rssi; 7097 break; 7098 } 7099 } 7100 } 7101 7102 if (frame_data->type == ROAM_FRAME_INFO_FRAME_TYPE_EXT) { 7103 wlan_diag_event.subtype = 7104 (uint8_t)cm_roam_get_eapol_tag(frame_data->subtype); 7105 diag_event = EVENT_WLAN_CONN_DP; 7106 wlan_diag_event.supported_links = 7107 wlan_convert_bitmap_to_band(frame_data->band); 7108 7109 } else { 7110 wlan_diag_event.subtype = 7111 (uint8_t)cm_roam_get_tag(frame_data->subtype, 7112 !frame_data->is_rsp); 7113 diag_event = EVENT_WLAN_MGMT; 7114 7115 wlan_diag_event.supported_links = frame_data->band; 7116 status = wlan_populate_roam_mld_log_param(vdev, 7117 &wlan_diag_event, 7118 wlan_diag_event.subtype); 7119 if (QDF_IS_STATUS_ERROR(status)) { 7120 mlme_err("vdev: %d Unable to populate MLO parameter", 7121 wlan_vdev_get_id(vdev)); 7122 return status; 7123 } 7124 } 7125 7126 if (wlan_diag_event.subtype > WLAN_CONN_DIAG_REASSOC_RESP_EVENT && 7127 wlan_diag_event.subtype < WLAN_CONN_DIAG_BMISS_EVENT) 7128 wlan_diag_event.reason = frame_data->status_code; 7129 7130 if (wlan_diag_event.subtype == WLAN_CONN_DIAG_DEAUTH_RX_EVENT || 7131 wlan_diag_event.subtype == WLAN_CONN_DIAG_DISASSOC_RX_EVENT) 7132 wlan_populate_vsie(vdev, &wlan_diag_event, false); 7133 7134 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, diag_event); 7135 if (wlan_diag_event.subtype == WLAN_CONN_DIAG_REASSOC_RESP_EVENT || 7136 wlan_diag_event.subtype == WLAN_CONN_DIAG_ASSOC_RESP_EVENT) 7137 wlan_connectivity_mlo_setup_event(vdev); 7138 7139 return status; 7140 } 7141 7142 QDF_STATUS 7143 cm_roam_beacon_loss_disconnect_event(struct wlan_objmgr_psoc *psoc, 7144 struct qdf_mac_addr bssid, uint8_t vdev_id) 7145 { 7146 struct wlan_objmgr_vdev *vdev = NULL; 7147 QDF_STATUS status = QDF_STATUS_SUCCESS; 7148 7149 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info); 7150 7151 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 7152 WLAN_MLME_CM_ID); 7153 if (!vdev) { 7154 mlme_err("Vdev[%d] is null", vdev_id); 7155 return QDF_STATUS_E_FAILURE; 7156 } 7157 7158 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) { 7159 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 7160 return status; 7161 } 7162 7163 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 7164 7165 populate_diag_cmn(&wlan_diag_event.diag_cmn, vdev_id, 7166 0, &bssid); 7167 7168 wlan_diag_event.subtype = WLAN_CONN_DIAG_BMISS_EVENT; 7169 wlan_diag_event.version = DIAG_MGMT_VERSION; 7170 wlan_diag_event.rssi = mlme_get_hb_ap_rssi(vdev); 7171 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 7172 7173 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MGMT); 7174 7175 return status; 7176 } 7177 #endif 7178 7179 QDF_STATUS 7180 cm_send_rso_stop(struct wlan_objmgr_vdev *vdev) 7181 { 7182 bool send_resp = true, start_timer; 7183 7184 if (!vdev) { 7185 mlme_err("vdev is NULL"); 7186 return QDF_STATUS_E_INVAL; 7187 } 7188 start_timer = cm_roam_offload_enabled(wlan_vdev_get_psoc(vdev)); 7189 7190 cm_roam_state_change(wlan_vdev_get_pdev(vdev), wlan_vdev_get_id(vdev), 7191 WLAN_ROAM_RSO_STOPPED, REASON_DISCONNECTED, 7192 &send_resp, start_timer); 7193 /* 7194 * RSO stop resp is not supported or RSO STOP timer/req failed, 7195 * send QDF_STATUS_E_NOSUPPORT so that we continue from the caller 7196 */ 7197 if (send_resp) 7198 return QDF_STATUS_E_NOSUPPORT; 7199 7200 return QDF_STATUS_SUCCESS; 7201 } 7202 7203 QDF_STATUS 7204 cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, 7205 uint8_t vdev_id, uint16_t param_value) 7206 { 7207 QDF_STATUS status; 7208 7209 wlan_cm_roam_set_ho_delay_config(psoc, param_value); 7210 status = wlan_cm_tgt_send_roam_ho_delay_config(psoc, 7211 vdev_id, param_value); 7212 if (QDF_IS_STATUS_ERROR(status)) 7213 mlme_debug("fail to send roam HO delay config"); 7214 7215 return status; 7216 } 7217 7218 QDF_STATUS 7219 cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_psoc *psoc, 7220 uint8_t vdev_id, uint8_t param_value) 7221 { 7222 QDF_STATUS status; 7223 7224 wlan_cm_set_exclude_rm_partial_scan_freq(psoc, param_value); 7225 status = wlan_cm_tgt_exclude_rm_partial_scan_freq(psoc, vdev_id, 7226 param_value); 7227 if (QDF_IS_STATUS_ERROR(status)) 7228 mlme_debug("fail to exclude roam partial scan channels"); 7229 7230 return status; 7231 } 7232 7233 QDF_STATUS cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_psoc *psoc, 7234 uint8_t vdev_id, 7235 uint8_t param_value) 7236 { 7237 QDF_STATUS status; 7238 7239 wlan_cm_roam_set_full_scan_6ghz_on_disc(psoc, param_value); 7240 status = wlan_cm_tgt_send_roam_full_scan_6ghz_on_disc(psoc, vdev_id, 7241 param_value); 7242 if (QDF_IS_STATUS_ERROR(status)) 7243 mlme_debug("fail to send 6 GHz channels inclusion in full scan"); 7244 7245 return status; 7246 } 7247 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 7248