Skip to content
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

net: wifi: Introduce Wi-Fi network manager's support #59249

Merged
merged 6 commits into from
Jul 11, 2023
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
16 changes: 12 additions & 4 deletions doc/connectivity/networking/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,20 @@ can be disabled if not needed.
listen management events generated by core stack when for example IP address
is added to the device, or network interface is coming up etc.

* **Wi-Fi Management API.** Applications can use Wi-Fi management API to
manage the interface, in example to connect to Wi-Fi network and to scan
available Wi-Fi networks.

* **Wi-Fi Network Manager API.** Wi-Fi Network Managers can now register
themselves to the Wi-Fi stack. The Network Managers can then implement
the Wi-Fi Management API and manage the Wi-Fi interface.

* **Multiple Network Technologies.** The Zephyr OS can be configured to
support multiple network technologies at the same time simply by enabling
them in Kconfig: for example, Ethernet and 802.15.4 support. Note that no
automatic IP routing functionality is provided between these technologies.
Applications can send data according to their needs to desired network
interface.
them in Kconfig: for example, Ethernet, Wi-Fi and 802.15.4 support. Note
that no automatic IP routing functionality is provided between these
technologies. Applications can send data according to their needs to desired
network interface.

* **Minimal Copy Network Buffer Management.** It is possible to have minimal
copy network data path. This means that the system tries to avoid copying
Expand Down
24 changes: 14 additions & 10 deletions drivers/wifi/esp32/src/esp_wifi_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,18 +624,22 @@ static int esp32_wifi_dev_init(const struct device *dev)
return 0;
}

static const struct wifi_mgmt_ops esp32_wifi_mgmt = {
.scan = esp32_wifi_scan,
.connect = esp32_wifi_connect,
.disconnect = esp32_wifi_disconnect,
.ap_enable = esp32_wifi_ap_enable,
.ap_disable = esp32_wifi_ap_disable,
.iface_status = esp32_wifi_status,
#if defined(CONFIG_NET_STATISTICS_WIFI)
.get_stats = esp32_wifi_stats,
#endif
};

static const struct net_wifi_mgmt_offload esp32_api = {
.wifi_iface.iface_api.init = esp32_wifi_init,
.wifi_iface.iface_api.init = esp32_wifi_init,
.wifi_iface.send = esp32_wifi_send,
#if defined(CONFIG_NET_STATISTICS_WIFI)
.get_stats = esp32_wifi_stats,
#endif
.scan = esp32_wifi_scan,
.connect = esp32_wifi_connect,
.disconnect = esp32_wifi_disconnect,
.ap_enable = esp32_wifi_ap_enable,
.ap_disable = esp32_wifi_ap_disable,
.iface_status = esp32_wifi_status,
.wifi_mgmt_api = &esp32_wifi_mgmt,
};

NET_DEVICE_DT_INST_DEFINE(0,
Expand Down
19 changes: 12 additions & 7 deletions drivers/wifi/esp_at/esp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,15 +1223,20 @@ static enum offloaded_net_if_types esp_offload_get_type(void)
{
return L2_OFFLOADED_NET_IF_TYPE_WIFI;
}

static const struct wifi_mgmt_ops esp_mgmt_ops = {
.scan = esp_mgmt_scan,
.connect = esp_mgmt_connect,
.disconnect = esp_mgmt_disconnect,
.ap_enable = esp_mgmt_ap_enable,
.ap_disable = esp_mgmt_ap_disable,
.iface_status = esp_mgmt_iface_status,
};

static const struct net_wifi_mgmt_offload esp_api = {
.wifi_iface.iface_api.init = esp_iface_init,
.wifi_iface.get_type = esp_offload_get_type,
.scan = esp_mgmt_scan,
.connect = esp_mgmt_connect,
.disconnect = esp_mgmt_disconnect,
.ap_enable = esp_mgmt_ap_enable,
.ap_disable = esp_mgmt_ap_disable,
.iface_status = esp_mgmt_iface_status,
.wifi_iface.get_type = esp_offload_get_type,
.wifi_mgmt_api = &esp_mgmt_ops,
};

static int esp_init(const struct device *dev);
Expand Down
18 changes: 11 additions & 7 deletions drivers/wifi/eswifi/eswifi_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,15 +786,19 @@ static enum offloaded_net_if_types eswifi_get_type(void)
return L2_OFFLOADED_NET_IF_TYPE_WIFI;
}

