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 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 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 84 void target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event *ev) 85 { 86 } 87 88 static inline QDF_STATUS 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 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 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 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 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 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 158 void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev) 159 { 160 } 161 162 static inline QDF_STATUS 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 666 target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops *ops) 667 { 668 } 669 #endif 670 671 QDF_STATUS 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