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