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