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