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