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 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_debug("Max Entries = %d", max_entries); 1162 direct_buf_rx_debug("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_debug("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_debug("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_debug("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_debug("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_debug("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, 1324 dbr_cfg_req.base_paddr_hi, 1325 dbr_cfg_req.head_idx_paddr_lo, 1326 dbr_cfg_req.head_idx_paddr_hi, 1327 dbr_cfg_req.tail_idx_paddr_lo, 1328 dbr_cfg_req.tail_idx_paddr_hi, 1329 dbr_cfg_req.num_elems, 1330 dbr_cfg_req.num_resp_per_event, 1331 dbr_cfg_req.event_timeout_ms); 1332 status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req); 1333 1334 return status; 1335 } 1336 1337 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev, 1338 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1339 enum DBR_MODULE mod_id, uint8_t srng_id) 1340 { 1341 QDF_STATUS status = QDF_STATUS_SUCCESS; 1342 struct direct_buf_rx_module_param *mod_param; 1343 1344 direct_buf_rx_debug("Init DBR ring for module %d, srng %d", 1345 mod_id, srng_id); 1346 1347 if (!dbr_pdev_obj) { 1348 direct_buf_rx_err("dir buf rx object is null"); 1349 return QDF_STATUS_E_INVAL; 1350 } 1351 1352 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1353 1354 if (!mod_param) { 1355 direct_buf_rx_err("dir buf rx module param is null"); 1356 return QDF_STATUS_E_FAILURE; 1357 } 1358 1359 direct_buf_rx_debug("mod_param %pK", mod_param); 1360 1361 mod_param->mod_id = mod_id; 1362 mod_param->pdev_id = dbr_get_pdev_id( 1363 srng_id, wlan_objmgr_pdev_get_pdev_id(pdev)); 1364 mod_param->srng_id = srng_id; 1365 1366 /* Initialize DMA ring now */ 1367 status = target_if_dbr_init_srng(pdev, mod_param); 1368 if (QDF_IS_STATUS_ERROR(status)) { 1369 direct_buf_rx_err("DBR ring init failed %d", status); 1370 return status; 1371 } 1372 1373 /* Send CFG request command to firmware */ 1374 status = target_if_dbr_cfg_tgt(pdev, mod_param); 1375 if (QDF_IS_STATUS_ERROR(status)) { 1376 direct_buf_rx_err("DBR config to target failed %d", status); 1377 goto dbr_srng_init_failed; 1378 } 1379 1380 return QDF_STATUS_SUCCESS; 1381 1382 dbr_srng_init_failed: 1383 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id); 1384 return status; 1385 } 1386 1387 QDF_STATUS target_if_direct_buf_rx_module_register( 1388 struct wlan_objmgr_pdev *pdev, uint8_t mod_id, 1389 struct dbr_module_config *dbr_config, 1390 bool (*dbr_rsp_handler) 1391 (struct wlan_objmgr_pdev *pdev, 1392 struct direct_buf_rx_data *dbr_data)) 1393 { 1394 QDF_STATUS status; 1395 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1396 struct dbr_module_config *config = NULL; 1397 struct direct_buf_rx_module_param *mod_param; 1398 uint8_t srng_id; 1399 1400 if (!pdev) { 1401 direct_buf_rx_err("pdev context passed is null"); 1402 return QDF_STATUS_E_INVAL; 1403 } 1404 1405 if (!dbr_rsp_handler) { 1406 direct_buf_rx_err("Response handler is null"); 1407 return QDF_STATUS_E_INVAL; 1408 } 1409 1410 if (mod_id >= DBR_MODULE_MAX) { 1411 direct_buf_rx_err("Invalid module id"); 1412 return QDF_STATUS_E_INVAL; 1413 } 1414 1415 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1416 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1417 1418 if (!dbr_pdev_obj) { 1419 direct_buf_rx_err("dir buf rx object is null"); 1420 return QDF_STATUS_E_FAILURE; 1421 } 1422 1423 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1424 1425 if (!dbr_pdev_obj->dbr_mod_param) { 1426 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1427 return QDF_STATUS_E_FAILURE; 1428 } 1429 1430 if (mod_id >= dbr_pdev_obj->num_modules) { 1431 direct_buf_rx_err("Module %d not supported in target", mod_id); 1432 return QDF_STATUS_E_FAILURE; 1433 } 1434 1435 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1436 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1437 config = &mod_param->dbr_config; 1438 mod_param->dbr_rsp_handler = dbr_rsp_handler; 1439 *config = *dbr_config; 1440 1441 status = target_if_init_dbr_ring(pdev, dbr_pdev_obj, 1442 (enum DBR_MODULE)mod_id, 1443 srng_id); 1444 if (QDF_IS_STATUS_ERROR(status)) 1445 direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d", 1446 srng_id, status); 1447 } 1448 1449 return status; 1450 } 1451 1452 QDF_STATUS target_if_direct_buf_rx_module_unregister( 1453 struct wlan_objmgr_pdev *pdev, uint8_t mod_id) 1454 { 1455 QDF_STATUS status; 1456 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1457 uint8_t srng_id; 1458 1459 if (!pdev) { 1460 direct_buf_rx_err("pdev context passed is null"); 1461 return QDF_STATUS_E_INVAL; 1462 } 1463 1464 if (mod_id >= DBR_MODULE_MAX) { 1465 direct_buf_rx_err("Invalid module id"); 1466 return QDF_STATUS_E_INVAL; 1467 } 1468 1469 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 1470 (pdev, 1471 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1472 1473 if (!dbr_pdev_obj) { 1474 direct_buf_rx_err("dir buf rx object is null"); 1475 return QDF_STATUS_E_FAILURE; 1476 } 1477 1478 direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj); 1479 1480 if (!dbr_pdev_obj->dbr_mod_param) { 1481 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 1482 return QDF_STATUS_E_FAILURE; 1483 } 1484 1485 if (mod_id >= dbr_pdev_obj->num_modules) { 1486 direct_buf_rx_err("Module %d not supported in target", mod_id); 1487 return QDF_STATUS_E_FAILURE; 1488 } 1489 1490 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1491 status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 1492 mod_id, srng_id); 1493 direct_buf_rx_info("status %d", status); 1494 } 1495 1496 return status; 1497 } 1498 1499 static void *target_if_dbr_vaddr_lookup( 1500 struct direct_buf_rx_module_param *mod_param, 1501 qdf_dma_addr_t paddr, uint32_t cookie) 1502 { 1503 struct direct_buf_rx_buf_info *dbr_buf_pool; 1504 1505 dbr_buf_pool = mod_param->dbr_buf_pool; 1506 1507 if (dbr_buf_pool[cookie].paddr == paddr) { 1508 return dbr_buf_pool[cookie].vaddr + 1509 dbr_buf_pool[cookie].offset; 1510 } 1511 1512 direct_buf_rx_debug("Incorrect paddr found on cookie slot"); 1513 return NULL; 1514 } 1515 1516 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev, 1517 uint8_t mod_id, qdf_dma_addr_t paddr, 1518 uint32_t *cookie, uint8_t srng_id) 1519 { 1520 struct direct_buf_rx_buf_info *dbr_buf_pool; 1521 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1522 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1523 struct direct_buf_rx_module_param *mod_param; 1524 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1525 uint32_t idx; 1526 1527 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1528 if (!dbr_pdev_obj) { 1529 direct_buf_rx_err("dir buf rx object is null"); 1530 return QDF_STATUS_E_FAILURE; 1531 } 1532 1533 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1534 if (!mod_param) { 1535 direct_buf_rx_err("dir buf rx module param is null"); 1536 return QDF_STATUS_E_FAILURE; 1537 } 1538 1539 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1540 dbr_buf_pool = mod_param->dbr_buf_pool; 1541 1542 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1543 if (dbr_buf_pool[idx].paddr && 1544 dbr_buf_pool[idx].paddr == paddr) { 1545 *cookie = idx; 1546 return QDF_STATUS_SUCCESS; 1547 } 1548 } 1549 1550 return QDF_STATUS_E_FAILURE; 1551 } 1552 1553 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev, 1554 uint8_t mod_id, qdf_dma_addr_t paddr, 1555 uint32_t cookie, uint8_t srng_id) 1556 { 1557 struct direct_buf_rx_module_param *mod_param; 1558 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1559 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 1560 void *vaddr; 1561 QDF_STATUS status; 1562 1563 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 1564 if (!dbr_pdev_obj) { 1565 direct_buf_rx_err("dir buf rx object is null"); 1566 return QDF_STATUS_E_FAILURE; 1567 } 1568 1569 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1570 if (!mod_param) { 1571 direct_buf_rx_err("dir buf rx module param is null"); 1572 return QDF_STATUS_E_FAILURE; 1573 } 1574 1575 vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie); 1576 if (!vaddr) 1577 return QDF_STATUS_E_FAILURE; 1578 1579 status = target_if_dbr_replenish_ring(pdev, mod_param, 1580 vaddr, cookie); 1581 if (QDF_IS_STATUS_ERROR(status)) { 1582 direct_buf_rx_err("Ring replenish failed"); 1583 return QDF_STATUS_E_FAILURE; 1584 } 1585 1586 return QDF_STATUS_SUCCESS; 1587 } 1588 1589 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, 1590 struct direct_buf_rx_module_param *mod_param, 1591 struct direct_buf_rx_rsp *dbr_rsp, 1592 struct direct_buf_rx_data *dbr_data, 1593 uint8_t idx, uint32_t *cookie) 1594 { 1595 qdf_dma_addr_t paddr = 0; 1596 uint32_t addr_hi; 1597 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1598 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1599 struct wlan_objmgr_psoc *psoc; 1600 1601 psoc = wlan_pdev_get_psoc(pdev); 1602 if (!psoc) { 1603 direct_buf_rx_err("psoc is null"); 1604 return QDF_STATUS_E_FAILURE; 1605 } 1606 1607 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1608 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1609 1610 if (!dbr_psoc_obj) { 1611 direct_buf_rx_err("dir buf rx psoc object is null"); 1612 return QDF_STATUS_E_FAILURE; 1613 } 1614 1615 dbr_ring_cap = mod_param->dbr_ring_cap; 1616 addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET( 1617 dbr_rsp->dbr_entries[idx].paddr_hi); 1618 paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 | 1619 dbr_rsp->dbr_entries[idx].paddr_lo); 1620 *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( 1621 dbr_rsp->dbr_entries[idx].paddr_hi); 1622 dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); 1623 dbr_data->cookie = *cookie; 1624 dbr_data->paddr = paddr; 1625 direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK", 1626 dbr_data->cookie, dbr_data->vaddr); 1627 dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len; 1628 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr, 1629 QDF_DMA_FROM_DEVICE, 1630 dbr_ring_cap->min_buf_size); 1631 1632 return QDF_STATUS_SUCCESS; 1633 } 1634 1635 #ifdef DBR_MULTI_SRNG_ENABLE 1636 /** 1637 * dbr_get_pdev_and_srng_id() - get pdev object and srng id 1638 * 1639 * @psoc: pointer to psoc object 1640 * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid 1641 * @srng_id: pointer to return srng id 1642 * 1643 * Return : pointer to pdev 1644 */ 1645 static struct wlan_objmgr_pdev * 1646 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1647 uint8_t *srng_id) 1648 { 1649 struct wlan_objmgr_pdev *pdev; 1650 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1651 1652 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 1653 if (!pdev) { 1654 pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC, 1655 dbr_mod_id); 1656 if (pdev) { 1657 direct_buf_rx_debug("update srng id from %d to %d", 1658 *srng_id, pdev_id); 1659 *srng_id = pdev_id; 1660 } 1661 } 1662 1663 return pdev; 1664 } 1665 #else 1666 static struct wlan_objmgr_pdev * 1667 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1668 uint8_t *srng_id) 1669 { 1670 struct wlan_objmgr_pdev *pdev; 1671 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1672 1673 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 1674 1675 return pdev; 1676 } 1677 #endif 1678 1679 #ifdef DIRECT_BUF_RX_DEBUG 1680 /** 1681 * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry 1682 * @pdev: pointer to pdev object 1683 * @mod_id: Module ID 1684 * @event: ring debug event 1685 * 1686 * Log the given event, head and tail pointers of DBR ring of the given module 1687 * into its ring debug data structure. 1688 * Also, log the timestamp at the time of logging. 1689 */ 1690 static void target_if_dbr_add_ring_debug_entry( 1691 struct wlan_objmgr_pdev *pdev, 1692 uint32_t mod_id, 1693 enum DBR_RING_DEBUG_EVENT event, 1694 uint8_t srng_id) 1695 { 1696 struct wlan_objmgr_psoc *psoc; 1697 void *hal_soc, *srng; 1698 uint32_t hp = 0, tp = 0; 1699 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1700 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1701 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1702 struct direct_buf_rx_module_debug *mod_debug; 1703 struct direct_buf_rx_module_param *mod_param; 1704 struct direct_buf_rx_ring_debug *ring_debug; 1705 struct direct_buf_rx_ring_debug_entry *entry; 1706 1707 mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); 1708 1709 if (!mod_debug) 1710 return; 1711 1712 psoc = wlan_pdev_get_psoc(pdev); 1713 1714 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( 1715 pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1716 1717 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 1718 psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1719 1720 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1721 if (!mod_param) { 1722 direct_buf_rx_err("dir buf rx module param is null"); 1723 return; 1724 } 1725 1726 hal_soc = dbr_psoc_obj->hal_soc; 1727 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1728 srng = dbr_ring_cfg->srng; 1729 ring_debug = &mod_debug->dbr_ring_debug[srng_id]; 1730 1731 if (ring_debug->entries) { 1732 if (hal_srng_access_start(hal_soc, srng)) { 1733 direct_buf_rx_err("module %d - HAL srng access failed", 1734 mod_id); 1735 return; 1736 } 1737 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 1738 hal_srng_access_end(hal_soc, srng); 1739 entry = &ring_debug->entries[ring_debug->ring_debug_idx]; 1740 1741 entry->head_idx = hp; 1742 entry->tail_idx = tp; 1743 entry->timestamp = qdf_get_log_timestamp(); 1744 entry->event = event; 1745 1746 ring_debug->ring_debug_idx++; 1747 if (ring_debug->ring_debug_idx == 1748 ring_debug->num_ring_debug_entries) 1749 ring_debug->ring_debug_idx = 0; 1750 } 1751 } 1752 1753 #else 1754 static void target_if_dbr_add_ring_debug_entry( 1755 struct wlan_objmgr_pdev *pdev, 1756 uint32_t mod_id, 1757 enum DBR_RING_DEBUG_EVENT event, 1758 uint8_t srng_id) 1759 { 1760 } 1761 #endif /* DIRECT_BUF_RX_DEBUG */ 1762 1763 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, 1764 uint8_t *data_buf, 1765 uint32_t data_len) 1766 { 1767 int ret = 0; 1768 uint8_t i = 0; 1769 QDF_STATUS status; 1770 uint32_t cookie = 0; 1771 struct direct_buf_rx_rsp dbr_rsp = {0}; 1772 struct direct_buf_rx_data dbr_data = {0}; 1773 struct wlan_objmgr_psoc *psoc; 1774 struct wlan_objmgr_pdev *pdev; 1775 struct direct_buf_rx_buf_info *dbr_buf_pool; 1776 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1777 struct direct_buf_rx_module_param *mod_param; 1778 struct wmi_unified *wmi_handle; 1779 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 1780 uint8_t srng_id = 0; 1781 1782 direct_buf_rx_enter(); 1783 1784 psoc = target_if_get_psoc_from_scn_hdl(scn); 1785 if (!psoc) { 1786 direct_buf_rx_err("psoc is null"); 1787 return QDF_STATUS_E_FAILURE; 1788 } 1789 1790 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 1791 if (!wmi_handle) { 1792 direct_buf_rx_err("WMI handle is null"); 1793 return QDF_STATUS_E_FAILURE; 1794 } 1795 1796 if (wmi_extract_dbr_buf_release_fixed( 1797 wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) { 1798 direct_buf_rx_err("unable to extract DBR rsp fixed param"); 1799 return QDF_STATUS_E_FAILURE; 1800 } 1801 1802 direct_buf_rx_debug("Num buf release entry = %d", 1803 dbr_rsp.num_buf_release_entry); 1804 1805 pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id, 1806 &srng_id); 1807 if (!pdev || (srng_id >= DBR_SRNG_NUM)) { 1808 direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d", 1809 pdev, srng_id); 1810 return QDF_STATUS_E_INVAL; 1811 } 1812 1813 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1814 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1815 1816 if (!dbr_pdev_obj) { 1817 direct_buf_rx_err("dir buf rx object is null"); 1818 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1819 return QDF_STATUS_E_FAILURE; 1820 } 1821 1822 if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) { 1823 direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id); 1824 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1825 return QDF_STATUS_E_FAILURE; 1826 } 1827 mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]); 1828 1829 if (!mod_param) { 1830 direct_buf_rx_err("dir buf rx module param is null"); 1831 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1832 return QDF_STATUS_E_FAILURE; 1833 } 1834 1835 dbr_buf_pool = mod_param->dbr_buf_pool; 1836 dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry * 1837 sizeof(struct direct_buf_rx_entry)); 1838 1839 if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) { 1840 direct_buf_rx_err("More than expected number of metadata"); 1841 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1842 return QDF_STATUS_E_FAILURE; 1843 } 1844 1845 for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { 1846 if (wmi_extract_dbr_buf_release_entry( 1847 wmi_handle, data_buf, i, 1848 &dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) { 1849 direct_buf_rx_err("Unable to extract DBR buf entry %d", 1850 i+1); 1851 qdf_mem_free(dbr_rsp.dbr_entries); 1852 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1853 return QDF_STATUS_E_FAILURE; 1854 } 1855 status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp, 1856 &dbr_data, i, &cookie); 1857 1858 if (QDF_IS_STATUS_ERROR(status)) { 1859 direct_buf_rx_err("DBR data get failed"); 1860 qdf_mem_free(dbr_rsp.dbr_entries); 1861 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1862 return QDF_STATUS_E_FAILURE; 1863 } 1864 1865 dbr_data.meta_data_valid = false; 1866 if (i < dbr_rsp.num_meta_data_entry) { 1867 if (wmi_extract_dbr_buf_metadata( 1868 wmi_handle, data_buf, i, 1869 &dbr_data.meta_data) == QDF_STATUS_SUCCESS) 1870 dbr_data.meta_data_valid = true; 1871 } 1872 1873 target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id, 1874 DBR_RING_DEBUG_EVENT_RX, 1875 srng_id); 1876 if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { 1877 status = target_if_dbr_replenish_ring(pdev, mod_param, 1878 dbr_data.vaddr, 1879 cookie); 1880 1881 target_if_dbr_add_ring_debug_entry( 1882 pdev, dbr_rsp.mod_id, 1883 DBR_RING_DEBUG_EVENT_REPLENISH_RING, 1884 srng_id); 1885 1886 if (QDF_IS_STATUS_ERROR(status)) { 1887 direct_buf_rx_err("Ring replenish failed"); 1888 qdf_mem_free(dbr_rsp.dbr_entries); 1889 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1890 return QDF_STATUS_E_FAILURE; 1891 } 1892 } 1893 } 1894 1895 qdf_mem_free(dbr_rsp.dbr_entries); 1896 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1897 1898 return ret; 1899 } 1900 1901 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev, 1902 struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 1903 struct direct_buf_rx_module_param *mod_param) 1904 { 1905 uint32_t idx; 1906 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1907 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1908 struct direct_buf_rx_buf_info *dbr_buf_pool; 1909 1910 direct_buf_rx_enter(); 1911 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1912 dbr_ring_cap = mod_param->dbr_ring_cap; 1913 dbr_buf_pool = mod_param->dbr_buf_pool; 1914 1915 direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK", 1916 dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool); 1917 1918 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1919 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, 1920 (qdf_dma_addr_t)dbr_buf_pool[idx].paddr, 1921 QDF_DMA_FROM_DEVICE, 1922 dbr_ring_cap->min_buf_size); 1923 qdf_mem_free(dbr_buf_pool[idx].vaddr); 1924 } 1925 1926 return QDF_STATUS_SUCCESS; 1927 } 1928 1929 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, 1930 struct direct_buf_rx_module_param *mod_param) 1931 { 1932 struct wlan_objmgr_psoc *psoc; 1933 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1934 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1935 1936 direct_buf_rx_enter(); 1937 psoc = wlan_pdev_get_psoc(pdev); 1938 if (!psoc) { 1939 direct_buf_rx_err("psoc is null"); 1940 return QDF_STATUS_E_FAILURE; 1941 } 1942 1943 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1944 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1945 1946 if (!dbr_psoc_obj) { 1947 direct_buf_rx_err("dir buf rx psoc object is null"); 1948 return QDF_STATUS_E_FAILURE; 1949 } 1950 direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj); 1951 1952 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1953 if (dbr_ring_cfg) { 1954 target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); 1955 hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); 1956 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1957 dbr_psoc_obj->osdev->dev, 1958 dbr_ring_cfg->ring_alloc_size, 1959 dbr_ring_cfg->base_vaddr_unaligned, 1960 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1961 } 1962 1963 return QDF_STATUS_SUCCESS; 1964 } 1965 1966 static QDF_STATUS target_if_dbr_deinit_srng( 1967 struct wlan_objmgr_pdev *pdev, 1968 struct direct_buf_rx_module_param *mod_param) 1969 { 1970 struct direct_buf_rx_buf_info *dbr_buf_pool; 1971 1972 direct_buf_rx_enter(); 1973 dbr_buf_pool = mod_param->dbr_buf_pool; 1974 direct_buf_rx_debug("dbr buf pool %pK", dbr_buf_pool); 1975 target_if_dbr_deinit_ring(pdev, mod_param); 1976 if (mod_param->dbr_buf_pool) 1977 qdf_mem_free(dbr_buf_pool); 1978 mod_param->dbr_buf_pool = NULL; 1979 1980 return QDF_STATUS_SUCCESS; 1981 } 1982 1983 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev, 1984 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1985 enum DBR_MODULE mod_id, uint8_t srng_id) 1986 { 1987 struct direct_buf_rx_module_param *mod_param; 1988 1989 direct_buf_rx_enter(); 1990 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1991 1992 if (!mod_param) { 1993 direct_buf_rx_err("dir buf rx module param is null"); 1994 return QDF_STATUS_E_FAILURE; 1995 } 1996 direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK", 1997 mod_param, mod_param->dbr_ring_cap); 1998 target_if_dbr_deinit_srng(pdev, mod_param); 1999 if (mod_param->dbr_ring_cap) 2000 qdf_mem_free(mod_param->dbr_ring_cap); 2001 mod_param->dbr_ring_cap = NULL; 2002 if (mod_param->dbr_ring_cfg) 2003 qdf_mem_free(mod_param->dbr_ring_cfg); 2004 mod_param->dbr_ring_cfg = NULL; 2005 2006 return QDF_STATUS_SUCCESS; 2007 } 2008 2009 QDF_STATUS target_if_direct_buf_rx_register_events( 2010 struct wlan_objmgr_psoc *psoc) 2011 { 2012 int ret; 2013 2014 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2015 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2016 return QDF_STATUS_E_INVAL; 2017 } 2018 2019 ret = wmi_unified_register_event_handler( 2020 get_wmi_unified_hdl_from_psoc(psoc), 2021 wmi_dma_buf_release_event_id, 2022 target_if_direct_buf_rx_rsp_event_handler, 2023 WMI_RX_UMAC_CTX); 2024 2025 if (ret) 2026 direct_buf_rx_debug("event handler not supported, ret=%d", ret); 2027 2028 return QDF_STATUS_SUCCESS; 2029 } 2030 2031 QDF_STATUS target_if_direct_buf_rx_unregister_events( 2032 struct wlan_objmgr_psoc *psoc) 2033 { 2034 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 2035 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 2036 return QDF_STATUS_E_INVAL; 2037 } 2038 2039 wmi_unified_unregister_event_handler( 2040 get_wmi_unified_hdl_from_psoc(psoc), 2041 wmi_dma_buf_release_event_id); 2042 2043 return QDF_STATUS_SUCCESS; 2044 } 2045 2046 QDF_STATUS target_if_direct_buf_rx_print_ring_stat( 2047 struct wlan_objmgr_pdev *pdev) 2048 { 2049 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 2050 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2051 struct wlan_objmgr_psoc *psoc; 2052 void *srng, *hal_soc; 2053 uint32_t hp = 0, tp = 0; 2054 struct direct_buf_rx_module_param *mod_param; 2055 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 2056 uint8_t num_modules, mod_idx; 2057 uint8_t srng_id; 2058 2059 if (!pdev) { 2060 direct_buf_rx_err("pdev is null"); 2061 return QDF_STATUS_E_INVAL; 2062 } 2063 2064 psoc = wlan_pdev_get_psoc(pdev); 2065 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2066 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2067 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2068 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2069 hal_soc = dbr_psoc_obj->hal_soc; 2070 num_modules = dbr_pdev_obj->num_modules; 2071 direct_buf_rx_debug("--------------------------------------------------"); 2072 direct_buf_rx_debug("| Module ID | Module | Head Idx | Tail Idx |"); 2073 direct_buf_rx_debug("--------------------------------------------------"); 2074 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 2075 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 2076 mod_param = 2077 &dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id]; 2078 dbr_ring_cfg = mod_param->dbr_ring_cfg; 2079 srng = dbr_ring_cfg->srng; 2080 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 2081 direct_buf_rx_debug("|%11d|%14s|%10x|%10x|", 2082 mod_idx, g_dbr_module_name[mod_idx]. 2083 module_name_str, 2084 hp, tp); 2085 } 2086 } 2087 direct_buf_rx_debug("--------------------------------------------------"); 2088 2089 return QDF_STATUS_SUCCESS; 2090 } 2091 2092 QDF_STATUS 2093 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, 2094 struct module_ring_params *param, 2095 uint8_t mod_id, uint8_t srng_id) 2096 { 2097 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 2098 struct direct_buf_rx_module_param *dbr_mod_param; 2099 2100 if (!pdev) { 2101 direct_buf_rx_err("pdev context passed is null"); 2102 return QDF_STATUS_E_INVAL; 2103 } 2104 2105 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 2106 (pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 2107 2108 if (!dbr_pdev_obj) { 2109 direct_buf_rx_err("dir buf rx object is null"); 2110 return QDF_STATUS_E_FAILURE; 2111 } 2112 2113 if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) { 2114 direct_buf_rx_err("invalid params, mod id %d, srng id %d", 2115 mod_id, srng_id); 2116 return QDF_STATUS_E_INVAL; 2117 } 2118 2119 dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 2120 param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr; 2121 param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size; 2122 2123 return QDF_STATUS_SUCCESS; 2124 } 2125