Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions drivers/wifi/nrf_wifi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ zephyr_library_sources_ifndef(CONFIG_NRF70_OFFLOADED_RAW_TX
src/fmac_main.c
)

zephyr_library_sources_ifdef(CONFIG_NRF_WIFI_PATCHES_BUILTIN
src/fw_load.c
)
if(NOT CONFIG_NRF71_ON_IPC)
zephyr_library_sources_ifdef(CONFIG_NRF_WIFI_PATCHES_BUILTIN
src/fw_load.c
)
endif()

if(NOT CONFIG_NRF70_RADIO_TEST AND NOT CONFIG_NRF70_OFFLOADED_RAW_TX)
zephyr_library_sources(
Expand Down
10 changes: 8 additions & 2 deletions drivers/wifi/nrf_wifi/Kconfig.nrfwifi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
# SPDX-License-Identifier: Apache-2.0
#

# TODO: Use DTS generated Kconfig once the board support is added
DT_COMPAT_NORDIC_WIFI71 := nordic,wifi71

menuconfig WIFI_NRF70
bool "nRF70 driver"
select NET_L2_WIFI_MGMT if NETWORKING
Expand All @@ -16,15 +19,16 @@ menuconfig WIFI_NRF70
depends on \
DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || \
DT_HAS_NORDIC_NRF7001_SPI_ENABLED || DT_HAS_NORDIC_NRF7001_QSPI_ENABLED || \
DT_HAS_NORDIC_NRF7000_SPI_ENABLED || DT_HAS_NORDIC_NRF7000_QSPI_ENABLED
DT_HAS_NORDIC_NRF7000_SPI_ENABLED || DT_HAS_NORDIC_NRF7000_QSPI_ENABLED || \
$(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71))
help
Nordic Wi-Fi Driver

if WIFI_NRF70
# Hidden symbols for internal use
config WIFI_NRF7002
bool
default y if DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED
default y if DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71))

config WIFI_NRF7001
bool
Expand Down Expand Up @@ -133,6 +137,7 @@ endchoice

config NRF_WIFI_LOW_POWER
bool "Low power mode in nRF Wi-Fi chipsets"
depends on !NRF71_ON_IPC
default y

config NRF70_TCP_IP_CHECKSUM_OFFLOAD
Expand Down Expand Up @@ -184,6 +189,7 @@ config NRF70_SR_COEX_RF_SWITCH

config NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL
bool "Configuration of GPIO control for coexistence"
depends on !NRF71_ON_IPC
default y

config NRF70_SR_COEX_SWCTRL1_OUTPUT
Expand Down
4 changes: 4 additions & 0 deletions drivers/wifi/nrf_wifi/src/fmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,12 @@ void reg_change_callbk_fn(void *vif_ctx,
}
#endif /* !CONFIG_NRF70_RADIO_TEST */

#ifdef CONFIG_NRF71_ON_IPC
#define MAX_TX_PWR(label) DT_PROP(DT_NODELABEL(wifi), label) * 4
#else
/* DTS uses 1dBm as the unit for TX power, while the RPU uses 0.25dBm */
#define MAX_TX_PWR(label) DT_PROP(DT_NODELABEL(nrf70), label) * 4
#endif /* CONFIG_NRF71_ON_IPC */

void configure_tx_pwr_settings(struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params)
Expand Down
3 changes: 2 additions & 1 deletion drivers/wifi/nrf_wifi/src/fw_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ enum nrf_wifi_status nrf_wifi_fw_load(void *rpu_ctx)
LOG_ERR("%s: nrf_wifi_fmac_fw_parse failed", __func__);
return status;
}
#ifndef CONFIG_NRF71_ON_IPC
/* Load the FW patches to the RPU */
status = nrf_wifi_fmac_fw_load(rpu_ctx, &fw_info);

if (status != NRF_WIFI_STATUS_SUCCESS) {
LOG_ERR("%s: nrf_wifi_fmac_fw_load failed", __func__);
}

