1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #ifndef _HAL_API_H_ 21 #define _HAL_API_H_ 22 23 #include "qdf_types.h" 24 #include "qdf_util.h" 25 #include "qdf_atomic.h" 26 #include "hal_internal.h" 27 #include "hif.h" 28 #include "hif_io32.h" 29 #include "qdf_platform.h" 30 31 #ifdef DUMP_REO_QUEUE_INFO_IN_DDR 32 #include "hal_hw_headers.h" 33 #endif 34 35 /* Ring index for WBM2SW2 release ring */ 36 #define HAL_IPA_TX_COMP_RING_IDX 2 37 38 #if defined(CONFIG_SHADOW_V2) || defined(CONFIG_SHADOW_V3) 39 #define ignore_shadow false 40 #define CHECK_SHADOW_REGISTERS true 41 #else 42 #define ignore_shadow true 43 #define CHECK_SHADOW_REGISTERS false 44 #endif 45 46 /* 47 * Indices for stats 48 */ 49 enum RING_USAGE { 50 RING_USAGE_100, 51 RING_USAGE_GREAT_90, 52 RING_USAGE_70_TO_90, 53 RING_USAGE_50_TO_70, 54 RING_USAGE_LESS_50, 55 RING_USAGE_MAX, 56 }; 57 58 /* 59 * Structure for tracking ring utilization 60 */ 61 struct ring_util_stats { 62 uint32_t util[RING_USAGE_MAX]; 63 }; 64 65 #define RING_USAGE_100_PERCENTAGE 100 66 #define RING_USAGE_50_PERCENTAGE 50 67 #define RING_USAGE_70_PERCENTAGE 70 68 #define RING_USAGE_90_PERCENTAGE 90 69 70 /* calculate the register address offset from bar0 of shadow register x */ 71 #if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ 72 defined(QCA_WIFI_KIWI) 73 #define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x000008FC 74 #define SHADOW_REGISTER_END_ADDRESS_OFFSET \ 75 ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (MAX_SHADOW_REGISTERS))) 76 #define SHADOW_REGISTER(x) ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (x))) 77 #elif defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCN9000) 78 #define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x00003024 79 #define SHADOW_REGISTER_END_ADDRESS_OFFSET \ 80 ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (MAX_SHADOW_REGISTERS))) 81 #define SHADOW_REGISTER(x) ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (x))) 82 #elif defined(QCA_WIFI_QCA6750) 83 #define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x00000504 84 #define SHADOW_REGISTER_END_ADDRESS_OFFSET \ 85 ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (MAX_SHADOW_REGISTERS))) 86 #define SHADOW_REGISTER(x) ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (x))) 87 #else 88 #define SHADOW_REGISTER(x) 0 89 #endif /* QCA_WIFI_QCA6390 || QCA_WIFI_QCA6490 || QCA_WIFI_QCA6750 */ 90 91 /* 92 * BAR + 4K is always accessible, any access outside this 93 * space requires force wake procedure. 94 * OFFSET = 4K - 32 bytes = 0xFE0 95 */ 96 #define MAPPED_REF_OFF 0xFE0 97 98 #define HAL_OFFSET(block, field) block ## _ ## field ## _OFFSET 99 100 #ifdef ENABLE_VERBOSE_DEBUG 101 static inline void 102 hal_set_verbose_debug(bool flag) 103 { 104 is_hal_verbose_debug_enabled = flag; 105 } 106 #endif 107 108 #ifdef ENABLE_HAL_SOC_STATS 109 #define HAL_STATS_INC(_handle, _field, _delta) \ 110 { \ 111 if (likely(_handle)) \ 112 _handle->stats._field += _delta; \ 113 } 114 #else 115 #define HAL_STATS_INC(_handle, _field, _delta) 116 #endif 117 118 #ifdef ENABLE_HAL_REG_WR_HISTORY 119 #define HAL_REG_WRITE_FAIL_HIST_ADD(hal_soc, offset, wr_val, rd_val) \ 120 hal_reg_wr_fail_history_add(hal_soc, offset, wr_val, rd_val) 121 122 void hal_reg_wr_fail_history_add(struct hal_soc *hal_soc, 123 uint32_t offset, 124 uint32_t wr_val, 125 uint32_t rd_val); 126 127 static inline int hal_history_get_next_index(qdf_atomic_t *table_index, 128 int array_size) 129 { 130 int record_index = qdf_atomic_inc_return(table_index); 131 132 return record_index & (array_size - 1); 133 } 134 #else 135 #define HAL_REG_WRITE_FAIL_HIST_ADD(hal_soc, offset, wr_val, rd_val) \ 136 hal_err("write failed at reg offset 0x%x, write 0x%x read 0x%x", \ 137 offset, \ 138 wr_val, \ 139 rd_val) 140 #endif 141 142 /** 143 * hal_reg_write_result_check() - check register writing result 144 * @hal_soc: HAL soc handle 145 * @offset: register offset to read 146 * @exp_val: the expected value of register 147 * 148 * Return: QDF_STATUS - Success or Failure 149 */ 150 static inline QDF_STATUS hal_reg_write_result_check(struct hal_soc *hal_soc, 151 uint32_t offset, 152 uint32_t exp_val) 153 { 154 uint32_t value; 155 156 value = qdf_ioread32(hal_soc->dev_base_addr + offset); 157 if (qdf_unlikely(exp_val != value)) { 158 HAL_REG_WRITE_FAIL_HIST_ADD(hal_soc, offset, exp_val, value); 159 HAL_STATS_INC(hal_soc, reg_write_fail, 1); 160 161 return QDF_STATUS_E_FAILURE; 162 } 163 164 return QDF_STATUS_SUCCESS; 165 } 166 167 #ifdef WINDOW_REG_PLD_LOCK_ENABLE 168 static inline void hal_lock_reg_access(struct hal_soc *soc, 169 unsigned long *flags) 170 { 171 pld_lock_reg_window(soc->qdf_dev->dev, flags); 172 } 173 174 static inline void hal_unlock_reg_access(struct hal_soc *soc, 175 unsigned long *flags) 176 { 177 pld_unlock_reg_window(soc->qdf_dev->dev, flags); 178 } 179 #else 180 static inline void hal_lock_reg_access(struct hal_soc *soc, 181 unsigned long *flags) 182 { 183 qdf_spin_lock_irqsave(&soc->register_access_lock); 184 } 185 186 static inline void hal_unlock_reg_access(struct hal_soc *soc, 187 unsigned long *flags) 188 { 189 qdf_spin_unlock_irqrestore(&soc->register_access_lock); 190 } 191 #endif 192 193 #ifdef PCIE_REG_WINDOW_LOCAL_NO_CACHE 194 /** 195 * hal_select_window_confirm() - write remap window register and 196 * check writing result 197 * @hal_soc: hal soc handle 198 * @offset: offset to write 199 * 200 */ 201 static inline void hal_select_window_confirm(struct hal_soc *hal_soc, 202 uint32_t offset) 203 { 204 uint32_t window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK; 205 206 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS, 207 WINDOW_ENABLE_BIT | window); 208 hal_soc->register_window = window; 209 210 hal_reg_write_result_check(hal_soc, WINDOW_REG_ADDRESS, 211 WINDOW_ENABLE_BIT | window); 212 } 213 #else 214 static inline void hal_select_window_confirm(struct hal_soc *hal_soc, 215 uint32_t offset) 216 { 217 uint32_t window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK; 218 219 if (window != hal_soc->register_window) { 220 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS, 221 WINDOW_ENABLE_BIT | window); 222 hal_soc->register_window = window; 223 224 hal_reg_write_result_check( 225 hal_soc, 226 WINDOW_REG_ADDRESS, 227 WINDOW_ENABLE_BIT | window); 228 } 229 } 230 #endif 231 232 static inline qdf_iomem_t hal_get_window_address(struct hal_soc *hal_soc, 233 qdf_iomem_t addr) 234 { 235 return hal_soc->ops->hal_get_window_address(hal_soc, addr); 236 } 237 238 static inline void hal_tx_init_cmd_credit_ring(hal_soc_handle_t hal_soc_hdl, 239 hal_ring_handle_t hal_ring_hdl) 240 { 241 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 242 243 return hal_soc->ops->hal_tx_init_cmd_credit_ring(hal_soc_hdl, 244 hal_ring_hdl); 245 } 246 247 /** 248 * hal_write32_mb() - Access registers to update configuration 249 * @hal_soc: hal soc handle 250 * @offset: offset address from the BAR 251 * @value: value to write 252 * 253 * Return: None 254 * 255 * Description: Register address space is split below: 256 * SHADOW REGION UNWINDOWED REGION WINDOWED REGION 257 * |--------------------|-------------------|------------------| 258 * BAR NO FORCE WAKE BAR+4K FORCE WAKE BAR+512K FORCE WAKE 259 * 260 * 1. Any access to the shadow region, doesn't need force wake 261 * and windowing logic to access. 262 * 2. Any access beyond BAR + 4K: 263 * If init_phase enabled, no force wake is needed and access 264 * should be based on windowed or unwindowed access. 265 * If init_phase disabled, force wake is needed and access 266 * should be based on windowed or unwindowed access. 267 * 268 * note1: WINDOW_RANGE_MASK = (1 << WINDOW_SHIFT) -1 269 * note2: 1 << WINDOW_SHIFT = MAX_UNWINDOWED_ADDRESS 270 * note3: WINDOW_VALUE_MASK = big enough that trying to write past 271 * that window would be a bug 272 */ 273 #if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) && \ 274 !defined(QCA_WIFI_QCA6750) && !defined(QCA_WIFI_KIWI) && \ 275 !defined(QCA_WIFI_WCN6450) 276 static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, 277 uint32_t value) 278 { 279 unsigned long flags; 280 qdf_iomem_t new_addr; 281 282 if (!hal_soc->use_register_windowing || 283 offset < MAX_UNWINDOWED_ADDRESS) { 284 qdf_iowrite32(hal_soc->dev_base_addr + offset, value); 285 } else if (hal_soc->static_window_map) { 286 new_addr = hal_get_window_address(hal_soc, 287 hal_soc->dev_base_addr + offset); 288 qdf_iowrite32(new_addr, value); 289 } else { 290 hal_lock_reg_access(hal_soc, &flags); 291 hal_select_window_confirm(hal_soc, offset); 292 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START + 293 (offset & WINDOW_RANGE_MASK), value); 294 hal_unlock_reg_access(hal_soc, &flags); 295 } 296 } 297 298 /** 299 * hal_write32_mb_confirm() - write register and check writing result 300 * @hal_soc: hal soc handle 301 * @offset: I/O memory address to write 302 * @value: value to write 303 * 304 * Return: QDF_STATUS - return E_NOSUPPORT as no read back confirmation 305 */ 306 static inline QDF_STATUS hal_write32_mb_confirm(struct hal_soc *hal_soc, 307 uint32_t offset, 308 uint32_t value) 309 { 310 hal_write32_mb(hal_soc, offset, value); 311 return QDF_STATUS_E_NOSUPPORT; 312 } 313 314 #define hal_write32_mb_cmem(_hal_soc, _offset, _value) 315 #else 316 static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, 317 uint32_t value) 318 { 319 unsigned long flags; 320 qdf_iomem_t new_addr; 321 bool init_phase; 322 323 if (!TARGET_ACCESS_ALLOWED(HIF_GET_SOFTC( 324 hal_soc->hif_handle))) { 325 hal_err_rl("target access is not allowed"); 326 return; 327 } 328 329 /* Region < BAR + 4K can be directly accessed */ 330 if (offset < MAPPED_REF_OFF) { 331 qdf_iowrite32(hal_soc->dev_base_addr + offset, value); 332 return; 333 } 334 335 init_phase = hal_soc->init_phase; 336 337 /* Region greater than BAR + 4K */ 338 if (!init_phase && hif_force_wake_request(hal_soc->hif_handle)) { 339 hal_err_rl("Wake up request failed"); 340 qdf_check_state_before_panic(__func__, __LINE__); 341 return; 342 } 343 344 if (!hal_soc->use_register_windowing || 345 offset < MAX_UNWINDOWED_ADDRESS) { 346 qdf_iowrite32(hal_soc->dev_base_addr + offset, value); 347 } else if (hal_soc->static_window_map) { 348 new_addr = hal_get_window_address( 349 hal_soc, 350 hal_soc->dev_base_addr + offset); 351 qdf_iowrite32(new_addr, value); 352 } else { 353 hal_lock_reg_access(hal_soc, &flags); 354 hal_select_window_confirm(hal_soc, offset); 355 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START + 356 (offset & WINDOW_RANGE_MASK), value); 357 hal_unlock_reg_access(hal_soc, &flags); 358 } 359 360 if (!init_phase && hif_force_wake_release(hal_soc->hif_handle)) { 361 hal_err("Wake up release failed"); 362 qdf_check_state_before_panic(__func__, __LINE__); 363 return; 364 } 365 } 366 367 /** 368 * hal_write32_mb_confirm() - write register and check writing result 369 * @hal_soc: hal soc handle 370 * @offset: I/O memory address to write 371 * @value: value to write 372 * 373 * Return: QDF_STATUS - Success or Failure 374 */ 375 static inline QDF_STATUS hal_write32_mb_confirm(struct hal_soc *hal_soc, 376 uint32_t offset, 377 uint32_t value) 378 { 379 unsigned long flags; 380 qdf_iomem_t new_addr; 381 QDF_STATUS status = QDF_STATUS_E_FAILURE; 382 bool init_phase; 383 384 if (!TARGET_ACCESS_ALLOWED(HIF_GET_SOFTC( 385 hal_soc->hif_handle))) { 386 hal_err_rl("target access is not allowed"); 387 return status; 388 } 389 390 /* Region < BAR + 4K can be directly accessed */ 391 if (offset < MAPPED_REF_OFF) { 392 qdf_iowrite32(hal_soc->dev_base_addr + offset, value); 393 return QDF_STATUS_E_NOSUPPORT; 394 } 395 396 init_phase = hal_soc->init_phase; 397 398 /* Region greater than BAR + 4K */ 399 if (!init_phase && hif_force_wake_request(hal_soc->hif_handle)) { 400 hal_err("Wake up request failed"); 401 qdf_check_state_before_panic(__func__, __LINE__); 402 return status; 403 } 404 405 if (!hal_soc->use_register_windowing || 406 offset < MAX_UNWINDOWED_ADDRESS) { 407 qdf_iowrite32(hal_soc->dev_base_addr + offset, value); 408 status = hal_reg_write_result_check(hal_soc, offset, 409 value); 410 } else if (hal_soc->static_window_map) { 411 new_addr = hal_get_window_address( 412 hal_soc, 413 hal_soc->dev_base_addr + offset); 414 qdf_iowrite32(new_addr, value); 415 status = hal_reg_write_result_check( 416 hal_soc, 417 new_addr - hal_soc->dev_base_addr, 418 value); 419 } else { 420 hal_lock_reg_access(hal_soc, &flags); 421 hal_select_window_confirm(hal_soc, offset); 422 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START + 423 (offset & WINDOW_RANGE_MASK), value); 424 425 status = hal_reg_write_result_check( 426 hal_soc, 427 WINDOW_START + (offset & WINDOW_RANGE_MASK), 428 value); 429 hal_unlock_reg_access(hal_soc, &flags); 430 } 431 432 if (!init_phase && hif_force_wake_release(hal_soc->hif_handle)) { 433 hal_err("Wake up release failed"); 434 qdf_check_state_before_panic(__func__, __LINE__); 435 return QDF_STATUS_E_INVAL; 436 } 437 438 return status; 439 } 440 441 /** 442 * hal_write32_mb_cmem() - write CMEM 443 * @hal_soc: hal soc handle 444 * @offset: offset into CMEM to write 445 * @value: value to write 446 */ 447 static inline void hal_write32_mb_cmem(struct hal_soc *hal_soc, uint32_t offset, 448 uint32_t value) 449 { 450 unsigned long flags; 451 qdf_iomem_t new_addr; 452 453 if (!TARGET_ACCESS_ALLOWED(HIF_GET_SOFTC( 454 hal_soc->hif_handle))) { 455 hal_err_rl("%s: target access is not allowed", __func__); 456 return; 457 } 458 459 if (!hal_soc->use_register_windowing || 460 offset < MAX_UNWINDOWED_ADDRESS) { 461 qdf_iowrite32(hal_soc->dev_base_addr + offset, value); 462 } else if (hal_soc->static_window_map) { 463 new_addr = hal_get_window_address( 464 hal_soc, 465 hal_soc->dev_base_addr + offset); 466 qdf_iowrite32(new_addr, value); 467 } else { 468 hal_lock_reg_access(hal_soc, &flags); 469 hal_select_window_confirm(hal_soc, offset); 470 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START + 471 (offset & WINDOW_RANGE_MASK), value); 472 hal_unlock_reg_access(hal_soc, &flags); 473 } 474 } 475 #endif 476 477 /** 478 * hal_write_address_32_mb() - write a value to a register 479 * @hal_soc: hal soc handle 480 * @addr: I/O memory address to write 481 * @value: value to write 482 * @wr_confirm: true if read back confirmation is required 483 */ 484 static inline 485 void hal_write_address_32_mb(struct hal_soc *hal_soc, 486 qdf_iomem_t addr, uint32_t value, bool wr_confirm) 487 { 488 uint32_t offset; 489 490 if (!hal_soc->use_register_windowing) 491 return qdf_iowrite32(addr, value); 492 493 offset = addr - hal_soc->dev_base_addr; 494 495 if (qdf_unlikely(wr_confirm)) 496 hal_write32_mb_confirm(hal_soc, offset, value); 497 else 498 hal_write32_mb(hal_soc, offset, value); 499 } 500 501 502 #ifdef DP_HAL_MULTIWINDOW_DIRECT_ACCESS 503 static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, 504 struct hal_srng *srng, 505 void __iomem *addr, 506 uint32_t value) 507 { 508 qdf_iowrite32(addr, value); 509 hal_srng_reg_his_add(srng, value); 510 } 511 #elif defined(FEATURE_HAL_DELAYED_REG_WRITE) 512 static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, 513 struct hal_srng *srng, 514 void __iomem *addr, 515 uint32_t value) 516 { 517 hal_delayed_reg_write(hal_soc, srng, addr, value); 518 } 519 #else 520 static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, 521 struct hal_srng *srng, 522 void __iomem *addr, 523 uint32_t value) 524 { 525 hal_write_address_32_mb(hal_soc, addr, value, false); 526 hal_srng_reg_his_add(srng, value); 527 } 528 #endif 529 530 #if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) && \ 531 !defined(QCA_WIFI_QCA6750) && !defined(QCA_WIFI_KIWI) && \ 532 !defined(QCA_WIFI_WCN6450) 533 /** 534 * hal_read32_mb() - Access registers to read configuration 535 * @hal_soc: hal soc handle 536 * @offset: offset address from the BAR 537 * 538 * Description: Register address space is split below: 539 * SHADOW REGION UNWINDOWED REGION WINDOWED REGION 540 * |--------------------|-------------------|------------------| 541 * BAR NO FORCE WAKE BAR+4K FORCE WAKE BAR+512K FORCE WAKE 542 * 543 * 1. Any access to the shadow region, doesn't need force wake 544 * and windowing logic to access. 545 * 2. Any access beyond BAR + 4K: 546 * If init_phase enabled, no force wake is needed and access 547 * should be based on windowed or unwindowed access. 548 * If init_phase disabled, force wake is needed and access 549 * should be based on windowed or unwindowed access. 550 * 551 * Return: value read 552 */ 553 static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) 554 { 555 uint32_t ret; 556 unsigned long flags; 557 qdf_iomem_t new_addr; 558 559 if (!hal_soc->use_register_windowing || 560 offset < MAX_UNWINDOWED_ADDRESS) { 561 return qdf_ioread32(hal_soc->dev_base_addr + offset); 562 } else if (hal_soc->static_window_map) { 563 new_addr = hal_get_window_address(hal_soc, hal_soc->dev_base_addr + offset); 564 return qdf_ioread32(new_addr); 565 } 566 567 hal_lock_reg_access(hal_soc, &flags); 568 hal_select_window_confirm(hal_soc, offset); 569 ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START + 570 (offset & WINDOW_RANGE_MASK)); 571 hal_unlock_reg_access(hal_soc, &flags); 572 573 return ret; 574 } 575 576 #define hal_read32_mb_cmem(_hal_soc, _offset) 577 #else 578 static 579 uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) 580 { 581 uint32_t ret; 582 unsigned long flags; 583 qdf_iomem_t new_addr; 584 bool init_phase; 585 586 if (!TARGET_ACCESS_ALLOWED(HIF_GET_SOFTC( 587 hal_soc->hif_handle))) { 588 hal_err_rl("target access is not allowed"); 589 return 0; 590 } 591 592 /* Region < BAR + 4K can be directly accessed */ 593 if (offset < MAPPED_REF_OFF) 594 return qdf_ioread32(hal_soc->dev_base_addr + offset); 595 596 init_phase = hal_soc->init_phase; 597 if (!init_phase && hif_force_wake_request(hal_soc->hif_handle)) { 598 hal_err("Wake up request failed"); 599 qdf_check_state_before_panic(__func__, __LINE__); 600 return 0; 601 } 602 603 if (!hal_soc->use_register_windowing || 604 offset < MAX_UNWINDOWED_ADDRESS) { 605 ret = qdf_ioread32(hal_soc->dev_base_addr + offset); 606 } else if (hal_soc->static_window_map) { 607 new_addr = hal_get_window_address( 608 hal_soc, 609 hal_soc->dev_base_addr + offset); 610 ret = qdf_ioread32(new_addr); 611 } else { 612 hal_lock_reg_access(hal_soc, &flags); 613 hal_select_window_confirm(hal_soc, offset); 614 ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START + 615 (offset & WINDOW_RANGE_MASK)); 616 hal_unlock_reg_access(hal_soc, &flags); 617 } 618 619 if (!init_phase && hif_force_wake_release(hal_soc->hif_handle)) { 620 hal_err("Wake up release failed"); 621 qdf_check_state_before_panic(__func__, __LINE__); 622 return 0; 623 } 624 625 return ret; 626 } 627 628 static inline 629 uint32_t hal_read32_mb_cmem(struct hal_soc *hal_soc, uint32_t offset) 630 { 631 uint32_t ret; 632 unsigned long flags; 633 qdf_iomem_t new_addr; 634 635 if (!TARGET_ACCESS_ALLOWED(HIF_GET_SOFTC( 636 hal_soc->hif_handle))) { 637 hal_err_rl("%s: target access is not allowed", __func__); 638 return 0; 639 } 640 641 if (!hal_soc->use_register_windowing || 642 offset < MAX_UNWINDOWED_ADDRESS) { 643 ret = qdf_ioread32(hal_soc->dev_base_addr + offset); 644 } else if (hal_soc->static_window_map) { 645 new_addr = hal_get_window_address( 646 hal_soc, 647 hal_soc->dev_base_addr + offset); 648 ret = qdf_ioread32(new_addr); 649 } else { 650 hal_lock_reg_access(hal_soc, &flags); 651 hal_select_window_confirm(hal_soc, offset); 652 ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START + 653 (offset & WINDOW_RANGE_MASK)); 654 hal_unlock_reg_access(hal_soc, &flags); 655 } 656 return ret; 657 } 658 #endif 659 660 /* Max times allowed for register writing retry */ 661 #define HAL_REG_WRITE_RETRY_MAX 5 662 /* Delay milliseconds for each time retry */ 663 #define HAL_REG_WRITE_RETRY_DELAY 1 664 665 #ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE 666 /* To check shadow config index range between 0..31 */ 667 #define HAL_SHADOW_REG_INDEX_LOW 32 668 /* To check shadow config index range between 32..39 */ 669 #define HAL_SHADOW_REG_INDEX_HIGH 40 670 /* Dirty bit reg offsets corresponding to shadow config index */ 671 #define HAL_SHADOW_REG_DIRTY_BIT_DATA_LOW_OFFSET 0x30C8 672 #define HAL_SHADOW_REG_DIRTY_BIT_DATA_HIGH_OFFSET 0x30C4 673 /* PCIE_PCIE_TOP base addr offset */ 674 #define HAL_PCIE_PCIE_TOP_WRAPPER 0x01E00000 675 /* Max retry attempts to read the dirty bit reg */ 676 #ifdef HAL_CONFIG_SLUB_DEBUG_ON 677 #define HAL_SHADOW_DIRTY_BIT_POLL_MAX 10000 678 #else 679 #define HAL_SHADOW_DIRTY_BIT_POLL_MAX 2000 680 #endif 681 /* Delay in usecs for polling dirty bit reg */ 682 #define HAL_SHADOW_DIRTY_BIT_POLL_DELAY 5 683 684 /** 685 * hal_poll_dirty_bit_reg() - Poll dirty register bit to confirm 686 * write was successful 687 * @hal: hal soc handle 688 * @shadow_config_index: index of shadow reg used to confirm 689 * write 690 * 691 * Return: QDF_STATUS_SUCCESS on success 692 */ 693 static inline QDF_STATUS hal_poll_dirty_bit_reg(struct hal_soc *hal, 694 int shadow_config_index) 695 { 696 uint32_t read_value = 0; 697 int retry_cnt = 0; 698 uint32_t reg_offset = 0; 699 700 if (shadow_config_index > 0 && 701 shadow_config_index < HAL_SHADOW_REG_INDEX_LOW) { 702 reg_offset = 703 HAL_SHADOW_REG_DIRTY_BIT_DATA_LOW_OFFSET; 704 } else if (shadow_config_index >= HAL_SHADOW_REG_INDEX_LOW && 705 shadow_config_index < HAL_SHADOW_REG_INDEX_HIGH) { 706 reg_offset = 707 HAL_SHADOW_REG_DIRTY_BIT_DATA_HIGH_OFFSET; 708 } else { 709 hal_err("Invalid shadow_config_index = %d", 710 shadow_config_index); 711 return QDF_STATUS_E_INVAL; 712 } 713 while (retry_cnt < HAL_SHADOW_DIRTY_BIT_POLL_MAX) { 714 read_value = hal_read32_mb( 715 hal, HAL_PCIE_PCIE_TOP_WRAPPER + reg_offset); 716 /* Check if dirty bit corresponding to shadow_index is set */ 717 if (read_value & BIT(shadow_config_index)) { 718 /* Dirty reg bit not reset */ 719 qdf_udelay(HAL_SHADOW_DIRTY_BIT_POLL_DELAY); 720 retry_cnt++; 721 } else { 722 hal_debug("Shadow write: offset 0x%x read val 0x%x", 723 reg_offset, read_value); 724 return QDF_STATUS_SUCCESS; 725 } 726 } 727 return QDF_STATUS_E_TIMEOUT; 728 } 729 730 /** 731 * hal_write32_mb_shadow_confirm() - write to shadow reg and 732 * poll dirty register bit to confirm write 733 * @hal: hal soc handle 734 * @reg_offset: target reg offset address from BAR 735 * @value: value to write 736 * 737 * Return: QDF_STATUS_SUCCESS on success 738 */ 739 static inline QDF_STATUS hal_write32_mb_shadow_confirm( 740 struct hal_soc *hal, 741 uint32_t reg_offset, 742 uint32_t value) 743 { 744 int i; 745 QDF_STATUS ret; 746 uint32_t shadow_reg_offset; 747 int shadow_config_index; 748 bool is_reg_offset_present = false; 749 750 for (i = 0; i < MAX_GENERIC_SHADOW_REG; i++) { 751 /* Found the shadow config for the reg_offset */ 752 struct shadow_reg_config *hal_shadow_reg_list = 753 &hal->list_shadow_reg_config[i]; 754 if (hal_shadow_reg_list->target_register == 755 reg_offset) { 756 shadow_config_index = 757 hal_shadow_reg_list->shadow_config_index; 758 shadow_reg_offset = 759 SHADOW_REGISTER(shadow_config_index); 760 hal_write32_mb_confirm( 761 hal, shadow_reg_offset, value); 762 is_reg_offset_present = true; 763 break; 764 } 765 ret = QDF_STATUS_E_FAILURE; 766 } 767 if (is_reg_offset_present) { 768 ret = hal_poll_dirty_bit_reg(hal, shadow_config_index); 769 hal_info("Shadow write:reg 0x%x val 0x%x ret %d", 770 reg_offset, value, ret); 771 if (QDF_IS_STATUS_ERROR(ret)) { 772 HAL_STATS_INC(hal, shadow_reg_write_fail, 1); 773 return ret; 774 } 775 HAL_STATS_INC(hal, shadow_reg_write_succ, 1); 776 } 777 return ret; 778 } 779 780 /** 781 * hal_write32_mb_confirm_retry() - write register with confirming and 782 * do retry/recovery if writing failed 783 * @hal_soc: hal soc handle 784 * @offset: offset address from the BAR 785 * @value: value to write 786 * @recovery: is recovery needed or not. 787 * 788 * Write the register value with confirming and read it back, if 789 * read back value is not as expected, do retry for writing, if 790 * retry hit max times allowed but still fail, check if recovery 791 * needed. 792 * 793 * Return: None 794 */ 795 static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, 796 uint32_t offset, 797 uint32_t value, 798 bool recovery) 799 { 800 QDF_STATUS ret; 801 802 ret = hal_write32_mb_shadow_confirm(hal_soc, offset, value); 803 if (QDF_IS_STATUS_ERROR(ret) && recovery) 804 qdf_trigger_self_recovery(NULL, QDF_HAL_REG_WRITE_FAILURE); 805 } 806 #else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ 807 808 static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, 809 uint32_t offset, 810 uint32_t value, 811 bool recovery) 812 { 813 uint8_t retry_cnt = 0; 814 uint32_t read_value; 815 QDF_STATUS ret; 816 817 while (retry_cnt <= HAL_REG_WRITE_RETRY_MAX) { 818 ret = hal_write32_mb_confirm(hal_soc, offset, value); 819 /* Positive confirmation, return directly */ 820 if (qdf_likely(QDF_IS_STATUS_SUCCESS(ret))) 821 return; 822 823 read_value = hal_read32_mb(hal_soc, offset); 824 if (qdf_likely(read_value == value)) 825 break; 826 827 /* write failed, do retry */ 828 hal_warn("Retry reg offset 0x%x, value 0x%x, read value 0x%x", 829 offset, value, read_value); 830 qdf_mdelay(HAL_REG_WRITE_RETRY_DELAY); 831 retry_cnt++; 832 } 833 834 if (retry_cnt > HAL_REG_WRITE_RETRY_MAX && recovery) 835 qdf_trigger_self_recovery(NULL, QDF_HAL_REG_WRITE_FAILURE); 836 } 837 #endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ 838 839 #if defined(FEATURE_HAL_DELAYED_REG_WRITE) 840 /** 841 * hal_dump_reg_write_srng_stats() - dump SRNG reg write stats 842 * @hal_soc_hdl: HAL soc handle 843 * 844 * Return: none 845 */ 846 void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl); 847 848 /** 849 * hal_dump_reg_write_stats() - dump reg write stats 850 * @hal_soc_hdl: HAL soc handle 851 * 852 * Return: none 853 */ 854 void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl); 855 856 /** 857 * hal_get_reg_write_pending_work() - get the number of entries 858 * pending in the workqueue to be processed. 859 * @hal_soc: HAL soc handle 860 * 861 * Returns: the number of entries pending to be processed 862 */ 863 int hal_get_reg_write_pending_work(void *hal_soc); 864 865 #else 866 static inline void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl) 867 { 868 } 869 870 static inline void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl) 871 { 872 } 873 874 static inline int hal_get_reg_write_pending_work(void *hal_soc) 875 { 876 return 0; 877 } 878 #endif 879 880 #if defined(FEATURE_HAL_DELAYED_REG_WRITE) && defined(QCA_WIFI_QCA6750) 881 /** 882 * hal_srng_check_and_update_hptp() - Check and force update HP/TP 883 * to the hardware 884 * @hal_soc: HAL soc handle 885 * @srng: SRNG handle 886 * @update: Whether or not update is needed 887 * 888 * Returns: void 889 */ 890 void hal_srng_check_and_update_hptp(struct hal_soc *hal_soc, 891 struct hal_srng *srng, 892 bool update); 893 #else 894 static inline void 895 hal_srng_check_and_update_hptp(struct hal_soc *hal_soc, struct hal_srng *srng, 896 bool update) 897 { 898 } 899 #endif 900 901 /** 902 * hal_read_address_32_mb() - Read 32-bit value from the register 903 * @soc: soc handle 904 * @addr: register address to read 905 * 906 * Return: 32-bit value 907 */ 908 static inline 909 uint32_t hal_read_address_32_mb(struct hal_soc *soc, 910 qdf_iomem_t addr) 911 { 912 uint32_t offset; 913 uint32_t ret; 914 915 if (!soc->use_register_windowing) 916 return qdf_ioread32(addr); 917 918 offset = addr - soc->dev_base_addr; 919 ret = hal_read32_mb(soc, offset); 920 return ret; 921 } 922 923 /** 924 * hal_attach() - Initialize HAL layer 925 * @hif_handle: Opaque HIF handle 926 * @qdf_dev: QDF device 927 * 928 * This function should be called as part of HIF initialization (for accessing 929 * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle() 930 * 931 * Return: Opaque HAL SOC handle 932 * NULL on failure (if given ring is not available) 933 */ 934 void *hal_attach(struct hif_opaque_softc *hif_handle, qdf_device_t qdf_dev); 935 936 /** 937 * hal_detach() - Detach HAL layer 938 * @hal_soc: HAL SOC handle 939 * 940 * This function should be called as part of HIF detach 941 * 942 */ 943 void hal_detach(void *hal_soc); 944 945 #define HAL_SRNG_LMAC_RING 0x80000000 946 /* SRNG flags passed in hal_srng_params.flags */ 947 #define HAL_SRNG_MSI_SWAP 0x00000008 948 #define HAL_SRNG_RING_PTR_SWAP 0x00000010 949 #define HAL_SRNG_DATA_TLV_SWAP 0x00000020 950 #define HAL_SRNG_LOW_THRES_INTR_ENABLE 0x00010000 951 #define HAL_SRNG_MSI_INTR 0x00020000 952 #define HAL_SRNG_CACHED_DESC 0x00040000 953 954 #if defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_KIWI) 955 #define HAL_SRNG_PREFETCH_TIMER 1 956 #else 957 #define HAL_SRNG_PREFETCH_TIMER 0 958 #endif 959 960 #define PN_SIZE_24 0 961 #define PN_SIZE_48 1 962 #define PN_SIZE_128 2 963 964 #ifdef FORCE_WAKE 965 /** 966 * hal_set_init_phase() - Indicate initialization of 967 * datapath rings 968 * @soc: hal_soc handle 969 * @init_phase: flag to indicate datapath rings 970 * initialization status 971 * 972 * Return: None 973 */ 974 void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase); 975 #else 976 static inline 977 void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase) 978 { 979 } 980 #endif /* FORCE_WAKE */ 981 982 /** 983 * hal_srng_get_entrysize() - Returns size of ring entry in bytes. 984 * @hal_soc: Opaque HAL SOC handle 985 * @ring_type: one of the types from hal_ring_type 986 * 987 * Should be used by callers for calculating the size of memory to be 988 * allocated before calling hal_srng_setup to setup the ring 989 * 990 * Return: ring entry size 991 */ 992 uint32_t hal_srng_get_entrysize(void *hal_soc, int ring_type); 993 994 /** 995 * hal_srng_max_entries() - Returns maximum possible number of ring entries 996 * @hal_soc: Opaque HAL SOC handle 997 * @ring_type: one of the types from hal_ring_type 998 * 999 * Return: Maximum number of entries for the given ring_type 1000 */ 1001 uint32_t hal_srng_max_entries(void *hal_soc, int ring_type); 1002 1003 void hal_set_low_threshold(hal_ring_handle_t hal_ring_hdl, 1004 uint32_t low_threshold); 1005 1006 /** 1007 * hal_srng_dump() - Dump ring status 1008 * @srng: hal srng pointer 1009 */ 1010 void hal_srng_dump(struct hal_srng *srng); 1011 1012 /** 1013 * hal_srng_get_dir() - Returns the direction of the ring 1014 * @hal_soc: Opaque HAL SOC handle 1015 * @ring_type: one of the types from hal_ring_type 1016 * 1017 * Return: Ring direction 1018 */ 1019 enum hal_srng_dir hal_srng_get_dir(void *hal_soc, int ring_type); 1020 1021 /* HAL memory information */ 1022 struct hal_mem_info { 1023 /* dev base virtual addr */ 1024 void *dev_base_addr; 1025 /* dev base physical addr */ 1026 void *dev_base_paddr; 1027 /* dev base ce virtual addr - applicable only for qca5018 */ 1028 /* In qca5018 CE register are outside wcss block */ 1029 /* using a separate address space to access CE registers */ 1030 void *dev_base_addr_ce; 1031 /* dev base ce physical addr */ 1032 void *dev_base_paddr_ce; 1033 /* Remote virtual pointer memory for HW/FW updates */ 1034 void *shadow_rdptr_mem_vaddr; 1035 /* Remote physical pointer memory for HW/FW updates */ 1036 void *shadow_rdptr_mem_paddr; 1037 /* Shared memory for ring pointer updates from host to FW */ 1038 void *shadow_wrptr_mem_vaddr; 1039 /* Shared physical memory for ring pointer updates from host to FW */ 1040 void *shadow_wrptr_mem_paddr; 1041 /* lmac srng start id */ 1042 uint8_t lmac_srng_start_id; 1043 }; 1044 1045 /* SRNG parameters to be passed to hal_srng_setup */ 1046 struct hal_srng_params { 1047 /* Physical base address of the ring */ 1048 qdf_dma_addr_t ring_base_paddr; 1049 /* Virtual base address of the ring */ 1050 void *ring_base_vaddr; 1051 /* Number of entries in ring */ 1052 uint32_t num_entries; 1053 /* max transfer length */ 1054 uint16_t max_buffer_length; 1055 /* MSI Address */ 1056 qdf_dma_addr_t msi_addr; 1057 /* MSI data */ 1058 uint32_t msi_data; 1059 /* Interrupt timer threshold – in micro seconds */ 1060 uint32_t intr_timer_thres_us; 1061 /* Interrupt batch counter threshold – in number of ring entries */ 1062 uint32_t intr_batch_cntr_thres_entries; 1063 /* Low threshold – in number of ring entries 1064 * (valid for src rings only) 1065 */ 1066 uint32_t low_threshold; 1067 /* Misc flags */ 1068 uint32_t flags; 1069 /* Unique ring id */ 1070 uint8_t ring_id; 1071 /* Source or Destination ring */ 1072 enum hal_srng_dir ring_dir; 1073 /* Size of ring entry */ 1074 uint32_t entry_size; 1075 /* hw register base address */ 1076 void *hwreg_base[MAX_SRNG_REG_GROUPS]; 1077 /* prefetch timer config - in micro seconds */ 1078 uint32_t prefetch_timer; 1079 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ 1080 /* Near full IRQ support flag */ 1081 uint32_t nf_irq_support; 1082 /* MSI2 Address */ 1083 qdf_dma_addr_t msi2_addr; 1084 /* MSI2 data */ 1085 uint32_t msi2_data; 1086 /* Critical threshold */ 1087 uint16_t crit_thresh; 1088 /* High threshold */ 1089 uint16_t high_thresh; 1090 /* Safe threshold */ 1091 uint16_t safe_thresh; 1092 #endif 1093 /* Timer threshold to issue ring pointer update - in micro seconds */ 1094 uint16_t pointer_timer_threshold; 1095 /* Number threshold of ring entries to issue pointer update */ 1096 uint8_t pointer_num_threshold; 1097 }; 1098 1099 /** 1100 * hal_construct_srng_shadow_regs() - initialize the shadow 1101 * registers for srngs 1102 * @hal_soc: hal handle 1103 * 1104 * Return: QDF_STATUS_OK on success 1105 */ 1106 QDF_STATUS hal_construct_srng_shadow_regs(void *hal_soc); 1107 1108 /** 1109 * hal_set_one_shadow_config() - add a config for the specified ring 1110 * @hal_soc: hal handle 1111 * @ring_type: ring type 1112 * @ring_num: ring num 1113 * 1114 * The ring type and ring num uniquely specify the ring. After this call, 1115 * the hp/tp will be added as the next entry int the shadow register 1116 * configuration table. The hal code will use the shadow register address 1117 * in place of the hp/tp address. 1118 * 1119 * This function is exposed, so that the CE module can skip configuring shadow 1120 * registers for unused ring and rings assigned to the firmware. 1121 * 1122 * Return: QDF_STATUS_OK on success 1123 */ 1124 QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type, 1125 int ring_num); 1126 1127 /** 1128 * hal_get_shadow_config() - retrieve the config table for shadow cfg v2 1129 * @hal_soc: hal handle 1130 * @shadow_config: will point to the table after 1131 * @num_shadow_registers_configured: will contain the number of valid entries 1132 */ 1133 extern void 1134 hal_get_shadow_config(void *hal_soc, 1135 struct pld_shadow_reg_v2_cfg **shadow_config, 1136 int *num_shadow_registers_configured); 1137 1138 #ifdef CONFIG_SHADOW_V3 1139 /** 1140 * hal_get_shadow_v3_config() - retrieve the config table for shadow cfg v3 1141 * @hal_soc: hal handle 1142 * @shadow_config: will point to the table after 1143 * @num_shadow_registers_configured: will contain the number of valid entries 1144 */ 1145 extern void 1146 hal_get_shadow_v3_config(void *hal_soc, 1147 struct pld_shadow_reg_v3_cfg **shadow_config, 1148 int *num_shadow_registers_configured); 1149 #endif 1150 1151 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ 1152 /** 1153 * hal_srng_is_near_full_irq_supported() - Check if srng supports near full irq 1154 * @hal_soc: HAL SoC handle [To be validated by caller] 1155 * @ring_type: srng type 1156 * @ring_num: The index of the srng (of the same type) 1157 * 1158 * Return: true, if srng support near full irq trigger 1159 * false, if the srng does not support near full irq support. 1160 */ 1161 bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc, 1162 int ring_type, int ring_num); 1163 #else 1164 static inline 1165 bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc, 1166 int ring_type, int ring_num) 1167 { 1168 return false; 1169 } 1170 #endif 1171 1172 /** 1173 * hal_srng_setup() - Initialize HW SRNG ring. 1174 * @hal_soc: Opaque HAL SOC handle 1175 * @ring_type: one of the types from hal_ring_type 1176 * @ring_num: Ring number if there are multiple rings of 1177 * same type (staring from 0) 1178 * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings 1179 * @ring_params: SRNG ring params in hal_srng_params structure. 1180 * @idle_check: Check if ring is idle 1181 * 1182 * Callers are expected to allocate contiguous ring memory of size 1183 * 'num_entries * entry_size' bytes and pass the physical and virtual base 1184 * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in hal_srng_params 1185 * structure. Ring base address should be 8 byte aligned and size of each ring 1186 * entry should be queried using the API hal_srng_get_entrysize 1187 * 1188 * Return: Opaque pointer to ring on success 1189 * NULL on failure (if given ring is not available) 1190 */ 1191 void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, 1192 int mac_id, struct hal_srng_params *ring_params, 1193 bool idle_check); 1194 1195 /** 1196 * hal_srng_setup_idx() - Initialize HW SRNG ring. 1197 * @hal_soc: Opaque HAL SOC handle 1198 * @ring_type: one of the types from hal_ring_type 1199 * @ring_num: Ring number if there are multiple rings of 1200 * same type (staring from 0) 1201 * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings 1202 * @ring_params: SRNG ring params in hal_srng_params structure. 1203 * @idle_check: Check if ring is idle 1204 * @idx: Ring index 1205 * 1206 * Callers are expected to allocate contiguous ring memory of size 1207 * 'num_entries * entry_size' bytes and pass the physical and virtual base 1208 * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in hal_srng_params 1209 * structure. Ring base address should be 8 byte aligned and size of each ring 1210 * entry should be queried using the API hal_srng_get_entrysize 1211 * 1212 * Return: Opaque pointer to ring on success 1213 * NULL on failure (if given ring is not available) 1214 */ 1215 void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, 1216 int mac_id, struct hal_srng_params *ring_params, 1217 bool idle_check, uint32_t idx); 1218 1219 1220 /* Remapping ids of REO rings */ 1221 #define REO_REMAP_TCL 0 1222 #define REO_REMAP_SW1 1 1223 #define REO_REMAP_SW2 2 1224 #define REO_REMAP_SW3 3 1225 #define REO_REMAP_SW4 4 1226 #define REO_REMAP_RELEASE 5 1227 #define REO_REMAP_FW 6 1228 /* 1229 * In Beryllium: 4 bits REO destination ring value is defined as: 0: TCL 1230 * 1:SW1 2:SW2 3:SW3 4:SW4 5:Release 6:FW(WIFI) 7:SW5 1231 * 8:SW6 9:SW7 10:SW8 11: NOT_USED. 1232 * 1233 */ 1234 #define REO_REMAP_SW5 7 1235 #define REO_REMAP_SW6 8 1236 #define REO_REMAP_SW7 9 1237 #define REO_REMAP_SW8 10 1238 1239 /* 1240 * Macro to access HWIO_REO_R0_ERROR_DESTINATION_RING_CTRL_IX_0 1241 * to map destination to rings 1242 */ 1243 #define HAL_REO_ERR_REMAP_IX0(_VALUE, _OFFSET) \ 1244 ((_VALUE) << \ 1245 (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ERROR_ ## \ 1246 DESTINATION_RING_ ## _OFFSET ## _SHFT)) 1247 1248 /* 1249 * Macro to access HWIO_REO_R0_ERROR_DESTINATION_RING_CTRL_IX_1 1250 * to map destination to rings 1251 */ 1252 #define HAL_REO_ERR_REMAP_IX1(_VALUE, _OFFSET) \ 1253 ((_VALUE) << \ 1254 (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ERROR_ ## \ 1255 DESTINATION_RING_ ## _OFFSET ## _SHFT)) 1256 1257 /* 1258 * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0 1259 * to map destination to rings 1260 */ 1261 #define HAL_REO_REMAP_IX0(_VALUE, _OFFSET) \ 1262 ((_VALUE) << \ 1263 (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_DEST_RING_MAPPING_ ## \ 1264 _OFFSET ## _SHFT)) 1265 1266 /* 1267 * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1 1268 * to map destination to rings 1269 */ 1270 #define HAL_REO_REMAP_IX2(_VALUE, _OFFSET) \ 1271 ((_VALUE) << \ 1272 (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_DEST_RING_MAPPING_ ## \ 1273 _OFFSET ## _SHFT)) 1274 1275 /* 1276 * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3 1277 * to map destination to rings 1278 */ 1279 #define HAL_REO_REMAP_IX3(_VALUE, _OFFSET) \ 1280 ((_VALUE) << \ 1281 (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_DEST_RING_MAPPING_ ## \ 1282 _OFFSET ## _SHFT)) 1283 1284 /** 1285 * hal_reo_read_write_ctrl_ix() - Read or write REO_DESTINATION_RING_CTRL_IX 1286 * @hal_soc_hdl: HAL SOC handle 1287 * @read: boolean value to indicate if read or write 1288 * @ix0: pointer to store IX0 reg value 1289 * @ix1: pointer to store IX1 reg value 1290 * @ix2: pointer to store IX2 reg value 1291 * @ix3: pointer to store IX3 reg value 1292 */ 1293 void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read, 1294 uint32_t *ix0, uint32_t *ix1, 1295 uint32_t *ix2, uint32_t *ix3); 1296 1297 /** 1298 * hal_srng_dst_set_hp_paddr_confirm() - Set physical address to dest SRNG head 1299 * pointer and confirm that write went through by reading back the value 1300 * @sring: sring pointer 1301 * @paddr: physical address 1302 * 1303 * Return: None 1304 */ 1305 void hal_srng_dst_set_hp_paddr_confirm(struct hal_srng *sring, 1306 uint64_t paddr); 1307 1308 /** 1309 * hal_srng_dst_init_hp() - Initialize head pointer with cached head pointer 1310 * @hal_soc: hal_soc handle 1311 * @srng: sring pointer 1312 * @vaddr: virtual address 1313 */ 1314 void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc, 1315 struct hal_srng *srng, 1316 uint32_t *vaddr); 1317 1318 /** 1319 * hal_srng_dst_update_hp_addr() - Update hp_addr with current HW HP value 1320 * @hal_soc: hal_soc handle 1321 * @hal_ring_hdl: Opaque HAL SRNG pointer 1322 * 1323 * Return: None 1324 */ 1325 void hal_srng_dst_update_hp_addr(struct hal_soc_handle *hal_soc, 1326 hal_ring_handle_t hal_ring_hdl); 1327 1328 /** 1329 * hal_srng_cleanup() - Deinitialize HW SRNG ring. 1330 * @hal_soc: Opaque HAL SOC handle 1331 * @hal_ring_hdl: Opaque HAL SRNG pointer 1332 * @umac_reset_inprogress: UMAC reset enabled/disabled. 1333 */ 1334 void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl, 1335 bool umac_reset_inprogress); 1336 1337 static inline bool hal_srng_initialized(hal_ring_handle_t hal_ring_hdl) 1338 { 1339 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1340 1341 return !!srng->initialized; 1342 } 1343 1344 /** 1345 * hal_srng_dst_peek() - Check if there are any entries in the ring (peek) 1346 * @hal_soc_hdl: Opaque HAL SOC handle 1347 * @hal_ring_hdl: Destination ring pointer 1348 * 1349 * Caller takes responsibility for any locking needs. 1350 * 1351 * Return: Opaque pointer for next ring entry; NULL on failire 1352 */ 1353 static inline 1354 void *hal_srng_dst_peek(hal_soc_handle_t hal_soc_hdl, 1355 hal_ring_handle_t hal_ring_hdl) 1356 { 1357 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1358 1359 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) 1360 return (void *)(&srng->ring_base_vaddr[srng->u.dst_ring.tp]); 1361 1362 return NULL; 1363 } 1364 1365 1366 /** 1367 * hal_mem_dma_cache_sync() - Cache sync the specified virtual address Range 1368 * @soc: HAL soc handle 1369 * @desc: desc start address 1370 * @entry_size: size of memory to sync 1371 * 1372 * Return: void 1373 */ 1374 #if defined(__LINUX_MIPS32_ARCH__) || defined(__LINUX_MIPS64_ARCH__) 1375 static inline void hal_mem_dma_cache_sync(struct hal_soc *soc, uint32_t *desc, 1376 uint32_t entry_size) 1377 { 1378 qdf_nbuf_dma_inv_range((void *)desc, (void *)(desc + entry_size)); 1379 } 1380 #else 1381 static inline void hal_mem_dma_cache_sync(struct hal_soc *soc, uint32_t *desc, 1382 uint32_t entry_size) 1383 { 1384 qdf_mem_dma_cache_sync(soc->qdf_dev, qdf_mem_virt_to_phys(desc), 1385 QDF_DMA_FROM_DEVICE, 1386 (entry_size * sizeof(uint32_t))); 1387 } 1388 #endif 1389 1390 /** 1391 * hal_srng_access_start_unlocked() - Start ring access (unlocked). Should use 1392 * hal_srng_access_start() if locked access is required 1393 * @hal_soc_hdl: Opaque HAL SOC handle 1394 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 1395 * 1396 * This API doesn't implement any byte-order conversion on reading hp/tp. 1397 * So, Use API only for those srngs for which the target writes hp/tp values to 1398 * the DDR in the Host order. 1399 * 1400 * Return: 0 on success; error on failire 1401 */ 1402 static inline int 1403 hal_srng_access_start_unlocked(hal_soc_handle_t hal_soc_hdl, 1404 hal_ring_handle_t hal_ring_hdl) 1405 { 1406 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1407 struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl; 1408 uint32_t *desc; 1409 1410 if (srng->ring_dir == HAL_SRNG_SRC_RING) 1411 srng->u.src_ring.cached_tp = 1412 *(volatile uint32_t *)(srng->u.src_ring.tp_addr); 1413 else { 1414 srng->u.dst_ring.cached_hp = 1415 *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); 1416 1417 if (srng->flags & HAL_SRNG_CACHED_DESC) { 1418 desc = hal_srng_dst_peek(hal_soc_hdl, hal_ring_hdl); 1419 if (qdf_likely(desc)) { 1420 hal_mem_dma_cache_sync(soc, desc, 1421 srng->entry_size); 1422 qdf_prefetch(desc); 1423 } 1424 } 1425 } 1426 1427 return 0; 1428 } 1429 1430 /** 1431 * hal_le_srng_access_start_unlocked_in_cpu_order() - Start ring access 1432 * (unlocked) with endianness correction. 1433 * @hal_soc_hdl: Opaque HAL SOC handle 1434 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 1435 * 1436 * This API provides same functionally as hal_srng_access_start_unlocked() 1437 * except that it converts the little-endian formatted hp/tp values to 1438 * Host order on reading them. So, this API should only be used for those srngs 1439 * for which the target always writes hp/tp values in little-endian order 1440 * regardless of Host order. 1441 * 1442 * Also, this API doesn't take the lock. For locked access, use 1443 * hal_srng_access_start/hal_le_srng_access_start_in_cpu_order. 1444 * 1445 * Return: 0 on success; error on failire 1446 */ 1447 static inline int 1448 hal_le_srng_access_start_unlocked_in_cpu_order( 1449 hal_soc_handle_t hal_soc_hdl, 1450 hal_ring_handle_t hal_ring_hdl) 1451 { 1452 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1453 struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl; 1454 uint32_t *desc; 1455 1456 if (srng->ring_dir == HAL_SRNG_SRC_RING) 1457 srng->u.src_ring.cached_tp = 1458 qdf_le32_to_cpu(*(volatile uint32_t *) 1459 (srng->u.src_ring.tp_addr)); 1460 else { 1461 srng->u.dst_ring.cached_hp = 1462 qdf_le32_to_cpu(*(volatile uint32_t *) 1463 (srng->u.dst_ring.hp_addr)); 1464 1465 if (srng->flags & HAL_SRNG_CACHED_DESC) { 1466 desc = hal_srng_dst_peek(hal_soc_hdl, hal_ring_hdl); 1467 if (qdf_likely(desc)) { 1468 hal_mem_dma_cache_sync(soc, desc, 1469 srng->entry_size); 1470 qdf_prefetch(desc); 1471 } 1472 } 1473 } 1474 1475 return 0; 1476 } 1477 1478 /** 1479 * hal_srng_try_access_start() - Try to start (locked) ring access 1480 * @hal_soc_hdl: Opaque HAL SOC handle 1481 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 1482 * 1483 * Return: 0 on success; error on failure 1484 */ 1485 static inline int hal_srng_try_access_start(hal_soc_handle_t hal_soc_hdl, 1486 hal_ring_handle_t hal_ring_hdl) 1487 { 1488 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1489 1490 if (qdf_unlikely(!hal_ring_hdl)) { 1491 qdf_print("Error: Invalid hal_ring\n"); 1492 return -EINVAL; 1493 } 1494 1495 if (!SRNG_TRY_LOCK(&(srng->lock))) 1496 return -EINVAL; 1497 1498 return hal_srng_access_start_unlocked(hal_soc_hdl, hal_ring_hdl); 1499 } 1500 1501 /** 1502 * hal_srng_access_start() - Start (locked) ring access 1503 * 1504 * @hal_soc_hdl: Opaque HAL SOC handle 1505 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 1506 * 1507 * This API doesn't implement any byte-order conversion on reading hp/tp. 1508 * So, Use API only for those srngs for which the target writes hp/tp values to 1509 * the DDR in the Host order. 1510 * 1511 * Return: 0 on success; error on failire 1512 */ 1513 static inline int hal_srng_access_start(hal_soc_handle_t hal_soc_hdl, 1514 hal_ring_handle_t hal_ring_hdl) 1515 { 1516 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1517 1518 if (qdf_unlikely(!hal_ring_hdl)) { 1519 qdf_print("Error: Invalid hal_ring\n"); 1520 return -EINVAL; 1521 } 1522 1523 SRNG_LOCK(&(srng->lock)); 1524 1525 return hal_srng_access_start_unlocked(hal_soc_hdl, hal_ring_hdl); 1526 } 1527 1528 /** 1529 * hal_le_srng_access_start_in_cpu_order() - Start (locked) ring access with 1530 * endianness correction 1531 * @hal_soc_hdl: Opaque HAL SOC handle 1532 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 1533 * 1534 * This API provides same functionally as hal_srng_access_start() 1535 * except that it converts the little-endian formatted hp/tp values to 1536 * Host order on reading them. So, this API should only be used for those srngs 1537 * for which the target always writes hp/tp values in little-endian order 1538 * regardless of Host order. 1539 * 1540 * Return: 0 on success; error on failire 1541 */ 1542 static inline int 1543 hal_le_srng_access_start_in_cpu_order( 1544 hal_soc_handle_t hal_soc_hdl, 1545 hal_ring_handle_t hal_ring_hdl) 1546 { 1547 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1548 1549 if (qdf_unlikely(!hal_ring_hdl)) { 1550 qdf_print("Error: Invalid hal_ring\n"); 1551 return -EINVAL; 1552 } 1553 1554 SRNG_LOCK(&(srng->lock)); 1555 1556 return hal_le_srng_access_start_unlocked_in_cpu_order( 1557 hal_soc_hdl, hal_ring_hdl); 1558 } 1559 1560 /** 1561 * hal_srng_dst_get_next() - Get next entry from a destination ring 1562 * @hal_soc: Opaque HAL SOC handle 1563 * @hal_ring_hdl: Destination ring pointer 1564 * 1565 * Return: Opaque pointer for next ring entry; NULL on failure 1566 */ 1567 static inline 1568 void *hal_srng_dst_get_next(void *hal_soc, 1569 hal_ring_handle_t hal_ring_hdl) 1570 { 1571 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1572 uint32_t *desc; 1573 1574 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 1575 return NULL; 1576 1577 desc = &srng->ring_base_vaddr[srng->u.dst_ring.tp]; 1578 /* TODO: Using % is expensive, but we have to do this since 1579 * size of some SRNG rings is not power of 2 (due to descriptor 1580 * sizes). Need to create separate API for rings used 1581 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 1582 * SW2RXDMA and CE rings) 1583 */ 1584 srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size); 1585 if (srng->u.dst_ring.tp == srng->ring_size) 1586 srng->u.dst_ring.tp = 0; 1587 1588 if (srng->flags & HAL_SRNG_CACHED_DESC) { 1589 struct hal_soc *soc = (struct hal_soc *)hal_soc; 1590 uint32_t *desc_next; 1591 uint32_t tp; 1592 1593 tp = srng->u.dst_ring.tp; 1594 desc_next = &srng->ring_base_vaddr[srng->u.dst_ring.tp]; 1595 hal_mem_dma_cache_sync(soc, desc_next, srng->entry_size); 1596 qdf_prefetch(desc_next); 1597 } 1598 1599 return (void *)desc; 1600 } 1601 1602 /** 1603 * hal_srng_dst_get_next_cached() - Get cached next entry 1604 * @hal_soc: Opaque HAL SOC handle 1605 * @hal_ring_hdl: Destination ring pointer 1606 * 1607 * Get next entry from a destination ring and move cached tail pointer 1608 * 1609 * Return: Opaque pointer for next ring entry; NULL on failure 1610 */ 1611 static inline 1612 void *hal_srng_dst_get_next_cached(void *hal_soc, 1613 hal_ring_handle_t hal_ring_hdl) 1614 { 1615 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1616 uint32_t *desc; 1617 uint32_t *desc_next; 1618 1619 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 1620 return NULL; 1621 1622 desc = &srng->ring_base_vaddr[srng->u.dst_ring.tp]; 1623 /* TODO: Using % is expensive, but we have to do this since 1624 * size of some SRNG rings is not power of 2 (due to descriptor 1625 * sizes). Need to create separate API for rings used 1626 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 1627 * SW2RXDMA and CE rings) 1628 */ 1629 srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size); 1630 if (srng->u.dst_ring.tp == srng->ring_size) 1631 srng->u.dst_ring.tp = 0; 1632 1633 desc_next = &srng->ring_base_vaddr[srng->u.dst_ring.tp]; 1634 qdf_prefetch(desc_next); 1635 return (void *)desc; 1636 } 1637 1638 /** 1639 * hal_srng_dst_dec_tp() - decrement the TP of the Dst ring by one entry 1640 * @hal_soc: Opaque HAL SOC handle 1641 * @hal_ring_hdl: Destination ring pointer 1642 * 1643 * reset the tail pointer in the destination ring by one entry 1644 * 1645 */ 1646 static inline 1647 void hal_srng_dst_dec_tp(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 1648 { 1649 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1650 1651 if (qdf_unlikely(!srng->u.dst_ring.tp)) 1652 srng->u.dst_ring.tp = (srng->ring_size - srng->entry_size); 1653 else 1654 srng->u.dst_ring.tp -= srng->entry_size; 1655 } 1656 1657 static inline int hal_srng_lock(hal_ring_handle_t hal_ring_hdl) 1658 { 1659 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1660 1661 if (qdf_unlikely(!hal_ring_hdl)) { 1662 qdf_print("error: invalid hal_ring\n"); 1663 return -EINVAL; 1664 } 1665 1666 SRNG_LOCK(&(srng->lock)); 1667 return 0; 1668 } 1669 1670 static inline int hal_srng_unlock(hal_ring_handle_t hal_ring_hdl) 1671 { 1672 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1673 1674 if (qdf_unlikely(!hal_ring_hdl)) { 1675 qdf_print("error: invalid hal_ring\n"); 1676 return -EINVAL; 1677 } 1678 1679 SRNG_UNLOCK(&(srng->lock)); 1680 return 0; 1681 } 1682 1683 /** 1684 * hal_srng_dst_get_next_hp() - Get next entry from a destination ring and move 1685 * cached head pointer 1686 * @hal_soc_hdl: Opaque HAL SOC handle 1687 * @hal_ring_hdl: Destination ring pointer 1688 * 1689 * Return: Opaque pointer for next ring entry; NULL on failire 1690 */ 1691 static inline void * 1692 hal_srng_dst_get_next_hp(hal_soc_handle_t hal_soc_hdl, 1693 hal_ring_handle_t hal_ring_hdl) 1694 { 1695 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1696 uint32_t *desc; 1697 /* TODO: Using % is expensive, but we have to do this since 1698 * size of some SRNG rings is not power of 2 (due to descriptor 1699 * sizes). Need to create separate API for rings used 1700 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 1701 * SW2RXDMA and CE rings) 1702 */ 1703 uint32_t next_hp = (srng->u.dst_ring.cached_hp + srng->entry_size) % 1704 srng->ring_size; 1705 1706 if (next_hp != srng->u.dst_ring.tp) { 1707 desc = &(srng->ring_base_vaddr[srng->u.dst_ring.cached_hp]); 1708 srng->u.dst_ring.cached_hp = next_hp; 1709 return (void *)desc; 1710 } 1711 1712 return NULL; 1713 } 1714 1715 /** 1716 * hal_srng_dst_peek_sync() - Check if there are any entries in the ring (peek) 1717 * @hal_soc_hdl: Opaque HAL SOC handle 1718 * @hal_ring_hdl: Destination ring pointer 1719 * 1720 * Sync cached head pointer with HW. 1721 * Caller takes responsibility for any locking needs. 1722 * 1723 * Return: Opaque pointer for next ring entry; NULL on failire 1724 */ 1725 static inline 1726 void *hal_srng_dst_peek_sync(hal_soc_handle_t hal_soc_hdl, 1727 hal_ring_handle_t hal_ring_hdl) 1728 { 1729 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1730 1731 srng->u.dst_ring.cached_hp = 1732 *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); 1733 1734 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) 1735 return (void *)(&(srng->ring_base_vaddr[srng->u.dst_ring.tp])); 1736 1737 return NULL; 1738 } 1739 1740 /** 1741 * hal_srng_dst_peek_sync_locked() - Peek for any entries in the ring 1742 * @hal_soc_hdl: Opaque HAL SOC handle 1743 * @hal_ring_hdl: Destination ring pointer 1744 * 1745 * Sync cached head pointer with HW. 1746 * This function takes up SRNG_LOCK. Should not be called with SRNG lock held. 1747 * 1748 * Return: Opaque pointer for next ring entry; NULL on failire 1749 */ 1750 static inline 1751 void *hal_srng_dst_peek_sync_locked(hal_soc_handle_t hal_soc_hdl, 1752 hal_ring_handle_t hal_ring_hdl) 1753 { 1754 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1755 void *ring_desc_ptr = NULL; 1756 1757 if (qdf_unlikely(!hal_ring_hdl)) { 1758 qdf_print("Error: Invalid hal_ring\n"); 1759 return NULL; 1760 } 1761 1762 SRNG_LOCK(&srng->lock); 1763 1764 ring_desc_ptr = hal_srng_dst_peek_sync(hal_soc_hdl, hal_ring_hdl); 1765 1766 SRNG_UNLOCK(&srng->lock); 1767 1768 return ring_desc_ptr; 1769 } 1770 1771 #define hal_srng_dst_num_valid_nolock(hal_soc, hal_ring_hdl, sync_hw_ptr) \ 1772 hal_srng_dst_num_valid(hal_soc, hal_ring_hdl, sync_hw_ptr) 1773 1774 /** 1775 * hal_srng_dst_num_valid() - Returns number of valid entries (to be processed 1776 * by SW) in destination ring 1777 * @hal_soc: Opaque HAL SOC handle 1778 * @hal_ring_hdl: Destination ring pointer 1779 * @sync_hw_ptr: Sync cached head pointer with HW 1780 * 1781 * Return: number of valid entries 1782 */ 1783 static inline 1784 uint32_t hal_srng_dst_num_valid(void *hal_soc, 1785 hal_ring_handle_t hal_ring_hdl, 1786 int sync_hw_ptr) 1787 { 1788 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1789 uint32_t hp; 1790 uint32_t tp = srng->u.dst_ring.tp; 1791 1792 if (sync_hw_ptr) { 1793 hp = *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); 1794 srng->u.dst_ring.cached_hp = hp; 1795 } else { 1796 hp = srng->u.dst_ring.cached_hp; 1797 } 1798 1799 if (hp >= tp) 1800 return (hp - tp) / srng->entry_size; 1801 1802 return (srng->ring_size - tp + hp) / srng->entry_size; 1803 } 1804 1805 /** 1806 * hal_srng_dst_inv_cached_descs() - API to invalidate descriptors in batch mode 1807 * @hal_soc: Opaque HAL SOC handle 1808 * @hal_ring_hdl: Destination ring pointer 1809 * @entry_count: call invalidate API if valid entries available 1810 * 1811 * Invalidates a set of cached descriptors starting from TP to cached_HP 1812 * 1813 * Return: HAL ring descriptor 1814 */ 1815 static inline void * 1816 hal_srng_dst_inv_cached_descs(void *hal_soc, 1817 hal_ring_handle_t hal_ring_hdl, 1818 uint32_t entry_count) 1819 { 1820 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1821 uint32_t *first_desc; 1822 uint32_t *last_desc; 1823 uint32_t last_desc_index; 1824 1825 /* 1826 * If SRNG does not have cached descriptors this 1827 * API call should be a no op 1828 */ 1829 if (!(srng->flags & HAL_SRNG_CACHED_DESC)) 1830 return NULL; 1831 1832 if (!entry_count) 1833 return NULL; 1834 1835 first_desc = &srng->ring_base_vaddr[srng->u.dst_ring.tp]; 1836 1837 last_desc_index = (srng->u.dst_ring.tp + 1838 (entry_count * srng->entry_size)) % 1839 srng->ring_size; 1840 1841 last_desc = &srng->ring_base_vaddr[last_desc_index]; 1842 1843 if (last_desc > (uint32_t *)first_desc) 1844 /* invalidate from tp to cached_hp */ 1845 qdf_nbuf_dma_inv_range_no_dsb((void *)first_desc, 1846 (void *)(last_desc)); 1847 else { 1848 /* invalidate from tp to end of the ring */ 1849 qdf_nbuf_dma_inv_range_no_dsb((void *)first_desc, 1850 (void *)srng->ring_vaddr_end); 1851 1852 /* invalidate from start of ring to cached_hp */ 1853 qdf_nbuf_dma_inv_range_no_dsb((void *)srng->ring_base_vaddr, 1854 (void *)last_desc); 1855 } 1856 qdf_dsb(); 1857 1858 return last_desc; 1859 } 1860 1861 /** 1862 * hal_srng_dst_num_valid_locked() - Returns num valid entries to be processed 1863 * @hal_soc: Opaque HAL SOC handle 1864 * @hal_ring_hdl: Destination ring pointer 1865 * @sync_hw_ptr: Sync cached head pointer with HW 1866 * 1867 * Returns number of valid entries to be processed by the host driver. The 1868 * function takes up SRNG lock. 1869 * 1870 * Return: Number of valid destination entries 1871 */ 1872 static inline uint32_t 1873 hal_srng_dst_num_valid_locked(hal_soc_handle_t hal_soc, 1874 hal_ring_handle_t hal_ring_hdl, 1875 int sync_hw_ptr) 1876 { 1877 uint32_t num_valid; 1878 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1879 1880 SRNG_LOCK(&srng->lock); 1881 num_valid = hal_srng_dst_num_valid(hal_soc, hal_ring_hdl, sync_hw_ptr); 1882 SRNG_UNLOCK(&srng->lock); 1883 1884 return num_valid; 1885 } 1886 1887 /** 1888 * hal_srng_sync_cachedhp() - sync cachehp pointer from hw hp 1889 * @hal_soc: Opaque HAL SOC handle 1890 * @hal_ring_hdl: Destination ring pointer 1891 * 1892 */ 1893 static inline 1894 void hal_srng_sync_cachedhp(void *hal_soc, 1895 hal_ring_handle_t hal_ring_hdl) 1896 { 1897 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1898 uint32_t hp; 1899 1900 hp = *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); 1901 srng->u.dst_ring.cached_hp = hp; 1902 } 1903 1904 /** 1905 * hal_srng_src_reap_next() - Reap next entry from a source ring 1906 * @hal_soc: Opaque HAL SOC handle 1907 * @hal_ring_hdl: Source ring pointer 1908 * 1909 * Reaps next entry from a source ring and moves reap pointer. This 1910 * can be used to release any buffers associated with completed ring 1911 * entries. Note that this should not be used for posting new 1912 * descriptor entries. Posting of new entries should be done only 1913 * using hal_srng_src_get_next_reaped() when this function is used for 1914 * reaping. 1915 * 1916 * Return: Opaque pointer for next ring entry; NULL on failire 1917 */ 1918 static inline void * 1919 hal_srng_src_reap_next(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 1920 { 1921 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1922 uint32_t *desc; 1923 1924 /* TODO: Using % is expensive, but we have to do this since 1925 * size of some SRNG rings is not power of 2 (due to descriptor 1926 * sizes). Need to create separate API for rings used 1927 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 1928 * SW2RXDMA and CE rings) 1929 */ 1930 uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) % 1931 srng->ring_size; 1932 1933 if (next_reap_hp != srng->u.src_ring.cached_tp) { 1934 desc = &(srng->ring_base_vaddr[next_reap_hp]); 1935 srng->u.src_ring.reap_hp = next_reap_hp; 1936 return (void *)desc; 1937 } 1938 1939 return NULL; 1940 } 1941 1942 /** 1943 * hal_srng_src_get_next_reaped() - Get next reaped entry from a source ring 1944 * @hal_soc: Opaque HAL SOC handle 1945 * @hal_ring_hdl: Source ring pointer 1946 * 1947 * Gets next entry from a source ring that is already reaped using 1948 * hal_srng_src_reap_next(), for posting new entries to the ring 1949 * 1950 * Return: Opaque pointer for next (reaped) source ring entry; NULL on failire 1951 */ 1952 static inline void * 1953 hal_srng_src_get_next_reaped(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 1954 { 1955 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1956 uint32_t *desc; 1957 1958 if (srng->u.src_ring.hp != srng->u.src_ring.reap_hp) { 1959 desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]); 1960 srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) % 1961 srng->ring_size; 1962 1963 return (void *)desc; 1964 } 1965 1966 return NULL; 1967 } 1968 1969 /** 1970 * hal_srng_src_pending_reap_next() - Reap next entry from a source ring 1971 * @hal_soc: Opaque HAL SOC handle 1972 * @hal_ring_hdl: Source ring pointer 1973 * 1974 * Reaps next entry from a source ring and move reap pointer. This API 1975 * is used in detach path to release any buffers associated with ring 1976 * entries which are pending reap. 1977 * 1978 * Return: Opaque pointer for next ring entry; NULL on failire 1979 */ 1980 static inline void * 1981 hal_srng_src_pending_reap_next(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 1982 { 1983 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 1984 uint32_t *desc; 1985 1986 uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) % 1987 srng->ring_size; 1988 1989 if (next_reap_hp != srng->u.src_ring.hp) { 1990 desc = &(srng->ring_base_vaddr[next_reap_hp]); 1991 srng->u.src_ring.reap_hp = next_reap_hp; 1992 return (void *)desc; 1993 } 1994 1995 return NULL; 1996 } 1997 1998 /** 1999 * hal_srng_src_done_val() - 2000 * @hal_soc: Opaque HAL SOC handle 2001 * @hal_ring_hdl: Source ring pointer 2002 * 2003 * Return: Opaque pointer for next ring entry; NULL on failire 2004 */ 2005 static inline uint32_t 2006 hal_srng_src_done_val(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 2007 { 2008 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2009 /* TODO: Using % is expensive, but we have to do this since 2010 * size of some SRNG rings is not power of 2 (due to descriptor 2011 * sizes). Need to create separate API for rings used 2012 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 2013 * SW2RXDMA and CE rings) 2014 */ 2015 uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) % 2016 srng->ring_size; 2017 2018 if (next_reap_hp == srng->u.src_ring.cached_tp) 2019 return 0; 2020 2021 if (srng->u.src_ring.cached_tp > next_reap_hp) 2022 return (srng->u.src_ring.cached_tp - next_reap_hp) / 2023 srng->entry_size; 2024 else 2025 return ((srng->ring_size - next_reap_hp) + 2026 srng->u.src_ring.cached_tp) / srng->entry_size; 2027 } 2028 2029 /** 2030 * hal_get_entrysize_from_srng() - Retrieve ring entry size 2031 * @hal_ring_hdl: Source ring pointer 2032 * 2033 * srng->entry_size value is in 4 byte dwords so left shifting 2034 * this by 2 to return the value of entry_size in bytes. 2035 * 2036 * Return: uint8_t 2037 */ 2038 static inline 2039 uint8_t hal_get_entrysize_from_srng(hal_ring_handle_t hal_ring_hdl) 2040 { 2041 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2042 2043 return srng->entry_size << 2; 2044 } 2045 2046 /** 2047 * hal_get_sw_hptp() - Get SW head and tail pointer location for any ring 2048 * @hal_soc: Opaque HAL SOC handle 2049 * @hal_ring_hdl: Source ring pointer 2050 * @tailp: Tail Pointer 2051 * @headp: Head Pointer 2052 * 2053 * Return: Update tail pointer and head pointer in arguments. 2054 */ 2055 static inline 2056 void hal_get_sw_hptp(void *hal_soc, hal_ring_handle_t hal_ring_hdl, 2057 uint32_t *tailp, uint32_t *headp) 2058 { 2059 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2060 2061 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 2062 *headp = srng->u.src_ring.hp; 2063 *tailp = *srng->u.src_ring.tp_addr; 2064 } else { 2065 *tailp = srng->u.dst_ring.tp; 2066 *headp = *srng->u.dst_ring.hp_addr; 2067 } 2068 } 2069 2070 #if defined(CLEAR_SW2TCL_CONSUMED_DESC) 2071 /** 2072 * hal_srng_src_get_next_consumed() - Get the next desc if consumed by HW 2073 * @hal_soc: Opaque HAL SOC handle 2074 * @hal_ring_hdl: Source ring pointer 2075 * 2076 * Return: pointer to descriptor if consumed by HW, else NULL 2077 */ 2078 static inline 2079 void *hal_srng_src_get_next_consumed(void *hal_soc, 2080 hal_ring_handle_t hal_ring_hdl) 2081 { 2082 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2083 uint32_t *desc = NULL; 2084 /* TODO: Using % is expensive, but we have to do this since 2085 * size of some SRNG rings is not power of 2 (due to descriptor 2086 * sizes). Need to create separate API for rings used 2087 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 2088 * SW2RXDMA and CE rings) 2089 */ 2090 uint32_t next_entry = (srng->last_desc_cleared + srng->entry_size) % 2091 srng->ring_size; 2092 2093 if (next_entry != srng->u.src_ring.cached_tp) { 2094 desc = &srng->ring_base_vaddr[next_entry]; 2095 srng->last_desc_cleared = next_entry; 2096 } 2097 2098 return desc; 2099 } 2100 2101 #else 2102 static inline 2103 void *hal_srng_src_get_next_consumed(void *hal_soc, 2104 hal_ring_handle_t hal_ring_hdl) 2105 { 2106 return NULL; 2107 } 2108 #endif /* CLEAR_SW2TCL_CONSUMED_DESC */ 2109 2110 /** 2111 * hal_srng_src_peek() - get the HP of the SRC ring 2112 * @hal_soc: Opaque HAL SOC handle 2113 * @hal_ring_hdl: Source ring pointer 2114 * 2115 * get the head pointer in the src ring but do not increment it 2116 * 2117 * Return: head descriptor 2118 */ 2119 static inline 2120 void *hal_srng_src_peek(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 2121 { 2122 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2123 uint32_t *desc; 2124 uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) % 2125 srng->ring_size; 2126 2127 if (next_hp != srng->u.src_ring.cached_tp) { 2128 desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]); 2129 return (void *)desc; 2130 } 2131 2132 return NULL; 2133 } 2134 2135 /** 2136 * hal_srng_src_get_next() - Get next entry from a source ring and move cached 2137 * tail pointer 2138 * @hal_soc: Opaque HAL SOC handle 2139 * @hal_ring_hdl: Source ring pointer 2140 * 2141 * Return: Opaque pointer for next ring entry; NULL on failure 2142 */ 2143 static inline 2144 void *hal_srng_src_get_next(void *hal_soc, 2145 hal_ring_handle_t hal_ring_hdl) 2146 { 2147 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2148 uint32_t *desc; 2149 /* TODO: Using % is expensive, but we have to do this since 2150 * size of some SRNG rings is not power of 2 (due to descriptor 2151 * sizes). Need to create separate API for rings used 2152 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 2153 * SW2RXDMA and CE rings) 2154 */ 2155 uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) % 2156 srng->ring_size; 2157 2158 if (next_hp != srng->u.src_ring.cached_tp) { 2159 desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]); 2160 srng->u.src_ring.hp = next_hp; 2161 /* TODO: Since reap function is not used by all rings, we can 2162 * remove the following update of reap_hp in this function 2163 * if we can ensure that only hal_srng_src_get_next_reaped 2164 * is used for the rings requiring reap functionality 2165 */ 2166 srng->u.src_ring.reap_hp = next_hp; 2167 return (void *)desc; 2168 } 2169 2170 return NULL; 2171 } 2172 2173 /** 2174 * hal_srng_src_peek_n_get_next() - Get next entry from a ring without 2175 * moving head pointer. 2176 * @hal_soc_hdl: Opaque HAL SOC handle 2177 * @hal_ring_hdl: Source ring pointer 2178 * 2179 * hal_srng_src_get_next should be called subsequently to move the head pointer 2180 * 2181 * Return: Opaque pointer for next ring entry; NULL on failire 2182 */ 2183 static inline 2184 void *hal_srng_src_peek_n_get_next(hal_soc_handle_t hal_soc_hdl, 2185 hal_ring_handle_t hal_ring_hdl) 2186 { 2187 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2188 uint32_t *desc; 2189 2190 /* TODO: Using % is expensive, but we have to do this since 2191 * size of some SRNG rings is not power of 2 (due to descriptor 2192 * sizes). Need to create separate API for rings used 2193 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 2194 * SW2RXDMA and CE rings) 2195 */ 2196 if (((srng->u.src_ring.hp + srng->entry_size) % 2197 srng->ring_size) != srng->u.src_ring.cached_tp) { 2198 desc = &(srng->ring_base_vaddr[(srng->u.src_ring.hp + 2199 srng->entry_size) % 2200 srng->ring_size]); 2201 return (void *)desc; 2202 } 2203 2204 return NULL; 2205 } 2206 2207 /** 2208 * hal_srng_src_dec_hp - Decrement source srng HP to previous index 2209 * @hal_soc_hdl: Opaque HAL SOC handle 2210 * @hal_ring_hdl: Source ring pointer 2211 * 2212 * Return: None 2213 */ 2214 static inline 2215 void hal_srng_src_dec_hp(hal_soc_handle_t hal_soc_hdl, 2216 hal_ring_handle_t hal_ring_hdl) 2217 { 2218 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2219 uint32_t hp = srng->u.src_ring.hp; 2220 2221 /* This HP adjustment is mostly done in error cases. 2222 * Only local HP is being decremented not the value 2223 * communicated to consumer or H.W. 2224 */ 2225 if (hp == srng->u.src_ring.cached_tp) 2226 return; 2227 else if (hp == 0) 2228 hp = srng->ring_size - srng->entry_size; 2229 else 2230 hp = (hp - srng->entry_size) % srng->ring_size; 2231 2232 srng->u.src_ring.hp = hp; 2233 } 2234 2235 /** 2236 * hal_srng_src_peek_n_get_next_next() - Get next to next, i.e HP + 2 entry from 2237 * a ring without moving head pointer. 2238 * @hal_soc_hdl: Opaque HAL SOC handle 2239 * @hal_ring_hdl: Source ring pointer 2240 * 2241 * Return: Opaque pointer for next to next ring entry; NULL on failire 2242 */ 2243 static inline 2244 void *hal_srng_src_peek_n_get_next_next(hal_soc_handle_t hal_soc_hdl, 2245 hal_ring_handle_t hal_ring_hdl) 2246 { 2247 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2248 uint32_t *desc; 2249 2250 /* TODO: Using % is expensive, but we have to do this since 2251 * size of some SRNG rings is not power of 2 (due to descriptor 2252 * sizes). Need to create separate API for rings used 2253 * per-packet, with sizes power of 2 (TCL2SW, REO2SW, 2254 * SW2RXDMA and CE rings) 2255 */ 2256 if ((((srng->u.src_ring.hp + (srng->entry_size)) % 2257 srng->ring_size) != srng->u.src_ring.cached_tp) && 2258 (((srng->u.src_ring.hp + (srng->entry_size * 2)) % 2259 srng->ring_size) != srng->u.src_ring.cached_tp)) { 2260 desc = &(srng->ring_base_vaddr[(srng->u.src_ring.hp + 2261 (srng->entry_size * 2)) % 2262 srng->ring_size]); 2263 return (void *)desc; 2264 } 2265 2266 return NULL; 2267 } 2268 2269 /** 2270 * hal_srng_src_get_cur_hp_n_move_next() - API returns current hp 2271 * and move hp to next in src ring 2272 * @hal_soc_hdl: HAL soc handle 2273 * @hal_ring_hdl: Source ring pointer 2274 * 2275 * This API should only be used at init time replenish. 2276 */ 2277 static inline void * 2278 hal_srng_src_get_cur_hp_n_move_next(hal_soc_handle_t hal_soc_hdl, 2279 hal_ring_handle_t hal_ring_hdl) 2280 { 2281 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2282 uint32_t *cur_desc = NULL; 2283 uint32_t next_hp; 2284 2285 cur_desc = &srng->ring_base_vaddr[(srng->u.src_ring.hp)]; 2286 2287 next_hp = (srng->u.src_ring.hp + srng->entry_size) % 2288 srng->ring_size; 2289 2290 if (next_hp != srng->u.src_ring.cached_tp) 2291 srng->u.src_ring.hp = next_hp; 2292 2293 return (void *)cur_desc; 2294 } 2295 2296 /** 2297 * hal_srng_src_num_avail() - Returns number of available entries in src ring 2298 * @hal_soc: Opaque HAL SOC handle 2299 * @hal_ring_hdl: Source ring pointer 2300 * @sync_hw_ptr: Sync cached tail pointer with HW 2301 * 2302 * Return: number of available entries 2303 */ 2304 static inline uint32_t 2305 hal_srng_src_num_avail(void *hal_soc, 2306 hal_ring_handle_t hal_ring_hdl, int sync_hw_ptr) 2307 { 2308 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2309 uint32_t tp; 2310 uint32_t hp = srng->u.src_ring.hp; 2311 2312 if (sync_hw_ptr) { 2313 tp = *(srng->u.src_ring.tp_addr); 2314 srng->u.src_ring.cached_tp = tp; 2315 } else { 2316 tp = srng->u.src_ring.cached_tp; 2317 } 2318 2319 if (tp > hp) 2320 return ((tp - hp) / srng->entry_size) - 1; 2321 else 2322 return ((srng->ring_size - hp + tp) / srng->entry_size) - 1; 2323 } 2324 2325 #ifdef WLAN_DP_SRNG_USAGE_WM_TRACKING 2326 /** 2327 * hal_srng_clear_ring_usage_wm_locked() - Clear SRNG usage watermark stats 2328 * @hal_soc_hdl: HAL soc handle 2329 * @hal_ring_hdl: SRNG handle 2330 * 2331 * This function tries to acquire SRNG lock, and hence should not be called 2332 * from a context which has already acquired the SRNG lock. 2333 * 2334 * Return: None 2335 */ 2336 static inline 2337 void hal_srng_clear_ring_usage_wm_locked(hal_soc_handle_t hal_soc_hdl, 2338 hal_ring_handle_t hal_ring_hdl) 2339 { 2340 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2341 2342 SRNG_LOCK(&srng->lock); 2343 srng->high_wm.val = 0; 2344 srng->high_wm.timestamp = 0; 2345 qdf_mem_zero(&srng->high_wm.bins[0], sizeof(srng->high_wm.bins[0]) * 2346 HAL_SRNG_HIGH_WM_BIN_MAX); 2347 SRNG_UNLOCK(&srng->lock); 2348 } 2349 2350 /** 2351 * hal_srng_update_ring_usage_wm_no_lock() - Update the SRNG usage wm stats 2352 * @hal_soc_hdl: HAL soc handle 2353 * @hal_ring_hdl: SRNG handle 2354 * 2355 * This function should be called with the SRNG lock held. 2356 * 2357 * Return: None 2358 */ 2359 static inline 2360 void hal_srng_update_ring_usage_wm_no_lock(hal_soc_handle_t hal_soc_hdl, 2361 hal_ring_handle_t hal_ring_hdl) 2362 { 2363 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2364 uint32_t curr_wm_val = 0; 2365 2366 if (srng->ring_dir == HAL_SRNG_SRC_RING) 2367 curr_wm_val = hal_srng_src_num_avail(hal_soc_hdl, hal_ring_hdl, 2368 0); 2369 else 2370 curr_wm_val = hal_srng_dst_num_valid(hal_soc_hdl, hal_ring_hdl, 2371 0); 2372 2373 if (curr_wm_val > srng->high_wm.val) { 2374 srng->high_wm.val = curr_wm_val; 2375 srng->high_wm.timestamp = qdf_get_system_timestamp(); 2376 } 2377 2378 if (curr_wm_val >= 2379 srng->high_wm.bin_thresh[HAL_SRNG_HIGH_WM_BIN_90_to_100]) 2380 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_90_to_100]++; 2381 else if (curr_wm_val >= 2382 srng->high_wm.bin_thresh[HAL_SRNG_HIGH_WM_BIN_80_to_90]) 2383 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_80_to_90]++; 2384 else if (curr_wm_val >= 2385 srng->high_wm.bin_thresh[HAL_SRNG_HIGH_WM_BIN_70_to_80]) 2386 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_70_to_80]++; 2387 else if (curr_wm_val >= 2388 srng->high_wm.bin_thresh[HAL_SRNG_HIGH_WM_BIN_60_to_70]) 2389 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_60_to_70]++; 2390 else if (curr_wm_val >= 2391 srng->high_wm.bin_thresh[HAL_SRNG_HIGH_WM_BIN_50_to_60]) 2392 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_50_to_60]++; 2393 else 2394 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_BELOW_50_PERCENT]++; 2395 } 2396 2397 static inline 2398 int hal_dump_srng_high_wm_stats(hal_soc_handle_t hal_soc_hdl, 2399 hal_ring_handle_t hal_ring_hdl, 2400 char *buf, int buf_len, int pos) 2401 { 2402 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2403 2404 return qdf_scnprintf(buf + pos, buf_len - pos, 2405 "%8u %7u %12llu %10u %10u %10u %10u %10u %10u", 2406 srng->ring_id, srng->high_wm.val, 2407 srng->high_wm.timestamp, 2408 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_BELOW_50_PERCENT], 2409 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_50_to_60], 2410 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_60_to_70], 2411 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_70_to_80], 2412 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_80_to_90], 2413 srng->high_wm.bins[HAL_SRNG_HIGH_WM_BIN_90_to_100]); 2414 } 2415 #else 2416 /** 2417 * hal_srng_clear_ring_usage_wm_locked() - Clear SRNG usage watermark stats 2418 * @hal_soc_hdl: HAL soc handle 2419 * @hal_ring_hdl: SRNG handle 2420 * 2421 * This function tries to acquire SRNG lock, and hence should not be called 2422 * from a context which has already acquired the SRNG lock. 2423 * 2424 * Return: None 2425 */ 2426 static inline 2427 void hal_srng_clear_ring_usage_wm_locked(hal_soc_handle_t hal_soc_hdl, 2428 hal_ring_handle_t hal_ring_hdl) 2429 { 2430 } 2431 2432 /** 2433 * hal_srng_update_ring_usage_wm_no_lock() - Update the SRNG usage wm stats 2434 * @hal_soc_hdl: HAL soc handle 2435 * @hal_ring_hdl: SRNG handle 2436 * 2437 * This function should be called with the SRNG lock held. 2438 * 2439 * Return: None 2440 */ 2441 static inline 2442 void hal_srng_update_ring_usage_wm_no_lock(hal_soc_handle_t hal_soc_hdl, 2443 hal_ring_handle_t hal_ring_hdl) 2444 { 2445 } 2446 2447 static inline 2448 int hal_dump_srng_high_wm_stats(hal_soc_handle_t hal_soc_hdl, 2449 hal_ring_handle_t hal_ring_hdl, 2450 char *buf, int buf_len, int pos) 2451 { 2452 return 0; 2453 } 2454 #endif 2455 2456 /** 2457 * hal_srng_access_end_unlocked() - End ring access (unlocked), update cached 2458 * ring head/tail pointers to HW. 2459 * @hal_soc: Opaque HAL SOC handle 2460 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2461 * 2462 * The target expects cached head/tail pointer to be updated to the 2463 * shared location in the little-endian order, This API ensures that. 2464 * This API should be used only if hal_srng_access_start_unlocked was used to 2465 * start ring access 2466 * 2467 * Return: None 2468 */ 2469 static inline void 2470 hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 2471 { 2472 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2473 2474 /* TODO: See if we need a write memory barrier here */ 2475 if (srng->flags & HAL_SRNG_LMAC_RING) { 2476 /* For LMAC rings, ring pointer updates are done through FW and 2477 * hence written to a shared memory location that is read by FW 2478 */ 2479 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 2480 *srng->u.src_ring.hp_addr = 2481 qdf_cpu_to_le32(srng->u.src_ring.hp); 2482 } else { 2483 *srng->u.dst_ring.tp_addr = 2484 qdf_cpu_to_le32(srng->u.dst_ring.tp); 2485 } 2486 } else { 2487 if (srng->ring_dir == HAL_SRNG_SRC_RING) 2488 hal_srng_write_address_32_mb(hal_soc, 2489 srng, 2490 srng->u.src_ring.hp_addr, 2491 srng->u.src_ring.hp); 2492 else 2493 hal_srng_write_address_32_mb(hal_soc, 2494 srng, 2495 srng->u.dst_ring.tp_addr, 2496 srng->u.dst_ring.tp); 2497 } 2498 } 2499 2500 /* hal_srng_access_end_unlocked already handles endianness conversion, 2501 * use the same. 2502 */ 2503 #define hal_le_srng_access_end_unlocked_in_cpu_order \ 2504 hal_srng_access_end_unlocked 2505 2506 /** 2507 * hal_srng_access_end() - Unlock ring access and update cached ring head/tail 2508 * pointers to HW 2509 * @hal_soc: Opaque HAL SOC handle 2510 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2511 * 2512 * The target expects cached head/tail pointer to be updated to the 2513 * shared location in the little-endian order, This API ensures that. 2514 * This API should be used only if hal_srng_access_start was used to 2515 * start ring access 2516 * 2517 */ 2518 static inline void 2519 hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 2520 { 2521 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2522 2523 if (qdf_unlikely(!hal_ring_hdl)) { 2524 qdf_print("Error: Invalid hal_ring\n"); 2525 return; 2526 } 2527 2528 hal_srng_access_end_unlocked(hal_soc, hal_ring_hdl); 2529 SRNG_UNLOCK(&(srng->lock)); 2530 } 2531 2532 #ifdef FEATURE_RUNTIME_PM 2533 #define hal_srng_access_end_v1 hal_srng_rtpm_access_end 2534 2535 /** 2536 * hal_srng_rtpm_access_end() - RTPM aware, Unlock ring access 2537 * @hal_soc_hdl: Opaque HAL SOC handle 2538 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2539 * @rtpm_id: RTPM debug id 2540 * 2541 * Function updates the HP/TP value to the hardware register. 2542 * The target expects cached head/tail pointer to be updated to the 2543 * shared location in the little-endian order, This API ensures that. 2544 * This API should be used only if hal_srng_access_start was used to 2545 * start ring access 2546 * 2547 * Return: None 2548 */ 2549 void 2550 hal_srng_rtpm_access_end(hal_soc_handle_t hal_soc_hdl, 2551 hal_ring_handle_t hal_ring_hdl, 2552 uint32_t rtpm_id); 2553 #else 2554 #define hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, rtpm_id) \ 2555 hal_srng_access_end(hal_soc_hdl, hal_ring_hdl) 2556 #endif 2557 2558 /* hal_srng_access_end already handles endianness conversion, so use the same */ 2559 #define hal_le_srng_access_end_in_cpu_order \ 2560 hal_srng_access_end 2561 2562 /** 2563 * hal_srng_access_end_reap() - Unlock ring access 2564 * @hal_soc: Opaque HAL SOC handle 2565 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2566 * 2567 * This should be used only if hal_srng_access_start to start ring access 2568 * and should be used only while reaping SRC ring completions 2569 * 2570 * Return: 0 on success; error on failire 2571 */ 2572 static inline void 2573 hal_srng_access_end_reap(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 2574 { 2575 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2576 2577 SRNG_UNLOCK(&(srng->lock)); 2578 } 2579 2580 /* TODO: Check if the following definitions is available in HW headers */ 2581 #define WBM_IDLE_SCATTER_BUF_SIZE 32704 2582 #define NUM_MPDUS_PER_LINK_DESC 6 2583 #define NUM_MSDUS_PER_LINK_DESC 7 2584 #define REO_QUEUE_DESC_ALIGN 128 2585 2586 #define LINK_DESC_ALIGN 128 2587 2588 #define ADDRESS_MATCH_TAG_VAL 0x5 2589 /* Number of mpdu link pointers is 9 in case of TX_MPDU_QUEUE_HEAD and 14 in 2590 * of TX_MPDU_QUEUE_EXT. We are defining a common average count here 2591 */ 2592 #define NUM_MPDU_LINKS_PER_QUEUE_DESC 12 2593 2594 /* TODO: Check with HW team on the scatter buffer size supported. As per WBM 2595 * MLD, scatter_buffer_size in IDLE_LIST_CONTROL register is 9 bits and size 2596 * should be specified in 16 word units. But the number of bits defined for 2597 * this field in HW header files is 5. 2598 */ 2599 #define WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE 8 2600 2601 2602 /** 2603 * hal_idle_list_scatter_buf_size() - Get the size of each scatter buffer 2604 * in an idle list 2605 * @hal_soc_hdl: Opaque HAL SOC handle 2606 * 2607 * Return: scatter buffer size 2608 */ 2609 static inline 2610 uint32_t hal_idle_list_scatter_buf_size(hal_soc_handle_t hal_soc_hdl) 2611 { 2612 return WBM_IDLE_SCATTER_BUF_SIZE; 2613 } 2614 2615 /** 2616 * hal_get_link_desc_size() - Get the size of each link descriptor 2617 * @hal_soc_hdl: Opaque HAL SOC handle 2618 * 2619 * Return: link descriptor size 2620 */ 2621 static inline uint32_t hal_get_link_desc_size(hal_soc_handle_t hal_soc_hdl) 2622 { 2623 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 2624 2625 if (!hal_soc || !hal_soc->ops) { 2626 qdf_print("Error: Invalid ops\n"); 2627 QDF_BUG(0); 2628 return -EINVAL; 2629 } 2630 if (!hal_soc->ops->hal_get_link_desc_size) { 2631 qdf_print("Error: Invalid function pointer\n"); 2632 QDF_BUG(0); 2633 return -EINVAL; 2634 } 2635 return hal_soc->ops->hal_get_link_desc_size(); 2636 } 2637 2638 /** 2639 * hal_get_link_desc_align() - Get the required start address alignment for 2640 * link descriptors 2641 * @hal_soc_hdl: Opaque HAL SOC handle 2642 * 2643 * Return: the required alignment 2644 */ 2645 static inline 2646 uint32_t hal_get_link_desc_align(hal_soc_handle_t hal_soc_hdl) 2647 { 2648 return LINK_DESC_ALIGN; 2649 } 2650 2651 /** 2652 * hal_num_mpdus_per_link_desc() - Get number of mpdus each link desc can hold 2653 * @hal_soc_hdl: Opaque HAL SOC handle 2654 * 2655 * Return: number of MPDUs 2656 */ 2657 static inline 2658 uint32_t hal_num_mpdus_per_link_desc(hal_soc_handle_t hal_soc_hdl) 2659 { 2660 return NUM_MPDUS_PER_LINK_DESC; 2661 } 2662 2663 /** 2664 * hal_num_msdus_per_link_desc() - Get number of msdus each link desc can hold 2665 * @hal_soc_hdl: Opaque HAL SOC handle 2666 * 2667 * Return: number of MSDUs 2668 */ 2669 static inline 2670 uint32_t hal_num_msdus_per_link_desc(hal_soc_handle_t hal_soc_hdl) 2671 { 2672 return NUM_MSDUS_PER_LINK_DESC; 2673 } 2674 2675 /** 2676 * hal_num_mpdu_links_per_queue_desc() - Get number of mpdu links each queue 2677 * descriptor can hold 2678 * @hal_soc_hdl: Opaque HAL SOC handle 2679 * 2680 * Return: number of links per queue descriptor 2681 */ 2682 static inline 2683 uint32_t hal_num_mpdu_links_per_queue_desc(hal_soc_handle_t hal_soc_hdl) 2684 { 2685 return NUM_MPDU_LINKS_PER_QUEUE_DESC; 2686 } 2687 2688 /** 2689 * hal_idle_scatter_buf_num_entries() - Get the number of link desc entries 2690 * that the given buffer size 2691 * @hal_soc_hdl: Opaque HAL SOC handle 2692 * @scatter_buf_size: Size of scatter buffer 2693 * 2694 * Return: number of entries 2695 */ 2696 static inline 2697 uint32_t hal_idle_scatter_buf_num_entries(hal_soc_handle_t hal_soc_hdl, 2698 uint32_t scatter_buf_size) 2699 { 2700 return (scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) / 2701 hal_srng_get_entrysize(hal_soc_hdl, WBM_IDLE_LINK); 2702 } 2703 2704 /** 2705 * hal_idle_list_num_scatter_bufs() - Get the number of scatter buffer 2706 * each given buffer size 2707 * @hal_soc_hdl: Opaque HAL SOC handle 2708 * @total_mem: size of memory to be scattered 2709 * @scatter_buf_size: Size of scatter buffer 2710 * 2711 * Return: number of idle list scatter buffers 2712 */ 2713 static inline 2714 uint32_t hal_idle_list_num_scatter_bufs(hal_soc_handle_t hal_soc_hdl, 2715 uint32_t total_mem, 2716 uint32_t scatter_buf_size) 2717 { 2718 uint8_t rem = (total_mem % (scatter_buf_size - 2719 WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) ? 1 : 0; 2720 2721 uint32_t num_scatter_bufs = (total_mem / (scatter_buf_size - 2722 WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) + rem; 2723 2724 return num_scatter_bufs; 2725 } 2726 2727 enum hal_pn_type { 2728 HAL_PN_NONE, 2729 HAL_PN_WPA, 2730 HAL_PN_WAPI_EVEN, 2731 HAL_PN_WAPI_UNEVEN, 2732 }; 2733 2734 #define HAL_RX_BA_WINDOW_256 256 2735 #define HAL_RX_BA_WINDOW_1024 1024 2736 2737 /** 2738 * hal_get_reo_qdesc_align() - Get start address alignment for reo 2739 * queue descriptors 2740 * @hal_soc_hdl: Opaque HAL SOC handle 2741 * 2742 * Return: required start address alignment 2743 */ 2744 static inline 2745 uint32_t hal_get_reo_qdesc_align(hal_soc_handle_t hal_soc_hdl) 2746 { 2747 return REO_QUEUE_DESC_ALIGN; 2748 } 2749 2750 /** 2751 * hal_srng_get_hp_addr() - Get head pointer physical address 2752 * @hal_soc: Opaque HAL SOC handle 2753 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2754 * 2755 * Return: head pointer physical address 2756 */ 2757 static inline qdf_dma_addr_t 2758 hal_srng_get_hp_addr(void *hal_soc, 2759 hal_ring_handle_t hal_ring_hdl) 2760 { 2761 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2762 struct hal_soc *hal = (struct hal_soc *)hal_soc; 2763 2764 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 2765 if (srng->flags & HAL_SRNG_LMAC_RING) 2766 return hal->shadow_wrptr_mem_paddr + 2767 ((unsigned long)(srng->u.src_ring.hp_addr) - 2768 (unsigned long)(hal->shadow_wrptr_mem_vaddr)); 2769 else if (ignore_shadow) 2770 return (qdf_dma_addr_t)srng->u.src_ring.hp_addr; 2771 else 2772 return ((struct hif_softc *)hal->hif_handle)->mem_pa + 2773 ((unsigned long)srng->u.src_ring.hp_addr - 2774 (unsigned long)hal->dev_base_addr); 2775 2776 } else { 2777 return hal->shadow_rdptr_mem_paddr + 2778 ((unsigned long)(srng->u.dst_ring.hp_addr) - 2779 (unsigned long)(hal->shadow_rdptr_mem_vaddr)); 2780 } 2781 } 2782 2783 /** 2784 * hal_srng_get_tp_addr() - Get tail pointer physical address 2785 * @hal_soc: Opaque HAL SOC handle 2786 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2787 * 2788 * Return: tail pointer physical address 2789 */ 2790 static inline qdf_dma_addr_t 2791 hal_srng_get_tp_addr(void *hal_soc, hal_ring_handle_t hal_ring_hdl) 2792 { 2793 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2794 struct hal_soc *hal = (struct hal_soc *)hal_soc; 2795 2796 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 2797 return hal->shadow_rdptr_mem_paddr + 2798 ((unsigned long)(srng->u.src_ring.tp_addr) - 2799 (unsigned long)(hal->shadow_rdptr_mem_vaddr)); 2800 } else { 2801 if (srng->flags & HAL_SRNG_LMAC_RING) 2802 return hal->shadow_wrptr_mem_paddr + 2803 ((unsigned long)(srng->u.dst_ring.tp_addr) - 2804 (unsigned long)(hal->shadow_wrptr_mem_vaddr)); 2805 else if (ignore_shadow) 2806 return (qdf_dma_addr_t)srng->u.dst_ring.tp_addr; 2807 else 2808 return ((struct hif_softc *)hal->hif_handle)->mem_pa + 2809 ((unsigned long)srng->u.dst_ring.tp_addr - 2810 (unsigned long)hal->dev_base_addr); 2811 } 2812 } 2813 2814 /** 2815 * hal_srng_get_num_entries() - Get total entries in the HAL Srng 2816 * @hal_soc_hdl: Opaque HAL SOC handle 2817 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2818 * 2819 * Return: total number of entries in hal ring 2820 */ 2821 static inline 2822 uint32_t hal_srng_get_num_entries(hal_soc_handle_t hal_soc_hdl, 2823 hal_ring_handle_t hal_ring_hdl) 2824 { 2825 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 2826 2827 return srng->num_entries; 2828 } 2829 2830 /** 2831 * hal_get_srng_params() - Retrieve SRNG parameters for a given ring from HAL 2832 * @hal_soc_hdl: Opaque HAL SOC handle 2833 * @hal_ring_hdl: Ring pointer (Source or Destination ring) 2834 * @ring_params: SRNG parameters will be returned through this structure 2835 */ 2836 void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl, 2837 hal_ring_handle_t hal_ring_hdl, 2838 struct hal_srng_params *ring_params); 2839 2840 /** 2841 * hal_get_meminfo() - Retrieve hal memory base address 2842 * @hal_soc_hdl: Opaque HAL SOC handle 2843 * @mem: pointer to structure to be updated with hal mem info 2844 */ 2845 void hal_get_meminfo(hal_soc_handle_t hal_soc_hdl, struct hal_mem_info *mem); 2846 2847 /** 2848 * hal_get_target_type() - Return target type 2849 * @hal_soc_hdl: Opaque HAL SOC handle 2850 * 2851 * Return: target type 2852 */ 2853 uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl); 2854 2855 /** 2856 * hal_srng_dst_hw_init() - Private function to initialize SRNG 2857 * destination ring HW 2858 * @hal: HAL SOC handle 2859 * @srng: SRNG ring pointer 2860 * @idle_check: Check if ring is idle 2861 * @idx: Ring index 2862 */ 2863 static inline void hal_srng_dst_hw_init(struct hal_soc *hal, 2864 struct hal_srng *srng, bool idle_check, 2865 uint16_t idx) 2866 { 2867 hal->ops->hal_srng_dst_hw_init(hal, srng, idle_check, idx); 2868 } 2869 2870 /** 2871 * hal_srng_src_hw_init() - Private function to initialize SRNG 2872 * source ring HW 2873 * @hal: HAL SOC handle 2874 * @srng: SRNG ring pointer 2875 * @idle_check: Check if ring is idle 2876 * @idx: Ring index 2877 */ 2878 static inline void hal_srng_src_hw_init(struct hal_soc *hal, 2879 struct hal_srng *srng, bool idle_check, 2880 uint16_t idx) 2881 { 2882 hal->ops->hal_srng_src_hw_init(hal, srng, idle_check, idx); 2883 } 2884 2885 /** 2886 * hal_srng_hw_disable() - Private function to disable SRNG 2887 * source ring HW 2888 * @hal_soc: HAL SOC handle 2889 * @srng: SRNG ring pointer 2890 */ 2891 static inline 2892 void hal_srng_hw_disable(struct hal_soc *hal_soc, struct hal_srng *srng) 2893 { 2894 if (hal_soc->ops->hal_srng_hw_disable) 2895 hal_soc->ops->hal_srng_hw_disable(hal_soc, srng); 2896 } 2897 2898 /** 2899 * hal_get_hw_hptp() - Get HW head and tail pointer value for any ring 2900 * @hal_soc_hdl: Opaque HAL SOC handle 2901 * @hal_ring_hdl: Source ring pointer 2902 * @headp: Head Pointer 2903 * @tailp: Tail Pointer 2904 * @ring_type: Ring 2905 * 2906 * Return: Update tail pointer and head pointer in arguments. 2907 */ 2908 static inline 2909 void hal_get_hw_hptp(hal_soc_handle_t hal_soc_hdl, 2910 hal_ring_handle_t hal_ring_hdl, 2911 uint32_t *headp, uint32_t *tailp, 2912 uint8_t ring_type) 2913 { 2914 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 2915 2916 hal_soc->ops->hal_get_hw_hptp(hal_soc, hal_ring_hdl, 2917 headp, tailp, ring_type); 2918 } 2919 2920 /** 2921 * hal_reo_setup() - Initialize HW REO block 2922 * @hal_soc_hdl: Opaque HAL SOC handle 2923 * @reoparams: parameters needed by HAL for REO config 2924 * @qref_reset: reset qref 2925 */ 2926 static inline void hal_reo_setup(hal_soc_handle_t hal_soc_hdl, 2927 void *reoparams, int qref_reset) 2928 { 2929 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 2930 2931 hal_soc->ops->hal_reo_setup(hal_soc, reoparams, qref_reset); 2932 } 2933 2934 static inline 2935 void hal_compute_reo_remap_ix2_ix3(hal_soc_handle_t hal_soc_hdl, 2936 uint32_t *ring, uint32_t num_rings, 2937 uint32_t *remap1, uint32_t *remap2) 2938 { 2939 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 2940 2941 return hal_soc->ops->hal_compute_reo_remap_ix2_ix3(ring, 2942 num_rings, remap1, remap2); 2943 } 2944 2945 static inline 2946 void hal_compute_reo_remap_ix0(hal_soc_handle_t hal_soc_hdl, uint32_t *remap0) 2947 { 2948 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 2949 2950 if (hal_soc->ops->hal_compute_reo_remap_ix0) 2951 hal_soc->ops->hal_compute_reo_remap_ix0(remap0); 2952 } 2953 2954 /** 2955 * hal_setup_link_idle_list() - Setup scattered idle list using the 2956 * buffer list provided 2957 * @hal_soc_hdl: Opaque HAL SOC handle 2958 * @scatter_bufs_base_paddr: Array of physical base addresses 2959 * @scatter_bufs_base_vaddr: Array of virtual base addresses 2960 * @num_scatter_bufs: Number of scatter buffers in the above lists 2961 * @scatter_buf_size: Size of each scatter buffer 2962 * @last_buf_end_offset: Offset to the last entry 2963 * @num_entries: Total entries of all scatter bufs 2964 * 2965 */ 2966 static inline 2967 void hal_setup_link_idle_list(hal_soc_handle_t hal_soc_hdl, 2968 qdf_dma_addr_t scatter_bufs_base_paddr[], 2969 void *scatter_bufs_base_vaddr[], 2970 uint32_t num_scatter_bufs, 2971 uint32_t scatter_buf_size, 2972 uint32_t last_buf_end_offset, 2973 uint32_t num_entries) 2974 { 2975 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 2976 2977 hal_soc->ops->hal_setup_link_idle_list(hal_soc, scatter_bufs_base_paddr, 2978 scatter_bufs_base_vaddr, num_scatter_bufs, 2979 scatter_buf_size, last_buf_end_offset, 2980 num_entries); 2981 2982 } 2983 2984 #ifdef DUMP_REO_QUEUE_INFO_IN_DDR 2985 /** 2986 * hal_dump_rx_reo_queue_desc() - Dump reo queue descriptor fields 2987 * @hw_qdesc_vaddr_aligned: Pointer to hw reo queue desc virtual addr 2988 * 2989 * Use the virtual addr pointer to reo h/w queue desc to read 2990 * the values from ddr and log them. 2991 * 2992 * Return: none 2993 */ 2994 static inline void hal_dump_rx_reo_queue_desc( 2995 void *hw_qdesc_vaddr_aligned) 2996 { 2997 struct rx_reo_queue *hw_qdesc = 2998 (struct rx_reo_queue *)hw_qdesc_vaddr_aligned; 2999 3000 if (!hw_qdesc) 3001 return; 3002 3003 hal_info("receive_queue_number %u vld %u window_jump_2k %u" 3004 " hole_count %u ba_window_size %u ignore_ampdu_flag %u" 3005 " svld %u ssn %u current_index %u" 3006 " disable_duplicate_detection %u soft_reorder_enable %u" 3007 " chk_2k_mode %u oor_mode %u mpdu_frames_processed_count %u" 3008 " msdu_frames_processed_count %u total_processed_byte_count %u" 3009 " late_receive_mpdu_count %u seq_2k_error_detected_flag %u" 3010 " pn_error_detected_flag %u current_mpdu_count %u" 3011 " current_msdu_count %u timeout_count %u" 3012 " forward_due_to_bar_count %u duplicate_count %u" 3013 " frames_in_order_count %u bar_received_count %u" 3014 " pn_check_needed %u pn_shall_be_even %u" 3015 " pn_shall_be_uneven %u pn_size %u", 3016 hw_qdesc->receive_queue_number, 3017 hw_qdesc->vld, 3018 hw_qdesc->window_jump_2k, 3019 hw_qdesc->hole_count, 3020 hw_qdesc->ba_window_size, 3021 hw_qdesc->ignore_ampdu_flag, 3022 hw_qdesc->svld, 3023 hw_qdesc->ssn, 3024 hw_qdesc->current_index, 3025 hw_qdesc->disable_duplicate_detection, 3026 hw_qdesc->soft_reorder_enable, 3027 hw_qdesc->chk_2k_mode, 3028 hw_qdesc->oor_mode, 3029 hw_qdesc->mpdu_frames_processed_count, 3030 hw_qdesc->msdu_frames_processed_count, 3031 hw_qdesc->total_processed_byte_count, 3032 hw_qdesc->late_receive_mpdu_count, 3033 hw_qdesc->seq_2k_error_detected_flag, 3034 hw_qdesc->pn_error_detected_flag, 3035 hw_qdesc->current_mpdu_count, 3036 hw_qdesc->current_msdu_count, 3037 hw_qdesc->timeout_count, 3038 hw_qdesc->forward_due_to_bar_count, 3039 hw_qdesc->duplicate_count, 3040 hw_qdesc->frames_in_order_count, 3041 hw_qdesc->bar_received_count, 3042 hw_qdesc->pn_check_needed, 3043 hw_qdesc->pn_shall_be_even, 3044 hw_qdesc->pn_shall_be_uneven, 3045 hw_qdesc->pn_size); 3046 } 3047 3048 #else /* DUMP_REO_QUEUE_INFO_IN_DDR */ 3049 3050 static inline void hal_dump_rx_reo_queue_desc( 3051 void *hw_qdesc_vaddr_aligned) 3052 { 3053 } 3054 #endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ 3055 3056 /** 3057 * hal_srng_dump_ring_desc() - Dump ring descriptor info 3058 * @hal_soc_hdl: Opaque HAL SOC handle 3059 * @hal_ring_hdl: Source ring pointer 3060 * @ring_desc: Opaque ring descriptor handle 3061 */ 3062 static inline void hal_srng_dump_ring_desc(hal_soc_handle_t hal_soc_hdl, 3063 hal_ring_handle_t hal_ring_hdl, 3064 hal_ring_desc_t ring_desc) 3065 { 3066 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3067 3068 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, 3069 ring_desc, (srng->entry_size << 2)); 3070 } 3071 3072 /** 3073 * hal_srng_dump_ring() - Dump last 128 descs of the ring 3074 * @hal_soc_hdl: Opaque HAL SOC handle 3075 * @hal_ring_hdl: Source ring pointer 3076 */ 3077 static inline void hal_srng_dump_ring(hal_soc_handle_t hal_soc_hdl, 3078 hal_ring_handle_t hal_ring_hdl) 3079 { 3080 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3081 uint32_t *desc; 3082 uint32_t tp, i; 3083 3084 tp = srng->u.dst_ring.tp; 3085 3086 for (i = 0; i < 128; i++) { 3087 if (!tp) 3088 tp = srng->ring_size; 3089 3090 desc = &srng->ring_base_vaddr[tp - srng->entry_size]; 3091 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, 3092 QDF_TRACE_LEVEL_DEBUG, 3093 desc, (srng->entry_size << 2)); 3094 3095 tp -= srng->entry_size; 3096 } 3097 } 3098 3099 /** 3100 * hal_rxdma_desc_to_hal_ring_desc() - API to convert rxdma ring desc 3101 * to opaque dp_ring desc type 3102 * @ring_desc: rxdma ring desc 3103 * 3104 * Return: hal_rxdma_desc_t type 3105 */ 3106 static inline 3107 hal_ring_desc_t hal_rxdma_desc_to_hal_ring_desc(hal_rxdma_desc_t ring_desc) 3108 { 3109 return (hal_ring_desc_t)ring_desc; 3110 } 3111 3112 /** 3113 * hal_srng_set_event() - Set hal_srng event 3114 * @hal_ring_hdl: Source ring pointer 3115 * @event: SRNG ring event 3116 * 3117 * Return: None 3118 */ 3119 static inline void hal_srng_set_event(hal_ring_handle_t hal_ring_hdl, int event) 3120 { 3121 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3122 3123 qdf_atomic_set_bit(event, &srng->srng_event); 3124 } 3125 3126 /** 3127 * hal_srng_clear_event() - Clear hal_srng event 3128 * @hal_ring_hdl: Source ring pointer 3129 * @event: SRNG ring event 3130 * 3131 * Return: None 3132 */ 3133 static inline 3134 void hal_srng_clear_event(hal_ring_handle_t hal_ring_hdl, int event) 3135 { 3136 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3137 3138 qdf_atomic_clear_bit(event, &srng->srng_event); 3139 } 3140 3141 /** 3142 * hal_srng_get_clear_event() - Clear srng event and return old value 3143 * @hal_ring_hdl: Source ring pointer 3144 * @event: SRNG ring event 3145 * 3146 * Return: Return old event value 3147 */ 3148 static inline 3149 int hal_srng_get_clear_event(hal_ring_handle_t hal_ring_hdl, int event) 3150 { 3151 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3152 3153 return qdf_atomic_test_and_clear_bit(event, &srng->srng_event); 3154 } 3155 3156 /** 3157 * hal_srng_set_flush_last_ts() - Record last flush time stamp 3158 * @hal_ring_hdl: Source ring pointer 3159 * 3160 * Return: None 3161 */ 3162 static inline void hal_srng_set_flush_last_ts(hal_ring_handle_t hal_ring_hdl) 3163 { 3164 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3165 3166 srng->last_flush_ts = qdf_get_log_timestamp(); 3167 } 3168 3169 /** 3170 * hal_srng_inc_flush_cnt() - Increment flush counter 3171 * @hal_ring_hdl: Source ring pointer 3172 * 3173 * Return: None 3174 */ 3175 static inline void hal_srng_inc_flush_cnt(hal_ring_handle_t hal_ring_hdl) 3176 { 3177 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3178 3179 srng->flush_count++; 3180 } 3181 3182 /** 3183 * hal_rx_sw_mon_desc_info_get() - Get SW monitor desc info 3184 * @hal: Core HAL soc handle 3185 * @ring_desc: Mon dest ring descriptor 3186 * @desc_info: Desc info to be populated 3187 * 3188 * Return void 3189 */ 3190 static inline void 3191 hal_rx_sw_mon_desc_info_get(struct hal_soc *hal, 3192 hal_ring_desc_t ring_desc, 3193 hal_rx_mon_desc_info_t desc_info) 3194 { 3195 return hal->ops->hal_rx_sw_mon_desc_info_get(ring_desc, desc_info); 3196 } 3197 3198 /** 3199 * hal_reo_set_err_dst_remap() - Set REO error destination ring remap 3200 * register value. 3201 * 3202 * @hal_soc_hdl: Opaque HAL soc handle 3203 * 3204 * Return: None 3205 */ 3206 static inline void hal_reo_set_err_dst_remap(hal_soc_handle_t hal_soc_hdl) 3207 { 3208 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 3209 3210 if (hal_soc->ops->hal_reo_set_err_dst_remap) 3211 hal_soc->ops->hal_reo_set_err_dst_remap(hal_soc); 3212 } 3213 3214 /** 3215 * hal_reo_enable_pn_in_dest() - Subscribe for previous PN for 2k-jump or 3216 * OOR error frames 3217 * @hal_soc_hdl: Opaque HAL soc handle 3218 * 3219 * Return: true if feature is enabled, 3220 * false, otherwise. 3221 */ 3222 static inline uint8_t 3223 hal_reo_enable_pn_in_dest(hal_soc_handle_t hal_soc_hdl) 3224 { 3225 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 3226 3227 if (hal_soc->ops->hal_reo_enable_pn_in_dest) 3228 return hal_soc->ops->hal_reo_enable_pn_in_dest(hal_soc); 3229 3230 return 0; 3231 } 3232 3233 #ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE 3234 3235 /** 3236 * hal_set_one_target_reg_config() - Populate the target reg 3237 * offset in hal_soc for one non srng related register at the 3238 * given list index 3239 * @hal: hal handle 3240 * @target_reg_offset: target register offset 3241 * @list_index: index in hal list for shadow regs 3242 * 3243 * Return: none 3244 */ 3245 void hal_set_one_target_reg_config(struct hal_soc *hal, 3246 uint32_t target_reg_offset, 3247 int list_index); 3248 3249 /** 3250 * hal_set_shadow_regs() - Populate register offset for 3251 * registers that need to be populated in list_shadow_reg_config 3252 * in order to be sent to FW. These reg offsets will be mapped 3253 * to shadow registers. 3254 * @hal_soc: hal handle 3255 * 3256 * Return: QDF_STATUS_OK on success 3257 */ 3258 QDF_STATUS hal_set_shadow_regs(void *hal_soc); 3259 3260 /** 3261 * hal_construct_shadow_regs() - initialize the shadow registers 3262 * for non-srng related register configs 3263 * @hal_soc: hal handle 3264 * 3265 * Return: QDF_STATUS_OK on success 3266 */ 3267 QDF_STATUS hal_construct_shadow_regs(void *hal_soc); 3268 3269 #else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ 3270 static inline void hal_set_one_target_reg_config( 3271 struct hal_soc *hal, 3272 uint32_t target_reg_offset, 3273 int list_index) 3274 { 3275 } 3276 3277 static inline QDF_STATUS hal_set_shadow_regs(void *hal_soc) 3278 { 3279 return QDF_STATUS_SUCCESS; 3280 } 3281 3282 static inline QDF_STATUS hal_construct_shadow_regs(void *hal_soc) 3283 { 3284 return QDF_STATUS_SUCCESS; 3285 } 3286 #endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ 3287 3288 #ifdef FEATURE_HAL_DELAYED_REG_WRITE 3289 /** 3290 * hal_flush_reg_write_work() - flush all writes from register write queue 3291 * @hal_handle: hal_soc pointer 3292 * 3293 * Return: None 3294 */ 3295 void hal_flush_reg_write_work(hal_soc_handle_t hal_handle); 3296 3297 #else 3298 static inline void hal_flush_reg_write_work(hal_soc_handle_t hal_handle) { } 3299 #endif 3300 3301 /** 3302 * hal_get_ring_usage() - Calculate the ring usage percentage 3303 * @hal_ring_hdl: Ring pointer 3304 * @ring_type: Ring type 3305 * @headp: pointer to head value 3306 * @tailp: pointer to tail value 3307 * 3308 * Calculate the ring usage percentage for src and dest rings 3309 * 3310 * Return: Ring usage percentage 3311 */ 3312 static inline 3313 uint32_t hal_get_ring_usage( 3314 hal_ring_handle_t hal_ring_hdl, 3315 enum hal_ring_type ring_type, uint32_t *headp, uint32_t *tailp) 3316 { 3317 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3318 uint32_t num_avail, num_valid = 0; 3319 uint32_t ring_usage; 3320 3321 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 3322 if (*tailp > *headp) 3323 num_avail = ((*tailp - *headp) / srng->entry_size) - 1; 3324 else 3325 num_avail = ((srng->ring_size - *headp + *tailp) / 3326 srng->entry_size) - 1; 3327 if (ring_type == WBM_IDLE_LINK) 3328 num_valid = num_avail; 3329 else 3330 num_valid = srng->num_entries - num_avail; 3331 } else { 3332 if (*headp >= *tailp) 3333 num_valid = ((*headp - *tailp) / srng->entry_size); 3334 else 3335 num_valid = ((srng->ring_size - *tailp + *headp) / 3336 srng->entry_size); 3337 } 3338 ring_usage = (100 * num_valid) / srng->num_entries; 3339 return ring_usage; 3340 } 3341 3342 /* 3343 * hal_update_ring_util_stats - API for tracking ring utlization 3344 * @hal_soc: Opaque HAL SOC handle 3345 * @hal_ring_hdl: Source ring pointer 3346 * @ring_type: Ring type 3347 * @ring_util_stats: Ring utilisation structure 3348 */ 3349 static inline 3350 void hal_update_ring_util(void *hal_soc, hal_ring_handle_t hal_ring_hdl, 3351 enum hal_ring_type ring_type, 3352 struct ring_util_stats *ring_utilisation) 3353 { 3354 uint32_t tailp, headp, ring_usage; 3355 3356 hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tailp, &headp); 3357 ring_usage = hal_get_ring_usage(hal_ring_hdl, ring_type, &headp, 3358 &tailp); 3359 3360 if (ring_usage == RING_USAGE_100_PERCENTAGE) { 3361 ring_utilisation->util[RING_USAGE_100]++; 3362 } else if (ring_usage > RING_USAGE_90_PERCENTAGE) { 3363 ring_utilisation->util[RING_USAGE_GREAT_90]++; 3364 } else if ((ring_usage > RING_USAGE_70_PERCENTAGE) && 3365 (ring_usage <= RING_USAGE_90_PERCENTAGE)) { 3366 ring_utilisation->util[RING_USAGE_70_TO_90]++; 3367 } else if ((ring_usage > RING_USAGE_50_PERCENTAGE) && 3368 (ring_usage <= RING_USAGE_70_PERCENTAGE)) { 3369 ring_utilisation->util[RING_USAGE_50_TO_70]++; 3370 } else { 3371 ring_utilisation->util[RING_USAGE_LESS_50]++; 3372 } 3373 } 3374 3375 /** 3376 * hal_cmem_write() - function for CMEM buffer writing 3377 * @hal_soc_hdl: HAL SOC handle 3378 * @offset: CMEM address 3379 * @value: value to write 3380 * 3381 * Return: None. 3382 */ 3383 static inline void 3384 hal_cmem_write(hal_soc_handle_t hal_soc_hdl, uint32_t offset, 3385 uint32_t value) 3386 { 3387 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 3388 3389 if (hal_soc->ops->hal_cmem_write) 3390 hal_soc->ops->hal_cmem_write(hal_soc_hdl, offset, value); 3391 3392 return; 3393 } 3394 3395 static inline bool 3396 hal_dmac_cmn_src_rxbuf_ring_get(hal_soc_handle_t hal_soc_hdl) 3397 { 3398 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 3399 3400 return hal_soc->dmac_cmn_src_rxbuf_ring; 3401 } 3402 3403 /** 3404 * hal_srng_dst_prefetch() - function to prefetch 4 destination ring descs 3405 * @hal_soc_hdl: HAL SOC handle 3406 * @hal_ring_hdl: Destination ring pointer 3407 * @num_valid: valid entries in the ring 3408 * 3409 * Return: last prefetched destination ring descriptor 3410 */ 3411 static inline 3412 void *hal_srng_dst_prefetch(hal_soc_handle_t hal_soc_hdl, 3413 hal_ring_handle_t hal_ring_hdl, 3414 uint16_t num_valid) 3415 { 3416 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3417 uint8_t *desc; 3418 uint32_t cnt; 3419 /* 3420 * prefetching 4 HW descriptors will ensure atleast by the time 3421 * 5th HW descriptor is being processed it is guaranteed that the 3422 * 5th HW descriptor, its SW Desc, its nbuf and its nbuf's data 3423 * are in cache line. basically ensuring all the 4 (HW, SW, nbuf 3424 * & nbuf->data) are prefetched. 3425 */ 3426 uint32_t max_prefetch = 4; 3427 3428 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 3429 return NULL; 3430 3431 desc = (uint8_t *)&srng->ring_base_vaddr[srng->u.dst_ring.tp]; 3432 3433 if (num_valid < max_prefetch) 3434 max_prefetch = num_valid; 3435 3436 for (cnt = 0; cnt < max_prefetch; cnt++) { 3437 desc += srng->entry_size * sizeof(uint32_t); 3438 if (desc == ((uint8_t *)srng->ring_vaddr_end)) 3439 desc = (uint8_t *)&srng->ring_base_vaddr[0]; 3440 3441 qdf_prefetch(desc); 3442 } 3443 return (void *)desc; 3444 } 3445 3446 /** 3447 * hal_srng_dst_prefetch_next_cached_desc() - function to prefetch next desc 3448 * @hal_soc_hdl: HAL SOC handle 3449 * @hal_ring_hdl: Destination ring pointer 3450 * @last_prefetched_hw_desc: last prefetched HW descriptor 3451 * 3452 * Return: next prefetched destination descriptor 3453 */ 3454 static inline 3455 void *hal_srng_dst_prefetch_next_cached_desc(hal_soc_handle_t hal_soc_hdl, 3456 hal_ring_handle_t hal_ring_hdl, 3457 uint8_t *last_prefetched_hw_desc) 3458 { 3459 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3460 3461 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 3462 return NULL; 3463 3464 last_prefetched_hw_desc += srng->entry_size * sizeof(uint32_t); 3465 if (last_prefetched_hw_desc == ((uint8_t *)srng->ring_vaddr_end)) 3466 last_prefetched_hw_desc = (uint8_t *)&srng->ring_base_vaddr[0]; 3467 3468 qdf_prefetch(last_prefetched_hw_desc); 3469 return (void *)last_prefetched_hw_desc; 3470 } 3471 3472 /** 3473 * hal_srng_dst_prefetch_32_byte_desc() - function to prefetch a desc at 3474 * 64 byte offset 3475 * @hal_soc_hdl: HAL SOC handle 3476 * @hal_ring_hdl: Destination ring pointer 3477 * @num_valid: valid entries in the ring 3478 * 3479 * Return: last prefetched destination ring descriptor 3480 */ 3481 static inline 3482 void *hal_srng_dst_prefetch_32_byte_desc(hal_soc_handle_t hal_soc_hdl, 3483 hal_ring_handle_t hal_ring_hdl, 3484 uint16_t num_valid) 3485 { 3486 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3487 uint8_t *desc; 3488 3489 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 3490 return NULL; 3491 3492 desc = (uint8_t *)&srng->ring_base_vaddr[srng->u.dst_ring.tp]; 3493 3494 if ((uintptr_t)desc & 0x3f) 3495 desc += srng->entry_size * sizeof(uint32_t); 3496 else 3497 desc += (srng->entry_size * sizeof(uint32_t)) * 2; 3498 3499 if (desc == ((uint8_t *)srng->ring_vaddr_end)) 3500 desc = (uint8_t *)&srng->ring_base_vaddr[0]; 3501 3502 qdf_prefetch(desc); 3503 3504 return (void *)(desc + srng->entry_size * sizeof(uint32_t)); 3505 } 3506 3507 /** 3508 * hal_srng_dst_get_next_32_byte_desc() - function to prefetch next desc 3509 * @hal_soc_hdl: HAL SOC handle 3510 * @hal_ring_hdl: Destination ring pointer 3511 * @last_prefetched_hw_desc: last prefetched HW descriptor 3512 * 3513 * Return: next prefetched destination descriptor 3514 */ 3515 static inline 3516 void *hal_srng_dst_get_next_32_byte_desc(hal_soc_handle_t hal_soc_hdl, 3517 hal_ring_handle_t hal_ring_hdl, 3518 uint8_t *last_prefetched_hw_desc) 3519 { 3520 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3521 3522 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 3523 return NULL; 3524 3525 last_prefetched_hw_desc += srng->entry_size * sizeof(uint32_t); 3526 if (last_prefetched_hw_desc == ((uint8_t *)srng->ring_vaddr_end)) 3527 last_prefetched_hw_desc = (uint8_t *)&srng->ring_base_vaddr[0]; 3528 3529 return (void *)last_prefetched_hw_desc; 3530 } 3531 3532 /** 3533 * hal_srng_src_set_hp() - set head idx. 3534 * @hal_ring_hdl: srng handle 3535 * @idx: head idx 3536 * 3537 * Return: none 3538 */ 3539 static inline 3540 void hal_srng_src_set_hp(hal_ring_handle_t hal_ring_hdl, uint16_t idx) 3541 { 3542 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3543 3544 srng->u.src_ring.hp = idx * srng->entry_size; 3545 } 3546 3547 /** 3548 * hal_srng_dst_set_tp() - set tail idx. 3549 * @hal_ring_hdl: srng handle 3550 * @idx: tail idx 3551 * 3552 * Return: none 3553 */ 3554 static inline 3555 void hal_srng_dst_set_tp(hal_ring_handle_t hal_ring_hdl, uint16_t idx) 3556 { 3557 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3558 3559 srng->u.dst_ring.tp = idx * srng->entry_size; 3560 } 3561 3562 /** 3563 * hal_srng_src_get_tpidx() - get tail idx 3564 * @hal_ring_hdl: srng handle 3565 * 3566 * Return: tail idx 3567 */ 3568 static inline 3569 uint16_t hal_srng_src_get_tpidx(hal_ring_handle_t hal_ring_hdl) 3570 { 3571 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3572 uint32_t tp = *(volatile uint32_t *)(srng->u.src_ring.tp_addr); 3573 3574 return tp / srng->entry_size; 3575 } 3576 3577 /** 3578 * hal_srng_dst_get_hpidx() - get head idx 3579 * @hal_ring_hdl: srng handle 3580 * 3581 * Return: head idx 3582 */ 3583 static inline 3584 uint16_t hal_srng_dst_get_hpidx(hal_ring_handle_t hal_ring_hdl) 3585 { 3586 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3587 uint32_t hp = *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); 3588 3589 return hp / srng->entry_size; 3590 } 3591 3592 /** 3593 * hal_srng_batch_threshold_irq_enabled() - check if srng batch count 3594 * threshold irq enabled 3595 * @hal_ring_hdl: srng handle 3596 * 3597 * Return: true if enabled, false if not. 3598 */ 3599 static inline 3600 bool hal_srng_batch_threshold_irq_enabled(hal_ring_handle_t hal_ring_hdl) 3601 { 3602 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; 3603 3604 if (srng->intr_batch_cntr_thres_entries && 3605 srng->flags & HAL_SRNG_MSI_INTR) 3606 return true; 3607 else 3608 return false; 3609 } 3610 3611 #ifdef FEATURE_DIRECT_LINK 3612 /** 3613 * hal_srng_set_msi_irq_config() - Set the MSI irq configuration for srng 3614 * @hal_soc_hdl: hal soc handle 3615 * @hal_ring_hdl: srng handle 3616 * @ring_params: ring parameters 3617 * 3618 * Return: QDF status 3619 */ 3620 static inline QDF_STATUS 3621 hal_srng_set_msi_irq_config(hal_soc_handle_t hal_soc_hdl, 3622 hal_ring_handle_t hal_ring_hdl, 3623 struct hal_srng_params *ring_params) 3624 { 3625 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; 3626 3627 return hal_soc->ops->hal_srng_set_msi_config(hal_ring_hdl, ring_params); 3628 } 3629 #else 3630 static inline QDF_STATUS 3631 hal_srng_set_msi_irq_config(hal_soc_handle_t hal_soc_hdl, 3632 hal_ring_handle_t hal_ring_hdl, 3633 struct hal_srng_params *ring_params) 3634 { 3635 return QDF_STATUS_E_NOSUPPORT; 3636 } 3637 #endif 3638 #endif /* _HAL_APIH_ */ 3639