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