#endif /* !CONFIG_NRF71_ON_IPC */
return status;
}
10 changes: 10 additions & 0 deletions drivers/wifi/nrf_wifi/src/net_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ enum nrf_wifi_status nrf_wifi_get_mac_addr(struct nrf_wifi_vif_ctx_zep *vif_ctx_
random_mac_addr,
WIFI_MAC_ADDR_LEN);
#elif CONFIG_WIFI_OTP_MAC_ADDRESS
#ifndef CONFIG_NRF71_ON_IPC
status = nrf_wifi_fmac_otp_mac_addr_get(fmac_dev_ctx,
vif_ctx_zep->vif_idx,
vif_ctx_zep->mac_addr.addr);
Expand All @@ -573,6 +574,15 @@ enum nrf_wifi_status nrf_wifi_get_mac_addr(struct nrf_wifi_vif_ctx_zep *vif_ctx_
__func__);
goto unlock;
}
#else
/* Set dummy MAC address */
vif_ctx_zep->mac_addr.addr[0] = 0x00;
vif_ctx_zep->mac_addr.addr[1] = 0x00;
vif_ctx_zep->mac_addr.addr[2] = 0x5E;
vif_ctx_zep->mac_addr.addr[3] = 0x00;
vif_ctx_zep->mac_addr.addr[4] = 0x10;
vif_ctx_zep->mac_addr.addr[5] = 0x00;
#endif /* !CONFIG_NRF71_ON_IPC */
#endif

if (!nrf_wifi_utils_is_mac_addr_valid(vif_ctx_zep->mac_addr.addr)) {
Expand Down
19 changes: 18 additions & 1 deletion modules/nrf_wifi/bus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,18 @@ if (CONFIG_NRF70_BUSLIB)
inc
${NRF_WIFI_DIR}/os_if/inc
)
zephyr_library_include_directories_ifdef(CONFIG_NRF71_ON_IPC
${NRF_WIFI_DIR}/bus_if/bal/inc
# QSPI is common to (Q)SPI and IPC
${NRF_WIFI_DIR}/bus_if/bus/qspi/inc
${NRF_WIFI_DIR}/fw_if/umac_if/inc/fw
${NRF_WIFI_DIR}/hw_if/hal/inc
)

zephyr_library_compile_definitions_ifdef(CONFIG_NRF71_ON_IPC
NRF71_ON_IPC
)
zephyr_library_sources(
rpu_hw_if.c
device.c
)
if(NOT CONFIG_WIFI_NRF70)
Expand All @@ -27,9 +37,16 @@ if (CONFIG_NRF70_BUSLIB)
)
endif()
zephyr_library_sources_ifdef(CONFIG_NRF70_ON_QSPI
rpu_hw_if.c
qspi_if.c
)
zephyr_library_sources_ifdef(CONFIG_NRF70_ON_SPI
rpu_hw_if.c
spi_if.c
)
zephyr_library_sources_ifdef(CONFIG_NRF71_ON_IPC
ipc_if.c
ipc_service.c
spsc_qm.c
)
endif()
10 changes: 10 additions & 0 deletions modules/nrf_wifi/bus/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ DT_COMPAT_NORDIC_NRF7001_QSPI := nordic,nrf7001-qspi
DT_COMPAT_NORDIC_NRF7001_SPI := nordic,nrf7001-spi
DT_COMPAT_NORDIC_NRF7000_QSPI := nordic,nrf7000-qspi
DT_COMPAT_NORDIC_NRF7000_SPI := nordic,nrf7000-spi
DT_COMPAT_NORDIC_WIFI71 := nordic,wifi71

menuconfig NRF70_BUSLIB
bool "NRF70 Bus Library"
Expand All @@ -30,6 +31,15 @@ config NRF70_ON_SPI
$(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7000_SPI))
select SPI

config NRF71_ON_IPC
def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71))
select MBOX
select IPC_SERVICE
select SPSC_PBUF
help
nRF71 is a Wi-Fi and BLE combo SoC and uses IPC as a communication
between APP and Wi-Fi cores.

module = WIFI_NRF70_BUSLIB
module-dep = LOG
module-str = Log level for Wi-Fi nRF70 bus library
Expand Down
28 changes: 24 additions & 4 deletions modules/nrf_wifi/bus/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,26 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
#include <stdio.h>
#include <string.h>

#if defined(CONFIG_NRF71_ON_IPC)
#include "ipc_if.h"
#else
#include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
#include "spi_if.h"

static struct qspi_config config;
#endif

