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