/* * Copyright (c) 2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ /** * @brief Header containing OS specific definitions for the * Zephyr OS layer of the Wi-Fi driver. */ #include #include #include #include #include #include #include #include #include #include #include "shim.h" #include "work.h" #include "timer.h" #include "osal_ops.h" LOG_MODULE_REGISTER(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); struct zep_shim_intr_priv *intr_priv; static void *zep_shim_mem_alloc(size_t size) { size_t size_aligned = ROUND_UP(size, 4); return k_malloc(size_aligned); } static void *zep_shim_mem_zalloc(size_t size) { size_t size_aligned = ROUND_UP(size, 4); return k_calloc(size_aligned, sizeof(char)); } static void *zep_shim_mem_cpy(void *dest, const void *src, size_t count) { return memcpy(dest, src, count); } static void *zep_shim_mem_set(void *start, int val, size_t size) { return memset(start, val, size); } static int zep_shim_mem_cmp(const void *addr1, const void *addr2, size_t size) { return memcmp(addr1, addr2, size); } static unsigned int zep_shim_qspi_read_reg32(void *priv, unsigned long addr) { unsigned int val; struct zep_shim_bus_qspi_priv *qspi_priv = priv; struct qspi_dev *dev; dev = qspi_priv->qspi_dev; if (addr < 0x0C0000) { dev->hl_read(addr, &val, 4); } else { dev->read(addr, &val, 4); } return val; } static void zep_shim_qspi_write_reg32(void *priv, unsigned long addr, unsigned int val) { struct zep_shim_bus_qspi_priv *qspi_priv = priv; struct qspi_dev *dev; dev = qspi_priv->qspi_dev; dev->write(addr, &val, 4); } static void zep_shim_qspi_cpy_from(void *priv, void *dest, unsigned long addr, size_t count) { struct zep_shim_bus_qspi_priv *qspi_priv = priv; struct qspi_dev *dev; size_t count_aligned = ROUND_UP(count, 4); dev = qspi_priv->qspi_dev; if (addr < 0x0C0000) { dev->hl_read(addr, dest, count_aligned); } else { dev->read(addr, dest, count_aligned); } } static void zep_shim_qspi_cpy_to(void *priv, unsigned long addr, const void *src, size_t count) { struct zep_shim_bus_qspi_priv *qspi_priv = priv; struct qspi_dev *dev; size_t count_aligned = ROUND_UP(count, 4); dev = qspi_priv->qspi_dev; dev->write(addr, src, count_aligned); } static void *zep_shim_spinlock_alloc(void) { struct k_mutex *lock = NULL; lock = k_malloc(sizeof(*lock)); if (!lock) { LOG_ERR("%s: Unable to allocate memory for spinlock", __func__); } return lock; } static void zep_shim_spinlock_free(void *lock) { k_free(lock); } static void zep_shim_spinlock_init(void *lock) { k_mutex_init(lock); } static void zep_shim_spinlock_take(void *lock) { k_mutex_lock(lock, K_FOREVER); } static void zep_shim_spinlock_rel(void *lock) { k_mutex_unlock(lock); } static void zep_shim_spinlock_irq_take(void *lock, unsigned long *flags) { ARG_UNUSED(flags); k_mutex_lock(lock, K_FOREVER); } static void zep_shim_spinlock_irq_rel(void *lock, unsigned long *flags) { ARG_UNUSED(flags); k_mutex_unlock(lock); } static int zep_shim_pr_dbg(const char *fmt, va_list args) { static char buf[80]; vsnprintf(buf, sizeof(buf), fmt, args); LOG_DBG("%s", buf); return 0; } static int zep_shim_pr_info(const char *fmt, va_list args) { static char buf[80]; vsnprintf(buf, sizeof(buf), fmt, args); LOG_INF("%s", buf); return 0; } static int zep_shim_pr_err(const char *fmt, va_list args) { static char buf[256]; vsnprintf(buf, sizeof(buf), fmt, args); LOG_ERR("%s", buf); return 0; } struct nwb { unsigned char *data; unsigned char *tail; int len; int headroom; void *next; void *priv; int iftype; void *ifaddr; void *dev; int hostbuffer; void *cleanup_ctx; void (*cleanup_cb)(); unsigned char priority; bool chksum_done; }; static void *zep_shim_nbuf_alloc(unsigned int size) { struct nwb *nbuff; nbuff = (struct nwb *)k_calloc(sizeof(struct nwb), sizeof(char)); if (!nbuff) { return NULL; } nbuff->priv = k_calloc(size, sizeof(char)); if (!nbuff->priv) { k_free(nbuff); return NULL; } nbuff->data = (unsigned char *)nbuff->priv; nbuff->tail = nbuff->data; nbuff->len = 0; nbuff->headroom = 0; nbuff->next = NULL; return nbuff; } static void zep_shim_nbuf_free(void *nbuf) { if (!nbuf) { return; } k_free(((struct nwb *)nbuf)->priv); k_free(nbuf); } static void zep_shim_nbuf_headroom_res(void *nbuf, unsigned int size) { struct nwb *nwb = (struct nwb *)nbuf; nwb->data += size; nwb->tail += size; nwb->headroom += size; } static unsigned int zep_shim_nbuf_headroom_get(void *nbuf) { return ((struct nwb *)nbuf)->headroom; } static unsigned int zep_shim_nbuf_data_size(void *nbuf) { return ((struct nwb *)nbuf)->len; } static void *zep_shim_nbuf_data_get(void *nbuf) { return ((struct nwb *)nbuf)->data; } static void *zep_shim_nbuf_data_put(void *nbuf, unsigned int size) { struct nwb *nwb = (struct nwb *)nbuf; unsigned char *data = nwb->tail; nwb->tail += size; nwb->len += size; return data; } static void *zep_shim_nbuf_data_push(void *nbuf, unsigned int size) { struct nwb *nwb = (struct nwb *)nbuf; nwb->data -= size; nwb->headroom -= size; nwb->len += size; return nwb->data; } static void *zep_shim_nbuf_data_pull(void *nbuf, unsigned int size) { struct nwb *nwb = (struct nwb *)nbuf; nwb->data += size; nwb->headroom += size; nwb->len -= size; return nwb->data; } static unsigned char zep_shim_nbuf_get_priority(void *nbuf) { struct nwb *nwb = (struct nwb *)nbuf; return nwb->priority; } static unsigned char zep_shim_nbuf_get_chksum_done(void *nbuf) { struct nwb *nwb = (struct nwb *)nbuf; return nwb->chksum_done; } static void zep_shim_nbuf_set_chksum_done(void *nbuf, unsigned char chksum_done) { struct nwb *nwb = (struct nwb *)nbuf; nwb->chksum_done = (bool)chksum_done; } #include #include void *net_pkt_to_nbuf(struct net_pkt *pkt) { struct nwb *nbuff; unsigned char *data; unsigned int len; len = net_pkt_get_len(pkt); nbuff = zep_shim_nbuf_alloc(len + 100); if (!nbuff) { return NULL; } zep_shim_nbuf_headroom_res(nbuff, 100); data = zep_shim_nbuf_data_put(nbuff, len); net_pkt_read(pkt, data, len); nbuff->priority = net_pkt_priority(pkt); nbuff->chksum_done = (bool)net_pkt_is_chksum_done(pkt); return nbuff; } void *net_pkt_from_nbuf(void *iface, void *frm) { struct net_pkt *pkt = NULL; unsigned char *data; unsigned int len; struct nwb *nwb = frm; if (!nwb) { return NULL; } len = zep_shim_nbuf_data_size(nwb); data = zep_shim_nbuf_data_get(nwb); pkt = net_pkt_rx_alloc_with_buffer(iface, len, AF_UNSPEC, 0, K_MSEC(100)); if (!pkt) { goto out; } if (net_pkt_write(pkt, data, len)) { net_pkt_unref(pkt); pkt = NULL; goto out; } out: zep_shim_nbuf_free(nwb); return pkt; } #if defined(CONFIG_NRF70_RAW_DATA_RX) || defined(CONFIG_NRF70_PROMISC_DATA_RX) void *net_raw_pkt_from_nbuf(void *iface, void *frm, unsigned short raw_hdr_len, void *raw_rx_hdr, bool pkt_free) { struct net_pkt *pkt = NULL; unsigned char *nwb_data; unsigned char *data = NULL; unsigned int nwb_len; unsigned int total_len; struct nwb *nwb = frm; if (!nwb) { LOG_ERR("%s: Received network buffer is NULL", __func__); return NULL; } nwb_len = zep_shim_nbuf_data_size(nwb); nwb_data = zep_shim_nbuf_data_get(nwb); total_len = raw_hdr_len + nwb_len; data = (unsigned char *)k_malloc(total_len); if (!data) { LOG_ERR("%s: Unable to allocate memory for sniffer data packet", __func__); goto out; } pkt = net_pkt_rx_alloc_with_buffer(iface, total_len, AF_PACKET, ETH_P_ALL, K_MSEC(100)); if (!pkt) { LOG_ERR("%s: Unable to allocate net packet buffer", __func__); goto out; } memcpy(data, raw_rx_hdr, raw_hdr_len); memcpy((data+raw_hdr_len), nwb_data, nwb_len); if (net_pkt_write(pkt, data, total_len)) { net_pkt_unref(pkt); pkt = NULL; goto out; } out: if (data != NULL) { k_free(data); } if (pkt_free) { zep_shim_nbuf_free(nwb); } return pkt; } #endif /* CONFIG_NRF70_RAW_DATA_RX || CONFIG_NRF70_PROMISC_DATA_RX */ static void *zep_shim_llist_node_alloc(void) { struct zep_shim_llist_node *llist_node = NULL; llist_node = k_calloc(sizeof(*llist_node), sizeof(char)); if (!llist_node) { LOG_ERR("%s: Unable to allocate memory for linked list node", __func__); return NULL; } sys_dnode_init(&llist_node->head); return llist_node; } static void zep_shim_llist_node_free(void *llist_node) { k_free(llist_node); } static void *zep_shim_llist_node_data_get(void *llist_node) { struct zep_shim_llist_node *zep_llist_node = NULL; zep_llist_node = (struct zep_shim_llist_node *)llist_node; return zep_llist_node->data; } static void zep_shim_llist_node_data_set(void *llist_node, void *data) { struct zep_shim_llist_node *zep_llist_node = NULL; zep_llist_node = (struct zep_shim_llist_node *)llist_node; zep_llist_node->data = data; } static void *zep_shim_llist_alloc(void) { struct zep_shim_llist *llist = NULL; llist = k_calloc(sizeof(*llist), sizeof(char)); if (!llist) { LOG_ERR("%s: Unable to allocate memory for linked list", __func__); } return llist; } static void zep_shim_llist_free(void *llist) { k_free(llist); } static void zep_shim_llist_init(void *llist) { struct zep_shim_llist *zep_llist = NULL; zep_llist = (struct zep_shim_llist *)llist; sys_dlist_init(&zep_llist->head); } static void zep_shim_llist_add_node_tail(void *llist, void *llist_node) { struct zep_shim_llist *zep_llist = NULL; struct zep_shim_llist_node *zep_node = NULL; zep_llist = (struct zep_shim_llist *)llist; zep_node = (struct zep_shim_llist_node *)llist_node; sys_dlist_append(&zep_llist->head, &zep_node->head); zep_llist->len += 1; } static void zep_shim_llist_add_node_head(void *llist, void *llist_node) { struct zep_shim_llist *zep_llist = NULL; struct zep_shim_llist_node *zep_node = NULL; zep_llist = (struct zep_shim_llist *)llist; zep_node = (struct zep_shim_llist_node *)llist_node; sys_dlist_prepend(&zep_llist->head, &zep_node->head); zep_llist->len += 1; } static void *zep_shim_llist_get_node_head(void *llist) { struct zep_shim_llist_node *zep_head_node = NULL; struct zep_shim_llist *zep_llist = NULL; zep_llist = (struct zep_shim_llist *)llist; if (!zep_llist->len) { return NULL; } zep_head_node = (struct zep_shim_llist_node *)sys_dlist_peek_head(&zep_llist->head); return zep_head_node; } static void *zep_shim_llist_get_node_nxt(void *llist, void *llist_node) { struct zep_shim_llist_node *zep_node = NULL; struct zep_shim_llist_node *zep_nxt_node = NULL; struct zep_shim_llist *zep_llist = NULL; zep_llist = (struct zep_shim_llist *)llist; zep_node = (struct zep_shim_llist_node *)llist_node; zep_nxt_node = (struct zep_shim_llist_node *)sys_dlist_peek_next(&zep_llist->head, &zep_node->head); return zep_nxt_node; } static void zep_shim_llist_del_node(void *llist, void *llist_node) { struct zep_shim_llist_node *zep_node = NULL; struct zep_shim_llist *zep_llist = NULL; zep_llist = (struct zep_shim_llist *)llist; zep_node = (struct zep_shim_llist_node *)llist_node; sys_dlist_remove(&zep_node->head); zep_llist->len -= 1; } static unsigned int zep_shim_llist_len(void *llist) { struct zep_shim_llist *zep_llist = NULL; zep_llist = (struct zep_shim_llist *)llist; return zep_llist->len; } static void *zep_shim_work_alloc(int type) { return work_alloc(type); } static void zep_shim_work_free(void *item) { work_free(item); } static void zep_shim_work_init(void *item, void (*callback)(unsigned long data), unsigned long data) { work_init(item, callback, data); } static void zep_shim_work_schedule(void *item) { work_schedule(item); } static void zep_shim_work_kill(void *item) { work_kill(item); } static unsigned long zep_shim_time_get_curr_us(void) { return k_uptime_get() * USEC_PER_MSEC; } static unsigned int zep_shim_time_elapsed_us(unsigned long start_time_us) { unsigned long curr_time_us = 0; curr_time_us = zep_shim_time_get_curr_us(); return curr_time_us - start_time_us; } static unsigned long zep_shim_time_get_curr_ms(void) { return k_uptime_get(); } static unsigned int zep_shim_time_elapsed_ms(unsigned long start_time_ms) { unsigned long curr_time_ms = 0; curr_time_ms = zep_shim_time_get_curr_ms(); return curr_time_ms - start_time_ms; } static enum nrf_wifi_status zep_shim_bus_qspi_dev_init(void *os_qspi_dev_ctx) { ARG_UNUSED(os_qspi_dev_ctx); return NRF_WIFI_STATUS_SUCCESS; } static void zep_shim_bus_qspi_dev_deinit(void *priv) { struct zep_shim_bus_qspi_priv *qspi_priv = priv; volatile struct qspi_dev *dev = qspi_priv->qspi_dev; dev->deinit(); } static void *zep_shim_bus_qspi_dev_add(void *os_qspi_priv, void *osal_qspi_dev_ctx) { struct zep_shim_bus_qspi_priv *zep_qspi_priv = os_qspi_priv; struct qspi_dev *dev = qspi_dev(); int ret; enum nrf_wifi_status status; ret = rpu_init(); if (ret) { LOG_ERR("%s: RPU init failed with error %d", __func__, ret); return NULL; } status = dev->init(qspi_defconfig()); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: QSPI device init failed", __func__); return NULL; } ret = rpu_enable(); if (ret) { LOG_ERR("%s: RPU enable failed with error %d", __func__, ret); return NULL; } zep_qspi_priv->qspi_dev = dev; zep_qspi_priv->dev_added = true; return zep_qspi_priv; } static void zep_shim_bus_qspi_dev_rem(void *priv) { struct zep_shim_bus_qspi_priv *qspi_priv = priv; struct qspi_dev *dev = qspi_priv->qspi_dev; ARG_UNUSED(dev); /* TODO: Make qspi_dev a dynamic instance and remove it here */ rpu_disable(); } static void *zep_shim_bus_qspi_init(void) { struct zep_shim_bus_qspi_priv *qspi_priv = NULL; qspi_priv = k_calloc(sizeof(*qspi_priv), sizeof(char)); if (!qspi_priv) { LOG_ERR("%s: Unable to allocate memory for qspi_priv", __func__); goto out; } out: return qspi_priv; } static void zep_shim_bus_qspi_deinit(void *os_qspi_priv) { struct zep_shim_bus_qspi_priv *qspi_priv = NULL; qspi_priv = os_qspi_priv; k_free(qspi_priv); } #ifdef CONFIG_NRF_WIFI_LOW_POWER static int zep_shim_bus_qspi_ps_sleep(void *os_qspi_priv) { rpu_sleep(); return 0; } static int zep_shim_bus_qspi_ps_wake(void *os_qspi_priv) { rpu_wakeup(); return 0; } static int zep_shim_bus_qspi_ps_status(void *os_qspi_priv) { return rpu_sleep_status(); } #endif /* CONFIG_NRF_WIFI_LOW_POWER */ static void zep_shim_bus_qspi_dev_host_map_get(void *os_qspi_dev_ctx, struct nrf_wifi_osal_host_map *host_map) { if (!os_qspi_dev_ctx || !host_map) { LOG_ERR("%s: Invalid parameters", __func__); return; } host_map->addr = 0; } static void irq_work_handler(struct k_work *work) { int ret = 0; if (!intr_priv || !intr_priv->callbk_fn || !intr_priv->callbk_data) { LOG_ERR("%s: Invalid intr_priv handler", __func__); return; } ret = intr_priv->callbk_fn(intr_priv->callbk_data); if (ret) { LOG_ERR("%s: Interrupt callback failed", __func__); } } extern struct k_work_q zep_wifi_intr_q; static void zep_shim_irq_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { ARG_UNUSED(cb); ARG_UNUSED(pins); if (!(intr_priv && intr_priv->callbk_fn && intr_priv->callbk_data)) { LOG_ERR("%s: Invalid intr_priv", __func__); return; } k_work_schedule_for_queue(&zep_wifi_intr_q, &intr_priv->work, K_NO_WAIT); } static enum nrf_wifi_status zep_shim_bus_qspi_intr_reg(void *os_dev_ctx, void *callbk_data, int (*callbk_fn)(void *callbk_data)) { enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; int ret = -1; ARG_UNUSED(os_dev_ctx); intr_priv = k_calloc(sizeof(*intr_priv), sizeof(char)); if (!intr_priv) { LOG_ERR("%s: Unable to allocate memory for intr_priv", __func__); goto out; } intr_priv->callbk_data = callbk_data; intr_priv->callbk_fn = callbk_fn; k_work_init_delayable(&intr_priv->work, irq_work_handler); ret = rpu_irq_config(&intr_priv->gpio_cb_data, zep_shim_irq_handler); if (ret) { LOG_ERR("%s: request_irq failed", __func__); k_free(intr_priv); intr_priv = NULL; goto out; } status = NRF_WIFI_STATUS_SUCCESS; out: return status; } static void zep_shim_bus_qspi_intr_unreg(void *os_qspi_dev_ctx) { struct k_work_sync sync; int ret; ARG_UNUSED(os_qspi_dev_ctx); ret = rpu_irq_remove(&intr_priv->gpio_cb_data); if (ret) { LOG_ERR("%s: rpu_irq_remove failed", __func__); return; } k_work_cancel_delayable_sync(&intr_priv->work, &sync); k_free(intr_priv); intr_priv = NULL; } #ifdef CONFIG_NRF_WIFI_LOW_POWER static void *zep_shim_timer_alloc(void) { struct timer_list *timer = NULL; timer = k_malloc(sizeof(*timer)); if (!timer) { LOG_ERR("%s: Unable to allocate memory for work", __func__); } return timer; } static void zep_shim_timer_init(void *timer, void (*callback)(unsigned long), unsigned long data) { ((struct timer_list *)timer)->function = callback; ((struct timer_list *)timer)->data = data; init_timer(timer); } static void zep_shim_timer_free(void *timer) { k_free(timer); } static void zep_shim_timer_schedule(void *timer, unsigned long duration) { mod_timer(timer, duration); } static void zep_shim_timer_kill(void *timer) { del_timer_sync(timer); } #endif /* CONFIG_NRF_WIFI_LOW_POWER */ static void zep_shim_assert(int test_val, int val, enum nrf_wifi_assert_op_type op, char *msg) { switch (op) { case NRF_WIFI_ASSERT_EQUAL_TO: NET_ASSERT(test_val == val, "%s", msg); break; case NRF_WIFI_ASSERT_NOT_EQUAL_TO: NET_ASSERT(test_val != val, "%s", msg); break; case NRF_WIFI_ASSERT_LESS_THAN: NET_ASSERT(test_val < val, "%s", msg); break; case NRF_WIFI_ASSERT_LESS_THAN_EQUAL_TO: NET_ASSERT(test_val <= val, "%s", msg); break; case NRF_WIFI_ASSERT_GREATER_THAN: NET_ASSERT(test_val > val, "%s", msg); break; case NRF_WIFI_ASSERT_GREATER_THAN_EQUAL_TO: NET_ASSERT(test_val >= val, "%s", msg); break; default: LOG_ERR("%s: Invalid assertion operation", __func__); } } static unsigned int zep_shim_strlen(const void *str) { return strlen(str); } const struct nrf_wifi_osal_ops nrf_wifi_os_zep_ops = { .mem_alloc = zep_shim_mem_alloc, .mem_zalloc = zep_shim_mem_zalloc, .mem_free = k_free, .mem_cpy = zep_shim_mem_cpy, .mem_set = zep_shim_mem_set, .mem_cmp = zep_shim_mem_cmp, .qspi_read_reg32 = zep_shim_qspi_read_reg32, .qspi_write_reg32 = zep_shim_qspi_write_reg32, .qspi_cpy_from = zep_shim_qspi_cpy_from, .qspi_cpy_to = zep_shim_qspi_cpy_to, .spinlock_alloc = zep_shim_spinlock_alloc, .spinlock_free = zep_shim_spinlock_free, .spinlock_init = zep_shim_spinlock_init, .spinlock_take = zep_shim_spinlock_take, .spinlock_rel = zep_shim_spinlock_rel, .spinlock_irq_take = zep_shim_spinlock_irq_take, .spinlock_irq_rel = zep_shim_spinlock_irq_rel, .log_dbg = zep_shim_pr_dbg, .log_info = zep_shim_pr_info, .log_err = zep_shim_pr_err, .llist_node_alloc = zep_shim_llist_node_alloc, .llist_node_free = zep_shim_llist_node_free, .llist_node_data_get = zep_shim_llist_node_data_get, .llist_node_data_set = zep_shim_llist_node_data_set, .llist_alloc = zep_shim_llist_alloc, .llist_free = zep_shim_llist_free, .llist_init = zep_shim_llist_init, .llist_add_node_tail = zep_shim_llist_add_node_tail, .llist_add_node_head = zep_shim_llist_add_node_head, .llist_get_node_head = zep_shim_llist_get_node_head, .llist_get_node_nxt = zep_shim_llist_get_node_nxt, .llist_del_node = zep_shim_llist_del_node, .llist_len = zep_shim_llist_len, .nbuf_alloc = zep_shim_nbuf_alloc, .nbuf_free = zep_shim_nbuf_free, .nbuf_headroom_res = zep_shim_nbuf_headroom_res, .nbuf_headroom_get = zep_shim_nbuf_headroom_get, .nbuf_data_size = zep_shim_nbuf_data_size, .nbuf_data_get = zep_shim_nbuf_data_get, .nbuf_data_put = zep_shim_nbuf_data_put, .nbuf_data_push = zep_shim_nbuf_data_push, .nbuf_data_pull = zep_shim_nbuf_data_pull, .nbuf_get_priority = zep_shim_nbuf_get_priority, .nbuf_get_chksum_done = zep_shim_nbuf_get_chksum_done, .nbuf_set_chksum_done = zep_shim_nbuf_set_chksum_done, .tasklet_alloc = zep_shim_work_alloc, .tasklet_free = zep_shim_work_free, .tasklet_init = zep_shim_work_init, .tasklet_schedule = zep_shim_work_schedule, .tasklet_kill = zep_shim_work_kill, .sleep_ms = k_msleep, .delay_us = k_usleep, .time_get_curr_us = zep_shim_time_get_curr_us, .time_elapsed_us = zep_shim_time_elapsed_us, .time_get_curr_ms = zep_shim_time_get_curr_ms, .time_elapsed_ms = zep_shim_time_elapsed_ms, .bus_qspi_init = zep_shim_bus_qspi_init, .bus_qspi_deinit = zep_shim_bus_qspi_deinit, .bus_qspi_dev_add = zep_shim_bus_qspi_dev_add, .bus_qspi_dev_rem = zep_shim_bus_qspi_dev_rem, .bus_qspi_dev_init = zep_shim_bus_qspi_dev_init, .bus_qspi_dev_deinit = zep_shim_bus_qspi_dev_deinit, .bus_qspi_dev_intr_reg = zep_shim_bus_qspi_intr_reg, .bus_qspi_dev_intr_unreg = zep_shim_bus_qspi_intr_unreg, .bus_qspi_dev_host_map_get = zep_shim_bus_qspi_dev_host_map_get, #ifdef CONFIG_NRF_WIFI_LOW_POWER .timer_alloc = zep_shim_timer_alloc, .timer_init = zep_shim_timer_init, .timer_free = zep_shim_timer_free, .timer_schedule = zep_shim_timer_schedule, .timer_kill = zep_shim_timer_kill, .bus_qspi_ps_sleep = zep_shim_bus_qspi_ps_sleep, .bus_qspi_ps_wake = zep_shim_bus_qspi_ps_wake, .bus_qspi_ps_status = zep_shim_bus_qspi_ps_status, #endif /* CONFIG_NRF_WIFI_LOW_POWER */ .assert = zep_shim_assert, .strlen = zep_shim_strlen, };