Skip to content

drivers: wifi: nrf7002: Add support for multiple virtual interfaces #91916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
6 changes: 5 additions & 1 deletion boards/nordic/nrf7002dk/nrf70_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ wifi-max-tx-pwr-2g-dsss = <21>;
wifi-max-tx-pwr-2g-mcs0 = <16>;
wifi-max-tx-pwr-2g-mcs7 = <16>;

wlan0: wlan {
wlan0: wlan0 {
compatible = "nordic,wlan";
};

wlan1: wlan1 {
compatible = "nordic,wlan";
};
4 changes: 4 additions & 0 deletions boards/shields/nrf7002eb/nrf7002eb.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
compatible = "nordic,wlan";
};

wlan1: wlan1 {
compatible = "nordic,wlan";
};

wifi-max-tx-pwr-2g-dsss = <21>;
wifi-max-tx-pwr-2g-mcs0 = <16>;
wifi-max-tx-pwr-2g-mcs7 = <16>;
Expand Down
4 changes: 4 additions & 0 deletions boards/shields/nrf7002ek/nrf7002ek_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ wifi-max-tx-pwr-2g-mcs7 = <16>;
wlan0: wlan0 {
compatible = "nordic,wlan";
};

wlan1: wlan1 {
compatible = "nordic,wlan";
};
9 changes: 9 additions & 0 deletions drivers/wifi/nrf_wifi/Kconfig.nrfwifi
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ config NRF70_AP_MODE
depends on WIFI_NM_WPA_SUPPLICANT_AP
default y if WIFI_USAGE_MODE_AP || WIFI_USAGE_MODE_STA_AP

config NRF70_ENABLE_DUAL_VIF
bool "Dual virtual Wi-Fi interfaces"
default y if WIFI_NM_MAX_MANAGED_INTERFACES = 2
depends on (WIFI_NRF7002 || WIFI_NRF7001) && NET_L2_ETHERNET
help
Enable support for two virtual Wi-Fi interfaces (VIFs).
When enabled, the driver can operate two VIFs simultaneously,
allowing use cases such as one interface in AP mode and another in STA mode.

config NRF70_P2P_MODE
bool "P2P support in driver"

Expand Down
27 changes: 27 additions & 0 deletions drivers/wifi/nrf_wifi/src/fmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,19 @@ static int nrf_wifi_drv_main_zep(const struct device *dev)
struct nrf_wifi_data_config_params data_config = { 0 };
struct rx_buf_pool_params rx_buf_pools[MAX_NUM_OF_RX_QUEUES];
struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = dev->data;
static unsigned int vif_ctx_cnt;

if (vif_ctx_cnt >= MAX_NUM_VIFS) {
LOG_ERR("%s: Max number of VIFs reached", __func__);
return -ENOMEM;
}

if (vif_ctx_cnt >= 1) {
/* FMAC is already initialized for VIF-0 */
return 0;
}

++vif_ctx_cnt;
vif_ctx_zep->rpu_ctx_zep = &rpu_drv_priv_zep.rpu_ctx_zep;

#ifdef CONFIG_NRF70_DATA_TX
Expand Down Expand Up @@ -953,6 +965,21 @@ ETH_NET_DEVICE_DT_INST_DEFINE(0,
CONFIG_WIFI_INIT_PRIORITY, /* prio */
&wifi_offload_ops, /* api */
CONFIG_NRF_WIFI_IFACE_MTU); /*mtu */
#ifdef CONFIG_NRF70_ENABLE_DUAL_VIF
/* Register second interface */
ETH_NET_DEVICE_DT_INST_DEFINE(1,
nrf_wifi_drv_main_zep, /* init_fn */
NULL, /* pm_action_cb */
&rpu_drv_priv_zep.rpu_ctx_zep.vif_ctx_zep[1], /* data */
#ifdef CONFIG_NRF70_STA_MODE
&wpa_supp_ops, /* cfg */
#else /* CONFIG_NRF70_STA_MODE */
NULL, /* cfg */
#endif /* !CONFIG_NRF70_STA_MODE */
CONFIG_WIFI_INIT_PRIORITY, /* prio */
&wifi_offload_ops, /* api */
CONFIG_NRF_WIFI_IFACE_MTU); /*mtu */
#endif /* NRF70_ENABLE_DUAL_VIF */
#else
DEVICE_DT_INST_DEFINE(0,
nrf_wifi_drv_main_zep, /* init_fn */
Expand Down
3 changes: 1 addition & 2 deletions drivers/wifi/nrf_wifi/src/net_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,7 @@ int nrf_wifi_if_start_zep(const struct device *dev)
}

k_mutex_init(&vif_ctx_zep->vif_lock);
rpu_ctx_zep->vif_ctx_zep[vif_ctx_zep->vif_idx].if_type =
add_vif_info.iftype;
vif_ctx_zep->if_type = add_vif_info.iftype;

