xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 #ifndef _HAL_GENERIC_API_H_
20 #define _HAL_GENERIC_API_H_
21 
22 #include <hal_rx.h>
23 
24 #define SRNG_ENABLE_BIT 0x40
25 #define SRNG_IDLE_STATE_BIT 0x80
26 
27 /**
28  * hal_get_radiotap_he_gi_ltf() - Convert HE ltf and GI value
29  * from stats enum to radiotap enum
30  * @he_gi: HE GI value used in stats
31  * @he_ltf: HE LTF value used in stats
32  *
33  * Return: void
34  */
35 static inline void hal_get_radiotap_he_gi_ltf(uint16_t *he_gi, uint16_t *he_ltf)
36 {
37 	switch (*he_gi) {
38 	case HE_GI_0_8:
39 		*he_gi = HE_GI_RADIOTAP_0_8;
40 		break;
41 	case HE_GI_1_6:
42 		*he_gi = HE_GI_RADIOTAP_1_6;
43 		break;
44 	case HE_GI_3_2:
45 		*he_gi = HE_GI_RADIOTAP_3_2;
46 		break;
47 	default:
48 		*he_gi = HE_GI_RADIOTAP_RESERVED;
49 	}
50 
51 	switch (*he_ltf) {
52 	case HE_LTF_1_X:
53 		*he_ltf = HE_LTF_RADIOTAP_1_X;
54 		break;
55 	case HE_LTF_2_X:
56 		*he_ltf = HE_LTF_RADIOTAP_2_X;
57 		break;
58 	case HE_LTF_4_X:
59 		*he_ltf = HE_LTF_RADIOTAP_4_X;
60 		break;
61 	default:
62 		*he_ltf = HE_LTF_RADIOTAP_UNKNOWN;
63 	}
64 }
65 
66 /* channel number to freq conversion */
67 #define CHANNEL_NUM_14 14
68 #define CHANNEL_NUM_15 15
69 #define CHANNEL_NUM_27 27
70 #define CHANNEL_NUM_35 35
71 #define CHANNEL_NUM_182 182
72 #define CHANNEL_NUM_197 197
73 #define CHANNEL_FREQ_2484 2484
74 #define CHANNEL_FREQ_2407 2407
75 #define CHANNEL_FREQ_2512 2512
76 #define CHANNEL_FREQ_5000 5000
77 #define CHANNEL_FREQ_5950 5950
78 #define CHANNEL_FREQ_4000 4000
79 #define CHANNEL_FREQ_5150 5150
80 #define CHANNEL_FREQ_5920 5920
81 #define CHANNEL_FREQ_5935 5935
82 #define FREQ_MULTIPLIER_CONST_5MHZ 5
83 #define FREQ_MULTIPLIER_CONST_20MHZ 20
84 /**
85  * hal_rx_radiotap_num_to_freq() - Get frequency from chan number
86  * @chan_num - Input channel number
87  * @center_freq - Input Channel Center frequency
88  *
89  * Return - Channel frequency in Mhz
90  */
91 static inline uint16_t
92 hal_rx_radiotap_num_to_freq(uint16_t chan_num, qdf_freq_t center_freq)
93 {
94 	if (center_freq > CHANNEL_FREQ_5920 && center_freq < CHANNEL_FREQ_5950)
95 		return CHANNEL_FREQ_5935;
96 
97 	if (center_freq < CHANNEL_FREQ_5950) {
98 		if (chan_num == CHANNEL_NUM_14)
99 			return CHANNEL_FREQ_2484;
100 		if (chan_num < CHANNEL_NUM_14)
101 			return CHANNEL_FREQ_2407 +
102 				(chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
103 
104 		if (chan_num < CHANNEL_NUM_27)
105 			return CHANNEL_FREQ_2512 +
106 				((chan_num - CHANNEL_NUM_15) *
107 					FREQ_MULTIPLIER_CONST_20MHZ);
108 
109 		if (chan_num > CHANNEL_NUM_182 &&
110 		    chan_num < CHANNEL_NUM_197)
111 			return ((chan_num * FREQ_MULTIPLIER_CONST_5MHZ) +
112 				CHANNEL_FREQ_4000);
113 
114 		return CHANNEL_FREQ_5000 +
115 			(chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
116 	} else {
117 		return CHANNEL_FREQ_5950 +
118 			(chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
119 	}
120 }
121 
122 /**
123  * hal_get_hw_hptp_generic()  - Get HW head and tail pointer value for any ring
124  * @hal_soc: Opaque HAL SOC handle
125  * @hal_ring: Source ring pointer
126  * @headp: Head Pointer
127  * @tailp: Tail Pointer
128  * @ring: Ring type
129  *
130  * Return: Update tail pointer and head pointer in arguments.
131  */
132 static inline
133 void hal_get_hw_hptp_generic(struct hal_soc *hal_soc,
134 			     hal_ring_handle_t hal_ring_hdl,
135 			     uint32_t *headp, uint32_t *tailp,
136 			     uint8_t ring)
137 {
138 	struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
139 	struct hal_hw_srng_config *ring_config;
140 	enum hal_ring_type ring_type = (enum hal_ring_type)ring;
141 
142 	if (!hal_soc  || !srng) {
143 		QDF_TRACE(QDF_MODULE_ID_HAL, QDF_TRACE_LEVEL_ERROR,
144 			  "%s: Context is Null", __func__);
145 		return;
146 	}
147 
148 	ring_config = HAL_SRNG_CONFIG(hal_soc, ring_type);
149 	if (!ring_config->lmac_ring) {
150 		if (srng->ring_dir == HAL_SRNG_SRC_RING) {
151 			*headp = SRNG_SRC_REG_READ(srng, HP);
152 			*tailp = SRNG_SRC_REG_READ(srng, TP);
153 		} else {
154 			*headp = SRNG_DST_REG_READ(srng, HP);
155 			*tailp = SRNG_DST_REG_READ(srng, TP);
156 		}
157 	}
158 }
159 
160 #if defined(WBM_IDLE_LSB_WRITE_CONFIRM_WAR)
161 /**
162  * hal_wbm_idle_lsb_write_confirm() - Check and update WBM_IDLE_LINK ring LSB
163  * @srng: srng handle
164  *
165  * Return: None
166  */
167 static void hal_wbm_idle_lsb_write_confirm(struct hal_srng *srng)
168 {
169 	if (srng->ring_id == HAL_SRNG_WBM_IDLE_LINK) {
170 		while (SRNG_SRC_REG_READ(srng, BASE_LSB) !=
171 		       ((unsigned int)srng->ring_base_paddr & 0xffffffff))
172 				SRNG_SRC_REG_WRITE(srng, BASE_LSB,
173 						   srng->ring_base_paddr &
174 						   0xffffffff);
175 	}
176 }
177 #else
178 static void hal_wbm_idle_lsb_write_confirm(struct hal_srng *srng)
179 {
180 }
181 #endif
182 
183 #ifdef DP_UMAC_HW_RESET_SUPPORT
184 /**
185  * hal_srng_src_hw_write_cons_prefetch_timer() - Write cons prefetch timer reg
186  * @srng: srng handle
187  * @value: value to set
188  *
189  * Return: None
190  */
191 static inline
192 void hal_srng_src_hw_write_cons_prefetch_timer(struct hal_srng *srng,
193 					       uint32_t value)
194 {
195 	SRNG_SRC_REG_WRITE(srng, CONSUMER_PREFETCH_TIMER, value);
196 }
197 
198 /**
199  * hal_srng_hw_disable_generic - Private function to disable SRNG
200  * source ring HW
201  * @hal_soc: HAL SOC handle
202  * @srng: SRNG ring pointer
203  */
204 static inline
205 void hal_srng_hw_disable_generic(struct hal_soc *hal, struct hal_srng *srng)
206 {
207 	uint32_t reg_val = 0;
208 
209 	if (srng->ring_dir == HAL_SRNG_DST_RING) {
210 		reg_val = SRNG_DST_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT);
211 		SRNG_DST_REG_WRITE(srng, MISC, reg_val);
212 	} else {
213 		reg_val = SRNG_SRC_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT);
214 		SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
215 		srng->prefetch_timer =
216 			SRNG_SRC_REG_READ(srng, CONSUMER_PREFETCH_TIMER);
217 		hal_srng_src_hw_write_cons_prefetch_timer(srng, 0);
218 	}
219 }
220 #else
221 static inline
222 void hal_srng_hw_disable_generic(struct hal_soc *hal, struct hal_srng *srng)
223 {
224 }
225 
226 static inline
227 void hal_srng_src_hw_write_cons_prefetch_timer(struct hal_srng *srng,
228 					       uint32_t value)
229 {
230 }
231 #endif
232 /**
233  * hal_srng_src_hw_init - Private function to initialize SRNG
234  * source ring HW
235  * @hal_soc: HAL SOC handle
236  * @srng: SRNG ring pointer
237  * @idle_check: Check if ring is idle
238  */
239 static inline
240 void hal_srng_src_hw_init_generic(struct hal_soc *hal,
241 				  struct hal_srng *srng, bool idle_check)
242 {
243 	uint32_t reg_val = 0;
244 	uint64_t tp_addr = 0;
245 
246 	if (idle_check) {
247 		reg_val = SRNG_SRC_REG_READ(srng, MISC);
248 		if (!(reg_val & SRNG_IDLE_STATE_BIT)) {
249 			hal_err("ring_id %d not in idle state", srng->ring_id);
250 			qdf_assert_always(0);
251 		}
252 
253 		hal_srng_src_hw_write_cons_prefetch_timer(srng,
254 							  srng->prefetch_timer);
255 	}
256 
257 	hal_debug("hw_init srng %d", srng->ring_id);
258 
259 	if (srng->flags & HAL_SRNG_MSI_INTR) {
260 		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB,
261 			srng->msi_addr & 0xffffffff);
262 		reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR),
263 			(uint64_t)(srng->msi_addr) >> 32) |
264 			SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB,
265 			MSI1_ENABLE), 1);
266 		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
267 		SRNG_SRC_REG_WRITE(srng, MSI1_DATA,
268 				   qdf_cpu_to_le32(srng->msi_data));
269 	}
270 
271 	SRNG_SRC_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
272 	hal_wbm_idle_lsb_write_confirm(srng);
273 
274 	reg_val = SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
275 		((uint64_t)(srng->ring_base_paddr) >> 32)) |
276 		SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_SIZE),
277 		srng->entry_size * srng->num_entries);
278 	SRNG_SRC_REG_WRITE(srng, BASE_MSB, reg_val);
279 
280 	reg_val = SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size);
281 	SRNG_SRC_REG_WRITE(srng, ID, reg_val);
282 
283 	/**
284 	 * Interrupt setup:
285 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
286 	 * if level mode is required
287 	 */
288 	reg_val = 0;
289 
290 	/*
291 	 * WAR - Hawkeye v1 has a hardware bug which requires timer value to be
292 	 * programmed in terms of 1us resolution instead of 8us resolution as
293 	 * given in MLD.
294 	 */
295 	if (srng->intr_timer_thres_us) {
296 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
297 			INTERRUPT_TIMER_THRESHOLD),
298 			srng->intr_timer_thres_us);
299 		/* For HK v2 this should be (srng->intr_timer_thres_us >> 3) */
300 	}
301 
302 	if (srng->intr_batch_cntr_thres_entries) {
303 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
304 			BATCH_COUNTER_THRESHOLD),
305 			srng->intr_batch_cntr_thres_entries *
306 			srng->entry_size);
307 	}
308 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
309 
310 	reg_val = 0;
311 	if (srng->flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
312 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX1,
313 			LOW_THRESHOLD), srng->u.src_ring.low_threshold);
314 	}
315 
316 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX1, reg_val);
317 
318 	/* As per HW team, TP_ADDR and HP_ADDR for Idle link ring should
319 	 * remain 0 to avoid some WBM stability issues. Remote head/tail
320 	 * pointers are not required since this ring is completely managed
321 	 * by WBM HW
322 	 */
323 	reg_val = 0;
324 	if (srng->ring_id != HAL_SRNG_WBM_IDLE_LINK) {
325 		tp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
326 			((unsigned long)(srng->u.src_ring.tp_addr) -
327 			(unsigned long)(hal->shadow_rdptr_mem_vaddr)));
328 		SRNG_SRC_REG_WRITE(srng, TP_ADDR_LSB, tp_addr & 0xffffffff);
329 		SRNG_SRC_REG_WRITE(srng, TP_ADDR_MSB, tp_addr >> 32);
330 	} else {
331 		reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, RING_ID_DISABLE), 1);
332 	}
333 
334 	/* Initilaize head and tail pointers to indicate ring is empty */
335 	SRNG_SRC_REG_WRITE(srng, HP, 0);
336 	SRNG_SRC_REG_WRITE(srng, TP, 0);
337 	*(srng->u.src_ring.tp_addr) = 0;
338 
339 	reg_val |= ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
340 			SRNG_SM(SRNG_SRC_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
341 			((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
342 			SRNG_SM(SRNG_SRC_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
343 			((srng->flags & HAL_SRNG_MSI_SWAP) ?
344 			SRNG_SM(SRNG_SRC_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
345 
346 	/* Loop count is not used for SRC rings */
347 	reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, LOOPCNT_DISABLE), 1);
348 
349 	/*
350 	 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
351 	 * todo: update fw_api and replace with above line
352 	 * (when SRNG_ENABLE field for the MISC register is available in fw_api)
353 	 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
354 	 */
355 	reg_val |= SRNG_ENABLE_BIT;
356 
357 	SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
358 }
359 
360 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
361 /**
362  * hal_srng_dst_msi2_setup() - Configure MSI2 register for a SRNG
363  * @srng: SRNG handle
364  *
365  * Return: None
366  */
367 static inline void hal_srng_dst_msi2_setup(struct hal_srng *srng)
368 {
369 	uint32_t reg_val = 0;
370 
371 	if (srng->u.dst_ring.nf_irq_support) {
372 		SRNG_DST_REG_WRITE(srng, MSI2_BASE_LSB,
373 				   srng->msi2_addr & 0xffffffff);
374 		reg_val = SRNG_SM(SRNG_DST_FLD(MSI2_BASE_MSB, ADDR),
375 				  (uint64_t)(srng->msi2_addr) >> 32) |
376 				  SRNG_SM(SRNG_DST_FLD(MSI2_BASE_MSB,
377 					  MSI2_ENABLE), 1);
378 		SRNG_DST_REG_WRITE(srng, MSI2_BASE_MSB, reg_val);
379 		SRNG_DST_REG_WRITE(srng, MSI2_DATA,
380 				   qdf_cpu_to_le32(srng->msi2_data));
381 	}
382 }
383 
384 /**
385  * hal_srng_dst_near_full_int_setup() - Configure near-full params for SRNG
386  * @srng: SRNG handle
387  *
388  * Return: None
389  */
390 static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng)
391 {
392 	uint32_t reg_val = 0;
393 
394 	if (srng->u.dst_ring.nf_irq_support) {
395 		if (srng->intr_timer_thres_us) {
396 			reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT2_SETUP,
397 					   INTERRUPT2_TIMER_THRESHOLD),
398 					   srng->intr_timer_thres_us >> 3);
399 		}
400 
401 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT2_SETUP,
402 				   HIGH_THRESHOLD),
403 				   srng->u.dst_ring.high_thresh *
404 				   srng->entry_size);
405 	}
406 
407 	SRNG_DST_REG_WRITE(srng, PRODUCER_INT2_SETUP, reg_val);
408 }
409 #else
410 static inline void hal_srng_dst_msi2_setup(struct hal_srng *srng)
411 {
412 }
413 
414 static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng)
415 {
416 }
417 #endif
418 
419 /**
420  * hal_srng_dst_hw_init - Private function to initialize SRNG
421  * destination ring HW
422  * @hal_soc: HAL SOC handle
423  * @srng: SRNG ring pointer
424  * @idle_check: Check if ring is idle
425  */
426 static inline
427 void hal_srng_dst_hw_init_generic(struct hal_soc *hal,
428 				  struct hal_srng *srng, bool idle_check)
429 {
430 	uint32_t reg_val = 0;
431 	uint64_t hp_addr = 0;
432 
433 	if (idle_check) {
434 		reg_val = SRNG_DST_REG_READ(srng, MISC);
435 		if (!(reg_val & SRNG_IDLE_STATE_BIT)) {
436 			hal_err("ring_id %d not in idle state", srng->ring_id);
437 			qdf_assert_always(0);
438 		}
439 	}
440 
441 	hal_debug("hw_init srng %d", srng->ring_id);
442 
443 	if (srng->flags & HAL_SRNG_MSI_INTR) {
444 		SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB,
445 			srng->msi_addr & 0xffffffff);
446 		reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR),
447 			(uint64_t)(srng->msi_addr) >> 32) |
448 			SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB,
449 			MSI1_ENABLE), 1);
450 		SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
451 		SRNG_DST_REG_WRITE(srng, MSI1_DATA,
452 				   qdf_cpu_to_le32(srng->msi_data));
453 
454 		hal_srng_dst_msi2_setup(srng);
455 	}
456 
457 	SRNG_DST_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
458 	reg_val = SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
459 		((uint64_t)(srng->ring_base_paddr) >> 32)) |
460 		SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_SIZE),
461 		srng->entry_size * srng->num_entries);
462 	SRNG_DST_REG_WRITE(srng, BASE_MSB, reg_val);
463 
464 	reg_val = SRNG_SM(SRNG_DST_FLD(ID, RING_ID), srng->ring_id) |
465 		SRNG_SM(SRNG_DST_FLD(ID, ENTRY_SIZE), srng->entry_size);
466 	SRNG_DST_REG_WRITE(srng, ID, reg_val);
467 
468 
469 	/**
470 	 * Interrupt setup:
471 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
472 	 * if level mode is required
473 	 */
474 	reg_val = 0;
475 	if (srng->intr_timer_thres_us) {
476 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
477 			INTERRUPT_TIMER_THRESHOLD),
478 			srng->intr_timer_thres_us >> 3);
479 	}
480 
481 	if (srng->intr_batch_cntr_thres_entries) {
482 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
483 			BATCH_COUNTER_THRESHOLD),
484 			srng->intr_batch_cntr_thres_entries *
485 			srng->entry_size);
486 	}
487 
488 	SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
489 
490 	/**
491 	 * Near-Full Interrupt setup:
492 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
493 	 * if level mode is required
494 	 */
495 	hal_srng_dst_near_full_int_setup(srng);
496 
497 	hp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
498 		((unsigned long)(srng->u.dst_ring.hp_addr) -
499 		(unsigned long)(hal->shadow_rdptr_mem_vaddr)));
500 	SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, hp_addr & 0xffffffff);
501 	SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, hp_addr >> 32);
502 
503 	/* Initilaize head and tail pointers to indicate ring is empty */
504 	SRNG_DST_REG_WRITE(srng, HP, 0);
505 	SRNG_DST_REG_WRITE(srng, TP, 0);
506 	*(srng->u.dst_ring.hp_addr) = 0;
507 
508 	reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
509 			SRNG_SM(SRNG_DST_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
510 			((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
511 			SRNG_SM(SRNG_DST_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
512 			((srng->flags & HAL_SRNG_MSI_SWAP) ?
513 			SRNG_SM(SRNG_DST_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
514 
515 	/*
516 	 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
517 	 * todo: update fw_api and replace with above line
518 	 * (when SRNG_ENABLE field for the MISC register is available in fw_api)
519 	 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
520 	 */
521 	reg_val |= 0x40;
522 
523 	SRNG_DST_REG_WRITE(srng, MISC, reg_val);
524 
525 }
526 
527 /**
528  * hal_srng_hw_reg_offset_init_generic() - Initialize the HW srng reg offset
529  * @hal_soc: HAL Soc handle
530  *
531  * Return: None
532  */
533 static inline void hal_srng_hw_reg_offset_init_generic(struct hal_soc *hal_soc)
534 {
535 	int32_t *hw_reg_offset = hal_soc->hal_hw_reg_offset;
536 
537 	/* dst */
538 	hw_reg_offset[DST_HP] = REG_OFFSET(DST, HP);
539 	hw_reg_offset[DST_TP] = REG_OFFSET(DST, TP);
540 	hw_reg_offset[DST_ID] = REG_OFFSET(DST, ID);
541 	hw_reg_offset[DST_MISC] = REG_OFFSET(DST, MISC);
542 	hw_reg_offset[DST_HP_ADDR_LSB] = REG_OFFSET(DST, HP_ADDR_LSB);
543 	hw_reg_offset[DST_HP_ADDR_MSB] = REG_OFFSET(DST, HP_ADDR_MSB);
544 	hw_reg_offset[DST_MSI1_BASE_LSB] = REG_OFFSET(DST, MSI1_BASE_LSB);
545 	hw_reg_offset[DST_MSI1_BASE_MSB] = REG_OFFSET(DST, MSI1_BASE_MSB);
546 	hw_reg_offset[DST_MSI1_DATA] = REG_OFFSET(DST, MSI1_DATA);
547 	hw_reg_offset[DST_BASE_LSB] = REG_OFFSET(DST, BASE_LSB);
548 	hw_reg_offset[DST_BASE_MSB] = REG_OFFSET(DST, BASE_MSB);
549 	hw_reg_offset[DST_PRODUCER_INT_SETUP] =
550 					REG_OFFSET(DST, PRODUCER_INT_SETUP);
551 
552 	/* src */
553 	hw_reg_offset[SRC_HP] = REG_OFFSET(SRC, HP);
554 	hw_reg_offset[SRC_TP] = REG_OFFSET(SRC, TP);
555 	hw_reg_offset[SRC_ID] = REG_OFFSET(SRC, ID);
556 	hw_reg_offset[SRC_MISC] = REG_OFFSET(SRC, MISC);
557 	hw_reg_offset[SRC_TP_ADDR_LSB] = REG_OFFSET(SRC, TP_ADDR_LSB);
558 	hw_reg_offset[SRC_TP_ADDR_MSB] = REG_OFFSET(SRC, TP_ADDR_MSB);
559 	hw_reg_offset[SRC_MSI1_BASE_LSB] = REG_OFFSET(SRC, MSI1_BASE_LSB);
560 	hw_reg_offset[SRC_MSI1_BASE_MSB] = REG_OFFSET(SRC, MSI1_BASE_MSB);
561 	hw_reg_offset[SRC_MSI1_DATA] = REG_OFFSET(SRC, MSI1_DATA);
562 	hw_reg_offset[SRC_BASE_LSB] = REG_OFFSET(SRC, BASE_LSB);
563 	hw_reg_offset[SRC_BASE_MSB] = REG_OFFSET(SRC, BASE_MSB);
564 	hw_reg_offset[SRC_CONSUMER_INT_SETUP_IX0] =
565 					REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0);
566 	hw_reg_offset[SRC_CONSUMER_INT_SETUP_IX1] =
567 					REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1);
568 #ifdef DP_UMAC_HW_RESET_SUPPORT
569 	hw_reg_offset[SRC_CONSUMER_PREFETCH_TIMER] =
570 				REG_OFFSET(SRC, CONSUMER_PREFETCH_TIMER);
571 #endif
572 }
573 
574 #endif /* HAL_GENERIC_API_H_ */
575