Skip to content

Commit 3c86e5b

Browse files
krish2718nordicjm
authored andcommitted
[nrf fromlist] nrf_wifi: Add nRF71 support
nRF7120 PDK support that uses IPC as comms b/w APP and Wi-Fi domains. Upstream PR #: 88816 Signed-off-by: Chaitanya Tata <[email protected]>
1 parent d8dae50 commit 3c86e5b

File tree

16 files changed

+978
-17
lines changed

16 files changed

+978
-17
lines changed

drivers/wifi/nrf_wifi/CMakeLists.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ zephyr_library_sources_ifndef(CONFIG_NRF70_OFFLOADED_RAW_TX
2727
src/fmac_main.c
2828
)
2929

30-
zephyr_library_sources_ifdef(CONFIG_NRF_WIFI_PATCHES_BUILTIN
31-
src/fw_load.c
32-
)
30+
if(NOT CONFIG_NRF71_ON_IPC)
31+
zephyr_library_sources_ifdef(CONFIG_NRF_WIFI_PATCHES_BUILTIN
32+
src/fw_load.c
33+
)
34+
endif()
3335

3436
if(NOT CONFIG_NRF70_RADIO_TEST AND NOT CONFIG_NRF70_OFFLOADED_RAW_TX)
3537
zephyr_library_sources(

drivers/wifi/nrf_wifi/Kconfig.nrfwifi

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# SPDX-License-Identifier: Apache-2.0
66
#
77

8+
# TODO: Use DTS generated Kconfig once the board support is added
9+
DT_COMPAT_NORDIC_WIFI71 := nordic,wifi71
10+
811
menuconfig WIFI_NRF70
912
bool "nRF70 driver"
1013
select NET_L2_WIFI_MGMT if NETWORKING
@@ -16,15 +19,16 @@ menuconfig WIFI_NRF70
1619
depends on \
1720
DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || \
1821
DT_HAS_NORDIC_NRF7001_SPI_ENABLED || DT_HAS_NORDIC_NRF7001_QSPI_ENABLED || \
19-
DT_HAS_NORDIC_NRF7000_SPI_ENABLED || DT_HAS_NORDIC_NRF7000_QSPI_ENABLED
22+
DT_HAS_NORDIC_NRF7000_SPI_ENABLED || DT_HAS_NORDIC_NRF7000_QSPI_ENABLED || \
23+
$(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71))
2024
help
2125
Nordic Wi-Fi Driver
2226

2327
if WIFI_NRF70
2428
# Hidden symbols for internal use
2529
config WIFI_NRF7002
2630
bool
27-
default y if DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED
31+
default y if DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71))
2832

2933
config WIFI_NRF7001
3034
bool
@@ -133,6 +137,7 @@ endchoice
133137

134138
config NRF_WIFI_LOW_POWER
135139
bool "Low power mode in nRF Wi-Fi chipsets"
140+
depends on !NRF71_ON_IPC
136141
default y
137142

138143
config NRF70_TCP_IP_CHECKSUM_OFFLOAD
@@ -184,6 +189,7 @@ config NRF70_SR_COEX_RF_SWITCH
184189

185190
config NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL
186191
bool "Configuration of GPIO control for coexistence"
192+
depends on !NRF71_ON_IPC
187193
default y
188194

189195
config NRF70_SR_COEX_SWCTRL1_OUTPUT

drivers/wifi/nrf_wifi/src/fmac_main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,12 @@ void reg_change_callbk_fn(void *vif_ctx,
479479
}
480480
#endif /* !CONFIG_NRF70_RADIO_TEST */
481481

482+
#ifdef CONFIG_NRF71_ON_IPC
483+
#define MAX_TX_PWR(label) DT_PROP(DT_NODELABEL(wifi), label) * 4
484+
#else
482485
/* DTS uses 1dBm as the unit for TX power, while the RPU uses 0.25dBm */
483486
#define MAX_TX_PWR(label) DT_PROP(DT_NODELABEL(nrf70), label) * 4
487+
#endif /* CONFIG_NRF71_ON_IPC */
484488

485489
void configure_tx_pwr_settings(struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
486490
struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params)

