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