static const struct wifi_mgmt_ops eswifi_mgmt_api = {
.scan = eswifi_mgmt_scan,
.connect = eswifi_mgmt_connect,
.disconnect = eswifi_mgmt_disconnect,
.ap_enable = eswifi_mgmt_ap_enable,
.ap_disable = eswifi_mgmt_ap_disable,
.iface_status = eswifi_mgmt_iface_status,
};

static const struct net_wifi_mgmt_offload eswifi_offload_api = {
.wifi_iface.iface_api.init = eswifi_iface_init,
.wifi_iface.get_type = eswifi_get_type,
.scan = eswifi_mgmt_scan,
.connect = eswifi_mgmt_connect,
.disconnect = eswifi_mgmt_disconnect,
.ap_enable = eswifi_mgmt_ap_enable,
.ap_disable = eswifi_mgmt_ap_disable,
.iface_status = eswifi_mgmt_iface_status,
.wifi_iface.get_type = eswifi_get_type,
.wifi_mgmt_api = &eswifi_mgmt_api,
};

NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, eswifi_init, NULL,
Expand Down
12 changes: 8 additions & 4 deletions drivers/wifi/simplelink/simplelink.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,16 @@ static enum offloaded_net_if_types simplelink_get_type(void)
return L2_OFFLOADED_NET_IF_TYPE_WIFI;
}

static const struct wifi_mgmt_ops simplelink_mgmt = {
.scan = simplelink_mgmt_scan,
.connect = simplelink_mgmt_connect,
.disconnect = simplelink_mgmt_disconnect,
};

static const struct net_wifi_mgmt_offload simplelink_api = {
.wifi_iface.iface_api.init = simplelink_iface_init,
.wifi_iface.get_type = simplelink_get_type,
.scan = simplelink_mgmt_scan,
.connect = simplelink_mgmt_connect,
.disconnect = simplelink_mgmt_disconnect,
.wifi_iface.get_type = simplelink_get_type,
.wifi_mgmt_api = &simplelink_mgmt,
};

static int simplelink_init(const struct device *dev)
Expand Down
15 changes: 9 additions & 6 deletions drivers/wifi/winc1500/wifi_winc1500.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,14 +1108,17 @@ static enum offloaded_net_if_types winc1500_get_wifi_type(void)
return L2_OFFLOADED_NET_IF_TYPE_WIFI;
}

static const struct wifi_mgmt_ops winc1500_mgmt_ops = {
.scan = winc1500_mgmt_scan,
.connect = winc1500_mgmt_connect,
.disconnect = winc1500_mgmt_disconnect,
.ap_enable = winc1500_mgmt_ap_enable,
.ap_disable = winc1500_mgmt_ap_disable,
};
static const struct net_wifi_mgmt_offload winc1500_api = {
.wifi_iface.iface_api.init = winc1500_iface_init,
.wifi_iface.get_type = winc1500_get_wifi_type,
.scan = winc1500_mgmt_scan,
.connect = winc1500_mgmt_connect,
.disconnect = winc1500_mgmt_disconnect,
.ap_enable = winc1500_mgmt_ap_enable,
.ap_disable = winc1500_mgmt_ap_disable,
.wifi_iface.get_type = winc1500_get_wifi_type,
.wifi_mgmt_api = &winc1500_mgmt_ops,
};

