1 /*
2  * Copyright (c) 2012-2015, 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: Implements legacy connect specific APIs of connection manager to
20  * initiate vdev manager operations
21  */
22 
23 #include "wlan_cm_vdev_api.h"
24 #include "wlan_scan_utils_api.h"
25 #include "wlan_mlme_dbg.h"
26 #include "wlan_cm_api.h"
27 #include "wlan_policy_mgr_api.h"
28 #include "wlan_p2p_api.h"
29 #include "wlan_tdls_api.h"
30 #include "wlan_mlme_vdev_mgr_interface.h"
31 #include "wni_api.h"
32 #include "wlan_crypto_global_api.h"
33 #include "wlan_scan_api.h"
34 #include "wlan_logging_sock_svc.h"
35 #include "cfg_ucfg_api.h"
36 #include "wlan_roam_debug.h"
37 #include "wlan_mlo_mgr_sta.h"
38 #include "wlan_mlo_mgr_roam.h"
39 #include "wlan_reg_ucfg_api.h"
40 #include "wlan_mlme_api.h"
41 #include "wlan_reg_services_api.h"
42 #include "wlan_psoc_mlme_api.h"
43 #include "wlan_t2lm_api.h"
44 #include "wlan_mlo_t2lm.h"
45 #include "wlan_mlo_link_force.h"
46 #include "wlan_mlo_mgr_link_switch.h"
47 #include "wlan_dp_api.h"
48 #include <wlan_cp_stats_chipset_stats.h>
49 
50 #ifdef WLAN_FEATURE_FILS_SK
cm_update_hlp_info(struct wlan_objmgr_vdev * vdev,const uint8_t * gen_ie,uint16_t len,bool flush)51 void cm_update_hlp_info(struct wlan_objmgr_vdev *vdev,
52 			const uint8_t *gen_ie, uint16_t len,
53 			bool flush)
54 {
55 	struct mlme_legacy_priv *mlme_priv;
56 
57 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
58 	if (!mlme_priv)
59 		return;
60 
61 	if (flush) {
62 		mlme_priv->connect_info.hlp_ie_len = 0;
63 		if (mlme_priv->connect_info.hlp_ie) {
64 			qdf_mem_free(mlme_priv->connect_info.hlp_ie);
65 			mlme_priv->connect_info.hlp_ie = NULL;
66 		}
67 	}
68 
69 	if (!len || !gen_ie)
70 		return;
71 
72 	if ((mlme_priv->connect_info.hlp_ie_len + len) >
73 	    FILS_MAX_HLP_DATA_LEN) {
74 		mlme_err("HLP len exceeds: hlp_ie_len %d len %d",
75 			 mlme_priv->connect_info.hlp_ie_len, len);
76 		return;
77 	}
78 
79 	if (!mlme_priv->connect_info.hlp_ie) {
80 		mlme_priv->connect_info.hlp_ie =
81 				qdf_mem_malloc(FILS_MAX_HLP_DATA_LEN);
82 		if (!mlme_priv->connect_info.hlp_ie)
83 			return;
84 	}
85 
86 	qdf_mem_copy(mlme_priv->connect_info.hlp_ie +
87 		     mlme_priv->connect_info.hlp_ie_len, gen_ie, len);
88 	mlme_priv->connect_info.hlp_ie_len += len;
89 	mlme_debug("hlp_ie_len %d len %d", mlme_priv->connect_info.hlp_ie_len,
90 		   len);
91 }
92 #endif
93 
wlan_cm_is_vdev_id_roam_reassoc_state(struct wlan_objmgr_vdev * vdev)94 static bool wlan_cm_is_vdev_id_roam_reassoc_state(struct wlan_objmgr_vdev *vdev)
95 {
96 	return wlan_cm_is_vdev_roam_reassoc_state(vdev);
97 }
98 
99 static void
wlan_cm_disconnect_on_wait_key_timeout(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)100 wlan_cm_disconnect_on_wait_key_timeout(struct wlan_objmgr_psoc *psoc,
101 				       struct wlan_objmgr_vdev *vdev)
102 {
103 	mlo_disconnect(vdev, CM_MLME_DISCONNECT, REASON_KEY_TIMEOUT, NULL);
104 }
105 
cm_wait_for_key_time_out_handler(void * data)106 void cm_wait_for_key_time_out_handler(void *data)
107 {
108 	uint8_t vdev_id;
109 	struct wlan_objmgr_vdev *vdev;
110 	struct wlan_objmgr_psoc *psoc;
111 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
112 	struct wait_for_key_timer *wait_key_timer =
113 				(struct wait_for_key_timer *)data;
114 
115 	vdev = wait_key_timer->vdev;
116 	vdev_id = vdev->vdev_objmgr.vdev_id;
117 
118 	psoc = wlan_vdev_get_psoc(vdev);
119 	if (!psoc) {
120 		mlme_err("psoc obj is NULL for vdev id %d", vdev_id);
121 		return;
122 	}
123 
124 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
125 	if (!mlme_obj) {
126 		mlme_err("psoc mlme obj is NULL for vdev id %d", vdev_id);
127 		return;
128 	}
129 
130 	if (cm_csr_is_ss_wait_for_key(vdev_id)) {
131 		cm_csr_set_ss_none(vdev_id);
132 		if (wlan_cm_is_vdev_id_roam_reassoc_state(vdev))
133 			mlme_obj->cfg.timeouts.heart_beat_threshold =
134 					cfg_default(CFG_HEART_BEAT_THRESHOLD);
135 
136 		wlan_cm_disconnect_on_wait_key_timeout(psoc, vdev);
137 	}
138 }
139 
cm_start_wait_for_key_timer(struct wlan_objmgr_vdev * vdev,uint32_t interval)140 QDF_STATUS cm_start_wait_for_key_timer(struct wlan_objmgr_vdev *vdev,
141 				       uint32_t interval)
142 {
143 	uint8_t vdev_id;
144 	struct wlan_objmgr_psoc *psoc;
145 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
146 	struct vdev_mlme_obj *vdev_mlme;
147 
148 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
149 	if (!vdev_mlme) {
150 		mlme_err("vdev priv mlme obj is NULL");
151 		return QDF_STATUS_E_INVAL;
152 	}
153 	vdev_id = vdev->vdev_objmgr.vdev_id;
154 
155 	psoc = wlan_vdev_get_psoc(vdev);
156 	if (!psoc) {
157 		mlme_err("psoc obj is NULL for vdev id %d", vdev_id);
158 		return QDF_STATUS_E_INVAL;
159 	}
160 
161 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
162 	if (!mlme_obj) {
163 		mlme_err("psoc mlme obj is NULL for vdev id %d", vdev_id);
164 		return QDF_STATUS_E_INVAL;
165 	}
166 
167 	if (wlan_cm_is_vdev_id_roam_reassoc_state(vdev))
168 		mlme_obj->cfg.timeouts.heart_beat_threshold = 0;
169 
170 	return qdf_mc_timer_start(&vdev_mlme->ext_vdev_ptr->wait_key_timer.timer,
171 				  interval / QDF_MC_TIMER_TO_MS_UNIT);
172 }
173 
cm_stop_wait_for_key_timer(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)174 void cm_stop_wait_for_key_timer(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
175 {
176 	struct wlan_objmgr_vdev *vdev;
177 	struct vdev_mlme_obj *vdev_mlme;
178 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
179 
180 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
181 						    WLAN_MLME_CM_ID);
182 	if (!vdev) {
183 		mlme_err("vdev is NULL for vdev id %d", vdev_id);
184 		return;
185 	}
186 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
187 	if (!vdev_mlme) {
188 		mlme_err("vdev priv mlme obj is NULL");
189 		goto end;
190 	}
191 
192 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
193 	if (!mlme_obj) {
194 		mlme_err("psoc mlme obj is NULL for vdev id %d", vdev_id);
195 		goto end;
196 	}
197 
198 	if (wlan_cm_is_vdev_id_roam_reassoc_state(vdev))
199 		mlme_obj->cfg.timeouts.heart_beat_threshold =
200 					cfg_default(CFG_HEART_BEAT_THRESHOLD);
201 
202 	qdf_mc_timer_stop(&vdev_mlme->ext_vdev_ptr->wait_key_timer.timer);
203 
204 end:
205 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
206 }
207 
cm_update_wait_for_key_timer(struct wlan_objmgr_vdev * vdev,uint8_t vdev_id,uint32_t interval)208 void cm_update_wait_for_key_timer(struct wlan_objmgr_vdev *vdev,
209 				  uint8_t vdev_id, uint32_t interval)
210 {
211 	cm_csr_set_ss_wait_for_key(vdev_id);
212 
213 	if (QDF_IS_STATUS_ERROR(cm_start_wait_for_key_timer(vdev,  interval))) {
214 		mlme_err("Failed wait for key timer start");
215 		cm_csr_set_ss_none(vdev_id);
216 	}
217 }
218 
cm_update_prev_ap_ie(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t len,uint8_t * bcn_ptr)219 void cm_update_prev_ap_ie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
220 			  uint32_t len, uint8_t *bcn_ptr)
221 {
222 	struct wlan_objmgr_vdev *vdev;
223 	struct rso_config *rso_cfg;
224 	struct element_info *bcn_ie;
225 
226 	if (!len || !bcn_ptr)
227 		return;
228 
229 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
230 						    WLAN_MLME_CM_ID);
231 	if (!vdev) {
232 		mlme_err("vdev is NULL for vdev id %d", vdev_id);
233 		return;
234 	}
235 	rso_cfg = wlan_cm_get_rso_config(vdev);
236 	if (!rso_cfg)
237 		goto end;
238 
239 	bcn_ie = &rso_cfg->prev_ap_bcn_ie;
240 	if (bcn_ie->ptr) {
241 		qdf_mem_free(bcn_ie->ptr);
242 		bcn_ie->ptr = NULL;
243 		bcn_ie->len = 0;
244 	}
245 	bcn_ie->ptr = qdf_mem_malloc(len);
246 	if (!bcn_ie->ptr) {
247 		bcn_ie->len = 0;
248 		goto end;
249 	}
250 
251 	qdf_mem_copy(bcn_ie->ptr, bcn_ptr, len);
252 end:
253 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
254 }
255 
cm_get_rssi_snr_by_bssid(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * bssid,int8_t * rssi,int8_t * snr)256 QDF_STATUS cm_get_rssi_snr_by_bssid(struct wlan_objmgr_pdev *pdev,
257 				    struct qdf_mac_addr *bssid,
258 				    int8_t *rssi, int8_t *snr)
259 {
260 	struct scan_filter *scan_filter;
261 	qdf_list_t *list = NULL;
262 	struct scan_cache_node *first_node = NULL;
263 	QDF_STATUS status = QDF_STATUS_SUCCESS;
264 
265 	if (snr)
266 		*snr = 0;
267 	if (rssi)
268 		*rssi = 0;
269 	scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
270 	if (!scan_filter)
271 		return QDF_STATUS_E_NOMEM;
272 
273 	scan_filter->num_of_bssid = 1;
274 	qdf_mem_copy(scan_filter->bssid_list[0].bytes,
275 		     bssid, sizeof(struct qdf_mac_addr));
276 	scan_filter->ignore_auth_enc_type = true;
277 	list = wlan_scan_get_result(pdev, scan_filter);
278 	qdf_mem_free(scan_filter);
279 
280 	if (!list || (list && !qdf_list_size(list))) {
281 		mlme_debug("scan list empty");
282 		status = QDF_STATUS_E_NULL_VALUE;
283 		goto error;
284 	}
285 
286 	qdf_list_peek_front(list, (qdf_list_node_t **) &first_node);
287 	if (first_node && first_node->entry) {
288 		if (rssi)
289 			*rssi = first_node->entry->rssi_raw;
290 		if (snr)
291 			*snr = first_node->entry->snr;
292 	}
293 
294 error:
295 	if (list)
296 		wlan_scan_purge_results(list);
297 
298 	return status;
299 }
300 
301 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
302 #ifdef WLAN_FEATURE_11BE
303 static const
cm_diag_get_eht_dot11_mode_str(enum mgmt_dot11_mode dot11mode)304 char *cm_diag_get_eht_dot11_mode_str(enum mgmt_dot11_mode dot11mode)
305 {
306 
307 	switch (dot11mode) {
308 	CASE_RETURN_STRING(DOT11_MODE_11BE);
309 	CASE_RETURN_STRING(DOT11_MODE_11BE_ONLY);
310 	default:
311 		return "Unknown";
312 	}
313 }
314 
cm_diag_get_320_ch_width_str(uint8_t ch_width)315 static const char *cm_diag_get_320_ch_width_str(uint8_t ch_width)
316 {
317 	switch (ch_width) {
318 	CASE_RETURN_STRING(BW_320MHZ);
319 	default:
320 		return "Unknown";
321 	}
322 }
323 #else
324 static const
cm_diag_get_eht_dot11_mode_str(enum mgmt_dot11_mode dot11mode)325 char *cm_diag_get_eht_dot11_mode_str(enum mgmt_dot11_mode dot11mode)
326 {
327 	return "Unknown";
328 }
329 
cm_diag_get_320_ch_width_str(uint8_t ch_width)330 static const char *cm_diag_get_320_ch_width_str(uint8_t ch_width)
331 {
332 	return "Unknown";
333 }
334 #endif
335 
cm_diag_get_ch_width_str(uint8_t ch_width)336 static const char *cm_diag_get_ch_width_str(uint8_t ch_width)
337 {
338 	switch (ch_width) {
339 	CASE_RETURN_STRING(BW_20MHZ);
340 	CASE_RETURN_STRING(BW_40MHZ);
341 	CASE_RETURN_STRING(BW_80MHZ);
342 	CASE_RETURN_STRING(BW_160MHZ);
343 	CASE_RETURN_STRING(BW_80P80MHZ);
344 	CASE_RETURN_STRING(BW_5MHZ);
345 	CASE_RETURN_STRING(BW_10MHZ);
346 	default:
347 		return cm_diag_get_320_ch_width_str(ch_width);
348 	}
349 }
350 
cm_diag_get_dot11_mode_str(enum mgmt_dot11_mode dot11mode)351 static const char *cm_diag_get_dot11_mode_str(enum mgmt_dot11_mode dot11mode)
352 {
353 	switch (dot11mode) {
354 	CASE_RETURN_STRING(DOT11_MODE_AUTO);
355 	CASE_RETURN_STRING(DOT11_MODE_ABG);
356 	CASE_RETURN_STRING(DOT11_MODE_11A);
357 	CASE_RETURN_STRING(DOT11_MODE_11B);
358 	CASE_RETURN_STRING(DOT11_MODE_11G);
359 	CASE_RETURN_STRING(DOT11_MODE_11N);
360 	CASE_RETURN_STRING(DOT11_MODE_11AC);
361 	CASE_RETURN_STRING(DOT11_MODE_11G_ONLY);
362 	CASE_RETURN_STRING(DOT11_MODE_11N_ONLY);
363 	CASE_RETURN_STRING(DOT11_MODE_11AC_ONLY);
364 	CASE_RETURN_STRING(DOT11_MODE_11AX);
365 	CASE_RETURN_STRING(DOT11_MODE_11AX_ONLY);
366 	default:
367 		return cm_diag_get_eht_dot11_mode_str(dot11mode);
368 	}
369 }
370 
cm_diag_get_encr_type_str(uint8_t encr_type)371 static const char *cm_diag_get_encr_type_str(uint8_t encr_type)
372 {
373 	switch (encr_type) {
374 	CASE_RETURN_STRING(ENC_MODE_OPEN);
375 	CASE_RETURN_STRING(ENC_MODE_WEP40);
376 	CASE_RETURN_STRING(ENC_MODE_WEP104);
377 	CASE_RETURN_STRING(ENC_MODE_TKIP);
378 	CASE_RETURN_STRING(ENC_MODE_AES);
379 	CASE_RETURN_STRING(ENC_MODE_AES_GCMP);
380 	CASE_RETURN_STRING(ENC_MODE_AES_GCMP_256);
381 	CASE_RETURN_STRING(ENC_MODE_SMS4);
382 	default:
383 		return "Unknown";
384 	}
385 }
386 
cm_diag_get_akm_str(enum mgmt_auth_type auth_type,uint32_t akm)387 static const uint8_t *cm_diag_get_akm_str(enum mgmt_auth_type auth_type,
388 					  uint32_t akm)
389 {
390 	if (auth_type == AUTH_OPEN)
391 		return "Open";
392 	else if (auth_type == AUTH_SHARED)
393 		return "Shared Key";
394 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384))
395 		return "FT-FILS-SHA384";
396 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256))
397 		return "FT-FILS-SHA256";
398 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384))
399 		return "FILS-SHA384";
400 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256))
401 		return "FILS-SHA256";
402 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY))
403 		return "FT-SAE-EXT-KEY";
404 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE))
405 		return "FT-SAE";
406 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))
407 		return "SAE-EXT-KEY";
408 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE))
409 		return "SAE";
410 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_DPP))
411 		return "DPP";
412 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OSEN))
413 		return "OSEN";
414 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE))
415 		return "OWE";
416 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X))
417 		return "FT-802.1x";
418 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK))
419 		return "FT-PSK";
420 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
421 		return "EAP 802.1x";
422 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
423 		return "WPA2-PSK";
424 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
425 		return "RSN-CCKM";
426 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256))
427 		return "PSK-SHA256";
428 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256))
429 		return "EAP 802.1x-SHA256";
430 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B))
431 		return "EAP Suite-B SHA256";
432 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192))
433 		return "EAP Suite-B SHA384";
434 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384))
435 		return "FT-Suite-B SHA384";
436 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
437 		return "WPA";
438 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
439 		return "WPA-PSK";
440 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
441 		return "WPA-CCKM";
442 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WPA_NONE))
443 		return "WPA-NONE";
444 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))
445 		return "WAPI-CERT";
446 	else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK))
447 		return "WAPI-PSK";
448 	else
449 		return "NONE";
450 }
451 
452 #if defined(WLAN_FEATURE_11BE)
453 static enum mgmt_dot11_mode
cm_diag_eht_dot11_mode_from_phy_mode(enum wlan_phymode phymode)454 cm_diag_eht_dot11_mode_from_phy_mode(enum wlan_phymode phymode)
455 {
456 	if (IS_WLAN_PHYMODE_EHT(phymode))
457 		return DOT11_MODE_11BE;
458 	else
459 		return DOT11_MODE_MAX;
460 }
461 
462 static enum mgmt_ch_width
cm_get_diag_eht_320_ch_width(enum phy_ch_width ch_width)463 cm_get_diag_eht_320_ch_width(enum phy_ch_width ch_width)
464 {
465 	if (ch_width == CH_WIDTH_320MHZ)
466 		return BW_320MHZ;
467 	else
468 		return BW_MAX;
469 }
470 #else
471 static enum mgmt_dot11_mode
cm_diag_eht_dot11_mode_from_phy_mode(enum wlan_phymode phymode)472 cm_diag_eht_dot11_mode_from_phy_mode(enum wlan_phymode phymode)
473 {
474 	return DOT11_MODE_MAX;
475 }
476 
477 static enum mgmt_ch_width
cm_get_diag_eht_320_ch_width(enum phy_ch_width ch_width)478 cm_get_diag_eht_320_ch_width(enum phy_ch_width ch_width)
479 {
480 	return BW_MAX;
481 }
482 #endif
483 
484 static enum mgmt_dot11_mode
cm_diag_dot11_mode_from_phy_mode(enum wlan_phymode phymode)485 cm_diag_dot11_mode_from_phy_mode(enum wlan_phymode phymode)
486 {
487 	switch (phymode) {
488 	case WLAN_PHYMODE_11A:
489 		return DOT11_MODE_11A;
490 	case WLAN_PHYMODE_11B:
491 		return DOT11_MODE_11B;
492 	case WLAN_PHYMODE_11G:
493 		return DOT11_MODE_11G;
494 	case WLAN_PHYMODE_11G_ONLY:
495 		return DOT11_MODE_11G_ONLY;
496 	case WLAN_PHYMODE_AUTO:
497 		return DOT11_MODE_AUTO;
498 	default:
499 		if (IS_WLAN_PHYMODE_HT(phymode))
500 			return DOT11_MODE_11N;
501 		else if (IS_WLAN_PHYMODE_VHT(phymode))
502 			return DOT11_MODE_11AC;
503 		else if (IS_WLAN_PHYMODE_HE(phymode))
504 			return DOT11_MODE_11AX;
505 		else
506 			return cm_diag_eht_dot11_mode_from_phy_mode(phymode);
507 	}
508 }
509 
cm_get_diag_ch_width(enum phy_ch_width ch_width)510 static enum mgmt_ch_width cm_get_diag_ch_width(enum phy_ch_width ch_width)
511 {
512 	switch (ch_width) {
513 	case CH_WIDTH_20MHZ:
514 		return BW_20MHZ;
515 	case CH_WIDTH_40MHZ:
516 		return BW_40MHZ;
517 	case CH_WIDTH_80MHZ:
518 		return BW_80MHZ;
519 	case CH_WIDTH_160MHZ:
520 		return BW_160MHZ;
521 	case CH_WIDTH_80P80MHZ:
522 		return BW_80P80MHZ;
523 	case CH_WIDTH_5MHZ:
524 		return BW_5MHZ;
525 	case CH_WIDTH_10MHZ:
526 		return BW_10MHZ;
527 	default:
528 		return cm_get_diag_eht_320_ch_width(ch_width);
529 	}
530 }
531 
cm_get_diag_persona(enum QDF_OPMODE persona)532 static enum mgmt_bss_type cm_get_diag_persona(enum QDF_OPMODE persona)
533 {
534 	switch (persona) {
535 	case QDF_STA_MODE:
536 		return STA_PERSONA;
537 	case QDF_SAP_MODE:
538 		return SAP_PERSONA;
539 	case QDF_P2P_CLIENT_MODE:
540 		return P2P_CLIENT_PERSONA;
541 	case QDF_P2P_GO_MODE:
542 		return P2P_GO_PERSONA;
543 	case QDF_FTM_MODE:
544 		return FTM_PERSONA;
545 	case QDF_MONITOR_MODE:
546 		return MONITOR_PERSONA;
547 	case QDF_P2P_DEVICE_MODE:
548 		return P2P_DEVICE_PERSONA;
549 	case QDF_OCB_MODE:
550 		return OCB_PERSONA;
551 	case QDF_EPPING_MODE:
552 		return EPPING_PERSONA;
553 	case QDF_QVIT_MODE:
554 		return QVIT_PERSONA;
555 	case QDF_NDI_MODE:
556 		return NDI_PERSONA;
557 	case QDF_WDS_MODE:
558 		return WDS_PERSONA;
559 	case QDF_BTAMP_MODE:
560 		return BTAMP_PERSONA;
561 	case QDF_AHDEMO_MODE:
562 		return AHDEMO_PERSONA;
563 	default:
564 		return MAX_PERSONA;
565 	}
566 }
567 
cm_get_diag_enc_type(uint32_t cipherset)568 static enum mgmt_encrypt_type cm_get_diag_enc_type(uint32_t cipherset)
569 {
570 	enum mgmt_encrypt_type n = ENC_MODE_OPEN;
571 
572 	if (!cipherset)
573 		return n;
574 
575 	if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM_256))
576 		n = ENC_MODE_AES_GCMP_256;
577 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM))
578 		n = ENC_MODE_AES_GCMP;
579 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM) ||
580 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_OCB) ||
581 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM_256) ||
582 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC) ||
583 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC_256) ||
584 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC) ||
585 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC_256))
586 		n = ENC_MODE_AES;
587 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_TKIP))
588 		n = ENC_MODE_TKIP;
589 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_GCM4) ||
590 		 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_SMS4))
591 		n = ENC_MODE_SMS4;
592 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP))
593 		n = ENC_MODE_WEP40;
594 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_40))
595 		n = ENC_MODE_WEP40;
596 	else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_104))
597 		n = ENC_MODE_WEP104;
598 
599 	return n;
600 }
601 
cm_diag_fill_rsn_auth_type(uint8_t * auth_type,uint32_t akm)602 static void cm_diag_fill_rsn_auth_type(uint8_t *auth_type, uint32_t akm)
603 {
604 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) ||
605 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X) ||
606 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256) ||
607 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B) ||
608 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192) ||
609 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384))
610 		*auth_type = AUTH_WPA2_EAP;
611 	else
612 		*auth_type = AUTH_WPA2_PSK;
613 }
614 
cm_diag_fill_wpa_auth_type(uint8_t * auth_type,uint32_t akm)615 static void cm_diag_fill_wpa_auth_type(uint8_t *auth_type, uint32_t akm)
616 {
617 	/* Try the more preferred ones first. */
618 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
619 		*auth_type = AUTH_WPA_EAP;
620 	else
621 		*auth_type = AUTH_WPA_PSK;
622 }
623 
cm_diag_fill_wapi_auth_type(uint8_t * auth_type,uint32_t akm)624 static void cm_diag_fill_wapi_auth_type(uint8_t *auth_type, uint32_t akm)
625 {
626 	/* Try the more preferred ones first. */
627 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))
628 		*auth_type = AUTH_WAPI_CERT;
629 	else
630 		*auth_type = AUTH_WAPI_PSK;
631 }
632 
cm_diag_get_auth_type(uint8_t * auth_type,uint32_t authmodeset,uint32_t akm,uint32_t ucastcipherset)633 static void cm_diag_get_auth_type(uint8_t *auth_type,
634 				  uint32_t authmodeset, uint32_t akm,
635 				  uint32_t ucastcipherset)
636 {
637 	if (!authmodeset) {
638 		*auth_type = AUTH_OPEN;
639 		return;
640 	}
641 
642 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_NONE) ||
643 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_OPEN)) {
644 		*auth_type = AUTH_OPEN;
645 		return;
646 	}
647 
648 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_AUTO)) {
649 		if ((QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
650 		     QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
651 		     QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)))
652 			*auth_type = AUTH_SHARED;
653 		else
654 			*auth_type = AUTH_OPEN;
655 
656 		return;
657 	}
658 
659 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SHARED)) {
660 		*auth_type = AUTH_SHARED;
661 		return;
662 	}
663 
664 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_8021X) ||
665 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_RSNA) ||
666 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_CCKM) ||
667 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SAE) ||
668 	    QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_FILS_SK)) {
669 		cm_diag_fill_rsn_auth_type(auth_type, akm);
670 		return;
671 	}
672 
673 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WPA)) {
674 		cm_diag_fill_wpa_auth_type(auth_type, akm);
675 		return;
676 	}
677 
678 	if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WAPI)) {
679 		cm_diag_fill_wapi_auth_type(auth_type, akm);
680 		return;
681 	}
682 
683 	*auth_type = AUTH_OPEN;
684 }
685 
686 static void
cm_connect_success_diag(struct wlan_mlme_psoc_ext_obj * mlme_obj,struct host_event_wlan_connection_stats * stats)687 cm_connect_success_diag(struct wlan_mlme_psoc_ext_obj *mlme_obj,
688 			struct host_event_wlan_connection_stats *stats)
689 {
690 	WLAN_HOST_DIAG_EVENT_DEF(connect_status,
691 				 host_event_wlan_status_payload_type);
692 
693 	qdf_mem_zero(&connect_status,
694 		     sizeof(host_event_wlan_status_payload_type));
695 
696 	connect_status.eventId = DIAG_WLAN_STATUS_CONNECT;
697 	connect_status.bssType = 0;
698 	mlme_obj->cfg.sta.current_rssi = stats->rssi;
699 
700 	connect_status.qosCapability = stats->qos_capability;
701 	connect_status.authType = stats->auth_type;
702 	connect_status.encryptionType = stats->encryption_type;
703 	qdf_mem_copy(connect_status.ssid, stats->ssid, stats->ssid_len);
704 	connect_status.reason = DIAG_REASON_UNSPECIFIED;
705 	qdf_mem_copy(&mlme_obj->cfg.sta.event_payload, &connect_status,
706 		     sizeof(host_event_wlan_status_payload_type));
707 	WLAN_HOST_DIAG_EVENT_REPORT(&connect_status, EVENT_WLAN_STATUS_V2);
708 }
709 
710 #ifdef WLAN_FEATURE_11BE_MLO
cm_print_mlo_info(struct wlan_objmgr_vdev * vdev)711 static void cm_print_mlo_info(struct wlan_objmgr_vdev *vdev)
712 {
713 	struct wlan_objmgr_peer *peer;
714 	struct qdf_mac_addr *mld_addr;
715 
716 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
717 		return;
718 
719 	mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
720 	peer = wlan_vdev_get_bsspeer(vdev);
721 	if (!peer)
722 		return;
723 
724 	mlme_nofl_debug("self_mld_addr:" QDF_MAC_ADDR_FMT " link_id:%d",
725 			QDF_MAC_ADDR_REF(mld_addr->bytes),
726 			wlan_vdev_get_link_id(vdev));
727 	mlme_nofl_debug("peer_mld_mac:" QDF_MAC_ADDR_FMT,
728 			QDF_MAC_ADDR_REF(peer->mldaddr));
729 }
730 #else
cm_print_mlo_info(struct wlan_objmgr_vdev * vdev)731 static void cm_print_mlo_info(struct wlan_objmgr_vdev *vdev)
732 {
733 }
734 #endif
735 
cm_connect_info(struct wlan_objmgr_vdev * vdev,bool connect_success,struct qdf_mac_addr * bssid,struct wlan_ssid * ssid,qdf_freq_t freq)736 void cm_connect_info(struct wlan_objmgr_vdev *vdev, bool connect_success,
737 		     struct qdf_mac_addr *bssid, struct wlan_ssid *ssid,
738 		     qdf_freq_t freq)
739 {
740 	struct wlan_channel *des_chan;
741 	struct vdev_mlme_obj *vdev_mlme;
742 	struct wlan_crypto_params *crypto_params;
743 	uint8_t max_supported_nss;
744 	enum QDF_OPMODE opmode;
745 	struct wlan_objmgr_pdev *pdev;
746 	struct wlan_objmgr_psoc *psoc;
747 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
748 	enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
749 	WLAN_HOST_DIAG_EVENT_DEF(conn_stats,
750 				 struct host_event_wlan_connection_stats);
751 
752 	if (!ssid || !bssid)
753 		return;
754 	pdev = wlan_vdev_get_pdev(vdev);
755 	if (!pdev)
756 		return;
757 	psoc = wlan_pdev_get_psoc(pdev);
758 	if (!psoc)
759 		return;
760 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
761 	if (!mlme_obj)
762 		return;
763 	qdf_mem_zero(&conn_stats,
764 		     sizeof(struct host_event_wlan_connection_stats));
765 
766 	qdf_mem_copy(conn_stats.bssid, bssid->bytes,
767 		     QDF_MAC_ADDR_SIZE);
768 
769 	conn_stats.ssid_len = ssid->length;
770 	if (conn_stats.ssid_len > WLAN_SSID_MAX_LEN)
771 		conn_stats.ssid_len = WLAN_SSID_MAX_LEN;
772 	qdf_mem_copy(conn_stats.ssid, ssid->ssid, conn_stats.ssid_len);
773 
774 	cm_get_rssi_snr_by_bssid(pdev, bssid, &conn_stats.rssi, NULL);
775 	conn_stats.est_link_speed = 0;
776 
777 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
778 
779 	wlan_mlme_get_sta_ch_width(vdev, &ch_width);
780 	conn_stats.chnl_bw = cm_get_diag_ch_width(ch_width);
781 	conn_stats.dot11mode =
782 		cm_diag_dot11_mode_from_phy_mode(des_chan->ch_phymode);
783 
784 	opmode = wlan_vdev_mlme_get_opmode(vdev);
785 	conn_stats.bss_type = cm_get_diag_persona(opmode);
786 
787 	if (freq)
788 		conn_stats.operating_channel =
789 			wlan_reg_freq_to_chan(pdev, freq);
790 
791 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
792 	if (!vdev_mlme) {
793 		mlme_err("vdev component object is NULL");
794 		return;
795 	}
796 	conn_stats.qos_capability =
797 			vdev_mlme->ext_vdev_ptr->connect_info.qos_enabled;
798 
799 	crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
800 
801 	if (!crypto_params) {
802 		mlme_err("crypto params is null");
803 		return;
804 	}
805 
806 	cm_diag_get_auth_type(&conn_stats.auth_type,
807 			   crypto_params->authmodeset,
808 			   crypto_params->key_mgmt,
809 			   crypto_params->ucastcipherset);
810 
811 	conn_stats.encryption_type =
812 	     cm_get_diag_enc_type(crypto_params->ucastcipherset);
813 
814 	conn_stats.result_code = connect_success;
815 	conn_stats.reason_code = 0;
816 	conn_stats.op_freq = freq;
817 
818 	max_supported_nss = mlme_obj->cfg.vht_caps.vht_cap_info.enable2x2 ?
819 			    MAX_VDEV_NSS : 1;
820 	mlme_nofl_debug("+---------CONNECTION INFO START------------+");
821 	mlme_nofl_debug("VDEV-ID: %d self_mac:"QDF_MAC_ADDR_FMT,
822 			wlan_vdev_get_id(vdev),
823 			QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)));
824 	mlme_nofl_debug("ssid: " QDF_SSID_FMT " bssid: " QDF_MAC_ADDR_FMT " RSSI: %d dBm",
825 			QDF_SSID_REF(conn_stats.ssid_len, conn_stats.ssid),
826 			QDF_MAC_ADDR_REF(conn_stats.bssid), conn_stats.rssi);
827 	mlme_nofl_debug("Channel Freq: %d channel_bw: %s dot11Mode: %s",
828 			conn_stats.op_freq,
829 			cm_diag_get_ch_width_str(conn_stats.chnl_bw),
830 			cm_diag_get_dot11_mode_str(conn_stats.dot11mode));
831 	mlme_nofl_debug("AKM: %s Encry-type: %s",
832 			cm_diag_get_akm_str(conn_stats.auth_type,
833 					    crypto_params->key_mgmt),
834 			cm_diag_get_encr_type_str(conn_stats.encryption_type));
835 	mlme_nofl_debug("DUT_NSS: %d | Intersected NSS:%d",
836 			max_supported_nss, wlan_vdev_mlme_get_nss(vdev));
837 	mlme_nofl_debug("Qos enable: %d | Associated: %s",
838 			conn_stats.qos_capability,
839 			(conn_stats.result_code ? "yes" : "no"));
840 	cm_print_mlo_info(vdev);
841 	mlme_nofl_debug("+---------CONNECTION INFO END------------+");
842 
843 	WLAN_HOST_DIAG_EVENT_REPORT(&conn_stats, EVENT_WLAN_CONN_STATS_V2);
844 
845 	if (!connect_success)
846 		return;
847 
848 	/* store connect info on success */
849 	cm_connect_success_diag(mlme_obj, &conn_stats);
850 }
851 
cm_diag_get_auth_enc_type_vdev_id(struct wlan_objmgr_psoc * psoc,uint8_t * auth_type,uint8_t * ucast_cipher,uint8_t * mcast_cipher,uint8_t vdev_id)852 void cm_diag_get_auth_enc_type_vdev_id(struct wlan_objmgr_psoc *psoc,
853 				       uint8_t *auth_type,
854 				       uint8_t *ucast_cipher,
855 				       uint8_t *mcast_cipher,
856 				       uint8_t vdev_id)
857 {
858 	struct wlan_objmgr_vdev *vdev;
859 	struct wlan_crypto_params *crypto_params;
860 
861 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
862 						    WLAN_MLME_CM_ID);
863 	if (!vdev) {
864 		mlme_err("vdev object is NULL for vdev %d", vdev_id);
865 		return;
866 	}
867 
868 	crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
869 	if (!crypto_params) {
870 		mlme_err("crypto params is null");
871 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
872 		return;
873 	}
874 	if (auth_type)
875 		cm_diag_get_auth_type(auth_type,
876 				      crypto_params->authmodeset,
877 				      crypto_params->key_mgmt,
878 				      crypto_params->ucastcipherset);
879 	if (ucast_cipher)
880 		*ucast_cipher =
881 			cm_get_diag_enc_type(crypto_params->ucastcipherset);
882 	if (mcast_cipher)
883 		*mcast_cipher =
884 			cm_get_diag_enc_type(crypto_params->ucastcipherset);
885 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
886 
887 }
888 
889 #ifdef WLAN_UNIT_TEST
cm_diag_get_persona(enum mgmt_bss_type persona)890 static const char *cm_diag_get_persona(enum mgmt_bss_type persona)
891 {
892 	switch (persona) {
893 	CASE_RETURN_STRING(STA_PERSONA);
894 	CASE_RETURN_STRING(SAP_PERSONA);
895 	CASE_RETURN_STRING(P2P_CLIENT_PERSONA);
896 	CASE_RETURN_STRING(P2P_GO_PERSONA);
897 	CASE_RETURN_STRING(FTM_PERSONA);
898 	CASE_RETURN_STRING(MONITOR_PERSONA);
899 	CASE_RETURN_STRING(P2P_DEVICE_PERSONA);
900 	CASE_RETURN_STRING(NDI_PERSONA);
901 	CASE_RETURN_STRING(WDS_PERSONA);
902 	default:
903 		return "Unknown";
904 	}
905 }
906 
cm_diag_get_auth_type_str(uint8_t auth_type)907 static const char *cm_diag_get_auth_type_str(uint8_t auth_type)
908 {
909 	switch (auth_type) {
910 	CASE_RETURN_STRING(AUTH_OPEN);
911 	CASE_RETURN_STRING(AUTH_SHARED);
912 	CASE_RETURN_STRING(AUTH_WPA_EAP);
913 	CASE_RETURN_STRING(AUTH_WPA_PSK);
914 	CASE_RETURN_STRING(AUTH_WPA2_EAP);
915 	CASE_RETURN_STRING(AUTH_WPA2_PSK);
916 	CASE_RETURN_STRING(AUTH_WAPI_CERT);
917 	CASE_RETURN_STRING(AUTH_WAPI_PSK);
918 	default:
919 		return "Unknown";
920 	}
921 }
922 
cm_get_sta_cxn_info(struct wlan_objmgr_vdev * vdev,char * buf,uint32_t buf_sz)923 void cm_get_sta_cxn_info(struct wlan_objmgr_vdev *vdev,
924 			 char *buf, uint32_t buf_sz)
925 {
926 	struct qdf_mac_addr bss_peer_mac;
927 	struct wlan_ssid ssid;
928 	QDF_STATUS status;
929 	struct wlan_channel *des_chan;
930 	struct vdev_mlme_obj *vdev_mlme;
931 	struct wlan_crypto_params *crypto_params;
932 	qdf_freq_t oper_freq;
933 	int8_t rssi = 0;
934 	uint32_t nss, hw_mode;
935 	struct policy_mgr_conc_connection_info *conn_info;
936 	uint32_t i = 0, len = 0, max_cxn = 0;
937 	enum mgmt_ch_width ch_width;
938 	enum mgmt_dot11_mode dot11mode;
939 	enum mgmt_bss_type type;
940 	uint8_t authtype;
941 	enum mgmt_encrypt_type enctype;
942 	enum QDF_OPMODE opmode;
943 	struct wlan_objmgr_pdev *pdev;
944 	struct wlan_objmgr_psoc *psoc;
945 
946 	pdev = wlan_vdev_get_pdev(vdev);
947 	if (!pdev)
948 		return;
949 	psoc = wlan_pdev_get_psoc(pdev);
950 	if (!psoc)
951 		return;
952 
953 	qdf_mem_set(buf, buf_sz, '\0');
954 
955 	status = wlan_vdev_get_bss_peer_mac(vdev, &bss_peer_mac);
956 	if (QDF_IS_STATUS_ERROR(status))
957 		return;
958 
959 	len += qdf_scnprintf(buf + len, buf_sz - len,
960 			     "\n\tbssid: "QDF_MAC_ADDR_FMT,
961 			     QDF_MAC_ADDR_REF(bss_peer_mac.bytes));
962 
963 	status = wlan_vdev_mlme_get_ssid(vdev, ssid.ssid, &ssid.length);
964 	if (QDF_IS_STATUS_ERROR(status))
965 		return;
966 	if (ssid.length > WLAN_SSID_MAX_LEN)
967 		ssid.length = WLAN_SSID_MAX_LEN;
968 	len += qdf_scnprintf(buf + len, buf_sz - len,
969 			     "\n\tssid: %.*s", ssid.length,
970 			     ssid.ssid);
971 
972 	cm_get_rssi_snr_by_bssid(pdev, &bss_peer_mac, &rssi, NULL);
973 	len += qdf_scnprintf(buf + len, buf_sz - len,
974 			     "\n\trssi: %d", rssi);
975 
976 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
977 	ch_width = cm_get_diag_ch_width(des_chan->ch_width);
978 	len += qdf_scnprintf(buf + len, buf_sz - len,
979 			     "\n\tbw: %s", cm_diag_get_ch_width_str(ch_width));
980 	dot11mode = cm_diag_dot11_mode_from_phy_mode(des_chan->ch_phymode);
981 	len += qdf_scnprintf(buf + len, buf_sz - len,
982 			     "\n\tdot11mode: %s",
983 			     cm_diag_get_dot11_mode_str(dot11mode));
984 
985 	opmode = wlan_vdev_mlme_get_opmode(vdev);
986 	type = cm_get_diag_persona(opmode);
987 	len += qdf_scnprintf(buf + len, buf_sz - len,
988 			     "\n\tbss_type: %s", cm_diag_get_persona(type));
989 
990 	oper_freq = wlan_get_operation_chan_freq(vdev);
991 	len += qdf_scnprintf(buf + len, buf_sz - len,
992 			     "\n\tch_freq: %d", oper_freq);
993 
994 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
995 	if (!vdev_mlme) {
996 		mlme_err("vdev component object is NULL");
997 		return;
998 	}
999 	len += qdf_scnprintf(buf + len, buf_sz - len,
1000 			     "\n\tQoS: %d",
1001 			     vdev_mlme->ext_vdev_ptr->connect_info.qos_enabled);
1002 
1003 	crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
1004 
1005 	if (!crypto_params) {
1006 		mlme_err("crypto params is null");
1007 		return;
1008 	}
1009 
1010 	cm_diag_get_auth_type(&authtype, crypto_params->authmodeset,
1011 			   crypto_params->key_mgmt,
1012 			   crypto_params->ucastcipherset);
1013 	len += qdf_scnprintf(buf + len, buf_sz - len,
1014 			     "\n\tauth_type: %s",
1015 			     cm_diag_get_auth_type_str(authtype));
1016 
1017 	enctype = cm_get_diag_enc_type(crypto_params->ucastcipherset);
1018 	len += qdf_scnprintf(buf + len, buf_sz - len,
1019 			     "\n\tencry_type: %s",
1020 			     cm_diag_get_encr_type_str(enctype));
1021 
1022 	conn_info = policy_mgr_get_conn_info(&max_cxn);
1023 	for (i = 0; i < max_cxn; i++)
1024 		if ((conn_info->vdev_id == wlan_vdev_get_id(vdev)) &&
1025 		    (conn_info->in_use))
1026 			break;
1027 	len += qdf_scnprintf(buf + len, buf_sz - len,
1028 			     "\n\tmac: %d", conn_info->mac);
1029 	nss = wlan_vdev_mlme_get_nss(vdev);
1030 	len += qdf_scnprintf(buf + len, buf_sz - len,
1031 			     "\n\torig_nss: %dx%d neg_nss: %dx%d",
1032 			     conn_info->original_nss, conn_info->original_nss,
1033 			     nss, nss);
1034 	hw_mode = policy_mgr_is_current_hwmode_dbs(psoc);
1035 	len += qdf_scnprintf(buf + len, buf_sz - len,
1036 			     "\n\tis_current_hw_mode_dbs: %s",
1037 			     ((hw_mode != 0) ? "yes" : "no"));
1038 }
1039 #endif
1040 #endif
1041 
1042 #define MGMT_FRAME_FULL_PROTECTION (RSN_CAP_MFP_REQUIRED | RSN_CAP_MFP_CAPABLE)
1043 
cm_connect_start_ind(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * req)1044 QDF_STATUS cm_connect_start_ind(struct wlan_objmgr_vdev *vdev,
1045 				struct wlan_cm_connect_req *req)
1046 {
1047 	struct wlan_objmgr_psoc *psoc;
1048 	struct rso_config *rso_cfg;
1049 	struct cm_roam_values_copy src_cfg = {};
1050 
1051 	if (!vdev || !req) {
1052 		mlme_err("vdev or req is NULL");
1053 		return QDF_STATUS_E_INVAL;
1054 	}
1055 
1056 	psoc = wlan_vdev_get_psoc(vdev);
1057 	if (!psoc) {
1058 		mlme_err("vdev_id: %d psoc not found", req->vdev_id);
1059 		return QDF_STATUS_E_INVAL;
1060 	}
1061 
1062 	if (!wlan_dp_is_local_pkt_capture_active(psoc) &&
1063 	    policy_mgr_is_sta_mon_concurrency(psoc))
1064 		return QDF_STATUS_E_NOSUPPORT;
1065 
1066 	rso_cfg = wlan_cm_get_rso_config(vdev);
1067 	if (rso_cfg) {
1068 		uint8_t rso_user_mfp;
1069 
1070 		rso_cfg->orig_sec_info.rsn_caps = req->crypto.rsn_caps;
1071 		rso_cfg->orig_sec_info.authmodeset = req->crypto.auth_type;
1072 		rso_cfg->orig_sec_info.ucastcipherset =
1073 					req->crypto.ciphers_pairwise;
1074 		rso_cfg->orig_sec_info.mcastcipherset =
1075 					req->crypto.group_cipher;
1076 		rso_cfg->orig_sec_info.key_mgmt = req->crypto.akm_suites;
1077 		/*
1078 		 * reset the roam channel list entries present in the rso
1079 		 * config which gets stored during connect resp failure in
1080 		 * wlan_cm_send_connect_rsp
1081 		 */
1082 		rso_cfg->tried_candidate_freq_list.num_chan = 0;
1083 
1084 		/*
1085 		 * This user configure MFP capability is global and is for
1086 		 * multiple profiles which can be used by firmware for cross-AKM
1087 		 * roaming. When user configures MFP required then we should
1088 		 * set both MFPC and MFPR in RSN caps.
1089 		 */
1090 		rso_user_mfp = req->crypto.user_mfp;
1091 		if (rso_user_mfp == RSN_CAP_MFP_REQUIRED)
1092 			rso_user_mfp = MGMT_FRAME_FULL_PROTECTION;
1093 		rso_cfg->rso_rsn_caps = (req->crypto.rsn_caps) &
1094 					(~MGMT_FRAME_FULL_PROTECTION);
1095 		rso_cfg->rso_rsn_caps = (rso_cfg->rso_rsn_caps) | rso_user_mfp;
1096 	}
1097 
1098 	if (wlan_get_vendor_ie_ptr_from_oui(HS20_OUI_TYPE,
1099 					    HS20_OUI_TYPE_SIZE,
1100 					    req->assoc_ie.ptr,
1101 					    req->assoc_ie.len))
1102 		src_cfg.bool_value = true;
1103 	wlan_cm_roam_cfg_set_value(wlan_vdev_get_psoc(vdev),
1104 				   wlan_vdev_get_id(vdev),
1105 				   HS_20_AP, &src_cfg);
1106 	if (req->source != CM_MLO_LINK_SWITCH_CONNECT)
1107 		ml_nlink_conn_change_notify(
1108 			psoc, wlan_vdev_get_id(vdev),
1109 			ml_nlink_connect_start_evt, NULL);
1110 
1111 	return QDF_STATUS_SUCCESS;
1112 }
1113 
cm_free_join_req(struct cm_vdev_join_req * join_req)1114 void cm_free_join_req(struct cm_vdev_join_req *join_req)
1115 {
1116 	if (!join_req)
1117 		return;
1118 
1119 	util_scan_free_cache_entry(join_req->entry);
1120 	join_req->entry = NULL;
1121 	qdf_mem_free(join_req->assoc_ie.ptr);
1122 	qdf_mem_free(join_req->scan_ie.ptr);
1123 	join_req->assoc_ie.ptr = NULL;
1124 	join_req->scan_ie.ptr = NULL;
1125 	qdf_mem_free(join_req);
1126 }
1127 
cm_flush_join_req(struct scheduler_msg * msg)1128 QDF_STATUS cm_flush_join_req(struct scheduler_msg *msg)
1129 {
1130 	struct cm_vdev_join_req *join_req;
1131 
1132 	if (!msg || !msg->bodyptr) {
1133 		mlme_err("msg or msg->bodyptr is NULL");
1134 		return QDF_STATUS_E_INVAL;
1135 	}
1136 
1137 	join_req = msg->bodyptr;
1138 	cm_free_join_req(join_req);
1139 
1140 	return QDF_STATUS_SUCCESS;
1141 }
1142 #ifdef WLAN_FEATURE_11BE_MLO
1143 #if defined (SAP_MULTI_LINK_EMULATION)
1144 static void
set_partner_info_for_2link_sap(struct scan_cache_entry * scan_entry,struct mlo_partner_info * partner_info)1145 set_partner_info_for_2link_sap(struct scan_cache_entry *scan_entry,
1146 			       struct mlo_partner_info *partner_info)
1147 {
1148 	partner_info->partner_link_info[0].link_addr =
1149 		scan_entry->ml_info.link_info[0].link_addr;
1150 	partner_info->partner_link_info[0].link_id =
1151 		scan_entry->ml_info.link_info[0].link_id;
1152 	partner_info->partner_link_info[0].chan_freq =
1153 		scan_entry->ml_info.link_info[0].freq;
1154 	partner_info->num_partner_links = 1;
1155 
1156 }
1157 #else
1158 static void
set_partner_info_for_2link_sap(struct scan_cache_entry * scan_entry,struct mlo_partner_info * partner_info)1159 set_partner_info_for_2link_sap(struct scan_cache_entry *scan_entry,
1160 			       struct mlo_partner_info *partner_info)
1161 {
1162 }
1163 #endif
1164 
1165 QDF_STATUS
cm_get_ml_partner_info(struct wlan_objmgr_pdev * pdev,struct cm_connect_req * conn_req)1166 cm_get_ml_partner_info(struct wlan_objmgr_pdev *pdev,
1167 		       struct cm_connect_req *conn_req)
1168 {
1169 	uint8_t i, j = 0;
1170 	uint8_t mlo_support_link_num;
1171 	struct wlan_objmgr_psoc *psoc;
1172 	struct scan_cache_entry *scan_entry = conn_req->cur_candidate->entry;
1173 	struct mlo_partner_info *partner_info = &conn_req->req.ml_parnter_info;
1174 
1175 	/* Initialize number of partner links as zero */
1176 	partner_info->num_partner_links = 0;
1177 
1178 	/* If ML IE is not present then return failure*/
1179 	if (!scan_entry->ie_list.multi_link_bv)
1180 		return QDF_STATUS_E_FAILURE;
1181 
1182 	/* In case of single link ML return success*/
1183 	if (!scan_entry->ml_info.num_links)
1184 		return QDF_STATUS_SUCCESS;
1185 
1186 	psoc = wlan_pdev_get_psoc(pdev);
1187 	if (!psoc) {
1188 		mlme_err("psoc is NULL");
1189 		return QDF_STATUS_E_INVAL;
1190 	}
1191 
1192 	mlo_support_link_num = wlan_mlme_get_sta_mlo_conn_max_num(psoc);
1193 	mlme_debug("sta mlo support link num: %d", mlo_support_link_num);
1194 
1195 	/* TODO: Make sure that scan_entry->ml_info->link_info is a sorted
1196 	 * list.
1197 	 * When candidates are selected by filter, partner link is set as
1198 	 * valid in scan entry when mlo band match, then valid partner link is
1199 	 * copied to join request, after that partner link valid bit in scan
1200 	 * entry should be cleared to not affect next connect request.
1201 	 */
1202 	for (i = 0; i < scan_entry->ml_info.num_links; i++) {
1203 		mlme_debug("freq: %d, link id: %d is valid %d "QDF_MAC_ADDR_FMT,
1204 			   scan_entry->ml_info.link_info[i].freq,
1205 			   scan_entry->ml_info.link_info[i].link_id,
1206 			   scan_entry->ml_info.link_info[i].is_valid_link,
1207 			   QDF_MAC_ADDR_REF(
1208 			   scan_entry->ml_info.link_info[i].link_addr.bytes));
1209 		if (mlo_support_link_num && j >= mlo_support_link_num - 1)
1210 			break;
1211 
1212 		if (!scan_entry->ml_info.link_info[i].is_valid_link)
1213 			continue;
1214 
1215 		partner_info->partner_link_info[j].link_addr =
1216 				scan_entry->ml_info.link_info[i].link_addr;
1217 		partner_info->partner_link_info[j].link_id =
1218 				scan_entry->ml_info.link_info[i].link_id;
1219 		partner_info->partner_link_info[j].chan_freq =
1220 				scan_entry->ml_info.link_info[i].freq;
1221 		j++;
1222 	}
1223 
1224 	partner_info->num_partner_links = j;
1225 	mlme_debug("sta and ap intersect num of partner link: %d", j);
1226 
1227 	set_partner_info_for_2link_sap(scan_entry, partner_info);
1228 
1229 	return QDF_STATUS_SUCCESS;
1230 }
1231 
cm_update_mlo_mgr_info(struct wlan_objmgr_vdev * vdev,struct cm_vdev_join_req * join_req)1232 static void cm_update_mlo_mgr_info(struct wlan_objmgr_vdev *vdev,
1233 				   struct cm_vdev_join_req *join_req)
1234 {
1235 	struct qdf_mac_addr link_addr;
1236 	uint8_t link_id, i;
1237 	struct wlan_channel channel = {0};
1238 	struct mlo_partner_info *partner_info;
1239 
1240 	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
1241 		return;
1242 
1243 	link_id = join_req->entry->ml_info.self_link_id;
1244 	qdf_mem_copy(link_addr.bytes, join_req->entry->bssid.bytes,
1245 		     QDF_MAC_ADDR_SIZE);
1246 
1247 	/* Reset Previous info if any and update the AP self link info */
1248 	mlo_mgr_reset_ap_link_info(vdev);
1249 	mlo_mgr_update_ap_link_info(vdev, link_id, link_addr.bytes, channel);
1250 
1251 	partner_info = &join_req->partner_info;
1252 	for (i = 0; i < partner_info->num_partner_links; i++) {
1253 		link_id = partner_info->partner_link_info[i].link_id;
1254 		qdf_mem_copy(link_addr.bytes,
1255 			     partner_info->partner_link_info[i].link_addr.bytes,
1256 			     QDF_MAC_ADDR_SIZE);
1257 		/* Updating AP partner link info */
1258 		mlo_mgr_update_ap_link_info(vdev, link_id, link_addr.bytes,
1259 					    channel);
1260 	}
1261 }
1262 
1263 static void
cm_copy_join_req_info_from_cm_connect_req(struct wlan_objmgr_vdev * vdev,struct cm_vdev_join_req * join_req,struct wlan_cm_vdev_connect_req * req)1264 cm_copy_join_req_info_from_cm_connect_req(struct wlan_objmgr_vdev *vdev,
1265 					  struct cm_vdev_join_req *join_req,
1266 					  struct wlan_cm_vdev_connect_req *req)
1267 {
1268 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
1269 		return;
1270 
1271 	qdf_mem_copy(&join_req->partner_info, &req->ml_parnter_info,
1272 		     sizeof(struct mlo_partner_info));
1273 
1274 	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev))
1275 		join_req->assoc_link_id = join_req->entry->ml_info.self_link_id;
1276 
1277 	mlme_debug("Num of partner links %d assoc_link_id:%d",
1278 		   join_req->partner_info.num_partner_links,
1279 		   join_req->assoc_link_id);
1280 
1281 	cm_update_mlo_mgr_info(vdev, join_req);
1282 }
1283 #else
1284 static inline void
cm_copy_join_req_info_from_cm_connect_req(struct wlan_objmgr_vdev * vdev,struct cm_vdev_join_req * join_req,struct wlan_cm_vdev_connect_req * req)1285 cm_copy_join_req_info_from_cm_connect_req(struct wlan_objmgr_vdev *vdev,
1286 					  struct cm_vdev_join_req *join_req,
1287 					  struct wlan_cm_vdev_connect_req *req)
1288 {
1289 }
1290 #endif
1291 
1292 static QDF_STATUS
cm_copy_join_params(struct wlan_objmgr_vdev * vdev,struct cm_vdev_join_req * join_req,struct wlan_cm_vdev_connect_req * req)1293 cm_copy_join_params(struct wlan_objmgr_vdev *vdev,
1294 		    struct cm_vdev_join_req *join_req,
1295 		    struct wlan_cm_vdev_connect_req *req)
1296 {
1297 	if (req->assoc_ie.len) {
1298 		join_req->assoc_ie.ptr = qdf_mem_malloc(req->assoc_ie.len);
1299 		if (!join_req->assoc_ie.ptr)
1300 		return QDF_STATUS_E_NOMEM;
1301 		qdf_mem_copy(join_req->assoc_ie.ptr, req->assoc_ie.ptr,
1302 			     req->assoc_ie.len);
1303 		join_req->assoc_ie.len = req->assoc_ie.len;
1304 	}
1305 	if (req->scan_ie.len) {
1306 		join_req->scan_ie.ptr = qdf_mem_malloc(req->scan_ie.len);
1307 		if (!join_req->scan_ie.ptr)
1308 			return QDF_STATUS_E_NOMEM;
1309 		join_req->scan_ie.len = req->scan_ie.len;
1310 		qdf_mem_copy(join_req->scan_ie.ptr, req->scan_ie.ptr,
1311 			     req->scan_ie.len);
1312 	}
1313 	join_req->entry = util_scan_copy_cache_entry(req->bss->entry);
1314 	if (!join_req->entry)
1315 		return QDF_STATUS_E_NOMEM;
1316 
1317 	cm_copy_join_req_info_from_cm_connect_req(vdev, join_req, req);
1318 
1319 	if (req->owe_trans_ssid.length)
1320 		join_req->owe_trans_ssid = req->owe_trans_ssid;
1321 
1322 	join_req->vdev_id = req->vdev_id;
1323 	join_req->cm_id = req->cm_id;
1324 	join_req->force_rsne_override = req->force_rsne_override;
1325 	join_req->is_wps_connection = req->is_wps_connection;
1326 	join_req->is_osen_connection = req->is_osen_connection;
1327 	join_req->is_ssid_hidden = req->bss->entry->is_hidden_ssid;
1328 
1329 	return QDF_STATUS_SUCCESS;
1330 }
1331 
wlan_cm_send_connect_rsp(struct scheduler_msg * msg)1332 QDF_STATUS wlan_cm_send_connect_rsp(struct scheduler_msg *msg)
1333 {
1334 	struct cm_vdev_join_rsp *rsp;
1335 	struct wlan_objmgr_vdev *vdev;
1336 	QDF_STATUS status;
1337 	struct wlan_objmgr_peer *peer;
1338 
1339 	if (!msg || !msg->bodyptr)
1340 		return QDF_STATUS_E_FAILURE;
1341 
1342 	rsp = msg->bodyptr;
1343 
1344 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(rsp->psoc,
1345 						    rsp->connect_rsp.vdev_id,
1346 						    WLAN_MLME_CM_ID);
1347 	if (!vdev) {
1348 		mlme_err(CM_PREFIX_FMT "vdev not found",
1349 			 CM_PREFIX_REF(rsp->connect_rsp.vdev_id,
1350 				       rsp->connect_rsp.cm_id));
1351 		wlan_cm_free_connect_rsp(rsp);
1352 		return QDF_STATUS_E_INVAL;
1353 	}
1354 
1355 	/*  check and delete bss peer in case of failure */
1356 	if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status) &&
1357 	    (wlan_vdev_mlme_is_init_state(vdev) == QDF_STATUS_SUCCESS)) {
1358 		peer = wlan_objmgr_vdev_try_get_bsspeer(vdev,
1359 							WLAN_MLME_CM_ID);
1360 		if (peer) {
1361 			cm_send_bss_peer_delete_req(vdev);
1362 			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_CM_ID);
1363 		}
1364 	}
1365 
1366 	/*
1367 	 * Host creates a ROAM_SCAN_CHAN list with BSSID entries present
1368 	 * in the scan database. If the connection to an AP fails due to
1369 	 * Auth/Join/Assoc timeout, Host removes the AP entry from the
1370 	 * Scan database, assuming it’s not reachable (to avoid
1371 	 * reconnecting to the AP as it's not responding). Due to this,
1372 	 * FW does not include the frequency(s), for which the
1373 	 * connection failed, in roam scan.
1374 	 * To avoid this, store the frequency(s) of all the candidates
1375 	 * to which the driver tried connection in the rso config during
1376 	 * connect resp failure and use the same list to update the roam
1377 	 * channel list on the top of entries present in scan db.
1378 	 */
1379 	if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status))
1380 		cm_update_tried_candidate_freq_list(rsp->psoc, vdev,
1381 						    &rsp->connect_rsp);
1382 
1383 	cm_csr_connect_rsp(vdev, rsp);
1384 	if (rsp->connect_rsp.is_reassoc)
1385 		status = wlan_cm_reassoc_rsp(vdev, &rsp->connect_rsp);
1386 	else
1387 		status = wlan_cm_connect_rsp(vdev, &rsp->connect_rsp);
1388 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
1389 
1390 	wlan_cm_free_connect_rsp(rsp);
1391 
1392 	return status;
1393 }
1394 
1395 #define FILS_HLP_OUI_TYPE "\x5"
1396 #define FILS_HLP_OUI_LEN 1
1397 
1398 static void
cm_update_hlp_data_from_assoc_ie(struct wlan_objmgr_vdev * vdev,struct wlan_cm_vdev_connect_req * req)1399 cm_update_hlp_data_from_assoc_ie(struct wlan_objmgr_vdev *vdev,
1400 				 struct wlan_cm_vdev_connect_req *req)
1401 {
1402 	const uint8_t *hlp_ext_ie;
1403 	const uint8_t *fragment_ie;
1404 
1405 	/* clear hlp IE */
1406 	cm_update_hlp_info(vdev, NULL, 0, true);
1407 
1408 	hlp_ext_ie = wlan_get_ext_ie_ptr_from_ext_id(FILS_HLP_OUI_TYPE,
1409 						     FILS_HLP_OUI_LEN,
1410 						     req->assoc_ie.ptr,
1411 						     req->assoc_ie.len);
1412 	if (hlp_ext_ie)
1413 		cm_update_hlp_info(vdev, hlp_ext_ie, hlp_ext_ie[1] + 2, false);
1414 
1415 	fragment_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_FRAGMENT_IE,
1416 					       req->assoc_ie.ptr,
1417 					       req->assoc_ie.len);
1418 	if (fragment_ie)
1419 		cm_update_hlp_info(vdev, fragment_ie,
1420 				   fragment_ie[1] + 2, false);
1421 }
1422 
1423 QDF_STATUS
cm_handle_connect_req(struct wlan_objmgr_vdev * vdev,struct wlan_cm_vdev_connect_req * req)1424 cm_handle_connect_req(struct wlan_objmgr_vdev *vdev,
1425 			    struct wlan_cm_vdev_connect_req *req)
1426 {
1427 	struct cm_vdev_join_req *join_req;
1428 	struct scheduler_msg msg;
1429 	QDF_STATUS status;
1430 	struct wlan_objmgr_psoc *psoc;
1431 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
1432 
1433 	if (!vdev || !req)
1434 		return QDF_STATUS_E_FAILURE;
1435 
1436 	psoc = wlan_vdev_get_psoc(vdev);
1437 	if (!psoc) {
1438 		mlme_err(CM_PREFIX_FMT "psoc not found",
1439 			 CM_PREFIX_REF(req->vdev_id, req->cm_id));
1440 		return QDF_STATUS_E_INVAL;
1441 	}
1442 
1443 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
1444 	if (!mlme_obj)
1445 		return QDF_STATUS_E_INVAL;
1446 
1447 	qdf_mem_zero(&msg, sizeof(msg));
1448 	join_req = qdf_mem_malloc(sizeof(*join_req));
1449 	if (!join_req)
1450 		return QDF_STATUS_E_NOMEM;
1451 
1452 	status = cm_copy_join_params(vdev ,join_req, req);
1453 	if (QDF_IS_STATUS_ERROR(status)) {
1454 		mlme_err(CM_PREFIX_FMT "Failed to copy join req",
1455 			 CM_PREFIX_REF(req->vdev_id, req->cm_id));
1456 		cm_free_join_req(join_req);
1457 		return QDF_STATUS_E_FAILURE;
1458 	}
1459 
1460 	cm_update_hlp_data_from_assoc_ie(vdev, req);
1461 
1462 	status = cm_csr_handle_join_req(vdev, req, join_req, false);
1463 	if (QDF_IS_STATUS_ERROR(status)) {
1464 		mlme_err(CM_PREFIX_FMT "fail to fill params from legacy",
1465 			 CM_PREFIX_REF(req->vdev_id, req->cm_id));
1466 		cm_free_join_req(join_req);
1467 		return QDF_STATUS_E_FAILURE;
1468 	}
1469 
1470 	mlme_debug(CM_PREFIX_FMT "HT cap %x",
1471 		   CM_PREFIX_REF(req->vdev_id, req->cm_id), req->ht_caps);
1472 	wlan_rec_conn_info(req->vdev_id, DEBUG_CONN_CONNECTING,
1473 			   req->bss->entry->bssid.bytes,
1474 			   req->bss->entry->neg_sec_info.key_mgmt,
1475 			   req->bss->entry->channel.chan_freq);
1476 
1477 	msg.bodyptr = join_req;
1478 	msg.type = CM_CONNECT_REQ;
1479 	msg.flush_callback = cm_flush_join_req;
1480 
1481 	status = scheduler_post_message(QDF_MODULE_ID_MLME,
1482 					QDF_MODULE_ID_PE,
1483 					QDF_MODULE_ID_PE, &msg);
1484 	if (QDF_IS_STATUS_ERROR(status)) {
1485 		mlme_err(CM_PREFIX_FMT "msg post fail",
1486 			 CM_PREFIX_REF(req->vdev_id, req->cm_id));
1487 		cm_free_join_req(join_req);
1488 	}
1489 
1490 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
1491 		wlan_register_txrx_packetdump(OL_TXRX_PDEV_ID);
1492 
1493 	return status;
1494 }
1495 
1496 #ifdef WLAN_FEATURE_11BE_MLO
1497 /**
1498  * cm_set_peer_mld_info() - set mld_mac and is_assoc_peer flag
1499  * @req: cm_peer_create_req
1500  * @mld_mac: mld mac addr
1501  * @is_assoc_peer: is assoc peer
1502  *
1503  * Return: void
1504  */
cm_set_peer_mld_info(struct cm_peer_create_req * req,struct qdf_mac_addr * mld_mac,bool is_assoc_peer)1505 static void cm_set_peer_mld_info(struct cm_peer_create_req *req,
1506 				 struct qdf_mac_addr *mld_mac,
1507 				 bool is_assoc_peer)
1508 {
1509 	if (req && mld_mac) {
1510 		qdf_copy_macaddr(&req->mld_mac, mld_mac);
1511 		req->is_assoc_peer = is_assoc_peer;
1512 	}
1513 }
1514 #else
cm_set_peer_mld_info(struct cm_peer_create_req * req,struct qdf_mac_addr * mld_mac,bool is_assoc_peer)1515 static void cm_set_peer_mld_info(struct cm_peer_create_req *req,
1516 				 struct qdf_mac_addr *mld_mac,
1517 				 bool is_assoc_peer)
1518 {
1519 }
1520 #endif
1521 
1522 QDF_STATUS
cm_send_bss_peer_create_req(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * peer_mac,struct qdf_mac_addr * mld_mac,bool is_assoc_peer)1523 cm_send_bss_peer_create_req(struct wlan_objmgr_vdev *vdev,
1524 			    struct qdf_mac_addr *peer_mac,
1525 			    struct qdf_mac_addr *mld_mac,
1526 			    bool is_assoc_peer)
1527 {
1528 	struct scheduler_msg msg;
1529 	QDF_STATUS status;
1530 	struct cm_peer_create_req *req;
1531 
1532 	if (!vdev || !peer_mac)
1533 		return QDF_STATUS_E_FAILURE;
1534 
1535 	qdf_mem_zero(&msg, sizeof(msg));
1536 	req = qdf_mem_malloc(sizeof(*req));
1537 
1538 	if (!req)
1539 		return QDF_STATUS_E_NOMEM;
1540 
1541 	cm_set_peer_mld_info(req, mld_mac, is_assoc_peer);
1542 
1543 	req->vdev_id = wlan_vdev_get_id(vdev);
1544 	qdf_copy_macaddr(&req->peer_mac, peer_mac);
1545 	msg.bodyptr = req;
1546 	msg.type = CM_BSS_PEER_CREATE_REQ;
1547 
1548 	status = scheduler_post_message(QDF_MODULE_ID_MLME,
1549 					QDF_MODULE_ID_PE,
1550 					QDF_MODULE_ID_PE, &msg);
1551 	if (QDF_IS_STATUS_ERROR(status)) {
1552 		mlme_err("vdev %d: post fail", req->vdev_id);
1553 		qdf_mem_free(req);
1554 	}
1555 
1556 	return status;
1557 
1558 }
1559 
1560 #ifdef WLAN_FEATURE_FILS_SK
is_fils_connection(struct wlan_cm_connect_resp * resp)1561 static inline bool is_fils_connection(struct wlan_cm_connect_resp *resp)
1562 {
1563 	return resp->is_fils_connection;
1564 }
1565 #else
is_fils_connection(struct wlan_cm_connect_resp * resp)1566 static inline bool is_fils_connection(struct wlan_cm_connect_resp *resp)
1567 {
1568 	return false;
1569 }
1570 #endif
1571 
cm_process_connect_complete(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1572 static void cm_process_connect_complete(struct wlan_objmgr_psoc *psoc,
1573 					struct wlan_objmgr_pdev *pdev,
1574 					struct wlan_objmgr_vdev *vdev,
1575 					struct wlan_cm_connect_resp *rsp)
1576 {
1577 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
1578 	int32_t ucast_cipher, akm;
1579 	uint32_t key_interval;
1580 	struct element_info *bcn_probe_rsp = &rsp->connect_ies.bcn_probe_rsp;
1581 
1582 	if (bcn_probe_rsp->ptr &&
1583 	    bcn_probe_rsp->len > sizeof(struct wlan_frame_hdr)) {
1584 		cm_update_prev_ap_ie(psoc, vdev_id,
1585 				     bcn_probe_rsp->len -
1586 				     sizeof(struct wlan_frame_hdr),
1587 				     bcn_probe_rsp->ptr +
1588 				     sizeof(struct wlan_frame_hdr));
1589 	}
1590 	akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
1591 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) ||
1592 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) {
1593 		mlme_debug("Update the MDID in PMK cache for FT-SAE case");
1594 		cm_update_pmk_cache_ft(psoc, vdev_id, NULL);
1595 	}
1596 
1597 	cm_update_owe_info(vdev, rsp, vdev_id);
1598 	cm_csr_set_joined(vdev_id);
1599 	cm_csr_send_set_ie(vdev);
1600 
1601 	ucast_cipher = wlan_crypto_get_param(vdev,
1602 					     WLAN_CRYPTO_PARAM_UCAST_CIPHER);
1603 	if (!rsp->is_wps_connection &&
1604 	    (is_fils_connection(rsp) || !ucast_cipher ||
1605 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_NONE) ==
1606 			  ucast_cipher ||
1607 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP_40) ||
1608 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP_104) ||
1609 	    QDF_HAS_PARAM(ucast_cipher, WLAN_CRYPTO_CIPHER_WEP))) {
1610 		cm_csr_set_ss_none(vdev_id);
1611 		if (wlan_vdev_mlme_is_mlo_vdev(vdev))
1612 			mlo_enable_rso(pdev, vdev, rsp);
1613 		else
1614 			cm_roam_start_init_on_connect(pdev, vdev_id);
1615 	} else {
1616 		if (rsp->is_wps_connection)
1617 			key_interval =
1618 				WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
1619 		else
1620 			key_interval =
1621 				WAIT_FOR_KEY_TIMEOUT_PERIOD;
1622 		cm_update_wait_for_key_timer(vdev, vdev_id, key_interval);
1623 	}
1624 
1625 }
1626 
1627 #ifdef WLAN_FEATURE_11BE_MLO
1628 static QDF_STATUS
cm_update_tid_mapping(struct wlan_objmgr_vdev * vdev)1629 cm_update_tid_mapping(struct wlan_objmgr_vdev *vdev)
1630 {
1631 	struct wlan_t2lm_context *t2lm_ctx;
1632 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1633 
1634 	if (!vdev || !vdev->mlo_dev_ctx)
1635 		return QDF_STATUS_E_NULL_VALUE;
1636 
1637 	if (!wlan_cm_is_vdev_connected(vdev))
1638 		return QDF_STATUS_E_AGAIN;
1639 
1640 	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev) ||
1641 	    !mlo_check_if_all_links_up(vdev))
1642 		return QDF_STATUS_E_FAILURE;
1643 
1644 	t2lm_ctx = &vdev->mlo_dev_ctx->sta_ctx->copied_t2lm_ie_assoc_rsp;
1645 	if (!t2lm_ctx) {
1646 		mlme_err("T2LM ctx is NULL");
1647 		return QDF_STATUS_E_NULL_VALUE;
1648 	}
1649 
1650 	status = wlan_update_t2lm_mapping(vdev, t2lm_ctx, t2lm_ctx->tsf);
1651 	if (QDF_IS_STATUS_ERROR(status)) {
1652 		mlme_err("T2LM IE beacon process failed");
1653 	}
1654 	wlan_connectivity_t2lm_status_event(vdev);
1655 
1656 	return status;
1657 }
1658 #else
1659 static inline QDF_STATUS
cm_update_tid_mapping(struct wlan_objmgr_vdev * vdev)1660 cm_update_tid_mapping(struct wlan_objmgr_vdev *vdev)
1661 {
1662 	return QDF_STATUS_SUCCESS;
1663 }
1664 #endif
1665 static void
cm_install_link_vdev_keys(struct wlan_objmgr_vdev * vdev)1666 cm_install_link_vdev_keys(struct wlan_objmgr_vdev *vdev)
1667 {
1668 	struct wlan_crypto_key *crypto_key;
1669 	struct wlan_crypto_params *crypto_params;
1670 	enum QDF_OPMODE op_mode;
1671 	uint16_t i;
1672 	bool pairwise;
1673 	uint8_t vdev_id, link_id;
1674 	bool key_present = false;
1675 	uint16_t max_key_index = WLAN_CRYPTO_MAXKEYIDX +
1676 				 WLAN_CRYPTO_MAXIGTKKEYIDX +
1677 				 WLAN_CRYPTO_MAXBIGTKKEYIDX;
1678 
1679 	if (!vdev)
1680 		return;
1681 
1682 	vdev_id = wlan_vdev_get_id(vdev);
1683 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
1684 	if (op_mode != QDF_STA_MODE ||
1685 	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
1686 		return;
1687 
1688 	crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
1689 	if (!crypto_params) {
1690 		mlme_err("crypto params is null");
1691 		return;
1692 	}
1693 
1694 	if (!crypto_params->ucastcipherset ||
1695 	    QDF_HAS_PARAM(crypto_params->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE))
1696 		return;
1697 
1698 	link_id = wlan_vdev_get_link_id(vdev);
1699 
1700 	if (!mlo_is_set_key_defered(vdev, link_id) &&
1701 	    !mlo_mgr_is_link_switch_in_progress(vdev)) {
1702 		mlme_debug("keys are not deferred for link_id %d", link_id);
1703 		return;
1704 	}
1705 
1706 	wlan_crypto_aquire_lock();
1707 	for (i = 0; i < max_key_index; i++) {
1708 		crypto_key = wlan_crypto_get_key(vdev, i);
1709 		if (!crypto_key)
1710 			continue;
1711 
1712 		pairwise = crypto_key->key_type ? WLAN_CRYPTO_KEY_TYPE_UNICAST : WLAN_CRYPTO_KEY_TYPE_GROUP;
1713 		mlo_debug("MLO:send keys for vdev_id %d link_id %d , key_idx %d, pairwise %d",
1714 			  vdev_id, link_id, i, pairwise);
1715 		mlme_cm_osif_send_keys(vdev, i, pairwise,
1716 				       crypto_key->cipher_type);
1717 		key_present = true;
1718 	}
1719 	wlan_crypto_release_lock();
1720 
1721 	if (!key_present && mlo_mgr_is_link_switch_in_progress(vdev)) {
1722 		mlme_err("No key found for link_id %d", link_id);
1723 		QDF_BUG(0);
1724 	}
1725 	mlo_defer_set_keys(vdev, link_id, false);
1726 }
1727 
1728 #ifdef WLAN_CHIPSET_STATS
cm_cp_stats_cstats_log_connect_event(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1729 void cm_cp_stats_cstats_log_connect_event(struct wlan_objmgr_vdev *vdev,
1730 					  struct wlan_cm_connect_resp *rsp)
1731 {
1732 	struct vdev_mlme_obj *vdev_mlme;
1733 	struct wlan_channel *des_chan;
1734 	enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
1735 	struct wlan_crypto_params *crypto_params;
1736 	struct cstats_sta_connect_resp stat = {0};
1737 
1738 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
1739 		stat.cmn.hdr.evt_id =
1740 			WLAN_CHIPSET_STATS_STA_CONNECT_SUCCESS_EVENT_ID;
1741 	} else {
1742 		stat.cmn.hdr.evt_id =
1743 			WLAN_CHIPSET_STATS_STA_CONNECT_FAIL_EVENT_ID;
1744 	}
1745 
1746 	wlan_mlme_get_sta_ch_width(vdev, &ch_width);
1747 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
1748 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
1749 	if (!vdev_mlme) {
1750 		mlme_err("vdev component object is NULL");
1751 		return;
1752 	}
1753 
1754 	crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
1755 	if (!crypto_params) {
1756 		mlme_err("crypto params is null");
1757 		return;
1758 	}
1759 
1760 	cm_diag_get_auth_type(&stat.auth_type,
1761 			      crypto_params->authmodeset,
1762 			      crypto_params->key_mgmt,
1763 			      crypto_params->ucastcipherset);
1764 
1765 	stat.cmn.hdr.length = sizeof(struct cstats_sta_connect_resp) -
1766 			      sizeof(struct cstats_hdr);
1767 	stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
1768 	stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
1769 	stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
1770 	stat.cmn.time_tick = qdf_get_log_timestamp();
1771 	stat.freq = rsp->freq;
1772 	stat.chnl_bw = cm_get_diag_ch_width(ch_width);
1773 	stat.dot11mode = cm_diag_dot11_mode_from_phy_mode(des_chan->ch_phymode);
1774 	stat.qos_capability = vdev_mlme->ext_vdev_ptr->connect_info.qos_enabled;
1775 	stat.encryption_type =
1776 			cm_get_diag_enc_type(crypto_params->ucastcipherset);
1777 	stat.result_code = rsp->connect_status;
1778 	stat.ssid_len = rsp->ssid.length;
1779 	qdf_mem_copy(stat.ssid, rsp->ssid.ssid, rsp->ssid.length);
1780 	CSTATS_MAC_COPY(stat.bssid, rsp->bssid.bytes);
1781 
1782 	wlan_cstats_host_stats(sizeof(struct cstats_sta_connect_resp), &stat);
1783 }
1784 #else
1785 static inline void
cm_cp_stats_cstats_log_connect_event(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1786 cm_cp_stats_cstats_log_connect_event(struct wlan_objmgr_vdev *vdev,
1787 				     struct wlan_cm_connect_resp *rsp)
1788 {
1789 }
1790 #endif /* WLAN_CHIPSET_STATS */
1791 
1792 QDF_STATUS
cm_connect_complete_ind(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1793 cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev,
1794 			struct wlan_cm_connect_resp *rsp)
1795 {
1796 	uint8_t vdev_id;
1797 	struct wlan_objmgr_pdev *pdev;
1798 	struct wlan_objmgr_psoc *psoc;
1799 	enum QDF_OPMODE op_mode;
1800 	bool eht_capab = false;
1801 	QDF_STATUS status;
1802 
1803 	if (!vdev || !rsp) {
1804 		mlme_err("vdev or rsp is NULL");
1805 		return QDF_STATUS_E_INVAL;
1806 	}
1807 
1808 	vdev_id = wlan_vdev_get_id(vdev);
1809 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
1810 	pdev = wlan_vdev_get_pdev(vdev);
1811 	if (!pdev) {
1812 		mlme_err(CM_PREFIX_FMT "pdev not found",
1813 			 CM_PREFIX_REF(vdev_id, rsp->cm_id));
1814 		return QDF_STATUS_E_INVAL;
1815 	}
1816 	psoc = wlan_pdev_get_psoc(pdev);
1817 	if (!psoc) {
1818 		mlme_err(CM_PREFIX_FMT "psoc not found",
1819 			 CM_PREFIX_REF(vdev_id, rsp->cm_id));
1820 		return QDF_STATUS_E_INVAL;
1821 	}
1822 
1823 	cm_csr_connect_done_ind(vdev, rsp);
1824 
1825 	cm_cp_stats_cstats_log_connect_event(vdev, rsp);
1826 
1827 	cm_connect_info(vdev, QDF_IS_STATUS_SUCCESS(rsp->connect_status) ?
1828 			true : false, &rsp->bssid, &rsp->ssid,
1829 			rsp->freq);
1830 
1831 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
1832 		if (rsp->cm_id & CM_ID_LSWITCH_BIT)
1833 			ml_nlink_conn_change_notify(
1834 				psoc, vdev_id,
1835 				ml_nlink_link_switch_pre_completion_evt, NULL);
1836 
1837 		if (policy_mgr_ml_link_vdev_need_to_be_disabled(psoc, vdev,
1838 								false))
1839 			policy_mgr_move_vdev_from_connection_to_disabled_tbl(
1840 								psoc, vdev_id);
1841 		else
1842 			policy_mgr_incr_active_session(psoc, op_mode, vdev_id);
1843 		ml_nlink_conn_change_notify(
1844 			psoc, vdev_id,
1845 			ml_nlink_connect_completion_evt, NULL);
1846 		cm_process_connect_complete(psoc, pdev, vdev, rsp);
1847 		cm_install_link_vdev_keys(vdev);
1848 		wlan_tdls_notify_sta_connect(vdev_id,
1849 					     mlme_get_tdls_chan_switch_prohibited(vdev),
1850 					     mlme_get_tdls_prohibited(vdev),
1851 					     vdev);
1852 		wlan_p2p_status_connect(vdev);
1853 		cm_update_tid_mapping(vdev);
1854 		cm_update_associated_ch_info(vdev, true);
1855 
1856 		wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
1857 		if (eht_capab) {
1858 			status = policy_mgr_current_connections_update(
1859 					psoc, vdev_id,
1860 					rsp->freq,
1861 					POLICY_MGR_UPDATE_REASON_STA_CONNECT,
1862 					POLICY_MGR_DEF_REQ_ID);
1863 			if (status == QDF_STATUS_E_FAILURE)
1864 				mlme_debug("Failed to take next action after connect");
1865 		}
1866 	}
1867 
1868 	mlo_roam_connect_complete(vdev);
1869 
1870 	if (op_mode == QDF_STA_MODE &&
1871 		(wlan_vdev_mlme_is_mlo_link_vdev(vdev) ||
1872 	    !wlan_vdev_mlme_is_mlo_vdev(vdev)))
1873 		wlan_cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_INIT,
1874 					  REASON_CONNECT);
1875 
1876 	return QDF_STATUS_SUCCESS;
1877 }
1878 
1879 #ifdef FEATURE_WLAN_ESE
cm_free_tspec_ie(struct cm_vdev_join_rsp * rsp)1880 static void cm_free_tspec_ie(struct cm_vdev_join_rsp *rsp)
1881 {
1882 	qdf_mem_free(rsp->tspec_ie.ptr);
1883 	rsp->tspec_ie.ptr = NULL;
1884 	rsp->tspec_ie.len = 0;
1885 }
1886 
1887 #else
cm_free_tspec_ie(struct cm_vdev_join_rsp * rsp)1888 static void cm_free_tspec_ie(struct cm_vdev_join_rsp *rsp)
1889 {}
1890 #endif
1891 
wlan_cm_free_connect_rsp(struct cm_vdev_join_rsp * rsp)1892 void wlan_cm_free_connect_rsp(struct cm_vdev_join_rsp *rsp)
1893 {
1894 	cm_free_tspec_ie(rsp);
1895 	qdf_mem_free(rsp->ric_resp_ie.ptr);
1896 	cm_free_connect_rsp_ies(&rsp->connect_rsp);
1897 	qdf_mem_zero(rsp, sizeof(*rsp));
1898 	qdf_mem_free(rsp);
1899 }
1900 
cm_is_vdevid_connected(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)1901 bool cm_is_vdevid_connected(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
1902 {
1903 	struct wlan_objmgr_vdev *vdev;
1904 	bool connected;
1905 	enum QDF_OPMODE opmode;
1906 
1907 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
1908 						    WLAN_MLME_CM_ID);
1909 	if (!vdev) {
1910 		mlme_err("vdev %d: vdev not found", vdev_id);
1911 		return false;
1912 	}
1913 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1914 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
1915 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
1916 		return false;
1917 	}
1918 	connected = cm_is_vdev_connected(vdev);
1919 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
1920 
1921 	return connected;
1922 }
1923 
cm_is_vdevid_active(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)1924 bool cm_is_vdevid_active(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
1925 {
1926 	struct wlan_objmgr_vdev *vdev;
1927 	bool active;
1928 	enum QDF_OPMODE opmode;
1929 
1930 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
1931 						    WLAN_MLME_CM_ID);
1932 	if (!vdev) {
1933 		mlme_err("vdev %d: vdev not found", vdev_id);
1934 		return false;
1935 	}
1936 	opmode = wlan_vdev_mlme_get_opmode(vdev);
1937 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
1938 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
1939 		return false;
1940 	}
1941 	active = cm_is_vdev_active(vdev);
1942 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
1943 
1944 	return active;
1945 }
1946 
1947 static
cm_handle_hw_mode_change_resp_cb(struct scheduler_msg * msg)1948 QDF_STATUS cm_handle_hw_mode_change_resp_cb(struct scheduler_msg *msg)
1949 {
1950 	struct cm_vdev_hw_mode_rsp *rsp;
1951 
1952 	if (!msg || !msg->bodyptr)
1953 		return QDF_STATUS_E_FAILURE;
1954 
1955 	rsp = msg->bodyptr;
1956 	wlan_cm_hw_mode_change_resp(rsp->pdev, rsp->vdev_id, rsp->cm_id,
1957 				    rsp->status);
1958 
1959 	qdf_mem_free(rsp);
1960 
1961 	return QDF_STATUS_SUCCESS;
1962 }
1963 
1964 QDF_STATUS
wlan_cm_handle_hw_mode_change_resp(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,wlan_cm_id cm_id,QDF_STATUS status)1965 wlan_cm_handle_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev,
1966 				   uint8_t vdev_id,
1967 				   wlan_cm_id cm_id, QDF_STATUS status)
1968 {
1969 	struct cm_vdev_hw_mode_rsp *rsp;
1970 	struct scheduler_msg rsp_msg = {0};
1971 	QDF_STATUS qdf_status;
1972 
1973 	rsp = qdf_mem_malloc(sizeof(*rsp));
1974 	if (!rsp)
1975 		return QDF_STATUS_E_FAILURE;
1976 
1977 	rsp->pdev = pdev;
1978 	rsp->vdev_id = vdev_id;
1979 	rsp->cm_id = cm_id;
1980 	rsp->status = status;
1981 
1982 	rsp_msg.bodyptr = rsp;
1983 	rsp_msg.callback = cm_handle_hw_mode_change_resp_cb;
1984 
1985 	qdf_status = scheduler_post_message(QDF_MODULE_ID_MLME,
1986 					    QDF_MODULE_ID_TARGET_IF,
1987 					    QDF_MODULE_ID_TARGET_IF, &rsp_msg);
1988 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
1989 		mlme_err(CM_PREFIX_FMT "Failed to post HW mode change rsp",
1990 			 CM_PREFIX_REF(vdev_id, cm_id));
1991 		qdf_mem_free(rsp);
1992 	}
1993 
1994 	return qdf_status;
1995 }
1996