1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief API definitions for the Bus Abstraction Layer (BAL) of the Wi-Fi
9 * driver.
10 */
11
12
13 #include "bal_api.h"
14
15 #ifdef NRF_WIFI_LOW_POWER
16 #ifdef NRF_WIFI_LOW_POWER_DBG
17 #include "pal.h"
18
nrf_wifi_rpu_bal_sleep_chk(struct nrf_wifi_bal_dev_ctx * bal_ctx,unsigned long addr)19 static void nrf_wifi_rpu_bal_sleep_chk(struct nrf_wifi_bal_dev_ctx *bal_ctx,
20 unsigned long addr)
21 {
22 unsigned int sleep_reg_val = 0;
23 unsigned int rpu_ps_state_mask = 0;
24 unsigned long sleep_reg_addr = 0;
25
26 if (!bal_ctx->rpu_fw_booted)
27 return;
28
29 sleep_reg_addr = pal_rpu_ps_ctrl_reg_addr_get();
30
31 if (sleep_reg_addr == addr)
32 return;
33
34 sleep_reg_val = bal_ctx->bpriv->ops->read_word(bal_ctx->bus_dev_ctx,
35 sleep_reg_addr);
36
37 rpu_ps_state_mask = ((1 << RPU_REG_BIT_PS_STATE) |
38 (1 << RPU_REG_BIT_READY_STATE));
39
40 if ((sleep_reg_val & rpu_ps_state_mask) != rpu_ps_state_mask) {
41 nrf_wifi_osal_log_err("%s:RPU accessed when it is not ready !!! (Reg val = 0x%X)",
42 __func__,
43 sleep_reg_val);
44 }
45 }
46 #endif /* NRF_WIFI_LOW_POWER_DBG */
47 #endif /* NRF_WIFI_LOW_POWER */
48
49
nrf_wifi_bal_dev_add(struct nrf_wifi_bal_priv * bpriv,void * hal_dev_ctx)50 struct nrf_wifi_bal_dev_ctx *nrf_wifi_bal_dev_add(struct nrf_wifi_bal_priv *bpriv,
51 void *hal_dev_ctx)
52 {
53 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
54 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
55
56 bal_dev_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*bal_dev_ctx));
57
58 if (!bal_dev_ctx) {
59 nrf_wifi_osal_log_err("%s: Unable to allocate bal_dev_ctx", __func__);
60 goto out;
61 }
62
63 bal_dev_ctx->bpriv = bpriv;
64 bal_dev_ctx->hal_dev_ctx = hal_dev_ctx;
65
66 bal_dev_ctx->bus_dev_ctx = bpriv->ops->dev_add(bpriv->bus_priv,
67 bal_dev_ctx);
68
69 if (!bal_dev_ctx->bus_dev_ctx) {
70 nrf_wifi_osal_log_err("%s: Bus dev_add failed", __func__);
71 goto out;
72 }
73
74 status = NRF_WIFI_STATUS_SUCCESS;
75 out:
76 if (status != NRF_WIFI_STATUS_SUCCESS) {
77 if (bal_dev_ctx) {
78 nrf_wifi_osal_mem_free(bal_dev_ctx);
79 bal_dev_ctx = NULL;
80 }
81 }
82
83 return bal_dev_ctx;
84 }
85
86
nrf_wifi_bal_dev_rem(struct nrf_wifi_bal_dev_ctx * bal_dev_ctx)87 void nrf_wifi_bal_dev_rem(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx)
88 {
89 bal_dev_ctx->bpriv->ops->dev_rem(bal_dev_ctx->bus_dev_ctx);
90
91 nrf_wifi_osal_mem_free(bal_dev_ctx);
92 }
93
94
nrf_wifi_bal_dev_init(struct nrf_wifi_bal_dev_ctx * bal_dev_ctx)95 enum nrf_wifi_status nrf_wifi_bal_dev_init(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx)
96 {
97 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
98
99 #ifdef NRF_WIFI_LOW_POWER
100 bal_dev_ctx->rpu_fw_booted = true;
101 #endif /* NRF_WIFI_LOW_POWER */
102
103 status = bal_dev_ctx->bpriv->ops->dev_init(bal_dev_ctx->bus_dev_ctx);
104
105 if (status != NRF_WIFI_STATUS_SUCCESS) {
106 nrf_wifi_osal_log_err("%s: dev_init failed", __func__);
107 goto out;
108 }
109 out:
110 return status;
111 }
112
113
nrf_wifi_bal_dev_deinit(struct nrf_wifi_bal_dev_ctx * bal_dev_ctx)114 void nrf_wifi_bal_dev_deinit(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx)
115 {
116 bal_dev_ctx->bpriv->ops->dev_deinit(bal_dev_ctx->bus_dev_ctx);
117 }
118
119
nrf_wifi_bal_isr(void * ctx)120 static enum nrf_wifi_status nrf_wifi_bal_isr(void *ctx)
121 {
122 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
123 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
124
125 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
126
127 status = bal_dev_ctx->bpriv->intr_callbk_fn(bal_dev_ctx->hal_dev_ctx);
128
129 return status;
130 }
131
132
133 struct nrf_wifi_bal_priv *
nrf_wifi_bal_init(struct nrf_wifi_bal_cfg_params * cfg_params,enum nrf_wifi_status (* intr_callbk_fn)(void * hal_dev_ctx))134 nrf_wifi_bal_init(struct nrf_wifi_bal_cfg_params *cfg_params,
135 enum nrf_wifi_status (*intr_callbk_fn)(void *hal_dev_ctx))
136 {
137 struct nrf_wifi_bal_priv *bpriv = NULL;
138
139 bpriv = nrf_wifi_osal_mem_zalloc(sizeof(*bpriv));
140
141 if (!bpriv) {
142 nrf_wifi_osal_log_err("%s: Unable to allocate memory for bpriv", __func__);
143 goto out;
144 }
145
146 bpriv->intr_callbk_fn = intr_callbk_fn;
147
148 bpriv->ops = get_bus_ops();
149 if (!bpriv->ops) {
150 nrf_wifi_osal_log_err("%s: Bus ops not available", __func__);
151 nrf_wifi_osal_mem_free(bpriv);
152 bpriv = NULL;
153 goto out;
154 }
155
156 bpriv->bus_priv = bpriv->ops->init(cfg_params,
157 &nrf_wifi_bal_isr);
158
159 if (!bpriv->bus_priv) {
160 nrf_wifi_osal_log_err("%s: Failed", __func__);
161 nrf_wifi_osal_mem_free(bpriv);
162 bpriv = NULL;
163 }
164
165 out:
166 return bpriv;
167 }
168
169
nrf_wifi_bal_deinit(struct nrf_wifi_bal_priv * bpriv)170 void nrf_wifi_bal_deinit(struct nrf_wifi_bal_priv *bpriv)
171 {
172 bpriv->ops->deinit(bpriv->bus_priv);
173
174 nrf_wifi_osal_mem_free(bpriv);
175 }
176
177
nrf_wifi_bal_read_word(void * ctx,unsigned long addr_offset)178 unsigned int nrf_wifi_bal_read_word(void *ctx,
179 unsigned long addr_offset)
180 {
181 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
182 unsigned int val = 0;
183
184 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
185
186 #ifdef NRF_WIFI_LOW_POWER
187 #ifdef NRF_WIFI_LOW_POWER_DBG
188 nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx,
189 addr_offset);
190 #endif /* NRF_WIFI_LOW_POWER_DBG */
191 #endif /* NRF_WIFI_LOW_POWER */
192
193 val = bal_dev_ctx->bpriv->ops->read_word(bal_dev_ctx->bus_dev_ctx,
194 addr_offset);
195
196 return val;
197 }
198
199
nrf_wifi_bal_write_word(void * ctx,unsigned long addr_offset,unsigned int val)200 void nrf_wifi_bal_write_word(void *ctx,
201 unsigned long addr_offset,
202 unsigned int val)
203 {
204 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
205
206 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
207
208 #ifdef NRF_WIFI_LOW_POWER
209 #ifdef NRF_WIFI_LOW_POWER_DBG
210 nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx,
211 addr_offset);
212 #endif /* NRF_WIFI_LOW_POWER_DBG */
213 #endif /* NRF_WIFI_LOW_POWER */
214
215 bal_dev_ctx->bpriv->ops->write_word(bal_dev_ctx->bus_dev_ctx,
216 addr_offset,
217 val);
218 }
219
220
nrf_wifi_bal_read_block(void * ctx,void * dest_addr,unsigned long src_addr_offset,size_t len)221 void nrf_wifi_bal_read_block(void *ctx,
222 void *dest_addr,
223 unsigned long src_addr_offset,
224 size_t len)
225 {
226 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
227
228 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
229
230 #ifdef NRF_WIFI_LOW_POWER
231 #ifdef NRF_WIFI_LOW_POWER_DBG
232 nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx,
233 src_addr_offset);
234 #endif /* NRF_WIFI_LOW_POWER_DBG */
235 #endif /* NRF_WIFI_LOW_POWER */
236
237 bal_dev_ctx->bpriv->ops->read_block(bal_dev_ctx->bus_dev_ctx,
238 dest_addr,
239 src_addr_offset,
240 len);
241 }
242
243
nrf_wifi_bal_write_block(void * ctx,unsigned long dest_addr_offset,const void * src_addr,size_t len)244 void nrf_wifi_bal_write_block(void *ctx,
245 unsigned long dest_addr_offset,
246 const void *src_addr,
247 size_t len)
248 {
249 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
250
251 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
252
253 #ifdef NRF_WIFI_LOW_POWER
254 #ifdef NRF_WIFI_LOW_POWER_DBG
255 nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx,
256 dest_addr_offset);
257 #endif /* NRF_WIFI_LOW_POWER_DBG */
258 #endif /* NRF_WIFI_LOW_POWER */
259
260 bal_dev_ctx->bpriv->ops->write_block(bal_dev_ctx->bus_dev_ctx,
261 dest_addr_offset,
262 src_addr,
263 len);
264 }
265
266
nrf_wifi_bal_dma_map(void * ctx,unsigned long virt_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)267 unsigned long nrf_wifi_bal_dma_map(void *ctx,
268 unsigned long virt_addr,
269 size_t len,
270 enum nrf_wifi_osal_dma_dir dma_dir)
271 {
272 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
273 unsigned long phy_addr = 0;
274
275 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
276
277 phy_addr = bal_dev_ctx->bpriv->ops->dma_map(bal_dev_ctx->bus_dev_ctx,
278 virt_addr,
279 len,
280 dma_dir);
281
282 return phy_addr;
283 }
284
285
nrf_wifi_bal_dma_unmap(void * ctx,unsigned long phy_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)286 unsigned long nrf_wifi_bal_dma_unmap(void *ctx,
287 unsigned long phy_addr,
288 size_t len,
289 enum nrf_wifi_osal_dma_dir dma_dir)
290 {
291 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
292 unsigned long virt_addr = 0;
293
294 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
295
296 virt_addr = bal_dev_ctx->bpriv->ops->dma_unmap(bal_dev_ctx->bus_dev_ctx,
297 phy_addr,
298 len,
299 dma_dir);
300
301 return virt_addr;
302 }
303
304
305 #ifdef NRF_WIFI_LOW_POWER
nrf_wifi_bal_rpu_ps_sleep(void * ctx)306 void nrf_wifi_bal_rpu_ps_sleep(void *ctx)
307 {
308 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
309
310 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
311
312 bal_dev_ctx->bpriv->ops->rpu_ps_sleep(bal_dev_ctx->bus_dev_ctx);
313 }
314
315
nrf_wifi_bal_rpu_ps_wake(void * ctx)316 void nrf_wifi_bal_rpu_ps_wake(void *ctx)
317 {
318 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
319
320 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
321
322 bal_dev_ctx->bpriv->ops->rpu_ps_wake(bal_dev_ctx->bus_dev_ctx);
323 }
324
325
nrf_wifi_bal_rpu_ps_status(void * ctx)326 int nrf_wifi_bal_rpu_ps_status(void *ctx)
327 {
328 struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
329
330 bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx;
331
332 return bal_dev_ctx->bpriv->ops->rpu_ps_status(bal_dev_ctx->bus_dev_ctx);
333 }
334 #endif /* NRF_WIFI_LOW_POWER */
335