1 /*
2 * Copyright (c) 2018, 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
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**
21 * DOC: target_if_cp_stats.c
22 *
23 * This file provide definition for APIs registered through lmac Tx Ops
24 */
25
26 #include <qdf_mem.h>
27 #include <qdf_status.h>
28 #include <target_if_cp_stats.h>
29 #include <wmi_unified_priv.h>
30 #include <wmi_unified_param.h>
31 #include <target_if.h>
32 #include <wlan_tgt_def_config.h>
33 #include <wmi_unified_api.h>
34 #include <wlan_osif_priv.h>
35 #include <wlan_cp_stats_utils_api.h>
36 #include <wlan_objmgr_peer_obj.h>
37 #ifdef WLAN_FEATURE_MIB_STATS
38 #include <wlan_cp_stats_mc_defs.h>
39 #endif
40 #include "cp_stats/core/src/wlan_cp_stats_defs.h"
41 #include "cdp_txrx_cmn_struct.h"
42 #include "cdp_txrx_ctrl.h"
43 #include "cp_stats/core/src/wlan_cp_stats_comp_handler.h"
44
45 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
46 #ifdef WLAN_SUPPORT_TWT
47 /**
48 * target_if_infra_cp_stats_twt_event_free() - Free event buffer
49 * @ev: pointer to infra cp stats event structure
50 *
51 * Return: None
52 */
53 static
target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event * ev)54 void target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event *ev)
55 {
56 qdf_mem_free(ev->twt_infra_cp_stats);
57 ev->twt_infra_cp_stats = NULL;
58 }
59
60 /**
61 * target_if_infra_cp_stats_twt_event_alloc() - Allocate event buffer for TWT
62 * parameters
63 * @ev: pointer to infra cp stats event structure
64 *
65 * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
66 * failure
67 */
68 static QDF_STATUS
target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event * ev)69 target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event *ev)
70 {
71 ev->twt_infra_cp_stats =
72 qdf_mem_malloc(sizeof(*ev->twt_infra_cp_stats) *
73 INFRA_CP_STATS_MAX_RESP_TWT_DIALOG_ID);
74 if (!ev->twt_infra_cp_stats) {
75 cp_stats_err("mem alloc failed for ev.twt_infra_cp_stats");
76 return QDF_STATUS_E_NOMEM;
77 }
78
79 return QDF_STATUS_SUCCESS;
80 }
81
82 #else
83 static inline
target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event * ev)84 void target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event *ev)
85 {
86 }
87
88 static inline QDF_STATUS
target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event * ev)89 target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event *ev)
90 {
91 return QDF_STATUS_SUCCESS;
92 }
93
94 static inline
target_if_infra_cp_stats_free_stats_event(struct infra_cp_stats_event * ev)95 void target_if_infra_cp_stats_free_stats_event(struct infra_cp_stats_event *ev)
96 {
97 }
98 #endif /* WLAN_SUPPORT_TWT */
99
100 static
target_if_infra_cp_stats_rrm_sta_stats_event_free(struct infra_cp_stats_event * ev)101 void target_if_infra_cp_stats_rrm_sta_stats_event_free(
102 struct infra_cp_stats_event *ev)
103 {
104 qdf_mem_free(ev->sta_stats);
105 ev->sta_stats = NULL;
106 }
107
108 static QDF_STATUS
target_if_infra_cp_stats_rrm_sta_stats_event_alloc(struct infra_cp_stats_event * ev)109 target_if_infra_cp_stats_rrm_sta_stats_event_alloc(
110 struct infra_cp_stats_event *ev)
111 {
112 ev->sta_stats =
113 qdf_mem_malloc(sizeof(*ev->sta_stats));
114 if (!ev->sta_stats) {
115 return QDF_STATUS_E_NOMEM;
116 }
117
118 return QDF_STATUS_SUCCESS;
119 }
120 #ifdef CONFIG_WLAN_BMISS
121
122 /**
123 * target_if_infra_cp_stats_bmiss_event_free() - Free event buffer
124 * @ev: pointer to infra cp stats event structure
125 *
126 * Return: None
127 */
128 static
target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event * ev)129 void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev)
130 {
131 qdf_mem_free(ev->bmiss_infra_cp_stats);
132 ev->bmiss_infra_cp_stats = NULL;
133 }
134
135 /**
136 * target_if_infra_cp_stats_bmiss_event_alloc() - Allocate buffer for bmiss
137 * parameters
138 * @ev: pointer to infra cp stats event structure
139 *
140 * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
141 * failure
142 */
143 static QDF_STATUS
target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event * ev)144 target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event *ev)
145 {
146 ev->bmiss_infra_cp_stats =
147 qdf_mem_malloc(sizeof(*ev->bmiss_infra_cp_stats));
148 if (!ev->bmiss_infra_cp_stats) {
149 cp_stats_err("mem alloc failed for ev.bmiss_infra_cp_stats");
150 return QDF_STATUS_E_NOMEM;
151 }
152
153 return QDF_STATUS_SUCCESS;
154 }
155 #else
156
157 static inline
target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event * ev)158 void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev)
159 {
160 }
161
162 static inline QDF_STATUS
target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event * ev)163 target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event *ev)
164 {
165 return QDF_STATUS_SUCCESS;
166 }
167 #endif /* CONFIG_WLAN_BMISS */
168
169 /**
170 * target_if_infra_cp_stats_event_free() - Free event buffer
171 * @ev: pointer to infra cp stats event structure
172 *
173 * Return : None
174 */
175 static
target_if_infra_cp_stats_event_free(struct infra_cp_stats_event * ev)176 void target_if_infra_cp_stats_event_free(struct infra_cp_stats_event *ev)
177 {
178 target_if_infra_cp_stats_twt_event_free(ev);
179 target_if_infra_cp_stats_bmiss_event_free(ev);
180 target_if_infra_cp_stats_rrm_sta_stats_event_free(ev);
181 }
182
183 /**
184 * target_if_infra_cp_stats_event_alloc() - Allocate buffer for event
185 * parameters
186 * @ev: pointer to infra cp stats event structure
187 *
188 * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
189 * failure
190 */
191 static QDF_STATUS
target_if_infra_cp_stats_event_alloc(struct infra_cp_stats_event * ev)192 target_if_infra_cp_stats_event_alloc(struct infra_cp_stats_event *ev)
193 {
194 QDF_STATUS status;
195
196 status = target_if_infra_cp_stats_twt_event_alloc(ev);
197 if (QDF_IS_STATUS_ERROR(status))
198 return QDF_STATUS_E_NOMEM;
199
200 status = target_if_infra_cp_stats_bmiss_event_alloc(ev);
201 if (QDF_IS_STATUS_ERROR(status))
202 return QDF_STATUS_E_NOMEM;
203
204 status = target_if_infra_cp_stats_rrm_sta_stats_event_alloc(ev);
205 if (QDF_IS_STATUS_ERROR(status))
206 return QDF_STATUS_E_NOMEM;
207
208 return QDF_STATUS_SUCCESS;
209 }
210
211 /**
212 * target_if_extract_infra_cp_stats_event() - Extract data from stats event
213 * @wmi_hdl: WMI Handle
214 * @data: pointer to event data buffer from firmware
215 * @data_len: length of the data buffer
216 * @ev: pointer of output structure to be filled with extracted values
217 *
218 * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
219 * on failure
220 */
221 static QDF_STATUS
target_if_extract_infra_cp_stats_event(struct wmi_unified * wmi_hdl,uint8_t * data,uint32_t data_len,struct infra_cp_stats_event * ev)222 target_if_extract_infra_cp_stats_event(struct wmi_unified *wmi_hdl,
223 uint8_t *data, uint32_t data_len,
224 struct infra_cp_stats_event *ev)
225 {
226 QDF_STATUS status;
227 uint32_t more_flag = 0;
228
229 status = wmi_unified_extract_cp_stats_more_pending(wmi_hdl, data,
230 &more_flag);
231
232 status = wmi_unified_extract_infra_cp_stats(wmi_hdl, data,
233 data_len, ev);
234
235 cp_stats_debug("request_id %d", ev->request_id);
236
237 return QDF_STATUS_SUCCESS;
238 }
239
240 /**
241 * target_if_infra_cp_stats_event_handler() - Handle
242 * wmi_pdev_cp_fwstats_eventid
243 * @scn: opaque scn handle
244 * @data: event buffer received from fw
245 * @datalen: length of event buffer
246 *
247 * Return: 0 for success or non zero error codes for failure
248 */
249 static
target_if_infra_cp_stats_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)250 int target_if_infra_cp_stats_event_handler(ol_scn_t scn, uint8_t *data,
251 uint32_t datalen)
252 {
253 QDF_STATUS status;
254 struct infra_cp_stats_event ev = {0};
255 struct wlan_objmgr_psoc *psoc;
256 struct wmi_unified *wmi_handle;
257 struct wlan_lmac_if_cp_stats_rx_ops *rx_ops;
258
259 cp_stats_debug("Enter");
260
261 if (!scn || !data) {
262 cp_stats_err("scn: 0x%pK, data: 0x%pK", scn, data);
263 return -EINVAL;
264 }
265
266 psoc = target_if_get_psoc_from_scn_hdl(scn);
267 if (!psoc) {
268 cp_stats_err("null psoc");
269 return -EINVAL;
270 }
271
272 rx_ops = target_if_cp_stats_get_rx_ops(psoc);
273 if (!rx_ops || !rx_ops->process_stats_event) {
274 cp_stats_err("callback not registered");
275 return -EINVAL;
276 }
277
278 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
279 if (!wmi_handle) {
280 cp_stats_err("wmi_handle is null");
281 return -EINVAL;
282 }
283 status = target_if_infra_cp_stats_event_alloc(&ev);
284 if (QDF_IS_STATUS_ERROR(status)) {
285 cp_stats_err("Alloc event mem failed");
286 goto end;
287 }
288
289 status = target_if_extract_infra_cp_stats_event(wmi_handle, data,
290 datalen, &ev);
291 if (QDF_IS_STATUS_ERROR(status)) {
292 cp_stats_err("extract event failed");
293 goto end;
294 }
295
296 status = rx_ops->process_infra_stats_event(psoc, &ev);
297
298 end:
299 target_if_infra_cp_stats_event_free(&ev);
300 return qdf_status_to_os_return(status);
301 }
302 #else
303 static
target_if_infra_cp_stats_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)304 int target_if_infra_cp_stats_event_handler(ol_scn_t scn, uint8_t *data,
305 uint32_t datalen)
306 {
307 return 0;
308 }
309 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
310
311 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED)
312 static int
target_if_twt_session_params_event_handler(ol_scn_t scn,uint8_t * evt_buf,uint32_t evt_data_len)313 target_if_twt_session_params_event_handler(ol_scn_t scn,
314 uint8_t *evt_buf,
315 uint32_t evt_data_len)
316 {
317 struct wlan_objmgr_psoc *psoc;
318 struct wlan_objmgr_peer *peer_obj;
319 struct wmi_unified *wmi_hdl;
320 struct twt_session_stats_info twt_params;
321 struct twt_session_stats_event_param params = {0};
322 struct peer_cp_stats *peer_cp_stats;
323 int i;
324 QDF_STATUS status;
325 uint32_t ev;
326 cdp_config_param_type val = {0};
327 ol_txrx_soc_handle soc_txrx_handle;
328 struct wlan_lmac_if_rx_ops *rx_ops;
329
330 TARGET_IF_ENTER();
331
332 if (!scn || !evt_buf) {
333 target_if_err("scn: 0x%pK, evt_buf: 0x%pK", scn, evt_buf);
334 return -EINVAL;
335 }
336
337 psoc = target_if_get_psoc_from_scn_hdl(scn);
338 if (!psoc) {
339 target_if_err("psoc object is null!");
340 return -EINVAL;
341 }
342
343 soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
344 if (!soc_txrx_handle)
345 return -EINVAL;
346
347 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
348 if (!wmi_hdl) {
349 target_if_err("wmi_handle is null!");
350 return -EINVAL;
351 }
352
353 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
354 if (!rx_ops) {
355 target_if_err("No valid twt session stats rx ops");
356 return -EINVAL;
357 }
358
359 status = wmi_extract_twt_session_stats_event(wmi_hdl, evt_buf, ¶ms);
360 if (QDF_IS_STATUS_ERROR(status)) {
361 target_if_err("Could not extract twt session stats event");
362 return qdf_status_to_os_return(status);
363 }
364
365 if (params.num_sessions > WLAN_MAX_TWT_SESSIONS_PER_PEER) {
366 target_if_err("Number of twt sessions exceeded, num:%d max:%d",
367 params.num_sessions, WLAN_MAX_TWT_SESSIONS_PER_PEER);
368 return -EINVAL;
369 }
370
371 for (i = 0; i < params.num_sessions; i++) {
372 status = wmi_extract_twt_session_stats_data(wmi_hdl, evt_buf,
373 ¶ms,
374 &twt_params, i);
375
376 if (QDF_IS_STATUS_ERROR(status)) {
377 target_if_err("Unable to extract twt params for idx %d",
378 i);
379 return -EINVAL;
380 }
381 peer_obj = wlan_objmgr_get_peer_by_mac(psoc,
382 twt_params.peer_mac.bytes,
383 WLAN_CP_STATS_ID);
384 if (!peer_obj) {
385 target_if_err("peer obj not found for "QDF_MAC_ADDR_FMT,
386 QDF_MAC_ADDR_REF(twt_params.peer_mac.bytes));
387 continue;
388 }
389
390 ev = twt_params.event_type;
391 if (ev == HOST_TWT_SESSION_SETUP)
392 val.cdp_peer_param_in_twt = 1;
393 else if (ev == HOST_TWT_SESSION_TEARDOWN)
394 val.cdp_peer_param_in_twt = 0;
395
396 cdp_txrx_set_peer_param(soc_txrx_handle, twt_params.vdev_id,
397 twt_params.peer_mac.bytes,
398 CDP_CONFIG_IN_TWT, val);
399
400 peer_cp_stats = wlan_cp_stats_get_peer_stats_obj(peer_obj);
401 if (!peer_cp_stats) {
402 target_if_err("peer_cp_stats is null");
403 continue;
404 }
405
406 wlan_cp_stats_peer_obj_lock(peer_cp_stats);
407
408 rx_ops->cp_stats_rx_ops.twt_get_session_param_resp(psoc,
409 &twt_params);
410
411 wlan_cp_stats_peer_obj_unlock(peer_cp_stats);
412 wlan_objmgr_peer_release_ref(peer_obj, WLAN_CP_STATS_ID);
413 }
414 return 0;
415 }
416
417 static QDF_STATUS
target_if_cp_stats_register_twt_session_event(struct wmi_unified * wmi_handle)418 target_if_cp_stats_register_twt_session_event(struct wmi_unified *wmi_handle)
419 {
420 QDF_STATUS ret_val;
421
422 ret_val = wmi_unified_register_event_handler(wmi_handle,
423 wmi_twt_session_stats_event_id,
424 target_if_twt_session_params_event_handler,
425 WMI_RX_WORK_CTX);
426
427 return ret_val;
428 }
429
430 static void
target_if_cp_stats_unregister_twt_session_event(struct wmi_unified * wmi_handle)431 target_if_cp_stats_unregister_twt_session_event(struct wmi_unified *wmi_handle)
432 {
433 wmi_unified_unregister_event_handler(wmi_handle,
434 wmi_twt_session_stats_event_id);
435 }
436 #else
437 static QDF_STATUS
target_if_cp_stats_register_twt_session_event(struct wmi_unified * wmi_handle)438 target_if_cp_stats_register_twt_session_event(struct wmi_unified *wmi_handle)
439 {
440 return QDF_STATUS_SUCCESS;
441 }
442
443 static void
target_if_cp_stats_unregister_twt_session_event(struct wmi_unified * wmi_handle)444 target_if_cp_stats_unregister_twt_session_event(struct wmi_unified *wmi_handle)
445 {
446 }
447 #endif /* WLAN_SUPPORT_TWT && WLAN_TWT_CONV_SUPPORTED*/
448
449 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
450 static QDF_STATUS
target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc * psoc,struct wmi_unified * wmi_handle)451 target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc *psoc,
452 struct wmi_unified *wmi_handle)
453 {
454 QDF_STATUS ret_val;
455
456 if (!psoc) {
457 cp_stats_err("PSOC is NULL!");
458 return QDF_STATUS_E_INVAL;
459 }
460
461 if (!wmi_handle) {
462 cp_stats_err("wmi_handle is null");
463 return QDF_STATUS_E_INVAL;
464 }
465
466 ret_val = wmi_unified_register_event_handler(wmi_handle,
467 wmi_pdev_cp_fwstats_eventid,
468 target_if_infra_cp_stats_event_handler,
469 WMI_RX_WORK_CTX);
470 if (QDF_IS_STATUS_ERROR(ret_val)) {
471 cp_stats_err("Failed to register for pdev_cp_fwstats_event");
472 return ret_val;
473 }
474
475 return QDF_STATUS_SUCCESS;
476 }
477 #else
478 static QDF_STATUS
target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc * psoc,struct wmi_unified * wmi_handle)479 target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc *psoc,
480 struct wmi_unified *wmi_handle)
481 {
482 return QDF_STATUS_SUCCESS;
483 }
484 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
485
486 static QDF_STATUS
target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc * psoc)487 target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc)
488 {
489 struct wmi_unified *wmi_handle;
490 QDF_STATUS ret_val;
491
492 if (!psoc) {
493 cp_stats_err("PSOC is NULL!");
494 return QDF_STATUS_E_INVAL;
495 }
496
497 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
498 if (!wmi_handle) {
499 cp_stats_err("wmi_handle is null");
500 return QDF_STATUS_E_INVAL;
501 }
502
503 ret_val = target_if_cp_stats_infra_register_event_handler(psoc,
504 wmi_handle);
505 if (QDF_IS_STATUS_ERROR(ret_val)) {
506 cp_stats_err("Failed to register for pdev_cp_fwstats_event");
507 return ret_val;
508 }
509
510 ret_val = target_if_cp_stats_register_twt_session_event(wmi_handle);
511 if (QDF_IS_STATUS_ERROR(ret_val)) {
512 cp_stats_err("Failed to register twt session stats event");
513 return ret_val;
514 }
515
516 return QDF_STATUS_SUCCESS;
517 }
518
519 static QDF_STATUS
target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc * psoc)520 target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
521 {
522 struct wmi_unified *wmi_handle;
523
524 if (!psoc) {
525 cp_stats_err("PSOC is NULL!");
526 return QDF_STATUS_E_INVAL;
527 }
528
529 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
530 if (!wmi_handle) {
531 cp_stats_err("wmi_handle is null");
532 return QDF_STATUS_E_INVAL;
533 }
534
535 wmi_unified_unregister_event_handler(wmi_handle,
536 wmi_pdev_cp_fwstats_eventid);
537 target_if_cp_stats_unregister_twt_session_event(wmi_handle);
538 return QDF_STATUS_SUCCESS;
539 }
540
541 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
542 /**
543 * target_if_infra_cp_stats_req() - API to send stats request to wmi
544 * @psoc: pointer to psoc object
545 * @req: pointer to object containing stats request parameters
546 *
547 * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
548 */
549 static
target_if_infra_cp_stats_req(struct wlan_objmgr_psoc * psoc,struct infra_cp_stats_cmd_info * req)550 QDF_STATUS target_if_infra_cp_stats_req(struct wlan_objmgr_psoc *psoc,
551 struct infra_cp_stats_cmd_info *req)
552
553 {
554 struct wmi_unified *wmi_handle;
555
556 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
557 if (!wmi_handle) {
558 cp_stats_err("wmi_handle is null.");
559 return QDF_STATUS_E_NULL_VALUE;
560 }
561
562 return wmi_unified_infra_cp_stats_request_send(wmi_handle, req);
563 }
564
target_if_register_infra_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)565 static void target_if_register_infra_cp_stats_txops(
566 struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
567 {
568 tx_ops->send_req_infra_cp_stats = target_if_infra_cp_stats_req;
569 }
570 #else
target_if_register_infra_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)571 static void target_if_register_infra_cp_stats_txops(
572 struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
573 {
574 }
575 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
576
577 #ifdef WLAN_CONFIG_TELEMETRY_AGENT
578 /**
579 * target_if_telemetry_cp_stats_req() - API to send stats request to wmi
580 * @pdev: pointer to pdev object
581 * @req: pointer to object containing stats request parameters
582 *
583 * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
584 */
585 static
target_if_telemetry_cp_stats_req(struct wlan_objmgr_pdev * pdev,struct infra_cp_stats_cmd_info * req)586 QDF_STATUS target_if_telemetry_cp_stats_req(struct wlan_objmgr_pdev *pdev,
587 struct infra_cp_stats_cmd_info *req)
588 {
589 struct wmi_unified *wmi_handle;
590
591 wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
592 if (!wmi_handle) {
593 cp_stats_err("wmi_handle is null.");
594 return QDF_STATUS_E_NULL_VALUE;
595 }
596 return wmi_unified_infra_cp_stats_request_send(wmi_handle, req);
597 }
598
target_if_register_telemetry_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)599 static void target_if_register_telemetry_cp_stats_txops(
600 struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
601 {
602 tx_ops->send_req_telemetry_cp_stats = target_if_telemetry_cp_stats_req;
603 }
604 #else
target_if_register_telemetry_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)605 static void target_if_register_telemetry_cp_stats_txops(
606 struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
607 { }
608 #endif
609 #ifdef WLAN_CHIPSET_STATS
610 QDF_STATUS
target_if_cp_stats_is_service_cstats_enabled(struct wlan_objmgr_psoc * psoc,bool * is_fw_support_cstats)611 target_if_cp_stats_is_service_cstats_enabled(struct wlan_objmgr_psoc *psoc,
612 bool *is_fw_support_cstats)
613 {
614 struct wmi_unified *wmi_handle;
615
616 if (!psoc) {
617 cp_stats_err("psoc is NULL!");
618 return QDF_STATUS_E_INVAL;
619 }
620
621 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
622 if (!wmi_handle) {
623 cp_stats_err("wmi_handle is null");
624 return QDF_STATUS_E_NULL_VALUE;
625 }
626
627 *is_fw_support_cstats =
628 wmi_service_enabled(wmi_handle,
629 wmi_service_chipset_logging_support);
630 return QDF_STATUS_SUCCESS;
631 }
632
633 static QDF_STATUS
target_if_cp_stats_enable_cstats(struct wlan_objmgr_psoc * psoc,uint32_t param_val,uint8_t mac_id)634 target_if_cp_stats_enable_cstats(struct wlan_objmgr_psoc *psoc,
635 uint32_t param_val, uint8_t mac_id)
636 {
637 struct wmi_unified *wmi_handle;
638 struct pdev_params params = {0};
639
640 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
641 if (!wmi_handle) {
642 cp_stats_err("wmi_handle is null");
643 return QDF_STATUS_E_NULL_VALUE;
644 }
645
646 params.param_id = WMI_PDEV_PARAM_ENABLE_CHIPSET_LOGGING;
647 params.param_value = param_val;
648
649 return wmi_unified_pdev_param_send(wmi_handle, ¶ms, mac_id);
650 }
651
652 /**
653 * target_if_register_cstats_enable_txops() - Register cstats enable in txops
654 *
655 * @ops: pointer to wlan_lmac_if_cp_stats_tx_ops
656 *
657 * Return: void
658 */
659 static void
target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops * ops)660 target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops *ops)
661 {
662 ops->send_cstats_enable = target_if_cp_stats_enable_cstats;
663 }
664 #else
665 static void
target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops * ops)666 target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops *ops)
667 {
668 }
669 #endif
670
671 QDF_STATUS
target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)672 target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
673 {
674 struct wlan_lmac_if_cp_stats_tx_ops *cp_stats_tx_ops;
675
676 if (!tx_ops) {
677 cp_stats_err("lmac tx ops is NULL!");
678 return QDF_STATUS_E_INVAL;
679 }
680
681 cp_stats_tx_ops = &tx_ops->cp_stats_tx_ops;
682 if (!cp_stats_tx_ops) {
683 cp_stats_err("lmac tx ops is NULL!");
684 return QDF_STATUS_E_FAILURE;
685 }
686
687 target_if_register_cstats_enable_txops(cp_stats_tx_ops);
688
689 target_if_register_infra_cp_stats_txops(cp_stats_tx_ops);
690 target_if_register_telemetry_cp_stats_txops(cp_stats_tx_ops);
691
692 cp_stats_tx_ops->cp_stats_attach =
693 target_if_cp_stats_register_event_handler;
694 cp_stats_tx_ops->cp_stats_detach =
695 target_if_cp_stats_unregister_event_handler;
696 cp_stats_tx_ops->cp_stats_legacy_attach =
697 target_if_cp_stats_register_legacy_event_handler;
698 cp_stats_tx_ops->cp_stats_legacy_detach =
699 target_if_cp_stats_unregister_legacy_event_handler;
700 return QDF_STATUS_SUCCESS;
701 }
702
703