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