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 return status; 827 828 attach_error: 829 qdf_mem_free(dbr_psoc_obj); 830 831 return status; 832 } 833 834 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler( 835 struct wlan_objmgr_psoc *psoc, void *data) 836 { 837 QDF_STATUS status; 838 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 839 840 direct_buf_rx_enter(); 841 842 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 843 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 844 845 if (!dbr_psoc_obj) { 846 direct_buf_rx_err("dir buf rx psoc obj is null"); 847 return QDF_STATUS_E_FAILURE; 848 } 849 850 target_if_dbr_deinit_mem_list(dbr_psoc_obj); 851 status = wlan_objmgr_psoc_component_obj_detach(psoc, 852 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 853 dbr_psoc_obj); 854 855 if (status != QDF_STATUS_SUCCESS) { 856 direct_buf_rx_err("failed to detach dir buf rx component %d", 857 status); 858 } 859 860 qdf_mem_free(dbr_psoc_obj); 861 862 return status; 863 } 864 865 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG) 866 /** 867 * target_if_dbr_debugfs_show_ring_debug() - Function to display ring debug 868 * entries in debugfs 869 * @file: qdf debugfs file handler 870 * @arg: pointer to DBR debugfs private object 871 * 872 * Return: QDF_STATUS of operation 873 */ 874 static QDF_STATUS target_if_dbr_debugfs_show_ring_debug( 875 qdf_debugfs_file_t file, void *arg) 876 { 877 struct dbr_debugfs_priv *priv = arg; 878 879 return target_if_dbr_print_ring_debug_entries(qdf_debugfs_printer, 880 file, priv->dbr_pdev_obj, 881 priv->mod_id, 882 priv->srng_id); 883 } 884 885 /** 886 * target_if_dbr_mod_debugfs_init() - Init debugfs for a given module 887 * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module 888 * @mod_id: Module ID corresponding to this ring 889 * 890 * Return: QDF_STATUS of operation 891 */ 892 static QDF_STATUS target_if_dbr_mod_debugfs_init( 893 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 894 enum DBR_MODULE mod_id) 895 { 896 struct direct_buf_rx_module_debug *mod_debug; 897 898 mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, 899 mod_id); 900 901 if (!mod_debug) 902 return QDF_STATUS_E_INVAL; 903 904 if (mod_debug->debugfs_entry) { 905 direct_buf_rx_err("debugfs mod entry was already created for %s module", 906 g_dbr_module_name[mod_id].module_name_str); 907 return QDF_STATUS_SUCCESS; 908 } 909 910 mod_debug->debugfs_entry = 911 qdf_debugfs_create_dir(g_dbr_module_name[mod_id].module_name_str, 912 dbr_pdev_obj->debugfs_entry); 913 914 if (!mod_debug->debugfs_entry) { 915 direct_buf_rx_err("error while creating direct_buf debugfs entry for %s module", 916 g_dbr_module_name[mod_id].module_name_str); 917 return QDF_STATUS_E_FAILURE; 918 } 919 920 return QDF_STATUS_SUCCESS; 921 } 922 923 /** 924 * target_if_dbr_ring_debugfs_init() - Init debugfs for a given ring 925 * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module 926 * @mod_id: Module ID corresponding to this ring 927 * @srng_id: srng ID corresponding to this ring 928 * 929 * Return: QDF_STATUS of operation 930 */ 931 static QDF_STATUS target_if_dbr_ring_debugfs_init( 932 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 933 enum DBR_MODULE mod_id, uint8_t srng_id) 934 { 935 struct direct_buf_rx_module_debug *mod_debug; 936 struct direct_buf_rx_ring_debug *ring_debug; 937 struct dbr_debugfs_priv *priv; 938 char debug_file_name[32]; 939 940 mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, 941 mod_id); 942 943 if (!mod_debug) 944 return QDF_STATUS_E_INVAL; 945 946 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 947 948 if (!mod_debug->debugfs_entry) { 949 direct_buf_rx_err("error mod_debug->debugfs_entry not created"); 950 return QDF_STATUS_E_FAILURE; 951 } 952 953 if (ring_debug->debugfs_entry) { 954 direct_buf_rx_err("debugfs file for %d ring under %s module already created", 955 srng_id, 956 g_dbr_module_name[mod_id].module_name_str); 957 return QDF_STATUS_SUCCESS; 958 } 959 960 qdf_snprintf(debug_file_name, sizeof(debug_file_name), 961 "ring_%d", srng_id); 962 963 // Allocate debugfs ops 964 ring_debug->debugfs_fops = 965 qdf_mem_malloc(sizeof(*ring_debug->debugfs_fops)); 966 if (!ring_debug->debugfs_fops) { 967 direct_buf_rx_err("error in allocating debugfs ops"); 968 return QDF_STATUS_E_NOMEM; 969 } 970 971 // Allocate private data 972 priv = qdf_mem_malloc(sizeof(*priv)); 973 if (!priv) { 974 direct_buf_rx_err("error in creating debugfs private data"); 975 goto priv_alloc_fail; 976 } 977 priv->dbr_pdev_obj = dbr_pdev_obj; 978 priv->mod_id = mod_id; 979 priv->srng_id = srng_id; 980 981 /* Fill in the debugfs ops for this ring. 982 * When the output time comes, the 'show' function will be 983 * called with 'priv' as an argument. 984 */ 985 ring_debug->debugfs_fops->show = target_if_dbr_debugfs_show_ring_debug; 986 ring_debug->debugfs_fops->priv = priv; 987 988 ring_debug->debugfs_entry = 989 qdf_debugfs_create_file_simplified( 990 debug_file_name, 991 (QDF_FILE_USR_READ | QDF_FILE_GRP_READ | 992 QDF_FILE_OTH_READ), 993 mod_debug->debugfs_entry, 994 ring_debug->debugfs_fops); 995 996 if (!ring_debug->debugfs_entry) { 997 direct_buf_rx_err("error while creating direct_buf debugfs file for %d ring under %s module", 998 srng_id, 999 g_dbr_module_name[mod_id].module_name_str); 1000 goto file_creation_fail; 1001 } 1002 1003 return QDF_STATUS_SUCCESS; 1004 1005 file_creation_fail: 1006 qdf_mem_free(ring_debug->debugfs_fops->priv); 1007 1008 priv_alloc_fail: 1009 qdf_mem_free(ring_debug->debugfs_fops); 1010 ring_debug->debugfs_fops = NULL; 1011 return QDF_STATUS_E_NOMEM; 1012 } 1013 1014 /** 1015 * target_if_dbr_mod_debugfs_deinit() - De-init debugfs for a given module 1016 * @mod_debug: Pointer to direct_buf_rx_module_debug structure 1017 * 1018 * Return: void 1019 */ 1020 static void target_if_dbr_mod_debugfs_deinit( 1021 struct direct_buf_rx_module_debug *mod_debug) 1022 { 1023 if (!mod_debug) { 1024 direct_buf_rx_err("mod_debug is null"); 1025 return; 1026 } 1027 1028 if (mod_debug->debugfs_entry) { 1029 qdf_debugfs_remove_file(mod_debug->debugfs_entry); 1030 mod_debug->debugfs_entry = NULL; 1031 } 1032 } 1033 1034 /** 1035 * target_if_dbr_ring_debugfs_deinit() - De-init debugfs for a given ring 1036 * @ring_debug: Pointer to direct_buf_rx_ring_debug structure 1037 * 1038 * Return: void 1039 */ 1040 static void target_if_dbr_ring_debugfs_deinit( 1041 struct direct_buf_rx_ring_debug *ring_debug) 1042 { 1043 if (!ring_debug) { 1044 direct_buf_rx_err("ring_debug is null"); 1045 return; 1046 } 1047 1048 if (ring_debug->debugfs_entry) { 1049 qdf_debugfs_remove_file(ring_debug->debugfs_entry); 1050 ring_debug->debugfs_entry = NULL; 1051 } 1052 1053 // Free the private data and debugfs ops of this ring 1054 if (ring_debug->debugfs_fops) { 1055 qdf_mem_free(ring_debug->debugfs_fops->priv); 1056 qdf_mem_free(ring_debug->debugfs_fops); 1057 ring_debug->debugfs_fops = NULL; 1058 } 1059 } 1060 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */ 1061 1062 #ifdef DIRECT_BUF_RX_DEBUG 1063 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, 1064 uint8_t mod_id) 1065 { 1066 struct direct_buf_rx_module_debug *mod_debug; 1067 struct direct_buf_rx_ring_debug *ring_debug; 1068 uint8_t srng_id; 1069 1070 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1071 if (!mod_debug) 1072 return QDF_STATUS_E_INVAL; 1073 1074 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1075 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 1076 if (!ring_debug->entries) { 1077 direct_buf_rx_debug("DBR ring debug for module %d srng %d was already disabled", 1078 mod_id, srng_id); 1079 continue; 1080 } 1081 /* De-init debugsfs for this ring */ 1082 target_if_dbr_ring_debugfs_deinit(ring_debug); 1083 qdf_mem_free(ring_debug->entries); 1084 ring_debug->entries = NULL; 1085 ring_debug->ring_debug_idx = 0; 1086 ring_debug->num_ring_debug_entries = 0; 1087 direct_buf_rx_info("DBR ring debug for module %d srng %d is now stopped", 1088 mod_id, srng_id); 1089 } 1090 target_if_dbr_mod_debugfs_deinit(mod_debug); 1091 1092 return QDF_STATUS_SUCCESS; 1093 } 1094 1095 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, 1096 uint8_t mod_id, 1097 uint32_t num_ring_debug_entries) 1098 { 1099 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1100 struct direct_buf_rx_module_debug *mod_debug; 1101 struct direct_buf_rx_ring_debug *ring_debug; 1102 uint8_t srng_id; 1103 1104 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1105 1106 if (!mod_debug) 1107 return QDF_STATUS_E_INVAL; 1108 1109 if (num_ring_debug_entries > DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES) { 1110 direct_buf_rx_err("Requested number of ring debug entries(%d) exceed the maximum entries allowed(%d)", 1111 num_ring_debug_entries, 1112 DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES); 1113 1114 return QDF_STATUS_E_FAILURE; 1115 } 1116 1117 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 1118 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1119 1120 target_if_dbr_mod_debugfs_init(dbr_pdev_obj, mod_id); 1121 1122 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1123 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 1124 1125 if (ring_debug->entries) { 1126 direct_buf_rx_err("DBR ring debug for module %d srng %d was already enabled", 1127 mod_id, srng_id); 1128 continue; 1129 } 1130 1131 ring_debug->entries = qdf_mem_malloc( 1132 num_ring_debug_entries * 1133 sizeof(*ring_debug->entries)); 1134 1135 if (!ring_debug->entries) 1136 return QDF_STATUS_E_NOMEM; 1137 1138 ring_debug->ring_debug_idx = 0; 1139 ring_debug->num_ring_debug_entries = num_ring_debug_entries; 1140 /* Init debugsfs for this ring */ 1141 target_if_dbr_ring_debugfs_init( 1142 dbr_pdev_obj, 1143 mod_id, srng_id); 1144 direct_buf_rx_info("DBR ring debug for module %d srng %d is now started", 1145 mod_id, srng_id); 1146 } 1147 return QDF_STATUS_SUCCESS; 1148 } 1149 1150 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, 1151 uint8_t mod_id, uint32_t value) 1152 { 1153 struct direct_buf_rx_module_debug *mod_debug; 1154 1155 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1156 1157 if (!mod_debug) 1158 return QDF_STATUS_E_INVAL; 1159 1160 mod_debug->poisoning_enabled = true; 1161 mod_debug->poison_value = value; /* Save the poison value */ 1162 1163 direct_buf_rx_debug("DBR buffer poisoning for module %d is now started", 1164 mod_id); 1165 return QDF_STATUS_SUCCESS; 1166 } 1167 1168 QDF_STATUS target_if_dbr_stop_buffer_poisoning( 1169 struct wlan_objmgr_pdev *pdev, 1170 uint8_t mod_id) 1171 { 1172 struct direct_buf_rx_module_debug *mod_debug; 1173 1174 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1175 1176 if (!mod_debug) 1177 return QDF_STATUS_E_INVAL; 1178 1179 mod_debug->poisoning_enabled = false; 1180 mod_debug->poison_value = 0; 1181 1182 direct_buf_rx_debug("DBR buffer poisoning for module %d is now stopped", 1183 mod_id); 1184 return QDF_STATUS_SUCCESS; 1185 } 1186 1187 /** 1188 * target_if_dbr_fill_buffer_u32() - Fill buffer with an unsigned 32-bit value 1189 * @buffer: pointer to the buffer 1190 * @num_bytes: Size of the destination buffer in bytes 1191 * @value: Unsigned 32-bit value to be copied 1192 * 1193 * Return : void 1194 */ 1195 static void 1196 target_if_dbr_fill_buffer_u32(uint8_t *buffer, uint32_t num_bytes, 1197 uint32_t value) 1198 { 1199 uint32_t *bufp; 1200 uint32_t idx; 1201 uint32_t size = (num_bytes >> 2); 1202 1203 if (!buffer) { 1204 direct_buf_rx_err("buffer empty"); 1205 return; 1206 } 1207 1208 bufp = (uint32_t *)buffer; 1209 1210 for (idx = 0; idx < size; ++idx) { 1211 *bufp = value; 1212 ++bufp; 1213 } 1214 } 1215 1216 /** 1217 * target_if_dbr_debug_poison_buffer() - Poison a given DBR buffer 1218 * @pdev: pointer to pdev object 1219 * @mod_id: Module ID of the owner of the buffer 1220 * @aligned_vaddr: Virtual address(aligned) of the buffer 1221 * @size: Size of the buffer 1222 * 1223 * Value with which the buffers will be poisoned would have been saved 1224 * while starting the buffer poisoning for the module, use that value. 1225 * 1226 * Return : QDF status of operation 1227 */ 1228 static QDF_STATUS target_if_dbr_debug_poison_buffer( 1229 struct wlan_objmgr_pdev *pdev, 1230 uint32_t mod_id, void *aligned_vaddr, uint32_t size) 1231 { 1232 struct direct_buf_rx_module_debug *mod_debug; 1233 1234 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1235 1236 if (!mod_debug) 1237 return QDF_STATUS_E_INVAL; 1238 1239 if (mod_debug->poisoning_enabled) { 1240 target_if_dbr_fill_buffer_u32(aligned_vaddr, size, 1241 mod_debug->poison_value); 1242 } 1243 1244 return QDF_STATUS_SUCCESS; 1245 } 1246 1247 static inline void target_if_dbr_qdf_show_ring_debug( 1248 struct wlan_objmgr_pdev *pdev, 1249 uint8_t mod_id, uint8_t srng_id) 1250 { 1251 struct direct_buf_rx_pdev_obj *dbr_pdev_obj = 1252 wlan_objmgr_pdev_get_comp_private_obj( 1253 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1254 1255 target_if_dbr_print_ring_debug_entries( 1256 target_if_dbr_qdf_err_printer, 1257 NULL, dbr_pdev_obj, 1258 mod_id, srng_id); 1259 } 1260 #else 1261 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, 1262 uint8_t mod_id) 1263 { 1264 return QDF_STATUS_SUCCESS; 1265 } 1266 1267 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, 1268 uint8_t mod_id, 1269 uint32_t num_ring_debug_entries) 1270 { 1271 return QDF_STATUS_SUCCESS; 1272 } 1273 1274 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, 1275 uint8_t mod_id, uint32_t value) 1276 { 1277 return QDF_STATUS_SUCCESS; 1278 } 1279 1280 QDF_STATUS target_if_dbr_stop_buffer_poisoning( 1281 struct wlan_objmgr_pdev *pdev, 1282 uint8_t mod_id) 1283 { 1284 return QDF_STATUS_SUCCESS; 1285 } 1286 1287 static QDF_STATUS target_if_dbr_debug_poison_buffer( 1288 struct wlan_objmgr_pdev *pdev, 1289 uint32_t mod_id, void *aligned_vaddr, uint32_t size) 1290 { 1291 return QDF_STATUS_SUCCESS; 1292 } 1293 1294 static inline void target_if_dbr_qdf_show_ring_debug( 1295 struct wlan_objmgr_pdev *pdev, 1296 uint8_t mod_id, uint8_t srng_id) 1297 { 1298 } 1299 #endif /* DIRECT_BUF_RX_DEBUG */ 1300 1301 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, 1302 struct direct_buf_rx_module_param *mod_param, 1303 void *aligned_vaddr, uint32_t cookie) 1304 { 1305 uint32_t *ring_entry; 1306 uint32_t dw_lo, dw_hi = 0, map_status; 1307 void *hal_soc, *srng; 1308 qdf_dma_addr_t paddr; 1309 struct wlan_objmgr_psoc *psoc; 1310 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1311 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1312 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1313 struct direct_buf_rx_buf_info *dbr_buf_pool; 1314 1315 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1316 dbr_ring_cap = mod_param->dbr_ring_cap; 1317 dbr_buf_pool = mod_param->dbr_buf_pool; 1318 1319 psoc = wlan_pdev_get_psoc(pdev); 1320 1321 if (!psoc) { 1322 direct_buf_rx_err("psoc is null"); 1323 return QDF_STATUS_E_FAILURE; 1324 } 1325 1326 if (cookie >= mod_param->dbr_ring_cfg->num_ptr) { 1327 direct_buf_rx_err("invalid cookie %d", cookie); 1328 return QDF_STATUS_E_INVAL; 1329 } 1330 1331 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1332 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1333 1334 if (!dbr_psoc_obj) { 1335 direct_buf_rx_err("dir buf rx psoc object is null"); 1336 return QDF_STATUS_E_FAILURE; 1337 } 1338 1339 hal_soc = dbr_psoc_obj->hal_soc; 1340 srng = dbr_ring_cfg->srng; 1341 if (!aligned_vaddr) { 1342 direct_buf_rx_err("aligned vaddr is null"); 1343 return QDF_STATUS_SUCCESS; 1344 } 1345 1346 target_if_dbr_debug_poison_buffer( 1347 pdev, mod_param->mod_id, aligned_vaddr, 1348 dbr_ring_cap->min_buf_size); 1349 1350 map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev, 1351 aligned_vaddr, 1352 QDF_DMA_FROM_DEVICE, 1353 dbr_ring_cap->min_buf_size, 1354 &paddr); 1355 if (map_status) { 1356 direct_buf_rx_err("mem map failed status = %d", map_status); 1357 return QDF_STATUS_E_FAILURE; 1358 } 1359 1360 QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align)); 1361 dbr_buf_pool[cookie].paddr = paddr; 1362 1363 hal_le_srng_access_start_in_cpu_order(hal_soc, srng); 1364 ring_entry = hal_srng_src_get_next(hal_soc, srng); 1365 1366 if (!ring_entry) { 1367 target_if_dbr_qdf_show_ring_debug(pdev, mod_param->mod_id, 1368 mod_param->srng_id); 1369 QDF_BUG(0); 1370 } 1371 1372 dw_lo = (uint64_t)paddr & 0xFFFFFFFF; 1373 WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32); 1374 WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie); 1375 *ring_entry = qdf_cpu_to_le32(dw_lo); 1376 ring_entry++; 1377 *ring_entry = qdf_cpu_to_le32(dw_hi); 1378 hal_le_srng_access_end_in_cpu_order(hal_soc, srng); 1379 1380 return QDF_STATUS_SUCCESS; 1381 } 1382 1383 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev, 1384 struct direct_buf_rx_module_param *mod_param) 1385 { 1386 uint32_t idx; 1387 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1388 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1389 struct direct_buf_rx_buf_info *dbr_buf_pool; 1390 void *buf_vaddr_unaligned, *buf_vaddr_aligned; 1391 QDF_STATUS status; 1392 uint8_t offset; 1393 1394 direct_buf_rx_enter(); 1395 1396 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1397 dbr_ring_cap = mod_param->dbr_ring_cap; 1398 dbr_buf_pool = mod_param->dbr_buf_pool; 1399 1400 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1401 buf_vaddr_unaligned = 1402 target_if_dbr_mem_get(pdev, &dbr_ring_cap->min_buf_size, 1403 &offset, 1404 dbr_ring_cap->min_buf_align, 1405 mod_param->mod_id); 1406 if (!buf_vaddr_unaligned) { 1407 direct_buf_rx_err("dir buf rx ring alloc failed"); 1408 return QDF_STATUS_E_NOMEM; 1409 } 1410 1411 dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned; 1412 dbr_buf_pool[idx].offset = offset; 1413 dbr_buf_pool[idx].cookie = idx; 1414 buf_vaddr_aligned = buf_vaddr_unaligned + offset; 1415 status = target_if_dbr_replenish_ring(pdev, mod_param, 1416 buf_vaddr_aligned, idx); 1417 if (QDF_IS_STATUS_ERROR(status)) { 1418 direct_buf_rx_err("replenish failed with status : %d", 1419 status); 1420 target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size, 1421 buf_vaddr_unaligned, offset, 1422 dbr_ring_cap->min_buf_align, 1423 mod_param->mod_id); 1424 return QDF_STATUS_E_FAILURE; 1425 } 1426 } 1427 1428 direct_buf_rx_exit(); 1429 1430 return QDF_STATUS_SUCCESS; 1431 } 1432 1433 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev, 1434 struct direct_buf_rx_module_param *mod_param) 1435 { 1436 void *srng; 1437 uint32_t num_entries, ring_alloc_size, max_entries, entry_size; 1438 qdf_dma_addr_t paddr; 1439 struct hal_srng_params ring_params = {0}; 1440 struct wlan_objmgr_psoc *psoc; 1441 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1442 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1443 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1444 QDF_STATUS status; 1445 1446 direct_buf_rx_enter(); 1447 1448 psoc = wlan_pdev_get_psoc(pdev); 1449 1450 if (!psoc) { 1451 direct_buf_rx_err("psoc is null"); 1452 return QDF_STATUS_E_FAILURE; 1453 } 1454 1455 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1456 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1457 1458 if (!dbr_psoc_obj) { 1459 direct_buf_rx_err("dir buf rx psoc object is null"); 1460 return QDF_STATUS_E_FAILURE; 1461 } 1462 1463 if (!dbr_psoc_obj->hal_soc || 1464 !dbr_psoc_obj->osdev) { 1465 direct_buf_rx_err("dir buf rx target attach failed"); 1466 return QDF_STATUS_E_FAILURE; 1467 } 1468 1469 max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc, 1470 DIR_BUF_RX_DMA_SRC); 1471 entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc, 1472 DIR_BUF_RX_DMA_SRC); 1473 direct_buf_rx_debug("Max Entries = %d", max_entries); 1474 direct_buf_rx_debug("Entry Size = %d", entry_size); 1475 1476 status = populate_dbr_cap_mod_param(pdev, mod_param); 1477 if (QDF_IS_STATUS_ERROR(status)) { 1478 direct_buf_rx_err("Module cap population failed"); 1479 return QDF_STATUS_E_FAILURE; 1480 } 1481 1482 dbr_ring_cap = mod_param->dbr_ring_cap; 1483 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1484 num_entries = dbr_ring_cap->ring_elems_min > max_entries ? 1485 max_entries : dbr_ring_cap->ring_elems_min; 1486 direct_buf_rx_debug("Num entries = %d", num_entries); 1487 dbr_ring_cfg->num_ptr = num_entries; 1488 mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof( 1489 struct direct_buf_rx_buf_info)); 1490 if (!mod_param->dbr_buf_pool) 1491 return QDF_STATUS_E_NOMEM; 1492 1493 ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1; 1494 dbr_ring_cfg->ring_alloc_size = ring_alloc_size; 1495 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 1496 dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent( 1497 dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size, 1498 &paddr); 1499 direct_buf_rx_debug("vaddr aligned allocated"); 1500 dbr_ring_cfg->base_paddr_unaligned = paddr; 1501 if (!dbr_ring_cfg->base_vaddr_unaligned) { 1502 direct_buf_rx_err("dir buf rx vaddr alloc failed"); 1503 qdf_mem_free(mod_param->dbr_buf_pool); 1504 return QDF_STATUS_E_NOMEM; 1505 } 1506 1507 /* Alignment is defined to 8 for now. Will be advertised by FW */ 1508 dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup( 1509 (uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned, 1510 DBR_RING_BASE_ALIGN); 1511 ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned; 1512 dbr_ring_cfg->base_paddr_aligned = qdf_roundup( 1513 (uint64_t)dbr_ring_cfg->base_paddr_unaligned, 1514 DBR_RING_BASE_ALIGN); 1515 ring_params.ring_base_paddr = 1516 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned; 1517 ring_params.num_entries = num_entries; 1518 srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC, 1519 mod_param->mod_id, 1520 mod_param->pdev_id, &ring_params, 0); 1521 1522 if (!srng) { 1523 direct_buf_rx_err("srng setup failed"); 1524 qdf_mem_free(mod_param->dbr_buf_pool); 1525 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1526 dbr_psoc_obj->osdev->dev, 1527 ring_alloc_size, 1528 dbr_ring_cfg->base_vaddr_unaligned, 1529 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1530 return QDF_STATUS_E_FAILURE; 1531 } 1532 dbr_ring_cfg->srng = srng; 1533 dbr_ring_cfg->tail_idx_addr = 1534 hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng); 1535 dbr_ring_cfg->head_idx_addr = 1536 hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng); 1537 dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size; 1538 1539 return target_if_dbr_fill_ring(pdev, mod_param); 1540 } 1541 1542 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev, 1543 struct direct_buf_rx_module_param *mod_param) 1544 { 1545 QDF_STATUS status; 1546 1547 direct_buf_rx_debug("Init DBR srng"); 1548 1549 if (!mod_param) { 1550 direct_buf_rx_err("dir buf rx module param is null"); 1551 return QDF_STATUS_E_INVAL; 1552 } 1553 1554 mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof( 1555 struct direct_buf_rx_ring_cap)); 1556 1557 if (!mod_param->dbr_ring_cap) 1558 return QDF_STATUS_E_NOMEM; 1559 1560 /* Allocate memory for DBR Ring Config */ 1561 mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof( 1562 struct direct_buf_rx_ring_cfg)); 1563 1564 if (!mod_param->dbr_ring_cfg) { 1565 qdf_mem_free(mod_param->dbr_ring_cap); 1566 return QDF_STATUS_E_NOMEM; 1567 } 1568 1569 status = target_if_dbr_init_ring(pdev, mod_param); 1570 1571 if (QDF_IS_STATUS_ERROR(status)) { 1572 direct_buf_rx_err("DBR ring init failed"); 1573 qdf_mem_free(mod_param->dbr_ring_cfg); 1574 qdf_mem_free(mod_param->dbr_ring_cap); 1575 return QDF_STATUS_E_FAILURE; 1576 } 1577 1578 return QDF_STATUS_SUCCESS; 1579 } 1580 1581 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, 1582 struct direct_buf_rx_module_param *mod_param) 1583 { 1584 QDF_STATUS status; 1585 struct wlan_objmgr_psoc *psoc; 1586 wmi_unified_t wmi_hdl; 1587 struct direct_buf_rx_cfg_req dbr_cfg_req = {0}; 1588 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1589 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1590 struct dbr_module_config *dbr_config; 1591 1592 direct_buf_rx_enter(); 1593 1594 psoc = wlan_pdev_get_psoc(pdev); 1595 if (!psoc) { 1596 direct_buf_rx_err("psoc is null"); 1597 return QDF_STATUS_E_FAILURE; 1598 } 1599 1600 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1601 dbr_ring_cap = mod_param->dbr_ring_cap; 1602 dbr_config = &mod_param->dbr_config; 1603 wmi_hdl = lmac_get_pdev_wmi_handle(pdev); 1604 if (!wmi_hdl) { 1605 direct_buf_rx_err("WMI handle null. Can't send WMI CMD"); 1606 return QDF_STATUS_E_INVAL; 1607 } 1608 1609 direct_buf_rx_debug("Sending DBR Ring CFG to target"); 1610 dbr_cfg_req.pdev_id = mod_param->pdev_id; 1611 /* Module ID numbering starts from 1 in FW. need to fix it */ 1612 dbr_cfg_req.mod_id = mod_param->mod_id; 1613 dbr_cfg_req.base_paddr_lo = 1614 qdf_get_lower_32_bits(dbr_ring_cfg->base_paddr_aligned); 1615 dbr_cfg_req.base_paddr_hi = 1616 qdf_get_upper_32_bits(dbr_ring_cfg->base_paddr_aligned); 1617 dbr_cfg_req.head_idx_paddr_lo = 1618 qdf_get_lower_32_bits(dbr_ring_cfg->head_idx_addr); 1619 dbr_cfg_req.head_idx_paddr_hi = 1620 qdf_get_upper_32_bits(dbr_ring_cfg->head_idx_addr); 1621 dbr_cfg_req.tail_idx_paddr_lo = 1622 qdf_get_lower_32_bits(dbr_ring_cfg->tail_idx_addr); 1623 dbr_cfg_req.tail_idx_paddr_hi = 1624 qdf_get_upper_32_bits(dbr_ring_cfg->tail_idx_addr); 1625 dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min; 1626 dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size; 1627 dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event; 1628 dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms; 1629 direct_buf_rx_debug("pdev id %d mod id %d base addr lo %x\n" 1630 "base addr hi %x head idx addr lo %x\n" 1631 "head idx addr hi %x tail idx addr lo %x\n" 1632 "tail idx addr hi %x num ptr %d\n" 1633 "num resp %d event timeout %d\n", 1634 dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id, 1635 dbr_cfg_req.base_paddr_lo, 1636 dbr_cfg_req.base_paddr_hi, 1637 dbr_cfg_req.head_idx_paddr_lo, 1638 dbr_cfg_req.head_idx_paddr_hi, 1639 dbr_cfg_req.tail_idx_paddr_lo, 1640 dbr_cfg_req.tail_idx_paddr_hi, 1641 dbr_cfg_req.num_elems, 1642 dbr_cfg_req.num_resp_per_event, 1643 dbr_cfg_req.event_timeout_ms); 1644 status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req); 1645 1646 return status; 1647 } 1648 1649 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev, 1650 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1651 enum DBR_MODULE mod_id, uint8_t srng_id) 1652 { 1653 QDF_STATUS status = QDF_STATUS_SUCCESS; 1654 struct direct_buf_rx_module_param *mod_param; 1655 1656 direct_buf_rx_debug("Init DBR ring for module %d, srng %d", 1657 mod_id, srng_id); 1658 1659 if (!dbr_pdev_obj) { 1660 direct_buf_rx_err("dir buf rx object is null"); 1661 return QDF_STATUS_E_INVAL; 1662 } 1663 1664 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1665 1666 if (!mod_param) { 1667 direct_buf_rx_err("dir buf rx module param is null"); 1668 return QDF_STATUS_E_FAILURE; 1669 } 1670 1671 direct_buf_rx_debug("mod_param %pK", mod_param); 1672 1673 mod_param->mod_id = mod_id; 1674 mod_param->pdev_id = dbr_get_pdev_id( 1675 srng_id, wlan_objmgr_pdev_get_pdev_id(pdev)); 1676 mod_param->srng_id = srng_id; 1677 1678 /* Initialize DMA ring now */ 1679 status = target_if_dbr_init_srng(pdev, mod_param); 1680 if (QDF_IS_STATUS_ERROR(status)) { 1681 direct_buf_rx_err("DBR ring init failed %d", status); 1682 return status; 1683 } 1684 1685 /* Send CFG request command to firmware */ 1686 status = target_if_dbr_cfg_tgt(pdev, mod_param); 1687 if (QDF_IS_STATUS_ERROR(status)) { 1688 direct_buf_rx_err("DBR config to target failed %d", status); 1689 goto dbr_srng_init_failed; 1690 } 1691 1692 return QDF_STATUS_SUCCESS; 1693 1694 dbr_srng_init_failed: 1695 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id); 1696 return status; 1697 } 1698 1699 QDF_STATUS target_if_direct_buf_rx_module_register( 1700 struct wlan_objmgr_pdev *pdev, uint8_t mod_id, 1701 struct dbr_module_config *dbr_config, 1702 bool (*dbr_rsp_handler) 1703 (struct wlan_objmgr_pdev *pdev, 1704 struct direct_buf_rx_data *dbr_data)) 1705 { 1706 QDF_STATUS status; 1707 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1708 struct dbr_module_config *config = NULL; 1709 struct direct_buf_rx_module_param *mod_param; 1710 uint8_t srng_id; 1711 1712 if (!pdev) { 1713 direct_buf_rx_err("pdev context passed is null"); 1714 return QDF_STATUS_E_INVAL; 1715 } 1716 1717 if (!dbr_rsp_handler) { 1718 direct_buf_rx_err("Response handler is null"); 1719 return QDF_STATUS_E_INVAL; 1720 } 1721 1722 if (mod_id >= DBR_MODULE_MAX) { 1723 direct_buf_rx_err("Invalid module id"); 1724 return QDF_STATUS_E_INVAL; 1725 } 1726 1727 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1728 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1729 1730 if (!dbr_pdev_obj) { 1731 direct_buf_rx_err("dir buf rx object is null"); 1732 return QDF_STATUS_E_FAILURE; 1733 } 1734 1735 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1736 1737 if (!dbr_pdev_obj->dbr_mod_param) { 1738 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1739 return QDF_STATUS_E_FAILURE; 1740 } 1741 1742 if (mod_id >= dbr_pdev_obj->num_modules) { 1743 direct_buf_rx_err("Module %d not supported in target", mod_id); 1744 return QDF_STATUS_E_FAILURE; 1745 } 1746 1747 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1748 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1749 config = &mod_param->dbr_config; 1750 mod_param->dbr_rsp_handler = dbr_rsp_handler; 1751 *config = *dbr_config; 1752 1753 status = target_if_init_dbr_ring(pdev, dbr_pdev_obj, 1754 (enum DBR_MODULE)mod_id, 1755 srng_id); 1756 if (QDF_IS_STATUS_ERROR(status)) 1757 direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d", 1758 srng_id, status); 1759 else 1760 mod_param->registered = true; 1761 } 1762 1763 return status; 1764 } 1765 1766 QDF_STATUS target_if_direct_buf_rx_module_unregister( 1767 struct wlan_objmgr_pdev *pdev, uint8_t mod_id) 1768 { 1769 QDF_STATUS status; 1770 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1771 uint8_t srng_id; 1772 1773 if (!pdev) { 1774 direct_buf_rx_err("pdev context passed is null"); 1775 return QDF_STATUS_E_INVAL; 1776 } 1777 1778 if (mod_id >= DBR_MODULE_MAX) { 1779 direct_buf_rx_err("Invalid module id"); 1780 return QDF_STATUS_E_INVAL; 1781 } 1782 1783 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 1784 (pdev, 1785 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1786 1787 if (!dbr_pdev_obj) { 1788 direct_buf_rx_err("dir buf rx object is null"); 1789 return QDF_STATUS_E_FAILURE; 1790 } 1791 1792 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1793 1794 if (!dbr_pdev_obj->dbr_mod_param) { 1795 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1796 return QDF_STATUS_E_FAILURE; 1797 } 1798 1799 if (mod_id >= dbr_pdev_obj->num_modules) { 1800 direct_buf_rx_err("Module %d not supported in target", mod_id); 1801 return QDF_STATUS_E_FAILURE; 1802 } 1803 1804 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1805 status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 1806 mod_id, srng_id); 1807 direct_buf_rx_info("status %d", status); 1808 } 1809 1810 return status; 1811 } 1812 1813 static void *target_if_dbr_vaddr_lookup( 1814 struct direct_buf_rx_module_param *mod_param, 1815 qdf_dma_addr_t paddr, uint32_t cookie) 1816 { 1817 struct direct_buf_rx_buf_info *dbr_buf_pool; 1818 1819 dbr_buf_pool = mod_param->dbr_buf_pool; 1820 1821 if (cookie >= mod_param->dbr_ring_cfg->num_ptr) { 1822 direct_buf_rx_err("invalid cookie %d", cookie); 1823 return NULL; 1824 } 1825 1826 if (dbr_buf_pool[cookie].paddr == paddr) { 1827 return dbr_buf_pool[cookie].vaddr + 1828 dbr_buf_pool[cookie].offset; 1829 } 1830 direct_buf_rx_debug("Invalid paddr, cookie %d, pool paddr %pK, paddr %pK", 1831 cookie, (void *)dbr_buf_pool[cookie].paddr, 1832 (void *)paddr); 1833 1834 return NULL; 1835 } 1836 1837 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev, 1838 uint8_t mod_id, qdf_dma_addr_t paddr, 1839 uint32_t *cookie, uint8_t srng_id) 1840 { 1841 struct direct_buf_rx_buf_info *dbr_buf_pool; 1842 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1843 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1844 struct direct_buf_rx_module_param *mod_param; 1845 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1846 uint32_t idx; 1847 1848 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1849 if (!dbr_pdev_obj) { 1850 direct_buf_rx_err("dir buf rx object is null"); 1851 return QDF_STATUS_E_FAILURE; 1852 } 1853 1854 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1855 if (!mod_param) { 1856 direct_buf_rx_err("dir buf rx module param is null"); 1857 return QDF_STATUS_E_FAILURE; 1858 } 1859 1860 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1861 dbr_buf_pool = mod_param->dbr_buf_pool; 1862 1863 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1864 if (dbr_buf_pool[idx].paddr && 1865 dbr_buf_pool[idx].paddr == paddr) { 1866 *cookie = idx; 1867 return QDF_STATUS_SUCCESS; 1868 } 1869 } 1870 1871 return QDF_STATUS_E_FAILURE; 1872 } 1873 1874 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev, 1875 uint8_t mod_id, qdf_dma_addr_t paddr, 1876 uint32_t cookie, uint8_t srng_id) 1877 { 1878 struct direct_buf_rx_module_param *mod_param; 1879 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1880 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1881 void *vaddr; 1882 QDF_STATUS status; 1883 1884 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1885 if (!dbr_pdev_obj) { 1886 direct_buf_rx_err("dir buf rx object is null"); 1887 return QDF_STATUS_E_FAILURE; 1888 } 1889 1890 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1891 if (!mod_param) { 1892 direct_buf_rx_err("dir buf rx module param is null"); 1893 return QDF_STATUS_E_FAILURE; 1894 } 1895 1896 vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie); 1897 if (!vaddr) 1898 return QDF_STATUS_E_FAILURE; 1899 1900 status = target_if_dbr_replenish_ring(pdev, mod_param, 1901 vaddr, cookie); 1902 if (QDF_IS_STATUS_ERROR(status)) { 1903 direct_buf_rx_err("Ring replenish failed"); 1904 return QDF_STATUS_E_FAILURE; 1905 } 1906 1907 return QDF_STATUS_SUCCESS; 1908 } 1909 1910 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, 1911 struct direct_buf_rx_module_param *mod_param, 1912 struct direct_buf_rx_rsp *dbr_rsp, 1913 struct direct_buf_rx_data *dbr_data, 1914 uint8_t idx, uint32_t *cookie) 1915 { 1916 qdf_dma_addr_t paddr = 0; 1917 uint32_t addr_hi; 1918 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1919 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1920 struct wlan_objmgr_psoc *psoc; 1921 1922 psoc = wlan_pdev_get_psoc(pdev); 1923 if (!psoc) { 1924 direct_buf_rx_err("psoc is null"); 1925 return QDF_STATUS_E_FAILURE; 1926 } 1927 1928 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1929 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1930 1931 if (!dbr_psoc_obj) { 1932 direct_buf_rx_err("dir buf rx psoc object is null"); 1933 return QDF_STATUS_E_FAILURE; 1934 } 1935 1936 dbr_ring_cap = mod_param->dbr_ring_cap; 1937 addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET( 1938 dbr_rsp->dbr_entries[idx].paddr_hi); 1939 paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 | 1940 dbr_rsp->dbr_entries[idx].paddr_lo); 1941 *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( 1942 dbr_rsp->dbr_entries[idx].paddr_hi); 1943 dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); 1944 1945 if (!dbr_data->vaddr) { 1946 direct_buf_rx_debug("dbr vaddr lookup failed, cookie %d, hi %x, lo %x", 1947 *cookie, dbr_rsp->dbr_entries[idx].paddr_hi, 1948 dbr_rsp->dbr_entries[idx].paddr_lo); 1949 return QDF_STATUS_E_FAILURE; 1950 } 1951 1952 dbr_data->cookie = *cookie; 1953 dbr_data->paddr = paddr; 1954 direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK", 1955 dbr_data->cookie, dbr_data->vaddr); 1956 dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len; 1957 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr, 1958 QDF_DMA_FROM_DEVICE, 1959 dbr_ring_cap->min_buf_size); 1960 1961 return QDF_STATUS_SUCCESS; 1962 } 1963 1964 #ifdef DBR_MULTI_SRNG_ENABLE 1965 /** 1966 * dbr_get_pdev_and_srng_id() - get pdev object and srng id 1967 * 1968 * @psoc: pointer to psoc object 1969 * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid 1970 * @srng_id: pointer to return srng id 1971 * 1972 * Return : pointer to pdev 1973 */ 1974 static struct wlan_objmgr_pdev * 1975 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1976 uint8_t *srng_id) 1977 { 1978 struct wlan_objmgr_pdev *pdev; 1979 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1980 1981 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 1982 if (!pdev) { 1983 pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC, 1984 dbr_mod_id); 1985 if (pdev) { 1986 direct_buf_rx_debug("update srng id from %d to %d", 1987 *srng_id, pdev_id); 1988 *srng_id = pdev_id; 1989 } 1990 } 1991 1992 return pdev; 1993 } 1994 #else 1995 static struct wlan_objmgr_pdev * 1996 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1997 uint8_t *srng_id) 1998 { 1999 struct wlan_objmgr_pdev *pdev; 2000 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 2001 2002 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 2003 2004 return pdev; 2005 } 2006 #endif 2007 2008 #ifdef DIRECT_BUF_RX_DEBUG 2009 /** 2010 * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry 2011 * @pdev: pointer to pdev object 2012 * @mod_id: Module ID 2013 * @event: ring debug event 2014 * 2015 * Log the given event, head and tail pointers of DBR ring of the given module 2016 * into its ring debug data structure. 2017 * Also, log the timestamp at the time of logging. 2018 */ 2019 static void target_if_dbr_add_ring_debug_entry( 2020 struct wlan_objmgr_pdev *pdev, 2021 uint32_t mod_id, 2022 enum DBR_RING_DEBUG_EVENT event, 2023 uint8_t srng_id) 2024 { 2025 struct wlan_objmgr_psoc *psoc; 2026 void *hal_soc, *srng; 2027 uint32_t hp = 0, tp = 0; 2028 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2029 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2030 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2031 struct direct_buf_rx_module_debug *mod_debug; 2032 struct direct_buf_rx_module_param *mod_param; 2033 struct direct_buf_rx_ring_debug *ring_debug; 2034 struct direct_buf_rx_ring_debug_entry *entry; 2035 2036 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 2037 2038 if (!mod_debug) 2039 return; 2040 2041 psoc = wlan_pdev_get_psoc(pdev); 2042 2043 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 2044 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2045 2046 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 2047 psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2048 2049 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 2050 if (!mod_param) { 2051 direct_buf_rx_err("dir buf rx module param is null"); 2052 return; 2053 } 2054 2055 hal_soc = dbr_psoc_obj->hal_soc; 2056 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2057 srng = dbr_ring_cfg->srng; 2058 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 2059 2060 if (ring_debug->entries) { 2061 if (hal_le_srng_access_start_in_cpu_order(hal_soc, srng)) { 2062 direct_buf_rx_err("module %d - HAL srng access failed", 2063 mod_id); 2064 return; 2065 } 2066 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 2067 hal_le_srng_access_end_in_cpu_order(hal_soc, srng); 2068 tp = qdf_le32_to_cpu(tp); 2069 entry = &ring_debug->entries[ring_debug->ring_debug_idx]; 2070 2071 entry->head_idx = hp; 2072 entry->tail_idx = tp; 2073 entry->timestamp = qdf_get_log_timestamp(); 2074 entry->event = event; 2075 2076 ring_debug->ring_debug_idx++; 2077 if (ring_debug->ring_debug_idx == 2078 ring_debug->num_ring_debug_entries) 2079 ring_debug->ring_debug_idx = 0; 2080 } 2081 } 2082 2083 #else 2084 static void target_if_dbr_add_ring_debug_entry( 2085 struct wlan_objmgr_pdev *pdev, 2086 uint32_t mod_id, 2087 enum DBR_RING_DEBUG_EVENT event, 2088 uint8_t srng_id) 2089 { 2090 } 2091 #endif /* DIRECT_BUF_RX_DEBUG */ 2092 2093 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, 2094 uint8_t *data_buf, 2095 uint32_t data_len) 2096 { 2097 int ret = 0; 2098 uint8_t i = 0; 2099 QDF_STATUS status; 2100 uint32_t cookie = 0; 2101 struct direct_buf_rx_rsp dbr_rsp = {0}; 2102 struct direct_buf_rx_data dbr_data = {0}; 2103 struct wlan_objmgr_psoc *psoc; 2104 struct wlan_objmgr_pdev *pdev; 2105 struct direct_buf_rx_buf_info *dbr_buf_pool; 2106 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2107 struct direct_buf_rx_module_param *mod_param; 2108 struct wmi_unified *wmi_handle; 2109 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 2110 uint8_t srng_id = 0; 2111 2112 direct_buf_rx_enter(); 2113 2114 psoc = target_if_get_psoc_from_scn_hdl(scn); 2115 if (!psoc) { 2116 direct_buf_rx_err("psoc is null"); 2117 return QDF_STATUS_E_FAILURE; 2118 } 2119 2120 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 2121 if (!wmi_handle) { 2122 direct_buf_rx_err("WMI handle is null"); 2123 return QDF_STATUS_E_FAILURE; 2124 } 2125 2126 if (wmi_extract_dbr_buf_release_fixed( 2127 wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) { 2128 direct_buf_rx_err("unable to extract DBR rsp fixed param"); 2129 return QDF_STATUS_E_FAILURE; 2130 } 2131 2132 direct_buf_rx_debug("Num buf release entry = %d", 2133 dbr_rsp.num_buf_release_entry); 2134 2135 pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id, 2136 &srng_id); 2137 if (!pdev || (srng_id >= DBR_SRNG_NUM)) { 2138 direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d", 2139 pdev, srng_id); 2140 return QDF_STATUS_E_INVAL; 2141 } 2142 2143 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2144 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2145 2146 if (!dbr_pdev_obj) { 2147 direct_buf_rx_err("dir buf rx object is null"); 2148 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2149 return QDF_STATUS_E_FAILURE; 2150 } 2151 2152 if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) { 2153 direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id); 2154 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2155 return QDF_STATUS_E_FAILURE; 2156 } 2157 mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]); 2158 2159 if (!mod_param) { 2160 direct_buf_rx_err("dir buf rx module param is null"); 2161 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2162 return QDF_STATUS_E_FAILURE; 2163 } 2164 2165 dbr_buf_pool = mod_param->dbr_buf_pool; 2166 dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry * 2167 sizeof(struct direct_buf_rx_entry)); 2168 if (!dbr_rsp.dbr_entries) { 2169 direct_buf_rx_err("invalid dbr_entries"); 2170 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2171 return QDF_STATUS_E_FAILURE; 2172 } 2173 2174 if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) { 2175 direct_buf_rx_err("More than expected number of metadata"); 2176 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2177 return QDF_STATUS_E_FAILURE; 2178 } 2179 2180 for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { 2181 if (wmi_extract_dbr_buf_release_entry( 2182 wmi_handle, data_buf, i, 2183 &dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) { 2184 direct_buf_rx_err("Unable to extract DBR buf entry %d", 2185 i+1); 2186 qdf_mem_free(dbr_rsp.dbr_entries); 2187 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2188 return QDF_STATUS_E_FAILURE; 2189 } 2190 status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp, 2191 &dbr_data, i, &cookie); 2192 2193 if (QDF_IS_STATUS_ERROR(status)) { 2194 direct_buf_rx_err("DBR data get failed"); 2195 qdf_mem_free(dbr_rsp.dbr_entries); 2196 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2197 return QDF_STATUS_E_FAILURE; 2198 } 2199 2200 dbr_data.meta_data_valid = false; 2201 if (i < dbr_rsp.num_meta_data_entry) { 2202 if (wmi_extract_dbr_buf_metadata( 2203 wmi_handle, data_buf, i, 2204 &dbr_data.meta_data) == QDF_STATUS_SUCCESS) 2205 dbr_data.meta_data_valid = true; 2206 } 2207 2208 target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id, 2209 DBR_RING_DEBUG_EVENT_RX, 2210 srng_id); 2211 if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { 2212 status = target_if_dbr_replenish_ring(pdev, mod_param, 2213 dbr_data.vaddr, 2214 cookie); 2215 2216 target_if_dbr_add_ring_debug_entry( 2217 pdev, dbr_rsp.mod_id, 2218 DBR_RING_DEBUG_EVENT_REPLENISH_RING, 2219 srng_id); 2220 2221 if (QDF_IS_STATUS_ERROR(status)) { 2222 direct_buf_rx_err("Ring replenish failed"); 2223 qdf_mem_free(dbr_rsp.dbr_entries); 2224 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2225 return QDF_STATUS_E_FAILURE; 2226 } 2227 } 2228 } 2229 2230 qdf_mem_free(dbr_rsp.dbr_entries); 2231 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 2232 2233 return ret; 2234 } 2235 2236 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev, 2237 struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 2238 struct direct_buf_rx_module_param *mod_param) 2239 { 2240 uint32_t idx; 2241 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2242 struct direct_buf_rx_ring_cap *dbr_ring_cap; 2243 struct direct_buf_rx_buf_info *dbr_buf_pool; 2244 2245 direct_buf_rx_enter(); 2246 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2247 dbr_ring_cap = mod_param->dbr_ring_cap; 2248 dbr_buf_pool = mod_param->dbr_buf_pool; 2249 2250 direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK", 2251 dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool); 2252 2253 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 2254 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, 2255 (qdf_dma_addr_t)dbr_buf_pool[idx].paddr, 2256 QDF_DMA_FROM_DEVICE, 2257 dbr_ring_cap->min_buf_size); 2258 target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size, 2259 dbr_buf_pool[idx].vaddr, 2260 dbr_buf_pool[idx].offset, 2261 dbr_ring_cap->min_buf_align, 2262 mod_param->mod_id); 2263 } 2264 2265 return QDF_STATUS_SUCCESS; 2266 } 2267 2268 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, 2269 struct direct_buf_rx_module_param *mod_param) 2270 { 2271 struct wlan_objmgr_psoc *psoc; 2272 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2273 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2274 2275 direct_buf_rx_enter(); 2276 psoc = wlan_pdev_get_psoc(pdev); 2277 if (!psoc) { 2278 direct_buf_rx_err("psoc is null"); 2279 return QDF_STATUS_E_FAILURE; 2280 } 2281 2282 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2283 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2284 2285 if (!dbr_psoc_obj) { 2286 direct_buf_rx_err("dir buf rx psoc object is null"); 2287 return QDF_STATUS_E_FAILURE; 2288 } 2289 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 2290 2291 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2292 if (dbr_ring_cfg) { 2293 target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); 2294 hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); 2295 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 2296 dbr_psoc_obj->osdev->dev, 2297 dbr_ring_cfg->ring_alloc_size, 2298 dbr_ring_cfg->base_vaddr_unaligned, 2299 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 2300 } 2301 2302 return QDF_STATUS_SUCCESS; 2303 } 2304 2305 static QDF_STATUS target_if_dbr_deinit_srng( 2306 struct wlan_objmgr_pdev *pdev, 2307 struct direct_buf_rx_module_param *mod_param) 2308 { 2309 struct direct_buf_rx_buf_info *dbr_buf_pool; 2310 2311 direct_buf_rx_enter(); 2312 dbr_buf_pool = mod_param->dbr_buf_pool; 2313 direct_buf_rx_debug("dbr buf pool %pK", dbr_buf_pool); 2314 target_if_dbr_deinit_ring(pdev, mod_param); 2315 if (mod_param->dbr_buf_pool) 2316 qdf_mem_free(dbr_buf_pool); 2317 mod_param->dbr_buf_pool = NULL; 2318 2319 return QDF_STATUS_SUCCESS; 2320 } 2321 2322 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev, 2323 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 2324 enum DBR_MODULE mod_id, uint8_t srng_id) 2325 { 2326 struct direct_buf_rx_module_param *mod_param; 2327 2328 direct_buf_rx_enter(); 2329 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 2330 2331 if (!mod_param) { 2332 direct_buf_rx_err("dir buf rx module param is null"); 2333 return QDF_STATUS_E_FAILURE; 2334 } 2335 direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK", 2336 mod_param, mod_param->dbr_ring_cap); 2337 2338 if (!mod_param->registered) { 2339 direct_buf_rx_err("module(%d) srng(%d) was not registered", 2340 mod_id, srng_id); 2341 return QDF_STATUS_SUCCESS; 2342 } 2343 2344 target_if_dbr_deinit_srng(pdev, mod_param); 2345 if (mod_param->dbr_ring_cap) 2346 qdf_mem_free(mod_param->dbr_ring_cap); 2347 mod_param->dbr_ring_cap = NULL; 2348 if (mod_param->dbr_ring_cfg) 2349 qdf_mem_free(mod_param->dbr_ring_cfg); 2350 mod_param->dbr_ring_cfg = NULL; 2351 2352 mod_param->registered = false; 2353 2354 return QDF_STATUS_SUCCESS; 2355 } 2356 2357 QDF_STATUS target_if_direct_buf_rx_register_events( 2358 struct wlan_objmgr_psoc *psoc) 2359 { 2360 QDF_STATUS ret; 2361 2362 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2363 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2364 return QDF_STATUS_E_INVAL; 2365 } 2366 2367 ret = wmi_unified_register_event_handler( 2368 get_wmi_unified_hdl_from_psoc(psoc), 2369 wmi_dma_buf_release_event_id, 2370 target_if_direct_buf_rx_rsp_event_handler, 2371 WMI_RX_UMAC_CTX); 2372 2373 if (QDF_IS_STATUS_ERROR(ret)) 2374 direct_buf_rx_debug("event handler not supported, ret=%d", ret); 2375 2376 return QDF_STATUS_SUCCESS; 2377 } 2378 2379 QDF_STATUS target_if_direct_buf_rx_unregister_events( 2380 struct wlan_objmgr_psoc *psoc) 2381 { 2382 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2383 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2384 return QDF_STATUS_E_INVAL; 2385 } 2386 2387 wmi_unified_unregister_event_handler( 2388 get_wmi_unified_hdl_from_psoc(psoc), 2389 wmi_dma_buf_release_event_id); 2390 2391 return QDF_STATUS_SUCCESS; 2392 } 2393 2394 QDF_STATUS target_if_direct_buf_rx_print_ring_stat( 2395 struct wlan_objmgr_pdev *pdev) 2396 { 2397 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2398 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2399 struct wlan_objmgr_psoc *psoc; 2400 void *srng, *hal_soc; 2401 uint32_t hp = 0, tp = 0; 2402 struct direct_buf_rx_module_param *mod_param; 2403 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2404 uint8_t num_modules, mod_idx; 2405 uint8_t srng_id; 2406 2407 if (!pdev) { 2408 direct_buf_rx_err("pdev is null"); 2409 return QDF_STATUS_E_INVAL; 2410 } 2411 2412 psoc = wlan_pdev_get_psoc(pdev); 2413 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2414 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2415 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2416 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2417 hal_soc = dbr_psoc_obj->hal_soc; 2418 num_modules = dbr_pdev_obj->num_modules; 2419 direct_buf_rx_debug("--------------------------------------------------"); 2420 direct_buf_rx_debug("| Module ID | Module | Head Idx | Tail Idx |"); 2421 direct_buf_rx_debug("--------------------------------------------------"); 2422 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 2423 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 2424 mod_param = 2425 &dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id]; 2426 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2427 if (!dbr_ring_cfg) { 2428 direct_buf_rx_info("dbr_ring_cfg is NULL"); 2429 direct_buf_rx_info("mod id %d mod %s", mod_idx, 2430 g_dbr_module_name[mod_idx]. 2431 module_name_str); 2432 continue; 2433 } 2434 srng = dbr_ring_cfg->srng; 2435 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 2436 tp = qdf_le32_to_cpu(tp); 2437 direct_buf_rx_debug("|%11d|%14s|%10x|%10x|", 2438 mod_idx, g_dbr_module_name[mod_idx]. 2439 module_name_str, 2440 hp, tp); 2441 } 2442 } 2443 direct_buf_rx_debug("--------------------------------------------------"); 2444 2445 return QDF_STATUS_SUCCESS; 2446 } 2447 2448 QDF_STATUS 2449 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, 2450 struct module_ring_params *param, 2451 uint8_t mod_id, uint8_t srng_id) 2452 { 2453 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2454 struct direct_buf_rx_module_param *dbr_mod_param; 2455 2456 if (!pdev) { 2457 direct_buf_rx_err("pdev context passed is null"); 2458 return QDF_STATUS_E_INVAL; 2459 } 2460 2461 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 2462 (pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2463 2464 if (!dbr_pdev_obj) { 2465 direct_buf_rx_err("dir buf rx object is null"); 2466 return QDF_STATUS_E_FAILURE; 2467 } 2468 2469 if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) { 2470 direct_buf_rx_err("invalid params, mod id %d, srng id %d", 2471 mod_id, srng_id); 2472 return QDF_STATUS_E_INVAL; 2473 } 2474 2475 dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 2476 param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr; 2477 param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size; 2478 2479 return QDF_STATUS_SUCCESS; 2480 } 2481