drivers/wifi/nrf_wifi/src/fw_load.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ enum nrf_wifi_status nrf_wifi_fw_load(void *rpu_ctx)
3131
LOG_ERR("%s: nrf_wifi_fmac_fw_parse failed", __func__);
3232
return status;
3333
}
34+
#ifndef CONFIG_NRF71_ON_IPC
3435
/* Load the FW patches to the RPU */
3536
status = nrf_wifi_fmac_fw_load(rpu_ctx, &fw_info);
3637

3738
if (status != NRF_WIFI_STATUS_SUCCESS) {
3839
LOG_ERR("%s: nrf_wifi_fmac_fw_load failed", __func__);
3940
}
40-
41+
#endif /* !CONFIG_NRF71_ON_IPC */
4142
return status;
4243
}

drivers/wifi/nrf_wifi/src/net_if.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ enum nrf_wifi_status nrf_wifi_get_mac_addr(struct nrf_wifi_vif_ctx_zep *vif_ctx_
565565
random_mac_addr,
566566
WIFI_MAC_ADDR_LEN);
567567
#elif CONFIG_WIFI_OTP_MAC_ADDRESS
568+
#ifndef CONFIG_NRF71_ON_IPC
568569
status = nrf_wifi_fmac_otp_mac_addr_get(fmac_dev_ctx,
569570
vif_ctx_zep->vif_idx,
570571
vif_ctx_zep->mac_addr.addr);
@@ -573,6 +574,15 @@ enum nrf_wifi_status nrf_wifi_get_mac_addr(struct nrf_wifi_vif_ctx_zep *vif_ctx_
573574
__func__);
574575
goto unlock;
575576
}
577+
#else
578+
/* Set dummy MAC address */
579+
vif_ctx_zep->mac_addr.addr[0] = 0x00;
580+
vif_ctx_zep->mac_addr.addr[1] = 0x00;
581+
vif_ctx_zep->mac_addr.addr[2] = 0x5E;
582+
vif_ctx_zep->mac_addr.addr[3] = 0x00;
583+
vif_ctx_zep->mac_addr.addr[4] = 0x10;
584+
vif_ctx_zep->mac_addr.addr[5] = 0x00;
585+
#endif /* !CONFIG_NRF71_ON_IPC */
576586
#endif
577587

578588
if (!nrf_wifi_utils_is_mac_addr_valid(vif_ctx_zep->mac_addr.addr)) {

modules/nrf_wifi/bus/CMakeLists.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,18 @@ if (CONFIG_NRF70_BUSLIB)
1717
inc
1818
${NRF_WIFI_DIR}/os_if/inc
1919
)
20+
zephyr_library_include_directories_ifdef(CONFIG_NRF71_ON_IPC
21+
${NRF_WIFI_DIR}/bus_if/bal/inc
22+
# QSPI is common to (Q)SPI and IPC
23+
${NRF_WIFI_DIR}/bus_if/bus/qspi/inc
24+
${NRF_WIFI_DIR}/fw_if/umac_if/inc/fw
25+
${NRF_WIFI_DIR}/hw_if/hal/inc
26+
)
27+
28+
zephyr_library_compile_definitions_ifdef(CONFIG_NRF71_ON_IPC
29+
NRF71_ON_IPC
30+
)
2031
zephyr_library_sources(
21-
rpu_hw_if.c
2232
device.c
2333
)
2434
if(NOT CONFIG_WIFI_NRF70)
@@ -27,9 +37,16 @@ if (CONFIG_NRF70_BUSLIB)
2737
)
2838
endif()
2939
zephyr_library_sources_ifdef(CONFIG_NRF70_ON_QSPI
40+
rpu_hw_if.c
3041
qspi_if.c
3142
)
3243
zephyr_library_sources_ifdef(CONFIG_NRF70_ON_SPI
44+
rpu_hw_if.c
3345
spi_if.c
3446
)
47+
zephyr_library_sources_ifdef(CONFIG_NRF71_ON_IPC
48+
ipc_if.c
49+
ipc_service.c
50+
spsc_qm.c
51+
)
3552
endif()

