blob: 54b9aa2e9cd0eb14b692ea368de42ca19b660403 [file] [log] [blame]
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001/*
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05302 * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07003 *
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05304 * 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.
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07008 *
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05309 * 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.
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -070017 */
18
19#ifndef _HAL_API_H_
20#define _HAL_API_H_
21
22#include "qdf_types.h"
Houston Hoffman61dad492017-04-07 17:09:34 -070023#include "qdf_util.h"
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -070024#include "hal_internal.h"
Houston Hoffman61dad492017-04-07 17:09:34 -070025#define MAX_UNWINDOWED_ADDRESS 0x80000
Venkata Sharath Chandra Manchala79860aa2018-06-12 15:16:36 -070026#ifdef QCA_WIFI_QCA6390
Venkata Sharath Chandra Manchala9347b8d2018-06-07 15:26:11 -070027#define WINDOW_ENABLE_BIT 0x40000000
28#else
Houston Hoffman61dad492017-04-07 17:09:34 -070029#define WINDOW_ENABLE_BIT 0x80000000
Venkata Sharath Chandra Manchala9347b8d2018-06-07 15:26:11 -070030#endif
Houston Hoffman61dad492017-04-07 17:09:34 -070031#define WINDOW_REG_ADDRESS 0x310C
32#define WINDOW_SHIFT 19
jiad5661cef2017-11-09 18:24:41 +080033#define WINDOW_VALUE_MASK 0x3F
Houston Hoffman61dad492017-04-07 17:09:34 -070034#define WINDOW_START MAX_UNWINDOWED_ADDRESS
35#define WINDOW_RANGE_MASK 0x7FFFF
36
Pramod Simha95c59f22018-08-27 10:03:04 -070037/*
38 * BAR + 4K is always accessible, any access outside this
39 * space requires force wake procedure.
40 * OFFSET = 4K - 32 bytes = 0x4063
41 */
42#define MAPPED_REF_OFF 0x4063
43#define FORCE_WAKE_DELAY_TIMEOUT 50
44#define FORCE_WAKE_DELAY_MS 5
45
Akshay Kosigi8eda31c2019-07-10 14:42:42 +053046/**
47 * hal_ring_desc - opaque handle for DP ring descriptor
48 */
49struct hal_ring_desc;
50typedef struct hal_ring_desc *hal_ring_desc_t;
51
52/**
53 * hal_link_desc - opaque handle for DP link descriptor
54 */
55struct hal_link_desc;
56typedef struct hal_link_desc *hal_link_desc_t;
57
58/**
59 * hal_rxdma_desc - opaque handle for DP rxdma dst ring descriptor
60 */
61struct hal_rxdma_desc;
62typedef struct hal_rxdma_desc *hal_rxdma_desc_t;
63
Krunal Soni9911b442019-02-22 15:39:03 -080064#ifdef ENABLE_VERBOSE_DEBUG
65static inline void
66hal_set_verbose_debug(bool flag)
67{
68 is_hal_verbose_debug_enabled = flag;
69}
70#endif
71
Pramod Simha95c59f22018-08-27 10:03:04 -070072#ifndef QCA_WIFI_QCA6390
73static inline int hal_force_wake_request(struct hal_soc *soc)
74{
75 return 0;
76}
77
78static inline int hal_force_wake_release(struct hal_soc *soc)
79{
80 return 0;
81}
82#else
83static inline int hal_force_wake_request(struct hal_soc *soc)
84{
85 uint32_t timeout = 0;
86
87 if (pld_force_wake_request(soc->qdf_dev->dev)) {
88 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
89 "%s: Request send failed \n", __func__);
90 return -EINVAL;
91 }
92
93 while (!pld_is_device_awake(soc->qdf_dev->dev) &&
94 timeout <= FORCE_WAKE_DELAY_TIMEOUT) {
95 mdelay(FORCE_WAKE_DELAY_MS);
96 timeout += FORCE_WAKE_DELAY_MS;
97 }
98
99 if (pld_is_device_awake(soc->qdf_dev->dev) == true)
100 return 0;
101 else
102 return -ETIMEDOUT;
103}
104
105static inline int hal_force_wake_release(struct hal_soc *soc)
106{
107 return pld_force_wake_release(soc->qdf_dev->dev);
108}
109#endif
110
Sravan Kumar Kairam830542f2019-07-10 12:09:55 +0530111#ifdef PCIE_REG_WINDOW_LOCAL_NO_CACHE
112static inline void hal_select_window(struct hal_soc *hal_soc, uint32_t offset)
113{
114 uint32_t window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK;
115
116 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS,
117 WINDOW_ENABLE_BIT | window);
118 hal_soc->register_window = window;
119}
120#else
Houston Hoffman61dad492017-04-07 17:09:34 -0700121static inline void hal_select_window(struct hal_soc *hal_soc, uint32_t offset)
122{
123 uint32_t window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK;
124 if (window != hal_soc->register_window) {
125 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS,
126 WINDOW_ENABLE_BIT | window);
127 hal_soc->register_window = window;
128 }
129}
Sravan Kumar Kairam830542f2019-07-10 12:09:55 +0530130#endif
Houston Hoffman61dad492017-04-07 17:09:34 -0700131
132/**
133 * note1: WINDOW_RANGE_MASK = (1 << WINDOW_SHIFT) -1
134 * note2: 1 << WINDOW_SHIFT = MAX_UNWINDOWED_ADDRESS
135 * note3: WINDOW_VALUE_MASK = big enough that trying to write past that window
136 * would be a bug
137 */
Pramod Simha95c59f22018-08-27 10:03:04 -0700138#ifndef QCA_WIFI_QCA6390
Houston Hoffman61dad492017-04-07 17:09:34 -0700139static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
140 uint32_t value)
141{
Houston Hoffman61dad492017-04-07 17:09:34 -0700142 if (!hal_soc->use_register_windowing ||
143 offset < MAX_UNWINDOWED_ADDRESS) {
144 qdf_iowrite32(hal_soc->dev_base_addr + offset, value);
145 } else {
146 qdf_spin_lock_irqsave(&hal_soc->register_access_lock);
147 hal_select_window(hal_soc, offset);
148 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START +
149 (offset & WINDOW_RANGE_MASK), value);
150 qdf_spin_unlock_irqrestore(&hal_soc->register_access_lock);
151 }
152}
Pramod Simha95c59f22018-08-27 10:03:04 -0700153#else
154static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
155 uint32_t value)
156{
157 if ((offset > MAPPED_REF_OFF) &&
158 hal_force_wake_request(hal_soc)) {
159 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
160 "%s: Wake up request failed\n", __func__);
161 return;
162 }
163
164 if (!hal_soc->use_register_windowing ||
165 offset < MAX_UNWINDOWED_ADDRESS) {
166 qdf_iowrite32(hal_soc->dev_base_addr + offset, value);
167 } else {
168 qdf_spin_lock_irqsave(&hal_soc->register_access_lock);
169 hal_select_window(hal_soc, offset);
170 qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START +
171 (offset & WINDOW_RANGE_MASK), value);
172 qdf_spin_unlock_irqrestore(&hal_soc->register_access_lock);
173 }
174
175 if ((offset > MAPPED_REF_OFF) &&
176 hal_force_wake_release(hal_soc))
177 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
178 "%s: Wake up release failed\n", __func__);
179}
180
181#endif
Houston Hoffman61dad492017-04-07 17:09:34 -0700182
183/**
184 * hal_write_address_32_mb - write a value to a register
185 *
186 */
187static inline void hal_write_address_32_mb(struct hal_soc *hal_soc,
188 void __iomem *addr, uint32_t value)
189{
190 uint32_t offset;
191
192 if (!hal_soc->use_register_windowing)
193 return qdf_iowrite32(addr, value);
194
195 offset = addr - hal_soc->dev_base_addr;
196 hal_write32_mb(hal_soc, offset, value);
197}
198
Pramod Simha95c59f22018-08-27 10:03:04 -0700199#ifndef QCA_WIFI_QCA6390
Houston Hoffman61dad492017-04-07 17:09:34 -0700200static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
201{
202 uint32_t ret;
203
204 if (!hal_soc->use_register_windowing ||
205 offset < MAX_UNWINDOWED_ADDRESS) {
206 return qdf_ioread32(hal_soc->dev_base_addr + offset);
207 }
208
209 qdf_spin_lock_irqsave(&hal_soc->register_access_lock);
210 hal_select_window(hal_soc, offset);
211 ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START +
212 (offset & WINDOW_RANGE_MASK));
213 qdf_spin_unlock_irqrestore(&hal_soc->register_access_lock);
214
215 return ret;
216}
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -0700217
218/**
219 * hal_read_address_32_mb() - Read 32-bit value from the register
220 * @soc: soc handle
221 * @addr: register address to read
222 *
223 * Return: 32-bit value
224 */
225static inline uint32_t hal_read_address_32_mb(struct hal_soc *soc,
226 void __iomem *addr)
227{
228 uint32_t offset;
229 uint32_t ret;
230
231 if (!soc->use_register_windowing)
232 return qdf_ioread32(addr);
233
234 offset = addr - soc->dev_base_addr;
235 ret = hal_read32_mb(soc, offset);
236 return ret;
237}
Pramod Simha95c59f22018-08-27 10:03:04 -0700238#else
239static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
240{
241 uint32_t ret;
242
243 if ((offset > MAPPED_REF_OFF) &&
244 hal_force_wake_request(hal_soc)) {
245 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
246 "%s: Wake up request failed\n", __func__);
247 return -EINVAL;
248 }
249
250 if (!hal_soc->use_register_windowing ||
251 offset < MAX_UNWINDOWED_ADDRESS) {
252 return qdf_ioread32(hal_soc->dev_base_addr + offset);
253 }
254
255 qdf_spin_lock_irqsave(&hal_soc->register_access_lock);
256 hal_select_window(hal_soc, offset);
257 ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START +
258 (offset & WINDOW_RANGE_MASK));
259 qdf_spin_unlock_irqrestore(&hal_soc->register_access_lock);
260
261 if ((offset > MAPPED_REF_OFF) &&
262 hal_force_wake_release(hal_soc))
263 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
264 "%s: Wake up release failed\n", __func__);
265
266 return ret;
267}
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -0700268
269static inline uint32_t hal_read_address_32_mb(struct hal_soc *soc,
270 void __iomem *addr)
271{
272 uint32_t offset;
273 uint32_t ret;
274
275 if (!soc->use_register_windowing)
276 return qdf_ioread32(addr);
277
278 offset = addr - soc->dev_base_addr;
279 ret = hal_read32_mb(soc, offset);
280 return ret;
281}
Pramod Simha95c59f22018-08-27 10:03:04 -0700282#endif
Houston Hoffman61dad492017-04-07 17:09:34 -0700283
284#include "hif_io32.h"
285
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700286/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -0700287 * hal_attach - Initialize HAL layer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700288 * @hif_handle: Opaque HIF handle
289 * @qdf_dev: QDF device
290 *
291 * Return: Opaque HAL SOC handle
292 * NULL on failure (if given ring is not available)
293 *
294 * This function should be called as part of HIF initialization (for accessing
295 * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle()
296 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530297void *hal_attach(struct hif_opaque_softc *hif_handle, qdf_device_t qdf_dev);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700298
299/**
300 * hal_detach - Detach HAL layer
301 * @hal_soc: HAL SOC handle
302 *
303 * This function should be called as part of HIF detach
304 *
305 */
306extern void hal_detach(void *hal_soc);
307
308/* SRNG type to be passed in APIs hal_srng_get_entrysize and hal_srng_setup */
309enum hal_ring_type {
Mohit Khanna81179cb2018-08-16 20:50:43 -0700310 REO_DST = 0,
311 REO_EXCEPTION = 1,
312 REO_REINJECT = 2,
313 REO_CMD = 3,
314 REO_STATUS = 4,
315 TCL_DATA = 5,
316 TCL_CMD = 6,
317 TCL_STATUS = 7,
318 CE_SRC = 8,
319 CE_DST = 9,
320 CE_DST_STATUS = 10,
321 WBM_IDLE_LINK = 11,
322 SW2WBM_RELEASE = 12,
323 WBM2SW_RELEASE = 13,
324 RXDMA_BUF = 14,
325 RXDMA_DST = 15,
326 RXDMA_MONITOR_BUF = 16,
327 RXDMA_MONITOR_STATUS = 17,
328 RXDMA_MONITOR_DST = 18,
329 RXDMA_MONITOR_DESC = 19,
330 DIR_BUF_RX_DMA_SRC = 20,
Naveen Rawatba24c482017-05-15 12:02:48 -0700331#ifdef WLAN_FEATURE_CIF_CFR
332 WIFI_POS_SRC,
333#endif
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700334 MAX_RING_TYPES
335};
336
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530337#define HAL_SRNG_LMAC_RING 0x80000000
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700338/* SRNG flags passed in hal_srng_params.flags */
339#define HAL_SRNG_MSI_SWAP 0x00000008
340#define HAL_SRNG_RING_PTR_SWAP 0x00000010
341#define HAL_SRNG_DATA_TLV_SWAP 0x00000020
342#define HAL_SRNG_LOW_THRES_INTR_ENABLE 0x00010000
343#define HAL_SRNG_MSI_INTR 0x00020000
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530344#define HAL_SRNG_CACHED_DESC 0x00040000
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700345
Gurumoorthi Gnanasambandhaned4bcf82017-05-24 00:10:59 +0530346#define PN_SIZE_24 0
347#define PN_SIZE_48 1
348#define PN_SIZE_128 2
349
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700350/**
351 * hal_srng_get_entrysize - Returns size of ring entry in bytes. Should be
352 * used by callers for calculating the size of memory to be allocated before
353 * calling hal_srng_setup to setup the ring
354 *
355 * @hal_soc: Opaque HAL SOC handle
356 * @ring_type: one of the types from hal_ring_type
357 *
358 */
359extern uint32_t hal_srng_get_entrysize(void *hal_soc, int ring_type);
360
Karunakar Dasinenid0ea21f2017-01-31 22:58:15 -0800361/**
362 * hal_srng_max_entries - Returns maximum possible number of ring entries
363 * @hal_soc: Opaque HAL SOC handle
364 * @ring_type: one of the types from hal_ring_type
365 *
366 * Return: Maximum number of entries for the given ring_type
367 */
368uint32_t hal_srng_max_entries(void *hal_soc, int ring_type);
369
Houston Hoffman648a9182017-05-21 23:27:50 -0700370/**
Kai Liub8e12412018-01-12 16:52:26 +0800371 * hal_srng_dump - Dump ring status
372 * @srng: hal srng pointer
373 */
374void hal_srng_dump(struct hal_srng *srng);
375
376/**
Houston Hoffman648a9182017-05-21 23:27:50 -0700377 * hal_srng_get_dir - Returns the direction of the ring
378 * @hal_soc: Opaque HAL SOC handle
379 * @ring_type: one of the types from hal_ring_type
380 *
381 * Return: Ring direction
382 */
383enum hal_srng_dir hal_srng_get_dir(void *hal_soc, int ring_type);
384
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530385/* HAL memory information */
386struct hal_mem_info {
387 /* dev base virutal addr */
388 void *dev_base_addr;
389 /* dev base physical addr */
390 void *dev_base_paddr;
391 /* Remote virtual pointer memory for HW/FW updates */
392 void *shadow_rdptr_mem_vaddr;
393 /* Remote physical pointer memory for HW/FW updates */
394 void *shadow_rdptr_mem_paddr;
395 /* Shared memory for ring pointer updates from host to FW */
396 void *shadow_wrptr_mem_vaddr;
397 /* Shared physical memory for ring pointer updates from host to FW */
398 void *shadow_wrptr_mem_paddr;
399};
400
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700401/* SRNG parameters to be passed to hal_srng_setup */
402struct hal_srng_params {
403 /* Physical base address of the ring */
404 qdf_dma_addr_t ring_base_paddr;
405 /* Virtual base address of the ring */
406 void *ring_base_vaddr;
407 /* Number of entries in ring */
408 uint32_t num_entries;
Houston Hoffman74109122016-10-21 14:58:34 -0700409 /* max transfer length */
410 uint16_t max_buffer_length;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700411 /* MSI Address */
412 qdf_dma_addr_t msi_addr;
413 /* MSI data */
414 uint32_t msi_data;
415 /* Interrupt timer threshold – in micro seconds */
416 uint32_t intr_timer_thres_us;
417 /* Interrupt batch counter threshold – in number of ring entries */
418 uint32_t intr_batch_cntr_thres_entries;
419 /* Low threshold – in number of ring entries
420 * (valid for src rings only)
421 */
422 uint32_t low_threshold;
423 /* Misc flags */
424 uint32_t flags;
Dhanashri Atre7351d172016-10-12 13:08:09 -0700425 /* Unique ring id */
426 uint8_t ring_id;
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530427 /* Source or Destination ring */
428 enum hal_srng_dir ring_dir;
429 /* Size of ring entry */
430 uint32_t entry_size;
431 /* hw register base address */
432 void *hwreg_base[MAX_SRNG_REG_GROUPS];
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700433};
434
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800435/* hal_construct_shadow_config() - initialize the shadow registers for dp rings
436 * @hal_soc: hal handle
437 *
438 * Return: QDF_STATUS_OK on success
439 */
440extern QDF_STATUS hal_construct_shadow_config(void *hal_soc);
441
442/* hal_set_one_shadow_config() - add a config for the specified ring
443 * @hal_soc: hal handle
444 * @ring_type: ring type
445 * @ring_num: ring num
446 *
447 * The ring type and ring num uniquely specify the ring. After this call,
448 * the hp/tp will be added as the next entry int the shadow register
449 * configuration table. The hal code will use the shadow register address
450 * in place of the hp/tp address.
451 *
452 * This function is exposed, so that the CE module can skip configuring shadow
453 * registers for unused ring and rings assigned to the firmware.
454 *
455 * Return: QDF_STATUS_OK on success
456 */
457extern QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type,
458 int ring_num);
459/**
460 * hal_get_shadow_config() - retrieve the config table
461 * @hal_soc: hal handle
462 * @shadow_config: will point to the table after
463 * @num_shadow_registers_configured: will contain the number of valid entries
464 */
465extern void hal_get_shadow_config(void *hal_soc,
466 struct pld_shadow_reg_v2_cfg **shadow_config,
467 int *num_shadow_registers_configured);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700468/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -0700469 * hal_srng_setup - Initialize HW SRNG ring.
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700470 *
471 * @hal_soc: Opaque HAL SOC handle
472 * @ring_type: one of the types from hal_ring_type
473 * @ring_num: Ring number if there are multiple rings of
474 * same type (staring from 0)
475 * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings
476 * @ring_params: SRNG ring params in hal_srng_params structure.
477
478 * Callers are expected to allocate contiguous ring memory of size
479 * 'num_entries * entry_size' bytes and pass the physical and virtual base
480 * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in hal_srng_params
481 * structure. Ring base address should be 8 byte aligned and size of each ring
482 * entry should be queried using the API hal_srng_get_entrysize
483 *
484 * Return: Opaque pointer to ring on success
485 * NULL on failure (if given ring is not available)
486 */
487extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
488 int mac_id, struct hal_srng_params *ring_params);
489
Yun Parkfde6b9e2017-06-26 17:13:11 -0700490/* Remapping ids of REO rings */
491#define REO_REMAP_TCL 0
492#define REO_REMAP_SW1 1
493#define REO_REMAP_SW2 2
494#define REO_REMAP_SW3 3
495#define REO_REMAP_SW4 4
496#define REO_REMAP_RELEASE 5
497#define REO_REMAP_FW 6
498#define REO_REMAP_UNUSED 7
499
500/*
501 * currently this macro only works for IX0 since all the rings we are remapping
502 * can be remapped from HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0
503 */
504#define HAL_REO_REMAP_VAL(_ORIGINAL_DEST, _NEW_DEST) \
505 HAL_REO_REMAP_VAL_(_ORIGINAL_DEST, _NEW_DEST)
506/* allow the destination macros to be expanded */
507#define HAL_REO_REMAP_VAL_(_ORIGINAL_DEST, _NEW_DEST) \
508 (_NEW_DEST << \
509 (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_DEST_RING_MAPPING_ ## \
510 _ORIGINAL_DEST ## _SHFT))
511
512/**
jiad09526ac2019-04-12 17:42:40 +0800513 * hal_reo_read_write_ctrl_ix - Read or write REO_DESTINATION_RING_CTRL_IX
Akshay Kosigi6a206752019-06-10 23:14:52 +0530514 * @hal_soc_hdl: HAL SOC handle
jiad09526ac2019-04-12 17:42:40 +0800515 * @read: boolean value to indicate if read or write
516 * @ix0: pointer to store IX0 reg value
517 * @ix1: pointer to store IX1 reg value
518 * @ix2: pointer to store IX2 reg value
519 * @ix3: pointer to store IX3 reg value
Yun Parkfde6b9e2017-06-26 17:13:11 -0700520 */
Akshay Kosigi6a206752019-06-10 23:14:52 +0530521void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read,
522 uint32_t *ix0, uint32_t *ix1,
523 uint32_t *ix2, uint32_t *ix3);
Yun Parkfde6b9e2017-06-26 17:13:11 -0700524
525/**
Yun Park601d0d82017-08-28 21:49:31 -0700526 * hal_srng_set_hp_paddr() - Set physical address to dest SRNG head pointer
Yun Parkfde6b9e2017-06-26 17:13:11 -0700527 * @sring: sring pointer
528 * @paddr: physical address
529 */
Yun Park601d0d82017-08-28 21:49:31 -0700530extern void hal_srng_dst_set_hp_paddr(struct hal_srng *sring, uint64_t paddr);
531
532/**
533 * hal_srng_dst_init_hp() - Initilaize head pointer with cached head pointer
534 * @srng: sring pointer
535 * @vaddr: virtual address
536 */
537extern void hal_srng_dst_init_hp(struct hal_srng *srng, uint32_t *vaddr);
Yun Parkfde6b9e2017-06-26 17:13:11 -0700538
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700539/**
540 * hal_srng_cleanup - Deinitialize HW SRNG ring.
541 * @hal_soc: Opaque HAL SOC handle
542 * @hal_srng: Opaque HAL SRNG pointer
543 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530544void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700545
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530546static inline bool hal_srng_initialized(hal_ring_handle_t hal_ring_hdl)
Houston Hoffman648a9182017-05-21 23:27:50 -0700547{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530548 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Houston Hoffman648a9182017-05-21 23:27:50 -0700549
550 return !!srng->initialized;
551}
552
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700553/**
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530554 * hal_srng_dst_peek - Check if there are any entries in the ring (peek)
555 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530556 * @hal_ring_hdl: Destination ring pointer
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530557 *
558 * Caller takes responsibility for any locking needs.
559 *
560 * Return: Opaque pointer for next ring entry; NULL on failire
561 */
562static inline
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530563void *hal_srng_dst_peek(hal_soc_handle_t hal_soc_hdl,
564 hal_ring_handle_t hal_ring_hdl)
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530565{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530566 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530567
568 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp)
569 return (void *)(&srng->ring_base_vaddr[srng->u.dst_ring.tp]);
570
571 return NULL;
572}
573
574/**
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700575 * hal_srng_access_start_unlocked - Start ring access (unlocked). Should use
576 * hal_srng_access_start if locked access is required
577 *
578 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530579 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700580 *
581 * Return: 0 on success; error on failire
582 */
Akshay Kosigi6a206752019-06-10 23:14:52 +0530583static inline int
584hal_srng_access_start_unlocked(hal_soc_handle_t hal_soc_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530585 hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700586{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530587 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Akshay Kosigi6a206752019-06-10 23:14:52 +0530588 struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl;
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530589 uint32_t *desc;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700590
591 if (srng->ring_dir == HAL_SRNG_SRC_RING)
592 srng->u.src_ring.cached_tp =
593 *(volatile uint32_t *)(srng->u.src_ring.tp_addr);
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530594 else {
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700595 srng->u.dst_ring.cached_hp =
596 *(volatile uint32_t *)(srng->u.dst_ring.hp_addr);
597
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530598 if (srng->flags & HAL_SRNG_CACHED_DESC) {
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530599 desc = hal_srng_dst_peek(hal_soc_hdl, hal_ring_hdl);
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530600 if (qdf_likely(desc)) {
601 qdf_mem_dma_cache_sync(soc->qdf_dev,
602 qdf_mem_virt_to_phys
603 (desc),
604 QDF_DMA_FROM_DEVICE,
605 (srng->entry_size *
606 sizeof(uint32_t)));
607 qdf_prefetch(desc);
608 }
609 }
610 }
611
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700612 return 0;
613}
614
615/**
616 * hal_srng_access_start - Start (locked) ring access
617 *
618 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530619 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700620 *
621 * Return: 0 on success; error on failire
622 */
Akshay Kosigi6a206752019-06-10 23:14:52 +0530623static inline int hal_srng_access_start(hal_soc_handle_t hal_soc_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530624 hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700625{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530626 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700627
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530628 if (qdf_unlikely(!hal_ring_hdl)) {
Krunal Sonief1f0f92018-09-17 21:09:55 -0700629 qdf_print("Error: Invalid hal_ring\n");
630 return -EINVAL;
631 }
632
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700633 SRNG_LOCK(&(srng->lock));
634
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530635 return hal_srng_access_start_unlocked(hal_soc_hdl, hal_ring_hdl);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700636}
637
638/**
639 * hal_srng_dst_get_next - Get next entry from a destination ring and move
640 * cached tail pointer
641 *
642 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530643 * @hal_ring_hdl: Destination ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700644 *
645 * Return: Opaque pointer for next ring entry; NULL on failire
646 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530647static inline
648void *hal_srng_dst_get_next(void *hal_soc,
649 hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700650{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530651 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530652 struct hal_soc *soc = (struct hal_soc *)hal_soc;
Karunakar Dasineni6bcbdd52017-08-10 18:31:07 -0700653 uint32_t *desc;
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530654 uint32_t *desc_next;
655 uint32_t tp;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700656
Karunakar Dasineni6bcbdd52017-08-10 18:31:07 -0700657 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) {
658 desc = &(srng->ring_base_vaddr[srng->u.dst_ring.tp]);
Karunakar Dasinenia0f09ea2016-11-21 17:41:31 -0800659 /* TODO: Using % is expensive, but we have to do this since
660 * size of some SRNG rings is not power of 2 (due to descriptor
661 * sizes). Need to create separate API for rings used
662 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
663 * SW2RXDMA and CE rings)
664 */
665 srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %
666 srng->ring_size;
667
Chaithanya Garrepalliab234e52019-05-28 12:10:49 +0530668 if (srng->flags & HAL_SRNG_CACHED_DESC) {
669 tp = srng->u.dst_ring.tp;
670 desc_next = &srng->ring_base_vaddr[tp];
671 qdf_mem_dma_cache_sync(soc->qdf_dev,
672 qdf_mem_virt_to_phys(desc_next),
673 QDF_DMA_FROM_DEVICE,
674 (srng->entry_size *
675 sizeof(uint32_t)));
676 qdf_prefetch(desc_next);
677 }
678
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700679 return (void *)desc;
680 }
Karunakar Dasineni6bcbdd52017-08-10 18:31:07 -0700681
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700682 return NULL;
683}
684
685/**
Yun Park601d0d82017-08-28 21:49:31 -0700686 * hal_srng_dst_get_next_hp - Get next entry from a destination ring and move
687 * cached head pointer
688 *
689 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530690 * @hal_ring_hdl: Destination ring pointer
Yun Park601d0d82017-08-28 21:49:31 -0700691 *
692 * Return: Opaque pointer for next ring entry; NULL on failire
693 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530694static inline void *
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530695hal_srng_dst_get_next_hp(hal_soc_handle_t hal_soc_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530696 hal_ring_handle_t hal_ring_hdl)
Yun Park601d0d82017-08-28 21:49:31 -0700697{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530698 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Yun Park601d0d82017-08-28 21:49:31 -0700699 uint32_t *desc;
700 /* TODO: Using % is expensive, but we have to do this since
701 * size of some SRNG rings is not power of 2 (due to descriptor
702 * sizes). Need to create separate API for rings used
703 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
704 * SW2RXDMA and CE rings)
705 */
706 uint32_t next_hp = (srng->u.dst_ring.cached_hp + srng->entry_size) %
707 srng->ring_size;
708
709 if (next_hp != srng->u.dst_ring.tp) {
710 desc = &(srng->ring_base_vaddr[srng->u.dst_ring.cached_hp]);
711 srng->u.dst_ring.cached_hp = next_hp;
712 return (void *)desc;
713 }
714
715 return NULL;
716}
717
718/**
Mohit Khannae5a6e942018-11-28 14:22:48 -0800719 * hal_srng_dst_peek_sync - Check if there are any entries in the ring (peek)
720 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530721 * @hal_ring_hdl: Destination ring pointer
Mohit Khannae5a6e942018-11-28 14:22:48 -0800722 *
723 * Sync cached head pointer with HW.
724 * Caller takes responsibility for any locking needs.
725 *
726 * Return: Opaque pointer for next ring entry; NULL on failire
727 */
728static inline
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530729void *hal_srng_dst_peek_sync(hal_soc_handle_t hal_soc_hdl,
730 hal_ring_handle_t hal_ring_hdl)
Mohit Khannae5a6e942018-11-28 14:22:48 -0800731{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530732 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Mohit Khannae5a6e942018-11-28 14:22:48 -0800733
734 srng->u.dst_ring.cached_hp =
735 *(volatile uint32_t *)(srng->u.dst_ring.hp_addr);
736
737 if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp)
Karunakar Dasineni6bcbdd52017-08-10 18:31:07 -0700738 return (void *)(&(srng->ring_base_vaddr[srng->u.dst_ring.tp]));
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700739
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700740 return NULL;
741}
742
743/**
Mohit Khannae5a6e942018-11-28 14:22:48 -0800744 * hal_srng_dst_peek_sync_locked - Peek for any entries in the ring
745 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530746 * @hal_ring_hdl: Destination ring pointer
Mohit Khannae5a6e942018-11-28 14:22:48 -0800747 *
748 * Sync cached head pointer with HW.
749 * This function takes up SRNG_LOCK. Should not be called with SRNG lock held.
750 *
751 * Return: Opaque pointer for next ring entry; NULL on failire
752 */
753static inline
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530754void *hal_srng_dst_peek_sync_locked(hal_soc_handle_t hal_soc_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530755 hal_ring_handle_t hal_ring_hdl)
Mohit Khannae5a6e942018-11-28 14:22:48 -0800756{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530757 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Mohit Khannae5a6e942018-11-28 14:22:48 -0800758 void *ring_desc_ptr = NULL;
759
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530760 if (qdf_unlikely(!hal_ring_hdl)) {
Mohit Khannae5a6e942018-11-28 14:22:48 -0800761 qdf_print("Error: Invalid hal_ring\n");
762 return NULL;
763 }
764
765 SRNG_LOCK(&srng->lock);
766
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530767 ring_desc_ptr = hal_srng_dst_peek_sync(hal_soc_hdl, hal_ring_hdl);
Mohit Khannae5a6e942018-11-28 14:22:48 -0800768
769 SRNG_UNLOCK(&srng->lock);
770
771 return ring_desc_ptr;
772}
773
774/**
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700775 * hal_srng_dst_num_valid - Returns number of valid entries (to be processed
776 * by SW) in destination ring
777 *
778 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530779 * @hal_ring_hdl: Destination ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700780 * @sync_hw_ptr: Sync cached head pointer with HW
781 *
782 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530783static inline uint32_t hal_srng_dst_num_valid(void *hal_soc,
784 hal_ring_handle_t hal_ring_hdl,
785 int sync_hw_ptr)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700786{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530787 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530788 uint32_t hp;
789 uint32_t tp = srng->u.dst_ring.tp;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700790
791 if (sync_hw_ptr) {
Jinwei Chen1cb78172019-02-12 12:36:10 +0800792 hp = *(volatile uint32_t *)(srng->u.dst_ring.hp_addr);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700793 srng->u.dst_ring.cached_hp = hp;
794 } else {
795 hp = srng->u.dst_ring.cached_hp;
796 }
797
798 if (hp >= tp)
799 return (hp - tp) / srng->entry_size;
800 else
801 return (srng->ring_size - tp + hp) / srng->entry_size;
802}
803
804/**
805 * hal_srng_src_reap_next - Reap next entry from a source ring and move reap
806 * pointer. This can be used to release any buffers associated with completed
807 * ring entries. Note that this should not be used for posting new descriptor
808 * entries. Posting of new entries should be done only using
809 * hal_srng_src_get_next_reaped when this function is used for reaping.
810 *
811 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530812 * @hal_ring_hdl: Source ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700813 *
814 * Return: Opaque pointer for next ring entry; NULL on failire
815 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530816static inline void *
817hal_srng_src_reap_next(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700818{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530819 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700820 uint32_t *desc;
Karunakar Dasinenia0f09ea2016-11-21 17:41:31 -0800821
822 /* TODO: Using % is expensive, but we have to do this since
823 * size of some SRNG rings is not power of 2 (due to descriptor
824 * sizes). Need to create separate API for rings used
825 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
826 * SW2RXDMA and CE rings)
827 */
828 uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
829 srng->ring_size;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700830
831 if (next_reap_hp != srng->u.src_ring.cached_tp) {
832 desc = &(srng->ring_base_vaddr[next_reap_hp]);
833 srng->u.src_ring.reap_hp = next_reap_hp;
834 return (void *)desc;
835 }
836
837 return NULL;
838}
839
840/**
841 * hal_srng_src_get_next_reaped - Get next entry from a source ring that is
842 * already reaped using hal_srng_src_reap_next, for posting new entries to
843 * the ring
844 *
845 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530846 * @hal_ring_hdl: Source ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700847 *
848 * Return: Opaque pointer for next (reaped) source ring entry; NULL on failire
849 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530850static inline void *
851hal_srng_src_get_next_reaped(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700852{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530853 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700854 uint32_t *desc;
855
856 if (srng->u.src_ring.hp != srng->u.src_ring.reap_hp) {
857 desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
Karunakar Dasinenia0f09ea2016-11-21 17:41:31 -0800858 srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) %
859 srng->ring_size;
860
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700861 return (void *)desc;
862 }
863
864 return NULL;
865}
866
867/**
Pamidipati, Vijay980ceb92017-07-05 05:20:17 +0530868 * hal_srng_src_pending_reap_next - Reap next entry from a source ring and
869 * move reap pointer. This API is used in detach path to release any buffers
870 * associated with ring entries which are pending reap.
871 *
872 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530873 * @hal_ring_hdl: Source ring pointer
Pamidipati, Vijay980ceb92017-07-05 05:20:17 +0530874 *
875 * Return: Opaque pointer for next ring entry; NULL on failire
876 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530877static inline void *
878hal_srng_src_pending_reap_next(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Pamidipati, Vijay980ceb92017-07-05 05:20:17 +0530879{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530880 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Pamidipati, Vijay980ceb92017-07-05 05:20:17 +0530881 uint32_t *desc;
882
883 uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
884 srng->ring_size;
885
886 if (next_reap_hp != srng->u.src_ring.hp) {
887 desc = &(srng->ring_base_vaddr[next_reap_hp]);
888 srng->u.src_ring.reap_hp = next_reap_hp;
889 return (void *)desc;
890 }
891
892 return NULL;
893}
894
895/**
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700896 * hal_srng_src_done_val -
897 *
898 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530899 * @hal_ring_hdl: Source ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700900 *
901 * Return: Opaque pointer for next ring entry; NULL on failire
902 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530903static inline uint32_t
904hal_srng_src_done_val(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700905{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530906 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasinenia0f09ea2016-11-21 17:41:31 -0800907 /* TODO: Using % is expensive, but we have to do this since
908 * size of some SRNG rings is not power of 2 (due to descriptor
909 * sizes). Need to create separate API for rings used
910 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
911 * SW2RXDMA and CE rings)
912 */
913 uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
914 srng->ring_size;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700915
916 if (next_reap_hp == srng->u.src_ring.cached_tp)
917 return 0;
918
919 if (srng->u.src_ring.cached_tp > next_reap_hp)
920 return (srng->u.src_ring.cached_tp - next_reap_hp) /
921 srng->entry_size;
922 else
923 return ((srng->ring_size - next_reap_hp) +
924 srng->u.src_ring.cached_tp) / srng->entry_size;
925}
sumedh baikady72b1c712017-08-24 12:11:46 -0700926
927/**
Venkata Sharath Chandra Manchalad8b05b52019-05-31 19:25:33 -0700928 * hal_get_entrysize_from_srng() - Retrieve ring entry size
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530929 * @hal_ring_hdl: Source ring pointer
Venkata Sharath Chandra Manchalad8b05b52019-05-31 19:25:33 -0700930 *
931 * Return: uint8_t
932 */
933static inline
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530934uint8_t hal_get_entrysize_from_srng(hal_ring_handle_t hal_ring_hdl)
Venkata Sharath Chandra Manchalad8b05b52019-05-31 19:25:33 -0700935{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530936 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Venkata Sharath Chandra Manchalad8b05b52019-05-31 19:25:33 -0700937
938 return srng->entry_size;
939}
940
941/**
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -0700942 * hal_get_sw_hptp - Get SW head and tail pointer location for any ring
sumedh baikady72b1c712017-08-24 12:11:46 -0700943 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530944 * @hal_ring_hdl: Source ring pointer
sumedh baikady72b1c712017-08-24 12:11:46 -0700945 * @tailp: Tail Pointer
946 * @headp: Head Pointer
947 *
948 * Return: Update tail pointer and head pointer in arguments.
949 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530950static inline
951void hal_get_sw_hptp(void *hal_soc, hal_ring_handle_t hal_ring_hdl,
952 uint32_t *tailp, uint32_t *headp)
sumedh baikady72b1c712017-08-24 12:11:46 -0700953{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530954 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
sumedh baikady72b1c712017-08-24 12:11:46 -0700955
956 if (srng->ring_dir == HAL_SRNG_SRC_RING) {
Rakesh Pillai56320c12019-06-05 00:25:48 +0530957 *headp = srng->u.src_ring.hp;
958 *tailp = *srng->u.src_ring.tp_addr;
sumedh baikady72b1c712017-08-24 12:11:46 -0700959 } else {
Rakesh Pillai56320c12019-06-05 00:25:48 +0530960 *tailp = srng->u.dst_ring.tp;
961 *headp = *srng->u.dst_ring.hp_addr;
sumedh baikady72b1c712017-08-24 12:11:46 -0700962 }
963}
964
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700965/**
966 * hal_srng_src_get_next - Get next entry from a source ring and move cached tail pointer
967 *
968 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530969 * @hal_ring_hdl: Source ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700970 *
971 * Return: Opaque pointer for next ring entry; NULL on failire
972 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530973static inline
974void *hal_srng_src_get_next(void *hal_soc,
975 hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700976{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530977 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700978 uint32_t *desc;
Karunakar Dasinenia0f09ea2016-11-21 17:41:31 -0800979 /* TODO: Using % is expensive, but we have to do this since
980 * size of some SRNG rings is not power of 2 (due to descriptor
981 * sizes). Need to create separate API for rings used
982 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
983 * SW2RXDMA and CE rings)
984 */
985 uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) %
986 srng->ring_size;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700987
988 if (next_hp != srng->u.src_ring.cached_tp) {
989 desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
990 srng->u.src_ring.hp = next_hp;
991 /* TODO: Since reap function is not used by all rings, we can
992 * remove the following update of reap_hp in this function
993 * if we can ensure that only hal_srng_src_get_next_reaped
994 * is used for the rings requiring reap functionality
995 */
996 srng->u.src_ring.reap_hp = next_hp;
997 return (void *)desc;
998 }
999
1000 return NULL;
1001}
1002
1003/**
1004 * hal_srng_src_peek - Get next entry from a ring without moving head pointer.
1005 * hal_srng_src_get_next should be called subsequently to move the head pointer
1006 *
1007 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301008 * @hal_ring_hdl: Source ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001009 *
1010 * Return: Opaque pointer for next ring entry; NULL on failire
1011 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301012static inline
1013void *hal_srng_src_peek(hal_soc_handle_t hal_soc_hdl,
1014 hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001015{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301016 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001017 uint32_t *desc;
1018
Karunakar Dasinenia0f09ea2016-11-21 17:41:31 -08001019 /* TODO: Using % is expensive, but we have to do this since
1020 * size of some SRNG rings is not power of 2 (due to descriptor
1021 * sizes). Need to create separate API for rings used
1022 * per-packet, with sizes power of 2 (TCL2SW, REO2SW,
1023 * SW2RXDMA and CE rings)
1024 */
1025 if (((srng->u.src_ring.hp + srng->entry_size) %
1026 srng->ring_size) != srng->u.src_ring.cached_tp) {
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001027 desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
1028 return (void *)desc;
1029 }
1030
1031 return NULL;
1032}
1033
1034/**
1035 * hal_srng_src_num_avail - Returns number of available entries in src ring
1036 *
1037 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301038 * @hal_ring_hdl: Source ring pointer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001039 * @sync_hw_ptr: Sync cached tail pointer with HW
1040 *
1041 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301042static inline uint32_t
1043hal_srng_src_num_avail(void *hal_soc,
1044 hal_ring_handle_t hal_ring_hdl, int sync_hw_ptr)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001045{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301046 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +05301047 uint32_t tp;
1048 uint32_t hp = srng->u.src_ring.hp;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001049
1050 if (sync_hw_ptr) {
1051 tp = *(srng->u.src_ring.tp_addr);
1052 srng->u.src_ring.cached_tp = tp;
1053 } else {
1054 tp = srng->u.src_ring.cached_tp;
1055 }
1056
1057 if (tp > hp)
1058 return ((tp - hp) / srng->entry_size) - 1;
1059 else
1060 return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;
1061}
1062
1063/**
1064 * hal_srng_access_end_unlocked - End ring access (unlocked) - update cached
1065 * ring head/tail pointers to HW.
1066 * This should be used only if hal_srng_access_start_unlocked to start ring
1067 * access
1068 *
1069 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301070 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001071 *
1072 * Return: 0 on success; error on failire
1073 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301074static inline void
1075hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001076{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301077 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001078
1079 /* TODO: See if we need a write memory barrier here */
1080 if (srng->flags & HAL_SRNG_LMAC_RING) {
1081 /* For LMAC rings, ring pointer updates are done through FW and
1082 * hence written to a shared memory location that is read by FW
1083 */
Kai Chen6eca1a62017-01-12 10:17:53 -08001084 if (srng->ring_dir == HAL_SRNG_SRC_RING) {
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001085 *(srng->u.src_ring.hp_addr) = srng->u.src_ring.hp;
Kai Chen6eca1a62017-01-12 10:17:53 -08001086 } else {
1087 *(srng->u.dst_ring.tp_addr) = srng->u.dst_ring.tp;
1088 }
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001089 } else {
1090 if (srng->ring_dir == HAL_SRNG_SRC_RING)
Houston Hoffman8bbc9902017-04-10 14:09:51 -07001091 hal_write_address_32_mb(hal_soc,
1092 srng->u.src_ring.hp_addr,
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001093 srng->u.src_ring.hp);
1094 else
Houston Hoffman8bbc9902017-04-10 14:09:51 -07001095 hal_write_address_32_mb(hal_soc,
1096 srng->u.dst_ring.tp_addr,
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001097 srng->u.dst_ring.tp);
1098 }
1099}
1100
1101/**
1102 * hal_srng_access_end - Unlock ring access and update cached ring head/tail
1103 * pointers to HW
1104 * This should be used only if hal_srng_access_start to start ring access
1105 *
1106 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301107 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001108 *
1109 * Return: 0 on success; error on failire
1110 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301111static inline void
1112hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001113{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301114 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001115
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301116 if (qdf_unlikely(!hal_ring_hdl)) {
Krunal Sonief1f0f92018-09-17 21:09:55 -07001117 qdf_print("Error: Invalid hal_ring\n");
1118 return;
1119 }
1120
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301121 hal_srng_access_end_unlocked(hal_soc, hal_ring_hdl);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001122 SRNG_UNLOCK(&(srng->lock));
1123}
1124
Pamidipati, Vijaydfe618e2016-10-09 09:17:24 +05301125/**
1126 * hal_srng_access_end_reap - Unlock ring access
1127 * This should be used only if hal_srng_access_start to start ring access
1128 * and should be used only while reaping SRC ring completions
1129 *
1130 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301131 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Pamidipati, Vijaydfe618e2016-10-09 09:17:24 +05301132 *
1133 * Return: 0 on success; error on failire
1134 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301135static inline void
1136hal_srng_access_end_reap(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Pamidipati, Vijaydfe618e2016-10-09 09:17:24 +05301137{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301138 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Yun Park601d0d82017-08-28 21:49:31 -07001139
Pamidipati, Vijaydfe618e2016-10-09 09:17:24 +05301140 SRNG_UNLOCK(&(srng->lock));
1141}
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001142
1143/* TODO: Check if the following definitions is available in HW headers */
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001144#define WBM_IDLE_SCATTER_BUF_SIZE 32704
1145#define NUM_MPDUS_PER_LINK_DESC 6
1146#define NUM_MSDUS_PER_LINK_DESC 7
1147#define REO_QUEUE_DESC_ALIGN 128
1148
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001149#define LINK_DESC_ALIGN 128
1150
Pramod Simhaccb15fb2017-06-19 12:21:13 -07001151#define ADDRESS_MATCH_TAG_VAL 0x5
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001152/* Number of mpdu link pointers is 9 in case of TX_MPDU_QUEUE_HEAD and 14 in
1153 * of TX_MPDU_QUEUE_EXT. We are defining a common average count here
1154 */
1155#define NUM_MPDU_LINKS_PER_QUEUE_DESC 12
1156
1157/* TODO: Check with HW team on the scatter buffer size supported. As per WBM
1158 * MLD, scatter_buffer_size in IDLE_LIST_CONTROL register is 9 bits and size
1159 * should be specified in 16 word units. But the number of bits defined for
1160 * this field in HW header files is 5.
1161 */
1162#define WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE 8
1163
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001164
1165/**
1166 * hal_idle_list_scatter_buf_size - Get the size of each scatter buffer
1167 * in an idle list
1168 *
1169 * @hal_soc: Opaque HAL SOC handle
1170 *
1171 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301172static inline
1173uint32_t hal_idle_list_scatter_buf_size(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001174{
1175 return WBM_IDLE_SCATTER_BUF_SIZE;
1176}
1177
1178/**
1179 * hal_get_link_desc_size - Get the size of each link descriptor
1180 *
1181 * @hal_soc: Opaque HAL SOC handle
1182 *
1183 */
Akshay Kosigi6a206752019-06-10 23:14:52 +05301184static inline uint32_t hal_get_link_desc_size(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001185{
Akshay Kosigi6a206752019-06-10 23:14:52 +05301186 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
1187
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +05301188 if (!hal_soc || !hal_soc->ops) {
1189 qdf_print("Error: Invalid ops\n");
1190 QDF_BUG(0);
1191 return -EINVAL;
1192 }
1193 if (!hal_soc->ops->hal_get_link_desc_size) {
1194 qdf_print("Error: Invalid function pointer\n");
1195 QDF_BUG(0);
1196 return -EINVAL;
1197 }
1198 return hal_soc->ops->hal_get_link_desc_size();
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001199}
1200
1201/**
1202 * hal_get_link_desc_align - Get the required start address alignment for
1203 * link descriptors
1204 *
1205 * @hal_soc: Opaque HAL SOC handle
1206 *
1207 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301208static inline
1209uint32_t hal_get_link_desc_align(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001210{
1211 return LINK_DESC_ALIGN;
1212}
1213
1214/**
1215 * hal_num_mpdus_per_link_desc - Get number of mpdus each link desc can hold
1216 *
1217 * @hal_soc: Opaque HAL SOC handle
1218 *
1219 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301220static inline
1221uint32_t hal_num_mpdus_per_link_desc(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001222{
1223 return NUM_MPDUS_PER_LINK_DESC;
1224}
1225
1226/**
1227 * hal_num_msdus_per_link_desc - Get number of msdus each link desc can hold
1228 *
1229 * @hal_soc: Opaque HAL SOC handle
1230 *
1231 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301232static inline
1233uint32_t hal_num_msdus_per_link_desc(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001234{
1235 return NUM_MSDUS_PER_LINK_DESC;
1236}
1237
1238/**
1239 * hal_num_mpdu_links_per_queue_desc - Get number of mpdu links each queue
1240 * descriptor can hold
1241 *
1242 * @hal_soc: Opaque HAL SOC handle
1243 *
1244 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301245static inline
1246uint32_t hal_num_mpdu_links_per_queue_desc(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001247{
1248 return NUM_MPDU_LINKS_PER_QUEUE_DESC;
1249}
1250
1251/**
1252 * hal_idle_list_scatter_buf_num_entries - Get the number of link desc entries
1253 * that the given buffer size
1254 *
1255 * @hal_soc: Opaque HAL SOC handle
1256 * @scatter_buf_size: Size of scatter buffer
1257 *
1258 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301259static inline
1260uint32_t hal_idle_scatter_buf_num_entries(hal_soc_handle_t hal_soc_hdl,
1261 uint32_t scatter_buf_size)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001262{
1263 return (scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) /
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301264 hal_srng_get_entrysize(hal_soc_hdl, WBM_IDLE_LINK);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001265}
1266
1267/**
Pramod Simhaccb15fb2017-06-19 12:21:13 -07001268 * hal_idle_list_num_scatter_bufs - Get the number of sctater buffer
1269 * each given buffer size
1270 *
1271 * @hal_soc: Opaque HAL SOC handle
1272 * @total_mem: size of memory to be scattered
1273 * @scatter_buf_size: Size of scatter buffer
1274 *
1275 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301276static inline
1277uint32_t hal_idle_list_num_scatter_bufs(hal_soc_handle_t hal_soc_hdl,
1278 uint32_t total_mem,
1279 uint32_t scatter_buf_size)
Pramod Simhaccb15fb2017-06-19 12:21:13 -07001280{
1281 uint8_t rem = (total_mem % (scatter_buf_size -
1282 WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) ? 1 : 0;
1283
1284 uint32_t num_scatter_bufs = (total_mem / (scatter_buf_size -
1285 WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) + rem;
1286
1287 return num_scatter_bufs;
1288}
1289
Dhanashri Atre14049172016-11-11 18:32:36 -08001290/* REO parameters to be passed to hal_reo_setup */
1291struct hal_reo_params {
Aniruddha Paul91dfd502018-01-08 11:24:34 +05301292 /** rx hash steering enabled or disabled */
Dhanashri Atre14049172016-11-11 18:32:36 -08001293 bool rx_hash_enabled;
Aniruddha Paul91dfd502018-01-08 11:24:34 +05301294 /** reo remap 1 register */
Tallapragada Kalyandbbb0c82017-08-24 20:58:04 +05301295 uint32_t remap1;
Aniruddha Paul91dfd502018-01-08 11:24:34 +05301296 /** reo remap 2 register */
Tallapragada Kalyandbbb0c82017-08-24 20:58:04 +05301297 uint32_t remap2;
Aniruddha Paul91dfd502018-01-08 11:24:34 +05301298 /** fragment destination ring */
1299 uint8_t frag_dst_ring;
1300 /** padding */
1301 uint8_t padding[3];
Dhanashri Atre14049172016-11-11 18:32:36 -08001302};
1303
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001304
1305enum hal_pn_type {
1306 HAL_PN_NONE,
1307 HAL_PN_WPA,
1308 HAL_PN_WAPI_EVEN,
1309 HAL_PN_WAPI_UNEVEN,
1310};
1311
1312#define HAL_RX_MAX_BA_WINDOW 256
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001313
1314/**
1315 * hal_get_reo_qdesc_align - Get start address alignment for reo
1316 * queue descriptors
1317 *
1318 * @hal_soc: Opaque HAL SOC handle
1319 *
1320 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301321static inline
1322uint32_t hal_get_reo_qdesc_align(hal_soc_handle_t hal_soc_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001323{
1324 return REO_QUEUE_DESC_ALIGN;
1325}
1326
1327/**
1328 * hal_reo_qdesc_setup - Setup HW REO queue descriptor
1329 *
1330 * @hal_soc: Opaque HAL SOC handle
1331 * @ba_window_size: BlockAck window size
1332 * @start_seq: Starting sequence number
1333 * @hw_qdesc_vaddr: Virtual address of REO queue descriptor memory
1334 * @hw_qdesc_paddr: Physical address of REO queue descriptor memory
1335 * @pn_type: PN type (one of the types defined in 'enum hal_pn_type')
1336 *
1337 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301338void hal_reo_qdesc_setup(hal_soc_handle_t hal_soc_hdl,
1339 int tid, uint32_t ba_window_size,
1340 uint32_t start_seq, void *hw_qdesc_vaddr,
1341 qdf_dma_addr_t hw_qdesc_paddr,
1342 int pn_type);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001343
1344/**
1345 * hal_srng_get_hp_addr - Get head pointer physical address
1346 *
1347 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301348 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001349 *
1350 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301351static inline qdf_dma_addr_t
1352hal_srng_get_hp_addr(void *hal_soc,
1353 hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001354{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301355 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001356 struct hal_soc *hal = (struct hal_soc *)hal_soc;
1357
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001358 if (srng->ring_dir == HAL_SRNG_SRC_RING) {
Manoj Ekbote7980f3e2017-02-06 15:30:00 -08001359 return hal->shadow_wrptr_mem_paddr +
1360 ((unsigned long)(srng->u.src_ring.hp_addr) -
1361 (unsigned long)(hal->shadow_wrptr_mem_vaddr));
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001362 } else {
Manoj Ekbote7980f3e2017-02-06 15:30:00 -08001363 return hal->shadow_rdptr_mem_paddr +
1364 ((unsigned long)(srng->u.dst_ring.hp_addr) -
1365 (unsigned long)(hal->shadow_rdptr_mem_vaddr));
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001366 }
1367}
1368
1369/**
1370 * hal_srng_get_tp_addr - Get tail pointer physical address
1371 *
1372 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301373 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001374 *
1375 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301376static inline qdf_dma_addr_t
1377hal_srng_get_tp_addr(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001378{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301379 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001380 struct hal_soc *hal = (struct hal_soc *)hal_soc;
1381
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001382 if (srng->ring_dir == HAL_SRNG_SRC_RING) {
1383 return hal->shadow_rdptr_mem_paddr +
1384 ((unsigned long)(srng->u.src_ring.tp_addr) -
1385 (unsigned long)(hal->shadow_rdptr_mem_vaddr));
1386 } else {
1387 return hal->shadow_wrptr_mem_paddr +
1388 ((unsigned long)(srng->u.dst_ring.tp_addr) -
1389 (unsigned long)(hal->shadow_wrptr_mem_vaddr));
1390 }
1391}
1392
1393/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -07001394 * hal_get_srng_params - Retrieve SRNG parameters for a given ring from HAL
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001395 *
1396 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301397 * @hal_ring_hdl: Ring pointer (Source or Destination ring)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001398 * @ring_params: SRNG parameters will be returned through this structure
1399 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301400void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl,
1401 hal_ring_handle_t hal_ring_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301402 struct hal_srng_params *ring_params);
Ravi Joshi36f68ad2016-11-09 17:09:47 -08001403
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +05301404/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -07001405 * hal_mem_info - Retrieve hal memory base address
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +05301406 *
1407 * @hal_soc: Opaque HAL SOC handle
1408 * @mem: pointer to structure to be updated with hal mem info
1409 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301410void hal_get_meminfo(hal_soc_handle_t hal_soc_hdl, struct hal_mem_info *mem);
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +05301411
1412/**
1413 * hal_get_target_type - Return target type
1414 *
1415 * @hal_soc: Opaque HAL SOC handle
1416 */
Akshay Kosigi6a206752019-06-10 23:14:52 +05301417uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl);
sumedh baikady1f8f3192018-02-20 17:30:32 -08001418
1419/**
1420 * hal_get_ba_aging_timeout - Retrieve BA aging timeout
1421 *
1422 * @hal_soc: Opaque HAL SOC handle
1423 * @ac: Access category
1424 * @value: timeout duration in millisec
1425 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301426void hal_get_ba_aging_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t ac,
sumedh baikady1f8f3192018-02-20 17:30:32 -08001427 uint32_t *value);
sumedh baikady1f8f3192018-02-20 17:30:32 -08001428/**
1429 * hal_set_aging_timeout - Set BA aging timeout
1430 *
1431 * @hal_soc: Opaque HAL SOC handle
1432 * @ac: Access category in millisec
1433 * @value: timeout duration value
1434 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301435void hal_set_ba_aging_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t ac,
sumedh baikady1f8f3192018-02-20 17:30:32 -08001436 uint32_t value);
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301437/**
1438 * hal_srng_dst_hw_init - Private function to initialize SRNG
1439 * destination ring HW
1440 * @hal_soc: HAL SOC handle
1441 * @srng: SRNG ring pointer
1442 */
1443static inline void hal_srng_dst_hw_init(struct hal_soc *hal,
1444 struct hal_srng *srng)
1445{
1446 hal->ops->hal_srng_dst_hw_init(hal, srng);
1447}
sumedh baikady1f8f3192018-02-20 17:30:32 -08001448
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301449/**
1450 * hal_srng_src_hw_init - Private function to initialize SRNG
1451 * source ring HW
1452 * @hal_soc: HAL SOC handle
1453 * @srng: SRNG ring pointer
1454 */
1455static inline void hal_srng_src_hw_init(struct hal_soc *hal,
1456 struct hal_srng *srng)
1457{
1458 hal->ops->hal_srng_src_hw_init(hal, srng);
1459}
1460
1461/**
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -07001462 * hal_get_hw_hptp() - Get HW head and tail pointer value for any ring
1463 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301464 * @hal_ring_hdl: Source ring pointer
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -07001465 * @headp: Head Pointer
1466 * @tailp: Tail Pointer
1467 * @ring_type: Ring
1468 *
1469 * Return: Update tail pointer and head pointer in arguments.
1470 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301471static inline
1472void hal_get_hw_hptp(hal_soc_handle_t hal_soc_hdl,
1473 hal_ring_handle_t hal_ring_hdl,
1474 uint32_t *headp, uint32_t *tailp,
1475 uint8_t ring_type)
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -07001476{
Akshay Kosigi6a206752019-06-10 23:14:52 +05301477 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
1478
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301479 hal_soc->ops->hal_get_hw_hptp(hal_soc, hal_ring_hdl,
Akshay Kosigi6a206752019-06-10 23:14:52 +05301480 headp, tailp, ring_type);
Venkata Sharath Chandra Manchala443b9b42018-10-10 12:04:54 -07001481}
1482
1483/**
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301484 * hal_reo_setup - Initialize HW REO block
1485 *
1486 * @hal_soc: Opaque HAL SOC handle
1487 * @reo_params: parameters needed by HAL for REO config
1488 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301489static inline void hal_reo_setup(hal_soc_handle_t hal_soc_hdl,
1490 void *reoparams)
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301491{
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301492 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301493
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301494 hal_soc->ops->hal_reo_setup(hal_soc, reoparams);
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301495}
1496
1497/**
1498 * hal_setup_link_idle_list - Setup scattered idle list using the
1499 * buffer list provided
1500 *
1501 * @hal_soc: Opaque HAL SOC handle
1502 * @scatter_bufs_base_paddr: Array of physical base addresses
1503 * @scatter_bufs_base_vaddr: Array of virtual base addresses
1504 * @num_scatter_bufs: Number of scatter buffers in the above lists
1505 * @scatter_buf_size: Size of each scatter buffer
1506 * @last_buf_end_offset: Offset to the last entry
1507 * @num_entries: Total entries of all scatter bufs
1508 *
1509 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301510static inline
1511void hal_setup_link_idle_list(hal_soc_handle_t hal_soc_hdl,
1512 qdf_dma_addr_t scatter_bufs_base_paddr[],
1513 void *scatter_bufs_base_vaddr[],
1514 uint32_t num_scatter_bufs,
1515 uint32_t scatter_buf_size,
1516 uint32_t last_buf_end_offset,
1517 uint32_t num_entries)
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301518{
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301519 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301520
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301521 hal_soc->ops->hal_setup_link_idle_list(hal_soc, scatter_bufs_base_paddr,
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +05301522 scatter_bufs_base_vaddr, num_scatter_bufs,
1523 scatter_buf_size, last_buf_end_offset,
1524 num_entries);
1525
1526}
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301527
1528/**
1529 * hal_srng_dump_ring_desc() - Dump ring descriptor info
1530 *
1531 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301532 * @hal_ring_hdl: Source ring pointer
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301533 * @ring_desc: Opaque ring descriptor handle
1534 */
Akshay Kosigia870c612019-07-08 23:10:30 +05301535static inline void hal_srng_dump_ring_desc(hal_soc_handle_t hal_soc_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301536 hal_ring_handle_t hal_ring_hdl,
Akshay Kosigi91c56522019-07-02 11:49:39 +05301537 hal_ring_desc_t ring_desc)
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301538{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301539 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301540
Saket Jha16d84322019-07-11 16:09:41 -07001541 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301542 ring_desc, (srng->entry_size << 2));
1543}
1544
1545/**
1546 * hal_srng_dump_ring() - Dump last 128 descs of the ring
1547 *
1548 * @hal_soc: Opaque HAL SOC handle
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301549 * @hal_ring_hdl: Source ring pointer
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301550 */
Akshay Kosigia870c612019-07-08 23:10:30 +05301551static inline void hal_srng_dump_ring(hal_soc_handle_t hal_soc_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301552 hal_ring_handle_t hal_ring_hdl)
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301553{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +05301554 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301555 uint32_t *desc;
1556 uint32_t tp, i;
1557
1558 tp = srng->u.dst_ring.tp;
1559
1560 for (i = 0; i < 128; i++) {
1561 if (!tp)
1562 tp = srng->ring_size;
1563
1564 desc = &srng->ring_base_vaddr[tp - srng->entry_size];
1565 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP,
nwzhaoea2ffbb2019-01-31 11:43:17 -08001566 QDF_TRACE_LEVEL_DEBUG,
Tallapragada Kalyaneff377a2019-01-09 19:13:19 +05301567 desc, (srng->entry_size << 2));
1568
1569 tp -= srng->entry_size;
1570 }
1571}
1572
Akshay Kosigi8eda31c2019-07-10 14:42:42 +05301573/*
1574 * hal_rxdma_desc_to_hal_ring_desc - API to convert rxdma ring desc
1575 * to opaque dp_ring desc type
1576 * @ring_desc - rxdma ring desc
1577 *
1578 * Return: hal_rxdma_desc_t type
1579 */
1580static inline
1581hal_ring_desc_t hal_rxdma_desc_to_hal_ring_desc(hal_rxdma_desc_t ring_desc)
1582{
1583 return (hal_ring_desc_t)ring_desc;
1584}
Ravi Joshi36f68ad2016-11-09 17:09:47 -08001585#endif /* _HAL_APIH_ */