1 /* 2 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "target_if.h" 20 #include "wlan_lmac_if_def.h" 21 #include "target_if_direct_buf_rx_main.h" 22 #include <target_if_direct_buf_rx_api.h> 23 #include "hal_api.h" 24 #include <service_ready_util.h> 25 #include <init_deinit_lmac.h> 26 27 /** 28 * struct module_name : Module name information structure 29 * @module_name_str : Module name subscribing to DBR 30 */ 31 struct module_name { 32 unsigned char module_name_str[QDF_MAX_NAME_SIZE]; 33 }; 34 35 static const struct module_name g_dbr_module_name[DBR_MODULE_MAX] = { 36 [DBR_MODULE_SPECTRAL] = {"SPECTRAL"}, 37 [DBR_MODULE_CFR] = {"CFR"}, 38 }; 39 40 static uint8_t get_num_dbr_modules_per_pdev(struct wlan_objmgr_pdev *pdev) 41 { 42 struct wlan_objmgr_psoc *psoc; 43 struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; 44 uint8_t num_dbr_ring_caps, cap_idx, pdev_id, num_modules; 45 struct target_psoc_info *tgt_psoc_info; 46 47 psoc = wlan_pdev_get_psoc(pdev); 48 49 if (!psoc) { 50 direct_buf_rx_err("psoc is null"); 51 return 0; 52 } 53 54 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 55 if (!tgt_psoc_info) { 56 direct_buf_rx_err("target_psoc_info is null"); 57 return 0; 58 } 59 num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); 60 dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); 61 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 62 num_modules = 0; 63 64 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 65 if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) 66 num_modules++; 67 } 68 69 return num_modules; 70 } 71 72 static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev, 73 struct direct_buf_rx_module_param *mod_param) 74 { 75 struct wlan_objmgr_psoc *psoc; 76 struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; 77 uint8_t cap_idx; 78 bool cap_found = false; 79 enum DBR_MODULE mod_id = mod_param->mod_id; 80 uint32_t num_dbr_ring_caps, pdev_id; 81 struct target_psoc_info *tgt_psoc_info; 82 83 psoc = wlan_pdev_get_psoc(pdev); 84 85 if (!psoc) { 86 direct_buf_rx_err("psoc is null"); 87 return QDF_STATUS_E_INVAL; 88 } 89 90 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 91 if (!tgt_psoc_info) { 92 direct_buf_rx_err("target_psoc_info is null"); 93 return QDF_STATUS_E_INVAL; 94 } 95 96 num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); 97 dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); 98 pdev_id = mod_param->pdev_id; 99 100 for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { 101 if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) { 102 if (dbr_ring_cap[cap_idx].mod_id == mod_id) { 103 mod_param->dbr_ring_cap->ring_elems_min = 104 dbr_ring_cap[cap_idx].ring_elems_min; 105 mod_param->dbr_ring_cap->min_buf_size = 106 dbr_ring_cap[cap_idx].min_buf_size; 107 mod_param->dbr_ring_cap->min_buf_align = 108 dbr_ring_cap[cap_idx].min_buf_align; 109 cap_found = true; 110 } 111 } 112 } 113 114 if (!cap_found) { 115 direct_buf_rx_err("No cap found for module %d in pdev %d", 116 mod_id, pdev_id); 117 return QDF_STATUS_E_FAILURE; 118 } 119 120 return QDF_STATUS_SUCCESS; 121 } 122 123 QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( 124 struct wlan_objmgr_pdev *pdev, void *data) 125 { 126 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 127 struct wlan_objmgr_psoc *psoc; 128 uint8_t num_modules; 129 QDF_STATUS status; 130 131 direct_buf_rx_enter(); 132 133 if (!pdev) { 134 direct_buf_rx_err("pdev context passed is null"); 135 return QDF_STATUS_E_INVAL; 136 } 137 138 psoc = wlan_pdev_get_psoc(pdev); 139 140 if (!psoc) { 141 direct_buf_rx_err("psoc is null"); 142 return QDF_STATUS_E_INVAL; 143 } 144 145 dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj)); 146 147 if (!dbr_pdev_obj) 148 return QDF_STATUS_E_NOMEM; 149 150 direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); 151 152 status = wlan_objmgr_pdev_component_obj_attach(pdev, 153 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 154 dbr_pdev_obj, QDF_STATUS_SUCCESS); 155 156 if (status != QDF_STATUS_SUCCESS) { 157 direct_buf_rx_err("Failed to attach dir buf rx component %d", 158 status); 159 qdf_mem_free(dbr_pdev_obj); 160 return status; 161 } 162 163 num_modules = get_num_dbr_modules_per_pdev(pdev); 164 direct_buf_rx_info("Number of modules = %d pdev %d", num_modules, 165 wlan_objmgr_pdev_get_pdev_id(pdev)); 166 dbr_pdev_obj->num_modules = num_modules; 167 168 if (!dbr_pdev_obj->num_modules) { 169 direct_buf_rx_info("Number of modules = %d", num_modules); 170 return QDF_STATUS_SUCCESS; 171 } 172 173 direct_buf_rx_info("sring number = %d", DBR_SRNG_NUM); 174 dbr_pdev_obj->dbr_mod_param = qdf_mem_malloc(num_modules * 175 DBR_SRNG_NUM * 176 sizeof(struct direct_buf_rx_module_param)); 177 178 if (!dbr_pdev_obj->dbr_mod_param) { 179 direct_buf_rx_err("alloc dbr mod param fail"); 180 wlan_objmgr_pdev_component_obj_detach(pdev, 181 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 182 dbr_pdev_obj); 183 qdf_mem_free(dbr_pdev_obj); 184 return QDF_STATUS_E_NOMEM; 185 } 186 187 return QDF_STATUS_SUCCESS; 188 } 189 190 QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler( 191 struct wlan_objmgr_pdev *pdev, void *data) 192 { 193 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 194 QDF_STATUS status; 195 uint8_t num_modules, mod_idx, srng_id; 196 197 if (!pdev) { 198 direct_buf_rx_err("pdev context passed is null"); 199 return QDF_STATUS_E_INVAL; 200 } 201 202 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 203 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 204 205 if (!dbr_pdev_obj) { 206 direct_buf_rx_err("dir buf rx object is null"); 207 return QDF_STATUS_E_FAILURE; 208 } 209 210 num_modules = dbr_pdev_obj->num_modules; 211 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 212 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) 213 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 214 mod_idx, srng_id); 215 } 216 217 qdf_mem_free(dbr_pdev_obj->dbr_mod_param); 218 dbr_pdev_obj->dbr_mod_param = NULL; 219 220 status = wlan_objmgr_pdev_component_obj_detach(pdev, 221 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 222 dbr_pdev_obj); 223 224 if (status != QDF_STATUS_SUCCESS) { 225 direct_buf_rx_err("failed to detach dir buf rx component %d", 226 status); 227 } 228 229 qdf_mem_free(dbr_pdev_obj); 230 231 return status; 232 } 233 234 QDF_STATUS target_if_direct_buf_rx_psoc_create_handler( 235 struct wlan_objmgr_psoc *psoc, void *data) 236 { 237 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 238 QDF_STATUS status; 239 240 direct_buf_rx_enter(); 241 242 if (!psoc) { 243 direct_buf_rx_err("psoc context passed is null"); 244 return QDF_STATUS_E_INVAL; 245 } 246 247 dbr_psoc_obj = qdf_mem_malloc(sizeof(*dbr_psoc_obj)); 248 249 if (!dbr_psoc_obj) 250 return QDF_STATUS_E_NOMEM; 251 252 direct_buf_rx_info("Dbr psoc obj %pK", dbr_psoc_obj); 253 254 status = wlan_objmgr_psoc_component_obj_attach(psoc, 255 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_psoc_obj, 256 QDF_STATUS_SUCCESS); 257 258 if (status != QDF_STATUS_SUCCESS) { 259 direct_buf_rx_err("Failed to attach dir buf rx component %d", 260 status); 261 goto attach_error; 262 } 263 264 return status; 265 266 attach_error: 267 qdf_mem_free(dbr_psoc_obj); 268 269 return status; 270 } 271 272 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler( 273 struct wlan_objmgr_psoc *psoc, void *data) 274 { 275 QDF_STATUS status; 276 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 277 278 direct_buf_rx_enter(); 279 280 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 281 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 282 283 if (!dbr_psoc_obj) { 284 direct_buf_rx_err("dir buf rx psoc obj is null"); 285 return QDF_STATUS_E_FAILURE; 286 } 287 288 status = wlan_objmgr_psoc_component_obj_detach(psoc, 289 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, 290 dbr_psoc_obj); 291 292 if (status != QDF_STATUS_SUCCESS) { 293 direct_buf_rx_err("failed to detach dir buf rx component %d", 294 status); 295 } 296 297 qdf_mem_free(dbr_psoc_obj); 298 299 return status; 300 } 301 302 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, 303 struct direct_buf_rx_module_param *mod_param, 304 void *aligned_vaddr, uint32_t cookie) 305 { 306 uint64_t *ring_entry; 307 uint32_t dw_lo, dw_hi = 0, map_status; 308 void *hal_soc, *srng; 309 qdf_dma_addr_t paddr; 310 struct wlan_objmgr_psoc *psoc; 311 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 312 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 313 struct direct_buf_rx_ring_cap *dbr_ring_cap; 314 struct direct_buf_rx_buf_info *dbr_buf_pool; 315 316 dbr_ring_cfg = mod_param->dbr_ring_cfg; 317 dbr_ring_cap = mod_param->dbr_ring_cap; 318 dbr_buf_pool = mod_param->dbr_buf_pool; 319 320 psoc = wlan_pdev_get_psoc(pdev); 321 322 if (!psoc) { 323 direct_buf_rx_err("psoc is null"); 324 return QDF_STATUS_E_FAILURE; 325 } 326 327 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 328 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 329 330 if (!dbr_psoc_obj) { 331 direct_buf_rx_err("dir buf rx psoc object is null"); 332 return QDF_STATUS_E_FAILURE; 333 } 334 335 hal_soc = dbr_psoc_obj->hal_soc; 336 srng = dbr_ring_cfg->srng; 337 if (!aligned_vaddr) { 338 direct_buf_rx_err("aligned vaddr is null"); 339 return QDF_STATUS_SUCCESS; 340 } 341 342 map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev, 343 aligned_vaddr, 344 QDF_DMA_FROM_DEVICE, 345 dbr_ring_cap->min_buf_size, 346 &paddr); 347 if (map_status) { 348 direct_buf_rx_err("mem map failed status = %d", map_status); 349 return QDF_STATUS_E_FAILURE; 350 } 351 352 QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align)); 353 dbr_buf_pool[cookie].paddr = paddr; 354 355 hal_srng_access_start(hal_soc, srng); 356 ring_entry = hal_srng_src_get_next(hal_soc, srng); 357 QDF_ASSERT(ring_entry); 358 dw_lo = (uint64_t)paddr & 0xFFFFFFFF; 359 WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32); 360 WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie); 361 *ring_entry = (uint64_t)dw_hi << 32 | dw_lo; 362 hal_srng_access_end(hal_soc, srng); 363 364 return QDF_STATUS_SUCCESS; 365 } 366 367 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev, 368 struct direct_buf_rx_module_param *mod_param) 369 { 370 uint32_t idx; 371 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 372 struct direct_buf_rx_ring_cap *dbr_ring_cap; 373 struct direct_buf_rx_buf_info *dbr_buf_pool; 374 QDF_STATUS status; 375 376 direct_buf_rx_enter(); 377 378 dbr_ring_cfg = mod_param->dbr_ring_cfg; 379 dbr_ring_cap = mod_param->dbr_ring_cap; 380 dbr_buf_pool = mod_param->dbr_buf_pool; 381 382 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 383 void *buf_vaddr_unaligned = NULL, *buf_vaddr_aligned; 384 dma_addr_t buf_paddr_aligned, buf_paddr_unaligned; 385 386 buf_vaddr_aligned = qdf_aligned_malloc( 387 &dbr_ring_cap->min_buf_size, &buf_vaddr_unaligned, 388 &buf_paddr_unaligned, &buf_paddr_aligned, 389 dbr_ring_cap->min_buf_align); 390 391 if (!buf_vaddr_aligned) { 392 direct_buf_rx_err("dir buf rx ring alloc failed"); 393 return QDF_STATUS_E_NOMEM; 394 } 395 dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned; 396 dbr_buf_pool[idx].offset = buf_vaddr_aligned - 397 buf_vaddr_unaligned; 398 dbr_buf_pool[idx].cookie = idx; 399 status = target_if_dbr_replenish_ring(pdev, mod_param, 400 buf_vaddr_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_vaddr_unaligned); 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 mod_param->pdev_id, &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 wmi_unified_t 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 = mod_param->pdev_id; 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, uint8_t srng_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, srng %d", 635 mod_id, srng_id); 636 637 if (!dbr_pdev_obj) { 638 direct_buf_rx_err("dir buf rx object is null"); 639 return QDF_STATUS_E_INVAL; 640 } 641 642 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 643 644 if (!mod_param) { 645 direct_buf_rx_err("dir buf rx module param is null"); 646 return QDF_STATUS_E_FAILURE; 647 } 648 649 direct_buf_rx_info("mod_param %pK", mod_param); 650 651 mod_param->mod_id = mod_id; 652 mod_param->pdev_id = dbr_get_pdev_id( 653 srng_id, wlan_objmgr_pdev_get_pdev_id(pdev)); 654 655 /* Initialize DMA ring now */ 656 status = target_if_dbr_init_srng(pdev, mod_param); 657 if (QDF_IS_STATUS_ERROR(status)) { 658 direct_buf_rx_err("DBR ring init failed %d", status); 659 return status; 660 } 661 662 /* Send CFG request command to firmware */ 663 status = target_if_dbr_cfg_tgt(pdev, mod_param); 664 if (QDF_IS_STATUS_ERROR(status)) { 665 direct_buf_rx_err("DBR config to target failed %d", status); 666 goto dbr_srng_init_failed; 667 } 668 669 return QDF_STATUS_SUCCESS; 670 671 dbr_srng_init_failed: 672 target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id); 673 return status; 674 } 675 676 QDF_STATUS target_if_direct_buf_rx_module_register( 677 struct wlan_objmgr_pdev *pdev, uint8_t mod_id, 678 struct dbr_module_config *dbr_config, 679 bool (*dbr_rsp_handler) 680 (struct wlan_objmgr_pdev *pdev, 681 struct direct_buf_rx_data *dbr_data)) 682 { 683 QDF_STATUS status; 684 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 685 struct dbr_module_config *config = NULL; 686 struct direct_buf_rx_module_param *mod_param; 687 uint8_t srng_id; 688 689 if (!pdev) { 690 direct_buf_rx_err("pdev context passed is null"); 691 return QDF_STATUS_E_INVAL; 692 } 693 694 if (!dbr_rsp_handler) { 695 direct_buf_rx_err("Response handler is null"); 696 return QDF_STATUS_E_INVAL; 697 } 698 699 if (mod_id >= DBR_MODULE_MAX) { 700 direct_buf_rx_err("Invalid module id"); 701 return QDF_STATUS_E_INVAL; 702 } 703 704 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 705 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 706 707 if (!dbr_pdev_obj) { 708 direct_buf_rx_err("dir buf rx object is null"); 709 return QDF_STATUS_E_FAILURE; 710 } 711 712 direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); 713 714 if (!dbr_pdev_obj->dbr_mod_param) { 715 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 716 return QDF_STATUS_E_FAILURE; 717 } 718 719 if (mod_id >= dbr_pdev_obj->num_modules) { 720 direct_buf_rx_err("Module %d not supported in target", mod_id); 721 return QDF_STATUS_E_FAILURE; 722 } 723 724 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 725 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 726 config = &mod_param->dbr_config; 727 mod_param->dbr_rsp_handler = dbr_rsp_handler; 728 *config = *dbr_config; 729 730 status = target_if_init_dbr_ring(pdev, dbr_pdev_obj, 731 (enum DBR_MODULE)mod_id, 732 srng_id); 733 if (QDF_IS_STATUS_ERROR(status)) 734 direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d", 735 srng_id, status); 736 } 737 738 return status; 739 } 740 741 QDF_STATUS target_if_direct_buf_rx_module_unregister( 742 struct wlan_objmgr_pdev *pdev, uint8_t mod_id) 743 { 744 QDF_STATUS status; 745 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 746 uint8_t srng_id; 747 748 if (!pdev) { 749 direct_buf_rx_err("pdev context passed is null"); 750 return QDF_STATUS_E_INVAL; 751 } 752 753 if (mod_id >= DBR_MODULE_MAX) { 754 direct_buf_rx_err("Invalid module id"); 755 return QDF_STATUS_E_INVAL; 756 } 757 758 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 759 (pdev, 760 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 761 762 if (!dbr_pdev_obj) { 763 direct_buf_rx_err("dir buf rx object is null"); 764 return QDF_STATUS_E_FAILURE; 765 } 766 767 direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); 768 769 if (!dbr_pdev_obj->dbr_mod_param) { 770 direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL"); 771 return QDF_STATUS_E_FAILURE; 772 } 773 774 if (mod_id >= dbr_pdev_obj->num_modules) { 775 direct_buf_rx_err("Module %d not supported in target", mod_id); 776 return QDF_STATUS_E_FAILURE; 777 } 778 779 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 780 status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, 781 mod_id, srng_id); 782 direct_buf_rx_info("status %d", status); 783 } 784 785 return status; 786 } 787 788 static void *target_if_dbr_vaddr_lookup( 789 struct direct_buf_rx_module_param *mod_param, 790 qdf_dma_addr_t paddr, uint32_t cookie) 791 { 792 struct direct_buf_rx_buf_info *dbr_buf_pool; 793 794 dbr_buf_pool = mod_param->dbr_buf_pool; 795 796 if (dbr_buf_pool[cookie].paddr == paddr) { 797 return dbr_buf_pool[cookie].vaddr + 798 dbr_buf_pool[cookie].offset; 799 } 800 801 direct_buf_rx_err("Incorrect paddr found on cookie slot"); 802 return NULL; 803 } 804 805 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev, 806 uint8_t mod_id, qdf_dma_addr_t paddr, 807 uint32_t *cookie, uint8_t srng_id) 808 { 809 struct direct_buf_rx_buf_info *dbr_buf_pool; 810 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 811 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 812 struct direct_buf_rx_module_param *mod_param; 813 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 814 uint32_t idx; 815 816 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 817 if (!dbr_pdev_obj) { 818 direct_buf_rx_err("dir buf rx object is null"); 819 return QDF_STATUS_E_FAILURE; 820 } 821 822 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 823 if (!mod_param) { 824 direct_buf_rx_err("dir buf rx module param is null"); 825 return QDF_STATUS_E_FAILURE; 826 } 827 828 dbr_ring_cfg = mod_param->dbr_ring_cfg; 829 dbr_buf_pool = mod_param->dbr_buf_pool; 830 831 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 832 if (dbr_buf_pool[idx].paddr && 833 dbr_buf_pool[idx].paddr == paddr) { 834 *cookie = idx; 835 return QDF_STATUS_SUCCESS; 836 } 837 } 838 839 return QDF_STATUS_E_FAILURE; 840 } 841 842 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev, 843 uint8_t mod_id, qdf_dma_addr_t paddr, 844 uint32_t cookie, uint8_t srng_id) 845 { 846 struct direct_buf_rx_module_param *mod_param; 847 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 848 enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX; 849 void *vaddr; 850 QDF_STATUS status; 851 852 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id); 853 if (!dbr_pdev_obj) { 854 direct_buf_rx_err("dir buf rx object is null"); 855 return QDF_STATUS_E_FAILURE; 856 } 857 858 mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 859 if (!mod_param) { 860 direct_buf_rx_err("dir buf rx module param is null"); 861 return QDF_STATUS_E_FAILURE; 862 } 863 864 vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie); 865 if (!vaddr) 866 return QDF_STATUS_E_FAILURE; 867 868 status = target_if_dbr_replenish_ring(pdev, mod_param, 869 vaddr, cookie); 870 if (QDF_IS_STATUS_ERROR(status)) { 871 direct_buf_rx_err("Ring replenish failed"); 872 return QDF_STATUS_E_FAILURE; 873 } 874 875 return QDF_STATUS_SUCCESS; 876 } 877 878 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, 879 struct direct_buf_rx_module_param *mod_param, 880 struct direct_buf_rx_rsp *dbr_rsp, 881 struct direct_buf_rx_data *dbr_data, 882 uint8_t idx, uint32_t *cookie) 883 { 884 qdf_dma_addr_t paddr = 0; 885 uint32_t addr_hi; 886 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 887 struct direct_buf_rx_ring_cap *dbr_ring_cap; 888 struct wlan_objmgr_psoc *psoc; 889 890 psoc = wlan_pdev_get_psoc(pdev); 891 if (!psoc) { 892 direct_buf_rx_err("psoc is null"); 893 return QDF_STATUS_E_FAILURE; 894 } 895 896 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 897 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 898 899 if (!dbr_psoc_obj) { 900 direct_buf_rx_err("dir buf rx psoc object is null"); 901 return QDF_STATUS_E_FAILURE; 902 } 903 904 dbr_ring_cap = mod_param->dbr_ring_cap; 905 addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET( 906 dbr_rsp->dbr_entries[idx].paddr_hi); 907 paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 | 908 dbr_rsp->dbr_entries[idx].paddr_lo); 909 *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( 910 dbr_rsp->dbr_entries[idx].paddr_hi); 911 dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); 912 dbr_data->cookie = *cookie; 913 dbr_data->paddr = paddr; 914 direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK", 915 dbr_data->cookie, dbr_data->vaddr); 916 dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len; 917 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr, 918 QDF_DMA_FROM_DEVICE, 919 dbr_ring_cap->min_buf_size); 920 921 return QDF_STATUS_SUCCESS; 922 } 923 924 #ifdef DBR_MULTI_SRNG_ENABLE 925 /** 926 * dbr_get_pdev_and_srng_id() - get pdev object and srng id 927 * 928 * @psoc: pointer to psoc object 929 * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid 930 * @srng_id: pointer to return srng id 931 * 932 * Return : pointer to pdev 933 */ 934 static struct wlan_objmgr_pdev * 935 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 936 uint8_t *srng_id) 937 { 938 struct wlan_objmgr_pdev *pdev; 939 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 940 941 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 942 if (!pdev) { 943 pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC, 944 dbr_mod_id); 945 if (pdev) { 946 direct_buf_rx_info("update srng id from %d to %d", 947 *srng_id, pdev_id); 948 *srng_id = pdev_id; 949 } 950 } 951 952 return pdev; 953 } 954 #else 955 static struct wlan_objmgr_pdev * 956 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 957 uint8_t *srng_id) 958 { 959 struct wlan_objmgr_pdev *pdev; 960 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 961 962 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id); 963 964 return pdev; 965 } 966 #endif 967 968 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, 969 uint8_t *data_buf, 970 uint32_t data_len) 971 { 972 int ret = 0; 973 uint8_t i = 0; 974 QDF_STATUS status; 975 uint32_t cookie = 0; 976 struct direct_buf_rx_rsp dbr_rsp = {0}; 977 struct direct_buf_rx_data dbr_data = {0}; 978 struct wlan_objmgr_psoc *psoc; 979 struct wlan_objmgr_pdev *pdev; 980 struct direct_buf_rx_buf_info *dbr_buf_pool; 981 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 982 struct direct_buf_rx_module_param *mod_param; 983 struct wmi_unified *wmi_handle; 984 wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; 985 uint8_t srng_id = 0; 986 987 direct_buf_rx_enter(); 988 989 psoc = target_if_get_psoc_from_scn_hdl(scn); 990 if (!psoc) { 991 direct_buf_rx_err("psoc is null"); 992 return QDF_STATUS_E_FAILURE; 993 } 994 995 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 996 if (!wmi_handle) { 997 direct_buf_rx_err("WMI handle is null"); 998 return QDF_STATUS_E_FAILURE; 999 } 1000 1001 if (wmi_extract_dbr_buf_release_fixed( 1002 wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) { 1003 direct_buf_rx_err("unable to extract DBR rsp fixed param"); 1004 return QDF_STATUS_E_FAILURE; 1005 } 1006 1007 direct_buf_rx_debug("Num buf release entry = %d", 1008 dbr_rsp.num_buf_release_entry); 1009 1010 pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id, 1011 &srng_id); 1012 if (!pdev || (srng_id >= DBR_SRNG_NUM)) { 1013 direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d", 1014 pdev, srng_id); 1015 return QDF_STATUS_E_INVAL; 1016 } 1017 1018 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1019 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1020 1021 if (!dbr_pdev_obj) { 1022 direct_buf_rx_err("dir buf rx object is null"); 1023 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1024 return QDF_STATUS_E_FAILURE; 1025 } 1026 1027 if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) { 1028 direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id); 1029 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1030 return QDF_STATUS_E_FAILURE; 1031 } 1032 mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]); 1033 1034 if (!mod_param) { 1035 direct_buf_rx_err("dir buf rx module param is null"); 1036 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1037 return QDF_STATUS_E_FAILURE; 1038 } 1039 1040 dbr_buf_pool = mod_param->dbr_buf_pool; 1041 dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry * 1042 sizeof(struct direct_buf_rx_entry)); 1043 1044 if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) { 1045 direct_buf_rx_err("More than expected number of metadata"); 1046 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1047 return QDF_STATUS_E_FAILURE; 1048 } 1049 1050 for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { 1051 if (wmi_extract_dbr_buf_release_entry( 1052 wmi_handle, data_buf, i, 1053 &dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) { 1054 direct_buf_rx_err("Unable to extract DBR buf entry %d", 1055 i+1); 1056 qdf_mem_free(dbr_rsp.dbr_entries); 1057 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1058 return QDF_STATUS_E_FAILURE; 1059 } 1060 status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp, 1061 &dbr_data, i, &cookie); 1062 1063 if (QDF_IS_STATUS_ERROR(status)) { 1064 direct_buf_rx_err("DBR data get failed"); 1065 qdf_mem_free(dbr_rsp.dbr_entries); 1066 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1067 return QDF_STATUS_E_FAILURE; 1068 } 1069 1070 dbr_data.meta_data_valid = false; 1071 if (i < dbr_rsp.num_meta_data_entry) { 1072 if (wmi_extract_dbr_buf_metadata( 1073 wmi_handle, data_buf, i, 1074 &dbr_data.meta_data) == QDF_STATUS_SUCCESS) 1075 dbr_data.meta_data_valid = true; 1076 } 1077 if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { 1078 status = target_if_dbr_replenish_ring(pdev, mod_param, 1079 dbr_data.vaddr, 1080 cookie); 1081 if (QDF_IS_STATUS_ERROR(status)) { 1082 direct_buf_rx_err("Ring replenish failed"); 1083 qdf_mem_free(dbr_rsp.dbr_entries); 1084 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1085 return QDF_STATUS_E_FAILURE; 1086 } 1087 } 1088 } 1089 1090 qdf_mem_free(dbr_rsp.dbr_entries); 1091 wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); 1092 1093 return ret; 1094 } 1095 1096 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev, 1097 struct direct_buf_rx_psoc_obj *dbr_psoc_obj, 1098 struct direct_buf_rx_module_param *mod_param) 1099 { 1100 uint32_t idx; 1101 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1102 struct direct_buf_rx_ring_cap *dbr_ring_cap; 1103 struct direct_buf_rx_buf_info *dbr_buf_pool; 1104 1105 direct_buf_rx_enter(); 1106 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1107 dbr_ring_cap = mod_param->dbr_ring_cap; 1108 dbr_buf_pool = mod_param->dbr_buf_pool; 1109 1110 direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK", 1111 dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool); 1112 1113 for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) { 1114 qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, 1115 (qdf_dma_addr_t)dbr_buf_pool[idx].paddr, 1116 QDF_DMA_FROM_DEVICE, 1117 dbr_ring_cap->min_buf_size); 1118 qdf_mem_free(dbr_buf_pool[idx].vaddr); 1119 } 1120 1121 return QDF_STATUS_SUCCESS; 1122 } 1123 1124 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, 1125 struct direct_buf_rx_module_param *mod_param) 1126 { 1127 struct wlan_objmgr_psoc *psoc; 1128 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1129 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1130 1131 direct_buf_rx_enter(); 1132 psoc = wlan_pdev_get_psoc(pdev); 1133 if (!psoc) { 1134 direct_buf_rx_err("psoc is null"); 1135 return QDF_STATUS_E_FAILURE; 1136 } 1137 1138 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1139 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1140 1141 if (!dbr_psoc_obj) { 1142 direct_buf_rx_err("dir buf rx psoc object is null"); 1143 return QDF_STATUS_E_FAILURE; 1144 } 1145 direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj); 1146 1147 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1148 if (dbr_ring_cfg) { 1149 target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); 1150 hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); 1151 qdf_mem_free_consistent(dbr_psoc_obj->osdev, 1152 dbr_psoc_obj->osdev->dev, 1153 dbr_ring_cfg->ring_alloc_size, 1154 dbr_ring_cfg->base_vaddr_unaligned, 1155 (qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0); 1156 } 1157 1158 return QDF_STATUS_SUCCESS; 1159 } 1160 1161 static QDF_STATUS target_if_dbr_deinit_srng( 1162 struct wlan_objmgr_pdev *pdev, 1163 struct direct_buf_rx_module_param *mod_param) 1164 { 1165 struct direct_buf_rx_buf_info *dbr_buf_pool; 1166 1167 direct_buf_rx_enter(); 1168 dbr_buf_pool = mod_param->dbr_buf_pool; 1169 direct_buf_rx_info("dbr buf pool %pK", dbr_buf_pool); 1170 target_if_dbr_deinit_ring(pdev, mod_param); 1171 if (mod_param->dbr_buf_pool) 1172 qdf_mem_free(dbr_buf_pool); 1173 mod_param->dbr_buf_pool = NULL; 1174 1175 return QDF_STATUS_SUCCESS; 1176 } 1177 1178 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev, 1179 struct direct_buf_rx_pdev_obj *dbr_pdev_obj, 1180 enum DBR_MODULE mod_id, uint8_t srng_id) 1181 { 1182 struct direct_buf_rx_module_param *mod_param; 1183 1184 direct_buf_rx_enter(); 1185 mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]); 1186 1187 if (!mod_param) { 1188 direct_buf_rx_err("dir buf rx module param is null"); 1189 return QDF_STATUS_E_FAILURE; 1190 } 1191 direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK", 1192 mod_param, mod_param->dbr_ring_cap); 1193 target_if_dbr_deinit_srng(pdev, mod_param); 1194 if (mod_param->dbr_ring_cap) 1195 qdf_mem_free(mod_param->dbr_ring_cap); 1196 mod_param->dbr_ring_cap = NULL; 1197 if (mod_param->dbr_ring_cfg) 1198 qdf_mem_free(mod_param->dbr_ring_cfg); 1199 mod_param->dbr_ring_cfg = NULL; 1200 1201 return QDF_STATUS_SUCCESS; 1202 } 1203 1204 QDF_STATUS target_if_direct_buf_rx_register_events( 1205 struct wlan_objmgr_psoc *psoc) 1206 { 1207 int ret; 1208 1209 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 1210 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 1211 return QDF_STATUS_E_INVAL; 1212 } 1213 1214 ret = wmi_unified_register_event_handler( 1215 get_wmi_unified_hdl_from_psoc(psoc), 1216 wmi_dma_buf_release_event_id, 1217 target_if_direct_buf_rx_rsp_event_handler, 1218 WMI_RX_UMAC_CTX); 1219 1220 if (ret) 1221 direct_buf_rx_info("event handler not supported, ret=%d", ret); 1222 1223 return QDF_STATUS_SUCCESS; 1224 } 1225 1226 QDF_STATUS target_if_direct_buf_rx_unregister_events( 1227 struct wlan_objmgr_psoc *psoc) 1228 { 1229 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 1230 direct_buf_rx_err("psoc or psoc->tgt_if_handle is null"); 1231 return QDF_STATUS_E_INVAL; 1232 } 1233 1234 wmi_unified_unregister_event_handler( 1235 get_wmi_unified_hdl_from_psoc(psoc), 1236 wmi_dma_buf_release_event_id); 1237 1238 return QDF_STATUS_SUCCESS; 1239 } 1240 1241 QDF_STATUS target_if_direct_buf_rx_print_ring_stat( 1242 struct wlan_objmgr_pdev *pdev) 1243 { 1244 struct direct_buf_rx_psoc_obj *dbr_psoc_obj; 1245 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1246 struct wlan_objmgr_psoc *psoc; 1247 void *srng, *hal_soc; 1248 uint32_t hp = 0, tp = 0; 1249 struct direct_buf_rx_module_param *mod_param; 1250 struct direct_buf_rx_ring_cfg *dbr_ring_cfg; 1251 uint8_t num_modules, mod_idx; 1252 uint8_t srng_id; 1253 1254 if (!pdev) { 1255 direct_buf_rx_err("pdev is null"); 1256 return QDF_STATUS_E_INVAL; 1257 } 1258 1259 psoc = wlan_pdev_get_psoc(pdev); 1260 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1261 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1262 dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1263 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1264 hal_soc = dbr_psoc_obj->hal_soc; 1265 num_modules = dbr_pdev_obj->num_modules; 1266 direct_buf_rx_err("--------------------------------------------------"); 1267 direct_buf_rx_err("| Module ID | Module | Head Idx | Tail Idx |"); 1268 direct_buf_rx_err("--------------------------------------------------"); 1269 for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { 1270 for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { 1271 mod_param = 1272 &dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id]; 1273 dbr_ring_cfg = mod_param->dbr_ring_cfg; 1274 srng = dbr_ring_cfg->srng; 1275 hal_get_sw_hptp(hal_soc, srng, &tp, &hp); 1276 direct_buf_rx_err("|%11d|%14s|%10x|%10x|", 1277 mod_idx, g_dbr_module_name[mod_idx]. 1278 module_name_str, 1279 hp, tp); 1280 } 1281 } 1282 direct_buf_rx_err("--------------------------------------------------"); 1283 1284 return QDF_STATUS_SUCCESS; 1285 } 1286 1287 QDF_STATUS 1288 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, 1289 struct module_ring_params *param, 1290 uint8_t mod_id, uint8_t srng_id) 1291 { 1292 struct direct_buf_rx_pdev_obj *dbr_pdev_obj; 1293 struct direct_buf_rx_module_param *dbr_mod_param; 1294 1295 if (!pdev) { 1296 direct_buf_rx_err("pdev context passed is null"); 1297 return QDF_STATUS_E_INVAL; 1298 } 1299 1300 dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj 1301 (pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); 1302 1303 if (!dbr_pdev_obj) { 1304 direct_buf_rx_err("dir buf rx object is null"); 1305 return QDF_STATUS_E_FAILURE; 1306 } 1307 1308 if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) { 1309 direct_buf_rx_err("invalid params, mod id %d, srng id %d", 1310 mod_id, srng_id); 1311 return QDF_STATUS_E_INVAL; 1312 } 1313 1314 dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; 1315 param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr; 1316 param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size; 1317 1318 return QDF_STATUS_SUCCESS; 1319 } 1320