1 /* 2 * Copyright (c) 2017-2020 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_debug("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_debug("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_debug("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_debug("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 uint32_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 = qdf_cpu_to_le32(dw_lo); 1071 ring_entry++; 1072 *ring_entry = qdf_cpu_to_le32(dw_hi); 1073 hal_srng_access_end(hal_soc, srng); 1074 1075 return QDF_STATUS_SUCCESS; 1076 } 1077 1078 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev, 1079 struct direct_buf_rx_module_param *mod_param) 1080 { 1081 uint32_t idx; 1082 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1083 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1084 struct direct_buf_rx_buf_info *dbr_buf_pool; 1085 QDF_STATUS status; 1086 1087 direct_buf_rx_enter(); 1088 1089 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1090 dbr_ring_cap = mod_param->dbr_ring_cap; 1091 dbr_buf_pool = mod_param->dbr_buf_pool; 1092 1093 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1094 void *buf_vaddr_unaligned = NULL, *buf_vaddr_aligned; 1095 dma_addr_t buf_paddr_aligned, buf_paddr_unaligned; 1096 1097 buf_vaddr_aligned = qdf_aligned_malloc( 1098 &dbr_ring_cap->min_buf_size, &buf_vaddr_unaligned, 1099 &buf_paddr_unaligned, &buf_paddr_aligned, 1100 dbr_ring_cap->min_buf_align); 1101 1102 if (!buf_vaddr_aligned) { 1103 direct_buf_rx_err("dir buf rx ring alloc failed"); 1104 return QDF_STATUS_E_NOMEM; 1105 } 1106 dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned; 1107 dbr_buf_pool[idx].offset = buf_vaddr_aligned - 1108 buf_vaddr_unaligned; 1109 dbr_buf_pool[idx].cookie = idx; 1110 status = target_if_dbr_replenish_ring(pdev, mod_param, 1111 buf_vaddr_aligned, idx); 1112 if (QDF_IS_STATUS_ERROR(status)) { 1113 direct_buf_rx_err("replenish failed with status : %d", 1114 status); 1115 qdf_mem_free(buf_vaddr_unaligned); 1116 return QDF_STATUS_E_FAILURE; 1117 } 1118 } 1119 1120 return QDF_STATUS_SUCCESS; 1121 } 1122 1123 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev, 1124 struct direct_buf_rx_module_param *mod_param) 1125 { 1126 void *srng; 1127 uint32_t num_entries, ring_alloc_size, max_entries, entry_size; 1128 qdf_dma_addr_t paddr; 1129 struct hal_srng_params ring_params = {0}; 1130 struct wlan_objmgr_psoc *psoc; 1131 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1132 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1133 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1134 QDF_STATUS status; 1135 1136 direct_buf_rx_enter(); 1137 1138 psoc = wlan_pdev_get_psoc(pdev); 1139 1140 if (!psoc) { 1141 direct_buf_rx_err("psoc is null"); 1142 return QDF_STATUS_E_FAILURE; 1143 } 1144 1145 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1146 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1147 1148 if (!dbr_psoc_obj) { 1149 direct_buf_rx_err("dir buf rx psoc object is null"); 1150 return QDF_STATUS_E_FAILURE; 1151 } 1152 1153 if (!dbr_psoc_obj->hal_soc || 1154 !dbr_psoc_obj->osdev) { 1155 direct_buf_rx_err("dir buf rx target attach failed"); 1156 return QDF_STATUS_E_FAILURE; 1157 } 1158 1159 max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc, 1160 DIR_BUF_RX_DMA_SRC); 1161 entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc, 1162 DIR_BUF_RX_DMA_SRC); 1163 direct_buf_rx_debug("Max Entries = %d", max_entries); 1164 direct_buf_rx_debug("Entry Size = %d", entry_size); 1165 1166 status = populate_dbr_cap_mod_param(pdev, mod_param); 1167 if (QDF_IS_STATUS_ERROR(status)) { 1168 direct_buf_rx_err("Module cap population failed"); 1169 return QDF_STATUS_E_FAILURE; 1170 } 1171 1172 dbr_ring_cap = mod_param->dbr_ring_cap; 1173 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1174 num_entries = dbr_ring_cap->ring_elems_min > max_entries ? 1175 max_entries : dbr_ring_cap->ring_elems_min; 1176 direct_buf_rx_debug("Num entries = %d", num_entries); 1177 dbr_ring_cfg->num_ptr = num_entries; 1178 mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof( 1179 struct direct_buf_rx_buf_info)); 1180 if (!mod_param->dbr_buf_pool) 1181 return QDF_STATUS_E_NOMEM; 1182 1183 ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1; 1184 dbr_ring_cfg->ring_alloc_size = ring_alloc_size; 1185 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 1186 dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent( 1187 dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size, 1188 &paddr); 1189 direct_buf_rx_debug("vaddr aligned allocated"); 1190 dbr_ring_cfg->base_paddr_unaligned = paddr; 1191 if (!dbr_ring_cfg->base_vaddr_unaligned) { 1192 direct_buf_rx_err("dir buf rx vaddr alloc failed"); 1193 qdf_mem_free(mod_param->dbr_buf_pool); 1194 return QDF_STATUS_E_NOMEM; 1195 } 1196 1197 /* Alignment is defined to 8 for now. Will be advertised by FW */ 1198 dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup( 1199 (uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned, 1200 DBR_RING_BASE_ALIGN); 1201 ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned; 1202 dbr_ring_cfg->base_paddr_aligned = qdf_roundup( 1203 (uint64_t)dbr_ring_cfg->base_paddr_unaligned, 1204 DBR_RING_BASE_ALIGN); 1205 ring_params.ring_base_paddr = 1206 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned; 1207 ring_params.num_entries = num_entries; 1208 srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC, 1209 mod_param->mod_id, 1210 mod_param->pdev_id, &ring_params); 1211 1212 if (!srng) { 1213 direct_buf_rx_err("srng setup failed"); 1214 qdf_mem_free(mod_param->dbr_buf_pool); 1215 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1216 dbr_psoc_obj->osdev->dev, 1217 ring_alloc_size, 1218 dbr_ring_cfg->base_vaddr_unaligned, 1219 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1220 return QDF_STATUS_E_FAILURE; 1221 } 1222 dbr_ring_cfg->srng = srng; 1223 dbr_ring_cfg->tail_idx_addr = 1224 hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng); 1225 dbr_ring_cfg->head_idx_addr = 1226 hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng); 1227 dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size; 1228 1229 return target_if_dbr_fill_ring(pdev, mod_param); 1230 } 1231 1232 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev, 1233 struct direct_buf_rx_module_param *mod_param) 1234 { 1235 QDF_STATUS status; 1236 1237 direct_buf_rx_debug("Init DBR srng"); 1238 1239 if (!mod_param) { 1240 direct_buf_rx_err("dir buf rx module param is null"); 1241 return QDF_STATUS_E_INVAL; 1242 } 1243 1244 mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof( 1245 struct direct_buf_rx_ring_cap)); 1246 1247 if (!mod_param->dbr_ring_cap) 1248 return QDF_STATUS_E_NOMEM; 1249 1250 /* Allocate memory for DBR Ring Config */ 1251 mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof( 1252 struct direct_buf_rx_ring_cfg)); 1253 1254 if (!mod_param->dbr_ring_cfg) { 1255 qdf_mem_free(mod_param->dbr_ring_cap); 1256 return QDF_STATUS_E_NOMEM; 1257 } 1258 1259 status = target_if_dbr_init_ring(pdev, mod_param); 1260 1261 if (QDF_IS_STATUS_ERROR(status)) { 1262 direct_buf_rx_err("DBR ring init failed"); 1263 qdf_mem_free(mod_param->dbr_ring_cfg); 1264 qdf_mem_free(mod_param->dbr_ring_cap); 1265 return QDF_STATUS_E_FAILURE; 1266 } 1267 1268 return QDF_STATUS_SUCCESS; 1269 } 1270 1271 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, 1272 struct direct_buf_rx_module_param *mod_param) 1273 { 1274 QDF_STATUS status; 1275 struct wlan_objmgr_psoc *psoc; 1276 wmi_unified_t wmi_hdl; 1277 struct direct_buf_rx_cfg_req dbr_cfg_req = {0}; 1278 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1279 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1280 struct dbr_module_config *dbr_config; 1281 1282 direct_buf_rx_enter(); 1283 1284 psoc = wlan_pdev_get_psoc(pdev); 1285 if (!psoc) { 1286 direct_buf_rx_err("psoc is null"); 1287 return QDF_STATUS_E_FAILURE; 1288 } 1289 1290 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1291 dbr_ring_cap = mod_param->dbr_ring_cap; 1292 dbr_config = &mod_param->dbr_config; 1293 wmi_hdl = lmac_get_pdev_wmi_handle(pdev); 1294 if (!wmi_hdl) { 1295 direct_buf_rx_err("WMI handle null. Can't send WMI CMD"); 1296 return QDF_STATUS_E_INVAL; 1297 } 1298 1299 direct_buf_rx_debug("Sending DBR Ring CFG to target"); 1300 dbr_cfg_req.pdev_id = mod_param->pdev_id; 1301 /* Module ID numbering starts from 1 in FW. need to fix it */ 1302 dbr_cfg_req.mod_id = mod_param->mod_id; 1303 dbr_cfg_req.base_paddr_lo = (uint64_t)dbr_ring_cfg->base_paddr_aligned 1304 & 0xFFFFFFFF; 1305 dbr_cfg_req.base_paddr_hi = (uint64_t)dbr_ring_cfg->base_paddr_aligned 1306 & 0xFFFFFFFF00000000; 1307 dbr_cfg_req.head_idx_paddr_lo = (uint64_t)dbr_ring_cfg->head_idx_addr 1308 & 0xFFFFFFFF; 1309 dbr_cfg_req.head_idx_paddr_hi = (uint64_t)dbr_ring_cfg->head_idx_addr 1310 & 0xFFFFFFFF00000000; 1311 dbr_cfg_req.tail_idx_paddr_lo = (uint64_t)dbr_ring_cfg->tail_idx_addr 1312 & 0xFFFFFFFF; 1313 dbr_cfg_req.tail_idx_paddr_hi = (uint64_t)dbr_ring_cfg->tail_idx_addr 1314 & 0xFFFFFFFF00000000; 1315 dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min; 1316 dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size; 1317 dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event; 1318 dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms; 1319 direct_buf_rx_debug("pdev id %d mod id %d base addr lo %x\n" 1320 "base addr hi %x head idx addr lo %x\n" 1321 "head idx addr hi %x tail idx addr lo %x\n" 1322 "tail idx addr hi %x num ptr %d\n" 1323 "num resp %d event timeout %d\n", 1324 dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id, 1325 dbr_cfg_req.base_paddr_lo, 1326 dbr_cfg_req.base_paddr_hi, 1327 dbr_cfg_req.head_idx_paddr_lo, 1328 dbr_cfg_req.head_idx_paddr_hi, 1329 dbr_cfg_req.tail_idx_paddr_lo, 1330 dbr_cfg_req.tail_idx_paddr_hi, 1331 dbr_cfg_req.num_elems, 1332 dbr_cfg_req.num_resp_per_event, 1333 dbr_cfg_req.event_timeout_ms); 1334 status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req); 1335 1336 return status; 1337 } 1338 1339 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev, 1340 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1341 enum DBR_MODULE mod_id, uint8_t srng_id) 1342 { 1343 QDF_STATUS status = QDF_STATUS_SUCCESS; 1344 struct direct_buf_rx_module_param *mod_param; 1345 1346 direct_buf_rx_debug("Init DBR ring for module %d, srng %d", 1347 mod_id, srng_id); 1348 1349 if (!dbr_pdev_obj) { 1350 direct_buf_rx_err("dir buf rx object is null"); 1351 return QDF_STATUS_E_INVAL; 1352 } 1353 1354 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1355 1356 if (!mod_param) { 1357 direct_buf_rx_err("dir buf rx module param is null"); 1358 return QDF_STATUS_E_FAILURE; 1359 } 1360 1361 direct_buf_rx_debug("mod_param %pK", mod_param); 1362 1363 mod_param->mod_id = mod_id; 1364 mod_param->pdev_id = dbr_get_pdev_id( 1365 srng_id, wlan_objmgr_pdev_get_pdev_id(pdev)); 1366 mod_param->srng_id = srng_id; 1367 1368 /* Initialize DMA ring now */ 1369 status = target_if_dbr_init_srng(pdev, mod_param); 1370 if (QDF_IS_STATUS_ERROR(status)) { 1371 direct_buf_rx_err("DBR ring init failed %d", status); 1372 return status; 1373 } 1374 1375 /* Send CFG request command to firmware */ 1376 status = target_if_dbr_cfg_tgt(pdev, mod_param); 1377 if (QDF_IS_STATUS_ERROR(status)) { 1378 direct_buf_rx_err("DBR config to target failed %d", status); 1379 goto dbr_srng_init_failed; 1380 } 1381 1382 return QDF_STATUS_SUCCESS; 1383 1384 dbr_srng_init_failed: 1385 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id); 1386 return status; 1387 } 1388 1389 QDF_STATUS target_if_direct_buf_rx_module_register( 1390 struct wlan_objmgr_pdev *pdev, uint8_t mod_id, 1391 struct dbr_module_config *dbr_config, 1392 bool (*dbr_rsp_handler) 1393 (struct wlan_objmgr_pdev *pdev, 1394 struct direct_buf_rx_data *dbr_data)) 1395 { 1396 QDF_STATUS status; 1397 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1398 struct dbr_module_config *config = NULL; 1399 struct direct_buf_rx_module_param *mod_param; 1400 uint8_t srng_id; 1401 1402 if (!pdev) { 1403 direct_buf_rx_err("pdev context passed is null"); 1404 return QDF_STATUS_E_INVAL; 1405 } 1406 1407 if (!dbr_rsp_handler) { 1408 direct_buf_rx_err("Response handler is null"); 1409 return QDF_STATUS_E_INVAL; 1410 } 1411 1412 if (mod_id >= DBR_MODULE_MAX) { 1413 direct_buf_rx_err("Invalid module id"); 1414 return QDF_STATUS_E_INVAL; 1415 } 1416 1417 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1418 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1419 1420 if (!dbr_pdev_obj) { 1421 direct_buf_rx_err("dir buf rx object is null"); 1422 return QDF_STATUS_E_FAILURE; 1423 } 1424 1425 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1426 1427 if (!dbr_pdev_obj->dbr_mod_param) { 1428 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1429 return QDF_STATUS_E_FAILURE; 1430 } 1431 1432 if (mod_id >= dbr_pdev_obj->num_modules) { 1433 direct_buf_rx_err("Module %d not supported in target", mod_id); 1434 return QDF_STATUS_E_FAILURE; 1435 } 1436 1437 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1438 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1439 config = &mod_param->dbr_config; 1440 mod_param->dbr_rsp_handler = dbr_rsp_handler; 1441 *config = *dbr_config; 1442 1443 status = target_if_init_dbr_ring(pdev, dbr_pdev_obj, 1444 (enum DBR_MODULE)mod_id, 1445 srng_id); 1446 if (QDF_IS_STATUS_ERROR(status)) 1447 direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d", 1448 srng_id, status); 1449 } 1450 1451 return status; 1452 } 1453 1454 QDF_STATUS target_if_direct_buf_rx_module_unregister( 1455 struct wlan_objmgr_pdev *pdev, uint8_t mod_id) 1456 { 1457 QDF_STATUS status; 1458 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1459 uint8_t srng_id; 1460 1461 if (!pdev) { 1462 direct_buf_rx_err("pdev context passed is null"); 1463 return QDF_STATUS_E_INVAL; 1464 } 1465 1466 if (mod_id >= DBR_MODULE_MAX) { 1467 direct_buf_rx_err("Invalid module id"); 1468 return QDF_STATUS_E_INVAL; 1469 } 1470 1471 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 1472 (pdev, 1473 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1474 1475 if (!dbr_pdev_obj) { 1476 direct_buf_rx_err("dir buf rx object is null"); 1477 return QDF_STATUS_E_FAILURE; 1478 } 1479 1480 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1481 1482 if (!dbr_pdev_obj->dbr_mod_param) { 1483 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1484 return QDF_STATUS_E_FAILURE; 1485 } 1486 1487 if (mod_id >= dbr_pdev_obj->num_modules) { 1488 direct_buf_rx_err("Module %d not supported in target", mod_id); 1489 return QDF_STATUS_E_FAILURE; 1490 } 1491 1492 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1493 status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 1494 mod_id, srng_id); 1495 direct_buf_rx_info("status %d", status); 1496 } 1497 1498 return status; 1499 } 1500 1501 static void *target_if_dbr_vaddr_lookup( 1502 struct direct_buf_rx_module_param *mod_param, 1503 qdf_dma_addr_t paddr, uint32_t cookie) 1504 { 1505 struct direct_buf_rx_buf_info *dbr_buf_pool; 1506 1507 dbr_buf_pool = mod_param->dbr_buf_pool; 1508 1509 if (dbr_buf_pool[cookie].paddr == paddr) { 1510 return dbr_buf_pool[cookie].vaddr + 1511 dbr_buf_pool[cookie].offset; 1512 } 1513 1514 direct_buf_rx_debug("Incorrect paddr found on cookie slot"); 1515 return NULL; 1516 } 1517 1518 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev, 1519 uint8_t mod_id, qdf_dma_addr_t paddr, 1520 uint32_t *cookie, uint8_t srng_id) 1521 { 1522 struct direct_buf_rx_buf_info *dbr_buf_pool; 1523 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1524 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1525 struct direct_buf_rx_module_param *mod_param; 1526 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1527 uint32_t idx; 1528 1529 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1530 if (!dbr_pdev_obj) { 1531 direct_buf_rx_err("dir buf rx object is null"); 1532 return QDF_STATUS_E_FAILURE; 1533 } 1534 1535 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1536 if (!mod_param) { 1537 direct_buf_rx_err("dir buf rx module param is null"); 1538 return QDF_STATUS_E_FAILURE; 1539 } 1540 1541 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1542 dbr_buf_pool = mod_param->dbr_buf_pool; 1543 1544 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1545 if (dbr_buf_pool[idx].paddr && 1546 dbr_buf_pool[idx].paddr == paddr) { 1547 *cookie = idx; 1548 return QDF_STATUS_SUCCESS; 1549 } 1550 } 1551 1552 return QDF_STATUS_E_FAILURE; 1553 } 1554 1555 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev, 1556 uint8_t mod_id, qdf_dma_addr_t paddr, 1557 uint32_t cookie, uint8_t srng_id) 1558 { 1559 struct direct_buf_rx_module_param *mod_param; 1560 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1561 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1562 void *vaddr; 1563 QDF_STATUS status; 1564 1565 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1566 if (!dbr_pdev_obj) { 1567 direct_buf_rx_err("dir buf rx object is null"); 1568 return QDF_STATUS_E_FAILURE; 1569 } 1570 1571 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1572 if (!mod_param) { 1573 direct_buf_rx_err("dir buf rx module param is null"); 1574 return QDF_STATUS_E_FAILURE; 1575 } 1576 1577 vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie); 1578 if (!vaddr) 1579 return QDF_STATUS_E_FAILURE; 1580 1581 status = target_if_dbr_replenish_ring(pdev, mod_param, 1582 vaddr, cookie); 1583 if (QDF_IS_STATUS_ERROR(status)) { 1584 direct_buf_rx_err("Ring replenish failed"); 1585 return QDF_STATUS_E_FAILURE; 1586 } 1587 1588 return QDF_STATUS_SUCCESS; 1589 } 1590 1591 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, 1592 struct direct_buf_rx_module_param *mod_param, 1593 struct direct_buf_rx_rsp *dbr_rsp, 1594 struct direct_buf_rx_data *dbr_data, 1595 uint8_t idx, uint32_t *cookie) 1596 { 1597 qdf_dma_addr_t paddr = 0; 1598 uint32_t addr_hi; 1599 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1600 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1601 struct wlan_objmgr_psoc *psoc; 1602 1603 psoc = wlan_pdev_get_psoc(pdev); 1604 if (!psoc) { 1605 direct_buf_rx_err("psoc is null"); 1606 return QDF_STATUS_E_FAILURE; 1607 } 1608 1609 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1610 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1611 1612 if (!dbr_psoc_obj) { 1613 direct_buf_rx_err("dir buf rx psoc object is null"); 1614 return QDF_STATUS_E_FAILURE; 1615 } 1616 1617 dbr_ring_cap = mod_param->dbr_ring_cap; 1618 addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET( 1619 dbr_rsp->dbr_entries[idx].paddr_hi); 1620 paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 | 1621 dbr_rsp->dbr_entries[idx].paddr_lo); 1622 *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( 1623 dbr_rsp->dbr_entries[idx].paddr_hi); 1624 dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); 1625 1626 if (!dbr_data->vaddr) { 1627 direct_buf_rx_err("dbr vaddr lookup failed, vaddr NULL"); 1628 return QDF_STATUS_E_FAILURE; 1629 } 1630 1631 dbr_data->cookie = *cookie; 1632 dbr_data->paddr = paddr; 1633 direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK", 1634 dbr_data->cookie, dbr_data->vaddr); 1635 dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len; 1636 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr, 1637 QDF_DMA_FROM_DEVICE, 1638 dbr_ring_cap->min_buf_size); 1639 1640 return QDF_STATUS_SUCCESS; 1641 } 1642 1643 #ifdef DBR_MULTI_SRNG_ENABLE 1644 /** 1645 * dbr_get_pdev_and_srng_id() - get pdev object and srng id 1646 * 1647 * @psoc: pointer to psoc object 1648 * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid 1649 * @srng_id: pointer to return srng id 1650 * 1651 * Return : pointer to pdev 1652 */ 1653 static struct wlan_objmgr_pdev * 1654 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1655 uint8_t *srng_id) 1656 { 1657 struct wlan_objmgr_pdev *pdev; 1658 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1659 1660 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 1661 if (!pdev) { 1662 pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC, 1663 dbr_mod_id); 1664 if (pdev) { 1665 direct_buf_rx_debug("update srng id from %d to %d", 1666 *srng_id, pdev_id); 1667 *srng_id = pdev_id; 1668 } 1669 } 1670 1671 return pdev; 1672 } 1673 #else 1674 static struct wlan_objmgr_pdev * 1675 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1676 uint8_t *srng_id) 1677 { 1678 struct wlan_objmgr_pdev *pdev; 1679 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1680 1681 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 1682 1683 return pdev; 1684 } 1685 #endif 1686 1687 #ifdef DIRECT_BUF_RX_DEBUG 1688 /** 1689 * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry 1690 * @pdev: pointer to pdev object 1691 * @mod_id: Module ID 1692 * @event: ring debug event 1693 * 1694 * Log the given event, head and tail pointers of DBR ring of the given module 1695 * into its ring debug data structure. 1696 * Also, log the timestamp at the time of logging. 1697 */ 1698 static void target_if_dbr_add_ring_debug_entry( 1699 struct wlan_objmgr_pdev *pdev, 1700 uint32_t mod_id, 1701 enum DBR_RING_DEBUG_EVENT event, 1702 uint8_t srng_id) 1703 { 1704 struct wlan_objmgr_psoc *psoc; 1705 void *hal_soc, *srng; 1706 uint32_t hp = 0, tp = 0; 1707 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1708 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1709 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1710 struct direct_buf_rx_module_debug *mod_debug; 1711 struct direct_buf_rx_module_param *mod_param; 1712 struct direct_buf_rx_ring_debug *ring_debug; 1713 struct direct_buf_rx_ring_debug_entry *entry; 1714 1715 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1716 1717 if (!mod_debug) 1718 return; 1719 1720 psoc = wlan_pdev_get_psoc(pdev); 1721 1722 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 1723 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1724 1725 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 1726 psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1727 1728 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1729 if (!mod_param) { 1730 direct_buf_rx_err("dir buf rx module param is null"); 1731 return; 1732 } 1733 1734 hal_soc = dbr_psoc_obj->hal_soc; 1735 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1736 srng = dbr_ring_cfg->srng; 1737 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 1738 1739 if (ring_debug->entries) { 1740 if (hal_srng_access_start(hal_soc, srng)) { 1741 direct_buf_rx_err("module %d - HAL srng access failed", 1742 mod_id); 1743 return; 1744 } 1745 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 1746 hal_srng_access_end(hal_soc, srng); 1747 entry = &ring_debug->entries[ring_debug->ring_debug_idx]; 1748 1749 entry->head_idx = hp; 1750 entry->tail_idx = tp; 1751 entry->timestamp = qdf_get_log_timestamp(); 1752 entry->event = event; 1753 1754 ring_debug->ring_debug_idx++; 1755 if (ring_debug->ring_debug_idx == 1756 ring_debug->num_ring_debug_entries) 1757 ring_debug->ring_debug_idx = 0; 1758 } 1759 } 1760 1761 #else 1762 static void target_if_dbr_add_ring_debug_entry( 1763 struct wlan_objmgr_pdev *pdev, 1764 uint32_t mod_id, 1765 enum DBR_RING_DEBUG_EVENT event, 1766 uint8_t srng_id) 1767 { 1768 } 1769 #endif /* DIRECT_BUF_RX_DEBUG */ 1770 1771 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, 1772 uint8_t *data_buf, 1773 uint32_t data_len) 1774 { 1775 int ret = 0; 1776 uint8_t i = 0; 1777 QDF_STATUS status; 1778 uint32_t cookie = 0; 1779 struct direct_buf_rx_rsp dbr_rsp = {0}; 1780 struct direct_buf_rx_data dbr_data = {0}; 1781 struct wlan_objmgr_psoc *psoc; 1782 struct wlan_objmgr_pdev *pdev; 1783 struct direct_buf_rx_buf_info *dbr_buf_pool; 1784 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1785 struct direct_buf_rx_module_param *mod_param; 1786 struct wmi_unified *wmi_handle; 1787 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1788 uint8_t srng_id = 0; 1789 1790 direct_buf_rx_enter(); 1791 1792 psoc = target_if_get_psoc_from_scn_hdl(scn); 1793 if (!psoc) { 1794 direct_buf_rx_err("psoc is null"); 1795 return QDF_STATUS_E_FAILURE; 1796 } 1797 1798 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 1799 if (!wmi_handle) { 1800 direct_buf_rx_err("WMI handle is null"); 1801 return QDF_STATUS_E_FAILURE; 1802 } 1803 1804 if (wmi_extract_dbr_buf_release_fixed( 1805 wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) { 1806 direct_buf_rx_err("unable to extract DBR rsp fixed param"); 1807 return QDF_STATUS_E_FAILURE; 1808 } 1809 1810 direct_buf_rx_debug("Num buf release entry = %d", 1811 dbr_rsp.num_buf_release_entry); 1812 1813 pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id, 1814 &srng_id); 1815 if (!pdev || (srng_id >= DBR_SRNG_NUM)) { 1816 direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d", 1817 pdev, srng_id); 1818 return QDF_STATUS_E_INVAL; 1819 } 1820 1821 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1822 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1823 1824 if (!dbr_pdev_obj) { 1825 direct_buf_rx_err("dir buf rx object is null"); 1826 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1827 return QDF_STATUS_E_FAILURE; 1828 } 1829 1830 if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) { 1831 direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id); 1832 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1833 return QDF_STATUS_E_FAILURE; 1834 } 1835 mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]); 1836 1837 if (!mod_param) { 1838 direct_buf_rx_err("dir buf rx module param is null"); 1839 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1840 return QDF_STATUS_E_FAILURE; 1841 } 1842 1843 dbr_buf_pool = mod_param->dbr_buf_pool; 1844 dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry * 1845 sizeof(struct direct_buf_rx_entry)); 1846 1847 if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) { 1848 direct_buf_rx_err("More than expected number of metadata"); 1849 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1850 return QDF_STATUS_E_FAILURE; 1851 } 1852 1853 for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { 1854 if (wmi_extract_dbr_buf_release_entry( 1855 wmi_handle, data_buf, i, 1856 &dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) { 1857 direct_buf_rx_err("Unable to extract DBR buf entry %d", 1858 i+1); 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 status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp, 1864 &dbr_data, i, &cookie); 1865 1866 if (QDF_IS_STATUS_ERROR(status)) { 1867 direct_buf_rx_err("DBR data get failed"); 1868 qdf_mem_free(dbr_rsp.dbr_entries); 1869 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1870 return QDF_STATUS_E_FAILURE; 1871 } 1872 1873 dbr_data.meta_data_valid = false; 1874 if (i < dbr_rsp.num_meta_data_entry) { 1875 if (wmi_extract_dbr_buf_metadata( 1876 wmi_handle, data_buf, i, 1877 &dbr_data.meta_data) == QDF_STATUS_SUCCESS) 1878 dbr_data.meta_data_valid = true; 1879 } 1880 1881 target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id, 1882 DBR_RING_DEBUG_EVENT_RX, 1883 srng_id); 1884 if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { 1885 status = target_if_dbr_replenish_ring(pdev, mod_param, 1886 dbr_data.vaddr, 1887 cookie); 1888 1889 target_if_dbr_add_ring_debug_entry( 1890 pdev, dbr_rsp.mod_id, 1891 DBR_RING_DEBUG_EVENT_REPLENISH_RING, 1892 srng_id); 1893 1894 if (QDF_IS_STATUS_ERROR(status)) { 1895 direct_buf_rx_err("Ring replenish failed"); 1896 qdf_mem_free(dbr_rsp.dbr_entries); 1897 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1898 return QDF_STATUS_E_FAILURE; 1899 } 1900 } 1901 } 1902 1903 qdf_mem_free(dbr_rsp.dbr_entries); 1904 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1905 1906 return ret; 1907 } 1908 1909 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev, 1910 struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 1911 struct direct_buf_rx_module_param *mod_param) 1912 { 1913 uint32_t idx; 1914 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1915 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1916 struct direct_buf_rx_buf_info *dbr_buf_pool; 1917 1918 direct_buf_rx_enter(); 1919 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1920 dbr_ring_cap = mod_param->dbr_ring_cap; 1921 dbr_buf_pool = mod_param->dbr_buf_pool; 1922 1923 direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK", 1924 dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool); 1925 1926 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1927 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, 1928 (qdf_dma_addr_t)dbr_buf_pool[idx].paddr, 1929 QDF_DMA_FROM_DEVICE, 1930 dbr_ring_cap->min_buf_size); 1931 qdf_mem_free(dbr_buf_pool[idx].vaddr); 1932 } 1933 1934 return QDF_STATUS_SUCCESS; 1935 } 1936 1937 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, 1938 struct direct_buf_rx_module_param *mod_param) 1939 { 1940 struct wlan_objmgr_psoc *psoc; 1941 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1942 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1943 1944 direct_buf_rx_enter(); 1945 psoc = wlan_pdev_get_psoc(pdev); 1946 if (!psoc) { 1947 direct_buf_rx_err("psoc is null"); 1948 return QDF_STATUS_E_FAILURE; 1949 } 1950 1951 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1952 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1953 1954 if (!dbr_psoc_obj) { 1955 direct_buf_rx_err("dir buf rx psoc object is null"); 1956 return QDF_STATUS_E_FAILURE; 1957 } 1958 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 1959 1960 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1961 if (dbr_ring_cfg) { 1962 target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); 1963 hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); 1964 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1965 dbr_psoc_obj->osdev->dev, 1966 dbr_ring_cfg->ring_alloc_size, 1967 dbr_ring_cfg->base_vaddr_unaligned, 1968 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1969 } 1970 1971 return QDF_STATUS_SUCCESS; 1972 } 1973 1974 static QDF_STATUS target_if_dbr_deinit_srng( 1975 struct wlan_objmgr_pdev *pdev, 1976 struct direct_buf_rx_module_param *mod_param) 1977 { 1978 struct direct_buf_rx_buf_info *dbr_buf_pool; 1979 1980 direct_buf_rx_enter(); 1981 dbr_buf_pool = mod_param->dbr_buf_pool; 1982 direct_buf_rx_debug("dbr buf pool %pK", dbr_buf_pool); 1983 target_if_dbr_deinit_ring(pdev, mod_param); 1984 if (mod_param->dbr_buf_pool) 1985 qdf_mem_free(dbr_buf_pool); 1986 mod_param->dbr_buf_pool = NULL; 1987 1988 return QDF_STATUS_SUCCESS; 1989 } 1990 1991 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev, 1992 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1993 enum DBR_MODULE mod_id, uint8_t srng_id) 1994 { 1995 struct direct_buf_rx_module_param *mod_param; 1996 1997 direct_buf_rx_enter(); 1998 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1999 2000 if (!mod_param) { 2001 direct_buf_rx_err("dir buf rx module param is null"); 2002 return QDF_STATUS_E_FAILURE; 2003 } 2004 direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK", 2005 mod_param, mod_param->dbr_ring_cap); 2006 target_if_dbr_deinit_srng(pdev, mod_param); 2007 if (mod_param->dbr_ring_cap) 2008 qdf_mem_free(mod_param->dbr_ring_cap); 2009 mod_param->dbr_ring_cap = NULL; 2010 if (mod_param->dbr_ring_cfg) 2011 qdf_mem_free(mod_param->dbr_ring_cfg); 2012 mod_param->dbr_ring_cfg = NULL; 2013 2014 return QDF_STATUS_SUCCESS; 2015 } 2016 2017 QDF_STATUS target_if_direct_buf_rx_register_events( 2018 struct wlan_objmgr_psoc *psoc) 2019 { 2020 QDF_STATUS ret; 2021 2022 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2023 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2024 return QDF_STATUS_E_INVAL; 2025 } 2026 2027 ret = wmi_unified_register_event_handler( 2028 get_wmi_unified_hdl_from_psoc(psoc), 2029 wmi_dma_buf_release_event_id, 2030 target_if_direct_buf_rx_rsp_event_handler, 2031 WMI_RX_UMAC_CTX); 2032 2033 if (QDF_IS_STATUS_ERROR(ret)) 2034 direct_buf_rx_debug("event handler not supported, ret=%d", ret); 2035 2036 return QDF_STATUS_SUCCESS; 2037 } 2038 2039 QDF_STATUS target_if_direct_buf_rx_unregister_events( 2040 struct wlan_objmgr_psoc *psoc) 2041 { 2042 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2043 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2044 return QDF_STATUS_E_INVAL; 2045 } 2046 2047 wmi_unified_unregister_event_handler( 2048 get_wmi_unified_hdl_from_psoc(psoc), 2049 wmi_dma_buf_release_event_id); 2050 2051 return QDF_STATUS_SUCCESS; 2052 } 2053 2054 QDF_STATUS target_if_direct_buf_rx_print_ring_stat( 2055 struct wlan_objmgr_pdev *pdev) 2056 { 2057 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2058 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2059 struct wlan_objmgr_psoc *psoc; 2060 void *srng, *hal_soc; 2061 uint32_t hp = 0, tp = 0; 2062 struct direct_buf_rx_module_param *mod_param; 2063 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2064 uint8_t num_modules, mod_idx; 2065 uint8_t srng_id; 2066 2067 if (!pdev) { 2068 direct_buf_rx_err("pdev is null"); 2069 return QDF_STATUS_E_INVAL; 2070 } 2071 2072 psoc = wlan_pdev_get_psoc(pdev); 2073 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2074 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2075 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2076 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2077 hal_soc = dbr_psoc_obj->hal_soc; 2078 num_modules = dbr_pdev_obj->num_modules; 2079 direct_buf_rx_debug("--------------------------------------------------"); 2080 direct_buf_rx_debug("| Module ID | Module | Head Idx | Tail Idx |"); 2081 direct_buf_rx_debug("--------------------------------------------------"); 2082 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 2083 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 2084 mod_param = 2085 &dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id]; 2086 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2087 if (!dbr_ring_cfg) { 2088 direct_buf_rx_info("dbr_ring_cfg is NULL"); 2089 direct_buf_rx_info("mod id %d mod %s", mod_idx, 2090 g_dbr_module_name[mod_idx]. 2091 module_name_str); 2092 continue; 2093 } 2094 srng = dbr_ring_cfg->srng; 2095 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 2096 direct_buf_rx_debug("|%11d|%14s|%10x|%10x|", 2097 mod_idx, g_dbr_module_name[mod_idx]. 2098 module_name_str, 2099 hp, tp); 2100 } 2101 } 2102 direct_buf_rx_debug("--------------------------------------------------"); 2103 2104 return QDF_STATUS_SUCCESS; 2105 } 2106 2107 QDF_STATUS 2108 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, 2109 struct module_ring_params *param, 2110 uint8_t mod_id, uint8_t srng_id) 2111 { 2112 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2113 struct direct_buf_rx_module_param *dbr_mod_param; 2114 2115 if (!pdev) { 2116 direct_buf_rx_err("pdev context passed is null"); 2117 return QDF_STATUS_E_INVAL; 2118 } 2119 2120 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 2121 (pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2122 2123 if (!dbr_pdev_obj) { 2124 direct_buf_rx_err("dir buf rx object is null"); 2125 return QDF_STATUS_E_FAILURE; 2126 } 2127 2128 if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) { 2129 direct_buf_rx_err("invalid params, mod id %d, srng id %d", 2130 mod_id, srng_id); 2131 return QDF_STATUS_E_INVAL; 2132 } 2133 2134 dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 2135 param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr; 2136 param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size; 2137 2138 return QDF_STATUS_SUCCESS; 2139 } 2140