1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 */ 5 #include <linux/dma-mapping.h> 6 #include "hal_tx.h" 7 #include "debug.h" 8 #include "hal_desc.h" 9 #include "hif.h" 10 11 static const struct hal_srng_config hw_srng_config_template[] = { 12 /* TODO: max_rings can populated by querying HW capabilities */ 13 { /* REO_DST */ 14 .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, 15 .max_rings = 4, 16 .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, 17 .lmac_ring = false, 18 .ring_dir = HAL_SRNG_DIR_DST, 19 .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, 20 }, 21 { /* REO_EXCEPTION */ 22 /* Designating REO2TCL ring as exception ring. This ring is 23 * similar to other REO2SW rings though it is named as REO2TCL. 24 * Any of theREO2SW rings can be used as exception ring. 25 */ 26 .start_ring_id = HAL_SRNG_RING_ID_REO2TCL, 27 .max_rings = 1, 28 .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, 29 .lmac_ring = false, 30 .ring_dir = HAL_SRNG_DIR_DST, 31 .max_size = HAL_REO_REO2TCL_RING_BASE_MSB_RING_SIZE, 32 }, 33 { /* REO_REINJECT */ 34 .start_ring_id = HAL_SRNG_RING_ID_SW2REO, 35 .max_rings = 1, 36 .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, 37 .lmac_ring = false, 38 .ring_dir = HAL_SRNG_DIR_SRC, 39 .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, 40 }, 41 { /* REO_CMD */ 42 .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, 43 .max_rings = 1, 44 .entry_size = (sizeof(struct hal_tlv_hdr) + 45 sizeof(struct hal_reo_get_queue_stats)) >> 2, 46 .lmac_ring = false, 47 .ring_dir = HAL_SRNG_DIR_SRC, 48 .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, 49 }, 50 { /* REO_STATUS */ 51 .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, 52 .max_rings = 1, 53 .entry_size = (sizeof(struct hal_tlv_hdr) + 54 sizeof(struct hal_reo_get_queue_stats_status)) >> 2, 55 .lmac_ring = false, 56 .ring_dir = HAL_SRNG_DIR_DST, 57 .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, 58 }, 59 { /* TCL_DATA */ 60 .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, 61 .max_rings = 3, 62 .entry_size = (sizeof(struct hal_tlv_hdr) + 63 sizeof(struct hal_tcl_data_cmd)) >> 2, 64 .lmac_ring = false, 65 .ring_dir = HAL_SRNG_DIR_SRC, 66 .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, 67 }, 68 { /* TCL_CMD */ 69 .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, 70 .max_rings = 1, 71 .entry_size = (sizeof(struct hal_tlv_hdr) + 72 sizeof(struct hal_tcl_gse_cmd)) >> 2, 73 .lmac_ring = false, 74 .ring_dir = HAL_SRNG_DIR_SRC, 75 .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, 76 }, 77 { /* TCL_STATUS */ 78 .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, 79 .max_rings = 1, 80 .entry_size = (sizeof(struct hal_tlv_hdr) + 81 sizeof(struct hal_tcl_status_ring)) >> 2, 82 .lmac_ring = false, 83 .ring_dir = HAL_SRNG_DIR_DST, 84 .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, 85 }, 86 { /* CE_SRC */ 87 .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, 88 .max_rings = 12, 89 .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, 90 .lmac_ring = false, 91 .ring_dir = HAL_SRNG_DIR_SRC, 92 .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, 93 }, 94 { /* CE_DST */ 95 .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, 96 .max_rings = 12, 97 .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, 98 .lmac_ring = false, 99 .ring_dir = HAL_SRNG_DIR_SRC, 100 .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, 101 }, 102 { /* CE_DST_STATUS */ 103 .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, 104 .max_rings = 12, 105 .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, 106 .lmac_ring = false, 107 .ring_dir = HAL_SRNG_DIR_DST, 108 .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, 109 }, 110 { /* WBM_IDLE_LINK */ 111 .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, 112 .max_rings = 1, 113 .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, 114 .lmac_ring = false, 115 .ring_dir = HAL_SRNG_DIR_SRC, 116 .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, 117 }, 118 { /* SW2WBM_RELEASE */ 119 .start_ring_id = HAL_SRNG_RING_ID_WBM_SW_RELEASE, 120 .max_rings = 1, 121 .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, 122 .lmac_ring = false, 123 .ring_dir = HAL_SRNG_DIR_SRC, 124 .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, 125 }, 126 { /* WBM2SW_RELEASE */ 127 .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, 128 .max_rings = 4, 129 .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, 130 .lmac_ring = false, 131 .ring_dir = HAL_SRNG_DIR_DST, 132 .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, 133 }, 134 { /* RXDMA_BUF */ 135 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF, 136 .max_rings = 2, 137 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, 138 .lmac_ring = true, 139 .ring_dir = HAL_SRNG_DIR_SRC, 140 .max_size = HAL_RXDMA_RING_MAX_SIZE, 141 }, 142 { /* RXDMA_DST */ 143 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, 144 .max_rings = 1, 145 .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, 146 .lmac_ring = true, 147 .ring_dir = HAL_SRNG_DIR_DST, 148 .max_size = HAL_RXDMA_RING_MAX_SIZE, 149 }, 150 { /* RXDMA_MONITOR_BUF */ 151 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA2_BUF, 152 .max_rings = 1, 153 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, 154 .lmac_ring = true, 155 .ring_dir = HAL_SRNG_DIR_SRC, 156 .max_size = HAL_RXDMA_RING_MAX_SIZE, 157 }, 158 { /* RXDMA_MONITOR_STATUS */ 159 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, 160 .max_rings = 1, 161 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, 162 .lmac_ring = true, 163 .ring_dir = HAL_SRNG_DIR_SRC, 164 .max_size = HAL_RXDMA_RING_MAX_SIZE, 165 }, 166 { /* RXDMA_MONITOR_DST */ 167 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1, 168 .max_rings = 1, 169 .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, 170 .lmac_ring = true, 171 .ring_dir = HAL_SRNG_DIR_DST, 172 .max_size = HAL_RXDMA_RING_MAX_SIZE, 173 }, 174 { /* RXDMA_MONITOR_DESC */ 175 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_DESC, 176 .max_rings = 1, 177 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, 178 .lmac_ring = true, 179 .ring_dir = HAL_SRNG_DIR_SRC, 180 .max_size = HAL_RXDMA_RING_MAX_SIZE, 181 }, 182 { /* RXDMA DIR BUF */ 183 .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, 184 .max_rings = 1, 185 .entry_size = 8 >> 2, /* TODO: Define the struct */ 186 .lmac_ring = true, 187 .ring_dir = HAL_SRNG_DIR_SRC, 188 .max_size = HAL_RXDMA_RING_MAX_SIZE, 189 }, 190 }; 191 192 static int ath11k_hal_alloc_cont_rdp(struct ath11k_base *ab) 193 { 194 struct ath11k_hal *hal = &ab->hal; 195 size_t size; 196 197 size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; 198 hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr, 199 GFP_KERNEL); 200 if (!hal->rdp.vaddr) 201 return -ENOMEM; 202 203 return 0; 204 } 205 206 static void ath11k_hal_free_cont_rdp(struct ath11k_base *ab) 207 { 208 struct ath11k_hal *hal = &ab->hal; 209 size_t size; 210 211 if (!hal->rdp.vaddr) 212 return; 213 214 size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; 215 dma_free_coherent(ab->dev, size, 216 hal->rdp.vaddr, hal->rdp.paddr); 217 hal->rdp.vaddr = NULL; 218 } 219 220 static int ath11k_hal_alloc_cont_wrp(struct ath11k_base *ab) 221 { 222 struct ath11k_hal *hal = &ab->hal; 223 size_t size; 224 225 size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS; 226 hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr, 227 GFP_KERNEL); 228 if (!hal->wrp.vaddr) 229 return -ENOMEM; 230 231 return 0; 232 } 233 234 static void ath11k_hal_free_cont_wrp(struct ath11k_base *ab) 235 { 236 struct ath11k_hal *hal = &ab->hal; 237 size_t size; 238 239 if (!hal->wrp.vaddr) 240 return; 241 242 size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS; 243 dma_free_coherent(ab->dev, size, 244 hal->wrp.vaddr, hal->wrp.paddr); 245 hal->wrp.vaddr = NULL; 246 } 247 248 static void ath11k_hal_ce_dst_setup(struct ath11k_base *ab, 249 struct hal_srng *srng, int ring_num) 250 { 251 struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; 252 u32 addr; 253 u32 val; 254 255 addr = HAL_CE_DST_RING_CTRL + 256 srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + 257 ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; 258 259 val = ath11k_hif_read32(ab, addr); 260 val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; 261 val |= FIELD_PREP(HAL_CE_DST_R0_DEST_CTRL_MAX_LEN, 262 srng->u.dst_ring.max_buffer_length); 263 ath11k_hif_write32(ab, addr, val); 264 } 265 266 static void ath11k_hal_srng_dst_hw_init(struct ath11k_base *ab, 267 struct hal_srng *srng) 268 { 269 struct ath11k_hal *hal = &ab->hal; 270 u32 val; 271 u64 hp_addr; 272 u32 reg_base; 273 274 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 275 276 if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { 277 ath11k_hif_write32(ab, reg_base + 278 HAL_REO1_RING_MSI1_BASE_LSB_OFFSET(ab), 279 srng->msi_addr); 280 281 val = FIELD_PREP(HAL_REO1_RING_MSI1_BASE_MSB_ADDR, 282 ((u64)srng->msi_addr >> 283 HAL_ADDR_MSB_REG_SHIFT)) | 284 HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; 285 ath11k_hif_write32(ab, reg_base + 286 HAL_REO1_RING_MSI1_BASE_MSB_OFFSET(ab), val); 287 288 ath11k_hif_write32(ab, 289 reg_base + HAL_REO1_RING_MSI1_DATA_OFFSET(ab), 290 srng->msi_data); 291 } 292 293 ath11k_hif_write32(ab, reg_base, srng->ring_base_paddr); 294 295 val = FIELD_PREP(HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB, 296 ((u64)srng->ring_base_paddr >> 297 HAL_ADDR_MSB_REG_SHIFT)) | 298 FIELD_PREP(HAL_REO1_RING_BASE_MSB_RING_SIZE, 299 (srng->entry_size * srng->num_entries)); 300 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_BASE_MSB_OFFSET(ab), val); 301 302 val = FIELD_PREP(HAL_REO1_RING_ID_RING_ID, srng->ring_id) | 303 FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size); 304 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_ID_OFFSET(ab), val); 305 306 /* interrupt setup */ 307 val = FIELD_PREP(HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD, 308 (srng->intr_timer_thres_us >> 3)); 309 310 val |= FIELD_PREP(HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD, 311 (srng->intr_batch_cntr_thres_entries * 312 srng->entry_size)); 313 314 ath11k_hif_write32(ab, 315 reg_base + HAL_REO1_RING_PRODUCER_INT_SETUP_OFFSET(ab), 316 val); 317 318 hp_addr = hal->rdp.paddr + 319 ((unsigned long)srng->u.dst_ring.hp_addr - 320 (unsigned long)hal->rdp.vaddr); 321 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_LSB_OFFSET(ab), 322 hp_addr & HAL_ADDR_LSB_REG_MASK); 323 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_MSB_OFFSET(ab), 324 hp_addr >> HAL_ADDR_MSB_REG_SHIFT); 325 326 /* Initialize head and tail pointers to indicate ring is empty */ 327 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; 328 ath11k_hif_write32(ab, reg_base, 0); 329 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET(ab), 0); 330 *srng->u.dst_ring.hp_addr = 0; 331 332 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 333 val = 0; 334 if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) 335 val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; 336 if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) 337 val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; 338 if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) 339 val |= HAL_REO1_RING_MISC_MSI_SWAP; 340 val |= HAL_REO1_RING_MISC_SRNG_ENABLE; 341 342 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_MISC_OFFSET(ab), val); 343 } 344 345 static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, 346 struct hal_srng *srng) 347 { 348 struct ath11k_hal *hal = &ab->hal; 349 u32 val; 350 u64 tp_addr; 351 u32 reg_base; 352 353 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 354 355 if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { 356 ath11k_hif_write32(ab, reg_base + 357 HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab), 358 srng->msi_addr); 359 360 val = FIELD_PREP(HAL_TCL1_RING_MSI1_BASE_MSB_ADDR, 361 ((u64)srng->msi_addr >> 362 HAL_ADDR_MSB_REG_SHIFT)) | 363 HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; 364 ath11k_hif_write32(ab, reg_base + 365 HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab), 366 val); 367 368 ath11k_hif_write32(ab, reg_base + 369 HAL_TCL1_RING_MSI1_DATA_OFFSET(ab), 370 srng->msi_data); 371 } 372 373 ath11k_hif_write32(ab, reg_base, srng->ring_base_paddr); 374 375 val = FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB, 376 ((u64)srng->ring_base_paddr >> 377 HAL_ADDR_MSB_REG_SHIFT)) | 378 FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_SIZE, 379 (srng->entry_size * srng->num_entries)); 380 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(ab), val); 381 382 val = FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size); 383 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val); 384 385 /* interrupt setup */ 386 /* NOTE: IPQ8074 v2 requires the interrupt timer threshold in the 387 * unit of 8 usecs instead of 1 usec (as required by v1). 388 */ 389 val = FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD, 390 srng->intr_timer_thres_us); 391 392 val |= FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD, 393 (srng->intr_batch_cntr_thres_entries * 394 srng->entry_size)); 395 396 ath11k_hif_write32(ab, 397 reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab), 398 val); 399 400 val = 0; 401 if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { 402 val |= FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD, 403 srng->u.src_ring.low_threshold); 404 } 405 ath11k_hif_write32(ab, 406 reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab), 407 val); 408 409 if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { 410 tp_addr = hal->rdp.paddr + 411 ((unsigned long)srng->u.src_ring.tp_addr - 412 (unsigned long)hal->rdp.vaddr); 413 ath11k_hif_write32(ab, 414 reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab), 415 tp_addr & HAL_ADDR_LSB_REG_MASK); 416 ath11k_hif_write32(ab, 417 reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab), 418 tp_addr >> HAL_ADDR_MSB_REG_SHIFT); 419 } 420 421 /* Initialize head and tail pointers to indicate ring is empty */ 422 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; 423 ath11k_hif_write32(ab, reg_base, 0); 424 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); 425 *srng->u.src_ring.tp_addr = 0; 426 427 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 428 val = 0; 429 if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) 430 val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; 431 if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) 432 val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; 433 if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) 434 val |= HAL_TCL1_RING_MISC_MSI_SWAP; 435 436 /* Loop count is not used for SRC rings */ 437 val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; 438 439 val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; 440 441 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val); 442 } 443 444 static void ath11k_hal_srng_hw_init(struct ath11k_base *ab, 445 struct hal_srng *srng) 446 { 447 if (srng->ring_dir == HAL_SRNG_DIR_SRC) 448 ath11k_hal_srng_src_hw_init(ab, srng); 449 else 450 ath11k_hal_srng_dst_hw_init(ab, srng); 451 } 452 453 static int ath11k_hal_srng_get_ring_id(struct ath11k_base *ab, 454 enum hal_ring_type type, 455 int ring_num, int mac_id) 456 { 457 struct hal_srng_config *srng_config = &ab->hal.srng_config[type]; 458 int ring_id; 459 460 if (ring_num >= srng_config->max_rings) { 461 ath11k_warn(ab, "invalid ring number :%d\n", ring_num); 462 return -EINVAL; 463 } 464 465 ring_id = srng_config->start_ring_id + ring_num; 466 if (srng_config->lmac_ring) 467 ring_id += mac_id * HAL_SRNG_RINGS_PER_LMAC; 468 469 if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX)) 470 return -EINVAL; 471 472 return ring_id; 473 } 474 475 int ath11k_hal_srng_get_entrysize(struct ath11k_base *ab, u32 ring_type) 476 { 477 struct hal_srng_config *srng_config; 478 479 if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES)) 480 return -EINVAL; 481 482 srng_config = &ab->hal.srng_config[ring_type]; 483 484 return (srng_config->entry_size << 2); 485 } 486 487 int ath11k_hal_srng_get_max_entries(struct ath11k_base *ab, u32 ring_type) 488 { 489 struct hal_srng_config *srng_config; 490 491 if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES)) 492 return -EINVAL; 493 494 srng_config = &ab->hal.srng_config[ring_type]; 495 496 return (srng_config->max_size / srng_config->entry_size); 497 } 498 499 void ath11k_hal_srng_get_params(struct ath11k_base *ab, struct hal_srng *srng, 500 struct hal_srng_params *params) 501 { 502 params->ring_base_paddr = srng->ring_base_paddr; 503 params->ring_base_vaddr = srng->ring_base_vaddr; 504 params->num_entries = srng->num_entries; 505 params->intr_timer_thres_us = srng->intr_timer_thres_us; 506 params->intr_batch_cntr_thres_entries = 507 srng->intr_batch_cntr_thres_entries; 508 params->low_threshold = srng->u.src_ring.low_threshold; 509 params->msi_addr = srng->msi_addr; 510 params->msi_data = srng->msi_data; 511 params->flags = srng->flags; 512 } 513 514 dma_addr_t ath11k_hal_srng_get_hp_addr(struct ath11k_base *ab, 515 struct hal_srng *srng) 516 { 517 if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING)) 518 return 0; 519 520 if (srng->ring_dir == HAL_SRNG_DIR_SRC) 521 return ab->hal.wrp.paddr + 522 ((unsigned long)srng->u.src_ring.hp_addr - 523 (unsigned long)ab->hal.wrp.vaddr); 524 else 525 return ab->hal.rdp.paddr + 526 ((unsigned long)srng->u.dst_ring.hp_addr - 527 (unsigned long)ab->hal.rdp.vaddr); 528 } 529 530 dma_addr_t ath11k_hal_srng_get_tp_addr(struct ath11k_base *ab, 531 struct hal_srng *srng) 532 { 533 if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING)) 534 return 0; 535 536 if (srng->ring_dir == HAL_SRNG_DIR_SRC) 537 return ab->hal.rdp.paddr + 538 ((unsigned long)srng->u.src_ring.tp_addr - 539 (unsigned long)ab->hal.rdp.vaddr); 540 else 541 return ab->hal.wrp.paddr + 542 ((unsigned long)srng->u.dst_ring.tp_addr - 543 (unsigned long)ab->hal.wrp.vaddr); 544 } 545 546 u32 ath11k_hal_ce_get_desc_size(enum hal_ce_desc type) 547 { 548 switch (type) { 549 case HAL_CE_DESC_SRC: 550 return sizeof(struct hal_ce_srng_src_desc); 551 case HAL_CE_DESC_DST: 552 return sizeof(struct hal_ce_srng_dest_desc); 553 case HAL_CE_DESC_DST_STATUS: 554 return sizeof(struct hal_ce_srng_dst_status_desc); 555 } 556 557 return 0; 558 } 559 560 void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id, 561 u8 byte_swap_data) 562 { 563 struct hal_ce_srng_src_desc *desc = (struct hal_ce_srng_src_desc *)buf; 564 565 desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK; 566 desc->buffer_addr_info = 567 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI, 568 ((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT)) | 569 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP, 570 byte_swap_data) | 571 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_GATHER, 0) | 572 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_LEN, len); 573 desc->meta_info = FIELD_PREP(HAL_CE_SRC_DESC_META_INFO_DATA, id); 574 } 575 576 void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr) 577 { 578 struct hal_ce_srng_dest_desc *desc = 579 (struct hal_ce_srng_dest_desc *)buf; 580 581 desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK; 582 desc->buffer_addr_info = 583 FIELD_PREP(HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI, 584 ((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT)); 585 } 586 587 u32 ath11k_hal_ce_dst_status_get_length(void *buf) 588 { 589 struct hal_ce_srng_dst_status_desc *desc = 590 (struct hal_ce_srng_dst_status_desc *)buf; 591 u32 len; 592 593 len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags); 594 desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN; 595 596 return len; 597 } 598 599 void ath11k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, 600 dma_addr_t paddr) 601 { 602 desc->buf_addr_info.info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, 603 (paddr & HAL_ADDR_LSB_REG_MASK)); 604 desc->buf_addr_info.info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, 605 ((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT)) | 606 FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, 1) | 607 FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie); 608 } 609 610 u32 *ath11k_hal_srng_dst_peek(struct ath11k_base *ab, struct hal_srng *srng) 611 { 612 lockdep_assert_held(&srng->lock); 613 614 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) 615 return (srng->ring_base_vaddr + srng->u.dst_ring.tp); 616 617 return NULL; 618 } 619 620 u32 *ath11k_hal_srng_dst_get_next_entry(struct ath11k_base *ab, 621 struct hal_srng *srng) 622 { 623 u32 *desc; 624 625 lockdep_assert_held(&srng->lock); 626 627 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 628 return NULL; 629 630 desc = srng->ring_base_vaddr + srng->u.dst_ring.tp; 631 632 srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) % 633 srng->ring_size; 634 635 return desc; 636 } 637 638 int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng, 639 bool sync_hw_ptr) 640 { 641 u32 tp, hp; 642 643 lockdep_assert_held(&srng->lock); 644 645 tp = srng->u.dst_ring.tp; 646 647 if (sync_hw_ptr) { 648 hp = *srng->u.dst_ring.hp_addr; 649 srng->u.dst_ring.cached_hp = hp; 650 } else { 651 hp = srng->u.dst_ring.cached_hp; 652 } 653 654 if (hp >= tp) 655 return (hp - tp) / srng->entry_size; 656 else 657 return (srng->ring_size - tp + hp) / srng->entry_size; 658 } 659 660 /* Returns number of available entries in src ring */ 661 int ath11k_hal_srng_src_num_free(struct ath11k_base *ab, struct hal_srng *srng, 662 bool sync_hw_ptr) 663 { 664 u32 tp, hp; 665 666 lockdep_assert_held(&srng->lock); 667 668 hp = srng->u.src_ring.hp; 669 670 if (sync_hw_ptr) { 671 tp = *srng->u.src_ring.tp_addr; 672 srng->u.src_ring.cached_tp = tp; 673 } else { 674 tp = srng->u.src_ring.cached_tp; 675 } 676 677 if (tp > hp) 678 return ((tp - hp) / srng->entry_size) - 1; 679 else 680 return ((srng->ring_size - hp + tp) / srng->entry_size) - 1; 681 } 682 683 u32 *ath11k_hal_srng_src_get_next_entry(struct ath11k_base *ab, 684 struct hal_srng *srng) 685 { 686 u32 *desc; 687 u32 next_hp; 688 689 lockdep_assert_held(&srng->lock); 690 691 /* TODO: Using % is expensive, but we have to do this since size of some 692 * SRNG rings is not power of 2 (due to descriptor sizes). Need to see 693 * if separate function is defined for rings having power of 2 ring size 694 * (TCL2SW, REO2SW, SW2RXDMA and CE rings) so that we can avoid the 695 * overhead of % by using mask (with &). 696 */ 697 next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size; 698 699 if (next_hp == srng->u.src_ring.cached_tp) 700 return NULL; 701 702 desc = srng->ring_base_vaddr + srng->u.src_ring.hp; 703 srng->u.src_ring.hp = next_hp; 704 705 /* TODO: Reap functionality is not used by all rings. If particular 706 * ring does not use reap functionality, we need not update reap_hp 707 * with next_hp pointer. Need to make sure a separate function is used 708 * before doing any optimization by removing below code updating 709 * reap_hp. 710 */ 711 srng->u.src_ring.reap_hp = next_hp; 712 713 return desc; 714 } 715 716 u32 *ath11k_hal_srng_src_reap_next(struct ath11k_base *ab, 717 struct hal_srng *srng) 718 { 719 u32 *desc; 720 u32 next_reap_hp; 721 722 lockdep_assert_held(&srng->lock); 723 724 next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) % 725 srng->ring_size; 726 727 if (next_reap_hp == srng->u.src_ring.cached_tp) 728 return NULL; 729 730 desc = srng->ring_base_vaddr + next_reap_hp; 731 srng->u.src_ring.reap_hp = next_reap_hp; 732 733 return desc; 734 } 735 736 u32 *ath11k_hal_srng_src_get_next_reaped(struct ath11k_base *ab, 737 struct hal_srng *srng) 738 { 739 u32 *desc; 740 741 lockdep_assert_held(&srng->lock); 742 743 if (srng->u.src_ring.hp == srng->u.src_ring.reap_hp) 744 return NULL; 745 746 desc = srng->ring_base_vaddr + srng->u.src_ring.hp; 747 srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) % 748 srng->ring_size; 749 750 return desc; 751 } 752 753 u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng) 754 { 755 lockdep_assert_held(&srng->lock); 756 757 if (((srng->u.src_ring.hp + srng->entry_size) % srng->ring_size) == 758 srng->u.src_ring.cached_tp) 759 return NULL; 760 761 return srng->ring_base_vaddr + srng->u.src_ring.hp; 762 } 763 764 void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng) 765 { 766 lockdep_assert_held(&srng->lock); 767 768 if (srng->ring_dir == HAL_SRNG_DIR_SRC) 769 srng->u.src_ring.cached_tp = 770 *(volatile u32 *)srng->u.src_ring.tp_addr; 771 else 772 srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr; 773 } 774 775 /* Update cached ring head/tail pointers to HW. ath11k_hal_srng_access_begin() 776 * should have been called before this. 777 */ 778 void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng) 779 { 780 lockdep_assert_held(&srng->lock); 781 782 /* TODO: See if we need a write memory barrier here */ 783 if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) { 784 /* For LMAC rings, ring pointer updates are done through FW and 785 * hence written to a shared memory location that is read by FW 786 */ 787 if (srng->ring_dir == HAL_SRNG_DIR_SRC) { 788 srng->u.src_ring.last_tp = 789 *(volatile u32 *)srng->u.src_ring.tp_addr; 790 *srng->u.src_ring.hp_addr = srng->u.src_ring.hp; 791 } else { 792 srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; 793 *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; 794 } 795 } else { 796 if (srng->ring_dir == HAL_SRNG_DIR_SRC) { 797 srng->u.src_ring.last_tp = 798 *(volatile u32 *)srng->u.src_ring.tp_addr; 799 ath11k_hif_write32(ab, 800 (unsigned long)srng->u.src_ring.hp_addr - 801 (unsigned long)ab->mem, 802 srng->u.src_ring.hp); 803 } else { 804 srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; 805 ath11k_hif_write32(ab, 806 (unsigned long)srng->u.dst_ring.tp_addr - 807 (unsigned long)ab->mem, 808 srng->u.dst_ring.tp); 809 } 810 } 811 812 srng->timestamp = jiffies; 813 } 814 815 void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, 816 struct hal_wbm_idle_scatter_list *sbuf, 817 u32 nsbufs, u32 tot_link_desc, 818 u32 end_offset) 819 { 820 struct ath11k_buffer_addr *link_addr; 821 int i; 822 u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; 823 824 link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; 825 826 for (i = 1; i < nsbufs; i++) { 827 link_addr->info0 = sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK; 828 link_addr->info1 = FIELD_PREP( 829 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, 830 (u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT) | 831 FIELD_PREP( 832 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG, 833 BASE_ADDR_MATCH_TAG_VAL); 834 835 link_addr = (void *)sbuf[i].vaddr + 836 HAL_WBM_IDLE_SCATTER_BUF_SIZE; 837 } 838 839 ath11k_hif_write32(ab, 840 HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR, 841 FIELD_PREP(HAL_WBM_SCATTER_BUFFER_SIZE, reg_scatter_buf_sz) | 842 FIELD_PREP(HAL_WBM_LINK_DESC_IDLE_LIST_MODE, 0x1)); 843 ath11k_hif_write32(ab, 844 HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR, 845 FIELD_PREP(HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST, 846 reg_scatter_buf_sz * nsbufs)); 847 ath11k_hif_write32(ab, 848 HAL_SEQ_WCSS_UMAC_WBM_REG + 849 HAL_WBM_SCATTERED_RING_BASE_LSB, 850 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, 851 sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK)); 852 ath11k_hif_write32(ab, 853 HAL_SEQ_WCSS_UMAC_WBM_REG + 854 HAL_WBM_SCATTERED_RING_BASE_MSB, 855 FIELD_PREP( 856 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, 857 (u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT) | 858 FIELD_PREP( 859 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG, 860 BASE_ADDR_MATCH_TAG_VAL)); 861 862 /* Setup head and tail pointers for the idle list */ 863 ath11k_hif_write32(ab, 864 HAL_SEQ_WCSS_UMAC_WBM_REG + 865 HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0, 866 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, 867 sbuf[nsbufs - 1].paddr)); 868 ath11k_hif_write32(ab, 869 HAL_SEQ_WCSS_UMAC_WBM_REG + 870 HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1, 871 FIELD_PREP( 872 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, 873 ((u64)sbuf[nsbufs - 1].paddr >> 874 HAL_ADDR_MSB_REG_SHIFT)) | 875 FIELD_PREP(HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1, 876 (end_offset >> 2))); 877 ath11k_hif_write32(ab, 878 HAL_SEQ_WCSS_UMAC_WBM_REG + 879 HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0, 880 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, 881 sbuf[0].paddr)); 882 883 ath11k_hif_write32(ab, 884 HAL_SEQ_WCSS_UMAC_WBM_REG + 885 HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0, 886 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, 887 sbuf[0].paddr)); 888 ath11k_hif_write32(ab, 889 HAL_SEQ_WCSS_UMAC_WBM_REG + 890 HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1, 891 FIELD_PREP( 892 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32, 893 ((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT)) | 894 FIELD_PREP(HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1, 895 0)); 896 ath11k_hif_write32(ab, 897 HAL_SEQ_WCSS_UMAC_WBM_REG + 898 HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR, 899 2 * tot_link_desc); 900 901 /* Enable the SRNG */ 902 ath11k_hif_write32(ab, 903 HAL_SEQ_WCSS_UMAC_WBM_REG + 904 HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab), 0x40); 905 } 906 907 int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type, 908 int ring_num, int mac_id, 909 struct hal_srng_params *params) 910 { 911 struct ath11k_hal *hal = &ab->hal; 912 struct hal_srng_config *srng_config = &ab->hal.srng_config[type]; 913 struct hal_srng *srng; 914 int ring_id; 915 u32 lmac_idx; 916 int i; 917 u32 reg_base; 918 919 ring_id = ath11k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); 920 if (ring_id < 0) 921 return ring_id; 922 923 srng = &hal->srng_list[ring_id]; 924 925 srng->ring_id = ring_id; 926 srng->ring_dir = srng_config->ring_dir; 927 srng->ring_base_paddr = params->ring_base_paddr; 928 srng->ring_base_vaddr = params->ring_base_vaddr; 929 srng->entry_size = srng_config->entry_size; 930 srng->num_entries = params->num_entries; 931 srng->ring_size = srng->entry_size * srng->num_entries; 932 srng->intr_batch_cntr_thres_entries = 933 params->intr_batch_cntr_thres_entries; 934 srng->intr_timer_thres_us = params->intr_timer_thres_us; 935 srng->flags = params->flags; 936 srng->msi_addr = params->msi_addr; 937 srng->msi_data = params->msi_data; 938 srng->initialized = 1; 939 spin_lock_init(&srng->lock); 940 941 for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) { 942 srng->hwreg_base[i] = srng_config->reg_start[i] + 943 (ring_num * srng_config->reg_size[i]); 944 } 945 946 memset(srng->ring_base_vaddr, 0, 947 (srng->entry_size * srng->num_entries) << 2); 948 949 /* TODO: Add comments on these swap configurations */ 950 if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) 951 srng->flags |= HAL_SRNG_FLAGS_MSI_SWAP | HAL_SRNG_FLAGS_DATA_TLV_SWAP | 952 HAL_SRNG_FLAGS_RING_PTR_SWAP; 953 954 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; 955 956 if (srng->ring_dir == HAL_SRNG_DIR_SRC) { 957 srng->u.src_ring.hp = 0; 958 srng->u.src_ring.cached_tp = 0; 959 srng->u.src_ring.reap_hp = srng->ring_size - srng->entry_size; 960 srng->u.src_ring.tp_addr = (void *)(hal->rdp.vaddr + ring_id); 961 srng->u.src_ring.low_threshold = params->low_threshold * 962 srng->entry_size; 963 if (srng_config->lmac_ring) { 964 lmac_idx = ring_id - HAL_SRNG_RING_ID_LMAC1_ID_START; 965 srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + 966 lmac_idx); 967 srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; 968 } else { 969 if (!ab->hw_params.supports_shadow_regs) 970 srng->u.src_ring.hp_addr = 971 (u32 *)((unsigned long)ab->mem + reg_base); 972 else 973 ath11k_dbg(ab, ATH11k_DBG_HAL, 974 "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n", 975 type, ring_num, 976 reg_base, 977 (unsigned long)srng->u.src_ring.hp_addr - 978 (unsigned long)ab->mem); 979 } 980 } else { 981 /* During initialization loop count in all the descriptors 982 * will be set to zero, and HW will set it to 1 on completing 983 * descriptor update in first loop, and increments it by 1 on 984 * subsequent loops (loop count wraps around after reaching 985 * 0xffff). The 'loop_cnt' in SW ring state is the expected 986 * loop count in descriptors updated by HW (to be processed 987 * by SW). 988 */ 989 srng->u.dst_ring.loop_cnt = 1; 990 srng->u.dst_ring.tp = 0; 991 srng->u.dst_ring.cached_hp = 0; 992 srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id); 993 if (srng_config->lmac_ring) { 994 /* For LMAC rings, tail pointer updates will be done 995 * through FW by writing to a shared memory location 996 */ 997 lmac_idx = ring_id - HAL_SRNG_RING_ID_LMAC1_ID_START; 998 srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr + 999 lmac_idx); 1000 srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; 1001 } else { 1002 if (!ab->hw_params.supports_shadow_regs) 1003 srng->u.dst_ring.tp_addr = 1004 (u32 *)((unsigned long)ab->mem + reg_base + 1005 (HAL_REO1_RING_TP(ab) - HAL_REO1_RING_HP(ab))); 1006 else 1007 ath11k_dbg(ab, ATH11k_DBG_HAL, 1008 "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n", 1009 type, ring_num, 1010 reg_base + (HAL_REO1_RING_TP(ab) - 1011 HAL_REO1_RING_HP(ab)), 1012 (unsigned long)srng->u.dst_ring.tp_addr - 1013 (unsigned long)ab->mem); 1014 } 1015 } 1016 1017 if (srng_config->lmac_ring) 1018 return ring_id; 1019 1020 ath11k_hal_srng_hw_init(ab, srng); 1021 1022 if (type == HAL_CE_DST) { 1023 srng->u.dst_ring.max_buffer_length = params->max_buffer_len; 1024 ath11k_hal_ce_dst_setup(ab, srng, ring_num); 1025 } 1026 1027 return ring_id; 1028 } 1029 1030 static void ath11k_hal_srng_update_hp_tp_addr(struct ath11k_base *ab, 1031 int shadow_cfg_idx, 1032 enum hal_ring_type ring_type, 1033 int ring_num) 1034 { 1035 struct hal_srng *srng; 1036 struct ath11k_hal *hal = &ab->hal; 1037 int ring_id; 1038 struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; 1039 1040 ring_id = ath11k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0); 1041 if (ring_id < 0) 1042 return; 1043 1044 srng = &hal->srng_list[ring_id]; 1045 1046 if (srng_config->ring_dir == HAL_SRNG_DIR_DST) 1047 srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + 1048 (unsigned long)ab->mem); 1049 else 1050 srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + 1051 (unsigned long)ab->mem); 1052 } 1053 1054 int ath11k_hal_srng_update_shadow_config(struct ath11k_base *ab, 1055 enum hal_ring_type ring_type, 1056 int ring_num) 1057 { 1058 struct ath11k_hal *hal = &ab->hal; 1059 struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; 1060 int shadow_cfg_idx = hal->num_shadow_reg_configured; 1061 u32 target_reg; 1062 1063 if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) 1064 return -EINVAL; 1065 1066 hal->num_shadow_reg_configured++; 1067 1068 target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START]; 1069 target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] * 1070 ring_num; 1071 1072 /* For destination ring, shadow the TP */ 1073 if (srng_config->ring_dir == HAL_SRNG_DIR_DST) 1074 target_reg += HAL_OFFSET_FROM_HP_TO_TP; 1075 1076 hal->shadow_reg_addr[shadow_cfg_idx] = target_reg; 1077 1078 /* update hp/tp addr to hal structure*/ 1079 ath11k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type, 1080 ring_num); 1081 1082 ath11k_dbg(ab, ATH11k_DBG_HAL, 1083 "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", 1084 target_reg, 1085 HAL_SHADOW_REG(shadow_cfg_idx), 1086 shadow_cfg_idx, 1087 ring_type, ring_num); 1088 1089 return 0; 1090 } 1091 1092 void ath11k_hal_srng_shadow_config(struct ath11k_base *ab) 1093 { 1094 struct ath11k_hal *hal = &ab->hal; 1095 int ring_type, ring_num; 1096 1097 /* update all the non-CE srngs. */ 1098 for (ring_type = 0; ring_type < HAL_MAX_RING_TYPES; ring_type++) { 1099 struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; 1100 1101 if (ring_type == HAL_CE_SRC || 1102 ring_type == HAL_CE_DST || 1103 ring_type == HAL_CE_DST_STATUS) 1104 continue; 1105 1106 if (srng_config->lmac_ring) 1107 continue; 1108 1109 for (ring_num = 0; ring_num < srng_config->max_rings; ring_num++) 1110 ath11k_hal_srng_update_shadow_config(ab, ring_type, ring_num); 1111 } 1112 } 1113 1114 void ath11k_hal_srng_get_shadow_config(struct ath11k_base *ab, 1115 u32 **cfg, u32 *len) 1116 { 1117 struct ath11k_hal *hal = &ab->hal; 1118 1119 *len = hal->num_shadow_reg_configured; 1120 *cfg = hal->shadow_reg_addr; 1121 } 1122 1123 void ath11k_hal_srng_shadow_update_hp_tp(struct ath11k_base *ab, 1124 struct hal_srng *srng) 1125 { 1126 lockdep_assert_held(&srng->lock); 1127 1128 /* check whether the ring is emptry. Update the shadow 1129 * HP only when then ring isn't' empty. 1130 */ 1131 if (srng->ring_dir == HAL_SRNG_DIR_SRC && 1132 *srng->u.src_ring.tp_addr != srng->u.src_ring.hp) 1133 ath11k_hal_srng_access_end(ab, srng); 1134 } 1135 1136 static int ath11k_hal_srng_create_config(struct ath11k_base *ab) 1137 { 1138 struct ath11k_hal *hal = &ab->hal; 1139 struct hal_srng_config *s; 1140 1141 hal->srng_config = kmemdup(hw_srng_config_template, 1142 sizeof(hw_srng_config_template), 1143 GFP_KERNEL); 1144 if (!hal->srng_config) 1145 return -ENOMEM; 1146 1147 s = &hal->srng_config[HAL_REO_DST]; 1148 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); 1149 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP(ab); 1150 s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 1151 s->reg_size[1] = HAL_REO2_RING_HP(ab) - HAL_REO1_RING_HP(ab); 1152 1153 s = &hal->srng_config[HAL_REO_EXCEPTION]; 1154 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_BASE_LSB(ab); 1155 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_HP(ab); 1156 1157 s = &hal->srng_config[HAL_REO_REINJECT]; 1158 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB; 1159 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; 1160 1161 s = &hal->srng_config[HAL_REO_CMD]; 1162 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB; 1163 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; 1164 1165 s = &hal->srng_config[HAL_REO_STATUS]; 1166 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); 1167 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP(ab); 1168 1169 s = &hal->srng_config[HAL_TCL_DATA]; 1170 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); 1171 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; 1172 s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); 1173 s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; 1174 1175 s = &hal->srng_config[HAL_TCL_CMD]; 1176 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); 1177 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; 1178 1179 s = &hal->srng_config[HAL_TCL_STATUS]; 1180 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); 1181 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; 1182 1183 s = &hal->srng_config[HAL_CE_SRC]; 1184 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; 1185 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; 1186 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - 1187 HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); 1188 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - 1189 HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); 1190 1191 s = &hal->srng_config[HAL_CE_DST]; 1192 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; 1193 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; 1194 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - 1195 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); 1196 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - 1197 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); 1198 1199 s = &hal->srng_config[HAL_CE_DST_STATUS]; 1200 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + 1201 HAL_CE_DST_STATUS_RING_BASE_LSB; 1202 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; 1203 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - 1204 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); 1205 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - 1206 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); 1207 1208 s = &hal->srng_config[HAL_WBM_IDLE_LINK]; 1209 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); 1210 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; 1211 1212 s = &hal->srng_config[HAL_SW2WBM_RELEASE]; 1213 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_BASE_LSB(ab); 1214 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_HP; 1215 1216 s = &hal->srng_config[HAL_WBM2SW_RELEASE]; 1217 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); 1218 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; 1219 s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - 1220 HAL_WBM0_RELEASE_RING_BASE_LSB(ab); 1221 s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; 1222 1223 return 0; 1224 } 1225 1226 int ath11k_hal_srng_init(struct ath11k_base *ab) 1227 { 1228 struct ath11k_hal *hal = &ab->hal; 1229 int ret; 1230 1231 memset(hal, 0, sizeof(*hal)); 1232 1233 ret = ath11k_hal_srng_create_config(ab); 1234 if (ret) 1235 goto err_hal; 1236 1237 ret = ath11k_hal_alloc_cont_rdp(ab); 1238 if (ret) 1239 goto err_hal; 1240 1241 ret = ath11k_hal_alloc_cont_wrp(ab); 1242 if (ret) 1243 goto err_free_cont_rdp; 1244 1245 return 0; 1246 1247 err_free_cont_rdp: 1248 ath11k_hal_free_cont_rdp(ab); 1249 1250 err_hal: 1251 return ret; 1252 } 1253 EXPORT_SYMBOL(ath11k_hal_srng_init); 1254 1255 void ath11k_hal_srng_deinit(struct ath11k_base *ab) 1256 { 1257 struct ath11k_hal *hal = &ab->hal; 1258 1259 ath11k_hal_free_cont_rdp(ab); 1260 ath11k_hal_free_cont_wrp(ab); 1261 kfree(hal->srng_config); 1262 } 1263 EXPORT_SYMBOL(ath11k_hal_srng_deinit); 1264 1265 void ath11k_hal_dump_srng_stats(struct ath11k_base *ab) 1266 { 1267 struct hal_srng *srng; 1268 struct ath11k_ext_irq_grp *irq_grp; 1269 struct ath11k_ce_pipe *ce_pipe; 1270 int i; 1271 1272 ath11k_err(ab, "Last interrupt received for each CE:\n"); 1273 for (i = 0; i < ab->hw_params.ce_count; i++) { 1274 ce_pipe = &ab->ce.ce_pipe[i]; 1275 1276 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 1277 continue; 1278 1279 ath11k_err(ab, "CE_id %d pipe_num %d %ums before\n", 1280 i, ce_pipe->pipe_num, 1281 jiffies_to_msecs(jiffies - ce_pipe->timestamp)); 1282 } 1283 1284 ath11k_err(ab, "\nLast interrupt received for each group:\n"); 1285 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { 1286 irq_grp = &ab->ext_irq_grp[i]; 1287 ath11k_err(ab, "group_id %d %ums before\n", 1288 irq_grp->grp_id, 1289 jiffies_to_msecs(jiffies - irq_grp->timestamp)); 1290 } 1291 1292 for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) { 1293 srng = &ab->hal.srng_list[i]; 1294 1295 if (!srng->initialized) 1296 continue; 1297 1298 if (srng->ring_dir == HAL_SRNG_DIR_SRC) 1299 ath11k_err(ab, 1300 "src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n", 1301 srng->ring_id, srng->u.src_ring.hp, 1302 srng->u.src_ring.reap_hp, 1303 *srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp, 1304 srng->u.src_ring.last_tp, 1305 jiffies_to_msecs(jiffies - srng->timestamp)); 1306 else if (srng->ring_dir == HAL_SRNG_DIR_DST) 1307 ath11k_err(ab, 1308 "dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n", 1309 srng->ring_id, srng->u.dst_ring.tp, 1310 *srng->u.dst_ring.hp_addr, 1311 srng->u.dst_ring.cached_hp, 1312 srng->u.dst_ring.last_hp, 1313 jiffies_to_msecs(jiffies - srng->timestamp)); 1314 } 1315 } 1316