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