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