#if defined(CONFIG_NRF70_ON_QSPI)
#if defined(CONFIG_NRF71_ON_IPC)
static struct rpu_dev ipc = {
.init = ipc_init,
.deinit = ipc_deinit,
.send = ipc_send,
.recv = ipc_recv,
.register_rx_cb = ipc_register_rx_cb,
};
#elif defined(CONFIG_NRF70_ON_QSPI)
static struct qspi_dev qspi = {.init = qspi_init,
.deinit = qspi_deinit,
.read = qspi_read,
Expand All @@ -34,6 +45,7 @@ static struct qspi_dev spim = {.init = spim_init,
.hl_read = spim_hl_read};
#endif

#ifndef CONFIG_NRF71_ON_IPC
struct qspi_config *qspi_defconfig(void)
{
memset(&config, 0, sizeof(struct qspi_config));
Expand Down Expand Up @@ -71,12 +83,20 @@ struct qspi_config *qspi_get_config(void)
{
return &config;
}
#endif

#ifndef CONFIG_NRF71_ON_IPC
struct qspi_dev *qspi_dev(void)
{
#if CONFIG_NRF70_ON_QSPI
#if defined(CONFIG_NRF70_ON_QSPI)
return &qspi;
#else
return &spim;
#endif
}
#else
struct rpu_dev *rpu_dev(void)
{
return &ipc;
}
#endif /*! CONFIG_NRF71_ON_IPC */
134 changes: 134 additions & 0 deletions modules/nrf_wifi/bus/ipc_if.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @brief File containing API definitions for the
* IPC bus layer of the nRF71 Wi-Fi driver.
*/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL);

#include "ipc_if.h"
#include "bal_structs.h"
#include "qspi.h"
#include "common/hal_structs_common.h"

/* Define addresses to use for the free queues */
#define EVENT_FREEQ_ADDR 0x200C2000
#define CMD_FREEQ_ADDR 0x200C3000

#define NUM_INSTANCES 3
#define NUM_ENDPOINTS 1

struct device *ipc_instances[NUM_INSTANCES];
struct ipc_ept ept[NUM_ENDPOINTS];
struct ipc_ept_cfg ept_cfg[NUM_ENDPOINTS];

static wifi_ipc_t wifi_event;
static wifi_ipc_t wifi_cmd;
static wifi_ipc_t wifi_tx;

static int (*callback_func)(void *data);

static void event_recv(void *data, void *priv)
{
struct nrf_wifi_bus_qspi_dev_ctx *dev_ctx = NULL;
struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL;
struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;

dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)priv;
bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)dev_ctx->bal_dev_ctx;
hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)bal_dev_ctx->hal_dev_ctx;
LOG_DBG("Event IPC received");

hal_dev_ctx->ipc_msg = data;
callback_func(priv);
LOG_DBG("Event IPC callback completed");
}

int ipc_init(void)
{
wifi_ipc_host_event_init(&wifi_event, EVENT_FREEQ_ADDR);
LOG_DBG("Event IPC initialized");
wifi_ipc_host_cmd_init(&wifi_cmd, CMD_FREEQ_ADDR);
LOG_DBG("Command IPC initialized");
return 0;
}

int ipc_deinit(void)
{
return 0;
}

int ipc_recv(ipc_ctx_t ctx, void *data, int len)
{
return 0;
}

int ipc_send(ipc_ctx_t ctx, const void *data, int len)
{

int ret = 0;

switch (ctx.inst) {
case IPC_INSTANCE_CMD_CTRL:
/* IPC service on RPU may not have been established. Keep trying. */
do {
ret = wifi_ipc_host_cmd_send_memcpy(&wifi_cmd, data, len);
} while (ret == WIFI_IPC_STATUS_BUSYQ_NOTREADY);

/* Critical error during IPC service transfer. Should never happen. */
if (ret == WIFI_IPC_STATUS_BUSYQ_CRITICAL_ERR) {
LOG_ERR("Critical error during IPC CMD busyq transfer");
return -1;
}
break;
case IPC_INSTANCE_CMD_TX:
/* IPC service on RPU may not have been established. Keep trying. */
do {
ret = wifi_ipc_host_tx_send(&wifi_tx, data);
} while (ret == WIFI_IPC_STATUS_BUSYQ_NOTREADY);

/* Critical error during IPC service transfer. Should never happen. */
if (ret == WIFI_IPC_STATUS_BUSYQ_CRITICAL_ERR) {
LOG_ERR("Critical error during IPC TX busyq transfer");
return -1;
}
case IPC_INSTANCE_RX:
break;
default:
break;
}

LOG_DBG("IPC send completed: %d", ret);

return ret;
}

int ipc_register_rx_cb(int (*rx_handler)(void *priv), void *data)
{
int ret;

callback_func = rx_handler;

ret = wifi_ipc_bind_ipc_service_tx_rx(&wifi_cmd, &wifi_event,
DEVICE_DT_GET(DT_NODELABEL(ipc0)), event_recv, data);
if (ret != WIFI_IPC_STATUS_OK) {
LOG_ERR("Failed to bind IPC service: %d", ret);
return -1;
}

ret = wifi_ipc_bind_ipc_service(&wifi_tx, DEVICE_DT_GET(DT_NODELABEL(ipc1)), event_recv,
data);
if (ret != WIFI_IPC_STATUS_OK) {
LOG_ERR("Failed to bind IPC service: %d", ret);
return -1;
}

return 0;
}
Loading
Loading