modules/nrf_wifi/bus/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ DT_COMPAT_NORDIC_NRF7001_QSPI := nordic,nrf7001-qspi
1010
DT_COMPAT_NORDIC_NRF7001_SPI := nordic,nrf7001-spi
1111
DT_COMPAT_NORDIC_NRF7000_QSPI := nordic,nrf7000-qspi
1212
DT_COMPAT_NORDIC_NRF7000_SPI := nordic,nrf7000-spi
13+
DT_COMPAT_NORDIC_WIFI71 := nordic,wifi71
1314

1415
menuconfig NRF70_BUSLIB
1516
bool "NRF70 Bus Library"
@@ -30,6 +31,15 @@ config NRF70_ON_SPI
3031
$(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7000_SPI))
3132
select SPI
3233

34+
config NRF71_ON_IPC
35+
def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71))
36+
select MBOX
37+
select IPC_SERVICE
38+
select SPSC_PBUF
39+
help
40+
nRF71 is a Wi-Fi and BLE combo SoC and uses IPC as a communication
41+
between APP and Wi-Fi cores.
42+
3343
module = WIFI_NRF70_BUSLIB
3444
module-dep = LOG
3545
module-str = Log level for Wi-Fi nRF70 bus library

modules/nrf_wifi/bus/device.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,26 @@
1212
#include <zephyr/kernel.h>
1313
#include <zephyr/sys/printk.h>
1414
#include <zephyr/drivers/gpio.h>
15-
#include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
1615
#include <stdio.h>
1716
#include <string.h>
1817

18+
#if defined(CONFIG_NRF71_ON_IPC)
19+
#include "ipc_if.h"
20+
#else
21+
#include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
1922
#include "spi_if.h"
20-
2123
static struct qspi_config config;
24+
#endif
2225

