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