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