23-
#if defined(CONFIG_NRF70_ON_QSPI)
26+
#if defined(CONFIG_NRF71_ON_IPC)
27+
static struct rpu_dev ipc = {
28+
.init = ipc_init,
29+
.deinit = ipc_deinit,
30+
.send = ipc_send,
31+
.recv = ipc_recv,
32+
.register_rx_cb = ipc_register_rx_cb,
33+
};
34+
#elif defined(CONFIG_NRF70_ON_QSPI)
2435
static struct qspi_dev qspi = {.init = qspi_init,
2536
.deinit = qspi_deinit,
2637
.read = qspi_read,
@@ -34,6 +45,7 @@ static struct qspi_dev spim = {.init = spim_init,
3445
.hl_read = spim_hl_read};
3546
#endif
3647

48+
#ifndef CONFIG_NRF71_ON_IPC
3749
struct qspi_config *qspi_defconfig(void)
3850
{
3951
memset(&config, 0, sizeof(struct qspi_config));
@@ -71,12 +83,20 @@ struct qspi_config *qspi_get_config(void)
7183
{
7284
return &config;
7385
}
86+
#endif
7487

88+
#ifndef CONFIG_NRF71_ON_IPC
7589
struct qspi_dev *qspi_dev(void)
7690
{
77-
#if CONFIG_NRF70_ON_QSPI
91+
#if defined(CONFIG_NRF70_ON_QSPI)
7892
return &qspi;
7993
#else
8094
return &spim;
8195
#endif
8296
}
97+
#else
98+
struct rpu_dev *rpu_dev(void)
99+
{
100+
return &ipc;
101+
}
102+
#endif /*! CONFIG_NRF71_ON_IPC */

modules/nrf_wifi/bus/ipc_if.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @brief File containing API definitions for the
9+
* IPC bus layer of the nRF71 Wi-Fi driver.
10+
*/
11+
#include <zephyr/kernel.h>
12+
#include <zephyr/logging/log.h>
13+
14+
LOG_MODULE_DECLARE(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL);
15+
16+
#include "ipc_if.h"
17+
#include "bal_structs.h"
18+
#include "qspi.h"
19+
#include "common/hal_structs_common.h"
20+
21+
/* Define addresses to use for the free queues */
22+
#define EVENT_FREEQ_ADDR 0x200C2000
23+
#define CMD_FREEQ_ADDR 0x200C3000
24+
25+
#define NUM_INSTANCES 3
26+
#define NUM_ENDPOINTS 1
27+
28+
struct device *ipc_instances[NUM_INSTANCES];
29+
struct ipc_ept ept[NUM_ENDPOINTS];
30+
struct ipc_ept_cfg ept_cfg[NUM_ENDPOINTS];
31+
32+
static wifi_ipc_t wifi_event;
33+
static wifi_ipc_t wifi_cmd;
34+
static wifi_ipc_t wifi_tx;
35+
36+
static int (*callback_func)(void *data);
37+
38+
static void event_recv(void *data, void *priv)
39+
{
40+
struct nrf_wifi_bus_qspi_dev_ctx *dev_ctx = NULL;
41+
struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
42+
struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
43+
44+
dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)priv;
45+
bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)dev_ctx->bal_dev_ctx;
46+
hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)bal_dev_ctx->hal_dev_ctx;
47+
LOG_DBG("Event IPC received");
48+
49+
hal_dev_ctx->ipc_msg = data;
50+
callback_func(priv);
51+
LOG_DBG("Event IPC callback completed");
52+
}
53+
54+
int ipc_init(void)
55+
{
56+
wifi_ipc_host_event_init(&wifi_event, EVENT_FREEQ_ADDR);
57+
LOG_DBG("Event IPC initialized");
58+
wifi_ipc_host_cmd_init(&wifi_cmd, CMD_FREEQ_ADDR);
59+
LOG_DBG("Command IPC initialized");
60+
return 0;
61+
}
62+
63+
int ipc_deinit(void)
64+
{
65+
return 0;
66+
}
67+
68+
int ipc_recv(ipc_ctx_t ctx, void *data, int len)
69+
{
70+
return 0;
71+
}
72+
73+
int ipc_send(ipc_ctx_t ctx, const void *data, int len)
74+
{
75+
76+
int ret = 0;
77+
78+
switch (ctx.inst) {
79+
case IPC_INSTANCE_CMD_CTRL:
80+
/* IPC service on RPU may not have been established. Keep trying. */
81+
do {
82+
ret = wifi_ipc_host_cmd_send_memcpy(&wifi_cmd, data, len);
83+
} while (ret == WIFI_IPC_STATUS_BUSYQ_NOTREADY);
84+
85+
/* Critical error during IPC service transfer. Should never happen. */
86+
if (ret == WIFI_IPC_STATUS_BUSYQ_CRITICAL_ERR) {
87+
LOG_ERR("Critical error during IPC CMD busyq transfer");
88+
return -1;
89+
}
90+
break;
91+
case IPC_INSTANCE_CMD_TX:
92+
/* IPC service on RPU may not have been established. Keep trying. */
93+
do {
94+
ret = wifi_ipc_host_tx_send(&wifi_tx, data);
95+
} while (ret == WIFI_IPC_STATUS_BUSYQ_NOTREADY);
96+
97+
/* Critical error during IPC service transfer. Should never happen. */
98+
if (ret == WIFI_IPC_STATUS_BUSYQ_CRITICAL_ERR) {
99+
LOG_ERR("Critical error during IPC TX busyq transfer");
100+
return -1;
101+
}
102+
case IPC_INSTANCE_RX:
103+
break;
104+
default:
105+
break;
106+
}
107+
108+
LOG_DBG("IPC send completed: %d", ret);
109+
110+
return ret;
111+
}
112+
113+
int ipc_register_rx_cb(int (*rx_handler)(void *priv), void *data)
114+
{
115+
int ret;
116+
117+
callback_func = rx_handler;
118+
119+
ret = wifi_ipc_bind_ipc_service_tx_rx(&wifi_cmd, &wifi_event,
120+
DEVICE_DT_GET(DT_NODELABEL(ipc0)), event_recv, data);
121+
if (ret != WIFI_IPC_STATUS_OK) {
122+
LOG_ERR("Failed to bind IPC service: %d", ret);
123+
return -1;
124+
}
125+
126+
ret = wifi_ipc_bind_ipc_service(&wifi_tx, DEVICE_DT_GET(DT_NODELABEL(ipc1)), event_recv,
127+
data);
128+
if (ret != WIFI_IPC_STATUS_OK) {
129+
LOG_ERR("Failed to bind IPC service: %d", ret);
130+
return -1;
131+
}
132+
133+
return 0;
134+
}

0 commit comments

Comments
 (0)