1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "hal_hw_headers.h" 20 #include "hal_api.h" 21 #include "target_type.h" 22 #include "wcss_version.h" 23 #include "qdf_module.h" 24 #ifdef QCA_WIFI_QCA8074 25 void hal_qca6290_attach(struct hal_soc *hal); 26 #endif 27 #ifdef QCA_WIFI_QCA8074 28 void hal_qca8074_attach(struct hal_soc *hal); 29 #endif 30 #ifdef QCA_WIFI_QCA8074V2 31 void hal_qca8074v2_attach(struct hal_soc *hal); 32 #endif 33 #ifdef QCA_WIFI_QCA6390 34 void hal_qca6390_attach(struct hal_soc *hal); 35 #endif 36 37 /** 38 * hal_get_srng_ring_id() - get the ring id of a descriped ring 39 * @hal: hal_soc data structure 40 * @ring_type: type enum describing the ring 41 * @ring_num: which ring of the ring type 42 * @mac_id: which mac does the ring belong to (or 0 for non-lmac rings) 43 * 44 * Return: the ring id or -EINVAL if the ring does not exist. 45 */ 46 static int hal_get_srng_ring_id(struct hal_soc *hal, int ring_type, 47 int ring_num, int mac_id) 48 { 49 struct hal_hw_srng_config *ring_config = 50 HAL_SRNG_CONFIG(hal, ring_type); 51 int ring_id; 52 53 if (ring_num >= ring_config->max_rings) { 54 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, 55 "%s: ring_num exceeded maximum no. of supported rings", 56 __func__); 57 /* TODO: This is a programming error. Assert if this happens */ 58 return -EINVAL; 59 } 60 61 if (ring_config->lmac_ring) { 62 ring_id = ring_config->start_ring_id + ring_num + 63 (mac_id * HAL_MAX_RINGS_PER_LMAC); 64 } else { 65 ring_id = ring_config->start_ring_id + ring_num; 66 } 67 68 return ring_id; 69 } 70 71 static struct hal_srng *hal_get_srng(struct hal_soc *hal, int ring_id) 72 { 73 /* TODO: Should we allocate srng structures dynamically? */ 74 return &(hal->srng_list[ring_id]); 75 } 76 77 #define HP_OFFSET_IN_REG_START 1 78 #define OFFSET_FROM_HP_TO_TP 4 79 static void hal_update_srng_hp_tp_address(void *hal_soc, 80 int shadow_config_index, 81 int ring_type, 82 int ring_num) 83 { 84 struct hal_srng *srng; 85 struct hal_soc *hal = (struct hal_soc *)hal_soc; 86 int ring_id; 87 struct hal_hw_srng_config *ring_config = 88 HAL_SRNG_CONFIG(hal, ring_type); 89 90 ring_id = hal_get_srng_ring_id(hal_soc, ring_type, ring_num, 0); 91 if (ring_id < 0) 92 return; 93 94 srng = hal_get_srng(hal_soc, ring_id); 95 96 if (ring_config->ring_dir == HAL_SRNG_DST_RING) 97 srng->u.dst_ring.tp_addr = SHADOW_REGISTER(shadow_config_index) 98 + hal->dev_base_addr; 99 else 100 srng->u.src_ring.hp_addr = SHADOW_REGISTER(shadow_config_index) 101 + hal->dev_base_addr; 102 } 103 104 QDF_STATUS hal_set_one_shadow_config(void *hal_soc, 105 int ring_type, 106 int ring_num) 107 { 108 uint32_t target_register; 109 struct hal_soc *hal = (struct hal_soc *)hal_soc; 110 struct hal_hw_srng_config *srng_config = &hal->hw_srng_table[ring_type]; 111 int shadow_config_index = hal->num_shadow_registers_configured; 112 113 if (shadow_config_index >= MAX_SHADOW_REGISTERS) { 114 QDF_ASSERT(0); 115 return QDF_STATUS_E_RESOURCES; 116 } 117 118 hal->num_shadow_registers_configured++; 119 120 target_register = srng_config->reg_start[HP_OFFSET_IN_REG_START]; 121 target_register += (srng_config->reg_size[HP_OFFSET_IN_REG_START] 122 *ring_num); 123 124 /* if the ring is a dst ring, we need to shadow the tail pointer */ 125 if (srng_config->ring_dir == HAL_SRNG_DST_RING) 126 target_register += OFFSET_FROM_HP_TO_TP; 127 128 hal->shadow_config[shadow_config_index].addr = target_register; 129 130 /* update hp/tp addr in the hal_soc structure*/ 131 hal_update_srng_hp_tp_address(hal_soc, shadow_config_index, ring_type, 132 ring_num); 133 134 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, 135 "%s: target_reg %x, shadow_index %x, ring_type %d, ring num %d", 136 __func__, target_register, shadow_config_index, 137 ring_type, ring_num); 138 139 return QDF_STATUS_SUCCESS; 140 } 141 142 qdf_export_symbol(hal_set_one_shadow_config); 143 144 QDF_STATUS hal_construct_shadow_config(void *hal_soc) 145 { 146 int ring_type, ring_num; 147 struct hal_soc *hal = (struct hal_soc *)hal_soc; 148 149 for (ring_type = 0; ring_type < MAX_RING_TYPES; ring_type++) { 150 struct hal_hw_srng_config *srng_config = 151 &hal->hw_srng_table[ring_type]; 152 153 if (ring_type == CE_SRC || 154 ring_type == CE_DST || 155 ring_type == CE_DST_STATUS) 156 continue; 157 158 if (srng_config->lmac_ring) 159 continue; 160 161 for (ring_num = 0; ring_num < srng_config->max_rings; 162 ring_num++) 163 hal_set_one_shadow_config(hal_soc, ring_type, ring_num); 164 } 165 166 return QDF_STATUS_SUCCESS; 167 } 168 169 qdf_export_symbol(hal_construct_shadow_config); 170 171 void hal_get_shadow_config(void *hal_soc, 172 struct pld_shadow_reg_v2_cfg **shadow_config, 173 int *num_shadow_registers_configured) 174 { 175 struct hal_soc *hal = (struct hal_soc *)hal_soc; 176 177 *shadow_config = hal->shadow_config; 178 *num_shadow_registers_configured = 179 hal->num_shadow_registers_configured; 180 181 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 182 "%s", __func__); 183 } 184 185 qdf_export_symbol(hal_get_shadow_config); 186 187 188 static void hal_validate_shadow_register(struct hal_soc *hal, 189 uint32_t *destination, 190 uint32_t *shadow_address) 191 { 192 unsigned int index; 193 uint32_t *shadow_0_offset = SHADOW_REGISTER(0) + hal->dev_base_addr; 194 int destination_ba_offset = 195 ((char *)destination) - (char *)hal->dev_base_addr; 196 197 index = shadow_address - shadow_0_offset; 198 199 if (index >= MAX_SHADOW_REGISTERS) { 200 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 201 "%s: index %x out of bounds", __func__, index); 202 goto error; 203 } else if (hal->shadow_config[index].addr != destination_ba_offset) { 204 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 205 "%s: sanity check failure, expected %x, found %x", 206 __func__, destination_ba_offset, 207 hal->shadow_config[index].addr); 208 goto error; 209 } 210 return; 211 error: 212 qdf_print("%s: baddr %pK, desination %pK, shadow_address %pK s0offset %pK index %x", 213 __func__, hal->dev_base_addr, destination, shadow_address, 214 shadow_0_offset, index); 215 QDF_BUG(0); 216 return; 217 } 218 219 static void hal_target_based_configure(struct hal_soc *hal) 220 { 221 switch (hal->target_type) { 222 #ifdef QCA_WIFI_QCA6290 223 case TARGET_TYPE_QCA6290: 224 hal->use_register_windowing = true; 225 hal_qca6290_attach(hal); 226 break; 227 #endif 228 #ifdef QCA_WIFI_QCA6390 229 case TARGET_TYPE_QCA6390: 230 hal->use_register_windowing = true; 231 hal_qca6390_attach(hal); 232 break; 233 #endif 234 #if defined(QCA_WIFI_QCA8074) && defined(CONFIG_WIN) 235 case TARGET_TYPE_QCA8074: 236 hal_qca8074_attach(hal); 237 break; 238 #endif 239 240 #if defined(QCA_WIFI_QCA8074V2) && defined(CONFIG_WIN) 241 case TARGET_TYPE_QCA8074V2: 242 hal_qca8074v2_attach(hal); 243 break; 244 #endif 245 default: 246 break; 247 } 248 } 249 250 uint32_t hal_get_target_type(struct hal_soc *hal) 251 { 252 struct hif_target_info *tgt_info = 253 hif_get_target_info_handle(hal->hif_handle); 254 255 return tgt_info->target_type; 256 } 257 258 qdf_export_symbol(hal_get_target_type); 259 260 /** 261 * hal_attach - Initialize HAL layer 262 * @hif_handle: Opaque HIF handle 263 * @qdf_dev: QDF device 264 * 265 * Return: Opaque HAL SOC handle 266 * NULL on failure (if given ring is not available) 267 * 268 * This function should be called as part of HIF initialization (for accessing 269 * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle() 270 * 271 */ 272 void *hal_attach(void *hif_handle, qdf_device_t qdf_dev) 273 { 274 struct hal_soc *hal; 275 int i; 276 277 hal = qdf_mem_malloc(sizeof(*hal)); 278 279 if (!hal) { 280 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 281 "%s: hal_soc allocation failed", __func__); 282 goto fail0; 283 } 284 hal->hif_handle = hif_handle; 285 hal->dev_base_addr = hif_get_dev_ba(hif_handle); 286 hal->qdf_dev = qdf_dev; 287 hal->shadow_rdptr_mem_vaddr = (uint32_t *)qdf_mem_alloc_consistent( 288 qdf_dev, qdf_dev->dev, sizeof(*(hal->shadow_rdptr_mem_vaddr)) * 289 HAL_SRNG_ID_MAX, &(hal->shadow_rdptr_mem_paddr)); 290 if (!hal->shadow_rdptr_mem_paddr) { 291 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 292 "%s: hal->shadow_rdptr_mem_paddr allocation failed", 293 __func__); 294 goto fail1; 295 } 296 297 hal->shadow_wrptr_mem_vaddr = 298 (uint32_t *)qdf_mem_alloc_consistent(qdf_dev, qdf_dev->dev, 299 sizeof(*(hal->shadow_wrptr_mem_vaddr)) * HAL_MAX_LMAC_RINGS, 300 &(hal->shadow_wrptr_mem_paddr)); 301 if (!hal->shadow_wrptr_mem_vaddr) { 302 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 303 "%s: hal->shadow_wrptr_mem_vaddr allocation failed", 304 __func__); 305 goto fail2; 306 } 307 308 for (i = 0; i < HAL_SRNG_ID_MAX; i++) { 309 hal->srng_list[i].initialized = 0; 310 hal->srng_list[i].ring_id = i; 311 } 312 313 qdf_spinlock_create(&hal->register_access_lock); 314 hal->register_window = 0; 315 hal->target_type = hal_get_target_type(hal); 316 317 hal_target_based_configure(hal); 318 319 return (void *)hal; 320 321 fail2: 322 qdf_mem_free_consistent(qdf_dev, qdf_dev->dev, 323 sizeof(*(hal->shadow_rdptr_mem_vaddr)) * HAL_SRNG_ID_MAX, 324 hal->shadow_rdptr_mem_vaddr, hal->shadow_rdptr_mem_paddr, 0); 325 fail1: 326 qdf_mem_free(hal); 327 fail0: 328 return NULL; 329 } 330 qdf_export_symbol(hal_attach); 331 332 /** 333 * hal_mem_info - Retrieve hal memory base address 334 * 335 * @hal_soc: Opaque HAL SOC handle 336 * @mem: pointer to structure to be updated with hal mem info 337 */ 338 void hal_get_meminfo(void *hal_soc, struct hal_mem_info *mem ) 339 { 340 struct hal_soc *hal = (struct hal_soc *)hal_soc; 341 mem->dev_base_addr = (void *)hal->dev_base_addr; 342 mem->shadow_rdptr_mem_vaddr = (void *)hal->shadow_rdptr_mem_vaddr; 343 mem->shadow_wrptr_mem_vaddr = (void *)hal->shadow_wrptr_mem_vaddr; 344 mem->shadow_rdptr_mem_paddr = (void *)hal->shadow_rdptr_mem_paddr; 345 mem->shadow_wrptr_mem_paddr = (void *)hal->shadow_wrptr_mem_paddr; 346 hif_read_phy_mem_base(hal->hif_handle, (qdf_dma_addr_t *)&mem->dev_base_paddr); 347 return; 348 } 349 qdf_export_symbol(hal_get_meminfo); 350 351 /** 352 * hal_detach - Detach HAL layer 353 * @hal_soc: HAL SOC handle 354 * 355 * Return: Opaque HAL SOC handle 356 * NULL on failure (if given ring is not available) 357 * 358 * This function should be called as part of HIF initialization (for accessing 359 * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle() 360 * 361 */ 362 extern void hal_detach(void *hal_soc) 363 { 364 struct hal_soc *hal = (struct hal_soc *)hal_soc; 365 366 qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev, 367 sizeof(*(hal->shadow_rdptr_mem_vaddr)) * HAL_SRNG_ID_MAX, 368 hal->shadow_rdptr_mem_vaddr, hal->shadow_rdptr_mem_paddr, 0); 369 qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev, 370 sizeof(*(hal->shadow_wrptr_mem_vaddr)) * HAL_MAX_LMAC_RINGS, 371 hal->shadow_wrptr_mem_vaddr, hal->shadow_wrptr_mem_paddr, 0); 372 qdf_mem_free(hal); 373 374 return; 375 } 376 qdf_export_symbol(hal_detach); 377 378 379 /** 380 * hal_ce_dst_setup - Initialize CE destination ring registers 381 * @hal_soc: HAL SOC handle 382 * @srng: SRNG ring pointer 383 */ 384 static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng, 385 int ring_num) 386 { 387 uint32_t reg_val = 0; 388 uint32_t reg_addr; 389 struct hal_hw_srng_config *ring_config = 390 HAL_SRNG_CONFIG(hal, CE_DST); 391 392 /* set DEST_MAX_LENGTH according to ce assignment */ 393 reg_addr = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_ADDR( 394 ring_config->reg_start[R0_INDEX] + 395 (ring_num * ring_config->reg_size[R0_INDEX])); 396 397 reg_val = HAL_REG_READ(hal, reg_addr); 398 reg_val &= ~HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK; 399 reg_val |= srng->u.dst_ring.max_buffer_length & 400 HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK; 401 HAL_REG_WRITE(hal, reg_addr, reg_val); 402 } 403 404 /** 405 * hal_reo_remap_IX0 - Remap REO ring destination 406 * @hal: HAL SOC handle 407 * @remap_val: Remap value 408 */ 409 void hal_reo_remap_IX0(struct hal_soc *hal, uint32_t remap_val) 410 { 411 uint32_t reg_offset = HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR( 412 SEQ_WCSS_UMAC_REO_REG_OFFSET); 413 HAL_REG_WRITE(hal, reg_offset, remap_val); 414 } 415 416 /** 417 * hal_srng_dst_set_hp_paddr() - Set physical address to dest ring head pointer 418 * @srng: sring pointer 419 * @paddr: physical address 420 */ 421 void hal_srng_dst_set_hp_paddr(struct hal_srng *srng, 422 uint64_t paddr) 423 { 424 SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, 425 paddr & 0xffffffff); 426 SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, 427 paddr >> 32); 428 } 429 430 /** 431 * hal_srng_dst_init_hp() - Initilaize destination ring head pointer 432 * @srng: sring pointer 433 * @vaddr: virtual address 434 */ 435 void hal_srng_dst_init_hp(struct hal_srng *srng, 436 uint32_t *vaddr) 437 { 438 srng->u.dst_ring.hp_addr = vaddr; 439 SRNG_DST_REG_WRITE(srng, HP, srng->u.dst_ring.cached_hp); 440 *(srng->u.dst_ring.hp_addr) = srng->u.dst_ring.cached_hp; 441 442 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 443 "hp_addr=%pK, cached_hp=%d, hp=%d", 444 (void *)srng->u.dst_ring.hp_addr, srng->u.dst_ring.cached_hp, 445 *(srng->u.dst_ring.hp_addr)); 446 } 447 448 /** 449 * hal_srng_hw_init - Private function to initialize SRNG HW 450 * @hal_soc: HAL SOC handle 451 * @srng: SRNG ring pointer 452 */ 453 static inline void hal_srng_hw_init(struct hal_soc *hal, 454 struct hal_srng *srng) 455 { 456 if (srng->ring_dir == HAL_SRNG_SRC_RING) 457 hal_srng_src_hw_init(hal, srng); 458 else 459 hal_srng_dst_hw_init(hal, srng); 460 } 461 462 #ifdef CONFIG_SHADOW_V2 463 #define ignore_shadow false 464 #define CHECK_SHADOW_REGISTERS true 465 #else 466 #define ignore_shadow true 467 #define CHECK_SHADOW_REGISTERS false 468 #endif 469 470 /** 471 * hal_srng_setup - Initialize HW SRNG ring. 472 * @hal_soc: Opaque HAL SOC handle 473 * @ring_type: one of the types from hal_ring_type 474 * @ring_num: Ring number if there are multiple rings of same type (staring 475 * from 0) 476 * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings 477 * @ring_params: SRNG ring params in hal_srng_params structure. 478 479 * Callers are expected to allocate contiguous ring memory of size 480 * 'num_entries * entry_size' bytes and pass the physical and virtual base 481 * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in 482 * hal_srng_params structure. Ring base address should be 8 byte aligned 483 * and size of each ring entry should be queried using the API 484 * hal_srng_get_entrysize 485 * 486 * Return: Opaque pointer to ring on success 487 * NULL on failure (if given ring is not available) 488 */ 489 void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, 490 int mac_id, struct hal_srng_params *ring_params) 491 { 492 int ring_id; 493 struct hal_soc *hal = (struct hal_soc *)hal_soc; 494 struct hal_srng *srng; 495 struct hal_hw_srng_config *ring_config = 496 HAL_SRNG_CONFIG(hal, ring_type); 497 void *dev_base_addr; 498 int i; 499 500 ring_id = hal_get_srng_ring_id(hal_soc, ring_type, ring_num, mac_id); 501 if (ring_id < 0) 502 return NULL; 503 504 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, 505 "%s: mac_id %d ring_id %d", 506 __func__, mac_id, ring_id); 507 508 srng = hal_get_srng(hal_soc, ring_id); 509 510 if (srng->initialized) { 511 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 512 "%s: Ring (ring_type, ring_num) already initialized", 513 __func__); 514 return NULL; 515 } 516 517 dev_base_addr = hal->dev_base_addr; 518 srng->ring_id = ring_id; 519 srng->ring_dir = ring_config->ring_dir; 520 srng->ring_base_paddr = ring_params->ring_base_paddr; 521 srng->ring_base_vaddr = ring_params->ring_base_vaddr; 522 srng->entry_size = ring_config->entry_size; 523 srng->num_entries = ring_params->num_entries; 524 srng->ring_size = srng->num_entries * srng->entry_size; 525 srng->ring_size_mask = srng->ring_size - 1; 526 srng->msi_addr = ring_params->msi_addr; 527 srng->msi_data = ring_params->msi_data; 528 srng->intr_timer_thres_us = ring_params->intr_timer_thres_us; 529 srng->intr_batch_cntr_thres_entries = 530 ring_params->intr_batch_cntr_thres_entries; 531 srng->hal_soc = hal_soc; 532 533 for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) { 534 srng->hwreg_base[i] = dev_base_addr + ring_config->reg_start[i] 535 + (ring_num * ring_config->reg_size[i]); 536 } 537 538 /* Zero out the entire ring memory */ 539 qdf_mem_zero(srng->ring_base_vaddr, (srng->entry_size * 540 srng->num_entries) << 2); 541 542 srng->flags = ring_params->flags; 543 #ifdef BIG_ENDIAN_HOST 544 /* TODO: See if we should we get these flags from caller */ 545 srng->flags |= HAL_SRNG_DATA_TLV_SWAP; 546 srng->flags |= HAL_SRNG_MSI_SWAP; 547 srng->flags |= HAL_SRNG_RING_PTR_SWAP; 548 #endif 549 550 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 551 srng->u.src_ring.hp = 0; 552 srng->u.src_ring.reap_hp = srng->ring_size - 553 srng->entry_size; 554 srng->u.src_ring.tp_addr = 555 &(hal->shadow_rdptr_mem_vaddr[ring_id]); 556 srng->u.src_ring.low_threshold = 557 ring_params->low_threshold * srng->entry_size; 558 if (ring_config->lmac_ring) { 559 /* For LMAC rings, head pointer updates will be done 560 * through FW by writing to a shared memory location 561 */ 562 srng->u.src_ring.hp_addr = 563 &(hal->shadow_wrptr_mem_vaddr[ring_id - 564 HAL_SRNG_LMAC1_ID_START]); 565 srng->flags |= HAL_SRNG_LMAC_RING; 566 } else if (ignore_shadow || (srng->u.src_ring.hp_addr == 0)) { 567 srng->u.src_ring.hp_addr = SRNG_SRC_ADDR(srng, HP); 568 569 if (CHECK_SHADOW_REGISTERS) { 570 QDF_TRACE(QDF_MODULE_ID_TXRX, 571 QDF_TRACE_LEVEL_ERROR, 572 "%s: Ring (%d, %d) missing shadow config", 573 __func__, ring_type, ring_num); 574 } 575 } else { 576 hal_validate_shadow_register(hal, 577 SRNG_SRC_ADDR(srng, HP), 578 srng->u.src_ring.hp_addr); 579 } 580 } else { 581 /* During initialization loop count in all the descriptors 582 * will be set to zero, and HW will set it to 1 on completing 583 * descriptor update in first loop, and increments it by 1 on 584 * subsequent loops (loop count wraps around after reaching 585 * 0xffff). The 'loop_cnt' in SW ring state is the expected 586 * loop count in descriptors updated by HW (to be processed 587 * by SW). 588 */ 589 srng->u.dst_ring.loop_cnt = 1; 590 srng->u.dst_ring.tp = 0; 591 srng->u.dst_ring.hp_addr = 592 &(hal->shadow_rdptr_mem_vaddr[ring_id]); 593 if (ring_config->lmac_ring) { 594 /* For LMAC rings, tail pointer updates will be done 595 * through FW by writing to a shared memory location 596 */ 597 srng->u.dst_ring.tp_addr = 598 &(hal->shadow_wrptr_mem_vaddr[ring_id - 599 HAL_SRNG_LMAC1_ID_START]); 600 srng->flags |= HAL_SRNG_LMAC_RING; 601 } else if (ignore_shadow || srng->u.dst_ring.tp_addr == 0) { 602 srng->u.dst_ring.tp_addr = SRNG_DST_ADDR(srng, TP); 603 604 if (CHECK_SHADOW_REGISTERS) { 605 QDF_TRACE(QDF_MODULE_ID_TXRX, 606 QDF_TRACE_LEVEL_ERROR, 607 "%s: Ring (%d, %d) missing shadow config", 608 __func__, ring_type, ring_num); 609 } 610 } else { 611 hal_validate_shadow_register(hal, 612 SRNG_DST_ADDR(srng, TP), 613 srng->u.dst_ring.tp_addr); 614 } 615 } 616 617 if (!(ring_config->lmac_ring)) { 618 hal_srng_hw_init(hal, srng); 619 620 if (ring_type == CE_DST) { 621 srng->u.dst_ring.max_buffer_length = ring_params->max_buffer_length; 622 hal_ce_dst_setup(hal, srng, ring_num); 623 } 624 } 625 626 SRNG_LOCK_INIT(&srng->lock); 627 628 srng->initialized = true; 629 630 return (void *)srng; 631 } 632 qdf_export_symbol(hal_srng_setup); 633 634 /** 635 * hal_srng_cleanup - Deinitialize HW SRNG ring. 636 * @hal_soc: Opaque HAL SOC handle 637 * @hal_srng: Opaque HAL SRNG pointer 638 */ 639 void hal_srng_cleanup(void *hal_soc, void *hal_srng) 640 { 641 struct hal_srng *srng = (struct hal_srng *)hal_srng; 642 SRNG_LOCK_DESTROY(&srng->lock); 643 srng->initialized = 0; 644 } 645 qdf_export_symbol(hal_srng_cleanup); 646 647 /** 648 * hal_srng_get_entrysize - Returns size of ring entry in bytes 649 * @hal_soc: Opaque HAL SOC handle 650 * @ring_type: one of the types from hal_ring_type 651 * 652 */ 653 uint32_t hal_srng_get_entrysize(void *hal_soc, int ring_type) 654 { 655 struct hal_soc *hal = (struct hal_soc *)hal_soc; 656 struct hal_hw_srng_config *ring_config = 657 HAL_SRNG_CONFIG(hal, ring_type); 658 return ring_config->entry_size << 2; 659 } 660 qdf_export_symbol(hal_srng_get_entrysize); 661 662 /** 663 * hal_srng_max_entries - Returns maximum possible number of ring entries 664 * @hal_soc: Opaque HAL SOC handle 665 * @ring_type: one of the types from hal_ring_type 666 * 667 * Return: Maximum number of entries for the given ring_type 668 */ 669 uint32_t hal_srng_max_entries(void *hal_soc, int ring_type) 670 { 671 struct hal_soc *hal = (struct hal_soc *)hal_soc; 672 struct hal_hw_srng_config *ring_config = 673 HAL_SRNG_CONFIG(hal, ring_type); 674 675 return ring_config->max_size / ring_config->entry_size; 676 } 677 qdf_export_symbol(hal_srng_max_entries); 678 679 enum hal_srng_dir hal_srng_get_dir(void *hal_soc, int ring_type) 680 { 681 struct hal_soc *hal = (struct hal_soc *)hal_soc; 682 struct hal_hw_srng_config *ring_config = 683 HAL_SRNG_CONFIG(hal, ring_type); 684 685 return ring_config->ring_dir; 686 } 687 688 /** 689 * hal_srng_dump - Dump ring status 690 * @srng: hal srng pointer 691 */ 692 void hal_srng_dump(struct hal_srng *srng) 693 { 694 if (srng->ring_dir == HAL_SRNG_SRC_RING) { 695 qdf_print("=== SRC RING %d ===", srng->ring_id); 696 qdf_print("hp %u, reap_hp %u, tp %u, cached tp %u", 697 srng->u.src_ring.hp, 698 srng->u.src_ring.reap_hp, 699 *srng->u.src_ring.tp_addr, 700 srng->u.src_ring.cached_tp); 701 } else { 702 qdf_print("=== DST RING %d ===", srng->ring_id); 703 qdf_print("tp %u, hp %u, cached tp %u, loop_cnt %u", 704 srng->u.dst_ring.tp, 705 *srng->u.dst_ring.hp_addr, 706 srng->u.dst_ring.cached_hp, 707 srng->u.dst_ring.loop_cnt); 708 } 709 } 710 711 /** 712 * hal_get_srng_params - Retrieve SRNG parameters for a given ring from HAL 713 * 714 * @hal_soc: Opaque HAL SOC handle 715 * @hal_ring: Ring pointer (Source or Destination ring) 716 * @ring_params: SRNG parameters will be returned through this structure 717 */ 718 extern void hal_get_srng_params(void *hal_soc, void *hal_ring, 719 struct hal_srng_params *ring_params) 720 { 721 struct hal_srng *srng = (struct hal_srng *)hal_ring; 722 int i =0; 723 ring_params->ring_id = srng->ring_id; 724 ring_params->ring_dir = srng->ring_dir; 725 ring_params->entry_size = srng->entry_size; 726 727 ring_params->ring_base_paddr = srng->ring_base_paddr; 728 ring_params->ring_base_vaddr = srng->ring_base_vaddr; 729 ring_params->num_entries = srng->num_entries; 730 ring_params->msi_addr = srng->msi_addr; 731 ring_params->msi_data = srng->msi_data; 732 ring_params->intr_timer_thres_us = srng->intr_timer_thres_us; 733 ring_params->intr_batch_cntr_thres_entries = 734 srng->intr_batch_cntr_thres_entries; 735 ring_params->low_threshold = srng->u.src_ring.low_threshold; 736 ring_params->flags = srng->flags; 737 ring_params->ring_id = srng->ring_id; 738 for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) 739 ring_params->hwreg_base[i] = srng->hwreg_base[i]; 740 } 741 qdf_export_symbol(hal_get_srng_params); 742