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