blob: 1234459d56c3ce87ea9da140eac44524e86bc1c4 [file] [log] [blame]
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -07001/*
Sravan Kumar Kairam4c6a8a92019-01-19 15:55:08 +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 */
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +053018
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +053019#include "hal_hw_headers.h"
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -070020#include "hal_api.h"
Pratik Gandhi034cb7c2017-11-10 16:46:06 +053021#include "target_type.h"
Kiran Venkatappa8524fdd2016-12-02 13:49:30 +053022#include "wcss_version.h"
Pratik Gandhidc82a772018-01-30 18:57:05 +053023#include "qdf_module.h"
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +053024#ifdef QCA_WIFI_QCA8074
25void hal_qca6290_attach(struct hal_soc *hal);
Yun Parkfde6b9e2017-06-26 17:13:11 -070026#endif
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +053027#ifdef QCA_WIFI_QCA8074
28void hal_qca8074_attach(struct hal_soc *hal);
Naveen Rawatba24c482017-05-15 12:02:48 -070029#endif
Balamurugan Mahalingam6a2601a2019-06-03 21:38:12 +053030#if defined(QCA_WIFI_QCA8074V2) || defined(QCA_WIFI_QCA6018)
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +053031void hal_qca8074v2_attach(struct hal_soc *hal);
32#endif
Balamurugan Mahalingam6cf4c272018-07-05 16:50:09 +053033#ifdef QCA_WIFI_QCA6390
34void hal_qca6390_attach(struct hal_soc *hal);
35#endif
Venkata Sharath Chandra Manchalae69c9c22019-09-23 18:31:36 -070036#ifdef QCA_WIFI_QCA6490
37void hal_qca6490_attach(struct hal_soc *hal);
38#endif
Nandha Kishore Easwaran5d3475b2019-06-27 11:38:53 +053039#ifdef QCA_WIFI_QCN9000
40void hal_qcn9000_attach(struct hal_soc *hal);
41#endif
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -070042
Krunal Soni9911b442019-02-22 15:39:03 -080043#ifdef ENABLE_VERBOSE_DEBUG
44bool is_hal_verbose_debug_enabled;
45#endif
46
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -070047/**
Houston Hoffman5141f9d2017-01-05 10:49:17 -080048 * hal_get_srng_ring_id() - get the ring id of a descriped ring
49 * @hal: hal_soc data structure
50 * @ring_type: type enum describing the ring
51 * @ring_num: which ring of the ring type
52 * @mac_id: which mac does the ring belong to (or 0 for non-lmac rings)
53 *
54 * Return: the ring id or -EINVAL if the ring does not exist.
55 */
56static int hal_get_srng_ring_id(struct hal_soc *hal, int ring_type,
57 int ring_num, int mac_id)
58{
59 struct hal_hw_srng_config *ring_config =
60 HAL_SRNG_CONFIG(hal, ring_type);
61 int ring_id;
62
63 if (ring_num >= ring_config->max_rings) {
Aditya Sathishded018e2018-07-02 16:25:21 +053064 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
65 "%s: ring_num exceeded maximum no. of supported rings",
66 __func__);
Manoj Ekbote376116e2017-12-19 10:44:41 -080067 /* TODO: This is a programming error. Assert if this happens */
Houston Hoffman5141f9d2017-01-05 10:49:17 -080068 return -EINVAL;
69 }
70
71 if (ring_config->lmac_ring) {
72 ring_id = ring_config->start_ring_id + ring_num +
73 (mac_id * HAL_MAX_RINGS_PER_LMAC);
74 } else {
75 ring_id = ring_config->start_ring_id + ring_num;
76 }
77
78 return ring_id;
79}
80
81static struct hal_srng *hal_get_srng(struct hal_soc *hal, int ring_id)
82{
83 /* TODO: Should we allocate srng structures dynamically? */
84 return &(hal->srng_list[ring_id]);
85}
86
87#define HP_OFFSET_IN_REG_START 1
88#define OFFSET_FROM_HP_TO_TP 4
Akshay Kosigi8eda31c2019-07-10 14:42:42 +053089static void hal_update_srng_hp_tp_address(struct hal_soc *hal_soc,
Houston Hoffman5141f9d2017-01-05 10:49:17 -080090 int shadow_config_index,
91 int ring_type,
92 int ring_num)
93{
94 struct hal_srng *srng;
Houston Hoffman5141f9d2017-01-05 10:49:17 -080095 int ring_id;
Pramod Simha627278c2018-08-14 11:58:29 -070096 struct hal_hw_srng_config *ring_config =
Akshay Kosigi8eda31c2019-07-10 14:42:42 +053097 HAL_SRNG_CONFIG(hal_soc, ring_type);
Houston Hoffman5141f9d2017-01-05 10:49:17 -080098
99 ring_id = hal_get_srng_ring_id(hal_soc, ring_type, ring_num, 0);
100 if (ring_id < 0)
101 return;
102
103 srng = hal_get_srng(hal_soc, ring_id);
104
Mohit Khanna81179cb2018-08-16 20:50:43 -0700105 if (ring_config->ring_dir == HAL_SRNG_DST_RING) {
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800106 srng->u.dst_ring.tp_addr = SHADOW_REGISTER(shadow_config_index)
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530107 + hal_soc->dev_base_addr;
Mohit Khannaefdae7f2018-11-02 16:19:48 -0700108 hal_debug("tp_addr=%pK dev base addr %pK index %u",
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530109 srng->u.dst_ring.tp_addr, hal_soc->dev_base_addr,
Mohit Khannaefdae7f2018-11-02 16:19:48 -0700110 shadow_config_index);
Mohit Khanna81179cb2018-08-16 20:50:43 -0700111 } else {
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800112 srng->u.src_ring.hp_addr = SHADOW_REGISTER(shadow_config_index)
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530113 + hal_soc->dev_base_addr;
Mohit Khannaefdae7f2018-11-02 16:19:48 -0700114 hal_debug("hp_addr=%pK dev base addr %pK index %u",
115 srng->u.src_ring.hp_addr,
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530116 hal_soc->dev_base_addr, shadow_config_index);
Mohit Khanna81179cb2018-08-16 20:50:43 -0700117 }
118
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800119}
120
121QDF_STATUS hal_set_one_shadow_config(void *hal_soc,
Yun Parkfde6b9e2017-06-26 17:13:11 -0700122 int ring_type,
123 int ring_num)
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800124{
125 uint32_t target_register;
126 struct hal_soc *hal = (struct hal_soc *)hal_soc;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530127 struct hal_hw_srng_config *srng_config = &hal->hw_srng_table[ring_type];
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800128 int shadow_config_index = hal->num_shadow_registers_configured;
129
130 if (shadow_config_index >= MAX_SHADOW_REGISTERS) {
131 QDF_ASSERT(0);
132 return QDF_STATUS_E_RESOURCES;
133 }
134
135 hal->num_shadow_registers_configured++;
136
137 target_register = srng_config->reg_start[HP_OFFSET_IN_REG_START];
138 target_register += (srng_config->reg_size[HP_OFFSET_IN_REG_START]
139 *ring_num);
140
141 /* if the ring is a dst ring, we need to shadow the tail pointer */
142 if (srng_config->ring_dir == HAL_SRNG_DST_RING)
143 target_register += OFFSET_FROM_HP_TO_TP;
144
145 hal->shadow_config[shadow_config_index].addr = target_register;
146
147 /* update hp/tp addr in the hal_soc structure*/
148 hal_update_srng_hp_tp_address(hal_soc, shadow_config_index, ring_type,
149 ring_num);
150
Mohit Khannaefdae7f2018-11-02 16:19:48 -0700151 hal_debug("target_reg %x, shadow register 0x%x shadow_index 0x%x, ring_type %d, ring num %d",
152 target_register,
Mohit Khanna81179cb2018-08-16 20:50:43 -0700153 SHADOW_REGISTER(shadow_config_index),
154 shadow_config_index,
155 ring_type, ring_num);
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800156
157 return QDF_STATUS_SUCCESS;
158}
159
Sathish Kumar86876492018-08-27 13:39:20 +0530160qdf_export_symbol(hal_set_one_shadow_config);
161
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800162QDF_STATUS hal_construct_shadow_config(void *hal_soc)
163{
164 int ring_type, ring_num;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530165 struct hal_soc *hal = (struct hal_soc *)hal_soc;
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800166
167 for (ring_type = 0; ring_type < MAX_RING_TYPES; ring_type++) {
168 struct hal_hw_srng_config *srng_config =
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530169 &hal->hw_srng_table[ring_type];
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800170
171 if (ring_type == CE_SRC ||
172 ring_type == CE_DST ||
173 ring_type == CE_DST_STATUS)
174 continue;
175
176 if (srng_config->lmac_ring)
177 continue;
178
179 for (ring_num = 0; ring_num < srng_config->max_rings;
180 ring_num++)
181 hal_set_one_shadow_config(hal_soc, ring_type, ring_num);
182 }
183
184 return QDF_STATUS_SUCCESS;
185}
186
Sathish Kumar86876492018-08-27 13:39:20 +0530187qdf_export_symbol(hal_construct_shadow_config);
188
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800189void hal_get_shadow_config(void *hal_soc,
190 struct pld_shadow_reg_v2_cfg **shadow_config,
191 int *num_shadow_registers_configured)
192{
193 struct hal_soc *hal = (struct hal_soc *)hal_soc;
194
195 *shadow_config = hal->shadow_config;
196 *num_shadow_registers_configured =
197 hal->num_shadow_registers_configured;
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800198}
199
Sathish Kumar86876492018-08-27 13:39:20 +0530200qdf_export_symbol(hal_get_shadow_config);
201
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800202
203static void hal_validate_shadow_register(struct hal_soc *hal,
204 uint32_t *destination,
205 uint32_t *shadow_address)
206{
207 unsigned int index;
208 uint32_t *shadow_0_offset = SHADOW_REGISTER(0) + hal->dev_base_addr;
209 int destination_ba_offset =
210 ((char *)destination) - (char *)hal->dev_base_addr;
211
212 index = shadow_address - shadow_0_offset;
213
sumedh baikady668d8672018-03-19 17:48:41 -0700214 if (index >= MAX_SHADOW_REGISTERS) {
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800215 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530216 "%s: index %x out of bounds", __func__, index);
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800217 goto error;
218 } else if (hal->shadow_config[index].addr != destination_ba_offset) {
219 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530220 "%s: sanity check failure, expected %x, found %x",
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800221 __func__, destination_ba_offset,
222 hal->shadow_config[index].addr);
223 goto error;
224 }
225 return;
226error:
Jeff Johnson05503ee2017-09-18 10:13:10 -0700227 qdf_print("%s: baddr %pK, desination %pK, shadow_address %pK s0offset %pK index %x",
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800228 __func__, hal->dev_base_addr, destination, shadow_address,
229 shadow_0_offset, index);
230 QDF_BUG(0);
231 return;
232}
233
Houston Hoffman61dad492017-04-07 17:09:34 -0700234static void hal_target_based_configure(struct hal_soc *hal)
235{
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530236 switch (hal->target_type) {
237#ifdef QCA_WIFI_QCA6290
Houston Hoffman61dad492017-04-07 17:09:34 -0700238 case TARGET_TYPE_QCA6290:
239 hal->use_register_windowing = true;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530240 hal_qca6290_attach(hal);
Houston Hoffman61dad492017-04-07 17:09:34 -0700241 break;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530242#endif
Balamurugan Mahalingam6cf4c272018-07-05 16:50:09 +0530243#ifdef QCA_WIFI_QCA6390
244 case TARGET_TYPE_QCA6390:
245 hal->use_register_windowing = true;
246 hal_qca6390_attach(hal);
247 break;
248#endif
Venkata Sharath Chandra Manchalae69c9c22019-09-23 18:31:36 -0700249#ifdef QCA_WIFI_QCA6490
250 case TARGET_TYPE_QCA6490:
251 hal->use_register_windowing = true;
252 hal_qca6490_attach(hal);
253 break;
254#endif
Akshay Kosigi283e2352019-06-19 14:33:47 +0530255#if defined(QCA_WIFI_QCA8074) && defined(WIFI_TARGET_TYPE_3_0)
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530256 case TARGET_TYPE_QCA8074:
257 hal_qca8074_attach(hal);
258 break;
259#endif
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +0530260
Akshay Kosigi283e2352019-06-19 14:33:47 +0530261#if defined(QCA_WIFI_QCA8074V2)
Balamurugan Mahalingam5d806412018-07-30 18:04:15 +0530262 case TARGET_TYPE_QCA8074V2:
263 hal_qca8074v2_attach(hal);
264 break;
265#endif
Basamma Yakkanahalli5f7cfd42018-11-02 15:52:37 +0530266
Akshay Kosigi283e2352019-06-19 14:33:47 +0530267#if defined(QCA_WIFI_QCA6018)
Basamma Yakkanahalli5f7cfd42018-11-02 15:52:37 +0530268 case TARGET_TYPE_QCA6018:
Balamurugan Mahalingam6a2601a2019-06-03 21:38:12 +0530269 hal_qca8074v2_attach(hal);
Basamma Yakkanahalli5f7cfd42018-11-02 15:52:37 +0530270 break;
271#endif
Nandha Kishore Easwaran5d3475b2019-06-27 11:38:53 +0530272
273#ifdef QCA_WIFI_QCN9000
274 case TARGET_TYPE_QCN9000:
275 hal->use_register_windowing = true;
276 hal_qcn9000_attach(hal);
277 break;
278#endif
Houston Hoffman61dad492017-04-07 17:09:34 -0700279 default:
280 break;
281 }
282}
283
Akshay Kosigi6a206752019-06-10 23:14:52 +0530284uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl)
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530285{
Akshay Kosigi6a206752019-06-10 23:14:52 +0530286 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530287 struct hif_target_info *tgt_info =
Akshay Kosigi6a206752019-06-10 23:14:52 +0530288 hif_get_target_info_handle(hal_soc->hif_handle);
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530289
290 return tgt_info->target_type;
291}
292
293qdf_export_symbol(hal_get_target_type);
294
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800295/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -0700296 * hal_attach - Initialize HAL layer
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700297 * @hif_handle: Opaque HIF handle
298 * @qdf_dev: QDF device
299 *
300 * Return: Opaque HAL SOC handle
301 * NULL on failure (if given ring is not available)
302 *
303 * This function should be called as part of HIF initialization (for accessing
304 * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle()
305 *
306 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530307void *hal_attach(struct hif_opaque_softc *hif_handle, qdf_device_t qdf_dev)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700308{
309 struct hal_soc *hal;
310 int i;
311
312 hal = qdf_mem_malloc(sizeof(*hal));
313
314 if (!hal) {
315 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530316 "%s: hal_soc allocation failed", __func__);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700317 goto fail0;
318 }
Karunakar Dasinenia46da422019-06-19 10:37:17 -0700319 qdf_minidump_log(hal, sizeof(*hal), "hal_soc");
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700320 hal->hif_handle = hif_handle;
321 hal->dev_base_addr = hif_get_dev_ba(hif_handle);
322 hal->qdf_dev = qdf_dev;
323 hal->shadow_rdptr_mem_vaddr = (uint32_t *)qdf_mem_alloc_consistent(
Kiran Venkatappa67685092016-10-19 11:57:37 +0530324 qdf_dev, qdf_dev->dev, sizeof(*(hal->shadow_rdptr_mem_vaddr)) *
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700325 HAL_SRNG_ID_MAX, &(hal->shadow_rdptr_mem_paddr));
326 if (!hal->shadow_rdptr_mem_paddr) {
327 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530328 "%s: hal->shadow_rdptr_mem_paddr allocation failed",
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700329 __func__);
330 goto fail1;
331 }
Sravan Kumar Kairam4c6a8a92019-01-19 15:55:08 +0530332 qdf_mem_zero(hal->shadow_rdptr_mem_vaddr,
333 sizeof(*(hal->shadow_rdptr_mem_vaddr)) * HAL_SRNG_ID_MAX);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700334
335 hal->shadow_wrptr_mem_vaddr =
Kiran Venkatappa67685092016-10-19 11:57:37 +0530336 (uint32_t *)qdf_mem_alloc_consistent(qdf_dev, qdf_dev->dev,
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700337 sizeof(*(hal->shadow_wrptr_mem_vaddr)) * HAL_MAX_LMAC_RINGS,
338 &(hal->shadow_wrptr_mem_paddr));
339 if (!hal->shadow_wrptr_mem_vaddr) {
340 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530341 "%s: hal->shadow_wrptr_mem_vaddr allocation failed",
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700342 __func__);
343 goto fail2;
344 }
Sravan Kumar Kairam4c6a8a92019-01-19 15:55:08 +0530345 qdf_mem_zero(hal->shadow_wrptr_mem_vaddr,
346 sizeof(*(hal->shadow_wrptr_mem_vaddr)) * HAL_MAX_LMAC_RINGS);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700347
348 for (i = 0; i < HAL_SRNG_ID_MAX; i++) {
349 hal->srng_list[i].initialized = 0;
350 hal->srng_list[i].ring_id = i;
351 }
352
Houston Hoffman61dad492017-04-07 17:09:34 -0700353 qdf_spinlock_create(&hal->register_access_lock);
354 hal->register_window = 0;
Akshay Kosigi6a206752019-06-10 23:14:52 +0530355 hal->target_type = hal_get_target_type(hal_soc_to_hal_soc_handle(hal));
Houston Hoffman61dad492017-04-07 17:09:34 -0700356
357 hal_target_based_configure(hal);
358
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700359 return (void *)hal;
360
361fail2:
Houston Hoffmane1961b62016-10-17 19:29:55 -0700362 qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700363 sizeof(*(hal->shadow_rdptr_mem_vaddr)) * HAL_SRNG_ID_MAX,
364 hal->shadow_rdptr_mem_vaddr, hal->shadow_rdptr_mem_paddr, 0);
365fail1:
366 qdf_mem_free(hal);
367fail0:
368 return NULL;
369}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530370qdf_export_symbol(hal_attach);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700371
372/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -0700373 * hal_mem_info - Retrieve hal memory base address
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530374 *
375 * @hal_soc: Opaque HAL SOC handle
376 * @mem: pointer to structure to be updated with hal mem info
377 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530378void hal_get_meminfo(hal_soc_handle_t hal_soc_hdl, struct hal_mem_info *mem)
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530379{
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530380 struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530381 mem->dev_base_addr = (void *)hal->dev_base_addr;
382 mem->shadow_rdptr_mem_vaddr = (void *)hal->shadow_rdptr_mem_vaddr;
383 mem->shadow_wrptr_mem_vaddr = (void *)hal->shadow_wrptr_mem_vaddr;
384 mem->shadow_rdptr_mem_paddr = (void *)hal->shadow_rdptr_mem_paddr;
385 mem->shadow_wrptr_mem_paddr = (void *)hal->shadow_wrptr_mem_paddr;
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530386 hif_read_phy_mem_base((void *)hal->hif_handle,
387 (qdf_dma_addr_t *)&mem->dev_base_paddr);
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530388 return;
389}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530390qdf_export_symbol(hal_get_meminfo);
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530391
392/**
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700393 * hal_detach - Detach HAL layer
394 * @hal_soc: HAL SOC handle
395 *
396 * Return: Opaque HAL SOC handle
397 * NULL on failure (if given ring is not available)
398 *
399 * This function should be called as part of HIF initialization (for accessing
400 * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle()
401 *
402 */
403extern void hal_detach(void *hal_soc)
404{
405 struct hal_soc *hal = (struct hal_soc *)hal_soc;
406
Houston Hoffmane1961b62016-10-17 19:29:55 -0700407 qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev,
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700408 sizeof(*(hal->shadow_rdptr_mem_vaddr)) * HAL_SRNG_ID_MAX,
409 hal->shadow_rdptr_mem_vaddr, hal->shadow_rdptr_mem_paddr, 0);
Houston Hoffmane1961b62016-10-17 19:29:55 -0700410 qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev,
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700411 sizeof(*(hal->shadow_wrptr_mem_vaddr)) * HAL_MAX_LMAC_RINGS,
412 hal->shadow_wrptr_mem_vaddr, hal->shadow_wrptr_mem_paddr, 0);
Karunakar Dasinenia46da422019-06-19 10:37:17 -0700413 qdf_minidump_remove(hal);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700414 qdf_mem_free(hal);
415
416 return;
417}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530418qdf_export_symbol(hal_detach);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700419
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700420
421/**
Houston Hoffman74109122016-10-21 14:58:34 -0700422 * hal_ce_dst_setup - Initialize CE destination ring registers
423 * @hal_soc: HAL SOC handle
424 * @srng: SRNG ring pointer
425 */
426static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng,
427 int ring_num)
428{
429 uint32_t reg_val = 0;
430 uint32_t reg_addr;
431 struct hal_hw_srng_config *ring_config =
432 HAL_SRNG_CONFIG(hal, CE_DST);
433
434 /* set DEST_MAX_LENGTH according to ce assignment */
435 reg_addr = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_ADDR(
436 ring_config->reg_start[R0_INDEX] +
437 (ring_num * ring_config->reg_size[R0_INDEX]));
438
439 reg_val = HAL_REG_READ(hal, reg_addr);
440 reg_val &= ~HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK;
441 reg_val |= srng->u.dst_ring.max_buffer_length &
442 HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK;
443 HAL_REG_WRITE(hal, reg_addr, reg_val);
444}
445
446/**
jiad09526ac2019-04-12 17:42:40 +0800447 * hal_reo_read_write_ctrl_ix - Read or write REO_DESTINATION_RING_CTRL_IX
Yun Parkfde6b9e2017-06-26 17:13:11 -0700448 * @hal: HAL SOC handle
jiad09526ac2019-04-12 17:42:40 +0800449 * @read: boolean value to indicate if read or write
450 * @ix0: pointer to store IX0 reg value
451 * @ix1: pointer to store IX1 reg value
452 * @ix2: pointer to store IX2 reg value
453 * @ix3: pointer to store IX3 reg value
Yun Parkfde6b9e2017-06-26 17:13:11 -0700454 */
Akshay Kosigi6a206752019-06-10 23:14:52 +0530455void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read,
456 uint32_t *ix0, uint32_t *ix1,
457 uint32_t *ix2, uint32_t *ix3)
Yun Parkfde6b9e2017-06-26 17:13:11 -0700458{
jiad09526ac2019-04-12 17:42:40 +0800459 uint32_t reg_offset;
Akshay Kosigi6a206752019-06-10 23:14:52 +0530460 struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
jiad09526ac2019-04-12 17:42:40 +0800461
462 if (read) {
463 if (ix0) {
464 reg_offset =
465 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR(
466 SEQ_WCSS_UMAC_REO_REG_OFFSET);
467 *ix0 = HAL_REG_READ(hal, reg_offset);
468 }
469
470 if (ix1) {
471 reg_offset =
472 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1_ADDR(
473 SEQ_WCSS_UMAC_REO_REG_OFFSET);
474 *ix1 = HAL_REG_READ(hal, reg_offset);
475 }
476
477 if (ix2) {
478 reg_offset =
479 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
480 SEQ_WCSS_UMAC_REO_REG_OFFSET);
481 *ix2 = HAL_REG_READ(hal, reg_offset);
482 }
483
484 if (ix3) {
485 reg_offset =
486 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
487 SEQ_WCSS_UMAC_REO_REG_OFFSET);
488 *ix3 = HAL_REG_READ(hal, reg_offset);
489 }
490 } else {
491 if (ix0) {
492 reg_offset =
493 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR(
494 SEQ_WCSS_UMAC_REO_REG_OFFSET);
Jinwei Chen99ae1c12019-11-01 19:43:30 +0800495 HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix0);
jiad09526ac2019-04-12 17:42:40 +0800496 }
497
498 if (ix1) {
499 reg_offset =
500 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1_ADDR(
501 SEQ_WCSS_UMAC_REO_REG_OFFSET);
502 HAL_REG_WRITE(hal, reg_offset, *ix1);
503 }
504
505 if (ix2) {
506 reg_offset =
507 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
508 SEQ_WCSS_UMAC_REO_REG_OFFSET);
509 HAL_REG_WRITE(hal, reg_offset, *ix2);
510 }
511
512 if (ix3) {
513 reg_offset =
514 HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
515 SEQ_WCSS_UMAC_REO_REG_OFFSET);
516 HAL_REG_WRITE(hal, reg_offset, *ix3);
517 }
518 }
Yun Parkfde6b9e2017-06-26 17:13:11 -0700519}
520
521/**
Yun Park601d0d82017-08-28 21:49:31 -0700522 * hal_srng_dst_set_hp_paddr() - Set physical address to dest ring head pointer
523 * @srng: sring pointer
Yun Parkfde6b9e2017-06-26 17:13:11 -0700524 * @paddr: physical address
525 */
Yun Park601d0d82017-08-28 21:49:31 -0700526void hal_srng_dst_set_hp_paddr(struct hal_srng *srng,
527 uint64_t paddr)
Yun Parkfde6b9e2017-06-26 17:13:11 -0700528{
Yun Park601d0d82017-08-28 21:49:31 -0700529 SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB,
Yun Parkfde6b9e2017-06-26 17:13:11 -0700530 paddr & 0xffffffff);
Yun Park601d0d82017-08-28 21:49:31 -0700531 SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB,
Yun Parkfde6b9e2017-06-26 17:13:11 -0700532 paddr >> 32);
533}
Yun Park601d0d82017-08-28 21:49:31 -0700534
535/**
536 * hal_srng_dst_init_hp() - Initilaize destination ring head pointer
537 * @srng: sring pointer
538 * @vaddr: virtual address
539 */
540void hal_srng_dst_init_hp(struct hal_srng *srng,
541 uint32_t *vaddr)
542{
Mohit Khanna81179cb2018-08-16 20:50:43 -0700543 if (!srng)
544 return;
545
Yun Park601d0d82017-08-28 21:49:31 -0700546 srng->u.dst_ring.hp_addr = vaddr;
547 SRNG_DST_REG_WRITE(srng, HP, srng->u.dst_ring.cached_hp);
Yun Park601d0d82017-08-28 21:49:31 -0700548
Mohit Khanna81179cb2018-08-16 20:50:43 -0700549 if (vaddr) {
550 *srng->u.dst_ring.hp_addr = srng->u.dst_ring.cached_hp;
551 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
552 "hp_addr=%pK, cached_hp=%d, hp=%d",
553 (void *)srng->u.dst_ring.hp_addr,
554 srng->u.dst_ring.cached_hp,
555 *srng->u.dst_ring.hp_addr);
556 }
Yun Park601d0d82017-08-28 21:49:31 -0700557}
558
Yun Parkfde6b9e2017-06-26 17:13:11 -0700559/**
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700560 * hal_srng_hw_init - Private function to initialize SRNG HW
561 * @hal_soc: HAL SOC handle
562 * @srng: SRNG ring pointer
563 */
564static inline void hal_srng_hw_init(struct hal_soc *hal,
565 struct hal_srng *srng)
566{
567 if (srng->ring_dir == HAL_SRNG_SRC_RING)
568 hal_srng_src_hw_init(hal, srng);
569 else
570 hal_srng_dst_hw_init(hal, srng);
571}
572
Houston Hoffmanf60a3482017-01-31 10:45:07 -0800573#ifdef CONFIG_SHADOW_V2
574#define ignore_shadow false
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800575#define CHECK_SHADOW_REGISTERS true
Houston Hoffmanf60a3482017-01-31 10:45:07 -0800576#else
577#define ignore_shadow true
578#define CHECK_SHADOW_REGISTERS false
579#endif
580
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700581/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -0700582 * hal_srng_setup - Initialize HW SRNG ring.
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700583 * @hal_soc: Opaque HAL SOC handle
584 * @ring_type: one of the types from hal_ring_type
585 * @ring_num: Ring number if there are multiple rings of same type (staring
586 * from 0)
587 * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings
588 * @ring_params: SRNG ring params in hal_srng_params structure.
589
590 * Callers are expected to allocate contiguous ring memory of size
591 * 'num_entries * entry_size' bytes and pass the physical and virtual base
592 * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in
593 * hal_srng_params structure. Ring base address should be 8 byte aligned
594 * and size of each ring entry should be queried using the API
595 * hal_srng_get_entrysize
596 *
597 * Return: Opaque pointer to ring on success
598 * NULL on failure (if given ring is not available)
599 */
600void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
601 int mac_id, struct hal_srng_params *ring_params)
602{
603 int ring_id;
604 struct hal_soc *hal = (struct hal_soc *)hal_soc;
605 struct hal_srng *srng;
606 struct hal_hw_srng_config *ring_config =
607 HAL_SRNG_CONFIG(hal, ring_type);
608 void *dev_base_addr;
609 int i;
610
Dhanashri Atre0215a3e2017-02-06 18:27:53 -0800611 ring_id = hal_get_srng_ring_id(hal_soc, ring_type, ring_num, mac_id);
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800612 if (ring_id < 0)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700613 return NULL;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700614
Krunal Soni9911b442019-02-22 15:39:03 -0800615 hal_verbose_debug("mac_id %d ring_id %d", mac_id, ring_id);
Dhanashri Atred4032ab2017-01-17 15:05:41 -0800616
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800617 srng = hal_get_srng(hal_soc, ring_id);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700618
619 if (srng->initialized) {
Krunal Soni9911b442019-02-22 15:39:03 -0800620 hal_verbose_debug("Ring (ring_type, ring_num) already initialized");
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700621 return NULL;
622 }
623
624 dev_base_addr = hal->dev_base_addr;
625 srng->ring_id = ring_id;
626 srng->ring_dir = ring_config->ring_dir;
627 srng->ring_base_paddr = ring_params->ring_base_paddr;
628 srng->ring_base_vaddr = ring_params->ring_base_vaddr;
629 srng->entry_size = ring_config->entry_size;
630 srng->num_entries = ring_params->num_entries;
631 srng->ring_size = srng->num_entries * srng->entry_size;
632 srng->ring_size_mask = srng->ring_size - 1;
633 srng->msi_addr = ring_params->msi_addr;
634 srng->msi_data = ring_params->msi_data;
635 srng->intr_timer_thres_us = ring_params->intr_timer_thres_us;
636 srng->intr_batch_cntr_thres_entries =
637 ring_params->intr_batch_cntr_thres_entries;
Houston Hoffman8bbc9902017-04-10 14:09:51 -0700638 srng->hal_soc = hal_soc;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700639
640 for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) {
641 srng->hwreg_base[i] = dev_base_addr + ring_config->reg_start[i]
642 + (ring_num * ring_config->reg_size[i]);
643 }
644
645 /* Zero out the entire ring memory */
646 qdf_mem_zero(srng->ring_base_vaddr, (srng->entry_size *
647 srng->num_entries) << 2);
648
649 srng->flags = ring_params->flags;
650#ifdef BIG_ENDIAN_HOST
651 /* TODO: See if we should we get these flags from caller */
652 srng->flags |= HAL_SRNG_DATA_TLV_SWAP;
653 srng->flags |= HAL_SRNG_MSI_SWAP;
654 srng->flags |= HAL_SRNG_RING_PTR_SWAP;
655#endif
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800656
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700657 if (srng->ring_dir == HAL_SRNG_SRC_RING) {
658 srng->u.src_ring.hp = 0;
659 srng->u.src_ring.reap_hp = srng->ring_size -
660 srng->entry_size;
661 srng->u.src_ring.tp_addr =
662 &(hal->shadow_rdptr_mem_vaddr[ring_id]);
Karunakar Dasineni335bbd12017-06-13 19:23:33 -0700663 srng->u.src_ring.low_threshold =
664 ring_params->low_threshold * srng->entry_size;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700665 if (ring_config->lmac_ring) {
666 /* For LMAC rings, head pointer updates will be done
667 * through FW by writing to a shared memory location
668 */
669 srng->u.src_ring.hp_addr =
670 &(hal->shadow_wrptr_mem_vaddr[ring_id -
671 HAL_SRNG_LMAC1_ID_START]);
672 srng->flags |= HAL_SRNG_LMAC_RING;
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800673 } else if (ignore_shadow || (srng->u.src_ring.hp_addr == 0)) {
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700674 srng->u.src_ring.hp_addr = SRNG_SRC_ADDR(srng, HP);
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800675
676 if (CHECK_SHADOW_REGISTERS) {
677 QDF_TRACE(QDF_MODULE_ID_TXRX,
Yun Parkfde6b9e2017-06-26 17:13:11 -0700678 QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530679 "%s: Ring (%d, %d) missing shadow config",
Yun Parkfde6b9e2017-06-26 17:13:11 -0700680 __func__, ring_type, ring_num);
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800681 }
682 } else {
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800683 hal_validate_shadow_register(hal,
684 SRNG_SRC_ADDR(srng, HP),
685 srng->u.src_ring.hp_addr);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700686 }
687 } else {
688 /* During initialization loop count in all the descriptors
689 * will be set to zero, and HW will set it to 1 on completing
690 * descriptor update in first loop, and increments it by 1 on
691 * subsequent loops (loop count wraps around after reaching
692 * 0xffff). The 'loop_cnt' in SW ring state is the expected
693 * loop count in descriptors updated by HW (to be processed
694 * by SW).
695 */
696 srng->u.dst_ring.loop_cnt = 1;
697 srng->u.dst_ring.tp = 0;
698 srng->u.dst_ring.hp_addr =
699 &(hal->shadow_rdptr_mem_vaddr[ring_id]);
700 if (ring_config->lmac_ring) {
701 /* For LMAC rings, tail pointer updates will be done
702 * through FW by writing to a shared memory location
703 */
704 srng->u.dst_ring.tp_addr =
705 &(hal->shadow_wrptr_mem_vaddr[ring_id -
706 HAL_SRNG_LMAC1_ID_START]);
707 srng->flags |= HAL_SRNG_LMAC_RING;
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800708 } else if (ignore_shadow || srng->u.dst_ring.tp_addr == 0) {
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700709 srng->u.dst_ring.tp_addr = SRNG_DST_ADDR(srng, TP);
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800710
711 if (CHECK_SHADOW_REGISTERS) {
712 QDF_TRACE(QDF_MODULE_ID_TXRX,
Yun Parkfde6b9e2017-06-26 17:13:11 -0700713 QDF_TRACE_LEVEL_ERROR,
Aditya Sathishded018e2018-07-02 16:25:21 +0530714 "%s: Ring (%d, %d) missing shadow config",
Yun Parkfde6b9e2017-06-26 17:13:11 -0700715 __func__, ring_type, ring_num);
Houston Hoffman5141f9d2017-01-05 10:49:17 -0800716 }
717 } else {
Houston Hoffmane3c1a372017-01-25 11:09:26 -0800718 hal_validate_shadow_register(hal,
719 SRNG_DST_ADDR(srng, TP),
720 srng->u.dst_ring.tp_addr);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700721 }
722 }
723
Houston Hoffman74109122016-10-21 14:58:34 -0700724 if (!(ring_config->lmac_ring)) {
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700725 hal_srng_hw_init(hal, srng);
726
Houston Hoffman74109122016-10-21 14:58:34 -0700727 if (ring_type == CE_DST) {
728 srng->u.dst_ring.max_buffer_length = ring_params->max_buffer_length;
729 hal_ce_dst_setup(hal, srng, ring_num);
730 }
731 }
732
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700733 SRNG_LOCK_INIT(&srng->lock);
734
Sravan Kumar Kairam78b01a12019-09-16 14:22:55 +0530735 srng->srng_event = 0;
736
Houston Hoffman648a9182017-05-21 23:27:50 -0700737 srng->initialized = true;
738
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700739 return (void *)srng;
740}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530741qdf_export_symbol(hal_srng_setup);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700742
743/**
744 * hal_srng_cleanup - Deinitialize HW SRNG ring.
745 * @hal_soc: Opaque HAL SOC handle
746 * @hal_srng: Opaque HAL SRNG pointer
747 */
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530748void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700749{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530750 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700751 SRNG_LOCK_DESTROY(&srng->lock);
752 srng->initialized = 0;
753}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530754qdf_export_symbol(hal_srng_cleanup);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700755
756/**
757 * hal_srng_get_entrysize - Returns size of ring entry in bytes
758 * @hal_soc: Opaque HAL SOC handle
759 * @ring_type: one of the types from hal_ring_type
760 *
761 */
762uint32_t hal_srng_get_entrysize(void *hal_soc, int ring_type)
763{
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530764 struct hal_soc *hal = (struct hal_soc *)hal_soc;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700765 struct hal_hw_srng_config *ring_config =
766 HAL_SRNG_CONFIG(hal, ring_type);
767 return ring_config->entry_size << 2;
768}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530769qdf_export_symbol(hal_srng_get_entrysize);
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700770
771/**
Karunakar Dasinenid0ea21f2017-01-31 22:58:15 -0800772 * hal_srng_max_entries - Returns maximum possible number of ring entries
773 * @hal_soc: Opaque HAL SOC handle
774 * @ring_type: one of the types from hal_ring_type
775 *
776 * Return: Maximum number of entries for the given ring_type
777 */
778uint32_t hal_srng_max_entries(void *hal_soc, int ring_type)
779{
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530780 struct hal_soc *hal = (struct hal_soc *)hal_soc;
Venkata Sharath Chandra Manchala9a59bd62018-06-14 16:53:29 -0700781 struct hal_hw_srng_config *ring_config =
782 HAL_SRNG_CONFIG(hal, ring_type);
783
784 return ring_config->max_size / ring_config->entry_size;
Karunakar Dasinenid0ea21f2017-01-31 22:58:15 -0800785}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530786qdf_export_symbol(hal_srng_max_entries);
Karunakar Dasinenid0ea21f2017-01-31 22:58:15 -0800787
Houston Hoffman648a9182017-05-21 23:27:50 -0700788enum hal_srng_dir hal_srng_get_dir(void *hal_soc, int ring_type)
789{
Balamurugan Mahalingamd0159642018-07-11 15:02:29 +0530790 struct hal_soc *hal = (struct hal_soc *)hal_soc;
Houston Hoffman648a9182017-05-21 23:27:50 -0700791 struct hal_hw_srng_config *ring_config =
792 HAL_SRNG_CONFIG(hal, ring_type);
793
794 return ring_config->ring_dir;
795}
796
Karunakar Dasinenid0ea21f2017-01-31 22:58:15 -0800797/**
Kai Liub8e12412018-01-12 16:52:26 +0800798 * hal_srng_dump - Dump ring status
799 * @srng: hal srng pointer
800 */
801void hal_srng_dump(struct hal_srng *srng)
802{
803 if (srng->ring_dir == HAL_SRNG_SRC_RING) {
Venkata Sharath Chandra Manchalaea6518b2019-10-25 18:03:25 -0700804 hal_debug("=== SRC RING %d ===", srng->ring_id);
805 hal_debug("hp %u, reap_hp %u, tp %u, cached tp %u",
Kai Liub8e12412018-01-12 16:52:26 +0800806 srng->u.src_ring.hp,
807 srng->u.src_ring.reap_hp,
808 *srng->u.src_ring.tp_addr,
809 srng->u.src_ring.cached_tp);
810 } else {
Venkata Sharath Chandra Manchalaea6518b2019-10-25 18:03:25 -0700811 hal_debug("=== DST RING %d ===", srng->ring_id);
812 hal_debug("tp %u, hp %u, cached tp %u, loop_cnt %u",
Kai Liub8e12412018-01-12 16:52:26 +0800813 srng->u.dst_ring.tp,
814 *srng->u.dst_ring.hp_addr,
815 srng->u.dst_ring.cached_hp,
816 srng->u.dst_ring.loop_cnt);
817 }
818}
819
820/**
Jeff Johnsonf7aed492018-05-12 11:14:55 -0700821 * hal_get_srng_params - Retrieve SRNG parameters for a given ring from HAL
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700822 *
823 * @hal_soc: Opaque HAL SOC handle
824 * @hal_ring: Ring pointer (Source or Destination ring)
825 * @ring_params: SRNG parameters will be returned through this structure
826 */
Akshay Kosigi8eda31c2019-07-10 14:42:42 +0530827extern void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl,
828 hal_ring_handle_t hal_ring_hdl,
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530829 struct hal_srng_params *ring_params)
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700830{
Akshay Kosigi0bca9fb2019-06-27 15:26:13 +0530831 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530832 int i =0;
833 ring_params->ring_id = srng->ring_id;
834 ring_params->ring_dir = srng->ring_dir;
835 ring_params->entry_size = srng->entry_size;
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700836
837 ring_params->ring_base_paddr = srng->ring_base_paddr;
838 ring_params->ring_base_vaddr = srng->ring_base_vaddr;
839 ring_params->num_entries = srng->num_entries;
840 ring_params->msi_addr = srng->msi_addr;
841 ring_params->msi_data = srng->msi_data;
842 ring_params->intr_timer_thres_us = srng->intr_timer_thres_us;
843 ring_params->intr_batch_cntr_thres_entries =
844 srng->intr_batch_cntr_thres_entries;
845 ring_params->low_threshold = srng->u.src_ring.low_threshold;
846 ring_params->flags = srng->flags;
Dhanashri Atre7351d172016-10-12 13:08:09 -0700847 ring_params->ring_id = srng->ring_id;
Bharat Kumar M9e22d3d2017-05-08 16:09:32 +0530848 for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++)
849 ring_params->hwreg_base[i] = srng->hwreg_base[i];
Karunakar Dasineni8fbfeea2016-08-31 14:43:27 -0700850}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530851qdf_export_symbol(hal_get_srng_params);