1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-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_logging.c
20  *
21  * Implementation for the connectivity and roam logging api.
22  */
23 #include "wlan_connectivity_logging.h"
24 #include "wlan_cm_api.h"
25 #include "wlan_mlme_main.h"
26 #include "wlan_mlo_mgr_sta.h"
27 #include "wlan_mlme_api.h"
28 #include "cdp_txrx_ctrl.h"
29 #include "wlan_mlo_mgr_peer.h"
30 #include "wlan_scan_api.h"
31 
32 #ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
33 static struct wlan_connectivity_log_buf_data global_cl;
34 
35 static void
wlan_connectivity_logging_register_callbacks(struct wlan_cl_osif_cbks * osif_cbks,void * osif_cb_context)36 wlan_connectivity_logging_register_callbacks(
37 				struct wlan_cl_osif_cbks *osif_cbks,
38 				void *osif_cb_context)
39 {
40 	global_cl.osif_cbks.wlan_connectivity_log_send_to_usr =
41 			osif_cbks->wlan_connectivity_log_send_to_usr;
42 	global_cl.osif_cb_context = osif_cb_context;
43 }
44 
wlan_connectivity_logging_start(struct wlan_objmgr_psoc * psoc,struct wlan_cl_osif_cbks * osif_cbks,void * osif_cb_context)45 void wlan_connectivity_logging_start(struct wlan_objmgr_psoc *psoc,
46 				     struct wlan_cl_osif_cbks *osif_cbks,
47 				     void *osif_cb_context)
48 {
49 	global_cl.head = qdf_mem_valloc(sizeof(*global_cl.head) *
50 					WLAN_MAX_LOG_RECORDS);
51 	if (!global_cl.head) {
52 		QDF_BUG(0);
53 		return;
54 	}
55 
56 	global_cl.psoc = psoc;
57 	global_cl.write_idx = 0;
58 	global_cl.read_idx = 0;
59 
60 	qdf_atomic_init(&global_cl.dropped_msgs);
61 	qdf_spinlock_create(&global_cl.write_ptr_lock);
62 
63 	global_cl.read_ptr = global_cl.head;
64 	global_cl.write_ptr = global_cl.head;
65 	global_cl.max_records = WLAN_MAX_LOG_RECORDS;
66 
67 	wlan_connectivity_logging_register_callbacks(osif_cbks,
68 						     osif_cb_context);
69 	qdf_atomic_set(&global_cl.is_active, 1);
70 }
71 
wlan_connectivity_logging_stop(void)72 void wlan_connectivity_logging_stop(void)
73 {
74 	if (!qdf_atomic_read(&global_cl.is_active))
75 		return;
76 
77 	qdf_spin_lock_bh(&global_cl.write_ptr_lock);
78 
79 	global_cl.psoc = NULL;
80 	global_cl.osif_cb_context = NULL;
81 	global_cl.osif_cbks.wlan_connectivity_log_send_to_usr = NULL;
82 
83 	qdf_atomic_set(&global_cl.is_active, 0);
84 	global_cl.read_ptr = NULL;
85 	global_cl.write_ptr = NULL;
86 	global_cl.read_idx = 0;
87 	global_cl.write_idx = 0;
88 
89 	qdf_mem_vfree(global_cl.head);
90 	global_cl.head = NULL;
91 	qdf_spin_unlock_bh(&global_cl.write_ptr_lock);
92 	qdf_spinlock_destroy(&global_cl.write_ptr_lock);
93 }
94 #endif
95 
96 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \
97 	defined(WLAN_FEATURE_11BE_MLO)
98 static void
wlan_clear_ml_vdev_sae_auth_logs(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)99 wlan_clear_ml_vdev_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
100 				 struct wlan_objmgr_vdev *vdev)
101 {
102 	struct wlan_mlo_dev_context *mlo_dev_ctx;
103 	struct wlan_objmgr_vdev *link_vdev;
104 	struct mlme_legacy_priv *mlme_priv;
105 	uint8_t i, link_vdev_id;
106 
107 	mlo_dev_ctx = vdev->mlo_dev_ctx;
108 	if (!mlo_dev_ctx) {
109 		logging_err_rl("mlo_dev ctx is NULL for vdev:%d",
110 			       wlan_vdev_get_id(vdev));
111 		return;
112 	}
113 
114 	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
115 		if (!mlo_dev_ctx->wlan_vdev_list[i])
116 			continue;
117 
118 		link_vdev_id =
119 			wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]);
120 		link_vdev = mlo_dev_ctx->wlan_vdev_list[i];
121 
122 		mlme_priv = wlan_vdev_mlme_get_ext_hdl(link_vdev);
123 		if (!mlme_priv) {
124 			logging_err_rl("vdev:%d legacy private object is NULL",
125 				       link_vdev_id);
126 			return;
127 		}
128 
129 		logging_debug("vdev:%d clear sae auth logs cache",
130 			      link_vdev_id);
131 		qdf_mem_zero(mlme_priv->auth_log, sizeof(mlme_priv->auth_log));
132 	}
133 }
134 #else
135 static inline void
wlan_clear_ml_vdev_sae_auth_logs(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)136 wlan_clear_ml_vdev_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
137 				 struct wlan_objmgr_vdev *vdev)
138 {}
139 #endif
140 
141 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
wlan_clear_sae_auth_logs_cache(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)142 void wlan_clear_sae_auth_logs_cache(struct wlan_objmgr_psoc *psoc,
143 				    uint8_t vdev_id)
144 {
145 	struct wlan_objmgr_vdev *vdev;
146 	struct mlme_legacy_priv *mlme_priv;
147 
148 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
149 						    WLAN_MLME_OBJMGR_ID);
150 	if (!vdev) {
151 		logging_err_rl("Invalid vdev:%d", vdev_id);
152 		return;
153 	}
154 
155 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
156 		wlan_clear_ml_vdev_sae_auth_logs(psoc, vdev);
157 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
158 		return;
159 	}
160 
161 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
162 	if (!mlme_priv) {
163 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
164 		logging_err_rl("vdev legacy private object is NULL");
165 		return;
166 	}
167 
168 	logging_debug("vdev:%d clear sae auth logs cache", vdev_id);
169 	qdf_mem_zero(mlme_priv->auth_log, sizeof(mlme_priv->auth_log));
170 
171 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
172 }
173 #endif
174 
175 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(CONNECTIVITY_DIAG_EVENT)
wlan_print_cached_sae_auth_logs(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * bssid,uint8_t vdev_id)176 QDF_STATUS wlan_print_cached_sae_auth_logs(struct wlan_objmgr_psoc *psoc,
177 					   struct qdf_mac_addr *bssid,
178 					   uint8_t vdev_id)
179 {
180 	uint8_t i, j;
181 	struct wlan_objmgr_vdev *vdev;
182 	struct mlme_legacy_priv *mlme_priv;
183 
184 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
185 						    WLAN_MLME_OBJMGR_ID);
186 	if (!vdev) {
187 		logging_err_rl("Invalid vdev:%d", vdev_id);
188 		return QDF_STATUS_E_FAILURE;
189 	}
190 
191 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) {
192 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
193 		return QDF_STATUS_E_FAILURE;
194 	}
195 
196 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
197 	if (!mlme_priv) {
198 		logging_err_rl("vdev legacy private object is NULL");
199 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
200 		return QDF_STATUS_E_FAILURE;
201 	}
202 
203 	/*
204 	 * Get the index of matching bssid and queue all the records for
205 	 * that bssid
206 	 */
207 	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
208 		if (!mlme_priv->auth_log[i][0].diag_cmn.ktime_us)
209 			continue;
210 
211 		if (qdf_is_macaddr_equal(bssid,
212 					 (struct qdf_mac_addr *)mlme_priv->auth_log[i][0].diag_cmn.bssid))
213 			break;
214 	}
215 
216 	/*
217 	 * No matching bssid found in cached log records.
218 	 * So return from here.
219 	 */
220 	if (i >= MAX_ROAM_CANDIDATE_AP) {
221 		logging_debug("No cached SAE auth logs");
222 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
223 		return QDF_STATUS_E_FAILURE;
224 	}
225 
226 	for (j = 0; j < WLAN_ROAM_MAX_CACHED_AUTH_FRAMES; j++) {
227 		if (!mlme_priv->auth_log[i][j].diag_cmn.ktime_us)
228 			continue;
229 
230 		WLAN_HOST_DIAG_EVENT_REPORT(&mlme_priv->auth_log[i][j],
231 					    EVENT_WLAN_MGMT);
232 		qdf_mem_zero(&mlme_priv->auth_log[i][j],
233 			     sizeof(struct wlan_diag_packet_info));
234 	}
235 
236 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
237 
238 	return QDF_STATUS_SUCCESS;
239 }
240 
wlan_is_log_record_present_for_bssid(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * bssid,uint8_t vdev_id)241 bool wlan_is_log_record_present_for_bssid(struct wlan_objmgr_psoc *psoc,
242 					  struct qdf_mac_addr *bssid,
243 					  uint8_t vdev_id)
244 {
245 	struct wlan_diag_packet_info *pkt_info;
246 	struct wlan_objmgr_vdev *vdev;
247 	struct mlme_legacy_priv *mlme_priv;
248 	int i;
249 
250 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
251 						    WLAN_MLME_OBJMGR_ID);
252 	if (!vdev) {
253 		logging_err_rl("Invalid vdev:%d", vdev_id);
254 		return false;
255 	}
256 
257 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
258 	if (!mlme_priv) {
259 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
260 		logging_err_rl("vdev legacy private object is NULL");
261 		return false;
262 	}
263 
264 	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
265 		pkt_info = &mlme_priv->auth_log[i][0];
266 		if (!pkt_info->diag_cmn.ktime_us)
267 			continue;
268 
269 		if (qdf_is_macaddr_equal(bssid,
270 					 (struct qdf_mac_addr *)pkt_info->diag_cmn.bssid)) {
271 			wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
272 			return true;
273 		}
274 	}
275 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
276 
277 	return false;
278 }
279 
280 #ifdef WLAN_FEATURE_11BE_MLO
281 bool
wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * bssid,uint8_t * vdev_id)282 wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc *psoc,
283 				       struct qdf_mac_addr *bssid,
284 				       uint8_t *vdev_id)
285 {
286 	struct wlan_objmgr_vdev *vdev;
287 	struct wlan_mlo_dev_context *mlo_dev_ctx;
288 	uint8_t i, link_vdev_id;
289 
290 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, *vdev_id,
291 						    WLAN_MLME_OBJMGR_ID);
292 	if (!vdev) {
293 		logging_err_rl("Invalid vdev:%d", *vdev_id);
294 		return false;
295 	}
296 
297 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
298 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
299 		return wlan_is_log_record_present_for_bssid(psoc, bssid,
300 							    *vdev_id);
301 	}
302 
303 	mlo_dev_ctx = vdev->mlo_dev_ctx;
304 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
305 
306 	if (!mlo_dev_ctx) {
307 		logging_err_rl("mlo_dev ctx is NULL for vdev:%d", *vdev_id);
308 		return wlan_is_log_record_present_for_bssid(psoc, bssid,
309 							    *vdev_id);
310 	}
311 
312 	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
313 		if (!mlo_dev_ctx->wlan_vdev_list[i])
314 			continue;
315 
316 		link_vdev_id = wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]);
317 		if (wlan_is_log_record_present_for_bssid(psoc, bssid,
318 							 link_vdev_id)) {
319 			*vdev_id = link_vdev_id;
320 			return true;
321 		}
322 	}
323 
324 	return false;
325 }
326 #else
327 bool
wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * bssid,uint8_t * vdev_id)328 wlan_is_sae_auth_log_present_for_bssid(struct wlan_objmgr_psoc *psoc,
329 				       struct qdf_mac_addr *bssid,
330 				       uint8_t *vdev_id)
331 {
332 	return wlan_is_log_record_present_for_bssid(psoc, bssid, *vdev_id);
333 }
334 #endif
335 
336 /**
337  * wlan_add_sae_log_record_to_available_slot() - Add a new log record into the
338  * cache for the queue.
339  * @psoc: objmgr psoc object
340  * @vdev: objmgr vdev object
341  * @pkt_info: Log packet record pointer
342  *
343  * Return: QDF_STATUS
344  */
345 static QDF_STATUS
wlan_add_sae_log_record_to_available_slot(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct wlan_diag_packet_info * pkt_info)346 wlan_add_sae_log_record_to_available_slot(struct wlan_objmgr_psoc *psoc,
347 					  struct wlan_objmgr_vdev *vdev,
348 					  struct wlan_diag_packet_info *pkt_info)
349 {
350 	struct mlme_legacy_priv *mlme_priv;
351 	uint8_t i, j;
352 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
353 	bool is_entry_exist =
354 		wlan_is_log_record_present_for_bssid(psoc,
355 						     (struct qdf_mac_addr *)pkt_info->diag_cmn.bssid,
356 						     vdev_id);
357 
358 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
359 	if (!mlme_priv) {
360 		logging_err_rl("vdev:%d legacy private object is NULL",
361 			       vdev_id);
362 		return QDF_STATUS_E_FAILURE;
363 	}
364 
365 	for (i = 0; i < MAX_ROAM_CANDIDATE_AP; i++) {
366 		if (is_entry_exist &&
367 		    mlme_priv->auth_log[i][0].diag_cmn.ktime_us &&
368 		    qdf_is_macaddr_equal((struct qdf_mac_addr *)pkt_info->diag_cmn.bssid,
369 					 (struct qdf_mac_addr *)mlme_priv->auth_log[i][0].diag_cmn.bssid)) {
370 			/*
371 			 * Frames for given bssid already exists store the new
372 			 * frame in corresponding array in empty slot
373 			 */
374 			for (j = 0; j < WLAN_ROAM_MAX_CACHED_AUTH_FRAMES; j++) {
375 				if (mlme_priv->auth_log[i][j].diag_cmn.ktime_us)
376 					continue;
377 
378 				logging_debug("vdev:%d added at [i][j]:[%d][%d]",
379 					      vdev_id, i, j);
380 				mlme_priv->auth_log[i][j] = *pkt_info;
381 				break;
382 			}
383 
384 		} else if (!is_entry_exist &&
385 			   !mlme_priv->auth_log[i][0].diag_cmn.ktime_us) {
386 			/*
387 			 * For given record, there is no existing bssid
388 			 * so add the entry at first available slot
389 			 */
390 			logging_debug("vdev:%d added entry at [i][j]:[%d][%d]",
391 				      vdev_id, i, 0);
392 			mlme_priv->auth_log[i][0] = *pkt_info;
393 			break;
394 		}
395 	}
396 
397 	return QDF_STATUS_SUCCESS;
398 }
399 
400 static void
wlan_cache_connectivity_log(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct wlan_diag_packet_info * pkt_info)401 wlan_cache_connectivity_log(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
402 			    struct wlan_diag_packet_info *pkt_info)
403 {
404 	struct wlan_objmgr_vdev *vdev;
405 
406 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
407 						    WLAN_MLME_OBJMGR_ID);
408 	if (!vdev) {
409 		logging_err_rl("Invalid vdev:%d", vdev_id);
410 		return;
411 	}
412 
413 	wlan_add_sae_log_record_to_available_slot(psoc, vdev, pkt_info);
414 
415 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
416 }
417 #endif
418 
419 #define WLAN_SAE_AUTH_ALGO_NUMBER 3
420 #ifdef CONNECTIVITY_DIAG_EVENT
421 
422 #ifdef WLAN_FEATURE_11BE_MLO
423 void
wlan_connectivity_t2lm_req_resp_event(struct wlan_objmgr_vdev * vdev,uint8_t token,enum wlan_t2lm_resp_frm_type t2lm_status,enum qdf_dp_tx_rx_status tx_status,qdf_freq_t freq,bool is_rx,uint8_t subtype)424 wlan_connectivity_t2lm_req_resp_event(struct wlan_objmgr_vdev *vdev,
425 				      uint8_t token,
426 				      enum wlan_t2lm_resp_frm_type t2lm_status,
427 				      enum qdf_dp_tx_rx_status tx_status,
428 				      qdf_freq_t freq,
429 				      bool is_rx, uint8_t subtype)
430 {
431 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
432 				 struct wlan_diag_mlo_t2lm_req_resp);
433 
434 	wlan_diag_event.diag_cmn.vdev_id = wlan_vdev_get_id(vdev);
435 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
436 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
437 
438 	wlan_diag_event.version = DIAG_MLO_T2LM_REQ_RESP_VERSION;
439 
440 	wlan_diag_event.token = token;
441 	wlan_diag_event.subtype = subtype;
442 
443 	wlan_diag_event.status = t2lm_status;
444 	wlan_diag_event.tx_status = wlan_get_diag_tx_status(tx_status);
445 	wlan_diag_event.is_rx = is_rx;
446 
447 	wlan_diag_event.band = wlan_convert_freq_to_diag_band(freq);
448 
449 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
450 				    EVENT_WLAN_MLO_T2LM_REQ_RESP);
451 }
452 
453 void
wlan_connectivity_mlo_reconfig_event(struct wlan_objmgr_vdev * vdev)454 wlan_connectivity_mlo_reconfig_event(struct wlan_objmgr_vdev *vdev)
455 {
456 	struct mlo_link_info *link_info = NULL;
457 	struct wlan_channel *chan_info = NULL;
458 	uint8_t link_id;
459 
460 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
461 				 struct wlan_diag_mlo_reconfig);
462 
463 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
464 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
465 	wlan_diag_event.version = DIAG_MLO_RECONFIG_VERSION;
466 
467 	link_id = wlan_vdev_get_link_id(vdev);
468 	wlan_diag_event.mlo_cmn_info.link_id = link_id;
469 
470 	if (!vdev->mlo_dev_ctx)
471 		return;
472 
473 	link_info = mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx, link_id);
474 	if (!link_info) {
475 		mlme_err("linl: %d Link info not found", link_id);
476 		return;
477 	}
478 	chan_info = link_info->link_chan_info;
479 	if (!chan_info) {
480 		mlme_err("link: %d Chan info not found", link_id);
481 		return;
482 	}
483 
484 	wlan_diag_event.mlo_cmn_info.band =
485 			wlan_convert_freq_to_diag_band(chan_info->ch_freq);
486 
487 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MLO_RECONFIG);
488 }
489 
490 static QDF_STATUS
wlan_populate_link_addr(struct wlan_objmgr_vdev * vdev,struct wlan_diag_sta_info * wlan_diag_event)491 wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
492 			struct wlan_diag_sta_info *wlan_diag_event)
493 {
494 	uint i = 0;
495 	struct mlo_link_switch_context *link_ctx = vdev->mlo_dev_ctx->link_ctx;
496 	struct wlan_channel *link_chan_info;
497 
498 	if (!link_ctx)
499 		return QDF_STATUS_E_FAILURE;
500 
501 	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
502 		link_chan_info = link_ctx->links_info[i].link_chan_info;
503 
504 		if (wlan_reg_is_24ghz_ch_freq(
505 		    (qdf_freq_t)link_chan_info->ch_freq)) {
506 			qdf_mem_copy(wlan_diag_event->mac_2g,
507 				     link_ctx->links_info[i].link_addr.bytes,
508 				     QDF_MAC_ADDR_SIZE);
509 		} else if (wlan_reg_is_5ghz_ch_freq(
510 			   (qdf_freq_t)link_chan_info->ch_freq)) {
511 			qdf_mem_copy(wlan_diag_event->mac_5g,
512 				     link_ctx->links_info[i].link_addr.bytes,
513 				     QDF_MAC_ADDR_SIZE);
514 		} else if (wlan_reg_is_6ghz_chan_freq(
515 			   link_chan_info->ch_freq)) {
516 			qdf_mem_copy(wlan_diag_event->mac_6g,
517 				     link_ctx->links_info[i].link_addr.bytes,
518 				     QDF_MAC_ADDR_SIZE);
519 		}
520 	}
521 
522 	return QDF_STATUS_SUCCESS;
523 }
524 
525 static uint8_t
wlan_populate_band_bitmap(struct mlo_link_switch_context * link_ctx)526 wlan_populate_band_bitmap(struct mlo_link_switch_context *link_ctx)
527 {
528 	uint8_t i, band_bitmap = 0, band;
529 	struct wlan_channel *link_chan_info;
530 
531 	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
532 		link_chan_info = link_ctx->links_info[i].link_chan_info;
533 
534 		band = wlan_reg_freq_to_band((qdf_freq_t)
535 					     link_chan_info->ch_freq);
536 
537 		band_bitmap |= BIT(band);
538 	}
539 
540 	return band_bitmap;
541 }
542 
543 QDF_STATUS
wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev * vdev,struct wlan_diag_packet_info * data,enum wlan_main_tag tag)544 wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
545 				   struct wlan_diag_packet_info *data,
546 				   enum wlan_main_tag tag)
547 {
548 	struct mlo_link_switch_context *link_ctx;
549 	struct qdf_mac_addr peer_mac, peer_mld_mac;
550 	QDF_STATUS status = QDF_STATUS_SUCCESS;
551 
552 	if (!mlo_is_mld_sta(vdev))
553 		return status;
554 
555 	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
556 		return QDF_STATUS_E_INVAL;
557 
558 	status = wlan_vdev_get_bss_peer_mac(vdev, &peer_mac);
559 	if (QDF_IS_STATUS_ERROR(status)) {
560 		logging_err("vdev: %d bss peer not found",
561 			    wlan_vdev_get_id(vdev));
562 		return status;
563 	}
564 
565 	qdf_mem_copy(data->diag_cmn.bssid, peer_mac.bytes, QDF_MAC_ADDR_SIZE);
566 
567 	status = wlan_vdev_get_bss_peer_mld_mac(vdev, &peer_mld_mac);
568 	if (QDF_IS_STATUS_ERROR(status)) {
569 		logging_err("vdev: %d failed to get mld mac address of peer",
570 			    wlan_vdev_get_id(vdev));
571 		return status;
572 	}
573 
574 	qdf_mem_copy(data->mld_addr, peer_mld_mac.bytes, QDF_MAC_ADDR_SIZE);
575 
576 	if (tag != WLAN_ASSOC_REQ && tag != WLAN_REASSOC_REQ)
577 		return status;
578 
579 	link_ctx = vdev->mlo_dev_ctx->link_ctx;
580 	if (!link_ctx) {
581 		logging_debug("vdev: %d link_ctx not found",
582 			      wlan_vdev_get_id(vdev));
583 		return QDF_STATUS_E_INVAL;
584 	}
585 
586 	data->supported_links = wlan_populate_band_bitmap(link_ctx);
587 
588 	return status;
589 }
590 
591 QDF_STATUS
wlan_populate_roam_mld_log_param(struct wlan_objmgr_vdev * vdev,struct wlan_diag_packet_info * data,enum wlan_main_tag tag)592 wlan_populate_roam_mld_log_param(struct wlan_objmgr_vdev *vdev,
593 				 struct wlan_diag_packet_info *data,
594 				 enum wlan_main_tag tag)
595 {
596 	struct wlan_objmgr_pdev *pdev;
597 	QDF_STATUS status = QDF_STATUS_SUCCESS;
598 
599 	if (!mlo_is_mld_sta(vdev))
600 		return status;
601 
602 	pdev = wlan_vdev_get_pdev(vdev);
603 	if (!pdev)
604 		return QDF_STATUS_E_INVAL;
605 
606 	status = wlan_scan_get_mld_addr_by_link_addr(
607 			pdev, (struct qdf_mac_addr *)data->diag_cmn.bssid,
608 			(struct qdf_mac_addr *)data->mld_addr);
609 	if (QDF_IS_STATUS_ERROR(status))
610 		logging_err_rl("vdev:%d Not able to fetch MLD addr for link addr: " QDF_MAC_ADDR_FMT,
611 			       wlan_vdev_get_id(vdev),
612 			       QDF_MAC_ADDR_REF(data->diag_cmn.bssid));
613 
614 	return status;
615 }
616 
617 enum wlan_diag_wifi_band
wlan_convert_freq_to_diag_band(uint16_t ch_freq)618 wlan_convert_freq_to_diag_band(uint16_t ch_freq)
619 {
620 	enum reg_wifi_band band;
621 
622 	band = wlan_reg_freq_to_band((qdf_freq_t)ch_freq);
623 
624 	switch (band) {
625 	case REG_BAND_2G:
626 		return WLAN_24GHZ_BAND;
627 	case REG_BAND_5G:
628 		return WLAN_5GHZ_BAND;
629 	case REG_BAND_6G:
630 		return WLAN_6GHZ_BAND;
631 	default:
632 		return WLAN_INVALID_BAND;
633 	}
634 }
635 
636 #define REJECTED_LINK_STATUS 1
637 
638 void
wlan_connectivity_mlo_setup_event(struct wlan_objmgr_vdev * vdev)639 wlan_connectivity_mlo_setup_event(struct wlan_objmgr_vdev *vdev)
640 {
641 	uint i = 0;
642 	struct mlo_link_switch_context *link_ctx = NULL;
643 	struct wlan_channel *chan_info;
644 	uint8_t num_links = 0;
645 
646 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
647 				 struct wlan_diag_mlo_setup);
648 
649 	if (!mlo_is_mld_sta(vdev))
650 		return;
651 
652 	qdf_mem_zero(&wlan_diag_event, sizeof(struct wlan_diag_mlo_setup));
653 
654 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
655 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
656 	wlan_diag_event.version = DIAG_MLO_SETUP_VERSION_V2;
657 
658 	if (!vdev->mlo_dev_ctx) {
659 		logging_err("vdev: %d MLO dev ctx not found",
660 			    wlan_vdev_get_id(vdev));
661 		return;
662 	}
663 
664 	link_ctx = vdev->mlo_dev_ctx->link_ctx;
665 	if (!link_ctx) {
666 		logging_err("vdev: %d mlo link ctx not found",
667 			    wlan_vdev_get_id(vdev));
668 		return;
669 	}
670 
671 	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
672 		if (link_ctx->links_info[i].link_id == WLAN_INVALID_LINK_ID)
673 			continue;
674 
675 		chan_info = link_ctx->links_info[i].link_chan_info;
676 		if (!chan_info) {
677 			logging_debug("link %d: chan_info not found",
678 				      link_ctx->links_info[i].link_id);
679 			continue;
680 		}
681 
682 		wlan_diag_event.mlo_cmn_info[num_links].link_id =
683 				link_ctx->links_info[i].link_id;
684 		wlan_diag_event.mlo_cmn_info[num_links].vdev_id =
685 				link_ctx->links_info[i].vdev_id;
686 
687 		qdf_mem_copy(wlan_diag_event.mlo_cmn_info[num_links].link_addr,
688 			     link_ctx->links_info[i].ap_link_addr.bytes,
689 			     QDF_MAC_ADDR_SIZE);
690 
691 		wlan_diag_event.mlo_cmn_info[num_links].band =
692 			wlan_convert_freq_to_diag_band(chan_info->ch_freq);
693 
694 		if (wlan_diag_event.mlo_cmn_info[num_links].band ==
695 							 WLAN_INVALID_BAND)
696 			wlan_diag_event.mlo_cmn_info[i].status =
697 							REJECTED_LINK_STATUS;
698 
699 		num_links++;
700 	}
701 
702 	wlan_diag_event.num_links = num_links;
703 
704 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MLO_SETUP);
705 }
706 
707 #define IS_LINK_SET(link_bitmap, link_id) ((link_bitmap) & (BIT(link_id)))
708 #define DEFAULT_TID_MAP 0xFF
709 
710 static void
wlan_populate_tid_link_id_bitmap(struct wlan_t2lm_info * t2lm,struct mlo_link_info * link_info,struct wlan_diag_mlo_t2lm_status * buf,uint8_t bss_link)711 wlan_populate_tid_link_id_bitmap(struct wlan_t2lm_info *t2lm,
712 				 struct mlo_link_info *link_info,
713 				 struct wlan_diag_mlo_t2lm_status *buf,
714 				 uint8_t bss_link)
715 {
716 	uint8_t link_id;
717 	uint8_t dir, i;
718 	uint16_t freq;
719 
720 	link_id = link_info->link_id;
721 	freq = link_info->link_chan_info->ch_freq;
722 	buf->mlo_cmn_info[bss_link].band =
723 		wlan_convert_freq_to_diag_band(freq);
724 	buf->mlo_cmn_info[bss_link].vdev_id = link_info->vdev_id;
725 
726 	for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) {
727 		if (t2lm[dir].default_link_mapping) {
728 			buf->mlo_cmn_info[bss_link].tid_ul = DEFAULT_TID_MAP;
729 			buf->mlo_cmn_info[bss_link].tid_dl = DEFAULT_TID_MAP;
730 			continue;
731 		}
732 
733 		for (i = 0; i < T2LM_MAX_NUM_TIDS; i++) {
734 			switch (t2lm[dir].direction) {
735 			case WLAN_T2LM_DL_DIRECTION:
736 				if (
737 				IS_LINK_SET(
738 				t2lm[dir].ieee_link_map_tid[i], link_id))
739 					buf->mlo_cmn_info[bss_link].tid_dl |=
740 									BIT(i);
741 				break;
742 			case WLAN_T2LM_UL_DIRECTION:
743 				if (
744 				IS_LINK_SET(
745 				t2lm[dir].ieee_link_map_tid[i], link_id))
746 					buf->mlo_cmn_info[bss_link].tid_ul |=
747 									BIT(i);
748 				break;
749 			case WLAN_T2LM_BIDI_DIRECTION:
750 				if (
751 				IS_LINK_SET(
752 				t2lm[dir].ieee_link_map_tid[i], link_id)) {
753 					buf->mlo_cmn_info[bss_link].tid_dl |=
754 									BIT(i);
755 					buf->mlo_cmn_info[bss_link].tid_ul |=
756 									BIT(i);
757 				}
758 				break;
759 			default:
760 				logging_debug("Invalid direction %d",
761 					      t2lm[dir].direction);
762 				break;
763 			}
764 		}
765 	}
766 }
767 
768 void
wlan_connectivity_t2lm_status_event(struct wlan_objmgr_vdev * vdev)769 wlan_connectivity_t2lm_status_event(struct wlan_objmgr_vdev *vdev)
770 {
771 	uint8_t i = 0, dir, num_links = 0;
772 	QDF_STATUS status;
773 	struct mlo_link_info *link_info;
774 	struct wlan_t2lm_info t2lm[WLAN_T2LM_MAX_DIRECTION] = {0};
775 
776 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
777 				 struct wlan_diag_mlo_t2lm_status);
778 
779 	if (!mlo_is_mld_sta(vdev))
780 		return;
781 
782 	if (!vdev->mlo_dev_ctx) {
783 		logging_err("MLO dev ctx not found");
784 		return;
785 	}
786 	link_info = mlo_mgr_get_ap_link(vdev);
787 	if (!link_info) {
788 		logging_err("link_info invalid");
789 		return;
790 	}
791 
792 	if (mlo_mgr_is_link_switch_in_progress(vdev))
793 		return;
794 
795 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
796 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
797 	wlan_diag_event.version = DIAG_MLO_T2LM_STATUS_VERSION_V2;
798 
799 	for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++)
800 		t2lm[dir].direction = WLAN_T2LM_INVALID_DIRECTION;
801 
802 	status = wlan_get_t2lm_mapping_status(vdev, t2lm);
803 	if (QDF_IS_STATUS_ERROR(status)) {
804 		logging_err("Unable to get t2lm_mapping");
805 		return;
806 	}
807 
808 	for (i = 0;
809 	     i < WLAN_MAX_ML_BSS_LINKS && i < MAX_NUM_LINKS_PER_EVENT; i++) {
810 		if (qdf_is_macaddr_zero(&link_info->ap_link_addr) &&
811 		    link_info->link_id == WLAN_INVALID_LINK_ID)
812 			continue;
813 
814 		wlan_populate_tid_link_id_bitmap(t2lm, link_info,
815 						 &wlan_diag_event, num_links);
816 		link_info++;
817 		num_links++;
818 	}
819 
820 	wlan_diag_event.num_links = num_links;
821 
822 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
823 				    EVENT_WLAN_MLO_T2LM_STATUS);
824 }
825 
826 #else
827 static QDF_STATUS
wlan_populate_link_addr(struct wlan_objmgr_vdev * vdev,struct wlan_diag_sta_info * wlan_diag_event)828 wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
829 			struct wlan_diag_sta_info *wlan_diag_event)
830 {
831 	return QDF_STATUS_SUCCESS;
832 }
833 #endif
834 
835 void
wlan_cdp_set_peer_freq(struct wlan_objmgr_psoc * psoc,uint8_t * peer_mac,uint32_t freq,uint8_t vdev_id)836 wlan_cdp_set_peer_freq(struct wlan_objmgr_psoc *psoc, uint8_t *peer_mac,
837 		       uint32_t freq, uint8_t vdev_id)
838 {
839 	ol_txrx_soc_handle soc_txrx_handle;
840 	cdp_config_param_type val = {0};
841 
842 	soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
843 
844 	val.cdp_peer_param_freq = freq;
845 	cdp_txrx_set_peer_param(soc_txrx_handle, vdev_id, peer_mac,
846 				CDP_CONFIG_PEER_FREQ, val);
847 }
848 
849 void
wlan_connectivity_sta_info_event(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool is_roam)850 wlan_connectivity_sta_info_event(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
851 				 bool is_roam)
852 {
853 	QDF_STATUS status;
854 	struct wlan_objmgr_vdev *vdev = NULL;
855 
856 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_sta_info);
857 
858 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
859 						    WLAN_MLME_OBJMGR_ID);
860 	if (!vdev) {
861 		logging_err_rl("Invalid vdev:%d", vdev_id);
862 		return;
863 	}
864 
865 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE ||
866 	    (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
867 	     (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ||
868 	      wlan_vdev_mlme_is_mlo_link_vdev(vdev))))
869 		goto out;
870 
871 	if (!is_roam && !wlan_cm_is_first_candidate_connect_attempt(vdev))
872 		goto out;
873 
874 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
875 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
876 	wlan_diag_event.diag_cmn.vdev_id = vdev_id;
877 	wlan_diag_event.is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev);
878 
879 	if (wlan_diag_event.is_mlo) {
880 		qdf_mem_copy(wlan_diag_event.diag_cmn.bssid,
881 			     wlan_vdev_mlme_get_mldaddr(vdev),
882 			     QDF_MAC_ADDR_SIZE);
883 		status = wlan_populate_link_addr(vdev, &wlan_diag_event);
884 		if (QDF_IS_STATUS_ERROR(status)) {
885 			logging_err_rl("wlan_populate_link_addr failed");
886 			goto out;
887 		}
888 	} else {
889 		qdf_mem_copy(wlan_diag_event.diag_cmn.bssid,
890 			     wlan_vdev_mlme_get_macaddr(vdev),
891 			     QDF_MAC_ADDR_SIZE);
892 	}
893 
894 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_STA_INFO);
895 out:
896 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
897 }
898 
899 void
wlan_populate_vsie(struct wlan_objmgr_vdev * vdev,struct wlan_diag_packet_info * data,bool is_tx)900 wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
901 		   struct wlan_diag_packet_info *data,
902 		   bool is_tx)
903 {
904 	struct element_info *vsie_info = NULL;
905 
906 	if (is_tx)
907 		vsie_info = mlme_get_self_disconnect_ies(vdev);
908 	else
909 		vsie_info = mlme_get_peer_disconnect_ies(vdev);
910 
911 	if (!vsie_info)
912 		return;
913 
914 	data->vsie_len = vsie_info->len;
915 	if (data->vsie_len > MAX_VSIE_LEN)
916 		data->vsie_len = MAX_VSIE_LEN;
917 
918 	qdf_mem_copy(data->vsie, vsie_info->ptr, data->vsie_len);
919 }
920 
921 void
wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc * psoc,struct wlan_frame_hdr * mac_hdr,uint8_t vdev_id,uint16_t status_code,enum qdf_dp_tx_rx_status tx_status,int8_t peer_rssi,uint8_t auth_algo,uint8_t auth_type,uint8_t auth_seq,uint16_t aid,enum wlan_main_tag tag)922 wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
923 			     struct wlan_frame_hdr *mac_hdr,
924 			     uint8_t vdev_id, uint16_t status_code,
925 			     enum qdf_dp_tx_rx_status tx_status,
926 			     int8_t peer_rssi,
927 			     uint8_t auth_algo, uint8_t auth_type,
928 			     uint8_t auth_seq, uint16_t aid,
929 			     enum wlan_main_tag tag)
930 {
931 	enum QDF_OPMODE opmode;
932 	bool cache_sae_frame_cap, is_initial_connection;
933 	struct wlan_objmgr_vdev *vdev;
934 	QDF_STATUS status;
935 
936 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info);
937 
938 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
939 						    WLAN_MLME_OBJMGR_ID);
940 	if (!vdev) {
941 		logging_debug("Unable to find vdev:%d", vdev_id);
942 		return;
943 	}
944 
945 	opmode = wlan_vdev_mlme_get_opmode(vdev);
946 	if (opmode != QDF_STA_MODE)
947 		goto out;
948 
949 	is_initial_connection = wlan_cm_is_vdev_connecting(vdev);
950 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
951 	    (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ||
952 	     (is_initial_connection &&
953 	      wlan_vdev_mlme_is_mlo_link_vdev(vdev)))) {
954 		logging_debug("vdev:%d is_connection:%d | %s skip mgmt event",
955 			      vdev_id, is_initial_connection,
956 			      wlan_vdev_mlme_is_mlo_link_vdev(vdev) ?
957 			      "link_vdev" : wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ? "link switch in prog" : "");
958 		goto out;
959 	}
960 
961 	qdf_mem_zero(&wlan_diag_event, sizeof(struct wlan_diag_packet_info));
962 
963 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
964 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
965 	wlan_diag_event.diag_cmn.vdev_id = vdev_id;
966 	wlan_diag_event.subtype = (uint8_t)tag;
967 
968 	qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, &mac_hdr->i_addr3[0],
969 		     QDF_MAC_ADDR_SIZE);
970 
971 	if (is_initial_connection) {
972 		status = wlan_populate_mlo_mgmt_event_param(vdev,
973 							    &wlan_diag_event,
974 							    tag);
975 		if (QDF_IS_STATUS_ERROR(status))
976 			goto out;
977 	}
978 
979 	wlan_diag_event.version = DIAG_MGMT_VERSION_V2;
980 	wlan_diag_event.tx_fail_reason = tx_status;
981 	wlan_diag_event.tx_status = wlan_get_diag_tx_status(tx_status);
982 	wlan_diag_event.rssi = peer_rssi;
983 	wlan_diag_event.sn =
984 		(le16toh(*(uint16_t *)mac_hdr->i_seq) >> WLAN_SEQ_SEQ_SHIFT);
985 	wlan_diag_event.status = status_code;
986 	wlan_diag_event.auth_algo = auth_algo;
987 	wlan_diag_event.auth_frame_type = auth_type;
988 	wlan_diag_event.auth_seq_num = auth_seq;
989 	wlan_diag_event.assoc_id = aid;
990 
991 	if (tag == WLAN_DEAUTH_RX || tag == WLAN_DISASSOC_RX)
992 		wlan_populate_vsie(vdev, &wlan_diag_event, false);
993 
994 	if (wlan_diag_event.subtype > WLAN_CONN_DIAG_REASSOC_RESP_EVENT &&
995 	    wlan_diag_event.subtype < WLAN_CONN_DIAG_BMISS_EVENT)
996 		wlan_diag_event.reason = status_code;
997 
998 	wlan_diag_event.is_retry_frame =
999 			(mac_hdr->i_fc[1] & IEEE80211_FC1_RETRY);
1000 
1001 	/*
1002 	 * Cache the SAE auth frames info in vdev mlme private and return in
1003 	 * case of roam preauth
1004 	 */
1005 	cache_sae_frame_cap =
1006 		wlan_psoc_nif_fw_ext2_cap_get(psoc,
1007 					      WLAN_ROAM_STATS_FRAME_INFO_PER_CANDIDATE);
1008 	if (!is_initial_connection &&
1009 	    (tag == WLAN_AUTH_REQ || tag == WLAN_AUTH_RESP) &&
1010 	    auth_algo == WLAN_SAE_AUTH_ALGO_NUMBER && cache_sae_frame_cap) {
1011 		wlan_cache_connectivity_log(psoc, vdev_id, &wlan_diag_event);
1012 		goto out;
1013 	}
1014 
1015 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MGMT);
1016 
1017 	if (tag == WLAN_ASSOC_RSP || tag == WLAN_REASSOC_RSP)
1018 		wlan_connectivity_mlo_setup_event(vdev);
1019 
1020 out:
1021 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
1022 }
1023 
1024 void
wlan_connectivity_connecting_event(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * con_req)1025 wlan_connectivity_connecting_event(struct wlan_objmgr_vdev *vdev,
1026 				   struct wlan_cm_connect_req *con_req)
1027 {
1028 	QDF_STATUS status;
1029 	struct wlan_cm_connect_req req;
1030 
1031 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_connect);
1032 
1033 	if (!wlan_cm_is_first_candidate_connect_attempt(vdev))
1034 		return;
1035 
1036 	/* for candidate not found case*/
1037 	if (con_req) {
1038 		req = *con_req;
1039 		qdf_mem_zero(&req.scan_ie, sizeof(struct element_info));
1040 		qdf_mem_zero(&req.assoc_ie, sizeof(struct element_info));
1041 	} else {
1042 		status = wlan_cm_get_active_connect_req_param(vdev, &req);
1043 		if (QDF_IS_STATUS_ERROR(status)) {
1044 			logging_err("vdev: %d failed to get active cmd request",
1045 				    wlan_vdev_get_id(vdev));
1046 			return;
1047 		}
1048 	}
1049 
1050 	wlan_diag_event.version = DIAG_CONN_VERSION;
1051 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
1052 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
1053 	wlan_diag_event.diag_cmn.vdev_id = wlan_vdev_get_id(vdev);
1054 	wlan_diag_event.subtype = WLAN_CONN_DIAG_CONNECTING_EVENT;
1055 
1056 	wlan_diag_event.ssid_len = req.ssid.length;
1057 
1058 	if (req.ssid.length > WLAN_SSID_MAX_LEN)
1059 		wlan_diag_event.ssid_len = WLAN_SSID_MAX_LEN;
1060 
1061 	qdf_mem_copy(wlan_diag_event.ssid, req.ssid.ssid,
1062 		     wlan_diag_event.ssid_len);
1063 
1064 	if (!qdf_is_macaddr_zero(&req.bssid))
1065 		qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, req.bssid.bytes,
1066 			     QDF_MAC_ADDR_SIZE);
1067 	else if (!qdf_is_macaddr_zero(&req.bssid_hint))
1068 		qdf_mem_copy(wlan_diag_event.bssid_hint, req.bssid_hint.bytes,
1069 			     QDF_MAC_ADDR_SIZE);
1070 
1071 	if (req.chan_freq)
1072 		wlan_diag_event.freq = req.chan_freq;
1073 	else if (req.chan_freq_hint)
1074 		wlan_diag_event.freq_hint = req.chan_freq_hint;
1075 
1076 	wlan_diag_event.pairwise_cipher	= req.crypto.user_cipher_pairwise;
1077 	wlan_diag_event.grp_cipher = req.crypto.user_grp_cipher;
1078 	wlan_diag_event.akm = req.crypto.user_akm_suite;
1079 	wlan_diag_event.auth_algo = req.crypto.user_auth_type;
1080 
1081 	if (req.scan_ie.len) {
1082 		qdf_mem_free(req.scan_ie.ptr);
1083 		qdf_mem_zero(&req.scan_ie, sizeof(struct element_info));
1084 	}
1085 
1086 	if (req.assoc_ie.len) {
1087 		qdf_mem_free(req.assoc_ie.ptr);
1088 		qdf_mem_zero(&req.assoc_ie, sizeof(struct element_info));
1089 	}
1090 
1091 	wlan_diag_event.bt_coex =
1092 		wlan_mlme_get_bt_profile_con(wlan_vdev_get_psoc(vdev));
1093 
1094 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_CONN);
1095 }
1096 
1097 #ifdef WLAN_FEATURE_11BE_MLO
1098 
1099 #define BAND_TO_BITMAP(band) (band - 1)
1100 
1101 static uint8_t
wlan_convert_link_id_to_diag_band(struct qdf_mac_addr * peer_mld,uint16_t link_bitmap)1102 wlan_convert_link_id_to_diag_band(struct qdf_mac_addr *peer_mld,
1103 				  uint16_t link_bitmap)
1104 {
1105 	uint8_t i, band_bitmap = 0, band;
1106 	struct wlan_mlo_dev_context *mldev = NULL;
1107 	struct wlan_mlo_peer_context *mlpeer = NULL;
1108 	struct mlo_link_info *link_info = NULL;
1109 	uint32_t freq;
1110 
1111 	mlpeer = wlan_mlo_get_mlpeer_by_peer_mladdr(peer_mld, &mldev);
1112 	if (!mlpeer) {
1113 		logging_err("ml peer not found");
1114 		return 0;
1115 	}
1116 
1117 	for (i = 0; i < MAX_MLO_LINK_ID; i++) {
1118 		if (IS_LINK_SET(link_bitmap, i)) {
1119 			link_info = mlo_mgr_get_ap_link_by_link_id(mldev, i);
1120 			if (!link_info) {
1121 				logging_err("link: %d info does not exist", i);
1122 				return 0;
1123 			}
1124 
1125 			freq = link_info->link_chan_info->ch_freq;
1126 			band = wlan_convert_freq_to_diag_band(freq);
1127 			if (band == WLAN_INVALID_BAND)
1128 				continue;
1129 
1130 			band_bitmap |= BIT(BAND_TO_BITMAP(band));
1131 		}
1132 	}
1133 
1134 	return band_bitmap;
1135 }
1136 
1137 static uint8_t
wlan_get_supported_link_band_bitmap(struct mlo_link_switch_context * link_ctx)1138 wlan_get_supported_link_band_bitmap(struct mlo_link_switch_context *link_ctx)
1139 {
1140 	uint8_t band_bitmap = 0, i = 0;
1141 	struct mlo_link_info link_info;
1142 	struct wlan_channel *chan_info;
1143 	enum wlan_diag_wifi_band band;
1144 
1145 	for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
1146 		link_info = link_ctx->links_info[i];
1147 
1148 		chan_info = link_info.link_chan_info;
1149 		if (!chan_info)
1150 			continue;
1151 
1152 		band = wlan_convert_freq_to_diag_band(chan_info->ch_freq);
1153 		if (band == WLAN_INVALID_BAND)
1154 			continue;
1155 
1156 		band_bitmap |= BIT(band - 1);
1157 	}
1158 
1159 	return band_bitmap;
1160 }
1161 
wlan_connectivity_mld_link_status_event(struct wlan_objmgr_psoc * psoc,struct mlo_link_switch_params * src)1162 void wlan_connectivity_mld_link_status_event(struct wlan_objmgr_psoc *psoc,
1163 					     struct mlo_link_switch_params *src)
1164 {
1165 	struct wlan_mlo_peer_context *ml_peer = NULL;
1166 	struct wlan_mlo_dev_context *mld_ctx = NULL;
1167 
1168 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
1169 				 struct wlan_diag_mlo_link_status);
1170 
1171 	qdf_mem_zero(&wlan_diag_event,
1172 		     sizeof(struct wlan_diag_mlo_link_status));
1173 
1174 	ml_peer = wlan_mlo_get_mlpeer_by_peer_mladdr(&src->mld_addr, &mld_ctx);
1175 
1176 	if (!mld_ctx) {
1177 		logging_err("mlo dev ctx for mld_mac: "
1178 			    QDF_MAC_ADDR_FMT
1179 			    " not found",
1180 			    QDF_MAC_ADDR_REF(src->mld_addr.bytes));
1181 		return;
1182 	}
1183 
1184 	wlan_diag_event.diag_cmn.timestamp_us = qdf_get_time_of_the_day_us();
1185 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
1186 	wlan_diag_event.version = DIAG_MLO_LINK_STATUS_VERSION_2;
1187 
1188 	wlan_diag_event.active_link =
1189 		wlan_convert_link_id_to_diag_band(&src->mld_addr,
1190 						  src->active_link_bitmap);
1191 	if (!wlan_diag_event.active_link)
1192 		return;
1193 	wlan_diag_event.prev_active_link =
1194 		wlan_convert_link_id_to_diag_band(&src->mld_addr,
1195 						  src->prev_link_bitmap);
1196 	if (!wlan_diag_event.prev_active_link)
1197 		return;
1198 
1199 	if (!mld_ctx->link_ctx) {
1200 		logging_err("link ctx for mld_mac: "
1201 			    QDF_MAC_ADDR_FMT
1202 			    " not found",
1203 			    QDF_MAC_ADDR_REF(src->mld_addr.bytes));
1204 		return;
1205 	}
1206 
1207 	wlan_diag_event.associated_links =
1208 			wlan_get_supported_link_band_bitmap(mld_ctx->link_ctx);
1209 
1210 	if (!wlan_diag_event.associated_links)
1211 		return;
1212 
1213 	wlan_diag_event.reason = src->reason_code;
1214 	/*
1215 	 * FW timestamp received from FW in milliseconds and to be sent to
1216 	 * userspace in microseconds
1217 	 */
1218 	wlan_diag_event.diag_cmn.fw_timestamp = src->fw_timestamp * 1000;
1219 
1220 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
1221 				    EVENT_WLAN_MLO_LINK_STATUS);
1222 }
1223 #endif
1224 #endif
1225