/* Check if user has provided a valid MAC address, if not
* fetch it from OTP.
Expand Down
5 changes: 4 additions & 1 deletion drivers/wifi/nrf_wifi/src/wpa_supp_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,10 @@ void *nrf_wifi_wpa_supp_dev_init(void *supp_drv_if_ctx, const char *iface_name,
struct zep_wpa_supp_dev_callbk_fns *supp_callbk_fns)
{
struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
const struct device *device = DEVICE_DT_GET(DT_CHOSEN(zephyr_wifi));
/* Get device for each interface */
int if_idx = net_if_get_by_name(iface_name);
struct net_if *iface = net_if_get_by_index(if_idx);
const struct device *device = net_if_get_device(iface);

if (!device) {
LOG_ERR("%s: Interface %s not found", __func__, iface_name);
Expand Down
1 change: 1 addition & 0 deletions lib/os/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ config FDTABLE

config ZVFS_OPEN_MAX
int "Maximum number of open file descriptors"
default 24 if NRF70_ENABLE_DUAL_VIF
default 16 if WIFI_NM_WPA_SUPPLICANT
default 16 if POSIX_API
default 4
Expand Down
1 change: 1 addition & 0 deletions lib/os/zvfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ if ZVFS_POLL
config ZVFS_POLL_MAX
int "Max number of supported zvfs_poll() entries"
default NET_SOCKETS_POLL_MAX if NET_SOCKETS_POLL_MAX > 0
default 8 if NRF70_ENABLE_DUAL_VIF
default 6 if WIFI_NM_WPA_SUPPLICANT
default 4 if SHELL_BACKEND_TELNET
default 3
Expand Down
40 changes: 21 additions & 19 deletions modules/hostap/src/supp_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,19 @@ static void supp_shell_connect_status(struct k_work *work);
static K_WORK_DELAYABLE_DEFINE(wpa_supp_status_work,
supp_shell_connect_status);

#define wpa_cli_cmd_v(cmd, ...) ({ \
bool status; \
\
if (zephyr_wpa_cli_cmd_v(cmd, ##__VA_ARGS__) < 0) { \
wpa_printf(MSG_ERROR, \
"Failed to execute wpa_cli command: %s", \
cmd); \
status = false; \
} else { \
status = true; \
} \
\
status; \
})
#define wpa_cli_cmd_v(cmd, ...) \
({ \
bool status; \
\
if (zephyr_wpa_cli_cmd_v(wpa_s->ctrl_conn, cmd, ##__VA_ARGS__) < 0) { \
wpa_printf(MSG_ERROR, "Failed to execute wpa_cli command: %s", cmd); \
status = false; \
} else { \
status = true; \
} \
\
status; \
})

static struct wpa_supplicant *get_wpa_s_handle(const struct device *dev)
{
Expand Down Expand Up @@ -622,7 +621,7 @@ static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s,
goto out;
}

ret = z_wpa_ctrl_add_network(&resp);
ret = z_wpa_ctrl_add_network(wpa_s->ctrl_conn, &resp);
if (ret) {
wpa_printf(MSG_ERROR, "Failed to add network");
goto out;
Expand Down Expand Up @@ -1313,7 +1312,7 @@ int supplicant_status(const struct device *dev, struct wifi_iface_status *status
status->channel = channel;

if (ssid_len == 0) {
int _res = z_wpa_ctrl_status(&cli_status);
int _res = z_wpa_ctrl_status(wpa_s->ctrl_conn, &cli_status);

if (_res < 0) {
ssid_len = 0;
Expand Down Expand Up @@ -1342,7 +1341,7 @@ int supplicant_status(const struct device *dev, struct wifi_iface_status *status

status->rssi = -WPA_INVALID_NOISE;
if (status->iface_mode == WIFI_MODE_INFRA) {
ret = z_wpa_ctrl_signal_poll(&signal_poll);
ret = z_wpa_ctrl_signal_poll(wpa_s->ctrl_conn, &signal_poll);
if (!ret) {
status->rssi = signal_poll.rssi;
status->current_phy_tx_rate = signal_poll.current_txrate;
Expand Down Expand Up @@ -1492,6 +1491,7 @@ int supplicant_11k_cfg(const struct device *dev, struct wifi_11k_params *params)
int supplicant_11k_neighbor_request(const struct device *dev, struct wifi_11k_params *params)
{
int ssid_len = strlen(params->ssid);
struct wpa_supplicant *wpa_s = get_wpa_s_handle(dev);

if (params != NULL && ssid_len > 0) {
if (ssid_len > WIFI_SSID_MAX_LEN) {
Expand Down Expand Up @@ -1758,6 +1758,7 @@ int supplicant_bss_ext_capab(const struct device *dev, int capab)
int supplicant_legacy_roam(const struct device *dev)
{
int ret = -1;
struct wpa_supplicant *wpa_s = get_wpa_s_handle(dev);

k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER);
if (!wpa_cli_cmd_v("scan")) {
Expand Down Expand Up @@ -1866,7 +1867,7 @@ static int supplicant_wps_pin(const struct device *dev, struct wifi_wps_config_p
}

if (params->oper == WIFI_WPS_PIN_GET) {
if (zephyr_wpa_cli_cmd_resp(get_pin_cmd, params->pin)) {
if (zephyr_wpa_cli_cmd_resp(wpa_s->ctrl_conn, get_pin_cmd, params->pin)) {
goto out;
}
} else if (params->oper == WIFI_WPS_PIN_SET) {
Expand Down Expand Up @@ -2299,6 +2300,7 @@ int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *pa
{
int ret;
char *cmd = NULL;
struct wpa_supplicant *wpa_s = get_wpa_s_handle(dev);

if (params == NULL) {
return -EINVAL;
Expand All @@ -2317,7 +2319,7 @@ int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *pa
}

wpa_printf(MSG_DEBUG, "wpa_cli %s", cmd);
if (zephyr_wpa_cli_cmd_resp(cmd, params->resp)) {
if (zephyr_wpa_cli_cmd_resp(wpa_s->ctrl_conn, cmd, params->resp)) {
os_free(cmd);
return -ENOEXEC;
}
Expand Down
2 changes: 0 additions & 2 deletions modules/hostap/src/supp_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ struct wpa_supplicant *zephyr_get_handle_by_ifname(const char *ifname);
struct hapd_interfaces *zephyr_get_default_hapd_context(void);
#endif

struct wpa_supplicant *zephyr_get_handle_by_ifname(const char *ifname);

struct wpa_supplicant_event_msg {
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
int hostapd;
Expand Down
21 changes: 20 additions & 1 deletion modules/hostap/src/wpa_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@
* @brief wpa_cli implementation for Zephyr OS
*/

#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/shell/shell.h>
#include <zephyr/net/net_if.h>
#include <zephyr/init.h>


#include "supp_main.h"

#include "common.h"
#include "wpa_supplicant_i.h"
#include "wpa_cli_zephyr.h"
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
#include "hostapd_cli_zephyr.h"
Expand All @@ -21,8 +28,20 @@ static int cmd_wpa_cli(const struct shell *sh,
size_t argc,
const char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is, if there are 2 virtual interfaces, then how to run wpa_cli cmd on the second interface, since you get the iface by net_if_get_first_wifi?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A separate pr can be created to specify interface index in wpa cli.
This change is added to make the wpa cli compatible with new wpa supplicant changes as ctrl_conn is now associated with wpa_s object

char if_name[CONFIG_NET_INTERFACE_NAME_LEN + 1];
struct wpa_supplicant *wpa_s = NULL;

ARG_UNUSED(sh);

if (iface == NULL) {
shell_error(sh, "No Wifi interface found");
return -ENOENT;
}

net_if_get_name(iface, if_name, sizeof(if_name));
wpa_s = zephyr_get_handle_by_ifname(if_name);

if (argc == 1) {
shell_error(sh, "Missing argument");
return -EINVAL;
Expand All @@ -32,7 +51,7 @@ static int cmd_wpa_cli(const struct shell *sh,
argc++;

/* Remove wpa_cli from the argument list */
return zephyr_wpa_ctrl_zephyr_cmd(argc - 1, &argv[1]);
return zephyr_wpa_ctrl_zephyr_cmd(wpa_s->ctrl_conn, argc - 1, &argv[1]);
}

#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
Expand Down
1 change: 1 addition & 0 deletions subsys/net/ip/Kconfig.ipv4
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ if NET_IPV4
config NET_IF_MAX_IPV4_COUNT
int "Max number of IPv4 network interfaces in the system"
default NET_VLAN_COUNT if NET_VLAN && NET_VLAN_COUNT > 0
default 2 if NRF70_ENABLE_DUAL_VIF
default 2 if NET_LOOPBACK
default 1
help
Expand Down
1 change: 1 addition & 0 deletions subsys/net/ip/Kconfig.ipv6
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ if NET_IPV6
config NET_IF_MAX_IPV6_COUNT
int "Max number of IPv6 network interfaces in the system"
default NET_VLAN_COUNT if NET_VLAN && NET_VLAN_COUNT > 0
default 2 if NRF70_ENABLE_DUAL_VIF
default 2 if NET_LOOPBACK
default 1
help
Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ manifest:
- hal
- name: hostap
path: modules/lib/hostap
revision: cf270006050cf944af699301c7f4de2b427cd862
revision: pull/80/head
- name: liblc3
revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183
path: modules/lib/liblc3
Expand Down
Loading