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 struct wlan_psoc_host_service_ext_param *ext_svc_param; 47 48 psoc = wlan_pdev_get_psoc(pdev); 49 50 if (!psoc) { 51 direct_buf_rx_err("psoc is null"); 52 return 0; 53 } 54 55 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 56 if (!tgt_psoc_info) { 57 direct_buf_rx_err("target_psoc_info is null"); 58 return 0; 59 } 60 ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info); 61 num_dbr_ring_caps = ext_svc_param->num_dbr_ring_caps; 62 dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); 63 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 64 num_modules = 0; 65 66 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 67 if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) 68 num_modules++; 69 } 70 71 return num_modules; 72 } 73 74 static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev, 75 struct direct_buf_rx_module_param *mod_param) 76 { 77 struct wlan_objmgr_psoc *psoc; 78 struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; 79 uint8_t cap_idx; 80 bool cap_found = false; 81 enum DBR_MODULE mod_id = mod_param->mod_id; 82 uint32_t num_dbr_ring_caps, pdev_id; 83 struct target_psoc_info *tgt_psoc_info; 84 struct wlan_psoc_host_service_ext_param *ext_svc_param; 85 86 psoc = wlan_pdev_get_psoc(pdev); 87 88 if (!psoc) { 89 direct_buf_rx_err("psoc is null"); 90 return QDF_STATUS_E_INVAL; 91 } 92 93 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 94 if (!tgt_psoc_info) { 95 direct_buf_rx_err("target_psoc_info is null"); 96 return QDF_STATUS_E_INVAL; 97 } 98 99 ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info); 100 num_dbr_ring_caps = ext_svc_param->num_dbr_ring_caps; 101 dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); 102 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 103 104 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 105 if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) { 106 if (dbr_ring_cap[cap_idx].mod_id == mod_id) { 107 mod_param->dbr_ring_cap->ring_elems_min = 108 dbr_ring_cap[cap_idx].ring_elems_min; 109 mod_param->dbr_ring_cap->min_buf_size = 110 dbr_ring_cap[cap_idx].min_buf_size; 111 mod_param->dbr_ring_cap->min_buf_align = 112 dbr_ring_cap[cap_idx].min_buf_align; 113 cap_found = true; 114 } 115 } 116 } 117 118 if (!cap_found) { 119 direct_buf_rx_err("No cap found for module %d in pdev %d", 120 mod_id, pdev_id); 121 return QDF_STATUS_E_FAILURE; 122 } 123 124 return QDF_STATUS_SUCCESS; 125 } 126 127 QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( 128 struct wlan_objmgr_pdev *pdev, void *data) 129 { 130 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 131 struct wlan_objmgr_psoc *psoc; 132 uint8_t num_modules; 133 QDF_STATUS status; 134 135 direct_buf_rx_enter(); 136 137 if (!pdev) { 138 direct_buf_rx_err("pdev context passed is null"); 139 return QDF_STATUS_E_INVAL; 140 } 141 142 psoc = wlan_pdev_get_psoc(pdev); 143 144 if (!psoc) { 145 direct_buf_rx_err("psoc is null"); 146 return QDF_STATUS_E_INVAL; 147 } 148 149 dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj)); 150 151 if (!dbr_pdev_obj) 152 return QDF_STATUS_E_NOMEM; 153 154 direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); 155 156 status = wlan_objmgr_pdev_component_obj_attach(pdev, 157 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 158 dbr_pdev_obj, QDF_STATUS_SUCCESS); 159 160 if (status != QDF_STATUS_SUCCESS) { 161 direct_buf_rx_err("Failed to attach dir buf rx component %d", 162 status); 163 qdf_mem_free(dbr_pdev_obj); 164 return status; 165 } 166 167 num_modules = get_num_dbr_modules_per_pdev(pdev); 168 direct_buf_rx_info("Number of modules = %d pdev %d", num_modules, 169 wlan_objmgr_pdev_get_pdev_id(pdev)); 170 dbr_pdev_obj->num_modules = num_modules; 171 172 if (!dbr_pdev_obj->num_modules) { 173 direct_buf_rx_info("Number of modules = %d", num_modules); 174 return QDF_STATUS_SUCCESS; 175 } 176 177 dbr_pdev_obj->dbr_mod_param = qdf_mem_malloc(num_modules * 178 sizeof(struct direct_buf_rx_module_param)); 179 180 if (!dbr_pdev_obj->dbr_mod_param) { 181 wlan_objmgr_pdev_component_obj_detach(pdev, 182 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 183 dbr_pdev_obj); 184 qdf_mem_free(dbr_pdev_obj); 185 return QDF_STATUS_E_NOMEM; 186 } 187 188 189 return QDF_STATUS_SUCCESS; 190 } 191 192 QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler( 193 struct wlan_objmgr_pdev *pdev, void *data) 194 { 195 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 196 QDF_STATUS status; 197 uint8_t num_modules, mod_idx; 198 199 if (!pdev) { 200 direct_buf_rx_err("pdev context passed is null"); 201 return QDF_STATUS_E_INVAL; 202 } 203 204 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 205 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 206 207 if (!dbr_pdev_obj) { 208 direct_buf_rx_err("dir buf rx object is null"); 209 return QDF_STATUS_E_FAILURE; 210 } 211 212 num_modules = dbr_pdev_obj->num_modules; 213 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) 214 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_idx); 215 216 qdf_mem_free(dbr_pdev_obj->dbr_mod_param); 217 dbr_pdev_obj->dbr_mod_param = NULL; 218 219 status = wlan_objmgr_pdev_component_obj_detach(pdev, 220 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 221 dbr_pdev_obj); 222 223 if (status != QDF_STATUS_SUCCESS) { 224 direct_buf_rx_err("failed to detach dir buf rx component %d", 225 status); 226 } 227 228 qdf_mem_free(dbr_pdev_obj); 229 230 return status; 231 } 232 233 QDF_STATUS target_if_direct_buf_rx_psoc_create_handler( 234 struct wlan_objmgr_psoc *psoc, void *data) 235 { 236 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 237 QDF_STATUS status; 238 239 direct_buf_rx_enter(); 240 241 if (!psoc) { 242 direct_buf_rx_err("psoc context passed is null"); 243 return QDF_STATUS_E_INVAL; 244 } 245 246 dbr_psoc_obj = qdf_mem_malloc(sizeof(*dbr_psoc_obj)); 247 248 if (!dbr_psoc_obj) 249 return QDF_STATUS_E_NOMEM; 250 251 direct_buf_rx_info("Dbr psoc obj %pK", dbr_psoc_obj); 252 253 status = wlan_objmgr_psoc_component_obj_attach(psoc, 254 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_psoc_obj, 255 QDF_STATUS_SUCCESS); 256 257 if (status != QDF_STATUS_SUCCESS) { 258 direct_buf_rx_err("Failed to attach dir buf rx component %d", 259 status); 260 goto attach_error; 261 } 262 263 return status; 264 265 attach_error: 266 qdf_mem_free(dbr_psoc_obj); 267 268 return status; 269 } 270 271 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler( 272 struct wlan_objmgr_psoc *psoc, void *data) 273 { 274 QDF_STATUS status; 275 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 276 277 direct_buf_rx_enter(); 278 279 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 280 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 281 282 if (!dbr_psoc_obj) { 283 direct_buf_rx_err("dir buf rx psoc obj is null"); 284 return QDF_STATUS_E_FAILURE; 285 } 286 287 status = wlan_objmgr_psoc_component_obj_detach(psoc, 288 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 289 dbr_psoc_obj); 290 291 if (status != QDF_STATUS_SUCCESS) { 292 direct_buf_rx_err("failed to detach dir buf rx component %d", 293 status); 294 } 295 296 qdf_mem_free(dbr_psoc_obj); 297 298 return status; 299 } 300 301 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, 302 struct direct_buf_rx_module_param *mod_param, 303 void *aligned_vaddr, uint32_t cookie) 304 { 305 uint64_t *ring_entry; 306 uint32_t dw_lo, dw_hi = 0, map_status; 307 void *hal_soc, *srng; 308 qdf_dma_addr_t paddr; 309 struct wlan_objmgr_psoc *psoc; 310 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 311 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 312 struct direct_buf_rx_ring_cap *dbr_ring_cap; 313 struct direct_buf_rx_buf_info *dbr_buf_pool; 314 315 direct_buf_rx_enter(); 316 317 dbr_ring_cfg = mod_param->dbr_ring_cfg; 318 dbr_ring_cap = mod_param->dbr_ring_cap; 319 dbr_buf_pool = mod_param->dbr_buf_pool; 320 321 psoc = wlan_pdev_get_psoc(pdev); 322 323 if (!psoc) { 324 direct_buf_rx_err("psoc is null"); 325 return QDF_STATUS_E_FAILURE; 326 } 327 328 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 329 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 330 331 if (!dbr_psoc_obj) { 332 direct_buf_rx_err("dir buf rx psoc object is null"); 333 return QDF_STATUS_E_FAILURE; 334 } 335 336 hal_soc = dbr_psoc_obj->hal_soc; 337 srng = dbr_ring_cfg->srng; 338 if (!aligned_vaddr) { 339 direct_buf_rx_err("aligned vaddr is null"); 340 return QDF_STATUS_SUCCESS; 341 } 342 343 map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev, 344 aligned_vaddr, 345 QDF_DMA_FROM_DEVICE, 346 dbr_ring_cap->min_buf_size, 347 &paddr); 348 if (map_status) { 349 direct_buf_rx_err("mem map failed status = %d", map_status); 350 return QDF_STATUS_E_FAILURE; 351 } 352 353 QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align)); 354 dbr_buf_pool[cookie].paddr = paddr; 355 356 hal_srng_access_start(hal_soc, srng); 357 ring_entry = hal_srng_src_get_next(hal_soc, srng); 358 QDF_ASSERT(ring_entry); 359 dw_lo = (uint64_t)paddr & 0xFFFFFFFF; 360 WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32); 361 WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie); 362 direct_buf_rx_info("Cookie = %d", cookie); 363 direct_buf_rx_info("dw_lo = %x dw_hi = %x", dw_lo, dw_hi); 364 *ring_entry = (uint64_t)dw_hi << 32 | dw_lo; 365 direct_buf_rx_info("Valid ring entry"); 366 hal_srng_access_end(hal_soc, srng); 367 368 return QDF_STATUS_SUCCESS; 369 } 370 371 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev, 372 struct direct_buf_rx_module_param *mod_param) 373 { 374 uint32_t idx; 375 void *buf, *buf_aligned; 376 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 377 struct direct_buf_rx_ring_cap *dbr_ring_cap; 378 struct direct_buf_rx_buf_info *dbr_buf_pool; 379 QDF_STATUS status; 380 381 direct_buf_rx_enter(); 382 383 dbr_ring_cfg = mod_param->dbr_ring_cfg; 384 dbr_ring_cap = mod_param->dbr_ring_cap; 385 dbr_buf_pool = mod_param->dbr_buf_pool; 386 387 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 388 buf_aligned = qdf_aligned_malloc(dbr_ring_cap->min_buf_size, 389 dbr_ring_cap->min_buf_align, 390 &buf); 391 if (!buf_aligned) { 392 direct_buf_rx_err( 393 "dir buf rx ring buf_aligned alloc failed"); 394 return QDF_STATUS_E_NOMEM; 395 } 396 dbr_buf_pool[idx].vaddr = buf; 397 dbr_buf_pool[idx].offset = buf_aligned - buf; 398 dbr_buf_pool[idx].cookie = idx; 399 status = target_if_dbr_replenish_ring(pdev, mod_param, 400 buf_aligned, idx); 401 if (QDF_IS_STATUS_ERROR(status)) { 402 direct_buf_rx_err("replenish failed with status : %d", 403 status); 404 qdf_mem_free(buf); 405 return QDF_STATUS_E_FAILURE; 406 } 407 } 408 409 return QDF_STATUS_SUCCESS; 410 } 411 412 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev, 413 struct direct_buf_rx_module_param *mod_param) 414 { 415 void *srng; 416 uint32_t num_entries, ring_alloc_size, max_entries, entry_size; 417 qdf_dma_addr_t paddr; 418 struct hal_srng_params ring_params = {0}; 419 struct wlan_objmgr_psoc *psoc; 420 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 421 struct direct_buf_rx_ring_cap *dbr_ring_cap; 422 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 423 QDF_STATUS status; 424 425 direct_buf_rx_enter(); 426 427 psoc = wlan_pdev_get_psoc(pdev); 428 429 if (!psoc) { 430 direct_buf_rx_err("psoc is null"); 431 return QDF_STATUS_E_FAILURE; 432 } 433 434 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 435 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 436 437 if (!dbr_psoc_obj) { 438 direct_buf_rx_err("dir buf rx psoc object is null"); 439 return QDF_STATUS_E_FAILURE; 440 } 441 442 if (!dbr_psoc_obj->hal_soc || 443 !dbr_psoc_obj->osdev) { 444 direct_buf_rx_err("dir buf rx target attach failed"); 445 return QDF_STATUS_E_FAILURE; 446 } 447 448 max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc, 449 DIR_BUF_RX_DMA_SRC); 450 entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc, 451 DIR_BUF_RX_DMA_SRC); 452 direct_buf_rx_info("Max Entries = %d", max_entries); 453 direct_buf_rx_info("Entry Size = %d", entry_size); 454 455 status = populate_dbr_cap_mod_param(pdev, mod_param); 456 if (QDF_IS_STATUS_ERROR(status)) { 457 direct_buf_rx_err("Module cap population failed"); 458 return QDF_STATUS_E_FAILURE; 459 } 460 461 dbr_ring_cap = mod_param->dbr_ring_cap; 462 dbr_ring_cfg = mod_param->dbr_ring_cfg; 463 num_entries = dbr_ring_cap->ring_elems_min > max_entries ? 464 max_entries : dbr_ring_cap->ring_elems_min; 465 direct_buf_rx_info("Num entries = %d", num_entries); 466 dbr_ring_cfg->num_ptr = num_entries; 467 mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof( 468 struct direct_buf_rx_buf_info)); 469 if (!mod_param->dbr_buf_pool) 470 return QDF_STATUS_E_NOMEM; 471 472 ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1; 473 dbr_ring_cfg->ring_alloc_size = ring_alloc_size; 474 direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj); 475 dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent( 476 dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size, 477 &paddr); 478 direct_buf_rx_info("vaddr aligned allocated"); 479 dbr_ring_cfg->base_paddr_unaligned = paddr; 480 if (!dbr_ring_cfg->base_vaddr_unaligned) { 481 direct_buf_rx_err("dir buf rx vaddr alloc failed"); 482 qdf_mem_free(mod_param->dbr_buf_pool); 483 return QDF_STATUS_E_NOMEM; 484 } 485 486 /* Alignment is defined to 8 for now. Will be advertised by FW */ 487 dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup( 488 (uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned, 489 DBR_RING_BASE_ALIGN); 490 ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned; 491 dbr_ring_cfg->base_paddr_aligned = qdf_roundup( 492 (uint64_t)dbr_ring_cfg->base_paddr_unaligned, 493 DBR_RING_BASE_ALIGN); 494 ring_params.ring_base_paddr = 495 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned; 496 ring_params.num_entries = num_entries; 497 srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC, 498 mod_param->mod_id, 499 wlan_objmgr_pdev_get_pdev_id(pdev), &ring_params); 500 501 if (!srng) { 502 direct_buf_rx_err("srng setup failed"); 503 qdf_mem_free(mod_param->dbr_buf_pool); 504 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 505 dbr_psoc_obj->osdev->dev, 506 ring_alloc_size, 507 dbr_ring_cfg->base_vaddr_unaligned, 508 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 509 return QDF_STATUS_E_FAILURE; 510 } 511 dbr_ring_cfg->srng = srng; 512 dbr_ring_cfg->tail_idx_addr = 513 hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng); 514 dbr_ring_cfg->head_idx_addr = 515 hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng); 516 dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size; 517 518 return target_if_dbr_fill_ring(pdev, mod_param); 519 } 520 521 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev, 522 struct direct_buf_rx_module_param *mod_param) 523 { 524 QDF_STATUS status; 525 526 direct_buf_rx_info("Init DBR srng"); 527 528 if (!mod_param) { 529 direct_buf_rx_err("dir buf rx module param is null"); 530 return QDF_STATUS_E_INVAL; 531 } 532 533 mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof( 534 struct direct_buf_rx_ring_cap)); 535 536 if (!mod_param->dbr_ring_cap) 537 return QDF_STATUS_E_NOMEM; 538 539 /* Allocate memory for DBR Ring Config */ 540 mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof( 541 struct direct_buf_rx_ring_cfg)); 542 543 if (!mod_param->dbr_ring_cfg) { 544 qdf_mem_free(mod_param->dbr_ring_cap); 545 return QDF_STATUS_E_NOMEM; 546 } 547 548 status = target_if_dbr_init_ring(pdev, mod_param); 549 550 if (QDF_IS_STATUS_ERROR(status)) { 551 direct_buf_rx_err("DBR ring init failed"); 552 qdf_mem_free(mod_param->dbr_ring_cfg); 553 qdf_mem_free(mod_param->dbr_ring_cap); 554 return QDF_STATUS_E_FAILURE; 555 } 556 557 return QDF_STATUS_SUCCESS; 558 } 559 560 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, 561 struct direct_buf_rx_module_param *mod_param) 562 { 563 QDF_STATUS status; 564 struct wlan_objmgr_psoc *psoc; 565 void *wmi_hdl; 566 struct direct_buf_rx_cfg_req dbr_cfg_req = {0}; 567 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 568 struct direct_buf_rx_ring_cap *dbr_ring_cap; 569 struct dbr_module_config *dbr_config; 570 571 direct_buf_rx_enter(); 572 573 psoc = wlan_pdev_get_psoc(pdev); 574 if (!psoc) { 575 direct_buf_rx_err("psoc is null"); 576 return QDF_STATUS_E_FAILURE; 577 } 578 579 dbr_ring_cfg = mod_param->dbr_ring_cfg; 580 dbr_ring_cap = mod_param->dbr_ring_cap; 581 dbr_config = &mod_param->dbr_config; 582 wmi_hdl = lmac_get_pdev_wmi_handle(pdev); 583 if (!wmi_hdl) { 584 direct_buf_rx_err("WMI handle null. Can't send WMI CMD"); 585 return QDF_STATUS_E_INVAL; 586 } 587 588 direct_buf_rx_debug("Sending DBR Ring CFG to target"); 589 dbr_cfg_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 590 /* Module ID numbering starts from 1 in FW. need to fix it */ 591 dbr_cfg_req.mod_id = mod_param->mod_id; 592 dbr_cfg_req.base_paddr_lo = (uint64_t)dbr_ring_cfg->base_paddr_aligned 593 & 0xFFFFFFFF; 594 dbr_cfg_req.base_paddr_hi = (uint64_t)dbr_ring_cfg->base_paddr_aligned 595 & 0xFFFFFFFF00000000; 596 dbr_cfg_req.head_idx_paddr_lo = (uint64_t)dbr_ring_cfg->head_idx_addr 597 & 0xFFFFFFFF; 598 dbr_cfg_req.head_idx_paddr_hi = (uint64_t)dbr_ring_cfg->head_idx_addr 599 & 0xFFFFFFFF00000000; 600 dbr_cfg_req.tail_idx_paddr_lo = (uint64_t)dbr_ring_cfg->tail_idx_addr 601 & 0xFFFFFFFF; 602 dbr_cfg_req.tail_idx_paddr_hi = (uint64_t)dbr_ring_cfg->tail_idx_addr 603 & 0xFFFFFFFF00000000; 604 dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min; 605 dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size; 606 dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event; 607 dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms; 608 direct_buf_rx_info("pdev id %d mod id %d base addr lo %x\n" 609 "base addr hi %x head idx addr lo %x\n" 610 "head idx addr hi %x tail idx addr lo %x\n" 611 "tail idx addr hi %x num ptr %d\n" 612 "num resp %d event timeout %d\n", 613 dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id, 614 dbr_cfg_req.base_paddr_lo, dbr_cfg_req.base_paddr_hi, 615 dbr_cfg_req.head_idx_paddr_lo, 616 dbr_cfg_req.head_idx_paddr_hi, 617 dbr_cfg_req.tail_idx_paddr_lo, 618 dbr_cfg_req.tail_idx_paddr_hi, 619 dbr_cfg_req.num_elems, 620 dbr_cfg_req.num_resp_per_event, 621 dbr_cfg_req.event_timeout_ms); 622 status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req); 623 624 return status; 625 } 626 627 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev, 628 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 629 enum DBR_MODULE mod_id) 630 { 631 QDF_STATUS status = QDF_STATUS_SUCCESS; 632 struct direct_buf_rx_module_param *mod_param; 633 634 direct_buf_rx_info("Init DBR ring for module %d", mod_id); 635 636 if (!dbr_pdev_obj) { 637 direct_buf_rx_err("dir buf rx object is null"); 638 return QDF_STATUS_E_INVAL; 639 } 640 641 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id]); 642 643 if (!mod_param) { 644 direct_buf_rx_err("dir buf rx module param is null"); 645 return QDF_STATUS_E_FAILURE; 646 } 647 648 direct_buf_rx_info("mod_param %pK", mod_param); 649 650 mod_param->mod_id = mod_id; 651 652 /* Initialize DMA ring now */ 653 status = target_if_dbr_init_srng(pdev, mod_param); 654 if (QDF_IS_STATUS_ERROR(status)) { 655 direct_buf_rx_err("DBR ring init failed %d", status); 656 return status; 657 } 658 659 /* Send CFG request command to firmware */ 660 status = target_if_dbr_cfg_tgt(pdev, mod_param); 661 if (QDF_IS_STATUS_ERROR(status)) { 662 direct_buf_rx_err("DBR config to target failed %d", status); 663 goto dbr_srng_init_failed; 664 } 665 666 return QDF_STATUS_SUCCESS; 667 668 dbr_srng_init_failed: 669 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id); 670 return status; 671 } 672 673 QDF_STATUS target_if_direct_buf_rx_module_register( 674 struct wlan_objmgr_pdev *pdev, uint8_t mod_id, 675 struct dbr_module_config *dbr_config, 676 bool (*dbr_rsp_handler) 677 (struct wlan_objmgr_pdev *pdev, 678 struct direct_buf_rx_data *dbr_data)) 679 { 680 QDF_STATUS status; 681 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 682 struct dbr_module_config *config = NULL; 683 684 if (!pdev) { 685 direct_buf_rx_err("pdev context passed is null"); 686 return QDF_STATUS_E_INVAL; 687 } 688 689 if (!dbr_rsp_handler) { 690 direct_buf_rx_err("Response handler is null"); 691 return QDF_STATUS_E_INVAL; 692 } 693 694 if (mod_id >= DBR_MODULE_MAX) { 695 direct_buf_rx_err("Invalid module id"); 696 return QDF_STATUS_E_INVAL; 697 } 698 699 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 700 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 701 702 if (!dbr_pdev_obj) { 703 direct_buf_rx_err("dir buf rx object is null"); 704 return QDF_STATUS_E_FAILURE; 705 } 706 707 direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); 708 709 if (!dbr_pdev_obj->dbr_mod_param) { 710 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 711 return QDF_STATUS_E_FAILURE; 712 } 713 714 if (mod_id >= dbr_pdev_obj->num_modules) { 715 direct_buf_rx_err("Module %d not supported in target", mod_id); 716 return QDF_STATUS_E_FAILURE; 717 } 718 719 config = &dbr_pdev_obj->dbr_mod_param[mod_id].dbr_config; 720 dbr_pdev_obj->dbr_mod_param[mod_id].dbr_rsp_handler = 721 dbr_rsp_handler; 722 *config = *dbr_config; 723 724 status = target_if_init_dbr_ring(pdev, dbr_pdev_obj, 725 (enum DBR_MODULE)mod_id); 726 727 return status; 728 } 729 730 QDF_STATUS target_if_direct_buf_rx_module_unregister( 731 struct wlan_objmgr_pdev *pdev, uint8_t mod_id) 732 { 733 QDF_STATUS status; 734 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 735 736 if (!pdev) { 737 direct_buf_rx_err("pdev context passed is null"); 738 return QDF_STATUS_E_INVAL; 739 } 740 741 if (mod_id >= DBR_MODULE_MAX) { 742 direct_buf_rx_err("Invalid module id"); 743 return QDF_STATUS_E_INVAL; 744 } 745 746 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 747 (pdev, 748 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 749 750 if (!dbr_pdev_obj) { 751 direct_buf_rx_err("dir buf rx object is null"); 752 return QDF_STATUS_E_FAILURE; 753 } 754 755 direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); 756 757 if (!dbr_pdev_obj->dbr_mod_param) { 758 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 759 return QDF_STATUS_E_FAILURE; 760 } 761 762 if (mod_id >= dbr_pdev_obj->num_modules) { 763 direct_buf_rx_err("Module %d not supported in target", mod_id); 764 return QDF_STATUS_E_FAILURE; 765 } 766 767 status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id); 768 769 return status; 770 } 771 772 static void *target_if_dbr_vaddr_lookup( 773 struct direct_buf_rx_module_param *mod_param, 774 qdf_dma_addr_t paddr, uint32_t cookie) 775 { 776 struct direct_buf_rx_buf_info *dbr_buf_pool; 777 778 dbr_buf_pool = mod_param->dbr_buf_pool; 779 780 if (dbr_buf_pool[cookie].paddr == paddr) { 781 return dbr_buf_pool[cookie].vaddr + 782 dbr_buf_pool[cookie].offset; 783 } 784 785 direct_buf_rx_err("Incorrect paddr found on cookie slot"); 786 return NULL; 787 } 788 789 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev, 790 uint8_t mod_id, qdf_dma_addr_t paddr, 791 uint32_t *cookie) 792 { 793 struct direct_buf_rx_buf_info *dbr_buf_pool; 794 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 795 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 796 struct direct_buf_rx_module_param *mod_param; 797 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 798 uint32_t idx; 799 800 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 801 if (!dbr_pdev_obj) { 802 direct_buf_rx_err("dir buf rx object is null"); 803 return QDF_STATUS_E_FAILURE; 804 } 805 806 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id]; 807 if (!mod_param) { 808 direct_buf_rx_err("dir buf rx module param is null"); 809 return QDF_STATUS_E_FAILURE; 810 } 811 812 dbr_ring_cfg = mod_param->dbr_ring_cfg; 813 dbr_buf_pool = mod_param->dbr_buf_pool; 814 815 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 816 if (dbr_buf_pool[idx].paddr && 817 dbr_buf_pool[idx].paddr == paddr) { 818 *cookie = idx; 819 return QDF_STATUS_SUCCESS; 820 } 821 } 822 823 return QDF_STATUS_E_FAILURE; 824 } 825 826 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev, 827 uint8_t mod_id, qdf_dma_addr_t paddr, 828 uint32_t cookie) 829 { 830 struct direct_buf_rx_module_param *mod_param; 831 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 832 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 833 void *vaddr; 834 QDF_STATUS status; 835 836 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 837 if (!dbr_pdev_obj) { 838 direct_buf_rx_err("dir buf rx object is null"); 839 return QDF_STATUS_E_FAILURE; 840 } 841 842 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id]; 843 if (!mod_param) { 844 direct_buf_rx_err("dir buf rx module param is null"); 845 return QDF_STATUS_E_FAILURE; 846 } 847 848 vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie); 849 if (!vaddr) 850 return QDF_STATUS_E_FAILURE; 851 852 status = target_if_dbr_replenish_ring(pdev, mod_param, 853 vaddr, cookie); 854 if (QDF_IS_STATUS_ERROR(status)) { 855 direct_buf_rx_err("Ring replenish failed"); 856 return QDF_STATUS_E_FAILURE; 857 } 858 859 return QDF_STATUS_SUCCESS; 860 } 861 862 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, 863 struct direct_buf_rx_module_param *mod_param, 864 struct direct_buf_rx_rsp *dbr_rsp, 865 struct direct_buf_rx_data *dbr_data, 866 uint8_t idx, uint32_t *cookie) 867 { 868 qdf_dma_addr_t paddr = 0; 869 uint32_t addr_hi; 870 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 871 struct direct_buf_rx_ring_cap *dbr_ring_cap; 872 struct wlan_objmgr_psoc *psoc; 873 874 psoc = wlan_pdev_get_psoc(pdev); 875 if (!psoc) { 876 direct_buf_rx_err("psoc is null"); 877 return QDF_STATUS_E_FAILURE; 878 } 879 880 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 881 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 882 883 if (!dbr_psoc_obj) { 884 direct_buf_rx_err("dir buf rx psoc object is null"); 885 return QDF_STATUS_E_FAILURE; 886 } 887 888 dbr_ring_cap = mod_param->dbr_ring_cap; 889 addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET( 890 dbr_rsp->dbr_entries[idx].paddr_hi); 891 paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 | 892 dbr_rsp->dbr_entries[idx].paddr_lo); 893 *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( 894 dbr_rsp->dbr_entries[idx].paddr_hi); 895 direct_buf_rx_info("Cookie = %d", *cookie); 896 dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); 897 dbr_data->cookie = *cookie; 898 dbr_data->paddr = paddr; 899 direct_buf_rx_info("Vaddr look up = %x", dbr_data->vaddr); 900 dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len; 901 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr, 902 QDF_DMA_FROM_DEVICE, 903 dbr_ring_cap->min_buf_size); 904 905 return QDF_STATUS_SUCCESS; 906 } 907 908 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, 909 uint8_t *data_buf, 910 uint32_t data_len) 911 { 912 int ret = 0; 913 uint8_t i = 0; 914 QDF_STATUS status; 915 uint32_t cookie = 0; 916 struct direct_buf_rx_rsp dbr_rsp = {0}; 917 struct direct_buf_rx_data dbr_data = {0}; 918 struct wlan_objmgr_psoc *psoc; 919 struct wlan_objmgr_pdev *pdev; 920 struct direct_buf_rx_buf_info *dbr_buf_pool; 921 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 922 struct direct_buf_rx_module_param *mod_param; 923 struct common_wmi_handle *wmi_handle; 924 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 925 926 direct_buf_rx_enter(); 927 928 psoc = target_if_get_psoc_from_scn_hdl(scn); 929 if (!psoc) { 930 direct_buf_rx_err("psoc is null"); 931 return QDF_STATUS_E_FAILURE; 932 } 933 934 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 935 if (!wmi_handle) { 936 direct_buf_rx_err("WMI handle is null"); 937 return QDF_STATUS_E_FAILURE; 938 } 939 940 if (wmi_extract_dbr_buf_release_fixed( 941 wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) { 942 direct_buf_rx_err("unable to extract DBR rsp fixed param"); 943 return QDF_STATUS_E_FAILURE; 944 } 945 946 direct_buf_rx_info("Num buf release entry = %d", 947 dbr_rsp.num_buf_release_entry); 948 949 pdev = wlan_objmgr_get_pdev_by_id(psoc, dbr_rsp.pdev_id, dbr_mod_id); 950 if (!pdev) { 951 direct_buf_rx_err("pdev is null"); 952 return QDF_STATUS_E_INVAL; 953 } 954 955 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 956 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 957 958 if (!dbr_pdev_obj) { 959 direct_buf_rx_err("dir buf rx object is null"); 960 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 961 return QDF_STATUS_E_FAILURE; 962 } 963 964 if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) { 965 direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id); 966 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 967 return QDF_STATUS_E_FAILURE; 968 } 969 mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id]); 970 971 if (!mod_param) { 972 direct_buf_rx_err("dir buf rx module param is null"); 973 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 974 return QDF_STATUS_E_FAILURE; 975 } 976 977 dbr_buf_pool = mod_param->dbr_buf_pool; 978 dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry * 979 sizeof(struct direct_buf_rx_entry)); 980 981 if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) { 982 direct_buf_rx_err("More than expected number of metadata"); 983 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 984 return QDF_STATUS_E_FAILURE; 985 } 986 987 for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { 988 if (wmi_extract_dbr_buf_release_entry( 989 wmi_handle, data_buf, i, 990 &dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) { 991 direct_buf_rx_err("Unable to extract DBR buf entry %d", 992 i+1); 993 qdf_mem_free(dbr_rsp.dbr_entries); 994 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 995 return QDF_STATUS_E_FAILURE; 996 } 997 status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp, 998 &dbr_data, i, &cookie); 999 1000 if (QDF_IS_STATUS_ERROR(status)) { 1001 direct_buf_rx_err("DBR data get failed"); 1002 qdf_mem_free(dbr_rsp.dbr_entries); 1003 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1004 return QDF_STATUS_E_FAILURE; 1005 } 1006 1007 dbr_data.meta_data_valid = false; 1008 if (i < dbr_rsp.num_meta_data_entry) { 1009 if (wmi_extract_dbr_buf_metadata( 1010 wmi_handle, data_buf, i, 1011 &dbr_data.meta_data) == QDF_STATUS_SUCCESS) 1012 dbr_data.meta_data_valid = true; 1013 } 1014 if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { 1015 status = target_if_dbr_replenish_ring(pdev, mod_param, 1016 dbr_data.vaddr, 1017 cookie); 1018 if (QDF_IS_STATUS_ERROR(status)) { 1019 direct_buf_rx_err("Ring replenish failed"); 1020 qdf_mem_free(dbr_rsp.dbr_entries); 1021 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1022 return QDF_STATUS_E_FAILURE; 1023 } 1024 } 1025 } 1026 1027 qdf_mem_free(dbr_rsp.dbr_entries); 1028 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1029 1030 return ret; 1031 } 1032 1033 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev, 1034 struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 1035 struct direct_buf_rx_module_param *mod_param) 1036 { 1037 uint32_t idx; 1038 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1039 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1040 struct direct_buf_rx_buf_info *dbr_buf_pool; 1041 1042 direct_buf_rx_enter(); 1043 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1044 dbr_ring_cap = mod_param->dbr_ring_cap; 1045 dbr_buf_pool = mod_param->dbr_buf_pool; 1046 1047 direct_buf_rx_info("dbr_ring_cfg %pK, dbr_ring_cap %pK dbr_buf_pool %pK", 1048 dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool); 1049 1050 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1051 direct_buf_rx_info("dbr buf pool unmap and free for ptr %d", 1052 idx); 1053 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, 1054 (qdf_dma_addr_t)dbr_buf_pool[idx].paddr, 1055 QDF_DMA_FROM_DEVICE, 1056 dbr_ring_cap->min_buf_size); 1057 qdf_mem_free(dbr_buf_pool[idx].vaddr); 1058 } 1059 1060 return QDF_STATUS_SUCCESS; 1061 } 1062 1063 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, 1064 struct direct_buf_rx_module_param *mod_param) 1065 { 1066 struct wlan_objmgr_psoc *psoc; 1067 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1068 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1069 1070 direct_buf_rx_enter(); 1071 psoc = wlan_pdev_get_psoc(pdev); 1072 if (!psoc) { 1073 direct_buf_rx_err("psoc is null"); 1074 return QDF_STATUS_E_FAILURE; 1075 } 1076 1077 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1078 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1079 1080 if (!dbr_psoc_obj) { 1081 direct_buf_rx_err("dir buf rx psoc object is null"); 1082 return QDF_STATUS_E_FAILURE; 1083 } 1084 direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj); 1085 1086 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1087 if (dbr_ring_cfg) { 1088 target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); 1089 hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); 1090 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1091 dbr_psoc_obj->osdev->dev, 1092 dbr_ring_cfg->ring_alloc_size, 1093 dbr_ring_cfg->base_vaddr_unaligned, 1094 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1095 } 1096 1097 return QDF_STATUS_SUCCESS; 1098 } 1099 1100 static QDF_STATUS target_if_dbr_deinit_srng( 1101 struct wlan_objmgr_pdev *pdev, 1102 struct direct_buf_rx_module_param *mod_param) 1103 { 1104 struct direct_buf_rx_buf_info *dbr_buf_pool; 1105 1106 direct_buf_rx_enter(); 1107 dbr_buf_pool = mod_param->dbr_buf_pool; 1108 direct_buf_rx_info("dbr buf pool %pK", dbr_buf_pool); 1109 target_if_dbr_deinit_ring(pdev, mod_param); 1110 if (mod_param->dbr_buf_pool) 1111 qdf_mem_free(dbr_buf_pool); 1112 mod_param->dbr_buf_pool = NULL; 1113 1114 return QDF_STATUS_SUCCESS; 1115 } 1116 1117 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev, 1118 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1119 enum DBR_MODULE mod_id) 1120 { 1121 struct direct_buf_rx_module_param *mod_param; 1122 1123 direct_buf_rx_enter(); 1124 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id]); 1125 1126 if (!mod_param) { 1127 direct_buf_rx_err("dir buf rx module param is null"); 1128 return QDF_STATUS_E_FAILURE; 1129 } 1130 direct_buf_rx_info("mod_param %pK", mod_param); 1131 direct_buf_rx_info("dbr_ring_cap %pK", mod_param->dbr_ring_cap); 1132 target_if_dbr_deinit_srng(pdev, mod_param); 1133 if (mod_param->dbr_ring_cap) 1134 qdf_mem_free(mod_param->dbr_ring_cap); 1135 mod_param->dbr_ring_cap = NULL; 1136 if (mod_param->dbr_ring_cfg) 1137 qdf_mem_free(mod_param->dbr_ring_cfg); 1138 mod_param->dbr_ring_cfg = NULL; 1139 1140 return QDF_STATUS_SUCCESS; 1141 } 1142 1143 QDF_STATUS target_if_direct_buf_rx_register_events( 1144 struct wlan_objmgr_psoc *psoc) 1145 { 1146 int ret; 1147 1148 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 1149 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 1150 return QDF_STATUS_E_INVAL; 1151 } 1152 1153 ret = wmi_unified_register_event_handler( 1154 get_wmi_unified_hdl_from_psoc(psoc), 1155 wmi_dma_buf_release_event_id, 1156 target_if_direct_buf_rx_rsp_event_handler, 1157 WMI_RX_UMAC_CTX); 1158 1159 if (ret) 1160 direct_buf_rx_info("event handler not supported", ret); 1161 1162 return QDF_STATUS_SUCCESS; 1163 } 1164 1165 QDF_STATUS target_if_direct_buf_rx_unregister_events( 1166 struct wlan_objmgr_psoc *psoc) 1167 { 1168 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 1169 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 1170 return QDF_STATUS_E_INVAL; 1171 } 1172 1173 wmi_unified_unregister_event_handler( 1174 get_wmi_unified_hdl_from_psoc(psoc), 1175 wmi_dma_buf_release_event_id); 1176 1177 return QDF_STATUS_SUCCESS; 1178 } 1179 1180 QDF_STATUS target_if_direct_buf_rx_print_ring_stat( 1181 struct wlan_objmgr_pdev *pdev) 1182 { 1183 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1184 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1185 struct wlan_objmgr_psoc *psoc; 1186 void *srng, *hal_soc; 1187 uint32_t hp = 0, tp = 0; 1188 struct direct_buf_rx_module_param *mod_param; 1189 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1190 uint8_t num_modules, mod_idx; 1191 1192 if (!pdev) { 1193 direct_buf_rx_err("pdev is null"); 1194 return QDF_STATUS_E_INVAL; 1195 } 1196 1197 psoc = wlan_pdev_get_psoc(pdev); 1198 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1199 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1200 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1201 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1202 hal_soc = dbr_psoc_obj->hal_soc; 1203 num_modules = dbr_pdev_obj->num_modules; 1204 direct_buf_rx_err("--------------------------------------------------"); 1205 direct_buf_rx_err("| Module ID | Module | Head Idx | Tail Idx |"); 1206 direct_buf_rx_err("--------------------------------------------------"); 1207 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 1208 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_idx]; 1209 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1210 srng = dbr_ring_cfg->srng; 1211 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 1212 direct_buf_rx_err("|%11d|%14s|%10x|%10x|", 1213 mod_idx, 1214 g_dbr_module_name[mod_idx].module_name_str, 1215 hp, tp); 1216 } 1217 direct_buf_rx_err("--------------------------------------------------"); 1218 1219 return QDF_STATUS_SUCCESS; 1220 } 1221 1222 QDF_STATUS 1223 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, 1224 struct module_ring_params *param, 1225 int mod_id) 1226 { 1227 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1228 struct direct_buf_rx_module_param *dbr_mod_param; 1229 1230 if (!pdev) { 1231 direct_buf_rx_err("pdev context passed is null"); 1232 return QDF_STATUS_E_INVAL; 1233 } 1234 1235 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 1236 (pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1237 1238 if (!dbr_pdev_obj) { 1239 direct_buf_rx_err("dir buf rx object is null"); 1240 return QDF_STATUS_E_FAILURE; 1241 } 1242 1243 dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id]; 1244 param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr; 1245 param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size; 1246 1247 return QDF_STATUS_SUCCESS; 1248 } 1249