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