static int winc1500_init(const struct device *dev)
Expand Down
29 changes: 16 additions & 13 deletions include/zephyr/net/wifi_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,19 +314,7 @@ typedef void (*scan_result_cb_t)(struct net_if *iface, int status,
typedef void (*raw_scan_result_cb_t)(struct net_if *iface, int status,
struct wifi_raw_scan_result *entry);
#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */
struct net_wifi_mgmt_offload {
/**
* Mandatory to get in first position.
* A network device should indeed provide a pointer on such
* net_if_api structure. So we make current structure pointer
* that can be casted to a net_if_api structure pointer.
*/
#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING
struct ethernet_api wifi_iface;
#else
struct offloaded_if_api wifi_iface;
#endif

struct wifi_mgmt_ops {
/* cb parameter is the cb that should be called for each
* result by the driver. The wifi mgmt part will take care of
* raising the necessary event etc...
Expand All @@ -350,6 +338,21 @@ struct net_wifi_mgmt_offload {
int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain);
};

struct net_wifi_mgmt_offload {
/**
* Mandatory to get in first position.
* A network device should indeed provide a pointer on such
* net_if_api structure. So we make current structure pointer
* that can be casted to a net_if_api structure pointer.
*/
#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING
struct ethernet_api wifi_iface;
#else
struct offloaded_if_api wifi_iface;
#endif
const struct wifi_mgmt_ops *const wifi_mgmt_api;
};

/* Make sure that the network interface API is properly setup inside
* Wifi mgmt offload API struct (it is the first one).
*/
Expand Down
100 changes: 100 additions & 0 deletions include/zephyr/net/wifi_nm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/** @file
* @brief Wi-Fi Network manager API
*
* This file contains the Wi-Fi network manager API. These APIs are used by the
* any network management application to register as a Wi-Fi network manager.
*/

/*
* Copyright (c) 2023 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_ZEPHYR_NET_WIFI_NM_H_
#define ZEPHYR_INCLUDE_ZEPHYR_NET_WIFI_NM_H_

#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <zephyr/sys/iterable_sections.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/wifi_mgmt.h>
/**
* @brief Wi-Fi Network manager API
* @defgroup wifi_nm Wi-Fi Network Manager API
* @ingroup networking
* @{
*/

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief WiFi Network manager instance
*/
struct wifi_nm_instance {
/** Name of the Network manager instance */
const char *name;
/** Wi-Fi Management operations */
const struct wifi_mgmt_ops *ops;
/** List of Managed interfaces */
struct net_if *mgd_ifaces[CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES];
};

#define WIFI_NM_NAME(name) wifi_nm_##name

#define DEFINE_WIFI_NM_INSTANCE(_name, _ops) \
static STRUCT_SECTION_ITERABLE(wifi_nm_instance, WIFI_NM_NAME(_name)) = { \
.name = STRINGIFY(_name), \
.ops = _ops, \
.mgd_ifaces = { NULL }, \
}

/**
* @brief Get a Network manager instance for a given name
*
* @param name Name of the Network manager instance
*
*/
struct wifi_nm_instance *wifi_nm_get_instance(const char *name);

/**
* @brief Get a Network manager instance for a given interface
*
* @param iface Interface
*
*/
struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface);

/**
* @brief Register a managed interface
*
* @param nm Pointer to Network manager instance
* @param iface Managed interface
*
* @retval 0 If successful.
* @retval -EINVAL If invalid parameters were passed.
* @retval -ENOTSUP If the interface is not a Wi-Fi interface.
* @retval -ENOMEM If the maximum number of managed interfaces has been reached.
*/
int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface);

/**
* @brief Unregister managed interface
*
* @param nm Pointer to Network manager instance
* @param iface Interface
* @return int 0 for OK; -EINVAL for invalid parameters; -ENOENT if interface is not registered
* with the Network manager.
*/
int wifi_nm_unregister_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface);

/**
* @}
*/

#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ZEPHYR_NET_WIFI_NM_H_ */
7 changes: 7 additions & 0 deletions subsys/net/l2/wifi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@ zephyr_library_compile_definitions_ifdef(

zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT wifi_mgmt.c)
zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_SHELL wifi_shell.c)
zephyr_library_sources_ifdef(CONFIG_WIFI_NM wifi_nm.c)

# Linker section placement for wifi_nm_instance iterable structure
zephyr_linker_sources_ifdef(CONFIG_WIFI_NM DATA_SECTIONS wifi_nm.ld)
if (CONFIG_WIFI_NM)
zephyr_iterable_section(NAME wifi_nm_instance GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
endif()
22 changes: 22 additions & 0 deletions subsys/net/l2/wifi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,25 @@ config WIFI_MGMT_FORCED_PASSIVE_SCAN
the scan type is always sent as passive.
This doesn't guarantee that passive scan will be used, it depends
on the underlying chip implementation to support and honour scan type.

config WIFI_NM
bool "Wi-Fi Network manager support"
help
This option enables using the Wi-Fi Network managers (e.g. wpa_supplicant) to
manage the Wi-Fi network interfaces.

if WIFI_NM

config WIFI_NM_MAX_MANAGED_INTERFACES
int "Maximum number of managed interfaces per Wi-Fi network manager"
default 1
help
This option defines the maximum number of managed interfaces per Wi-Fi
network manager instance that can be used simultaneously.

module = WIFI_NM
module-dep = NET_LOG
module-str = Log level for Wi-Fi Network manager module
module-help = Enables using the Wi-Fi Network managers to manage the Wi-Fi network interfaces.
source "subsys/net/Kconfig.template.log_config.net"
endif # WIFI_NM
Loading