1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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 #include "target_if.h" 21 #include "wlan_lmac_if_def.h" 22 #include "target_if_direct_buf_rx_main.h" 23 #include <target_if_direct_buf_rx_api.h> 24 #include "hal_api.h" 25 #include <service_ready_util.h> 26 #include <init_deinit_lmac.h> 27 28 /** 29 * struct module_name : Module name information structure 30 * @module_name_str : Module name subscribing to DBR 31 */ 32 struct module_name { 33 unsigned char module_name_str[QDF_MAX_NAME_SIZE]; 34 }; 35 36 static const struct module_name g_dbr_module_name[DBR_MODULE_MAX] = { 37 [DBR_MODULE_SPECTRAL] = {"SPECTRAL"}, 38 [DBR_MODULE_CFR] = {"CFR"}, 39 }; 40 41 static uint8_t get_num_dbr_modules_per_pdev(struct wlan_objmgr_pdev *pdev) 42 { 43 struct wlan_objmgr_psoc *psoc; 44 struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; 45 uint8_t num_dbr_ring_caps, cap_idx, pdev_id, num_modules; 46 struct target_psoc_info *tgt_psoc_info; 47 48 psoc = wlan_pdev_get_psoc(pdev); 49 50 if (!psoc) { 51 direct_buf_rx_err("psoc is null"); 52 return 0; 53 } 54 55 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 56 if (!tgt_psoc_info) { 57 direct_buf_rx_err("target_psoc_info is null"); 58 return 0; 59 } 60 num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); 61 dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); 62 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 63 num_modules = 0; 64 65 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 66 if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) 67 num_modules++; 68 } 69 70 return num_modules; 71 } 72 73 static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev, 74 struct direct_buf_rx_module_param *mod_param) 75 { 76 struct wlan_objmgr_psoc *psoc; 77 struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; 78 uint8_t cap_idx; 79 bool cap_found = false; 80 enum DBR_MODULE mod_id = mod_param->mod_id; 81 uint32_t num_dbr_ring_caps, pdev_id; 82 struct target_psoc_info *tgt_psoc_info; 83 84 psoc = wlan_pdev_get_psoc(pdev); 85 86 if (!psoc) { 87 direct_buf_rx_err("psoc is null"); 88 return QDF_STATUS_E_INVAL; 89 } 90 91 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 92 if (!tgt_psoc_info) { 93 direct_buf_rx_err("target_psoc_info is null"); 94 return QDF_STATUS_E_INVAL; 95 } 96 97 num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); 98 dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); 99 pdev_id = mod_param->pdev_id; 100 101 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 102 if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) { 103 if (dbr_ring_cap[cap_idx].mod_id == mod_id) { 104 mod_param->dbr_ring_cap->ring_elems_min = 105 dbr_ring_cap[cap_idx].ring_elems_min; 106 mod_param->dbr_ring_cap->min_buf_size = 107 dbr_ring_cap[cap_idx].min_buf_size; 108 mod_param->dbr_ring_cap->min_buf_align = 109 dbr_ring_cap[cap_idx].min_buf_align; 110 cap_found = true; 111 } 112 } 113 } 114 115 if (!cap_found) { 116 direct_buf_rx_err("No cap found for module %d in pdev %d", 117 mod_id, pdev_id); 118 return QDF_STATUS_E_FAILURE; 119 } 120 121 return QDF_STATUS_SUCCESS; 122 } 123 #ifdef DIRECT_BUF_RX_DEBUG 124 static inline struct direct_buf_rx_module_debug * 125 target_if_get_dbr_mod_debug_from_dbr_pdev_obj( 126 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 127 uint8_t mod_id) 128 { 129 if (!dbr_pdev_obj) { 130 direct_buf_rx_err("dir buf rx object is null"); 131 return NULL; 132 } 133 134 if (mod_id >= DBR_MODULE_MAX) { 135 direct_buf_rx_err("Invalid module id"); 136 return NULL; 137 } 138 139 if (!dbr_pdev_obj->dbr_mod_debug) { 140 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_debug is NULL"); 141 return NULL; 142 } 143 144 if (mod_id >= dbr_pdev_obj->num_modules) { 145 direct_buf_rx_err("Module %d not supported in target", mod_id); 146 return NULL; 147 } 148 return &dbr_pdev_obj->dbr_mod_debug[mod_id]; 149 } 150 151 static inline struct direct_buf_rx_module_debug * 152 target_if_get_dbr_mod_debug_from_pdev( 153 struct wlan_objmgr_pdev *pdev, 154 uint8_t mod_id) 155 { 156 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 157 158 if (!pdev) { 159 direct_buf_rx_err("pdev is null"); 160 return NULL; 161 } 162 163 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 164 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 165 166 return target_if_get_dbr_mod_debug_from_dbr_pdev_obj( 167 dbr_pdev_obj, mod_id); 168 } 169 #endif 170 171 #ifdef DIRECT_BUF_RX_DEBUG 172 #define RING_DEBUG_EVENT_NAME_SIZE 12 173 static const unsigned char 174 g_dbr_ring_debug_event[DBR_RING_DEBUG_EVENT_MAX][RING_DEBUG_EVENT_NAME_SIZE] = { 175 [DBR_RING_DEBUG_EVENT_RX] = "Rx", 176 [DBR_RING_DEBUG_EVENT_REPLENISH_RING] = "Replenish", 177 }; 178 179 /** 180 * target_if_dbr_print_ring_debug_entries() - Print ring debug entries 181 * @print: The print adapter function 182 * @print_priv: The private data to be consumed by @print 183 * @dbr_pdev_obj: Pdev object of the DBR module 184 * @mod_id: Module ID 185 * 186 * Print ring debug entries of the ring identified by @dbr_pdev_obj and @mod_id 187 * using the given print adapter function 188 * 189 * Return: QDF_STATUS of operation 190 */ 191 static QDF_STATUS target_if_dbr_print_ring_debug_entries( 192 qdf_abstract_print print, void *print_priv, 193 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 194 uint8_t mod_id, uint8_t srng_id) 195 { 196 struct direct_buf_rx_module_debug *mod_debug; 197 struct direct_buf_rx_ring_debug *ring_debug; 198 int idx; 199 200 mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, 201 mod_id); 202 if (!mod_debug) 203 return QDF_STATUS_E_INVAL; 204 205 mod_debug = &dbr_pdev_obj->dbr_mod_debug[mod_id]; 206 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 207 208 if (ring_debug->entries) { 209 print(print_priv, "Current debug entry is %d", 210 ring_debug->ring_debug_idx); 211 print(print_priv, "---------------------------------------------------------"); 212 print(print_priv, "| Number | Head Idx | Tail Idx | Timestamp | event |"); 213 print(print_priv, "---------------------------------------------------------"); 214 for (idx = 0; idx < ring_debug->num_ring_debug_entries; ++idx) { 215 print(print_priv, "|%8u|%10u|%10u|%11llu|%12s|", idx, 216 ring_debug->entries[idx].head_idx, 217 ring_debug->entries[idx].tail_idx, 218 ring_debug->entries[idx].timestamp, 219 g_dbr_ring_debug_event[ 220 ring_debug->entries[idx].event]); 221 } 222 print(print_priv, "---------------------------------------------------------"); 223 } 224 225 return QDF_STATUS_SUCCESS; 226 } 227 228 /** 229 * target_if_dbr_qdf_err_printer() - QDF error level printer for DBR module 230 * @print_priv: The private data 231 * @fmt: Format string 232 * 233 * This function should be passed in place of the 'print' argument to 234 * target_if_dbr_print_ring_debug_entries function for the logs that should be 235 * printed via QDF trace 236 * 237 * Return: QDF_STATUS of operation 238 */ 239 static int target_if_dbr_qdf_err_printer(void *priv, const char *fmt, ...) 240 { 241 va_list args; 242 243 va_start(args, fmt); 244 QDF_VTRACE(QDF_MODULE_ID_DIRECT_BUF_RX, QDF_TRACE_LEVEL_ERROR, 245 (char *)fmt, args); 246 va_end(args); 247 248 return 0; 249 } 250 251 static inline void target_if_direct_buf_rx_free_mod_debug( 252 struct direct_buf_rx_pdev_obj *dbr_pdev_obj) 253 { 254 if (!dbr_pdev_obj) { 255 direct_buf_rx_err("dir buf rx object is null"); 256 return; 257 } 258 /* Free the debug data structures of all modules */ 259 if (dbr_pdev_obj->dbr_mod_debug) { 260 qdf_mem_free(dbr_pdev_obj->dbr_mod_debug); 261 dbr_pdev_obj->dbr_mod_debug = NULL; 262 } 263 } 264 265 static inline QDF_STATUS target_if_direct_buf_rx_alloc_mod_debug( 266 struct direct_buf_rx_pdev_obj *dbr_pdev_obj) 267 { 268 if (!dbr_pdev_obj) { 269 direct_buf_rx_err("dir buf rx object is null"); 270 return QDF_STATUS_E_FAILURE; 271 } 272 /* Allocate the debug data structure for each module */ 273 dbr_pdev_obj->dbr_mod_debug = qdf_mem_malloc( 274 dbr_pdev_obj->num_modules * 275 sizeof(struct direct_buf_rx_module_debug)); 276 277 if (!dbr_pdev_obj->dbr_mod_debug) 278 return QDF_STATUS_E_NOMEM; 279 280 return QDF_STATUS_SUCCESS; 281 } 282 #else 283 static inline QDF_STATUS target_if_direct_buf_rx_alloc_mod_debug( 284 struct direct_buf_rx_pdev_obj *dbr_pdev_obj) 285 { 286 return QDF_STATUS_SUCCESS; 287 } 288 289 static inline void target_if_direct_buf_rx_free_mod_debug( 290 struct direct_buf_rx_pdev_obj *dbr_pdev_obj) 291 { 292 } 293 #endif 294 295 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG) 296 static inline void target_if_direct_buf_pdev_debugfs_init( 297 struct wlan_objmgr_pdev *pdev) 298 { 299 char dir_name[32]; 300 struct wlan_objmgr_psoc *psoc; 301 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 302 303 if (!pdev) { 304 direct_buf_rx_err("pdev is null"); 305 return; 306 } 307 308 psoc = wlan_pdev_get_psoc(pdev); 309 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 310 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 311 312 if (!dbr_pdev_obj) { 313 direct_buf_rx_err("dir buf rx object is null"); 314 return; 315 } 316 317 qdf_snprintf(dir_name, sizeof(dir_name), "SOC%u_PDEV%u", 318 wlan_psoc_get_id(psoc), 319 wlan_objmgr_pdev_get_pdev_id(pdev)); 320 321 /* Create debugfs entry for this radio */ 322 dbr_pdev_obj->debugfs_entry = qdf_debugfs_create_dir( 323 dir_name, dbr_debugfs_entry); 324 325 if (!dbr_pdev_obj->debugfs_entry) 326 direct_buf_rx_err("error while creating direct_buf debugfs dir"); 327 } 328 329 static inline void target_if_direct_buf_pdev_debugfs_deinit( 330 struct direct_buf_rx_pdev_obj *dbr_pdev_obj) 331 { 332 if (!dbr_pdev_obj) { 333 direct_buf_rx_err("dir buf rx object is null"); 334 return; 335 } 336 /* Remove the debugfs entry of the radio */ 337 if (dbr_pdev_obj->debugfs_entry) { 338 qdf_debugfs_remove_dir_recursive(dbr_pdev_obj->debugfs_entry); 339 dbr_pdev_obj->debugfs_entry = NULL; 340 } 341 } 342 #else 343 static inline void target_if_direct_buf_pdev_debugfs_init( 344 struct wlan_objmgr_pdev *pdev) 345 { 346 } 347 348 static inline void target_if_direct_buf_pdev_debugfs_deinit( 349 struct direct_buf_rx_pdev_obj *dbr_pdev_obj) 350 { 351 } 352 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */ 353 354 QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( 355 struct wlan_objmgr_pdev *pdev, void *data) 356 { 357 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 358 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 359 struct wlan_objmgr_psoc *psoc; 360 uint8_t num_modules; 361 QDF_STATUS status; 362 363 direct_buf_rx_enter(); 364 365 if (!pdev) { 366 direct_buf_rx_err("pdev context passed is null"); 367 return QDF_STATUS_E_INVAL; 368 } 369 370 psoc = wlan_pdev_get_psoc(pdev); 371 372 if (!psoc) { 373 direct_buf_rx_err("psoc is null"); 374 return QDF_STATUS_E_INVAL; 375 } 376 377 dbr_psoc_obj = 378 wlan_objmgr_psoc_get_comp_private_obj(psoc, 379 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 380 381 if (!dbr_psoc_obj) { 382 direct_buf_rx_err("dir buf rx psoc object is null"); 383 return QDF_STATUS_E_FAILURE; 384 } 385 386 dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj)); 387 388 if (!dbr_pdev_obj) 389 return QDF_STATUS_E_NOMEM; 390 391 status = wlan_objmgr_pdev_component_obj_attach(pdev, 392 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 393 dbr_pdev_obj, QDF_STATUS_SUCCESS); 394 395 if (status != QDF_STATUS_SUCCESS) { 396 direct_buf_rx_err("Failed to attach dir buf rx component %d", 397 status); 398 qdf_mem_free(dbr_pdev_obj); 399 return status; 400 } 401 402 dbr_psoc_obj->dbr_pdev_obj[wlan_objmgr_pdev_get_pdev_id(pdev)] = 403 dbr_pdev_obj; 404 405 num_modules = get_num_dbr_modules_per_pdev(pdev); 406 direct_buf_rx_debug("Number of modules = %d pdev %d DBR pdev obj %pK", 407 num_modules, wlan_objmgr_pdev_get_pdev_id(pdev), 408 dbr_pdev_obj); 409 dbr_pdev_obj->num_modules = num_modules; 410 411 if (!dbr_pdev_obj->num_modules) { 412 direct_buf_rx_info("Number of modules = %d", num_modules); 413 return QDF_STATUS_SUCCESS; 414 } 415 416 direct_buf_rx_debug("sring number = %d", DBR_SRNG_NUM); 417 dbr_pdev_obj->dbr_mod_param = qdf_mem_malloc(num_modules * 418 DBR_SRNG_NUM * 419 sizeof(struct direct_buf_rx_module_param)); 420 421 if (!dbr_pdev_obj->dbr_mod_param) { 422 direct_buf_rx_err("alloc dbr mod param fail"); 423 goto dbr_mod_param_fail; 424 } 425 426 if (target_if_direct_buf_rx_alloc_mod_debug(dbr_pdev_obj) != 427 QDF_STATUS_SUCCESS) 428 goto dbr_mod_debug_fail; 429 430 target_if_direct_buf_pdev_debugfs_init(pdev); 431 432 return QDF_STATUS_SUCCESS; 433 434 dbr_mod_debug_fail: 435 qdf_mem_free(dbr_pdev_obj->dbr_mod_param); 436 437 dbr_mod_param_fail: 438 wlan_objmgr_pdev_component_obj_detach( 439 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 440 dbr_pdev_obj); 441 qdf_mem_free(dbr_pdev_obj); 442 443 return QDF_STATUS_E_NOMEM; 444 } 445 446 QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler( 447 struct wlan_objmgr_pdev *pdev, void *data) 448 { 449 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 450 QDF_STATUS status; 451 uint8_t num_modules, mod_idx, srng_id; 452 453 if (!pdev) { 454 direct_buf_rx_err("pdev context passed is null"); 455 return QDF_STATUS_E_INVAL; 456 } 457 458 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 459 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 460 461 if (!dbr_pdev_obj) { 462 direct_buf_rx_err("dir buf rx object is null"); 463 return QDF_STATUS_E_FAILURE; 464 } 465 466 num_modules = dbr_pdev_obj->num_modules; 467 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 468 /* 469 * If the module didn't stop the ring debug by this time, 470 * it will result in memory leak of its ring debug entries. 471 * So, stop the ring debug 472 */ 473 target_if_dbr_stop_ring_debug(pdev, mod_idx); 474 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) 475 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 476 mod_idx, srng_id); 477 } 478 479 target_if_direct_buf_pdev_debugfs_deinit(dbr_pdev_obj); 480 target_if_direct_buf_rx_free_mod_debug(dbr_pdev_obj); 481 qdf_mem_free(dbr_pdev_obj->dbr_mod_param); 482 dbr_pdev_obj->dbr_mod_param = NULL; 483 484 status = wlan_objmgr_pdev_component_obj_detach(pdev, 485 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 486 dbr_pdev_obj); 487 488 if (status != QDF_STATUS_SUCCESS) { 489 direct_buf_rx_err("failed to detach dir buf rx component %d", 490 status); 491 } 492 493 qdf_mem_free(dbr_pdev_obj); 494 495 return status; 496 } 497 498 #if defined(DBR_HOLD_LARGE_MEM) && defined(CNSS_MEM_PRE_ALLOC) 499 /** 500 * struct direct_buf_rx_large_mem - large memory for DBR 501 * @node: large memory node 502 * @size: Size of the memory 503 * @vaddr_unaligned: unaligned base address of the memory 504 * @offset: offset between unaligned vaddr and aligned vaddr 505 * @align: Base address alignment 506 */ 507 struct direct_buf_rx_large_mem { 508 qdf_list_node_t node; 509 uint32_t size; 510 void *vaddr_unaligned; 511 uint8_t offset; 512 uint32_t align; 513 }; 514 515 /* check if the actual buffer_size/base_address_alignment match the request */ 516 #define DBR_MEM_NODE_MATCH(_actual_align, _actual_size, _req_align, _req_size) \ 517 ((_actual_align) == (_req_align) && \ 518 ((_actual_size) == (_req_size) || \ 519 (_actual_size) == ((_req_size) + (_req_align) - 1))) 520 521 /* 522 * Memory with a size(in bytes) equal or larger than this threshold will be 523 * hold during the entire PSOC lifetime. 524 * MUST equal or larger than the allocation threshold in cnss_prealloc module. 525 */ 526 #define TARGET_IF_DBR_HOLD_MEM_THRESHOLD (8 * 1024) 527 528 /** 529 * target_if_dbr_init_mem_list() - init the large memory list for DBR 530 * @dbr_psoc_obj: pointer to direct buffer rx module psoc obj 531 * 532 * Return: None 533 */ 534 static void 535 target_if_dbr_init_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj) 536 { 537 int i; 538 539 qdf_spinlock_create(&dbr_psoc_obj->mem_list_lock); 540 qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock); 541 for (i = 0; i < QDF_ARRAY_SIZE(dbr_psoc_obj->mem_list); i++) 542 qdf_list_create(&dbr_psoc_obj->mem_list[i], 0); 543 544 qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock); 545 } 546 547 /** 548 * target_if_dbr_deinit_mem_list() - deinit the large memory list for DBR 549 * @dbr_psoc_obj: pointer to direct buffer rx module psoc obj 550 * 551 * Return: None 552 */ 553 static void 554 target_if_dbr_deinit_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj) 555 { 556 struct direct_buf_rx_large_mem *cur, *next; 557 qdf_list_t *mem_list; 558 int i; 559 560 qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock); 561 for (i = 0; i < QDF_ARRAY_SIZE(dbr_psoc_obj->mem_list); i++) { 562 mem_list = &dbr_psoc_obj->mem_list[i]; 563 qdf_list_for_each_del(mem_list, cur, next, node) { 564 qdf_list_remove_node(mem_list, &cur->node); 565 qdf_mem_free(cur->vaddr_unaligned); 566 } 567 568 qdf_list_destroy(mem_list); 569 } 570 571 qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock); 572 qdf_spinlock_destroy(&dbr_psoc_obj->mem_list_lock); 573 } 574 575 /** 576 * target_if_dbr_mem_add() - allocate a new element for large memory list 577 * @dbr_psoc_obj: pointer to direct buffer rx module psoc obj 578 * @pdev_id: PDEV id 579 * @size: Size of the memory to be assigned to the new element 580 * @vaddr_unaligned: unaligned base address of the memory 581 * @offset: offset between unaligned vaddr and aligned vaddr 582 * @align: Base address alignment 583 * 584 * Return: None 585 */ 586 static void 587 target_if_dbr_mem_add(struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 588 uint8_t pdev_id, uint32_t size, void *vaddr_unaligned, 589 uint8_t offset, uint32_t align) 590 { 591 struct direct_buf_rx_large_mem *new_node; 592 uint32_t list_size; 593 594 new_node = vaddr_unaligned; 595 qdf_mem_zero(new_node, sizeof(*new_node)); 596 new_node->size = size; 597 new_node->vaddr_unaligned = vaddr_unaligned; 598 new_node->offset = offset; 599 new_node->align = align; 600 601 qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock); 602 qdf_list_insert_back(&dbr_psoc_obj->mem_list[pdev_id], 603 &new_node->node); 604 list_size = qdf_list_size(&dbr_psoc_obj->mem_list[pdev_id]); 605 qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock); 606 } 607 608 /** 609 * target_if_dbr_mem_get() - get aligned memory 610 * @pdev: pointer to pdev object 611 * @size: Size to be allocated 612 * @offset: offset between unaligned vaddr and aligned vaddr 613 * @align: Base address alignment 614 * @mod_id: DBR module id (enum DBR_MODULE) 615 * 616 * If size to be allocated is equal or smaller than the threshold, this 617 * function will allocate the aligned memory dynamically; 618 * If NOT, it will search the saved memory list, return the one which meet the 619 * requirement, otherwise, allocate the aligned memory dynamically. 620 * 621 * Return: 622 * Unaligned base address of the memory on succeed, NULL otherwise. 623 */ 624 static void * 625 target_if_dbr_mem_get(struct wlan_objmgr_pdev *pdev, uint32_t *size, 626 uint8_t *offset, uint32_t align, uint32_t mod_id) 627 { 628 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 629 struct wlan_objmgr_psoc *psoc; 630 struct direct_buf_rx_large_mem *cur, *next; 631 void *vaddr_unaligned = NULL, *vaddr_aligned; 632 dma_addr_t paddr_aligned, paddr_unaligned; 633 QDF_STATUS status; 634 qdf_list_t *mem_list; 635 uint8_t pdev_id; 636 637 if (*size < TARGET_IF_DBR_HOLD_MEM_THRESHOLD) { 638 vaddr_aligned = qdf_aligned_malloc(size, &vaddr_unaligned, 639 &paddr_unaligned, 640 &paddr_aligned, align); 641 if (!vaddr_aligned) 642 return NULL; 643 644 *offset = vaddr_aligned - vaddr_unaligned; 645 646 return vaddr_unaligned; 647 } 648 649 if (!pdev) { 650 direct_buf_rx_err("pdev context passed is null"); 651 return vaddr_unaligned; 652 } 653 654 psoc = wlan_pdev_get_psoc(pdev); 655 656 if (!psoc) { 657 direct_buf_rx_err("psoc is null"); 658 return vaddr_unaligned; 659 } 660 661 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 662 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 663 664 if (!dbr_psoc_obj) { 665 direct_buf_rx_err("dir buf rx psoc object is null"); 666 return vaddr_unaligned; 667 } 668 669 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 670 qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock); 671 mem_list = &dbr_psoc_obj->mem_list[pdev_id]; 672 qdf_list_for_each_del(mem_list, cur, next, node) { 673 if (DBR_MEM_NODE_MATCH(cur->align, cur->size, align, *size)) { 674 status = qdf_list_remove_node(mem_list, &cur->node); 675 if (QDF_IS_STATUS_ERROR(status)) { 676 direct_buf_rx_err("failed to remove node: %d", 677 status); 678 break; 679 } 680 681 *offset = cur->offset; 682 *size = cur->size; 683 vaddr_unaligned = cur->vaddr_unaligned; 684 break; 685 } 686 } 687 qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock); 688 689 if (vaddr_unaligned) { 690 qdf_mem_zero(vaddr_unaligned, *size); 691 return vaddr_unaligned; 692 } 693 694 vaddr_aligned = 695 qdf_aligned_malloc(size, &vaddr_unaligned, &paddr_unaligned, 696 &paddr_aligned, align); 697 if (!vaddr_aligned) 698 return NULL; 699 700 *offset = vaddr_aligned - vaddr_unaligned; 701 return vaddr_unaligned; 702 } 703 704 /** 705 * target_if_dbr_mem_put() - put aligned memory 706 * @pdev: pointer to pdev object 707 * @size: size of the memory to be put 708 * @vaddr_unaligned: unaligned base address of the memory 709 * @offset: offset between unaligned vaddr and aligned vaddr 710 * @align: Base address alignment 711 * @mod_id: DBR module id (enum DBR_MODULE) 712 * 713 * If size to be allocated is equal or smaller than the threshold, this 714 * function will free the memory directly; 715 * If NOT, it will search the saved memory list, mark the one which meet the 716 * requirement as NOT in use; and if no element is found, free the memory. 717 * 718 * Return: None 719 */ 720 static void 721 target_if_dbr_mem_put(struct wlan_objmgr_pdev *pdev, uint32_t size, 722 void *vaddr_unaligned, uint8_t offset, 723 uint32_t align, uint32_t mod_id) 724 { 725 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 726 struct wlan_objmgr_psoc *psoc; 727 728 if (!vaddr_unaligned) 729 return; 730 731 if (size < TARGET_IF_DBR_HOLD_MEM_THRESHOLD) { 732 qdf_mem_free(vaddr_unaligned); 733 return; 734 } 735 736 if (!pdev) { 737 direct_buf_rx_err("pdev context passed is null"); 738 return; 739 } 740 741 psoc = wlan_pdev_get_psoc(pdev); 742 if (!psoc) { 743 direct_buf_rx_err("psoc is null"); 744 return; 745 } 746 747 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 748 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 749 if (!dbr_psoc_obj) { 750 direct_buf_rx_err("dir buf rx psoc object is null"); 751 return; 752 } 753 754 target_if_dbr_mem_add(dbr_psoc_obj, wlan_objmgr_pdev_get_pdev_id(pdev), 755 size, vaddr_unaligned, offset, align); 756 } 757 #else 758 static inline void 759 target_if_dbr_init_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj) 760 { 761 } 762 763 static inline void 764 target_if_dbr_deinit_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj) 765 { 766 } 767 768 static void * 769 target_if_dbr_mem_get(struct wlan_objmgr_pdev *pdev, uint32_t *size, 770 uint8_t *offset, uint32_t align, uint32_t mod_id) 771 { 772 void *vaddr_unaligned = NULL, *vaddr_aligned; 773 dma_addr_t paddr_aligned, paddr_unaligned; 774 775 vaddr_aligned = qdf_aligned_malloc(size, &vaddr_unaligned, 776 &paddr_unaligned, &paddr_aligned, 777 align); 778 if (!vaddr_aligned) 779 return NULL; 780 781 *offset = vaddr_aligned - vaddr_unaligned; 782 return vaddr_unaligned; 783 } 784 785 static inline void 786 target_if_dbr_mem_put(struct wlan_objmgr_pdev *pdev, uint32_t size, 787 void *vaddr_unaligned, uint8_t offset, 788 uint32_t align, uint32_t mod_id) 789 { 790 qdf_mem_free(vaddr_unaligned); 791 } 792 #endif /* DBR_HOLD_LARGE_MEM */ 793 794 QDF_STATUS target_if_direct_buf_rx_psoc_create_handler( 795 struct wlan_objmgr_psoc *psoc, void *data) 796 { 797 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 798 QDF_STATUS status; 799 800 direct_buf_rx_enter(); 801 802 if (!psoc) { 803 direct_buf_rx_err("psoc context passed is null"); 804 return QDF_STATUS_E_INVAL; 805 } 806 807 dbr_psoc_obj = qdf_mem_malloc(sizeof(*dbr_psoc_obj)); 808 809 if (!dbr_psoc_obj) 810 return QDF_STATUS_E_NOMEM; 811 812 direct_buf_rx_debug("Dbr psoc obj %pK", dbr_psoc_obj); 813 814 target_if_dbr_init_mem_list(dbr_psoc_obj); 815 816 status = wlan_objmgr_psoc_component_obj_attach(psoc, 817 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_psoc_obj, 818 QDF_STATUS_SUCCESS); 819 820 if (status != QDF_STATUS_SUCCESS) { 821 direct_buf_rx_err("Failed to attach dir buf rx component %d", 822 status); 823 goto attach_error; 824 } 825 826 dbr_psoc_obj->handler_ctx = WMI_RX_UMAC_CTX; 827 828 return status; 829 830 attach_error: 831 qdf_mem_free(dbr_psoc_obj); 832 833 return status; 834 } 835 836 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler( 837 struct wlan_objmgr_psoc *psoc, void *data) 838 { 839 QDF_STATUS status; 840 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 841 842 direct_buf_rx_enter(); 843 844 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 845 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 846 847 if (!dbr_psoc_obj) { 848 direct_buf_rx_err("dir buf rx psoc obj is null"); 849 return QDF_STATUS_E_FAILURE; 850 } 851 852 target_if_dbr_deinit_mem_list(dbr_psoc_obj); 853 status = wlan_objmgr_psoc_component_obj_detach(psoc, 854 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 855 dbr_psoc_obj); 856 857 if (status != QDF_STATUS_SUCCESS) { 858 direct_buf_rx_err("failed to detach dir buf rx component %d", 859 status); 860 } 861 862 qdf_mem_free(dbr_psoc_obj); 863 864 return status; 865 } 866 867 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG) 868 /** 869 * target_if_dbr_debugfs_show_ring_debug() - Function to display ring debug 870 * entries in debugfs 871 * @file: qdf debugfs file handler 872 * @arg: pointer to DBR debugfs private object 873 * 874 * Return: QDF_STATUS of operation 875 */ 876 static QDF_STATUS target_if_dbr_debugfs_show_ring_debug( 877 qdf_debugfs_file_t file, void *arg) 878 { 879 struct dbr_debugfs_priv *priv = arg; 880 881 return target_if_dbr_print_ring_debug_entries(qdf_debugfs_printer, 882 file, priv->dbr_pdev_obj, 883 priv->mod_id, 884 priv->srng_id); 885 } 886 887 /** 888 * target_if_dbr_mod_debugfs_init() - Init debugfs for a given module 889 * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module 890 * @mod_id: Module ID corresponding to this ring 891 * 892 * Return: QDF_STATUS of operation 893 */ 894 static QDF_STATUS target_if_dbr_mod_debugfs_init( 895 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 896 enum DBR_MODULE mod_id) 897 { 898 struct direct_buf_rx_module_debug *mod_debug; 899 900 mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, 901 mod_id); 902 903 if (!mod_debug) 904 return QDF_STATUS_E_INVAL; 905 906 if (mod_debug->debugfs_entry) { 907 direct_buf_rx_err("debugfs mod entry was already created for %s module", 908 g_dbr_module_name[mod_id].module_name_str); 909 return QDF_STATUS_SUCCESS; 910 } 911 912 mod_debug->debugfs_entry = 913 qdf_debugfs_create_dir(g_dbr_module_name[mod_id].module_name_str, 914 dbr_pdev_obj->debugfs_entry); 915 916 if (!mod_debug->debugfs_entry) { 917 direct_buf_rx_err("error while creating direct_buf debugfs entry for %s module", 918 g_dbr_module_name[mod_id].module_name_str); 919 return QDF_STATUS_E_FAILURE; 920 } 921 922 return QDF_STATUS_SUCCESS; 923 } 924 925 /** 926 * target_if_dbr_ring_debugfs_init() - Init debugfs for a given ring 927 * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module 928 * @mod_id: Module ID corresponding to this ring 929 * @srng_id: srng ID corresponding to this ring 930 * 931 * Return: QDF_STATUS of operation 932 */ 933 static QDF_STATUS target_if_dbr_ring_debugfs_init( 934 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 935 enum DBR_MODULE mod_id, uint8_t srng_id) 936 { 937 struct direct_buf_rx_module_debug *mod_debug; 938 struct direct_buf_rx_ring_debug *ring_debug; 939 struct dbr_debugfs_priv *priv; 940 char debug_file_name[32]; 941 942 mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, 943 mod_id); 944 945 if (!mod_debug) 946 return QDF_STATUS_E_INVAL; 947 948 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 949 950 if (!mod_debug->debugfs_entry) { 951 direct_buf_rx_err("error mod_debug->debugfs_entry not created"); 952 return QDF_STATUS_E_FAILURE; 953 } 954 955 if (ring_debug->debugfs_entry) { 956 direct_buf_rx_err("debugfs file for %d ring under %s module already created", 957 srng_id, 958 g_dbr_module_name[mod_id].module_name_str); 959 return QDF_STATUS_SUCCESS; 960 } 961 962 qdf_snprintf(debug_file_name, sizeof(debug_file_name), 963 "ring_%d", srng_id); 964 965 // Allocate debugfs ops 966 ring_debug->debugfs_fops = 967 qdf_mem_malloc(sizeof(*ring_debug->debugfs_fops)); 968 if (!ring_debug->debugfs_fops) { 969 direct_buf_rx_err("error in allocating debugfs ops"); 970 return QDF_STATUS_E_NOMEM; 971 } 972 973 // Allocate private data 974 priv = qdf_mem_malloc(sizeof(*priv)); 975 if (!priv) { 976 direct_buf_rx_err("error in creating debugfs private data"); 977 goto priv_alloc_fail; 978 } 979 priv->dbr_pdev_obj = dbr_pdev_obj; 980 priv->mod_id = mod_id; 981 priv->srng_id = srng_id; 982 983 /* Fill in the debugfs ops for this ring. 984 * When the output time comes, the 'show' function will be 985 * called with 'priv' as an argument. 986 */ 987 ring_debug->debugfs_fops->show = target_if_dbr_debugfs_show_ring_debug; 988 ring_debug->debugfs_fops->priv = priv; 989 990 ring_debug->debugfs_entry = 991 qdf_debugfs_create_file_simplified( 992 debug_file_name, 993 (QDF_FILE_USR_READ | QDF_FILE_GRP_READ | 994 QDF_FILE_OTH_READ), 995 mod_debug->debugfs_entry, 996 ring_debug->debugfs_fops); 997 998 if (!ring_debug->debugfs_entry) { 999 direct_buf_rx_err("error while creating direct_buf debugfs file for %d ring under %s module", 1000 srng_id, 1001 g_dbr_module_name[mod_id].module_name_str); 1002 goto file_creation_fail; 1003 } 1004 1005 return QDF_STATUS_SUCCESS; 1006 1007 file_creation_fail: 1008 qdf_mem_free(ring_debug->debugfs_fops->priv); 1009 1010 priv_alloc_fail: 1011 qdf_mem_free(ring_debug->debugfs_fops); 1012 ring_debug->debugfs_fops = NULL; 1013 return QDF_STATUS_E_NOMEM; 1014 } 1015 1016 /** 1017 * target_if_dbr_mod_debugfs_deinit() - De-init debugfs for a given module 1018 * @mod_debug: Pointer to direct_buf_rx_module_debug structure 1019 * 1020 * Return: void 1021 */ 1022 static void target_if_dbr_mod_debugfs_deinit( 1023 struct direct_buf_rx_module_debug *mod_debug) 1024 { 1025 if (!mod_debug) { 1026 direct_buf_rx_err("mod_debug is null"); 1027 return; 1028 } 1029 1030 if (mod_debug->debugfs_entry) { 1031 qdf_debugfs_remove_file(mod_debug->debugfs_entry); 1032 mod_debug->debugfs_entry = NULL; 1033 } 1034 } 1035 1036 /** 1037 * target_if_dbr_ring_debugfs_deinit() - De-init debugfs for a given ring 1038 * @ring_debug: Pointer to direct_buf_rx_ring_debug structure 1039 * 1040 * Return: void 1041 */ 1042 static void target_if_dbr_ring_debugfs_deinit( 1043 struct direct_buf_rx_ring_debug *ring_debug) 1044 { 1045 if (!ring_debug) { 1046 direct_buf_rx_err("ring_debug is null"); 1047 return; 1048 } 1049 1050 if (ring_debug->debugfs_entry) { 1051 qdf_debugfs_remove_file(ring_debug->debugfs_entry); 1052 ring_debug->debugfs_entry = NULL; 1053 } 1054 1055 // Free the private data and debugfs ops of this ring 1056 if (ring_debug->debugfs_fops) { 1057 qdf_mem_free(ring_debug->debugfs_fops->priv); 1058 qdf_mem_free(ring_debug->debugfs_fops); 1059 ring_debug->debugfs_fops = NULL; 1060 } 1061 } 1062 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */ 1063 1064 #ifdef DIRECT_BUF_RX_DEBUG 1065 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, 1066 uint8_t mod_id) 1067 { 1068 struct direct_buf_rx_module_debug *mod_debug; 1069 struct direct_buf_rx_ring_debug *ring_debug; 1070 uint8_t srng_id; 1071 1072 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1073 if (!mod_debug) 1074 return QDF_STATUS_E_INVAL; 1075 1076 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1077 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 1078 if (!ring_debug->entries) { 1079 direct_buf_rx_debug("DBR ring debug for module %d srng %d was already disabled", 1080 mod_id, srng_id); 1081 continue; 1082 } 1083 /* De-init debugsfs for this ring */ 1084 target_if_dbr_ring_debugfs_deinit(ring_debug); 1085 qdf_mem_free(ring_debug->entries); 1086 ring_debug->entries = NULL; 1087 ring_debug->ring_debug_idx = 0; 1088 ring_debug->num_ring_debug_entries = 0; 1089 direct_buf_rx_info("DBR ring debug for module %d srng %d is now stopped", 1090 mod_id, srng_id); 1091 } 1092 target_if_dbr_mod_debugfs_deinit(mod_debug); 1093 1094 return QDF_STATUS_SUCCESS; 1095 } 1096 1097 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, 1098 uint8_t mod_id, 1099 uint32_t num_ring_debug_entries) 1100 { 1101 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1102 struct direct_buf_rx_module_debug *mod_debug; 1103 struct direct_buf_rx_ring_debug *ring_debug; 1104 uint8_t srng_id; 1105 1106 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1107 1108 if (!mod_debug) 1109 return QDF_STATUS_E_INVAL; 1110 1111 if (num_ring_debug_entries > DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES) { 1112 direct_buf_rx_err("Requested number of ring debug entries(%d) exceed the maximum entries allowed(%d)", 1113 num_ring_debug_entries, 1114 DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES); 1115 1116 return QDF_STATUS_E_FAILURE; 1117 } 1118 1119 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 1120 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1121 1122 target_if_dbr_mod_debugfs_init(dbr_pdev_obj, mod_id); 1123 1124 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1125 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 1126 1127 if (ring_debug->entries) { 1128 direct_buf_rx_err("DBR ring debug for module %d srng %d was already enabled", 1129 mod_id, srng_id); 1130 continue; 1131 } 1132 1133 ring_debug->entries = qdf_mem_malloc( 1134 num_ring_debug_entries * 1135 sizeof(*ring_debug->entries)); 1136 1137 if (!ring_debug->entries) 1138 return QDF_STATUS_E_NOMEM; 1139 1140 ring_debug->ring_debug_idx = 0; 1141 ring_debug->num_ring_debug_entries = num_ring_debug_entries; 1142 /* Init debugsfs for this ring */ 1143 target_if_dbr_ring_debugfs_init( 1144 dbr_pdev_obj, 1145 mod_id, srng_id); 1146 direct_buf_rx_info("DBR ring debug for module %d srng %d is now started", 1147 mod_id, srng_id); 1148 } 1149 return QDF_STATUS_SUCCESS; 1150 } 1151 1152 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, 1153 uint8_t mod_id, uint32_t value) 1154 { 1155 struct direct_buf_rx_module_debug *mod_debug; 1156 1157 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1158 1159 if (!mod_debug) 1160 return QDF_STATUS_E_INVAL; 1161 1162 mod_debug->poisoning_enabled = true; 1163 mod_debug->poison_value = value; /* Save the poison value */ 1164 1165 direct_buf_rx_debug("DBR buffer poisoning for module %d is now started", 1166 mod_id); 1167 return QDF_STATUS_SUCCESS; 1168 } 1169 1170 QDF_STATUS target_if_dbr_stop_buffer_poisoning( 1171 struct wlan_objmgr_pdev *pdev, 1172 uint8_t mod_id) 1173 { 1174 struct direct_buf_rx_module_debug *mod_debug; 1175 1176 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1177 1178 if (!mod_debug) 1179 return QDF_STATUS_E_INVAL; 1180 1181 mod_debug->poisoning_enabled = false; 1182 mod_debug->poison_value = 0; 1183 1184 direct_buf_rx_debug("DBR buffer poisoning for module %d is now stopped", 1185 mod_id); 1186 return QDF_STATUS_SUCCESS; 1187 } 1188 1189 /** 1190 * target_if_dbr_fill_buffer_u32() - Fill buffer with an unsigned 32-bit value 1191 * @buffer: pointer to the buffer 1192 * @num_bytes: Size of the destination buffer in bytes 1193 * @value: Unsigned 32-bit value to be copied 1194 * 1195 * Return : void 1196 */ 1197 static void 1198 target_if_dbr_fill_buffer_u32(uint8_t *buffer, uint32_t num_bytes, 1199 uint32_t value) 1200 { 1201 uint32_t *bufp; 1202 uint32_t idx; 1203 uint32_t size = (num_bytes >> 2); 1204 1205 if (!buffer) { 1206 direct_buf_rx_err("buffer empty"); 1207 return; 1208 } 1209 1210 bufp = (uint32_t *)buffer; 1211 1212 for (idx = 0; idx < size; ++idx) { 1213 *bufp = value; 1214 ++bufp; 1215 } 1216 } 1217 1218 /** 1219 * target_if_dbr_debug_poison_buffer() - Poison a given DBR buffer 1220 * @pdev: pointer to pdev object 1221 * @mod_id: Module ID of the owner of the buffer 1222 * @aligned_vaddr: Virtual address(aligned) of the buffer 1223 * @size: Size of the buffer 1224 * 1225 * Value with which the buffers will be poisoned would have been saved 1226 * while starting the buffer poisoning for the module, use that value. 1227 * 1228 * Return : QDF status of operation 1229 */ 1230 static QDF_STATUS target_if_dbr_debug_poison_buffer( 1231 struct wlan_objmgr_pdev *pdev, 1232 uint32_t mod_id, void *aligned_vaddr, uint32_t size) 1233 { 1234 struct direct_buf_rx_module_debug *mod_debug; 1235 1236 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1237 1238 if (!mod_debug) 1239 return QDF_STATUS_E_INVAL; 1240 1241 if (mod_debug->poisoning_enabled) { 1242 target_if_dbr_fill_buffer_u32(aligned_vaddr, size, 1243 mod_debug->poison_value); 1244 } 1245 1246 return QDF_STATUS_SUCCESS; 1247 } 1248 1249 static inline void target_if_dbr_qdf_show_ring_debug( 1250 struct wlan_objmgr_pdev *pdev, 1251 uint8_t mod_id, uint8_t srng_id) 1252 { 1253 struct direct_buf_rx_pdev_obj *dbr_pdev_obj = 1254 wlan_objmgr_pdev_get_comp_private_obj( 1255 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1256 1257 target_if_dbr_print_ring_debug_entries( 1258 target_if_dbr_qdf_err_printer, 1259 NULL, dbr_pdev_obj, 1260 mod_id, srng_id); 1261 } 1262 #else 1263 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, 1264 uint8_t mod_id) 1265 { 1266 return QDF_STATUS_SUCCESS; 1267 } 1268 1269 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, 1270 uint8_t mod_id, 1271 uint32_t num_ring_debug_entries) 1272 { 1273 return QDF_STATUS_SUCCESS; 1274 } 1275 1276 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, 1277 uint8_t mod_id, uint32_t value) 1278 { 1279 return QDF_STATUS_SUCCESS; 1280 } 1281 1282 QDF_STATUS target_if_dbr_stop_buffer_poisoning( 1283 struct wlan_objmgr_pdev *pdev, 1284 uint8_t mod_id) 1285 { 1286 return QDF_STATUS_SUCCESS; 1287 } 1288 1289 static QDF_STATUS target_if_dbr_debug_poison_buffer( 1290 struct wlan_objmgr_pdev *pdev, 1291 uint32_t mod_id, void *aligned_vaddr, uint32_t size) 1292 { 1293 return QDF_STATUS_SUCCESS; 1294 } 1295 1296 static inline void target_if_dbr_qdf_show_ring_debug( 1297 struct wlan_objmgr_pdev *pdev, 1298 uint8_t mod_id, uint8_t srng_id) 1299 { 1300 } 1301 #endif /* DIRECT_BUF_RX_DEBUG */ 1302 1303 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, 1304 struct direct_buf_rx_module_param *mod_param, 1305 void *aligned_vaddr, uint32_t cookie) 1306 { 1307 uint32_t *ring_entry; 1308 uint32_t dw_lo, dw_hi = 0, map_status; 1309 void *hal_soc, *srng; 1310 qdf_dma_addr_t paddr; 1311 struct wlan_objmgr_psoc *psoc; 1312 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1313 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1314 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1315 struct direct_buf_rx_buf_info *dbr_buf_pool; 1316 1317 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1318 dbr_ring_cap = mod_param->dbr_ring_cap; 1319 dbr_buf_pool = mod_param->dbr_buf_pool; 1320 1321 psoc = wlan_pdev_get_psoc(pdev); 1322 1323 if (!psoc) { 1324 direct_buf_rx_err("psoc is null"); 1325 return QDF_STATUS_E_FAILURE; 1326 } 1327 1328 if (cookie >= mod_param->dbr_ring_cfg->num_ptr) { 1329 direct_buf_rx_err("invalid cookie %d", cookie); 1330 return QDF_STATUS_E_INVAL; 1331 } 1332 1333 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1334 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1335 1336 if (!dbr_psoc_obj) { 1337 direct_buf_rx_err("dir buf rx psoc object is null"); 1338 return QDF_STATUS_E_FAILURE; 1339 } 1340 1341 hal_soc = dbr_psoc_obj->hal_soc; 1342 srng = dbr_ring_cfg->srng; 1343 if (!aligned_vaddr) { 1344 direct_buf_rx_err("aligned vaddr is null"); 1345 return QDF_STATUS_SUCCESS; 1346 } 1347 1348 target_if_dbr_debug_poison_buffer( 1349 pdev, mod_param->mod_id, aligned_vaddr, 1350 dbr_ring_cap->min_buf_size); 1351 1352 map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev, 1353 aligned_vaddr, 1354 QDF_DMA_FROM_DEVICE, 1355 dbr_ring_cap->min_buf_size, 1356 &paddr); 1357 if (map_status) { 1358 direct_buf_rx_err("mem map failed status = %d", map_status); 1359 return QDF_STATUS_E_FAILURE; 1360 } 1361 1362 QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align)); 1363 dbr_buf_pool[cookie].paddr = paddr; 1364 1365 hal_le_srng_access_start_in_cpu_order(hal_soc, srng); 1366 ring_entry = hal_srng_src_get_next(hal_soc, srng); 1367 1368 if (!ring_entry) { 1369 target_if_dbr_qdf_show_ring_debug(pdev, mod_param->mod_id, 1370 mod_param->srng_id); 1371 QDF_BUG(0); 1372 } 1373 1374 dw_lo = (uint64_t)paddr & 0xFFFFFFFF; 1375 WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32); 1376 WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie); 1377 *ring_entry = qdf_cpu_to_le32(dw_lo); 1378 ring_entry++; 1379 *ring_entry = qdf_cpu_to_le32(dw_hi); 1380 hal_le_srng_access_end_in_cpu_order(hal_soc, srng); 1381 1382 return QDF_STATUS_SUCCESS; 1383 } 1384 1385 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev, 1386 struct direct_buf_rx_module_param *mod_param) 1387 { 1388 uint32_t idx; 1389 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1390 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1391 struct direct_buf_rx_buf_info *dbr_buf_pool; 1392 void *buf_vaddr_unaligned, *buf_vaddr_aligned; 1393 QDF_STATUS status; 1394 uint8_t offset = 0; 1395 1396 direct_buf_rx_enter(); 1397 1398 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1399 dbr_ring_cap = mod_param->dbr_ring_cap; 1400 dbr_buf_pool = mod_param->dbr_buf_pool; 1401 1402 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1403 buf_vaddr_unaligned = 1404 target_if_dbr_mem_get(pdev, &dbr_ring_cap->min_buf_size, 1405 &offset, 1406 dbr_ring_cap->min_buf_align, 1407 mod_param->mod_id); 1408 if (!buf_vaddr_unaligned) { 1409 direct_buf_rx_err("dir buf rx ring alloc failed"); 1410 return QDF_STATUS_E_NOMEM; 1411 } 1412 1413 dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned; 1414 dbr_buf_pool[idx].offset = offset; 1415 dbr_buf_pool[idx].cookie = idx; 1416 buf_vaddr_aligned = buf_vaddr_unaligned + offset; 1417 status = target_if_dbr_replenish_ring(pdev, mod_param, 1418 buf_vaddr_aligned, idx); 1419 if (QDF_IS_STATUS_ERROR(status)) { 1420 direct_buf_rx_err("replenish failed with status : %d", 1421 status); 1422 target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size, 1423 buf_vaddr_unaligned, offset, 1424 dbr_ring_cap->min_buf_align, 1425 mod_param->mod_id); 1426 return QDF_STATUS_E_FAILURE; 1427 } 1428 } 1429 1430 direct_buf_rx_exit(); 1431 1432 return QDF_STATUS_SUCCESS; 1433 } 1434 1435 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev, 1436 struct direct_buf_rx_module_param *mod_param) 1437 { 1438 void *srng; 1439 uint32_t num_entries, ring_alloc_size, max_entries, entry_size; 1440 qdf_dma_addr_t paddr; 1441 struct hal_srng_params ring_params = {0}; 1442 struct wlan_objmgr_psoc *psoc; 1443 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1444 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1445 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1446 QDF_STATUS status; 1447 1448 direct_buf_rx_enter(); 1449 1450 psoc = wlan_pdev_get_psoc(pdev); 1451 1452 if (!psoc) { 1453 direct_buf_rx_err("psoc is null"); 1454 return QDF_STATUS_E_FAILURE; 1455 } 1456 1457 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1458 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1459 1460 if (!dbr_psoc_obj) { 1461 direct_buf_rx_err("dir buf rx psoc object is null"); 1462 return QDF_STATUS_E_FAILURE; 1463 } 1464 1465 if (!dbr_psoc_obj->hal_soc || 1466 !dbr_psoc_obj->osdev) { 1467 direct_buf_rx_err("dir buf rx target attach failed"); 1468 return QDF_STATUS_E_FAILURE; 1469 } 1470 1471 max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc, 1472 DIR_BUF_RX_DMA_SRC); 1473 entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc, 1474 DIR_BUF_RX_DMA_SRC); 1475 direct_buf_rx_debug("Max Entries = %d", max_entries); 1476 direct_buf_rx_debug("Entry Size = %d", entry_size); 1477 1478 status = populate_dbr_cap_mod_param(pdev, mod_param); 1479 if (QDF_IS_STATUS_ERROR(status)) { 1480 direct_buf_rx_err("Module cap population failed"); 1481 return QDF_STATUS_E_FAILURE; 1482 } 1483 1484 dbr_ring_cap = mod_param->dbr_ring_cap; 1485 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1486 num_entries = dbr_ring_cap->ring_elems_min > max_entries ? 1487 max_entries : dbr_ring_cap->ring_elems_min; 1488 direct_buf_rx_debug("Num entries = %d", num_entries); 1489 dbr_ring_cfg->num_ptr = num_entries; 1490 mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof( 1491 struct direct_buf_rx_buf_info)); 1492 if (!mod_param->dbr_buf_pool) 1493 return QDF_STATUS_E_NOMEM; 1494 1495 ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1; 1496 dbr_ring_cfg->ring_alloc_size = ring_alloc_size; 1497 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 1498 dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent( 1499 dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size, 1500 &paddr); 1501 direct_buf_rx_debug("vaddr aligned allocated"); 1502 dbr_ring_cfg->base_paddr_unaligned = paddr; 1503 if (!dbr_ring_cfg->base_vaddr_unaligned) { 1504 direct_buf_rx_err("dir buf rx vaddr alloc failed"); 1505 qdf_mem_free(mod_param->dbr_buf_pool); 1506 return QDF_STATUS_E_NOMEM; 1507 } 1508 1509 /* Alignment is defined to 8 for now. Will be advertised by FW */ 1510 dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup( 1511 (uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned, 1512 DBR_RING_BASE_ALIGN); 1513 ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned; 1514 dbr_ring_cfg->base_paddr_aligned = qdf_roundup( 1515 (uint64_t)dbr_ring_cfg->base_paddr_unaligned, 1516 DBR_RING_BASE_ALIGN); 1517 ring_params.ring_base_paddr = 1518 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned; 1519 ring_params.num_entries = num_entries; 1520 srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC, 1521 mod_param->mod_id, 1522 mod_param->pdev_id, &ring_params, 0); 1523 1524 if (!srng) { 1525 direct_buf_rx_err("srng setup failed"); 1526 qdf_mem_free(mod_param->dbr_buf_pool); 1527 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1528 dbr_psoc_obj->osdev->dev, 1529 ring_alloc_size, 1530 dbr_ring_cfg->base_vaddr_unaligned, 1531 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1532 return QDF_STATUS_E_FAILURE; 1533 } 1534 dbr_ring_cfg->srng = srng; 1535 dbr_ring_cfg->tail_idx_addr = 1536 hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng); 1537 dbr_ring_cfg->head_idx_addr = 1538 hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng); 1539 dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size; 1540 1541 return target_if_dbr_fill_ring(pdev, mod_param); 1542 } 1543 1544 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev, 1545 struct direct_buf_rx_module_param *mod_param) 1546 { 1547 QDF_STATUS status; 1548 1549 direct_buf_rx_debug("Init DBR srng"); 1550 1551 if (!mod_param) { 1552 direct_buf_rx_err("dir buf rx module param is null"); 1553 return QDF_STATUS_E_INVAL; 1554 } 1555 1556 mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof( 1557 struct direct_buf_rx_ring_cap)); 1558 1559 if (!mod_param->dbr_ring_cap) 1560 return QDF_STATUS_E_NOMEM; 1561 1562 /* Allocate memory for DBR Ring Config */ 1563 mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof( 1564 struct direct_buf_rx_ring_cfg)); 1565 1566 if (!mod_param->dbr_ring_cfg) { 1567 qdf_mem_free(mod_param->dbr_ring_cap); 1568 return QDF_STATUS_E_NOMEM; 1569 } 1570 1571 status = target_if_dbr_init_ring(pdev, mod_param); 1572 1573 if (QDF_IS_STATUS_ERROR(status)) { 1574 direct_buf_rx_err("DBR ring init failed"); 1575 qdf_mem_free(mod_param->dbr_ring_cfg); 1576 qdf_mem_free(mod_param->dbr_ring_cap); 1577 return QDF_STATUS_E_FAILURE; 1578 } 1579 1580 return QDF_STATUS_SUCCESS; 1581 } 1582 1583 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, 1584 struct direct_buf_rx_module_param *mod_param) 1585 { 1586 QDF_STATUS status; 1587 struct wlan_objmgr_psoc *psoc; 1588 wmi_unified_t wmi_hdl; 1589 struct direct_buf_rx_cfg_req dbr_cfg_req = {0}; 1590 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1591 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1592 struct dbr_module_config *dbr_config; 1593 1594 direct_buf_rx_enter(); 1595 1596 psoc = wlan_pdev_get_psoc(pdev); 1597 if (!psoc) { 1598 direct_buf_rx_err("psoc is null"); 1599 return QDF_STATUS_E_FAILURE; 1600 } 1601 1602 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1603 dbr_ring_cap = mod_param->dbr_ring_cap; 1604 dbr_config = &mod_param->dbr_config; 1605 wmi_hdl = lmac_get_pdev_wmi_handle(pdev); 1606 if (!wmi_hdl) { 1607 direct_buf_rx_err("WMI handle null. Can't send WMI CMD"); 1608 return QDF_STATUS_E_INVAL; 1609 } 1610 1611 direct_buf_rx_debug("Sending DBR Ring CFG to target"); 1612 dbr_cfg_req.pdev_id = mod_param->pdev_id; 1613 /* Module ID numbering starts from 1 in FW. need to fix it */ 1614 dbr_cfg_req.mod_id = mod_param->mod_id; 1615 dbr_cfg_req.base_paddr_lo = 1616 qdf_get_lower_32_bits(dbr_ring_cfg->base_paddr_aligned); 1617 dbr_cfg_req.base_paddr_hi = 1618 qdf_get_upper_32_bits(dbr_ring_cfg->base_paddr_aligned); 1619 dbr_cfg_req.head_idx_paddr_lo = 1620 qdf_get_lower_32_bits(dbr_ring_cfg->head_idx_addr); 1621 dbr_cfg_req.head_idx_paddr_hi = 1622 qdf_get_upper_32_bits(dbr_ring_cfg->head_idx_addr); 1623 dbr_cfg_req.tail_idx_paddr_lo = 1624 qdf_get_lower_32_bits(dbr_ring_cfg->tail_idx_addr); 1625 dbr_cfg_req.tail_idx_paddr_hi = 1626 qdf_get_upper_32_bits(dbr_ring_cfg->tail_idx_addr); 1627 dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min; 1628 dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size; 1629 dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event; 1630 dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms; 1631 direct_buf_rx_debug("pdev id %d mod id %d base addr lo %x\n" 1632 "base addr hi %x head idx addr lo %x\n" 1633 "head idx addr hi %x tail idx addr lo %x\n" 1634 "tail idx addr hi %x num ptr %d\n" 1635 "num resp %d event timeout %d\n", 1636 dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id, 1637 dbr_cfg_req.base_paddr_lo, 1638 dbr_cfg_req.base_paddr_hi, 1639 dbr_cfg_req.head_idx_paddr_lo, 1640 dbr_cfg_req.head_idx_paddr_hi, 1641 dbr_cfg_req.tail_idx_paddr_lo, 1642 dbr_cfg_req.tail_idx_paddr_hi, 1643 dbr_cfg_req.num_elems, 1644 dbr_cfg_req.num_resp_per_event, 1645 dbr_cfg_req.event_timeout_ms); 1646 status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req); 1647 1648 return status; 1649 } 1650 1651 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev, 1652 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1653 enum DBR_MODULE mod_id, uint8_t srng_id) 1654 { 1655 QDF_STATUS status = QDF_STATUS_SUCCESS; 1656 struct direct_buf_rx_module_param *mod_param; 1657 1658 direct_buf_rx_debug("Init DBR ring for module %d, srng %d", 1659 mod_id, srng_id); 1660 1661 if (!dbr_pdev_obj) { 1662 direct_buf_rx_err("dir buf rx object is null"); 1663 return QDF_STATUS_E_INVAL; 1664 } 1665 1666 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1667 1668 if (!mod_param) { 1669 direct_buf_rx_err("dir buf rx module param is null"); 1670 return QDF_STATUS_E_FAILURE; 1671 } 1672 1673 direct_buf_rx_debug("mod_param %pK", mod_param); 1674 1675 mod_param->mod_id = mod_id; 1676 mod_param->pdev_id = dbr_get_pdev_id( 1677 srng_id, wlan_objmgr_pdev_get_pdev_id(pdev)); 1678 mod_param->srng_id = srng_id; 1679 1680 /* Initialize DMA ring now */ 1681 status = target_if_dbr_init_srng(pdev, mod_param); 1682 if (QDF_IS_STATUS_ERROR(status)) { 1683 direct_buf_rx_err("DBR ring init failed %d", status); 1684 return status; 1685 } 1686 1687 mod_param->srng_initialized = true; 1688 1689 /* Send CFG request command to firmware */ 1690 status = target_if_dbr_cfg_tgt(pdev, mod_param); 1691 if (QDF_IS_STATUS_ERROR(status)) { 1692 direct_buf_rx_err("DBR config to target failed %d", status); 1693 goto dbr_srng_init_failed; 1694 } 1695 1696 return QDF_STATUS_SUCCESS; 1697 1698 dbr_srng_init_failed: 1699 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id); 1700 return status; 1701 } 1702 1703 QDF_STATUS target_if_direct_buf_rx_module_register( 1704 struct wlan_objmgr_pdev *pdev, uint8_t mod_id, 1705 struct dbr_module_config *dbr_config, 1706 bool (*dbr_rsp_handler) 1707 (struct wlan_objmgr_pdev *pdev, 1708 struct direct_buf_rx_data *dbr_data)) 1709 { 1710 QDF_STATUS status; 1711 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1712 struct dbr_module_config *config = NULL; 1713 struct direct_buf_rx_module_param *mod_param; 1714 uint8_t srng_id; 1715 1716 if (!pdev) { 1717 direct_buf_rx_err("pdev context passed is null"); 1718 return QDF_STATUS_E_INVAL; 1719 } 1720 1721 if (!dbr_rsp_handler) { 1722 direct_buf_rx_err("Response handler is null"); 1723 return QDF_STATUS_E_INVAL; 1724 } 1725 1726 if (mod_id >= DBR_MODULE_MAX) { 1727 direct_buf_rx_err("Invalid module id"); 1728 return QDF_STATUS_E_INVAL; 1729 } 1730 1731 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1732 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1733 1734 if (!dbr_pdev_obj) { 1735 direct_buf_rx_err("dir buf rx object is null"); 1736 return QDF_STATUS_E_FAILURE; 1737 } 1738 1739 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1740 1741 if (!dbr_pdev_obj->dbr_mod_param) { 1742 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1743 return QDF_STATUS_E_FAILURE; 1744 } 1745 1746 if (mod_id >= dbr_pdev_obj->num_modules) { 1747 direct_buf_rx_err("Module %d not supported in target", mod_id); 1748 return QDF_STATUS_E_FAILURE; 1749 } 1750 1751 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1752 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1753 config = &mod_param->dbr_config; 1754 mod_param->dbr_rsp_handler = dbr_rsp_handler; 1755 *config = *dbr_config; 1756 1757 status = target_if_init_dbr_ring(pdev, dbr_pdev_obj, 1758 (enum DBR_MODULE)mod_id, 1759 srng_id); 1760 if (QDF_IS_STATUS_ERROR(status)) 1761 direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d", 1762 srng_id, status); 1763 } 1764 1765 return status; 1766 } 1767 1768 QDF_STATUS target_if_direct_buf_rx_module_unregister( 1769 struct wlan_objmgr_pdev *pdev, uint8_t mod_id) 1770 { 1771 QDF_STATUS status; 1772 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1773 uint8_t srng_id; 1774 1775 if (!pdev) { 1776 direct_buf_rx_err("pdev context passed is null"); 1777 return QDF_STATUS_E_INVAL; 1778 } 1779 1780 if (mod_id >= DBR_MODULE_MAX) { 1781 direct_buf_rx_err("Invalid module id"); 1782 return QDF_STATUS_E_INVAL; 1783 } 1784 1785 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 1786 (pdev, 1787 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1788 1789 if (!dbr_pdev_obj) { 1790 direct_buf_rx_err("dir buf rx object is null"); 1791 return QDF_STATUS_E_FAILURE; 1792 } 1793 1794 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1795 1796 if (!dbr_pdev_obj->dbr_mod_param) { 1797 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1798 return QDF_STATUS_E_FAILURE; 1799 } 1800 1801 if (mod_id >= dbr_pdev_obj->num_modules) { 1802 direct_buf_rx_err("Module %d not supported in target", mod_id); 1803 return QDF_STATUS_E_FAILURE; 1804 } 1805 1806 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1807 status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 1808 mod_id, srng_id); 1809 direct_buf_rx_info("status %d", status); 1810 } 1811 1812 return status; 1813 } 1814 1815 static void *target_if_dbr_vaddr_lookup( 1816 struct direct_buf_rx_module_param *mod_param, 1817 qdf_dma_addr_t paddr, uint32_t cookie) 1818 { 1819 struct direct_buf_rx_buf_info *dbr_buf_pool; 1820 1821 dbr_buf_pool = mod_param->dbr_buf_pool; 1822 1823 if (cookie >= mod_param->dbr_ring_cfg->num_ptr) { 1824 direct_buf_rx_err("invalid cookie %d", cookie); 1825 return NULL; 1826 } 1827 1828 if (dbr_buf_pool[cookie].paddr == paddr) { 1829 return dbr_buf_pool[cookie].vaddr + 1830 dbr_buf_pool[cookie].offset; 1831 } 1832 direct_buf_rx_debug("Invalid paddr, cookie %d, pool paddr %pK, paddr %pK", 1833 cookie, (void *)dbr_buf_pool[cookie].paddr, 1834 (void *)paddr); 1835 1836 return NULL; 1837 } 1838 1839 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev, 1840 uint8_t mod_id, qdf_dma_addr_t paddr, 1841 uint32_t *cookie, uint8_t srng_id) 1842 { 1843 struct direct_buf_rx_buf_info *dbr_buf_pool; 1844 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1845 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1846 struct direct_buf_rx_module_param *mod_param; 1847 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1848 uint32_t idx; 1849 1850 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1851 if (!dbr_pdev_obj) { 1852 direct_buf_rx_err("dir buf rx object is null"); 1853 return QDF_STATUS_E_FAILURE; 1854 } 1855 1856 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1857 if (!mod_param) { 1858 direct_buf_rx_err("dir buf rx module param is null"); 1859 return QDF_STATUS_E_FAILURE; 1860 } 1861 1862 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1863 dbr_buf_pool = mod_param->dbr_buf_pool; 1864 1865 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1866 if (dbr_buf_pool[idx].paddr && 1867 dbr_buf_pool[idx].paddr == paddr) { 1868 *cookie = idx; 1869 return QDF_STATUS_SUCCESS; 1870 } 1871 } 1872 1873 return QDF_STATUS_E_FAILURE; 1874 } 1875 1876 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev, 1877 uint8_t mod_id, qdf_dma_addr_t paddr, 1878 uint32_t cookie, uint8_t srng_id) 1879 { 1880 struct direct_buf_rx_module_param *mod_param; 1881 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1882 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1883 void *vaddr; 1884 QDF_STATUS status; 1885 1886 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1887 if (!dbr_pdev_obj) { 1888 direct_buf_rx_err("dir buf rx object is null"); 1889 return QDF_STATUS_E_FAILURE; 1890 } 1891 1892 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1893 if (!mod_param) { 1894 direct_buf_rx_err("dir buf rx module param is null"); 1895 return QDF_STATUS_E_FAILURE; 1896 } 1897 1898 vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie); 1899 if (!vaddr) 1900 return QDF_STATUS_E_FAILURE; 1901 1902 status = target_if_dbr_replenish_ring(pdev, mod_param, 1903 vaddr, cookie); 1904 if (QDF_IS_STATUS_ERROR(status)) { 1905 direct_buf_rx_err("Ring replenish failed"); 1906 return QDF_STATUS_E_FAILURE; 1907 } 1908 1909 return QDF_STATUS_SUCCESS; 1910 } 1911 1912 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, 1913 struct direct_buf_rx_module_param *mod_param, 1914 struct direct_buf_rx_rsp *dbr_rsp, 1915 struct direct_buf_rx_data *dbr_data, 1916 uint8_t idx, uint32_t *cookie) 1917 { 1918 qdf_dma_addr_t paddr = 0; 1919 uint32_t addr_hi; 1920 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1921 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1922 struct wlan_objmgr_psoc *psoc; 1923 1924 psoc = wlan_pdev_get_psoc(pdev); 1925 if (!psoc) { 1926 direct_buf_rx_err("psoc is null"); 1927 return QDF_STATUS_E_FAILURE; 1928 } 1929 1930 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1931 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1932 1933 if (!dbr_psoc_obj) { 1934 direct_buf_rx_err("dir buf rx psoc object is null"); 1935 return QDF_STATUS_E_FAILURE; 1936 } 1937 1938 dbr_ring_cap = mod_param->dbr_ring_cap; 1939 addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET( 1940 dbr_rsp->dbr_entries[idx].paddr_hi); 1941 paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 | 1942 dbr_rsp->dbr_entries[idx].paddr_lo); 1943 *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( 1944 dbr_rsp->dbr_entries[idx].paddr_hi); 1945 dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); 1946 1947 if (!dbr_data->vaddr) { 1948 direct_buf_rx_debug("dbr vaddr lookup failed, cookie %d, hi %x, lo %x", 1949 *cookie, dbr_rsp->dbr_entries[idx].paddr_hi, 1950 dbr_rsp->dbr_entries[idx].paddr_lo); 1951 return QDF_STATUS_E_FAILURE; 1952 } 1953 1954 dbr_data->cookie = *cookie; 1955 dbr_data->paddr = paddr; 1956 direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK", 1957 dbr_data->cookie, dbr_data->vaddr); 1958 dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len; 1959 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr, 1960 QDF_DMA_FROM_DEVICE, 1961 dbr_ring_cap->min_buf_size); 1962 1963 return QDF_STATUS_SUCCESS; 1964 } 1965 1966 #ifdef DBR_MULTI_SRNG_ENABLE 1967 /** 1968 * dbr_get_pdev_and_srng_id() - get pdev object and srng id 1969 * 1970 * @psoc: pointer to psoc object 1971 * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid 1972 * @srng_id: pointer to return srng id 1973 * 1974 * Return : pointer to pdev 1975 */ 1976 static struct wlan_objmgr_pdev * 1977 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1978 uint8_t *srng_id) 1979 { 1980 struct wlan_objmgr_pdev *pdev; 1981 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1982 1983 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 1984 if (!pdev) { 1985 pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC, 1986 dbr_mod_id); 1987 if (pdev) { 1988 direct_buf_rx_debug("update srng id from %d to %d", 1989 *srng_id, pdev_id); 1990 *srng_id = pdev_id; 1991 } 1992 } 1993 1994 return pdev; 1995 } 1996 #else 1997 static struct wlan_objmgr_pdev * 1998 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1999 uint8_t *srng_id) 2000 { 2001 struct wlan_objmgr_pdev *pdev; 2002 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 2003 2004 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 2005 2006 return pdev; 2007 } 2008 #endif 2009 2010 #ifdef DIRECT_BUF_RX_DEBUG 2011 /** 2012 * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry 2013 * @pdev: pointer to pdev object 2014 * @mod_id: Module ID 2015 * @event: ring debug event 2016 * 2017 * Log the given event, head and tail pointers of DBR ring of the given module 2018 * into its ring debug data structure. 2019 * Also, log the timestamp at the time of logging. 2020 */ 2021 static void target_if_dbr_add_ring_debug_entry( 2022 struct wlan_objmgr_pdev *pdev, 2023 uint32_t mod_id, 2024 enum DBR_RING_DEBUG_EVENT event, 2025 uint8_t srng_id) 2026 { 2027 struct wlan_objmgr_psoc *psoc; 2028 void *hal_soc, *srng; 2029 uint32_t hp = 0, tp = 0; 2030 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2031 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2032 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2033 struct direct_buf_rx_module_debug *mod_debug; 2034 struct direct_buf_rx_module_param *mod_param; 2035 struct direct_buf_rx_ring_debug *ring_debug; 2036 struct direct_buf_rx_ring_debug_entry *entry; 2037 2038 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 2039 2040 if (!mod_debug) 2041 return; 2042 2043 psoc = wlan_pdev_get_psoc(pdev); 2044 2045 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 2046 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2047 2048 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 2049 psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2050 2051 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 2052 if (!mod_param) { 2053 direct_buf_rx_err("dir buf rx module param is null"); 2054 return; 2055 } 2056 2057 hal_soc = dbr_psoc_obj->hal_soc; 2058 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2059 srng = dbr_ring_cfg->srng; 2060 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 2061 2062 if (ring_debug->entries) { 2063 if (hal_le_srng_access_start_in_cpu_order(hal_soc, srng)) { 2064 direct_buf_rx_err("module %d - HAL srng access failed", 2065 mod_id); 2066 return; 2067 } 2068 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 2069 hal_le_srng_access_end_in_cpu_order(hal_soc, srng); 2070 tp = qdf_le32_to_cpu(tp); 2071 entry = &ring_debug->entries[ring_debug->ring_debug_idx]; 2072 2073 entry->head_idx = hp; 2074 entry->tail_idx = tp; 2075 entry->timestamp = qdf_get_log_timestamp(); 2076 entry->event = event; 2077 2078 ring_debug->ring_debug_idx++; 2079 if (ring_debug->ring_debug_idx == 2080 ring_debug->num_ring_debug_entries) 2081 ring_debug->ring_debug_idx = 0; 2082 } 2083 } 2084 2085 #else 2086 static void target_if_dbr_add_ring_debug_entry( 2087 struct wlan_objmgr_pdev *pdev, 2088 uint32_t mod_id, 2089 enum DBR_RING_DEBUG_EVENT event, 2090 uint8_t srng_id) 2091 { 2092 } 2093 #endif /* DIRECT_BUF_RX_DEBUG */ 2094 2095 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, 2096 uint8_t *data_buf, 2097 uint32_t data_len) 2098 { 2099 int ret = 0; 2100 uint8_t i = 0; 2101 QDF_STATUS status; 2102 uint32_t cookie = 0; 2103 struct direct_buf_rx_rsp dbr_rsp = {0}; 2104 struct direct_buf_rx_data dbr_data = {0}; 2105 struct wlan_objmgr_psoc *psoc; 2106 struct wlan_objmgr_pdev *pdev; 2107 struct direct_buf_rx_buf_info *dbr_buf_pool; 2108 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2109 struct direct_buf_rx_module_param *mod_param; 2110 struct wmi_unified *wmi_handle; 2111 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 2112 uint8_t srng_id = 0; 2113 2114 direct_buf_rx_enter(); 2115 2116 psoc = target_if_get_psoc_from_scn_hdl(scn); 2117 if (!psoc) { 2118 direct_buf_rx_err("psoc is null"); 2119 return QDF_STATUS_E_FAILURE; 2120 } 2121 2122 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 2123 if (!wmi_handle) { 2124 direct_buf_rx_err("WMI handle is null"); 2125 return QDF_STATUS_E_FAILURE; 2126 } 2127 2128 if (wmi_extract_dbr_buf_release_fixed( 2129 wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) { 2130 direct_buf_rx_err("unable to extract DBR rsp fixed param"); 2131 return QDF_STATUS_E_FAILURE; 2132 } 2133 2134 direct_buf_rx_debug("Num buf release entry = %d", 2135 dbr_rsp.num_buf_release_entry); 2136 2137 pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id, 2138 &srng_id); 2139 if (!pdev || (srng_id >= DBR_SRNG_NUM)) { 2140 direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d", 2141 pdev, srng_id); 2142 return QDF_STATUS_E_INVAL; 2143 } 2144 2145 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2146 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2147 2148 if (!dbr_pdev_obj) { 2149 direct_buf_rx_err("dir buf rx object is null"); 2150 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2151 return QDF_STATUS_E_FAILURE; 2152 } 2153 2154 if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) { 2155 direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id); 2156 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2157 return QDF_STATUS_E_FAILURE; 2158 } 2159 mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]); 2160 2161 if (!mod_param) { 2162 direct_buf_rx_err("dir buf rx module param is null"); 2163 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2164 return QDF_STATUS_E_FAILURE; 2165 } 2166 2167 dbr_buf_pool = mod_param->dbr_buf_pool; 2168 dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry * 2169 sizeof(struct direct_buf_rx_entry)); 2170 if (!dbr_rsp.dbr_entries) { 2171 direct_buf_rx_err("invalid dbr_entries"); 2172 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2173 return QDF_STATUS_E_FAILURE; 2174 } 2175 2176 if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) { 2177 direct_buf_rx_err("More than expected number of metadata"); 2178 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2179 return QDF_STATUS_E_FAILURE; 2180 } 2181 2182 for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { 2183 if (wmi_extract_dbr_buf_release_entry( 2184 wmi_handle, data_buf, i, 2185 &dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) { 2186 direct_buf_rx_err("Unable to extract DBR buf entry %d", 2187 i+1); 2188 qdf_mem_free(dbr_rsp.dbr_entries); 2189 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2190 return QDF_STATUS_E_FAILURE; 2191 } 2192 status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp, 2193 &dbr_data, i, &cookie); 2194 2195 if (QDF_IS_STATUS_ERROR(status)) { 2196 direct_buf_rx_err("DBR data get failed"); 2197 qdf_mem_free(dbr_rsp.dbr_entries); 2198 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2199 return QDF_STATUS_E_FAILURE; 2200 } 2201 2202 dbr_data.meta_data_valid = false; 2203 if (i < dbr_rsp.num_meta_data_entry) { 2204 if (wmi_extract_dbr_buf_metadata( 2205 wmi_handle, data_buf, i, 2206 &dbr_data.meta_data) == QDF_STATUS_SUCCESS) 2207 dbr_data.meta_data_valid = true; 2208 } 2209 2210 target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id, 2211 DBR_RING_DEBUG_EVENT_RX, 2212 srng_id); 2213 if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { 2214 status = target_if_dbr_replenish_ring(pdev, mod_param, 2215 dbr_data.vaddr, 2216 cookie); 2217 2218 target_if_dbr_add_ring_debug_entry( 2219 pdev, dbr_rsp.mod_id, 2220 DBR_RING_DEBUG_EVENT_REPLENISH_RING, 2221 srng_id); 2222 2223 if (QDF_IS_STATUS_ERROR(status)) { 2224 direct_buf_rx_err("Ring replenish failed"); 2225 qdf_mem_free(dbr_rsp.dbr_entries); 2226 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2227 return QDF_STATUS_E_FAILURE; 2228 } 2229 } 2230 } 2231 2232 qdf_mem_free(dbr_rsp.dbr_entries); 2233 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2234 2235 return ret; 2236 } 2237 2238 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev, 2239 struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 2240 struct direct_buf_rx_module_param *mod_param) 2241 { 2242 uint32_t idx; 2243 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2244 struct direct_buf_rx_ring_cap *dbr_ring_cap; 2245 struct direct_buf_rx_buf_info *dbr_buf_pool; 2246 2247 direct_buf_rx_enter(); 2248 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2249 dbr_ring_cap = mod_param->dbr_ring_cap; 2250 dbr_buf_pool = mod_param->dbr_buf_pool; 2251 2252 direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK", 2253 dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool); 2254 2255 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 2256 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, 2257 (qdf_dma_addr_t)dbr_buf_pool[idx].paddr, 2258 QDF_DMA_FROM_DEVICE, 2259 dbr_ring_cap->min_buf_size); 2260 target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size, 2261 dbr_buf_pool[idx].vaddr, 2262 dbr_buf_pool[idx].offset, 2263 dbr_ring_cap->min_buf_align, 2264 mod_param->mod_id); 2265 } 2266 2267 return QDF_STATUS_SUCCESS; 2268 } 2269 2270 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, 2271 struct direct_buf_rx_module_param *mod_param) 2272 { 2273 struct wlan_objmgr_psoc *psoc; 2274 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2275 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2276 2277 direct_buf_rx_enter(); 2278 psoc = wlan_pdev_get_psoc(pdev); 2279 if (!psoc) { 2280 direct_buf_rx_err("psoc is null"); 2281 return QDF_STATUS_E_FAILURE; 2282 } 2283 2284 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2285 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2286 2287 if (!dbr_psoc_obj) { 2288 direct_buf_rx_err("dir buf rx psoc object is null"); 2289 return QDF_STATUS_E_FAILURE; 2290 } 2291 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 2292 2293 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2294 if (dbr_ring_cfg) { 2295 target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); 2296 hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); 2297 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 2298 dbr_psoc_obj->osdev->dev, 2299 dbr_ring_cfg->ring_alloc_size, 2300 dbr_ring_cfg->base_vaddr_unaligned, 2301 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 2302 } 2303 2304 return QDF_STATUS_SUCCESS; 2305 } 2306 2307 static QDF_STATUS target_if_dbr_deinit_srng( 2308 struct wlan_objmgr_pdev *pdev, 2309 struct direct_buf_rx_module_param *mod_param) 2310 { 2311 struct direct_buf_rx_buf_info *dbr_buf_pool; 2312 2313 direct_buf_rx_enter(); 2314 dbr_buf_pool = mod_param->dbr_buf_pool; 2315 direct_buf_rx_debug("dbr buf pool %pK", dbr_buf_pool); 2316 target_if_dbr_deinit_ring(pdev, mod_param); 2317 if (mod_param->dbr_buf_pool) 2318 qdf_mem_free(dbr_buf_pool); 2319 mod_param->dbr_buf_pool = NULL; 2320 2321 return QDF_STATUS_SUCCESS; 2322 } 2323 2324 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev, 2325 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 2326 enum DBR_MODULE mod_id, uint8_t srng_id) 2327 { 2328 struct direct_buf_rx_module_param *mod_param; 2329 2330 direct_buf_rx_enter(); 2331 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 2332 2333 if (!mod_param) { 2334 direct_buf_rx_err("dir buf rx module param is null"); 2335 return QDF_STATUS_E_FAILURE; 2336 } 2337 direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK", 2338 mod_param, mod_param->dbr_ring_cap); 2339 2340 if (!mod_param->srng_initialized) { 2341 direct_buf_rx_err("module(%d) srng(%d) was not initialized", 2342 mod_id, srng_id); 2343 return QDF_STATUS_SUCCESS; 2344 } 2345 2346 target_if_dbr_deinit_srng(pdev, mod_param); 2347 if (mod_param->dbr_ring_cap) 2348 qdf_mem_free(mod_param->dbr_ring_cap); 2349 mod_param->dbr_ring_cap = NULL; 2350 if (mod_param->dbr_ring_cfg) 2351 qdf_mem_free(mod_param->dbr_ring_cfg); 2352 mod_param->dbr_ring_cfg = NULL; 2353 2354 mod_param->srng_initialized = false; 2355 2356 return QDF_STATUS_SUCCESS; 2357 } 2358 2359 QDF_STATUS target_if_direct_buf_rx_register_events( 2360 struct wlan_objmgr_psoc *psoc) 2361 { 2362 QDF_STATUS ret; 2363 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2364 2365 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2366 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2367 return QDF_STATUS_E_INVAL; 2368 } 2369 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 2370 psoc, 2371 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2372 2373 if (!dbr_psoc_obj) { 2374 direct_buf_rx_err("dir buf rx psoc object is null"); 2375 return QDF_STATUS_E_FAILURE; 2376 } 2377 2378 ret = wmi_unified_register_event_handler( 2379 get_wmi_unified_hdl_from_psoc(psoc), 2380 wmi_dma_buf_release_event_id, 2381 target_if_direct_buf_rx_rsp_event_handler, 2382 dbr_psoc_obj->handler_ctx); 2383 2384 direct_buf_rx_info("DBR Handler Context %d", dbr_psoc_obj->handler_ctx); 2385 if (QDF_IS_STATUS_ERROR(ret)) 2386 direct_buf_rx_debug("event handler not supported, ret=%d", ret); 2387 2388 return QDF_STATUS_SUCCESS; 2389 } 2390 2391 QDF_STATUS target_if_direct_buf_rx_unregister_events( 2392 struct wlan_objmgr_psoc *psoc) 2393 { 2394 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2395 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2396 return QDF_STATUS_E_INVAL; 2397 } 2398 2399 wmi_unified_unregister_event_handler( 2400 get_wmi_unified_hdl_from_psoc(psoc), 2401 wmi_dma_buf_release_event_id); 2402 2403 return QDF_STATUS_SUCCESS; 2404 } 2405 2406 QDF_STATUS target_if_direct_buf_rx_print_ring_stat( 2407 struct wlan_objmgr_pdev *pdev) 2408 { 2409 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2410 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2411 struct wlan_objmgr_psoc *psoc; 2412 void *srng, *hal_soc; 2413 uint32_t hp = 0, tp = 0; 2414 struct direct_buf_rx_module_param *mod_param; 2415 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2416 uint8_t num_modules, mod_idx; 2417 uint8_t srng_id; 2418 2419 if (!pdev) { 2420 direct_buf_rx_err("pdev is null"); 2421 return QDF_STATUS_E_INVAL; 2422 } 2423 2424 psoc = wlan_pdev_get_psoc(pdev); 2425 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2426 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2427 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2428 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2429 hal_soc = dbr_psoc_obj->hal_soc; 2430 num_modules = dbr_pdev_obj->num_modules; 2431 direct_buf_rx_debug("--------------------------------------------------"); 2432 direct_buf_rx_debug("| Module ID | Module | Head Idx | Tail Idx |"); 2433 direct_buf_rx_debug("--------------------------------------------------"); 2434 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 2435 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 2436 mod_param = 2437 &dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id]; 2438 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2439 if (!dbr_ring_cfg) { 2440 direct_buf_rx_info("dbr_ring_cfg is NULL"); 2441 direct_buf_rx_info("mod id %d mod %s", mod_idx, 2442 g_dbr_module_name[mod_idx]. 2443 module_name_str); 2444 continue; 2445 } 2446 srng = dbr_ring_cfg->srng; 2447 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 2448 tp = qdf_le32_to_cpu(tp); 2449 direct_buf_rx_debug("|%11d|%14s|%10x|%10x|", 2450 mod_idx, g_dbr_module_name[mod_idx]. 2451 module_name_str, 2452 hp, tp); 2453 } 2454 } 2455 direct_buf_rx_debug("--------------------------------------------------"); 2456 2457 return QDF_STATUS_SUCCESS; 2458 } 2459 2460 QDF_STATUS 2461 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, 2462 struct module_ring_params *param, 2463 uint8_t mod_id, uint8_t srng_id) 2464 { 2465 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2466 struct direct_buf_rx_module_param *dbr_mod_param; 2467 2468 if (!pdev) { 2469 direct_buf_rx_err("pdev context passed is null"); 2470 return QDF_STATUS_E_INVAL; 2471 } 2472 2473 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 2474 (pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2475 2476 if (!dbr_pdev_obj) { 2477 direct_buf_rx_err("dir buf rx object is null"); 2478 return QDF_STATUS_E_FAILURE; 2479 } 2480 2481 if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) { 2482 direct_buf_rx_err("invalid params, mod id %d, srng id %d", 2483 mod_id, srng_id); 2484 return QDF_STATUS_E_INVAL; 2485 } 2486 2487 dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 2488 param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr; 2489 param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size; 2490 2491 return QDF_STATUS_SUCCESS; 2492 } 2493