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