1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief Header containing OS specific definitions for the
9  * Zephyr OS layer of the Wi-Fi driver.
10  */
11 
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/time.h>
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/sys/printk.h>
18 #include <zephyr/drivers/gpio.h>
19 #include <zephyr/logging/log.h>
20 #include <zephyr/sys/__assert.h>
21 #include <zephyr/drivers/wifi/nrf_wifi/bus/rpu_hw_if.h>
22 #include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
23 #include <zephyr/sys/math_extras.h>
24 
25 #include "shim.h"
26 #include "work.h"
27 #include "timer.h"
28 #include "osal_ops.h"
29 
30 LOG_MODULE_REGISTER(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL);
31 #if defined(CONFIG_NOCACHE_MEMORY)
32 K_HEAP_DEFINE_NOCACHE(wifi_drv_ctrl_mem_pool, CONFIG_NRF_WIFI_CTRL_HEAP_SIZE);
33 K_HEAP_DEFINE_NOCACHE(wifi_drv_data_mem_pool, CONFIG_NRF_WIFI_DATA_HEAP_SIZE);
34 #else
35 K_HEAP_DEFINE(wifi_drv_ctrl_mem_pool, CONFIG_NRF_WIFI_CTRL_HEAP_SIZE);
36 K_HEAP_DEFINE(wifi_drv_data_mem_pool, CONFIG_NRF_WIFI_DATA_HEAP_SIZE);
37 #endif /* CONFIG_NOCACHE_MEMORY */
38 #define WORD_SIZE 4
39 
40 struct zep_shim_intr_priv *intr_priv;
41 
zep_shim_mem_alloc(size_t size)42 static void *zep_shim_mem_alloc(size_t size)
43 {
44 	size_t size_aligned = ROUND_UP(size, 4);
45 
46 	return k_heap_aligned_alloc(&wifi_drv_ctrl_mem_pool, WORD_SIZE, size_aligned, K_FOREVER);
47 }
48 
zep_shim_data_mem_alloc(size_t size)49 static void *zep_shim_data_mem_alloc(size_t size)
50 {
51 	size_t size_aligned = ROUND_UP(size, 4);
52 
53 	return k_heap_aligned_alloc(&wifi_drv_data_mem_pool, WORD_SIZE, size_aligned, K_FOREVER);
54 }
55 
zep_shim_mem_zalloc(size_t size)56 static void *zep_shim_mem_zalloc(size_t size)
57 {
58 	void *ret;
59 	size_t bounds;
60 
61 	size_t size_aligned = ROUND_UP(size, 4);
62 
63 	if (size_mul_overflow(size_aligned, sizeof(char), &bounds)) {
64 		return NULL;
65 	}
66 
67 	ret = zep_shim_mem_alloc(bounds);
68 	if (ret != NULL) {
69 		(void)memset(ret, 0, bounds);
70 	}
71 
72 	return ret;
73 }
74 
zep_shim_data_mem_zalloc(size_t size)75 static void *zep_shim_data_mem_zalloc(size_t size)
76 {
77 	void *ret;
78 	size_t bounds;
79 
80 	size_t size_aligned = ROUND_UP(size, 4);
81 
82 	if (size_mul_overflow(size_aligned, sizeof(char), &bounds)) {
83 		return NULL;
84 	}
85 
86 	ret = zep_shim_data_mem_alloc(bounds);
87 	if (ret != NULL) {
88 		(void)memset(ret, 0, bounds);
89 	}
90 
91 	return ret;
92 }
93 
zep_shim_mem_free(void * buf)94 static void zep_shim_mem_free(void *buf)
95 {
96 	if (buf) {
97 		k_heap_free(&wifi_drv_ctrl_mem_pool, buf);
98 	}
99 }
100 
zep_shim_data_mem_free(void * buf)101 static void zep_shim_data_mem_free(void *buf)
102 {
103 	if (buf) {
104 		k_heap_free(&wifi_drv_data_mem_pool, buf);
105 	}
106 }
107 
zep_shim_mem_cpy(void * dest,const void * src,size_t count)108 static void *zep_shim_mem_cpy(void *dest, const void *src, size_t count)
109 {
110 	return memcpy(dest, src, count);
111 }
112 
zep_shim_mem_set(void * start,int val,size_t size)113 static void *zep_shim_mem_set(void *start, int val, size_t size)
114 {
115 	return memset(start, val, size);
116 }
117 
zep_shim_mem_cmp(const void * addr1,const void * addr2,size_t size)118 static int zep_shim_mem_cmp(const void *addr1,
119 			    const void *addr2,
120 			    size_t size)
121 {
122 	return memcmp(addr1, addr2, size);
123 }
124 
zep_shim_qspi_read_reg32(void * priv,unsigned long addr)125 static unsigned int zep_shim_qspi_read_reg32(void *priv, unsigned long addr)
126 {
127 	unsigned int val;
128 	struct zep_shim_bus_qspi_priv *qspi_priv = priv;
129 	struct qspi_dev *dev;
130 
131 	dev = qspi_priv->qspi_dev;
132 
133 	if (addr < 0x0C0000) {
134 		dev->hl_read(addr, &val, 4);
135 	} else {
136 		dev->read(addr, &val, 4);
137 	}
138 
139 	return val;
140 }
141 
zep_shim_qspi_write_reg32(void * priv,unsigned long addr,unsigned int val)142 static void zep_shim_qspi_write_reg32(void *priv, unsigned long addr, unsigned int val)
143 {
144 	struct zep_shim_bus_qspi_priv *qspi_priv = priv;
145 	struct qspi_dev *dev;
146 
147 	dev = qspi_priv->qspi_dev;
148 
149 	dev->write(addr, &val, 4);
150 }
151 
zep_shim_qspi_cpy_from(void * priv,void * dest,unsigned long addr,size_t count)152 static void zep_shim_qspi_cpy_from(void *priv, void *dest, unsigned long addr, size_t count)
153 {
154 	struct zep_shim_bus_qspi_priv *qspi_priv = priv;
155 	struct qspi_dev *dev;
156 	size_t count_aligned = ROUND_UP(count, 4);
157 
158 	dev = qspi_priv->qspi_dev;
159 
160 	if (addr < 0x0C0000) {
161 		dev->hl_read(addr, dest, count_aligned);
162 	} else {
163 		dev->read(addr, dest, count_aligned);
164 	}
165 }
166 
zep_shim_qspi_cpy_to(void * priv,unsigned long addr,const void * src,size_t count)167 static void zep_shim_qspi_cpy_to(void *priv, unsigned long addr, const void *src, size_t count)
168 {
169 	struct zep_shim_bus_qspi_priv *qspi_priv = priv;
170 	struct qspi_dev *dev;
171 	size_t count_aligned = ROUND_UP(count, 4);
172 
173 	dev = qspi_priv->qspi_dev;
174 
175 	dev->write(addr, src, count_aligned);
176 }
177 
zep_shim_spinlock_alloc(void)178 static void *zep_shim_spinlock_alloc(void)
179 {
180 	struct k_mutex *lock = NULL;
181 
182 	lock = zep_shim_mem_zalloc(sizeof(*lock));
183 
184 	if (!lock) {
185 		LOG_ERR("%s: Unable to allocate memory for spinlock", __func__);
186 	}
187 
188 	return lock;
189 }
190 
zep_shim_spinlock_free(void * lock)191 static void zep_shim_spinlock_free(void *lock)
192 {
193 	k_heap_free(&wifi_drv_ctrl_mem_pool, lock);
194 }
195 
zep_shim_spinlock_init(void * lock)196 static void zep_shim_spinlock_init(void *lock)
197 {
198 	k_mutex_init(lock);
199 }
200 
zep_shim_spinlock_take(void * lock)201 static void zep_shim_spinlock_take(void *lock)
202 {
203 	k_mutex_lock(lock, K_FOREVER);
204 }
205 
zep_shim_spinlock_rel(void * lock)206 static void zep_shim_spinlock_rel(void *lock)
207 {
208 	k_mutex_unlock(lock);
209 }
210 
zep_shim_spinlock_irq_take(void * lock,unsigned long * flags)211 static void zep_shim_spinlock_irq_take(void *lock, unsigned long *flags)
212 {
213 	ARG_UNUSED(flags);
214 	k_mutex_lock(lock, K_FOREVER);
215 }
216 
zep_shim_spinlock_irq_rel(void * lock,unsigned long * flags)217 static void zep_shim_spinlock_irq_rel(void *lock, unsigned long *flags)
218 {
219 	ARG_UNUSED(flags);
220 	k_mutex_unlock(lock);
221 }
222 
zep_shim_pr_dbg(const char * fmt,va_list args)223 static int zep_shim_pr_dbg(const char *fmt, va_list args)
224 {
225 	static char buf[80];
226 
227 	vsnprintf(buf, sizeof(buf), fmt, args);
228 
229 	LOG_DBG("%s", buf);
230 
231 	return 0;
232 }
233 
zep_shim_pr_info(const char * fmt,va_list args)234 static int zep_shim_pr_info(const char *fmt, va_list args)
235 {
236 	static char buf[80];
237 
238 	vsnprintf(buf, sizeof(buf), fmt, args);
239 
240 	LOG_INF("%s", buf);
241 
242 	return 0;
243 }
244 
zep_shim_pr_err(const char * fmt,va_list args)245 static int zep_shim_pr_err(const char *fmt, va_list args)
246 {
247 	static char buf[256];
248 
249 	vsnprintf(buf, sizeof(buf), fmt, args);
250 
251 	LOG_ERR("%s", buf);
252 
253 	return 0;
254 }
255 
256 struct nwb {
257 	unsigned char *data;
258 	unsigned char *tail;
259 	int len;
260 	int headroom;
261 	void *next;
262 	void *priv;
263 	int iftype;
264 	void *ifaddr;
265 	void *dev;
266 	int hostbuffer;
267 	void *cleanup_ctx;
268 	void (*cleanup_cb)();
269 	unsigned char priority;
270 	bool chksum_done;
271 };
272 
zep_shim_nbuf_alloc(unsigned int size)273 static void *zep_shim_nbuf_alloc(unsigned int size)
274 {
275 	struct nwb *nbuff;
276 
277 	nbuff = (struct nwb *)zep_shim_data_mem_zalloc(sizeof(struct nwb));
278 
279 	if (!nbuff) {
280 		return NULL;
281 	}
282 
283 	nbuff->priv = zep_shim_data_mem_zalloc(size);
284 
285 	if (!nbuff->priv) {
286 		zep_shim_data_mem_free(nbuff);
287 		return NULL;
288 	}
289 
290 	nbuff->data = (unsigned char *)nbuff->priv;
291 	nbuff->tail = nbuff->data;
292 	nbuff->len = 0;
293 	nbuff->headroom = 0;
294 	nbuff->next = NULL;
295 
296 	return nbuff;
297 }
298 
zep_shim_nbuf_free(void * nbuf)299 static void zep_shim_nbuf_free(void *nbuf)
300 {
301 	if (!nbuf) {
302 		return;
303 	}
304 
305 	zep_shim_data_mem_free(((struct nwb *)nbuf)->priv);
306 	zep_shim_data_mem_free(nbuf);
307 }
308 
zep_shim_nbuf_headroom_res(void * nbuf,unsigned int size)309 static void zep_shim_nbuf_headroom_res(void *nbuf, unsigned int size)
310 {
311 	struct nwb *nwb = (struct nwb *)nbuf;
312 
313 	nwb->data += size;
314 	nwb->tail += size;
315 	nwb->headroom += size;
316 }
317 
zep_shim_nbuf_headroom_get(void * nbuf)318 static unsigned int zep_shim_nbuf_headroom_get(void *nbuf)
319 {
320 	return ((struct nwb *)nbuf)->headroom;
321 }
322 
zep_shim_nbuf_data_size(void * nbuf)323 static unsigned int zep_shim_nbuf_data_size(void *nbuf)
324 {
325 	return ((struct nwb *)nbuf)->len;
326 }
327 
zep_shim_nbuf_data_get(void * nbuf)328 static void *zep_shim_nbuf_data_get(void *nbuf)
329 {
330 	return ((struct nwb *)nbuf)->data;
331 }
332 
zep_shim_nbuf_data_put(void * nbuf,unsigned int size)333 static void *zep_shim_nbuf_data_put(void *nbuf, unsigned int size)
334 {
335 	struct nwb *nwb = (struct nwb *)nbuf;
336 	unsigned char *data = nwb->tail;
337 
338 	nwb->tail += size;
339 	nwb->len += size;
340 
341 	return data;
342 }
343 
zep_shim_nbuf_data_push(void * nbuf,unsigned int size)344 static void *zep_shim_nbuf_data_push(void *nbuf, unsigned int size)
345 {
346 	struct nwb *nwb = (struct nwb *)nbuf;
347 
348 	nwb->data -= size;
349 	nwb->headroom -= size;
350 	nwb->len += size;
351 
352 	return nwb->data;
353 }
354 
zep_shim_nbuf_data_pull(void * nbuf,unsigned int size)355 static void *zep_shim_nbuf_data_pull(void *nbuf, unsigned int size)
356 {
357 	struct nwb *nwb = (struct nwb *)nbuf;
358 
359 	nwb->data += size;
360 	nwb->headroom += size;
361 	nwb->len -= size;
362 
363 	return nwb->data;
364 }
365 
zep_shim_nbuf_get_priority(void * nbuf)366 static unsigned char zep_shim_nbuf_get_priority(void *nbuf)
367 {
368 	struct nwb *nwb = (struct nwb *)nbuf;
369 
370 	return nwb->priority;
371 }
372 
zep_shim_nbuf_get_chksum_done(void * nbuf)373 static unsigned char zep_shim_nbuf_get_chksum_done(void *nbuf)
374 {
375 	struct nwb *nwb = (struct nwb *)nbuf;
376 
377 	return nwb->chksum_done;
378 }
379 
zep_shim_nbuf_set_chksum_done(void * nbuf,unsigned char chksum_done)380 static void zep_shim_nbuf_set_chksum_done(void *nbuf, unsigned char chksum_done)
381 {
382 	struct nwb *nwb = (struct nwb *)nbuf;
383 
384 	nwb->chksum_done = (bool)chksum_done;
385 }
386 
387 #include <zephyr/net/ethernet.h>
388 #include <zephyr/net/net_core.h>
389 
net_pkt_to_nbuf(struct net_pkt * pkt)390 void *net_pkt_to_nbuf(struct net_pkt *pkt)
391 {
392 	struct nwb *nbuff;
393 	unsigned char *data;
394 	unsigned int len;
395 
396 	len = net_pkt_get_len(pkt);
397 
398 	nbuff = zep_shim_nbuf_alloc(len + 100);
399 
400 	if (!nbuff) {
401 		return NULL;
402 	}
403 
404 	zep_shim_nbuf_headroom_res(nbuff, 100);
405 
406 	data = zep_shim_nbuf_data_put(nbuff, len);
407 
408 	net_pkt_read(pkt, data, len);
409 
410 	nbuff->priority = net_pkt_priority(pkt);
411 	nbuff->chksum_done = (bool)net_pkt_is_chksum_done(pkt);
412 
413 	return nbuff;
414 }
415 
net_pkt_from_nbuf(void * iface,void * frm)416 void *net_pkt_from_nbuf(void *iface, void *frm)
417 {
418 	struct net_pkt *pkt = NULL;
419 	unsigned char *data;
420 	unsigned int len;
421 	struct nwb *nwb = frm;
422 
423 	if (!nwb) {
424 		return NULL;
425 	}
426 
427 	len = zep_shim_nbuf_data_size(nwb);
428 
429 	data = zep_shim_nbuf_data_get(nwb);
430 
431 	pkt = net_pkt_rx_alloc_with_buffer(iface, len, AF_UNSPEC, 0, K_MSEC(100));
432 
433 	if (!pkt) {
434 		goto out;
435 	}
436 
437 	if (net_pkt_write(pkt, data, len)) {
438 		net_pkt_unref(pkt);
439 		pkt = NULL;
440 		goto out;
441 	}
442 
443 out:
444 	zep_shim_nbuf_free(nwb);
445 	return pkt;
446 }
447 
448 #if defined(CONFIG_NRF70_RAW_DATA_RX) || defined(CONFIG_NRF70_PROMISC_DATA_RX)
net_raw_pkt_from_nbuf(void * iface,void * frm,unsigned short raw_hdr_len,void * raw_rx_hdr,bool pkt_free)449 void *net_raw_pkt_from_nbuf(void *iface, void *frm,
450 			    unsigned short raw_hdr_len,
451 			    void *raw_rx_hdr,
452 			    bool pkt_free)
453 {
454 	struct net_pkt *pkt = NULL;
455 	unsigned char *nwb_data;
456 	unsigned char *data =  NULL;
457 	unsigned int nwb_len;
458 	unsigned int total_len;
459 	struct nwb *nwb = frm;
460 
461 	if (!nwb) {
462 		LOG_ERR("%s: Received network buffer is NULL", __func__);
463 		return NULL;
464 	}
465 
466 	nwb_len = zep_shim_nbuf_data_size(nwb);
467 	nwb_data = zep_shim_nbuf_data_get(nwb);
468 	total_len = raw_hdr_len + nwb_len;
469 
470 	data = (unsigned char *)zep_shim_data_mem_zalloc(total_len);
471 	if (!data) {
472 		LOG_ERR("%s: Unable to allocate memory for sniffer data packet", __func__);
473 		goto out;
474 	}
475 
476 	pkt = net_pkt_rx_alloc_with_buffer(iface, total_len, AF_PACKET, ETH_P_ALL, K_MSEC(100));
477 	if (!pkt) {
478 		LOG_ERR("%s: Unable to allocate net packet buffer", __func__);
479 		goto out;
480 	}
481 
482 	memcpy(data, raw_rx_hdr, raw_hdr_len);
483 	memcpy((data+raw_hdr_len), nwb_data, nwb_len);
484 
485 	if (net_pkt_write(pkt, data, total_len)) {
486 		net_pkt_unref(pkt);
487 		pkt = NULL;
488 		goto out;
489 	}
490 out:
491 	if (data != NULL) {
492 		zep_shim_data_mem_free(data);
493 	}
494 
495 	if (pkt_free) {
496 		zep_shim_nbuf_free(nwb);
497 	}
498 
499 	return pkt;
500 }
501 #endif /* CONFIG_NRF70_RAW_DATA_RX || CONFIG_NRF70_PROMISC_DATA_RX */
502 
zep_shim_llist_node_alloc(void)503 static void *zep_shim_llist_node_alloc(void)
504 {
505 	struct zep_shim_llist_node *llist_node = NULL;
506 
507 	llist_node = zep_shim_data_mem_zalloc(sizeof(*llist_node));
508 
509 	if (!llist_node) {
510 		LOG_ERR("%s: Unable to allocate memory for linked list node", __func__);
511 		return NULL;
512 	}
513 
514 	sys_dnode_init(&llist_node->head);
515 
516 	return llist_node;
517 }
518 
zep_shim_llist_node_free(void * llist_node)519 static void zep_shim_llist_node_free(void *llist_node)
520 {
521 	zep_shim_data_mem_free(llist_node);
522 }
523 
zep_shim_llist_node_data_get(void * llist_node)524 static void *zep_shim_llist_node_data_get(void *llist_node)
525 {
526 	struct zep_shim_llist_node *zep_llist_node = NULL;
527 
528 	zep_llist_node = (struct zep_shim_llist_node *)llist_node;
529 
530 	return zep_llist_node->data;
531 }
532 
zep_shim_llist_node_data_set(void * llist_node,void * data)533 static void zep_shim_llist_node_data_set(void *llist_node, void *data)
534 {
535 	struct zep_shim_llist_node *zep_llist_node = NULL;
536 
537 	zep_llist_node = (struct zep_shim_llist_node *)llist_node;
538 
539 	zep_llist_node->data = data;
540 }
541 
zep_shim_llist_alloc(void)542 static void *zep_shim_llist_alloc(void)
543 {
544 	struct zep_shim_llist *llist = NULL;
545 
546 	llist = zep_shim_data_mem_zalloc(sizeof(*llist));
547 
548 	if (!llist) {
549 		LOG_ERR("%s: Unable to allocate memory for linked list", __func__);
550 	}
551 
552 	return llist;
553 }
554 
zep_shim_ctrl_llist_alloc(void)555 static void *zep_shim_ctrl_llist_alloc(void)
556 {
557 	struct zep_shim_llist *llist = NULL;
558 
559 	llist = zep_shim_mem_zalloc(sizeof(*llist));
560 
561 	if (!llist) {
562 		LOG_ERR("%s: Unable to allocate memory for linked list", __func__);
563 	}
564 
565 	return llist;
566 }
567 
zep_shim_llist_free(void * llist)568 static void zep_shim_llist_free(void *llist)
569 {
570 	zep_shim_data_mem_free(llist);
571 }
572 
zep_shim_ctrl_llist_free(void * llist)573 static void zep_shim_ctrl_llist_free(void *llist)
574 {
575 	zep_shim_mem_free(llist);
576 }
577 
zep_shim_llist_init(void * llist)578 static void zep_shim_llist_init(void *llist)
579 {
580 	struct zep_shim_llist *zep_llist = NULL;
581 
582 	zep_llist = (struct zep_shim_llist *)llist;
583 
584 	sys_dlist_init(&zep_llist->head);
585 }
586 
zep_shim_llist_add_node_tail(void * llist,void * llist_node)587 static void zep_shim_llist_add_node_tail(void *llist, void *llist_node)
588 {
589 	struct zep_shim_llist *zep_llist = NULL;
590 	struct zep_shim_llist_node *zep_node = NULL;
591 
592 	zep_llist = (struct zep_shim_llist *)llist;
593 	zep_node = (struct zep_shim_llist_node *)llist_node;
594 
595 	sys_dlist_append(&zep_llist->head, &zep_node->head);
596 
597 	zep_llist->len += 1;
598 }
599 
zep_shim_llist_add_node_head(void * llist,void * llist_node)600 static void zep_shim_llist_add_node_head(void *llist, void *llist_node)
601 {
602 	struct zep_shim_llist *zep_llist = NULL;
603 	struct zep_shim_llist_node *zep_node = NULL;
604 
605 	zep_llist = (struct zep_shim_llist *)llist;
606 	zep_node = (struct zep_shim_llist_node *)llist_node;
607 
608 	sys_dlist_prepend(&zep_llist->head, &zep_node->head);
609 
610 	zep_llist->len += 1;
611 }
612 
zep_shim_llist_get_node_head(void * llist)613 static void *zep_shim_llist_get_node_head(void *llist)
614 {
615 	struct zep_shim_llist_node *zep_head_node = NULL;
616 	struct zep_shim_llist *zep_llist = NULL;
617 
618 	zep_llist = (struct zep_shim_llist *)llist;
619 
620 	if (!zep_llist->len) {
621 		return NULL;
622 	}
623 
624 	zep_head_node = (struct zep_shim_llist_node *)sys_dlist_peek_head(&zep_llist->head);
625 
626 	return zep_head_node;
627 }
628 
zep_shim_llist_get_node_nxt(void * llist,void * llist_node)629 static void *zep_shim_llist_get_node_nxt(void *llist, void *llist_node)
630 {
631 	struct zep_shim_llist_node *zep_node = NULL;
632 	struct zep_shim_llist_node *zep_nxt_node = NULL;
633 	struct zep_shim_llist *zep_llist = NULL;
634 
635 	zep_llist = (struct zep_shim_llist *)llist;
636 	zep_node = (struct zep_shim_llist_node *)llist_node;
637 
638 	zep_nxt_node = (struct zep_shim_llist_node *)sys_dlist_peek_next(&zep_llist->head,
639 									 &zep_node->head);
640 
641 	return zep_nxt_node;
642 }
643 
zep_shim_llist_del_node(void * llist,void * llist_node)644 static void zep_shim_llist_del_node(void *llist, void *llist_node)
645 {
646 	struct zep_shim_llist_node *zep_node = NULL;
647 	struct zep_shim_llist *zep_llist = NULL;
648 
649 	zep_llist = (struct zep_shim_llist *)llist;
650 	zep_node = (struct zep_shim_llist_node *)llist_node;
651 
652 	sys_dlist_remove(&zep_node->head);
653 
654 	zep_llist->len -= 1;
655 }
656 
zep_shim_llist_len(void * llist)657 static unsigned int zep_shim_llist_len(void *llist)
658 {
659 	struct zep_shim_llist *zep_llist = NULL;
660 
661 	zep_llist = (struct zep_shim_llist *)llist;
662 
663 	return zep_llist->len;
664 }
665 
zep_shim_work_alloc(int type)666 static void *zep_shim_work_alloc(int type)
667 {
668 	return work_alloc(type);
669 }
670 
zep_shim_work_free(void * item)671 static void zep_shim_work_free(void *item)
672 {
673 	work_free(item);
674 }
675 
zep_shim_work_init(void * item,void (* callback)(unsigned long data),unsigned long data)676 static void zep_shim_work_init(void *item, void (*callback)(unsigned long data),
677 				  unsigned long data)
678 {
679 	work_init(item, callback, data);
680 }
681 
zep_shim_work_schedule(void * item)682 static void zep_shim_work_schedule(void *item)
683 {
684 	work_schedule(item);
685 }
686 
zep_shim_work_kill(void * item)687 static void zep_shim_work_kill(void *item)
688 {
689 	work_kill(item);
690 }
691 
zep_shim_time_get_curr_us(void)692 static unsigned long zep_shim_time_get_curr_us(void)
693 {
694 	return k_uptime_get() * USEC_PER_MSEC;
695 }
696 
zep_shim_time_elapsed_us(unsigned long start_time_us)697 static unsigned int zep_shim_time_elapsed_us(unsigned long start_time_us)
698 {
699 	unsigned long curr_time_us = 0;
700 
701 	curr_time_us = zep_shim_time_get_curr_us();
702 
703 	return curr_time_us - start_time_us;
704 }
705 
zep_shim_time_get_curr_ms(void)706 static unsigned long zep_shim_time_get_curr_ms(void)
707 {
708 	return k_uptime_get();
709 }
710 
zep_shim_time_elapsed_ms(unsigned long start_time_ms)711 static unsigned int zep_shim_time_elapsed_ms(unsigned long start_time_ms)
712 {
713 	unsigned long curr_time_ms = 0;
714 
715 	curr_time_ms = zep_shim_time_get_curr_ms();
716 
717 	return curr_time_ms - start_time_ms;
718 }
719 
zep_shim_bus_qspi_dev_init(void * os_qspi_dev_ctx)720 static enum nrf_wifi_status zep_shim_bus_qspi_dev_init(void *os_qspi_dev_ctx)
721 {
722 	ARG_UNUSED(os_qspi_dev_ctx);
723 
724 	return NRF_WIFI_STATUS_SUCCESS;
725 }
726 
zep_shim_bus_qspi_dev_deinit(void * priv)727 static void zep_shim_bus_qspi_dev_deinit(void *priv)
728 {
729 	struct zep_shim_bus_qspi_priv *qspi_priv = priv;
730 	volatile struct qspi_dev *dev = qspi_priv->qspi_dev;
731 
732 	dev->deinit();
733 }
734 
zep_shim_bus_qspi_dev_add(void * os_qspi_priv,void * osal_qspi_dev_ctx)735 static void *zep_shim_bus_qspi_dev_add(void *os_qspi_priv, void *osal_qspi_dev_ctx)
736 {
737 	struct zep_shim_bus_qspi_priv *zep_qspi_priv = os_qspi_priv;
738 	struct qspi_dev *dev = qspi_dev();
739 	int ret;
740 	enum nrf_wifi_status status;
741 
742 	ret = rpu_init();
743 	if (ret) {
744 		LOG_ERR("%s: RPU init failed with error %d", __func__, ret);
745 		return NULL;
746 	}
747 
748 	status = dev->init(qspi_defconfig());
749 	if (status != NRF_WIFI_STATUS_SUCCESS) {
750 		LOG_ERR("%s: QSPI device init failed", __func__);
751 		return NULL;
752 	}
753 
754 	ret = rpu_enable();
755 	if (ret) {
756 		LOG_ERR("%s: RPU enable failed with error %d", __func__, ret);
757 		return NULL;
758 	}
759 	zep_qspi_priv->qspi_dev = dev;
760 	zep_qspi_priv->dev_added = true;
761 
762 	return zep_qspi_priv;
763 }
764 
zep_shim_bus_qspi_dev_rem(void * priv)765 static void zep_shim_bus_qspi_dev_rem(void *priv)
766 {
767 	struct zep_shim_bus_qspi_priv *qspi_priv = priv;
768 	struct qspi_dev *dev = qspi_priv->qspi_dev;
769 
770 	ARG_UNUSED(dev);
771 
772 	/* TODO: Make qspi_dev a dynamic instance and remove it here */
773 	rpu_disable();
774 }
775 
zep_shim_bus_qspi_init(void)776 static void *zep_shim_bus_qspi_init(void)
777 {
778 	struct zep_shim_bus_qspi_priv *qspi_priv = NULL;
779 
780 	qspi_priv = zep_shim_mem_zalloc(sizeof(*qspi_priv));
781 
782 	if (!qspi_priv) {
783 		LOG_ERR("%s: Unable to allocate memory for qspi_priv", __func__);
784 		goto out;
785 	}
786 out:
787 	return qspi_priv;
788 }
789 
zep_shim_bus_qspi_deinit(void * os_qspi_priv)790 static void zep_shim_bus_qspi_deinit(void *os_qspi_priv)
791 {
792 	struct zep_shim_bus_qspi_priv *qspi_priv = NULL;
793 
794 	qspi_priv = os_qspi_priv;
795 
796 	zep_shim_mem_free(qspi_priv);
797 }
798 
799 #ifdef CONFIG_NRF_WIFI_LOW_POWER
zep_shim_bus_qspi_ps_sleep(void * os_qspi_priv)800 static int zep_shim_bus_qspi_ps_sleep(void *os_qspi_priv)
801 {
802 	rpu_sleep();
803 
804 	return 0;
805 }
806 
zep_shim_bus_qspi_ps_wake(void * os_qspi_priv)807 static int zep_shim_bus_qspi_ps_wake(void *os_qspi_priv)
808 {
809 	rpu_wakeup();
810 
811 	return 0;
812 }
813 
zep_shim_bus_qspi_ps_status(void * os_qspi_priv)814 static int zep_shim_bus_qspi_ps_status(void *os_qspi_priv)
815 {
816 	return rpu_sleep_status();
817 }
818 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
819 
zep_shim_bus_qspi_dev_host_map_get(void * os_qspi_dev_ctx,struct nrf_wifi_osal_host_map * host_map)820 static void zep_shim_bus_qspi_dev_host_map_get(void *os_qspi_dev_ctx,
821 					       struct nrf_wifi_osal_host_map *host_map)
822 {
823 	if (!os_qspi_dev_ctx || !host_map) {
824 		LOG_ERR("%s: Invalid parameters", __func__);
825 		return;
826 	}
827 
828 	host_map->addr = 0;
829 }
830 
irq_work_handler(struct k_work * work)831 static void irq_work_handler(struct k_work *work)
832 {
833 	int ret = 0;
834 
835 	if (!intr_priv || !intr_priv->callbk_fn || !intr_priv->callbk_data) {
836 		LOG_ERR("%s: Invalid intr_priv handler", __func__);
837 		return;
838 	}
839 
840 	ret = intr_priv->callbk_fn(intr_priv->callbk_data);
841 
842 	if (ret) {
843 		LOG_ERR("%s: Interrupt callback failed", __func__);
844 	}
845 }
846 
847 
848 extern struct k_work_q zep_wifi_intr_q;
849 
zep_shim_irq_handler(const struct device * dev,struct gpio_callback * cb,uint32_t pins)850 static void zep_shim_irq_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
851 {
852 	ARG_UNUSED(cb);
853 	ARG_UNUSED(pins);
854 
855 	if (!(intr_priv && intr_priv->callbk_fn && intr_priv->callbk_data)) {
856 		LOG_ERR("%s: Invalid intr_priv", __func__);
857 		return;
858 	}
859 
860 	k_work_schedule_for_queue(&zep_wifi_intr_q, &intr_priv->work, K_NO_WAIT);
861 }
862 
zep_shim_bus_qspi_intr_reg(void * os_dev_ctx,void * callbk_data,int (* callbk_fn)(void * callbk_data))863 static enum nrf_wifi_status zep_shim_bus_qspi_intr_reg(void *os_dev_ctx, void *callbk_data,
864 						       int (*callbk_fn)(void *callbk_data))
865 {
866 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
867 	int ret = -1;
868 
869 	ARG_UNUSED(os_dev_ctx);
870 
871 	intr_priv = zep_shim_mem_zalloc(sizeof(*intr_priv));
872 
873 	if (!intr_priv) {
874 		LOG_ERR("%s: Unable to allocate memory for intr_priv", __func__);
875 		goto out;
876 	}
877 
878 	intr_priv->callbk_data = callbk_data;
879 	intr_priv->callbk_fn = callbk_fn;
880 
881 	k_work_init_delayable(&intr_priv->work, irq_work_handler);
882 
883 	ret = rpu_irq_config(&intr_priv->gpio_cb_data, zep_shim_irq_handler);
884 
885 	if (ret) {
886 		LOG_ERR("%s: request_irq failed", __func__);
887 		zep_shim_mem_free(intr_priv);
888 		intr_priv = NULL;
889 		goto out;
890 	}
891 
892 	status = NRF_WIFI_STATUS_SUCCESS;
893 
894 out:
895 	return status;
896 }
897 
zep_shim_bus_qspi_intr_unreg(void * os_qspi_dev_ctx)898 static void zep_shim_bus_qspi_intr_unreg(void *os_qspi_dev_ctx)
899 {
900 	struct k_work_sync sync;
901 	int ret;
902 
903 	ARG_UNUSED(os_qspi_dev_ctx);
904 
905 	ret = rpu_irq_remove(&intr_priv->gpio_cb_data);
906 	if (ret) {
907 		LOG_ERR("%s: rpu_irq_remove failed", __func__);
908 		return;
909 	}
910 
911 	k_work_cancel_delayable_sync(&intr_priv->work, &sync);
912 
913 	zep_shim_mem_free(intr_priv);
914 	intr_priv = NULL;
915 }
916 
917 #ifdef CONFIG_NRF_WIFI_LOW_POWER
zep_shim_timer_alloc(void)918 static void *zep_shim_timer_alloc(void)
919 {
920 	struct timer_list *timer = NULL;
921 
922 	timer = zep_shim_mem_zalloc(sizeof(*timer));
923 
924 	if (!timer) {
925 		LOG_ERR("%s: Unable to allocate memory for work", __func__);
926 	}
927 
928 	return timer;
929 }
930 
zep_shim_timer_init(void * timer,void (* callback)(unsigned long),unsigned long data)931 static void zep_shim_timer_init(void *timer, void (*callback)(unsigned long), unsigned long data)
932 {
933 	((struct timer_list *)timer)->function = callback;
934 	((struct timer_list *)timer)->data = data;
935 
936 	init_timer(timer);
937 }
938 
zep_shim_timer_free(void * timer)939 static void zep_shim_timer_free(void *timer)
940 {
941 	zep_shim_mem_free(timer);
942 }
943 
zep_shim_timer_schedule(void * timer,unsigned long duration)944 static void zep_shim_timer_schedule(void *timer, unsigned long duration)
945 {
946 	mod_timer(timer, duration);
947 }
948 
zep_shim_timer_kill(void * timer)949 static void zep_shim_timer_kill(void *timer)
950 {
951 	del_timer_sync(timer);
952 }
953 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
954 
zep_shim_assert(int test_val,int val,enum nrf_wifi_assert_op_type op,char * msg)955 static void zep_shim_assert(int test_val, int val, enum nrf_wifi_assert_op_type op, char *msg)
956 {
957 	switch (op) {
958 	case NRF_WIFI_ASSERT_EQUAL_TO:
959 		NET_ASSERT(test_val == val, "%s", msg);
960 	break;
961 	case NRF_WIFI_ASSERT_NOT_EQUAL_TO:
962 		NET_ASSERT(test_val != val, "%s", msg);
963 	break;
964 	case NRF_WIFI_ASSERT_LESS_THAN:
965 		NET_ASSERT(test_val < val, "%s", msg);
966 	break;
967 	case NRF_WIFI_ASSERT_LESS_THAN_EQUAL_TO:
968 		NET_ASSERT(test_val <= val, "%s", msg);
969 	break;
970 	case NRF_WIFI_ASSERT_GREATER_THAN:
971 		NET_ASSERT(test_val > val, "%s", msg);
972 	break;
973 	case NRF_WIFI_ASSERT_GREATER_THAN_EQUAL_TO:
974 		NET_ASSERT(test_val >= val, "%s", msg);
975 	break;
976 	default:
977 		LOG_ERR("%s: Invalid assertion operation", __func__);
978 	}
979 }
980 
zep_shim_strlen(const void * str)981 static unsigned int zep_shim_strlen(const void *str)
982 {
983 	return strlen(str);
984 }
985 
986 const struct nrf_wifi_osal_ops nrf_wifi_os_zep_ops = {
987 	.mem_alloc = zep_shim_mem_alloc,
988 	.mem_zalloc = zep_shim_mem_zalloc,
989 	.data_mem_zalloc = zep_shim_data_mem_zalloc,
990 	.mem_free = zep_shim_mem_free,
991 	.data_mem_free = zep_shim_data_mem_free,
992 	.mem_cpy = zep_shim_mem_cpy,
993 	.mem_set = zep_shim_mem_set,
994 	.mem_cmp = zep_shim_mem_cmp,
995 
996 	.qspi_read_reg32 = zep_shim_qspi_read_reg32,
997 	.qspi_write_reg32 = zep_shim_qspi_write_reg32,
998 	.qspi_cpy_from = zep_shim_qspi_cpy_from,
999 	.qspi_cpy_to = zep_shim_qspi_cpy_to,
1000 
1001 	.spinlock_alloc = zep_shim_spinlock_alloc,
1002 	.spinlock_free = zep_shim_spinlock_free,
1003 	.spinlock_init = zep_shim_spinlock_init,
1004 	.spinlock_take = zep_shim_spinlock_take,
1005 	.spinlock_rel = zep_shim_spinlock_rel,
1006 
1007 	.spinlock_irq_take = zep_shim_spinlock_irq_take,
1008 	.spinlock_irq_rel = zep_shim_spinlock_irq_rel,
1009 
1010 	.log_dbg = zep_shim_pr_dbg,
1011 	.log_info = zep_shim_pr_info,
1012 	.log_err = zep_shim_pr_err,
1013 
1014 	.llist_node_alloc = zep_shim_llist_node_alloc,
1015 	.llist_node_free = zep_shim_llist_node_free,
1016 	.llist_node_data_get = zep_shim_llist_node_data_get,
1017 	.llist_node_data_set = zep_shim_llist_node_data_set,
1018 
1019 	.llist_alloc = zep_shim_llist_alloc,
1020 	.ctrl_llist_alloc = zep_shim_ctrl_llist_alloc,
1021 	.llist_free = zep_shim_llist_free,
1022 	.ctrl_llist_free = zep_shim_ctrl_llist_free,
1023 	.llist_init = zep_shim_llist_init,
1024 	.llist_add_node_tail = zep_shim_llist_add_node_tail,
1025 	.llist_add_node_head = zep_shim_llist_add_node_head,
1026 	.llist_get_node_head = zep_shim_llist_get_node_head,
1027 	.llist_get_node_nxt = zep_shim_llist_get_node_nxt,
1028 	.llist_del_node = zep_shim_llist_del_node,
1029 	.llist_len = zep_shim_llist_len,
1030 
1031 	.nbuf_alloc = zep_shim_nbuf_alloc,
1032 	.nbuf_free = zep_shim_nbuf_free,
1033 	.nbuf_headroom_res = zep_shim_nbuf_headroom_res,
1034 	.nbuf_headroom_get = zep_shim_nbuf_headroom_get,
1035 	.nbuf_data_size = zep_shim_nbuf_data_size,
1036 	.nbuf_data_get = zep_shim_nbuf_data_get,
1037 	.nbuf_data_put = zep_shim_nbuf_data_put,
1038 	.nbuf_data_push = zep_shim_nbuf_data_push,
1039 	.nbuf_data_pull = zep_shim_nbuf_data_pull,
1040 	.nbuf_get_priority = zep_shim_nbuf_get_priority,
1041 	.nbuf_get_chksum_done = zep_shim_nbuf_get_chksum_done,
1042 	.nbuf_set_chksum_done = zep_shim_nbuf_set_chksum_done,
1043 
1044 	.tasklet_alloc = zep_shim_work_alloc,
1045 	.tasklet_free = zep_shim_work_free,
1046 	.tasklet_init = zep_shim_work_init,
1047 	.tasklet_schedule = zep_shim_work_schedule,
1048 	.tasklet_kill = zep_shim_work_kill,
1049 
1050 	.sleep_ms = k_msleep,
1051 	.delay_us = k_usleep,
1052 	.time_get_curr_us = zep_shim_time_get_curr_us,
1053 	.time_elapsed_us = zep_shim_time_elapsed_us,
1054 	.time_get_curr_ms = zep_shim_time_get_curr_ms,
1055 	.time_elapsed_ms = zep_shim_time_elapsed_ms,
1056 
1057 	.bus_qspi_init = zep_shim_bus_qspi_init,
1058 	.bus_qspi_deinit = zep_shim_bus_qspi_deinit,
1059 	.bus_qspi_dev_add = zep_shim_bus_qspi_dev_add,
1060 	.bus_qspi_dev_rem = zep_shim_bus_qspi_dev_rem,
1061 	.bus_qspi_dev_init = zep_shim_bus_qspi_dev_init,
1062 	.bus_qspi_dev_deinit = zep_shim_bus_qspi_dev_deinit,
1063 	.bus_qspi_dev_intr_reg = zep_shim_bus_qspi_intr_reg,
1064 	.bus_qspi_dev_intr_unreg = zep_shim_bus_qspi_intr_unreg,
1065 	.bus_qspi_dev_host_map_get = zep_shim_bus_qspi_dev_host_map_get,
1066 
1067 #ifdef CONFIG_NRF_WIFI_LOW_POWER
1068 	.timer_alloc = zep_shim_timer_alloc,
1069 	.timer_init = zep_shim_timer_init,
1070 	.timer_free = zep_shim_timer_free,
1071 	.timer_schedule = zep_shim_timer_schedule,
1072 	.timer_kill = zep_shim_timer_kill,
1073 
1074 	.bus_qspi_ps_sleep = zep_shim_bus_qspi_ps_sleep,
1075 	.bus_qspi_ps_wake = zep_shim_bus_qspi_ps_wake,
1076 	.bus_qspi_ps_status = zep_shim_bus_qspi_ps_status,
1077 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
1078 
1079 	.assert = zep_shim_assert,
1080 	.strlen = zep_shim_strlen,
1081 };
1082