1  /*
2   * Copyright (c) 2020-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 any
6   * purpose with or without fee is hereby granted, provided that the above
7   * copyright notice and this permission notice appear in all copies.
8   *
9   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16   */
17  
18  /*
19   * DOC: wlan_cm_roam_ucfg_api.c
20   *
21   * Implementation for roaming ucfg public functionality.
22   */
23  
24  #include "wlan_mlme_ucfg_api.h"
25  #include "wlan_cm_roam_ucfg_api.h"
26  #include "../../core/src/wlan_cm_roam_offload.h"
27  #include "wlan_reg_ucfg_api.h"
28  #include "wlan_mlo_mgr_sta.h"
29  
ucfg_is_rso_enabled(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)30  bool ucfg_is_rso_enabled(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
31  {
32  	return wlan_is_rso_enabled(pdev, vdev_id);
33  }
34  
35  QDF_STATUS
ucfg_user_space_enable_disable_rso(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,const bool is_fast_roam_enabled)36  ucfg_user_space_enable_disable_rso(struct wlan_objmgr_pdev *pdev,
37  				   uint8_t vdev_id,
38  				   const bool is_fast_roam_enabled)
39  {
40  	bool supplicant_disabled_roaming;
41  	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
42  	QDF_STATUS status;
43  	bool lfr_enabled;
44  	enum roam_offload_state state;
45  	uint32_t set_val = 0;
46  	enum roam_offload_state  cur_state;
47  
48  	/*
49  	 * If the ini "FastRoamEnabled" is disabled, don't allow the
50  	 * userspace to enable roam offload
51  	 */
52  	ucfg_mlme_is_lfr_enabled(psoc, &lfr_enabled);
53  	if (!lfr_enabled) {
54  		mlme_debug("ROAM_CONFIG: Fast roam ini is disabled. is_fast_roam_enabled %d",
55  			   is_fast_roam_enabled);
56  		if (!is_fast_roam_enabled)
57  			return QDF_STATUS_SUCCESS;
58  
59  		return  QDF_STATUS_E_FAILURE;
60  	}
61  
62  	cur_state = mlme_get_roam_state(psoc, vdev_id);
63  	if (cur_state == WLAN_ROAM_INIT) {
64  		if (!is_fast_roam_enabled)
65  			set_val =
66  			WMI_VDEV_ROAM_11KV_CTRL_DISABLE_FW_TRIGGER_ROAMING;
67  
68  		status = cm_roam_send_disable_config(psoc, vdev_id, set_val);
69  		if (!QDF_IS_STATUS_SUCCESS(status))
70  			mlme_err("ROAM: update fast roaming failed, status: %d",
71  				 status);
72  	}
73  	wlan_mlme_set_usr_disabled_roaming(psoc, !is_fast_roam_enabled);
74  
75  	/*
76  	 * Supplicant_disabled_roaming flag is only effective for current
77  	 * connection, it will be cleared during new connection.
78  	 * is_fast_roam_enabled: true - enable RSO if not disabled by driver
79  	 *                       false - Disable RSO. Send RSO stop if false
80  	 *                       is set.
81  	 */
82  	supplicant_disabled_roaming =
83  		mlme_get_supplicant_disabled_roaming(psoc, vdev_id);
84  	if (!is_fast_roam_enabled && supplicant_disabled_roaming) {
85  		mlme_debug("ROAM_CONFIG: RSO already disabled by supplicant");
86  		return QDF_STATUS_E_ALREADY;
87  	}
88  
89  	mlme_set_supplicant_disabled_roaming(psoc, vdev_id,
90  					     !is_fast_roam_enabled);
91  
92  	/* For mlo connection, before all links are up
93  	 * supplicant can enable roaming, to handle this
94  	 * drop the enable rso as host will enable roaming
95  	 * once all links are up
96  	 */
97  	if (mlo_is_ml_connection_in_progress(psoc, vdev_id)) {
98  		mlme_debug("mlo connection in progress");
99  		return QDF_STATUS_SUCCESS;
100  	}
101  
102  	state = (is_fast_roam_enabled) ?
103  		WLAN_ROAM_RSO_ENABLED : WLAN_ROAM_RSO_STOPPED;
104  	status = cm_roam_state_change(pdev, vdev_id, state,
105  				      REASON_SUPPLICANT_DISABLED_ROAMING,
106  				      NULL, false);
107  
108  	return status;
109  }
110  
111  void
ucfg_clear_user_disabled_roaming(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)112  ucfg_clear_user_disabled_roaming(struct wlan_objmgr_psoc *psoc,
113  				 uint8_t vdev_id)
114  {
115  	wlan_mlme_set_usr_disabled_roaming(psoc, false);
116  	mlme_set_supplicant_disabled_roaming(psoc, vdev_id, false);
117  }
118  
ucfg_cm_abort_roam_scan(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)119  QDF_STATUS ucfg_cm_abort_roam_scan(struct wlan_objmgr_pdev *pdev,
120  				   uint8_t vdev_id)
121  {
122  	QDF_STATUS status;
123  	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
124  	bool roam_scan_offload_enabled;
125  
126  	ucfg_mlme_is_roam_scan_offload_enabled(psoc,
127  					       &roam_scan_offload_enabled);
128  	if (!roam_scan_offload_enabled)
129  		return QDF_STATUS_SUCCESS;
130  
131  	status = cm_roam_send_rso_cmd(psoc, vdev_id,
132  				      ROAM_SCAN_OFFLOAD_ABORT_SCAN,
133  				      REASON_ROAM_ABORT_ROAM_SCAN);
134  
135  	return status;
136  }
137  
ucfg_cm_get_roam_band(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t * roam_band)138  QDF_STATUS ucfg_cm_get_roam_band(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
139  				 uint32_t *roam_band)
140  {
141  	struct cm_roam_values_copy temp;
142  
143  	wlan_cm_roam_cfg_get_value(psoc, vdev_id, ROAM_BAND, &temp);
144  
145  	*roam_band = temp.uint_value;
146  
147  	return QDF_STATUS_SUCCESS;
148  }
149  
150  #ifdef FEATURE_WLAN_ESE
ucfg_cm_set_ese_roam_scan_channel_list(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,qdf_freq_t * chan_freq_list,uint8_t num_chan)151  QDF_STATUS ucfg_cm_set_ese_roam_scan_channel_list(struct wlan_objmgr_pdev *pdev,
152  						  uint8_t vdev_id,
153  						  qdf_freq_t *chan_freq_list,
154  						  uint8_t num_chan)
155  {
156  	QDF_STATUS status = QDF_STATUS_SUCCESS;
157  	enum band_info band = -1;
158  	uint32_t band_bitmap;
159  	struct wlan_objmgr_vdev *vdev;
160  	struct rso_config *rso_cfg;
161  	struct wlan_objmgr_psoc *psoc;
162  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
163  
164  	psoc = wlan_pdev_get_psoc(pdev);
165  	if (!psoc)
166  		return QDF_STATUS_E_INVAL;
167  
168  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
169  	if (!mlme_obj)
170  		return QDF_STATUS_E_INVAL;
171  
172  	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
173  						    WLAN_MLME_CM_ID);
174  	if (!vdev) {
175  		mlme_err("vdev object is NULL");
176  		return QDF_STATUS_E_INVAL;
177  	}
178  	status = cm_roam_acquire_lock(vdev);
179  	if (QDF_IS_STATUS_ERROR(status))
180  		goto release_ref;
181  
182  	rso_cfg = wlan_cm_get_rso_config(vdev);
183  	if (!rso_cfg) {
184  		status = QDF_STATUS_E_FAILURE;
185  		goto error;
186  	}
187  
188  	mlme_debug("Chan list Before");
189  	cm_dump_freq_list(&rso_cfg->roam_scan_freq_lst);
190  	ucfg_reg_get_band(pdev, &band_bitmap);
191  	band = wlan_reg_band_bitmap_to_band_info(band_bitmap);
192  	status = cm_create_roam_scan_channel_list(pdev, rso_cfg, num_chan,
193  						  chan_freq_list, num_chan,
194  						  band);
195  	if (QDF_IS_STATUS_SUCCESS(status)) {
196  		mlme_debug("Chan list After");
197  		cm_dump_freq_list(&rso_cfg->roam_scan_freq_lst);
198  	}
199  
200  	if (mlme_obj->cfg.lfr.roam_scan_offload_enabled)
201  		wlan_roam_update_cfg(psoc, vdev_id,
202  				     REASON_CHANNEL_LIST_CHANGED);
203  
204  
205  error:
206  	cm_roam_release_lock(vdev);
207  release_ref:
208  	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
209  
210  	return status;
211  }
212  
ucfg_cm_set_cckm_ie(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,const uint8_t * cck_ie,const uint8_t cck_ie_len)213  QDF_STATUS ucfg_cm_set_cckm_ie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
214  			       const uint8_t *cck_ie, const uint8_t cck_ie_len)
215  {
216  	struct wlan_objmgr_vdev *vdev;
217  	struct mlme_legacy_priv *mlme_priv;
218  
219  	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
220  						    WLAN_MLME_CM_ID);
221  
222  	if (!vdev) {
223  		mlme_err("vdev not found for id %d", vdev_id);
224  		return QDF_STATUS_E_FAILURE;
225  	}
226  
227  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
228  	if (!mlme_priv) {
229  		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
230  		return QDF_STATUS_E_FAILURE;
231  	}
232  	qdf_mem_copy(mlme_priv->connect_info.cckm_ie, cck_ie, cck_ie_len);
233  	mlme_priv->connect_info.cckm_ie_len = cck_ie_len;
234  	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
235  
236  	return QDF_STATUS_SUCCESS;
237  }
238  
239  #endif
240  
241  #ifdef WLAN_FEATURE_FILS_SK
242  QDF_STATUS
ucfg_cm_update_fils_config(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct wlan_fils_con_info * fils_info)243  ucfg_cm_update_fils_config(struct wlan_objmgr_psoc *psoc,
244  			   uint8_t vdev_id,
245  			   struct wlan_fils_con_info *fils_info)
246  {
247  	QDF_STATUS status;
248  	struct wlan_objmgr_vdev *vdev;
249  
250  	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
251  						    WLAN_MLME_NB_ID);
252  	if (!vdev) {
253  		mlme_err("vdev object is NULL");
254  		return QDF_STATUS_E_INVAL;
255  	}
256  
257  	status = wlan_cm_update_mlme_fils_info(vdev, fils_info);
258  	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
259  
260  	return status;
261  }
262  #endif
263  
264  QDF_STATUS
ucfg_wlan_cm_roam_invoke(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,struct qdf_mac_addr * bssid,qdf_freq_t ch_freq,enum wlan_cm_source source)265  ucfg_wlan_cm_roam_invoke(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
266  			 struct qdf_mac_addr *bssid, qdf_freq_t ch_freq,
267  			 enum wlan_cm_source source)
268  {
269  	return wlan_cm_roam_invoke(pdev, vdev_id, bssid, ch_freq, source);
270  }
271  
272  #ifdef WLAN_FEATURE_HOST_ROAM
ucfg_cm_set_ft_pre_auth_state(struct wlan_objmgr_vdev * vdev,bool state)273  void ucfg_cm_set_ft_pre_auth_state(struct wlan_objmgr_vdev *vdev, bool state)
274  {
275  	struct mlme_legacy_priv *mlme_priv;
276  
277  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
278  	if (!mlme_priv)
279  		return;
280  
281  	mlme_priv->connect_info.ft_info.set_ft_preauth_state = state;
282  }
283  
ucfg_cm_get_ft_pre_auth_state(struct wlan_objmgr_vdev * vdev)284  static bool ucfg_cm_get_ft_pre_auth_state(struct wlan_objmgr_vdev *vdev)
285  {
286  	struct mlme_legacy_priv *mlme_priv;
287  
288  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
289  	if (!mlme_priv)
290  		return false;
291  
292  	return mlme_priv->connect_info.ft_info.set_ft_preauth_state;
293  }
294  
ucfg_cm_set_ft_ies(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,const uint8_t * ft_ies,uint16_t ft_ies_length)295  void ucfg_cm_set_ft_ies(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
296  			const uint8_t *ft_ies, uint16_t ft_ies_length)
297  {
298  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
299  	struct wlan_objmgr_vdev *vdev;
300  	struct mlme_legacy_priv *mlme_priv;
301  
302  	if (!ft_ies) {
303  		mlme_err("ft ies is NULL");
304  		return;
305  	}
306  
307  	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
308  						    WLAN_MLME_CM_ID);
309  	if (!vdev)
310  		return;
311  
312  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
313  	if (!mlme_priv)
314  		goto end;
315  
316  	status = cm_roam_acquire_lock(vdev);
317  	if (QDF_IS_STATUS_ERROR(status))
318  		goto end;
319  
320  	mlme_debug("FT IEs Req is received in state %d",
321  		  mlme_priv->connect_info.ft_info.ft_state);
322  
323  	/* Global Station FT State */
324  	switch (mlme_priv->connect_info.ft_info.ft_state) {
325  	case FT_START_READY:
326  	case FT_AUTH_REQ_READY:
327  		mlme_debug("ft_ies_length: %d", ft_ies_length);
328  		ft_ies_length = QDF_MIN(ft_ies_length, MAX_FTIE_SIZE);
329  		mlme_priv->connect_info.ft_info.auth_ie_len = ft_ies_length;
330  		qdf_mem_copy(mlme_priv->connect_info.ft_info.auth_ft_ie,
331  			     ft_ies, ft_ies_length);
332  		mlme_priv->connect_info.ft_info.ft_state = FT_AUTH_REQ_READY;
333  		break;
334  
335  	case FT_REASSOC_REQ_WAIT:
336  		/*
337  		 * We are done with pre-auth, hence now waiting for
338  		 * reassoc req. This is the new FT Roaming in place At
339  		 * this juncture we'r ready to start sending Reassoc req
340  		 */
341  
342  		ft_ies_length = QDF_MIN(ft_ies_length, MAX_FTIE_SIZE);
343  
344  		mlme_debug("New Reassoc Req: %pK in state %d",
345  			   ft_ies, mlme_priv->connect_info.ft_info.ft_state);
346  		mlme_priv->connect_info.ft_info.reassoc_ie_len =
347  							ft_ies_length;
348  		qdf_mem_copy(mlme_priv->connect_info.ft_info.reassoc_ft_ie,
349  				ft_ies, ft_ies_length);
350  
351  		mlme_priv->connect_info.ft_info.ft_state = FT_SET_KEY_WAIT;
352  		mlme_debug("ft_ies_length: %d state: %d", ft_ies_length,
353  			   mlme_priv->connect_info.ft_info.ft_state);
354  		break;
355  
356  	default:
357  		mlme_warn("Unhandled state: %d",
358  			  mlme_priv->connect_info.ft_info.ft_state);
359  		break;
360  	}
361  	cm_roam_release_lock(vdev);
362  end:
363  	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
364  }
365  
ucfg_cm_check_ft_status(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)366  QDF_STATUS ucfg_cm_check_ft_status(struct wlan_objmgr_pdev *pdev,
367  				   uint8_t vdev_id)
368  {
369  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
370  	struct wlan_objmgr_vdev *vdev;
371  	struct mlme_legacy_priv *mlme_priv;
372  
373  	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
374  						    WLAN_MLME_CM_ID);
375  	if (!vdev)
376  		return status;
377  
378  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
379  	if (!mlme_priv)
380  		goto end;
381  
382  	status = cm_roam_acquire_lock(vdev);
383  	if (QDF_IS_STATUS_ERROR(status))
384  		goto end;
385  
386  	mlme_debug("FT update key is received in state %d",
387  		   mlme_priv->connect_info.ft_info.ft_state);
388  
389  	/* Global Station FT State */
390  	switch (mlme_priv->connect_info.ft_info.ft_state) {
391  	case FT_SET_KEY_WAIT:
392  		if (ucfg_cm_get_ft_pre_auth_state(vdev)) {
393  			mlme_priv->connect_info.ft_info.ft_state = FT_START_READY;
394  			mlme_debug("state changed to %d",
395  				   mlme_priv->connect_info.ft_info.ft_state);
396  			break;
397  		}
398  		fallthrough;
399  	default:
400  		mlme_debug("Unhandled state:%d",
401  			   mlme_priv->connect_info.ft_info.ft_state);
402  		status = QDF_STATUS_E_FAILURE;
403  		break;
404  	}
405  	cm_roam_release_lock(vdev);
406  end:
407  	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
408  
409  	return status;
410  }
411  
ucfg_cm_ft_key_ready_for_install(struct wlan_objmgr_vdev * vdev)412  bool ucfg_cm_ft_key_ready_for_install(struct wlan_objmgr_vdev *vdev)
413  {
414  	bool ret = false;
415  	struct mlme_legacy_priv *mlme_priv;
416  
417  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
418  	if (!mlme_priv)
419  		return ret;
420  
421  	if (ucfg_cm_get_ft_pre_auth_state(vdev) &&
422  	    mlme_priv->connect_info.ft_info.ft_state == FT_START_READY) {
423  		ret = true;
424  		ucfg_cm_set_ft_pre_auth_state(vdev, false);
425  	}
426  
427  	return ret;
428  }
429  
ucfg_cm_ft_reset(struct wlan_objmgr_vdev * vdev)430  void ucfg_cm_ft_reset(struct wlan_objmgr_vdev *vdev)
431  {
432  	struct mlme_legacy_priv *mlme_priv;
433  
434  	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
435  	if (!mlme_priv)
436  		return;
437  
438  	qdf_mem_zero(&mlme_priv->connect_info.ft_info,
439  		     sizeof(struct ft_context));
440  
441  	mlme_priv->connect_info.ft_info.ft_state = FT_START_READY;
442  }
443  #endif /* WLAN_FEATURE_HOST_ROAM */
444  
445  #ifdef WLAN_FEATURE_ROAM_OFFLOAD
446  #ifdef FEATURE_WLAN_ESE
447  static void
ucfg_cm_reset_esecckm_info(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)448  ucfg_cm_reset_esecckm_info(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
449  {
450  	struct wlan_objmgr_vdev *vdev;
451  	struct rso_config *rso_cfg;
452  
453  	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
454  						    WLAN_MLME_CM_ID);
455  	if (!vdev) {
456  		mlme_err("vdev object is NULL for vdev %d", vdev_id);
457  		return;
458  	}
459  	rso_cfg = wlan_cm_get_rso_config(vdev);
460  	if (!rso_cfg) {
461  		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
462  		return;
463  	}
464  
465  	qdf_mem_zero(rso_cfg->krk, WMI_KRK_KEY_LEN);
466  	qdf_mem_zero(rso_cfg->btk, WMI_BTK_KEY_LEN);
467  	rso_cfg->is_ese_assoc = false;
468  	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
469  
470  }
471  #else
472  static inline
ucfg_cm_reset_esecckm_info(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)473  void ucfg_cm_reset_esecckm_info(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
474  {
475  }
476  #endif
477  
ucfg_cm_reset_key(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)478  void ucfg_cm_reset_key(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
479  {
480  	wlan_cm_set_psk_pmk(pdev, vdev_id, NULL, 0);
481  	ucfg_cm_reset_esecckm_info(pdev, vdev_id);
482  }
483  
484  QDF_STATUS
ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,uint8_t param_value)485  ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev,
486  				  uint8_t vdev_id, uint8_t param_value)
487  {
488  	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
489  
490  	return cm_roam_send_rt_stats_config(psoc, vdev_id, param_value);
491  }
492  
493  QDF_STATUS
ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,uint16_t param_value)494  ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev,
495  				  uint8_t vdev_id, uint16_t param_value)
496  {
497  	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
498  
499  	return cm_roam_send_ho_delay_config(psoc, vdev_id, param_value);
500  }
501  
502  QDF_STATUS
ucfg_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,uint8_t param_value)503  ucfg_cm_exclude_rm_partial_scan_freq(struct wlan_objmgr_pdev *pdev,
504  				     uint8_t vdev_id, uint8_t param_value)
505  {
506  	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
507  
508  	return cm_exclude_rm_partial_scan_freq(psoc, vdev_id, param_value);
509  }
510  
ucfg_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,uint8_t param_value)511  QDF_STATUS ucfg_cm_roam_full_scan_6ghz_on_disc(struct wlan_objmgr_pdev *pdev,
512  					       uint8_t vdev_id,
513  					       uint8_t param_value)
514  {
515  	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
516  
517  	return cm_roam_full_scan_6ghz_on_disc(psoc, vdev_id, param_value);
518  }
519  #ifdef WLAN_VENDOR_HANDOFF_CONTROL
520  QDF_STATUS
ucfg_cm_roam_send_vendor_handoff_param_req(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t param_id,void * vendor_handoff_context)521  ucfg_cm_roam_send_vendor_handoff_param_req(struct wlan_objmgr_psoc *psoc,
522  					   uint8_t vdev_id,
523  					   uint32_t param_id,
524  					   void *vendor_handoff_context)
525  {
526  	return cm_roam_send_vendor_handoff_param_req(psoc, vdev_id, param_id,
527  						     vendor_handoff_context);
528  }
529  
530  bool
ucfg_cm_roam_is_vendor_handoff_control_enable(struct wlan_objmgr_psoc * psoc)531  ucfg_cm_roam_is_vendor_handoff_control_enable(struct wlan_objmgr_psoc *psoc)
532  {
533  	return cm_roam_is_vendor_handoff_control_enable(psoc);
534  }
535  
536  #endif
537  #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
538  
539  QDF_STATUS
ucfg_cm_get_roam_intra_band(struct wlan_objmgr_psoc * psoc,uint16_t * val)540  ucfg_cm_get_roam_intra_band(struct wlan_objmgr_psoc *psoc, uint16_t *val)
541  {
542  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
543  
544  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
545  	if (!mlme_obj)
546  		return QDF_STATUS_E_INVAL;
547  
548  	*val = mlme_obj->cfg.lfr.roam_intra_band;
549  
550  	return QDF_STATUS_SUCCESS;
551  }
552  
553  QDF_STATUS
ucfg_cm_get_roam_rescan_rssi_diff(struct wlan_objmgr_psoc * psoc,uint8_t * val)554  ucfg_cm_get_roam_rescan_rssi_diff(struct wlan_objmgr_psoc *psoc, uint8_t *val)
555  {
556  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
557  
558  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
559  	if (!mlme_obj)
560  		return QDF_STATUS_E_INVAL;
561  
562  	*val = mlme_obj->cfg.lfr.roam_rescan_rssi_diff;
563  
564  	return QDF_STATUS_SUCCESS;
565  }
566  
567  QDF_STATUS
ucfg_cm_get_neighbor_lookup_rssi_threshold(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * lookup_threshold)568  ucfg_cm_get_neighbor_lookup_rssi_threshold(struct wlan_objmgr_psoc *psoc,
569  					   uint8_t vdev_id,
570  					   uint8_t *lookup_threshold)
571  {
572  	struct cm_roam_values_copy temp;
573  
574  	wlan_cm_roam_cfg_get_value(psoc, vdev_id, NEXT_RSSI_THRESHOLD, &temp);
575  	*lookup_threshold = temp.uint_value;
576  
577  	return QDF_STATUS_SUCCESS;
578  }
579  
580  QDF_STATUS
ucfg_cm_get_empty_scan_refresh_period(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint16_t * refresh_threshold)581  ucfg_cm_get_empty_scan_refresh_period(struct wlan_objmgr_psoc *psoc,
582  				      uint8_t vdev_id,
583  				      uint16_t *refresh_threshold)
584  {
585  	struct cm_roam_values_copy temp;
586  
587  	wlan_cm_roam_cfg_get_value(psoc, vdev_id,
588  				   EMPTY_SCAN_REFRESH_PERIOD, &temp);
589  	*refresh_threshold = temp.uint_value;
590  
591  	return QDF_STATUS_SUCCESS;
592  }
593  
594  uint16_t
ucfg_cm_get_neighbor_scan_min_chan_time(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)595  ucfg_cm_get_neighbor_scan_min_chan_time(struct wlan_objmgr_psoc *psoc,
596  					uint8_t vdev_id)
597  {
598  	struct cm_roam_values_copy temp;
599  
600  	wlan_cm_roam_cfg_get_value(psoc, vdev_id,
601  				   SCAN_MIN_CHAN_TIME, &temp);
602  
603  	return temp.uint_value;
604  }
605  
606  QDF_STATUS
ucfg_cm_get_roam_rssi_diff(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * rssi_diff)607  ucfg_cm_get_roam_rssi_diff(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
608  			   uint8_t *rssi_diff)
609  {
610  	struct cm_roam_values_copy temp;
611  
612  	wlan_cm_roam_cfg_get_value(psoc, vdev_id,
613  				   ROAM_RSSI_DIFF, &temp);
614  	*rssi_diff = temp.uint_value;
615  
616  	return QDF_STATUS_SUCCESS;
617  }
618  
619  #ifdef FEATURE_WLAN_ESE
ucfg_cm_get_is_ese_feature_enabled(struct wlan_objmgr_psoc * psoc)620  bool ucfg_cm_get_is_ese_feature_enabled(struct wlan_objmgr_psoc *psoc)
621  {
622  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
623  
624  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
625  	if (!mlme_obj)
626  		return false;
627  
628  	return mlme_obj->cfg.lfr.ese_enabled;
629  }
630  #endif
631  
632  uint16_t
ucfg_cm_get_neighbor_scan_max_chan_time(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)633  ucfg_cm_get_neighbor_scan_max_chan_time(struct wlan_objmgr_psoc *psoc,
634  					uint8_t vdev_id)
635  {
636  	struct cm_roam_values_copy temp;
637  
638  	wlan_cm_roam_cfg_get_value(psoc, vdev_id,
639  				   SCAN_MAX_CHAN_TIME, &temp);
640  
641  	return temp.uint_value;
642  }
643  
644  uint16_t
ucfg_cm_get_neighbor_scan_period(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)645  ucfg_cm_get_neighbor_scan_period(struct wlan_objmgr_psoc *psoc,
646  				 uint8_t vdev_id)
647  {
648  	struct cm_roam_values_copy temp;
649  
650  	wlan_cm_roam_cfg_get_value(psoc, vdev_id,
651  				   NEIGHBOR_SCAN_PERIOD, &temp);
652  	return temp.uint_value;
653  }
654  
ucfg_cm_get_wes_mode(struct wlan_objmgr_psoc * psoc)655  bool ucfg_cm_get_wes_mode(struct wlan_objmgr_psoc *psoc)
656  {
657  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
658  
659  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
660  	if (!mlme_obj)
661  		return false;
662  
663  	return mlme_obj->cfg.lfr.wes_mode_enabled;
664  }
665  
ucfg_cm_get_is_lfr_feature_enabled(struct wlan_objmgr_psoc * psoc)666  bool ucfg_cm_get_is_lfr_feature_enabled(struct wlan_objmgr_psoc *psoc)
667  {
668  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
669  
670  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
671  	if (!mlme_obj)
672  		return false;
673  
674  	return mlme_obj->cfg.lfr.lfr_enabled;
675  }
676  
ucfg_cm_get_is_ft_feature_enabled(struct wlan_objmgr_psoc * psoc)677  bool ucfg_cm_get_is_ft_feature_enabled(struct wlan_objmgr_psoc *psoc)
678  {
679  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
680  
681  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
682  	if (!mlme_obj)
683  		return false;
684  
685  	return mlme_obj->cfg.lfr.fast_transition_enabled;
686  }
687  
688  QDF_STATUS
ucfg_cm_get_roam_scan_home_away_time(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint16_t * roam_scan_home_away_time)689  ucfg_cm_get_roam_scan_home_away_time(struct wlan_objmgr_psoc *psoc,
690  				     uint8_t vdev_id,
691  				     uint16_t *roam_scan_home_away_time)
692  {
693  	struct cm_roam_values_copy temp;
694  
695  	wlan_cm_roam_cfg_get_value(psoc, vdev_id, SCAN_HOME_AWAY, &temp);
696  
697  	*roam_scan_home_away_time = temp.uint_value;
698  
699  	return QDF_STATUS_SUCCESS;
700  }
701  
702  QDF_STATUS
ucfg_cm_get_roam_opportunistic_scan_threshold_diff(struct wlan_objmgr_psoc * psoc,int8_t * val)703  ucfg_cm_get_roam_opportunistic_scan_threshold_diff(
704  						struct wlan_objmgr_psoc *psoc,
705  						int8_t *val)
706  {
707  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
708  
709  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
710  	if (!mlme_obj)
711  		return QDF_STATUS_E_INVAL;
712  
713  	*val = mlme_obj->cfg.lfr.opportunistic_scan_threshold_diff;
714  
715  	return QDF_STATUS_SUCCESS;
716  }
717  
718  QDF_STATUS
ucfg_cm_get_neighbor_scan_refresh_period(struct wlan_objmgr_psoc * psoc,uint16_t * value)719  ucfg_cm_get_neighbor_scan_refresh_period(struct wlan_objmgr_psoc *psoc,
720  					 uint16_t *value)
721  {
722  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
723  
724  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
725  	if (!mlme_obj)
726  		return QDF_STATUS_E_INVAL;
727  
728  	*value = mlme_obj->cfg.lfr.neighbor_scan_results_refresh_period;
729  
730  	return QDF_STATUS_SUCCESS;
731  }
732  
733  QDF_STATUS
ucfg_cm_get_empty_scan_refresh_period_global(struct wlan_objmgr_psoc * psoc,uint16_t * roam_scan_period_global)734  ucfg_cm_get_empty_scan_refresh_period_global(struct wlan_objmgr_psoc *psoc,
735  					     uint16_t *roam_scan_period_global)
736  {
737  	struct wlan_mlme_psoc_ext_obj *mlme_obj;
738  
739  	mlme_obj = mlme_get_psoc_ext_obj(psoc);
740  	if (!mlme_obj)
741  		return QDF_STATUS_E_INVAL;
742  
743  	*roam_scan_period_global =
744  			mlme_obj->cfg.lfr.empty_scan_refresh_period;
745  
746  	return QDF_STATUS_SUCCESS;
747  }
748