1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5  */
6 
7 /**
8  * @brief Implements PCIe bus ops to initialize and read/write on a PCIe bus
9  */
10 #include "bal_structs.h"
11 #include "pcie.h"
12 #include "common/pal.h"
13 
14 #define NRF_WIFI_PCIE_DEV_NAME "nrfwifi0"
15 
nrf_wifi_bus_pcie_irq_handler(void * data)16 int nrf_wifi_bus_pcie_irq_handler(void *data)
17 {
18 	struct nrf_wifi_bus_pcie_dev_ctx *dev_ctx = NULL;
19 	struct nrf_wifi_bus_pcie_priv *pcie_priv = NULL;
20 	int ret = 0;
21 
22 	dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)data;
23 	pcie_priv = dev_ctx->pcie_priv;
24 
25 	ret = pcie_priv->intr_callbk_fn(dev_ctx->bal_dev_ctx);
26 
27 	return ret;
28 }
29 
nrf_wifi_bus_pcie_dev_add(void * bus_priv,void * bal_dev_ctx)30 void *nrf_wifi_bus_pcie_dev_add(void *bus_priv,
31 								void *bal_dev_ctx)
32 {
33 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
34 	struct nrf_wifi_bus_pcie_priv *pcie_priv = NULL;
35 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
36 	struct nrf_wifi_osal_host_map host_map;
37 
38 	pcie_priv = bus_priv;
39 
40 	pcie_dev_ctx = nrf_wifi_osal_mem_zalloc(
41 		sizeof(*pcie_dev_ctx));
42 
43 	if (!pcie_dev_ctx)
44 	{
45 		nrf_wifi_osal_log_err(
46 			"%s: Unable to allocate pcie_dev_ctx\n", __func__);
47 		goto out;
48 	}
49 
50 	pcie_dev_ctx->pcie_priv = pcie_priv;
51 	pcie_dev_ctx->bal_dev_ctx = bal_dev_ctx;
52 
53 	pcie_dev_ctx->os_pcie_dev_ctx = nrf_wifi_osal_bus_pcie_dev_add(
54 		pcie_priv->os_pcie_priv,
55 		pcie_dev_ctx);
56 
57 	if (!pcie_dev_ctx->os_pcie_dev_ctx)
58 	{
59 		nrf_wifi_osal_log_err(
60 			"%s: nrf_wifi_osal_bus_pcie_dev_add failed\n", __func__);
61 
62 		nrf_wifi_osal_mem_free(
63 			pcie_dev_ctx);
64 
65 		pcie_dev_ctx = NULL;
66 
67 		goto out;
68 	}
69 
70 	nrf_wifi_osal_bus_pcie_dev_host_map_get(
71 		pcie_dev_ctx->os_pcie_dev_ctx,
72 		&host_map);
73 
74 	pcie_dev_ctx->iomem_addr_base = nrf_wifi_osal_iomem_mmap(
75 		host_map.addr,
76 		host_map.size);
77 
78 #ifdef INLINE_BB_MODE
79 	pcie_dev_ctx->addr_pktram_base = pcie_priv->cfg_params.addr_pktram_base;
80 #endif /* INLINE_BB_MODE */
81 #ifdef OFFLINE_MODE
82 	pcie_dev_ctx->addr_pktram_base = ((unsigned long)pcie_dev_ctx->iomem_addr_base +
83 									  pcie_priv->cfg_params.addr_pktram_base);
84 #endif /* OFFLINE_MODE */
85 #ifdef INLINE_RX
86 	pcie_dev_ctx->addr_hostram_base_inline_rx = pcie_priv->cfg_params.addr_hostram_base_inline_rx;
87 #endif
88 
89 	status = nrf_wifi_osal_bus_pcie_dev_intr_reg(
90 		pcie_dev_ctx->os_pcie_dev_ctx,
91 		pcie_dev_ctx,
92 		&nrf_wifi_bus_pcie_irq_handler);
93 
94 	if (status != NRF_WIFI_STATUS_SUCCESS)
95 	{
96 		nrf_wifi_osal_log_err(
97 			"%s: Unable to register PCIe interrupt to the OS\n",
98 			__func__);
99 
100 		nrf_wifi_osal_iomem_unmap(
101 			pcie_dev_ctx->iomem_addr_base);
102 
103 		nrf_wifi_osal_bus_pcie_dev_rem(
104 			pcie_dev_ctx->os_pcie_dev_ctx);
105 
106 		nrf_wifi_osal_mem_free(
107 			pcie_dev_ctx);
108 
109 		pcie_dev_ctx = NULL;
110 
111 		goto out;
112 	}
113 
114 out:
115 	return pcie_dev_ctx;
116 }
117 
nrf_wifi_bus_pcie_dev_rem(void * bus_dev_ctx)118 void nrf_wifi_bus_pcie_dev_rem(void *bus_dev_ctx)
119 {
120 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
121 
122 	pcie_dev_ctx = bus_dev_ctx;
123 
124 	nrf_wifi_osal_iomem_unmap(
125 		pcie_dev_ctx->iomem_addr_base);
126 
127 	nrf_wifi_osal_bus_pcie_dev_intr_unreg(
128 		pcie_dev_ctx->os_pcie_dev_ctx);
129 
130 	nrf_wifi_osal_bus_pcie_dev_rem(
131 		pcie_dev_ctx->os_pcie_dev_ctx);
132 
133 	nrf_wifi_osal_mem_free(
134 		pcie_dev_ctx);
135 }
136 
nrf_wifi_bus_pcie_dev_init(void * bus_dev_ctx)137 enum nrf_wifi_status nrf_wifi_bus_pcie_dev_init(void *bus_dev_ctx)
138 {
139 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
140 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
141 
142 	pcie_dev_ctx = bus_dev_ctx;
143 
144 	status = nrf_wifi_osal_bus_pcie_dev_init(
145 		pcie_dev_ctx->os_pcie_dev_ctx);
146 
147 	if (status != NRF_WIFI_STATUS_SUCCESS)
148 	{
149 		nrf_wifi_osal_log_err(
150 			"%s: nrf_wifi_osal_pcie_dev_init failed\n", __func__);
151 
152 		goto out;
153 	}
154 out:
155 	return status;
156 }
157 
nrf_wifi_bus_pcie_dev_deinit(void * bus_dev_ctx)158 void nrf_wifi_bus_pcie_dev_deinit(void *bus_dev_ctx)
159 {
160 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
161 
162 	pcie_dev_ctx = bus_dev_ctx;
163 
164 	nrf_wifi_osal_bus_pcie_dev_deinit(
165 		pcie_dev_ctx->os_pcie_dev_ctx);
166 }
167 
nrf_wifi_bus_pcie_init(void * params,int (* intr_callbk_fn)(void * bal_dev_ctx))168 void *nrf_wifi_bus_pcie_init(void *params,
169 							 int (*intr_callbk_fn)(void *bal_dev_ctx))
170 {
171 	struct nrf_wifi_bus_pcie_priv *pcie_priv = NULL;
172 
173 	pcie_priv = nrf_wifi_osal_mem_zalloc(
174 		sizeof(*pcie_priv));
175 
176 	if (!pcie_priv)
177 	{
178 		nrf_wifi_osal_log_err(
179 			"%s: Unable to allocate memory for pcie_priv\n",
180 			__func__);
181 		goto out;
182 	}
183 
184 	nrf_wifi_osal_mem_cpy(
185 		&pcie_priv->cfg_params,
186 		params,
187 		sizeof(pcie_priv->cfg_params));
188 
189 	pcie_priv->intr_callbk_fn = intr_callbk_fn;
190 
191 	pcie_priv->os_pcie_priv = nrf_wifi_osal_bus_pcie_init(
192 		NRF_WIFI_PCIE_DRV_NAME,
193 		NRF_WIFI_PCI_VENDOR_ID,
194 		NRF_WIFI_PCI_SUB_VENDOR_ID,
195 		NRF_WIFI_PCI_DEVICE_ID,
196 		NRF_WIFI_PCI_SUB_DEVICE_ID);
197 
198 	if (!pcie_priv->os_pcie_priv)
199 	{
200 		nrf_wifi_osal_log_err(
201 			"%s: Unable to register PCIe driver\n",
202 			__func__);
203 
204 		nrf_wifi_osal_mem_free(
205 			pcie_priv);
206 
207 		pcie_priv = NULL;
208 
209 		goto out;
210 	}
211 out:
212 	return pcie_priv;
213 }
214 
nrf_wifi_bus_pcie_deinit(void * bus_priv)215 void nrf_wifi_bus_pcie_deinit(void *bus_priv)
216 {
217 	struct nrf_wifi_bus_pcie_priv *pcie_priv = NULL;
218 
219 	pcie_priv = bus_priv;
220 
221 	nrf_wifi_osal_bus_pcie_deinit(
222 		pcie_priv->os_pcie_priv);
223 
224 	nrf_wifi_osal_mem_free(
225 		pcie_priv);
226 }
227 
nrf_wifi_bus_pcie_read_word(void * dev_ctx,unsigned long addr_offset)228 unsigned int nrf_wifi_bus_pcie_read_word(void *dev_ctx,
229 										 unsigned long addr_offset)
230 {
231 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
232 	void *mmap_addr = NULL;
233 	unsigned int val = 0;
234 
235 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
236 
237 	mmap_addr = pcie_dev_ctx->iomem_addr_base + addr_offset;
238 
239 	val = nrf_wifi_osal_iomem_read_reg32(
240 		mmap_addr);
241 
242 	return val;
243 }
244 
nrf_wifi_bus_pcie_write_word(void * dev_ctx,unsigned long addr_offset,unsigned int val)245 void nrf_wifi_bus_pcie_write_word(void *dev_ctx,
246 								  unsigned long addr_offset,
247 								  unsigned int val)
248 {
249 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
250 	void *mmap_addr = NULL;
251 
252 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
253 
254 	mmap_addr = pcie_dev_ctx->iomem_addr_base + addr_offset;
255 
256 	nrf_wifi_osal_iomem_write_reg32(
257 		mmap_addr,
258 		val);
259 }
260 
nrf_wifi_bus_pcie_read_block(void * dev_ctx,void * dest_addr,unsigned long src_addr_offset,size_t len)261 void nrf_wifi_bus_pcie_read_block(void *dev_ctx,
262 								  void *dest_addr,
263 								  unsigned long src_addr_offset,
264 								  size_t len)
265 {
266 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
267 	void *mmap_addr = NULL;
268 
269 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
270 
271 	mmap_addr = pcie_dev_ctx->iomem_addr_base + src_addr_offset;
272 
273 	nrf_wifi_osal_iomem_cpy_from(
274 		dest_addr,
275 		mmap_addr,
276 		len);
277 }
278 
nrf_wifi_bus_pcie_write_block(void * dev_ctx,unsigned long dest_addr_offset,const void * src_addr,size_t len)279 void nrf_wifi_bus_pcie_write_block(void *dev_ctx,
280 								   unsigned long dest_addr_offset,
281 								   const void *src_addr,
282 								   size_t len)
283 {
284 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
285 	void *mmap_addr = NULL;
286 
287 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
288 
289 	mmap_addr = pcie_dev_ctx->iomem_addr_base + dest_addr_offset;
290 
291 	nrf_wifi_osal_iomem_cpy_to(
292 		mmap_addr,
293 		src_addr,
294 		len);
295 }
296 #ifdef SOC_WEZEN
297 #ifdef INLINE_RX
nrf_wifi_bus_pcie_dma_map_inline_rx(void * dev_ctx,unsigned long virt_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)298 unsigned long nrf_wifi_bus_pcie_dma_map_inline_rx(void *dev_ctx,
299 												  unsigned long virt_addr,
300 												  size_t len,
301 												  enum nrf_wifi_osal_dma_dir dma_dir)
302 {
303 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
304 	unsigned long phy_addr = 0;
305 
306 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
307 	phy_addr = SOC_HOST_DATA_RAM_BASE + (virt_addr - pcie_dev_ctx->addr_hostram_base_inline_rx);
308 	return phy_addr;
309 }
nrf_wifi_bus_pcie_dma_unmap_inline_rx(void * dev_ctx,unsigned long phy_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)310 unsigned long nrf_wifi_bus_pcie_dma_unmap_inline_rx(void *dev_ctx,
311 													unsigned long phy_addr,
312 													size_t len,
313 													enum nrf_wifi_osal_dma_dir dma_dir)
314 {
315 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
316 	unsigned long virt_addr = 0;
317 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
318 	virt_addr = pcie_dev_ctx->addr_hostram_base_inline_rx + (phy_addr - SOC_HOST_DATA_RAM_BASE);
319 	return virt_addr;
320 }
321 #endif
322 #endif
323 
nrf_wifi_bus_pcie_dma_map(void * dev_ctx,unsigned long virt_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)324 unsigned long nrf_wifi_bus_pcie_dma_map(void *dev_ctx,
325 										unsigned long virt_addr,
326 										size_t len,
327 										enum nrf_wifi_osal_dma_dir dma_dir)
328 {
329 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
330 	unsigned long phy_addr = 0;
331 
332 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
333 
334 #ifdef INLINE_MODE
335 	phy_addr = (unsigned long)nrf_wifi_osal_bus_pcie_dev_dma_map(
336 		pcie_dev_ctx->os_pcie_dev_ctx,
337 		(void *)virt_addr,
338 		len,
339 		dma_dir);
340 #endif /* INLINE_MODE */
341 #ifdef INLINE_BB_MODE
342 	phy_addr = SOC_HOST_PKTRAM_BASE + (virt_addr - pcie_dev_ctx->addr_pktram_base);
343 #endif /* INLINE_BB_MODE */
344 #ifdef OFFLINE_MODE
345 	phy_addr = (unsigned long)pcie_dev_ctx->iomem_addr_base + (virt_addr - pcie_dev_ctx->addr_pktram_base);
346 #endif /* OFFLINE_MODE */
347 
348 	return phy_addr;
349 }
350 
nrf_wifi_bus_pcie_dma_unmap(void * dev_ctx,unsigned long phy_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)351 unsigned long nrf_wifi_bus_pcie_dma_unmap(void *dev_ctx,
352 										  unsigned long phy_addr,
353 										  size_t len,
354 										  enum nrf_wifi_osal_dma_dir dma_dir)
355 {
356 	struct nrf_wifi_bus_pcie_dev_ctx *pcie_dev_ctx = NULL;
357 	unsigned long virt_addr = 0;
358 #ifdef OFFLINE_MODE
359 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
360 #endif /* OFFLINE_MODE */
361 
362 	pcie_dev_ctx = (struct nrf_wifi_bus_pcie_dev_ctx *)dev_ctx;
363 
364 #ifdef INLINE_MODE
365 	nrf_wifi_osal_bus_pcie_dev_dma_unmap(
366 		pcie_dev_ctx->os_pcie_dev_ctx,
367 		(void *)phy_addr,
368 		len,
369 		dma_dir);
370 #endif /* INLINE_MODE */
371 #ifdef INLINE_BB_MODE
372 	virt_addr = pcie_dev_ctx->addr_pktram_base + (phy_addr - SOC_HOST_PKTRAM_BASE);
373 #endif /* INLINE_BB_MODE */
374 #ifdef OFFLINE_MODE
375 #ifdef SOC_WEZEN
376 	status = pal_rpu_addr_offset_get(
377 		RPU_ADDR_DATA_RAM_START + phy_addr,
378 		&virt_addr,
379 		RPU_ADDR_DATA_RAM_START);
380 #else
381 	status = pal_rpu_addr_offset_get(
382 		RPU_ADDR_PKTRAM_START + phy_addr,
383 		&virt_addr,
384 		RPU_ADDR_PKTRAM_START);
385 #endif
386 	if (status != NRF_WIFI_STATUS_SUCCESS)
387 		nrf_wifi_osal_log_err(
388 			"%s: pal_rpu_addr_offset_get failed\n", __func__);
389 #endif /* OFFLINE_MODE */
390 
391 	return virt_addr;
392 }
393 
394 #ifdef NRF_WIFI_LOW_POWER
nrf_wifi_bus_pcie_rpu_ps_sleep(void * bus_dev_ctx)395 void nrf_wifi_bus_pcie_rpu_ps_sleep(void *bus_dev_ctx)
396 {
397 	unsigned long reg_addr = 0;
398 	unsigned int reg_val = 0;
399 
400 	reg_addr = pal_rpu_ps_ctrl_reg_addr_get();
401 
402 	reg_val = nrf_wifi_bus_pcie_read_word(bus_dev_ctx,
403 										  reg_addr);
404 
405 	reg_val &= (~(1 << RPU_REG_BIT_PS_CTRL));
406 
407 	nrf_wifi_bus_pcie_write_word(bus_dev_ctx,
408 								 reg_addr,
409 								 reg_val);
410 }
411 
nrf_wifi_bus_pcie_rpu_ps_wake(void * bus_dev_ctx)412 void nrf_wifi_bus_pcie_rpu_ps_wake(void *bus_dev_ctx)
413 {
414 	unsigned long reg_addr = 0;
415 	unsigned int reg_val = 0;
416 
417 	reg_addr = pal_rpu_ps_ctrl_reg_addr_get();
418 
419 	reg_val = (1 << RPU_REG_BIT_PS_CTRL);
420 
421 	nrf_wifi_bal_write_word(bus_dev_ctx,
422 							reg_addr,
423 							reg_val);
424 }
425 
nrf_wifi_bus_pcie_rpu_ps_status(void * bus_dev_ctx)426 int nrf_wifi_bus_pcie_rpu_ps_status(void *bus_dev_ctx)
427 {
428 	unsigned long reg_addr = 0;
429 
430 	reg_addr = pal_rpu_ps_ctrl_reg_addr_get();
431 
432 	return nrf_wifi_bus_pcie_read_word(bus_dev_ctx,
433 									   reg_addr);
434 }
435 #endif /* NRF_WIFI_LOW_POWER */
436 
437 struct nrf_wifi_bal_ops nrf_wifi_bus_pcie_ops = {
438 	.init = &nrf_wifi_bus_pcie_init,
439 	.deinit = &nrf_wifi_bus_pcie_deinit,
440 	.dev_add = &nrf_wifi_bus_pcie_dev_add,
441 	.dev_rem = &nrf_wifi_bus_pcie_dev_rem,
442 	.dev_init = &nrf_wifi_bus_pcie_dev_init,
443 	.dev_deinit = &nrf_wifi_bus_pcie_dev_deinit,
444 	.read_word = &nrf_wifi_bus_pcie_read_word,
445 	.write_word = &nrf_wifi_bus_pcie_write_word,
446 	.read_block = &nrf_wifi_bus_pcie_read_block,
447 	.write_block = &nrf_wifi_bus_pcie_write_block,
448 	.dma_map = &nrf_wifi_bus_pcie_dma_map,
449 	.dma_unmap = &nrf_wifi_bus_pcie_dma_unmap,
450 #ifdef SOC_WEZEN
451 #ifdef INLINE_RX
452 	.dma_map_inline_rx = &nrf_wifi_bus_pcie_dma_map_inline_rx,
453 	.dma_unmap_inline_rx = &nrf_wifi_bus_pcie_dma_unmap_inline_rx,
454 #endif
455 #endif
456 #ifdef NRF_WIFI_LOW_POWER
457 	.rpu_ps_sleep = &nrf_wifi_bus_pcie_rpu_ps_sleep,
458 	.rpu_ps_wake = &nrf_wifi_bus_pcie_rpu_ps_wake,
459 	.rpu_ps_status = &nrf_wifi_bus_pcie_rpu_ps_status,
460 #endif /* NRF_WIFI_LOW_POWER */
461 };
462 
get_bus_ops(void)463 struct nrf_wifi_bal_ops *get_bus_ops(void)
464 {
465 	return &nrf_wifi_bus_pcie_ops;
466 }
467