0001
0002
0003
0004
0005
0006 #include <linux/dma-mapping.h>
0007 #include "hal_tx.h"
0008 #include "debug.h"
0009 #include "hal_desc.h"
0010 #include "hif.h"
0011
0012 static const struct hal_srng_config hw_srng_config_template[] = {
0013
0014 {
0015 .start_ring_id = HAL_SRNG_RING_ID_REO2SW1,
0016 .max_rings = 4,
0017 .entry_size = sizeof(struct hal_reo_dest_ring) >> 2,
0018 .lmac_ring = false,
0019 .ring_dir = HAL_SRNG_DIR_DST,
0020 .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE,
0021 },
0022 {
0023
0024
0025
0026
0027 .start_ring_id = HAL_SRNG_RING_ID_REO2TCL,
0028 .max_rings = 1,
0029 .entry_size = sizeof(struct hal_reo_dest_ring) >> 2,
0030 .lmac_ring = false,
0031 .ring_dir = HAL_SRNG_DIR_DST,
0032 .max_size = HAL_REO_REO2TCL_RING_BASE_MSB_RING_SIZE,
0033 },
0034 {
0035 .start_ring_id = HAL_SRNG_RING_ID_SW2REO,
0036 .max_rings = 1,
0037 .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2,
0038 .lmac_ring = false,
0039 .ring_dir = HAL_SRNG_DIR_SRC,
0040 .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE,
0041 },
0042 {
0043 .start_ring_id = HAL_SRNG_RING_ID_REO_CMD,
0044 .max_rings = 1,
0045 .entry_size = (sizeof(struct hal_tlv_hdr) +
0046 sizeof(struct hal_reo_get_queue_stats)) >> 2,
0047 .lmac_ring = false,
0048 .ring_dir = HAL_SRNG_DIR_SRC,
0049 .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE,
0050 },
0051 {
0052 .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS,
0053 .max_rings = 1,
0054 .entry_size = (sizeof(struct hal_tlv_hdr) +
0055 sizeof(struct hal_reo_get_queue_stats_status)) >> 2,
0056 .lmac_ring = false,
0057 .ring_dir = HAL_SRNG_DIR_DST,
0058 .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE,
0059 },
0060 {
0061 .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1,
0062 .max_rings = 3,
0063 .entry_size = (sizeof(struct hal_tlv_hdr) +
0064 sizeof(struct hal_tcl_data_cmd)) >> 2,
0065 .lmac_ring = false,
0066 .ring_dir = HAL_SRNG_DIR_SRC,
0067 .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE,
0068 },
0069 {
0070 .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD,
0071 .max_rings = 1,
0072 .entry_size = (sizeof(struct hal_tlv_hdr) +
0073 sizeof(struct hal_tcl_gse_cmd)) >> 2,
0074 .lmac_ring = false,
0075 .ring_dir = HAL_SRNG_DIR_SRC,
0076 .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE,
0077 },
0078 {
0079 .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS,
0080 .max_rings = 1,
0081 .entry_size = (sizeof(struct hal_tlv_hdr) +
0082 sizeof(struct hal_tcl_status_ring)) >> 2,
0083 .lmac_ring = false,
0084 .ring_dir = HAL_SRNG_DIR_DST,
0085 .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE,
0086 },
0087 {
0088 .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC,
0089 .max_rings = 12,
0090 .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2,
0091 .lmac_ring = false,
0092 .ring_dir = HAL_SRNG_DIR_SRC,
0093 .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE,
0094 },
0095 {
0096 .start_ring_id = HAL_SRNG_RING_ID_CE0_DST,
0097 .max_rings = 12,
0098 .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2,
0099 .lmac_ring = false,
0100 .ring_dir = HAL_SRNG_DIR_SRC,
0101 .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE,
0102 },
0103 {
0104 .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS,
0105 .max_rings = 12,
0106 .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2,
0107 .lmac_ring = false,
0108 .ring_dir = HAL_SRNG_DIR_DST,
0109 .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE,
0110 },
0111 {
0112 .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK,
0113 .max_rings = 1,
0114 .entry_size = sizeof(struct hal_wbm_link_desc) >> 2,
0115 .lmac_ring = false,
0116 .ring_dir = HAL_SRNG_DIR_SRC,
0117 .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE,
0118 },
0119 {
0120 .start_ring_id = HAL_SRNG_RING_ID_WBM_SW_RELEASE,
0121 .max_rings = 1,
0122 .entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
0123 .lmac_ring = false,
0124 .ring_dir = HAL_SRNG_DIR_SRC,
0125 .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE,
0126 },
0127 {
0128 .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE,
0129 .max_rings = 4,
0130 .entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
0131 .lmac_ring = false,
0132 .ring_dir = HAL_SRNG_DIR_DST,
0133 .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE,
0134 },
0135 {
0136 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF,
0137 .max_rings = 2,
0138 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,
0139 .lmac_ring = true,
0140 .ring_dir = HAL_SRNG_DIR_SRC,
0141 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0142 },
0143 {
0144 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0,
0145 .max_rings = 1,
0146 .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2,
0147 .lmac_ring = true,
0148 .ring_dir = HAL_SRNG_DIR_DST,
0149 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0150 },
0151 {
0152 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA2_BUF,
0153 .max_rings = 1,
0154 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,
0155 .lmac_ring = true,
0156 .ring_dir = HAL_SRNG_DIR_SRC,
0157 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0158 },
0159 {
0160 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF,
0161 .max_rings = 1,
0162 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,
0163 .lmac_ring = true,
0164 .ring_dir = HAL_SRNG_DIR_SRC,
0165 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0166 },
0167 {
0168 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1,
0169 .max_rings = 1,
0170 .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2,
0171 .lmac_ring = true,
0172 .ring_dir = HAL_SRNG_DIR_DST,
0173 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0174 },
0175 {
0176 .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_DESC,
0177 .max_rings = 1,
0178 .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,
0179 .lmac_ring = true,
0180 .ring_dir = HAL_SRNG_DIR_SRC,
0181 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0182 },
0183 {
0184 .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF,
0185 .max_rings = 1,
0186 .entry_size = 8 >> 2,
0187 .lmac_ring = true,
0188 .ring_dir = HAL_SRNG_DIR_SRC,
0189 .max_size = HAL_RXDMA_RING_MAX_SIZE,
0190 },
0191 };
0192
0193 static int ath11k_hal_alloc_cont_rdp(struct ath11k_base *ab)
0194 {
0195 struct ath11k_hal *hal = &ab->hal;
0196 size_t size;
0197
0198 size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;
0199 hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr,
0200 GFP_KERNEL);
0201 if (!hal->rdp.vaddr)
0202 return -ENOMEM;
0203
0204 return 0;
0205 }
0206
0207 static void ath11k_hal_free_cont_rdp(struct ath11k_base *ab)
0208 {
0209 struct ath11k_hal *hal = &ab->hal;
0210 size_t size;
0211
0212 if (!hal->rdp.vaddr)
0213 return;
0214
0215 size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;
0216 dma_free_coherent(ab->dev, size,
0217 hal->rdp.vaddr, hal->rdp.paddr);
0218 hal->rdp.vaddr = NULL;
0219 }
0220
0221 static int ath11k_hal_alloc_cont_wrp(struct ath11k_base *ab)
0222 {
0223 struct ath11k_hal *hal = &ab->hal;
0224 size_t size;
0225
0226 size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS;
0227 hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr,
0228 GFP_KERNEL);
0229 if (!hal->wrp.vaddr)
0230 return -ENOMEM;
0231
0232 return 0;
0233 }
0234
0235 static void ath11k_hal_free_cont_wrp(struct ath11k_base *ab)
0236 {
0237 struct ath11k_hal *hal = &ab->hal;
0238 size_t size;
0239
0240 if (!hal->wrp.vaddr)
0241 return;
0242
0243 size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS;
0244 dma_free_coherent(ab->dev, size,
0245 hal->wrp.vaddr, hal->wrp.paddr);
0246 hal->wrp.vaddr = NULL;
0247 }
0248
0249 static void ath11k_hal_ce_dst_setup(struct ath11k_base *ab,
0250 struct hal_srng *srng, int ring_num)
0251 {
0252 struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST];
0253 u32 addr;
0254 u32 val;
0255
0256 addr = HAL_CE_DST_RING_CTRL +
0257 srng_config->reg_start[HAL_SRNG_REG_GRP_R0] +
0258 ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0];
0259
0260 val = ath11k_hif_read32(ab, addr);
0261 val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN;
0262 val |= FIELD_PREP(HAL_CE_DST_R0_DEST_CTRL_MAX_LEN,
0263 srng->u.dst_ring.max_buffer_length);
0264 ath11k_hif_write32(ab, addr, val);
0265 }
0266
0267 static void ath11k_hal_srng_dst_hw_init(struct ath11k_base *ab,
0268 struct hal_srng *srng)
0269 {
0270 struct ath11k_hal *hal = &ab->hal;
0271 u32 val;
0272 u64 hp_addr;
0273 u32 reg_base;
0274
0275 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
0276
0277 if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) {
0278 ath11k_hif_write32(ab, reg_base +
0279 HAL_REO1_RING_MSI1_BASE_LSB_OFFSET(ab),
0280 srng->msi_addr);
0281
0282 val = FIELD_PREP(HAL_REO1_RING_MSI1_BASE_MSB_ADDR,
0283 ((u64)srng->msi_addr >>
0284 HAL_ADDR_MSB_REG_SHIFT)) |
0285 HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE;
0286 ath11k_hif_write32(ab, reg_base +
0287 HAL_REO1_RING_MSI1_BASE_MSB_OFFSET(ab), val);
0288
0289 ath11k_hif_write32(ab,
0290 reg_base + HAL_REO1_RING_MSI1_DATA_OFFSET(ab),
0291 srng->msi_data);
0292 }
0293
0294 ath11k_hif_write32(ab, reg_base, srng->ring_base_paddr);
0295
0296 val = FIELD_PREP(HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB,
0297 ((u64)srng->ring_base_paddr >>
0298 HAL_ADDR_MSB_REG_SHIFT)) |
0299 FIELD_PREP(HAL_REO1_RING_BASE_MSB_RING_SIZE,
0300 (srng->entry_size * srng->num_entries));
0301 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_BASE_MSB_OFFSET(ab), val);
0302
0303 val = FIELD_PREP(HAL_REO1_RING_ID_RING_ID, srng->ring_id) |
0304 FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size);
0305 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_ID_OFFSET(ab), val);
0306
0307
0308 val = FIELD_PREP(HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD,
0309 (srng->intr_timer_thres_us >> 3));
0310
0311 val |= FIELD_PREP(HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD,
0312 (srng->intr_batch_cntr_thres_entries *
0313 srng->entry_size));
0314
0315 ath11k_hif_write32(ab,
0316 reg_base + HAL_REO1_RING_PRODUCER_INT_SETUP_OFFSET(ab),
0317 val);
0318
0319 hp_addr = hal->rdp.paddr +
0320 ((unsigned long)srng->u.dst_ring.hp_addr -
0321 (unsigned long)hal->rdp.vaddr);
0322 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_LSB_OFFSET(ab),
0323 hp_addr & HAL_ADDR_LSB_REG_MASK);
0324 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_MSB_OFFSET(ab),
0325 hp_addr >> HAL_ADDR_MSB_REG_SHIFT);
0326
0327
0328 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];
0329 ath11k_hif_write32(ab, reg_base, 0);
0330 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET(ab), 0);
0331 *srng->u.dst_ring.hp_addr = 0;
0332
0333 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
0334 val = 0;
0335 if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)
0336 val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP;
0337 if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP)
0338 val |= HAL_REO1_RING_MISC_HOST_FW_SWAP;
0339 if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP)
0340 val |= HAL_REO1_RING_MISC_MSI_SWAP;
0341 val |= HAL_REO1_RING_MISC_SRNG_ENABLE;
0342
0343 ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_MISC_OFFSET(ab), val);
0344 }
0345
0346 static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab,
0347 struct hal_srng *srng)
0348 {
0349 struct ath11k_hal *hal = &ab->hal;
0350 u32 val;
0351 u64 tp_addr;
0352 u32 reg_base;
0353
0354 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
0355
0356 if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) {
0357 ath11k_hif_write32(ab, reg_base +
0358 HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab),
0359 srng->msi_addr);
0360
0361 val = FIELD_PREP(HAL_TCL1_RING_MSI1_BASE_MSB_ADDR,
0362 ((u64)srng->msi_addr >>
0363 HAL_ADDR_MSB_REG_SHIFT)) |
0364 HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE;
0365 ath11k_hif_write32(ab, reg_base +
0366 HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab),
0367 val);
0368
0369 ath11k_hif_write32(ab, reg_base +
0370 HAL_TCL1_RING_MSI1_DATA_OFFSET(ab),
0371 srng->msi_data);
0372 }
0373
0374 ath11k_hif_write32(ab, reg_base, srng->ring_base_paddr);
0375
0376 val = FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB,
0377 ((u64)srng->ring_base_paddr >>
0378 HAL_ADDR_MSB_REG_SHIFT)) |
0379 FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_SIZE,
0380 (srng->entry_size * srng->num_entries));
0381 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(ab), val);
0382
0383 val = FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size);
0384 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val);
0385
0386 if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) {
0387 ath11k_hif_write32(ab, reg_base, (u32)srng->ring_base_paddr);
0388 val = FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB,
0389 ((u64)srng->ring_base_paddr >>
0390 HAL_ADDR_MSB_REG_SHIFT)) |
0391 FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_SIZE,
0392 (srng->entry_size * srng->num_entries));
0393 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(ab), val);
0394 }
0395
0396
0397
0398
0399
0400 val = FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD,
0401 srng->intr_timer_thres_us);
0402
0403 val |= FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD,
0404 (srng->intr_batch_cntr_thres_entries *
0405 srng->entry_size));
0406
0407 ath11k_hif_write32(ab,
0408 reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab),
0409 val);
0410
0411 val = 0;
0412 if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {
0413 val |= FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD,
0414 srng->u.src_ring.low_threshold);
0415 }
0416 ath11k_hif_write32(ab,
0417 reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab),
0418 val);
0419
0420 if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) {
0421 tp_addr = hal->rdp.paddr +
0422 ((unsigned long)srng->u.src_ring.tp_addr -
0423 (unsigned long)hal->rdp.vaddr);
0424 ath11k_hif_write32(ab,
0425 reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab),
0426 tp_addr & HAL_ADDR_LSB_REG_MASK);
0427 ath11k_hif_write32(ab,
0428 reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab),
0429 tp_addr >> HAL_ADDR_MSB_REG_SHIFT);
0430 }
0431
0432
0433 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];
0434 ath11k_hif_write32(ab, reg_base, 0);
0435 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0);
0436 *srng->u.src_ring.tp_addr = 0;
0437
0438 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
0439 val = 0;
0440 if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)
0441 val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP;
0442 if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP)
0443 val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP;
0444 if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP)
0445 val |= HAL_TCL1_RING_MISC_MSI_SWAP;
0446
0447
0448 val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE;
0449
0450 val |= HAL_TCL1_RING_MISC_SRNG_ENABLE;
0451
0452 ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val);
0453 }
0454
0455 static void ath11k_hal_srng_hw_init(struct ath11k_base *ab,
0456 struct hal_srng *srng)
0457 {
0458 if (srng->ring_dir == HAL_SRNG_DIR_SRC)
0459 ath11k_hal_srng_src_hw_init(ab, srng);
0460 else
0461 ath11k_hal_srng_dst_hw_init(ab, srng);
0462 }
0463
0464 static int ath11k_hal_srng_get_ring_id(struct ath11k_base *ab,
0465 enum hal_ring_type type,
0466 int ring_num, int mac_id)
0467 {
0468 struct hal_srng_config *srng_config = &ab->hal.srng_config[type];
0469 int ring_id;
0470
0471 if (ring_num >= srng_config->max_rings) {
0472 ath11k_warn(ab, "invalid ring number :%d\n", ring_num);
0473 return -EINVAL;
0474 }
0475
0476 ring_id = srng_config->start_ring_id + ring_num;
0477 if (srng_config->lmac_ring)
0478 ring_id += mac_id * HAL_SRNG_RINGS_PER_LMAC;
0479
0480 if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX))
0481 return -EINVAL;
0482
0483 return ring_id;
0484 }
0485
0486 int ath11k_hal_srng_get_entrysize(struct ath11k_base *ab, u32 ring_type)
0487 {
0488 struct hal_srng_config *srng_config;
0489
0490 if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES))
0491 return -EINVAL;
0492
0493 srng_config = &ab->hal.srng_config[ring_type];
0494
0495 return (srng_config->entry_size << 2);
0496 }
0497
0498 int ath11k_hal_srng_get_max_entries(struct ath11k_base *ab, u32 ring_type)
0499 {
0500 struct hal_srng_config *srng_config;
0501
0502 if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES))
0503 return -EINVAL;
0504
0505 srng_config = &ab->hal.srng_config[ring_type];
0506
0507 return (srng_config->max_size / srng_config->entry_size);
0508 }
0509
0510 void ath11k_hal_srng_get_params(struct ath11k_base *ab, struct hal_srng *srng,
0511 struct hal_srng_params *params)
0512 {
0513 params->ring_base_paddr = srng->ring_base_paddr;
0514 params->ring_base_vaddr = srng->ring_base_vaddr;
0515 params->num_entries = srng->num_entries;
0516 params->intr_timer_thres_us = srng->intr_timer_thres_us;
0517 params->intr_batch_cntr_thres_entries =
0518 srng->intr_batch_cntr_thres_entries;
0519 params->low_threshold = srng->u.src_ring.low_threshold;
0520 params->msi_addr = srng->msi_addr;
0521 params->msi_data = srng->msi_data;
0522 params->flags = srng->flags;
0523 }
0524
0525 dma_addr_t ath11k_hal_srng_get_hp_addr(struct ath11k_base *ab,
0526 struct hal_srng *srng)
0527 {
0528 if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING))
0529 return 0;
0530
0531 if (srng->ring_dir == HAL_SRNG_DIR_SRC)
0532 return ab->hal.wrp.paddr +
0533 ((unsigned long)srng->u.src_ring.hp_addr -
0534 (unsigned long)ab->hal.wrp.vaddr);
0535 else
0536 return ab->hal.rdp.paddr +
0537 ((unsigned long)srng->u.dst_ring.hp_addr -
0538 (unsigned long)ab->hal.rdp.vaddr);
0539 }
0540
0541 dma_addr_t ath11k_hal_srng_get_tp_addr(struct ath11k_base *ab,
0542 struct hal_srng *srng)
0543 {
0544 if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING))
0545 return 0;
0546
0547 if (srng->ring_dir == HAL_SRNG_DIR_SRC)
0548 return ab->hal.rdp.paddr +
0549 ((unsigned long)srng->u.src_ring.tp_addr -
0550 (unsigned long)ab->hal.rdp.vaddr);
0551 else
0552 return ab->hal.wrp.paddr +
0553 ((unsigned long)srng->u.dst_ring.tp_addr -
0554 (unsigned long)ab->hal.wrp.vaddr);
0555 }
0556
0557 u32 ath11k_hal_ce_get_desc_size(enum hal_ce_desc type)
0558 {
0559 switch (type) {
0560 case HAL_CE_DESC_SRC:
0561 return sizeof(struct hal_ce_srng_src_desc);
0562 case HAL_CE_DESC_DST:
0563 return sizeof(struct hal_ce_srng_dest_desc);
0564 case HAL_CE_DESC_DST_STATUS:
0565 return sizeof(struct hal_ce_srng_dst_status_desc);
0566 }
0567
0568 return 0;
0569 }
0570
0571 void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id,
0572 u8 byte_swap_data)
0573 {
0574 struct hal_ce_srng_src_desc *desc = (struct hal_ce_srng_src_desc *)buf;
0575
0576 desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
0577 desc->buffer_addr_info =
0578 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI,
0579 ((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT)) |
0580 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP,
0581 byte_swap_data) |
0582 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_GATHER, 0) |
0583 FIELD_PREP(HAL_CE_SRC_DESC_ADDR_INFO_LEN, len);
0584 desc->meta_info = FIELD_PREP(HAL_CE_SRC_DESC_META_INFO_DATA, id);
0585 }
0586
0587 void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr)
0588 {
0589 struct hal_ce_srng_dest_desc *desc =
0590 (struct hal_ce_srng_dest_desc *)buf;
0591
0592 desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
0593 desc->buffer_addr_info =
0594 FIELD_PREP(HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI,
0595 ((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT));
0596 }
0597
0598 u32 ath11k_hal_ce_dst_status_get_length(void *buf)
0599 {
0600 struct hal_ce_srng_dst_status_desc *desc =
0601 (struct hal_ce_srng_dst_status_desc *)buf;
0602 u32 len;
0603
0604 len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);
0605 desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN;
0606
0607 return len;
0608 }
0609
0610 void ath11k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie,
0611 dma_addr_t paddr)
0612 {
0613 desc->buf_addr_info.info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR,
0614 (paddr & HAL_ADDR_LSB_REG_MASK));
0615 desc->buf_addr_info.info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR,
0616 ((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT)) |
0617 FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, 1) |
0618 FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie);
0619 }
0620
0621 u32 *ath11k_hal_srng_dst_peek(struct ath11k_base *ab, struct hal_srng *srng)
0622 {
0623 lockdep_assert_held(&srng->lock);
0624
0625 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp)
0626 return (srng->ring_base_vaddr + srng->u.dst_ring.tp);
0627
0628 return NULL;
0629 }
0630
0631 static void ath11k_hal_srng_prefetch_desc(struct ath11k_base *ab,
0632 struct hal_srng *srng)
0633 {
0634 u32 *desc;
0635
0636
0637 desc = ath11k_hal_srng_dst_peek(ab, srng);
0638 if (likely(desc)) {
0639 dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc),
0640 (srng->entry_size * sizeof(u32)),
0641 DMA_FROM_DEVICE);
0642 prefetch(desc);
0643 }
0644 }
0645
0646 u32 *ath11k_hal_srng_dst_get_next_entry(struct ath11k_base *ab,
0647 struct hal_srng *srng)
0648 {
0649 u32 *desc;
0650
0651 lockdep_assert_held(&srng->lock);
0652
0653 if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp)
0654 return NULL;
0655
0656 desc = srng->ring_base_vaddr + srng->u.dst_ring.tp;
0657
0658 srng->u.dst_ring.tp += srng->entry_size;
0659
0660
0661 if (srng->u.dst_ring.tp == srng->ring_size)
0662 srng->u.dst_ring.tp = 0;
0663
0664
0665 if (srng->flags & HAL_SRNG_FLAGS_CACHED)
0666 ath11k_hal_srng_prefetch_desc(ab, srng);
0667
0668 return desc;
0669 }
0670
0671 int ath11k_hal_srng_dst_num_free(struct ath11k_base *ab, struct hal_srng *srng,
0672 bool sync_hw_ptr)
0673 {
0674 u32 tp, hp;
0675
0676 lockdep_assert_held(&srng->lock);
0677
0678 tp = srng->u.dst_ring.tp;
0679
0680 if (sync_hw_ptr) {
0681 hp = *srng->u.dst_ring.hp_addr;
0682 srng->u.dst_ring.cached_hp = hp;
0683 } else {
0684 hp = srng->u.dst_ring.cached_hp;
0685 }
0686
0687 if (hp >= tp)
0688 return (hp - tp) / srng->entry_size;
0689 else
0690 return (srng->ring_size - tp + hp) / srng->entry_size;
0691 }
0692
0693
0694 int ath11k_hal_srng_src_num_free(struct ath11k_base *ab, struct hal_srng *srng,
0695 bool sync_hw_ptr)
0696 {
0697 u32 tp, hp;
0698
0699 lockdep_assert_held(&srng->lock);
0700
0701 hp = srng->u.src_ring.hp;
0702
0703 if (sync_hw_ptr) {
0704 tp = *srng->u.src_ring.tp_addr;
0705 srng->u.src_ring.cached_tp = tp;
0706 } else {
0707 tp = srng->u.src_ring.cached_tp;
0708 }
0709
0710 if (tp > hp)
0711 return ((tp - hp) / srng->entry_size) - 1;
0712 else
0713 return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;
0714 }
0715
0716 u32 *ath11k_hal_srng_src_get_next_entry(struct ath11k_base *ab,
0717 struct hal_srng *srng)
0718 {
0719 u32 *desc;
0720 u32 next_hp;
0721
0722 lockdep_assert_held(&srng->lock);
0723
0724
0725
0726
0727
0728
0729
0730 next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size;
0731
0732 if (next_hp == srng->u.src_ring.cached_tp)
0733 return NULL;
0734
0735 desc = srng->ring_base_vaddr + srng->u.src_ring.hp;
0736 srng->u.src_ring.hp = next_hp;
0737
0738
0739
0740
0741
0742
0743
0744 srng->u.src_ring.reap_hp = next_hp;
0745
0746 return desc;
0747 }
0748
0749 u32 *ath11k_hal_srng_src_reap_next(struct ath11k_base *ab,
0750 struct hal_srng *srng)
0751 {
0752 u32 *desc;
0753 u32 next_reap_hp;
0754
0755 lockdep_assert_held(&srng->lock);
0756
0757 next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
0758 srng->ring_size;
0759
0760 if (next_reap_hp == srng->u.src_ring.cached_tp)
0761 return NULL;
0762
0763 desc = srng->ring_base_vaddr + next_reap_hp;
0764 srng->u.src_ring.reap_hp = next_reap_hp;
0765
0766 return desc;
0767 }
0768
0769 u32 *ath11k_hal_srng_src_get_next_reaped(struct ath11k_base *ab,
0770 struct hal_srng *srng)
0771 {
0772 u32 *desc;
0773
0774 lockdep_assert_held(&srng->lock);
0775
0776 if (srng->u.src_ring.hp == srng->u.src_ring.reap_hp)
0777 return NULL;
0778
0779 desc = srng->ring_base_vaddr + srng->u.src_ring.hp;
0780 srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) %
0781 srng->ring_size;
0782
0783 return desc;
0784 }
0785
0786 u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng)
0787 {
0788 lockdep_assert_held(&srng->lock);
0789
0790 if (((srng->u.src_ring.hp + srng->entry_size) % srng->ring_size) ==
0791 srng->u.src_ring.cached_tp)
0792 return NULL;
0793
0794 return srng->ring_base_vaddr + srng->u.src_ring.hp;
0795 }
0796
0797 void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng)
0798 {
0799 lockdep_assert_held(&srng->lock);
0800
0801 if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
0802 srng->u.src_ring.cached_tp =
0803 *(volatile u32 *)srng->u.src_ring.tp_addr;
0804 } else {
0805 srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
0806
0807
0808 if (srng->flags & HAL_SRNG_FLAGS_CACHED)
0809 ath11k_hal_srng_prefetch_desc(ab, srng);
0810 }
0811 }
0812
0813
0814
0815
0816 void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng)
0817 {
0818 lockdep_assert_held(&srng->lock);
0819
0820
0821 if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) {
0822
0823
0824
0825 if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
0826 srng->u.src_ring.last_tp =
0827 *(volatile u32 *)srng->u.src_ring.tp_addr;
0828 *srng->u.src_ring.hp_addr = srng->u.src_ring.hp;
0829 } else {
0830 srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
0831 *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
0832 }
0833 } else {
0834 if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
0835 srng->u.src_ring.last_tp =
0836 *(volatile u32 *)srng->u.src_ring.tp_addr;
0837 ath11k_hif_write32(ab,
0838 (unsigned long)srng->u.src_ring.hp_addr -
0839 (unsigned long)ab->mem,
0840 srng->u.src_ring.hp);
0841 } else {
0842 srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
0843 ath11k_hif_write32(ab,
0844 (unsigned long)srng->u.dst_ring.tp_addr -
0845 (unsigned long)ab->mem,
0846 srng->u.dst_ring.tp);
0847 }
0848 }
0849
0850 srng->timestamp = jiffies;
0851 }
0852
0853 void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab,
0854 struct hal_wbm_idle_scatter_list *sbuf,
0855 u32 nsbufs, u32 tot_link_desc,
0856 u32 end_offset)
0857 {
0858 struct ath11k_buffer_addr *link_addr;
0859 int i;
0860 u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64;
0861
0862 link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE;
0863
0864 for (i = 1; i < nsbufs; i++) {
0865 link_addr->info0 = sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK;
0866 link_addr->info1 = FIELD_PREP(
0867 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32,
0868 (u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT) |
0869 FIELD_PREP(
0870 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG,
0871 BASE_ADDR_MATCH_TAG_VAL);
0872
0873 link_addr = (void *)sbuf[i].vaddr +
0874 HAL_WBM_IDLE_SCATTER_BUF_SIZE;
0875 }
0876
0877 ath11k_hif_write32(ab,
0878 HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR,
0879 FIELD_PREP(HAL_WBM_SCATTER_BUFFER_SIZE, reg_scatter_buf_sz) |
0880 FIELD_PREP(HAL_WBM_LINK_DESC_IDLE_LIST_MODE, 0x1));
0881 ath11k_hif_write32(ab,
0882 HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR,
0883 FIELD_PREP(HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST,
0884 reg_scatter_buf_sz * nsbufs));
0885 ath11k_hif_write32(ab,
0886 HAL_SEQ_WCSS_UMAC_WBM_REG +
0887 HAL_WBM_SCATTERED_RING_BASE_LSB,
0888 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR,
0889 sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK));
0890 ath11k_hif_write32(ab,
0891 HAL_SEQ_WCSS_UMAC_WBM_REG +
0892 HAL_WBM_SCATTERED_RING_BASE_MSB,
0893 FIELD_PREP(
0894 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32,
0895 (u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT) |
0896 FIELD_PREP(
0897 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG,
0898 BASE_ADDR_MATCH_TAG_VAL));
0899
0900
0901 ath11k_hif_write32(ab,
0902 HAL_SEQ_WCSS_UMAC_WBM_REG +
0903 HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0,
0904 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR,
0905 sbuf[nsbufs - 1].paddr));
0906 ath11k_hif_write32(ab,
0907 HAL_SEQ_WCSS_UMAC_WBM_REG +
0908 HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1,
0909 FIELD_PREP(
0910 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32,
0911 ((u64)sbuf[nsbufs - 1].paddr >>
0912 HAL_ADDR_MSB_REG_SHIFT)) |
0913 FIELD_PREP(HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1,
0914 (end_offset >> 2)));
0915 ath11k_hif_write32(ab,
0916 HAL_SEQ_WCSS_UMAC_WBM_REG +
0917 HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0,
0918 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR,
0919 sbuf[0].paddr));
0920
0921 ath11k_hif_write32(ab,
0922 HAL_SEQ_WCSS_UMAC_WBM_REG +
0923 HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0,
0924 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR,
0925 sbuf[0].paddr));
0926 ath11k_hif_write32(ab,
0927 HAL_SEQ_WCSS_UMAC_WBM_REG +
0928 HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1,
0929 FIELD_PREP(
0930 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32,
0931 ((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT)) |
0932 FIELD_PREP(HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1,
0933 0));
0934 ath11k_hif_write32(ab,
0935 HAL_SEQ_WCSS_UMAC_WBM_REG +
0936 HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR,
0937 2 * tot_link_desc);
0938
0939
0940 ath11k_hif_write32(ab,
0941 HAL_SEQ_WCSS_UMAC_WBM_REG +
0942 HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab), 0x40);
0943 }
0944
0945 int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type,
0946 int ring_num, int mac_id,
0947 struct hal_srng_params *params)
0948 {
0949 struct ath11k_hal *hal = &ab->hal;
0950 struct hal_srng_config *srng_config = &ab->hal.srng_config[type];
0951 struct hal_srng *srng;
0952 int ring_id;
0953 u32 lmac_idx;
0954 int i;
0955 u32 reg_base;
0956
0957 ring_id = ath11k_hal_srng_get_ring_id(ab, type, ring_num, mac_id);
0958 if (ring_id < 0)
0959 return ring_id;
0960
0961 srng = &hal->srng_list[ring_id];
0962
0963 srng->ring_id = ring_id;
0964 srng->ring_dir = srng_config->ring_dir;
0965 srng->ring_base_paddr = params->ring_base_paddr;
0966 srng->ring_base_vaddr = params->ring_base_vaddr;
0967 srng->entry_size = srng_config->entry_size;
0968 srng->num_entries = params->num_entries;
0969 srng->ring_size = srng->entry_size * srng->num_entries;
0970 srng->intr_batch_cntr_thres_entries =
0971 params->intr_batch_cntr_thres_entries;
0972 srng->intr_timer_thres_us = params->intr_timer_thres_us;
0973 srng->flags = params->flags;
0974 srng->msi_addr = params->msi_addr;
0975 srng->msi_data = params->msi_data;
0976 srng->initialized = 1;
0977 spin_lock_init(&srng->lock);
0978 lockdep_set_class(&srng->lock, hal->srng_key + ring_id);
0979
0980 for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) {
0981 srng->hwreg_base[i] = srng_config->reg_start[i] +
0982 (ring_num * srng_config->reg_size[i]);
0983 }
0984
0985 memset(srng->ring_base_vaddr, 0,
0986 (srng->entry_size * srng->num_entries) << 2);
0987
0988
0989 if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
0990 srng->flags |= HAL_SRNG_FLAGS_MSI_SWAP | HAL_SRNG_FLAGS_DATA_TLV_SWAP |
0991 HAL_SRNG_FLAGS_RING_PTR_SWAP;
0992
0993 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];
0994
0995 if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
0996 srng->u.src_ring.hp = 0;
0997 srng->u.src_ring.cached_tp = 0;
0998 srng->u.src_ring.reap_hp = srng->ring_size - srng->entry_size;
0999 srng->u.src_ring.tp_addr = (void *)(hal->rdp.vaddr + ring_id);
1000 srng->u.src_ring.low_threshold = params->low_threshold *
1001 srng->entry_size;
1002 if (srng_config->lmac_ring) {
1003 lmac_idx = ring_id - HAL_SRNG_RING_ID_LMAC1_ID_START;
1004 srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr +
1005 lmac_idx);
1006 srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;
1007 } else {
1008 if (!ab->hw_params.supports_shadow_regs)
1009 srng->u.src_ring.hp_addr =
1010 (u32 *)((unsigned long)ab->mem + reg_base);
1011 else
1012 ath11k_dbg(ab, ATH11k_DBG_HAL,
1013 "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n",
1014 type, ring_num,
1015 reg_base,
1016 (unsigned long)srng->u.src_ring.hp_addr -
1017 (unsigned long)ab->mem);
1018 }
1019 } else {
1020
1021
1022
1023
1024
1025
1026
1027
1028 srng->u.dst_ring.loop_cnt = 1;
1029 srng->u.dst_ring.tp = 0;
1030 srng->u.dst_ring.cached_hp = 0;
1031 srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id);
1032 if (srng_config->lmac_ring) {
1033
1034
1035
1036 lmac_idx = ring_id - HAL_SRNG_RING_ID_LMAC1_ID_START;
1037 srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr +
1038 lmac_idx);
1039 srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;
1040 } else {
1041 if (!ab->hw_params.supports_shadow_regs)
1042 srng->u.dst_ring.tp_addr =
1043 (u32 *)((unsigned long)ab->mem + reg_base +
1044 (HAL_REO1_RING_TP(ab) - HAL_REO1_RING_HP(ab)));
1045 else
1046 ath11k_dbg(ab, ATH11k_DBG_HAL,
1047 "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n",
1048 type, ring_num,
1049 reg_base + (HAL_REO1_RING_TP(ab) -
1050 HAL_REO1_RING_HP(ab)),
1051 (unsigned long)srng->u.dst_ring.tp_addr -
1052 (unsigned long)ab->mem);
1053 }
1054 }
1055
1056 if (srng_config->lmac_ring)
1057 return ring_id;
1058
1059 ath11k_hal_srng_hw_init(ab, srng);
1060
1061 if (type == HAL_CE_DST) {
1062 srng->u.dst_ring.max_buffer_length = params->max_buffer_len;
1063 ath11k_hal_ce_dst_setup(ab, srng, ring_num);
1064 }
1065
1066 return ring_id;
1067 }
1068
1069 static void ath11k_hal_srng_update_hp_tp_addr(struct ath11k_base *ab,
1070 int shadow_cfg_idx,
1071 enum hal_ring_type ring_type,
1072 int ring_num)
1073 {
1074 struct hal_srng *srng;
1075 struct ath11k_hal *hal = &ab->hal;
1076 int ring_id;
1077 struct hal_srng_config *srng_config = &hal->srng_config[ring_type];
1078
1079 ring_id = ath11k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0);
1080 if (ring_id < 0)
1081 return;
1082
1083 srng = &hal->srng_list[ring_id];
1084
1085 if (srng_config->ring_dir == HAL_SRNG_DIR_DST)
1086 srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(ab, shadow_cfg_idx) +
1087 (unsigned long)ab->mem);
1088 else
1089 srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(ab, shadow_cfg_idx) +
1090 (unsigned long)ab->mem);
1091 }
1092
1093 int ath11k_hal_srng_update_shadow_config(struct ath11k_base *ab,
1094 enum hal_ring_type ring_type,
1095 int ring_num)
1096 {
1097 struct ath11k_hal *hal = &ab->hal;
1098 struct hal_srng_config *srng_config = &hal->srng_config[ring_type];
1099 int shadow_cfg_idx = hal->num_shadow_reg_configured;
1100 u32 target_reg;
1101
1102 if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS)
1103 return -EINVAL;
1104
1105 hal->num_shadow_reg_configured++;
1106
1107 target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START];
1108 target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] *
1109 ring_num;
1110
1111
1112 if (srng_config->ring_dir == HAL_SRNG_DIR_DST)
1113 target_reg += HAL_OFFSET_FROM_HP_TO_TP;
1114
1115 hal->shadow_reg_addr[shadow_cfg_idx] = target_reg;
1116
1117
1118 ath11k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type,
1119 ring_num);
1120
1121 ath11k_dbg(ab, ATH11k_DBG_HAL,
1122 "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d",
1123 target_reg,
1124 HAL_SHADOW_REG(ab, shadow_cfg_idx),
1125 shadow_cfg_idx,
1126 ring_type, ring_num);
1127
1128 return 0;
1129 }
1130
1131 void ath11k_hal_srng_shadow_config(struct ath11k_base *ab)
1132 {
1133 struct ath11k_hal *hal = &ab->hal;
1134 int ring_type, ring_num;
1135
1136
1137 for (ring_type = 0; ring_type < HAL_MAX_RING_TYPES; ring_type++) {
1138 struct hal_srng_config *srng_config = &hal->srng_config[ring_type];
1139
1140 if (ring_type == HAL_CE_SRC ||
1141 ring_type == HAL_CE_DST ||
1142 ring_type == HAL_CE_DST_STATUS)
1143 continue;
1144
1145 if (srng_config->lmac_ring)
1146 continue;
1147
1148 for (ring_num = 0; ring_num < srng_config->max_rings; ring_num++)
1149 ath11k_hal_srng_update_shadow_config(ab, ring_type, ring_num);
1150 }
1151 }
1152
1153 void ath11k_hal_srng_get_shadow_config(struct ath11k_base *ab,
1154 u32 **cfg, u32 *len)
1155 {
1156 struct ath11k_hal *hal = &ab->hal;
1157
1158 *len = hal->num_shadow_reg_configured;
1159 *cfg = hal->shadow_reg_addr;
1160 }
1161
1162 void ath11k_hal_srng_shadow_update_hp_tp(struct ath11k_base *ab,
1163 struct hal_srng *srng)
1164 {
1165 lockdep_assert_held(&srng->lock);
1166
1167
1168
1169
1170 if (srng->ring_dir == HAL_SRNG_DIR_SRC &&
1171 *srng->u.src_ring.tp_addr != srng->u.src_ring.hp)
1172 ath11k_hal_srng_access_end(ab, srng);
1173 }
1174
1175 static int ath11k_hal_srng_create_config(struct ath11k_base *ab)
1176 {
1177 struct ath11k_hal *hal = &ab->hal;
1178 struct hal_srng_config *s;
1179
1180 hal->srng_config = kmemdup(hw_srng_config_template,
1181 sizeof(hw_srng_config_template),
1182 GFP_KERNEL);
1183 if (!hal->srng_config)
1184 return -ENOMEM;
1185
1186 s = &hal->srng_config[HAL_REO_DST];
1187 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab);
1188 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP(ab);
1189 s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
1190 s->reg_size[1] = HAL_REO2_RING_HP(ab) - HAL_REO1_RING_HP(ab);
1191
1192 s = &hal->srng_config[HAL_REO_EXCEPTION];
1193 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_BASE_LSB(ab);
1194 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_TCL_RING_HP(ab);
1195
1196 s = &hal->srng_config[HAL_REO_REINJECT];
1197 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab);
1198 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP(ab);
1199
1200 s = &hal->srng_config[HAL_REO_CMD];
1201 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab);
1202 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP(ab);
1203
1204 s = &hal->srng_config[HAL_REO_STATUS];
1205 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab);
1206 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP(ab);
1207
1208 s = &hal->srng_config[HAL_TCL_DATA];
1209 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab);
1210 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP;
1211 s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab);
1212 s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP;
1213
1214 s = &hal->srng_config[HAL_TCL_CMD];
1215 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab);
1216 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP;
1217
1218 s = &hal->srng_config[HAL_TCL_STATUS];
1219 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab);
1220 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
1221
1222 s = &hal->srng_config[HAL_CE_SRC];
1223 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
1224 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
1225 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
1226 HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
1227 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
1228 HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
1229
1230 s = &hal->srng_config[HAL_CE_DST];
1231 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
1232 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
1233 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
1234 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
1235 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
1236 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
1237
1238 s = &hal->srng_config[HAL_CE_DST_STATUS];
1239 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
1240 HAL_CE_DST_STATUS_RING_BASE_LSB;
1241 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
1242 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
1243 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
1244 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
1245 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
1246
1247 s = &hal->srng_config[HAL_WBM_IDLE_LINK];
1248 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab);
1249 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP;
1250
1251 s = &hal->srng_config[HAL_SW2WBM_RELEASE];
1252 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_BASE_LSB(ab);
1253 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_RELEASE_RING_HP;
1254
1255 s = &hal->srng_config[HAL_WBM2SW_RELEASE];
1256 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
1257 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP;
1258 s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) -
1259 HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
1260 s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP;
1261
1262 return 0;
1263 }
1264
1265 static void ath11k_hal_register_srng_key(struct ath11k_base *ab)
1266 {
1267 struct ath11k_hal *hal = &ab->hal;
1268 u32 ring_id;
1269
1270 for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++)
1271 lockdep_register_key(hal->srng_key + ring_id);
1272 }
1273
1274 static void ath11k_hal_unregister_srng_key(struct ath11k_base *ab)
1275 {
1276 struct ath11k_hal *hal = &ab->hal;
1277 u32 ring_id;
1278
1279 for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++)
1280 lockdep_unregister_key(hal->srng_key + ring_id);
1281 }
1282
1283 int ath11k_hal_srng_init(struct ath11k_base *ab)
1284 {
1285 struct ath11k_hal *hal = &ab->hal;
1286 int ret;
1287
1288 memset(hal, 0, sizeof(*hal));
1289
1290 ret = ath11k_hal_srng_create_config(ab);
1291 if (ret)
1292 goto err_hal;
1293
1294 ret = ath11k_hal_alloc_cont_rdp(ab);
1295 if (ret)
1296 goto err_hal;
1297
1298 ret = ath11k_hal_alloc_cont_wrp(ab);
1299 if (ret)
1300 goto err_free_cont_rdp;
1301
1302 ath11k_hal_register_srng_key(ab);
1303
1304 return 0;
1305
1306 err_free_cont_rdp:
1307 ath11k_hal_free_cont_rdp(ab);
1308
1309 err_hal:
1310 return ret;
1311 }
1312 EXPORT_SYMBOL(ath11k_hal_srng_init);
1313
1314 void ath11k_hal_srng_deinit(struct ath11k_base *ab)
1315 {
1316 struct ath11k_hal *hal = &ab->hal;
1317
1318 ath11k_hal_unregister_srng_key(ab);
1319 ath11k_hal_free_cont_rdp(ab);
1320 ath11k_hal_free_cont_wrp(ab);
1321 kfree(hal->srng_config);
1322 }
1323 EXPORT_SYMBOL(ath11k_hal_srng_deinit);
1324
1325 void ath11k_hal_dump_srng_stats(struct ath11k_base *ab)
1326 {
1327 struct hal_srng *srng;
1328 struct ath11k_ext_irq_grp *irq_grp;
1329 struct ath11k_ce_pipe *ce_pipe;
1330 int i;
1331
1332 ath11k_err(ab, "Last interrupt received for each CE:\n");
1333 for (i = 0; i < ab->hw_params.ce_count; i++) {
1334 ce_pipe = &ab->ce.ce_pipe[i];
1335
1336 if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
1337 continue;
1338
1339 ath11k_err(ab, "CE_id %d pipe_num %d %ums before\n",
1340 i, ce_pipe->pipe_num,
1341 jiffies_to_msecs(jiffies - ce_pipe->timestamp));
1342 }
1343
1344 ath11k_err(ab, "\nLast interrupt received for each group:\n");
1345 for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
1346 irq_grp = &ab->ext_irq_grp[i];
1347 ath11k_err(ab, "group_id %d %ums before\n",
1348 irq_grp->grp_id,
1349 jiffies_to_msecs(jiffies - irq_grp->timestamp));
1350 }
1351
1352 for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) {
1353 srng = &ab->hal.srng_list[i];
1354
1355 if (!srng->initialized)
1356 continue;
1357
1358 if (srng->ring_dir == HAL_SRNG_DIR_SRC)
1359 ath11k_err(ab,
1360 "src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n",
1361 srng->ring_id, srng->u.src_ring.hp,
1362 srng->u.src_ring.reap_hp,
1363 *srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp,
1364 srng->u.src_ring.last_tp,
1365 jiffies_to_msecs(jiffies - srng->timestamp));
1366 else if (srng->ring_dir == HAL_SRNG_DIR_DST)
1367 ath11k_err(ab,
1368 "dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n",
1369 srng->ring_id, srng->u.dst_ring.tp,
1370 *srng->u.dst_ring.hp_addr,
1371 srng->u.dst_ring.cached_hp,
1372 srng->u.dst_ring.last_hp,
1373 jiffies_to_msecs(jiffies - srng->timestamp));
1374 }
1375 }