drivers: wifi: siwx91x: Enable AP configuration support
- Adds support for configuring client maximum inactivity timeout. - Adds support for bandwidth, It supports 20MHZ only. - Adds support for setting the maximum number of clients and hidden SSID mode by rebooting the NWP device. Signed-off-by: Arunmani Alagarsamy <arunmani.a@silabs.com>
This commit is contained in:
parent
0459bd8638
commit
4c1a91fa63
4 changed files with 125 additions and 11 deletions
|
@ -34,6 +34,48 @@ enum {
|
|||
DEMAND_TWT = 2,
|
||||
};
|
||||
|
||||
static int siwx91x_nwp_reboot_if_required(const struct device *dev, uint8_t oper_mode)
|
||||
{
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
int ret;
|
||||
|
||||
if (sidev->reboot_needed) {
|
||||
ret = siwx91x_nwp_mode_switch(oper_mode, sidev->hidden_ssid, sidev->max_num_sta);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to reboot the device: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sidev->reboot_needed = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int siwx91x_set_hidden_ssid(const struct device *dev, bool enable)
|
||||
{
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
|
||||
if (sidev->hidden_ssid != enable) {
|
||||
sidev->hidden_ssid = enable;
|
||||
sidev->reboot_needed = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int siwx91x_set_max_sta(const struct device *dev, uint8_t max_sta)
|
||||
{
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
|
||||
if (sidev->max_num_sta != max_sta) {
|
||||
sidev->max_num_sta = max_sta;
|
||||
sidev->reboot_needed = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int siwx91x_sl_to_z_mode(sl_wifi_interface_t interface)
|
||||
{
|
||||
switch (interface) {
|
||||
|
@ -319,6 +361,7 @@ static int siwx91x_ap_disable_if_required(const struct device *dev,
|
|||
{
|
||||
struct wifi_iface_status prev_params = { };
|
||||
uint32_t prev_psk_length = WIFI_PSK_MAX_LEN;
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
uint8_t prev_psk[WIFI_PSK_MAX_LEN];
|
||||
sl_net_credential_type_t psk_type;
|
||||
int ret;
|
||||
|
@ -328,7 +371,7 @@ static int siwx91x_ap_disable_if_required(const struct device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (siwx91x_param_changed(&prev_params, new_params)) {
|
||||
if (sidev->reboot_needed || siwx91x_param_changed(&prev_params, new_params)) {
|
||||
return siwx91x_ap_disable(dev);
|
||||
}
|
||||
|
||||
|
@ -392,7 +435,8 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
struct siwx91x_dev *sidev = dev->data;
|
||||
/* Wiseconnect requires a valid PSK even if WIFI_SECURITY_TYPE_NONE is selected */
|
||||
static const char dummy_psk[] = "dummy_value";
|
||||
sl_status_t ret;
|
||||
sl_wifi_ap_configuration_t saved_ap_cfg;
|
||||
int ret;
|
||||
int sec;
|
||||
|
||||
sl_wifi_ap_configuration_t siwx91x_ap_cfg = {
|
||||
|
@ -401,11 +445,11 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
.rate_protocol = SL_WIFI_RATE_PROTOCOL_AUTO,
|
||||
.encryption = SL_WIFI_DEFAULT_ENCRYPTION,
|
||||
.channel.bandwidth = SL_WIFI_BANDWIDTH_20MHz,
|
||||
.maximum_clients = sidev->max_num_sta,
|
||||
.tdi_flags = SL_WIFI_TDI_NONE,
|
||||
.client_idle_timeout = 0xFF,
|
||||
.beacon_interval = 100,
|
||||
.dtim_beacon_count = 3,
|
||||
.maximum_clients = 4,
|
||||
.beacon_stop = 0,
|
||||
.options = 0,
|
||||
.is_11n_enabled = 1,
|
||||
|
@ -416,6 +460,8 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Device hiddes both length and ssid at same time */
|
||||
siwx91x_set_hidden_ssid(dev, params->ignore_broadcast_ssid);
|
||||
if (sidev->state == WIFI_STATE_COMPLETED) {
|
||||
ret = siwx91x_ap_disable_if_required(dev, params);
|
||||
if (ret < 0) {
|
||||
|
@ -458,9 +504,18 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = siwx91x_nwp_reboot_if_required(dev, WIFI_SOFTAP_MODE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
sli_get_saved_ap_configuration(&saved_ap_cfg);
|
||||
if (saved_ap_cfg.client_idle_timeout != 0) {
|
||||
siwx91x_ap_cfg.client_idle_timeout = saved_ap_cfg.client_idle_timeout;
|
||||
}
|
||||
|
||||
siwx91x_ap_cfg.ssid.length = params->ssid_length;
|
||||
strncpy(siwx91x_ap_cfg.ssid.value, params->ssid, params->ssid_length);
|
||||
|
||||
if (params->mfp != WIFI_MFP_DISABLE) {
|
||||
LOG_WRN("Needed MFP disable but got MFP %s, hence setting to MFP disable",
|
||||
wifi_mfp_txt(params->mfp));
|
||||
|
@ -904,7 +959,7 @@ static int siwx91x_mode(const struct device *dev, struct wifi_mode_info *mode)
|
|||
mode->mode = cur_mode;
|
||||
} else if (mode->oper == WIFI_MGMT_SET) {
|
||||
if (cur_mode != mode->mode) {
|
||||
ret = siwx91x_nwp_mode_switch(mode->mode);
|
||||
ret = siwx91x_nwp_mode_switch(mode->mode, false, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -915,6 +970,38 @@ static int siwx91x_mode(const struct device *dev, struct wifi_mode_info *mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int siwx91x_ap_config_params(const struct device *dev, struct wifi_ap_config_params *params)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
sl_wifi_ap_configuration_t siwx91x_ap_cfg;
|
||||
|
||||
__ASSERT(params, "params cannot be NULL");
|
||||
|
||||
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_AP_INTERFACE) {
|
||||
LOG_ERR("Wi-Fi not in AP mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((params->type & WIFI_AP_CONFIG_PARAM_BANDWIDTH) &&
|
||||
params->bandwidth != WIFI_FREQ_BANDWIDTH_20MHZ) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
sli_get_saved_ap_configuration(&siwx91x_ap_cfg);
|
||||
siwx91x_ap_cfg.channel.bandwidth = SL_WIFI_BANDWIDTH_20MHz;
|
||||
if (params->type & WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY) {
|
||||
siwx91x_ap_cfg.client_idle_timeout = params->max_inactivity * 1000;
|
||||
}
|
||||
|
||||
if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) {
|
||||
siwx91x_set_max_sta(dev, params->max_num_sta);
|
||||
}
|
||||
|
||||
sli_save_ap_configuration(&siwx91x_ap_cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE
|
||||
|
||||
static int siwx91x_send(const struct device *dev, struct net_pkt *pkt)
|
||||
|
@ -1226,6 +1313,7 @@ static const struct wifi_mgmt_ops siwx91x_mgmt = {
|
|||
.iface_status = siwx91x_status,
|
||||
.mode = siwx91x_mode,
|
||||
.set_twt = siwx91x_set_twt,
|
||||
.ap_config_params = siwx91x_ap_config_params,
|
||||
#if defined(CONFIG_NET_STATISTICS_WIFI)
|
||||
.get_stats = siwx91x_stats,
|
||||
#endif
|
||||
|
@ -1242,7 +1330,9 @@ static const struct net_wifi_mgmt_offload siwx91x_api = {
|
|||
.wifi_mgmt_api = &siwx91x_mgmt,
|
||||
};
|
||||
|
||||
static struct siwx91x_dev sidev;
|
||||
static struct siwx91x_dev sidev = {
|
||||
.max_num_sta = CONFIG_WIFI_MGMT_AP_MAX_NUM_STA,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE
|
||||
ETH_NET_DEVICE_DT_INST_DEFINE(0, siwx91x_dev_init, NULL, &sidev, NULL,
|
||||
|
|
|
@ -21,6 +21,9 @@ struct siwx91x_dev {
|
|||
enum wifi_iface_state scan_prev_state;
|
||||
scan_result_cb_t scan_res_cb;
|
||||
uint16_t scan_max_bss_cnt;
|
||||
uint8_t max_num_sta;
|
||||
bool reboot_needed;
|
||||
bool hidden_ssid;
|
||||
|
||||
#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD
|
||||
struct k_event fds_recv_event;
|
||||
|
|
|
@ -20,13 +20,16 @@
|
|||
#include "rsi_ble_common_config.h"
|
||||
#endif
|
||||
|
||||
#define AP_MAX_NUM_STA 4
|
||||
|
||||
LOG_MODULE_REGISTER(siwx91x_nwp);
|
||||
|
||||
BUILD_ASSERT(DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195) ||
|
||||
DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(255) ||
|
||||
DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(319));
|
||||
|
||||
int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t wifi_oper_mode)
|
||||
int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t wifi_oper_mode,
|
||||
bool hidden_ssid, uint8_t max_num_sta)
|
||||
{
|
||||
sl_wifi_device_configuration_t default_config = {
|
||||
.band = SL_SI91X_WIFI_BAND_2_4GHZ,
|
||||
|
@ -48,6 +51,13 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w
|
|||
sl_si91x_boot_configuration_t *boot_config = &default_config.boot_config;
|
||||
|
||||
__ASSERT(get_config, "get_config cannot be NULL");
|
||||
__ASSERT((hidden_ssid == true || max_num_sta != 0) && wifi_oper_mode != WIFI_SOFTAP_MODE,
|
||||
"hidden_ssid or max_num_sta requires SOFTAP mode");
|
||||
|
||||
if (wifi_oper_mode == WIFI_SOFTAP_MODE && max_num_sta > AP_MAX_NUM_STA) {
|
||||
LOG_ERR("Exceeded maximum supported stations (%d)", AP_MAX_NUM_STA);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The size does not match exactly because 1 KB is reserved at the start of the RAM */
|
||||
if (DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195)) {
|
||||
|
@ -110,6 +120,15 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w
|
|||
} else if (wifi_oper_mode == WIFI_SOFTAP_MODE) {
|
||||
boot_config->oper_mode = SL_SI91X_ACCESS_POINT_MODE;
|
||||
boot_config->coex_mode = SL_SI91X_WLAN_ONLY_MODE;
|
||||
boot_config->custom_feature_bit_map |= SL_SI91X_CUSTOM_FEAT_LIMIT_PACKETS_PER_STA;
|
||||
|
||||
if (hidden_ssid) {
|
||||
boot_config->custom_feature_bit_map |=
|
||||
SL_SI91X_CUSTOM_FEAT_AP_IN_HIDDEN_MODE;
|
||||
}
|
||||
|
||||
boot_config->custom_feature_bit_map |=
|
||||
SL_WIFI_CUSTOM_FEAT_MAX_NUM_OF_CLIENTS(max_num_sta);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) {
|
||||
LOG_WRN("Bluetooth is not supported in AP mode");
|
||||
|
@ -166,12 +185,12 @@ int siwx91x_get_nwp_config(sl_wifi_device_configuration_t *get_config, uint8_t w
|
|||
return 0;
|
||||
}
|
||||
|
||||
int siwx91x_nwp_mode_switch(uint8_t oper_mode)
|
||||
int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num_sta)
|
||||
{
|
||||
sl_wifi_device_configuration_t nwp_config;
|
||||
int status;
|
||||
|
||||
status = siwx91x_get_nwp_config(&nwp_config, oper_mode);
|
||||
status = siwx91x_get_nwp_config(&nwp_config, oper_mode, hidden_ssid, max_num_sta);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
@ -195,7 +214,7 @@ static int siwg917_nwp_init(void)
|
|||
sl_wifi_device_configuration_t network_config;
|
||||
sl_status_t status;
|
||||
|
||||
siwx91x_get_nwp_config(&network_config, WIFI_STA_MODE);
|
||||
siwx91x_get_nwp_config(&network_config, WIFI_STA_MODE, false, 0);
|
||||
/* TODO: If sl_net_*_profile() functions will be needed for WiFi then call
|
||||
* sl_net_set_profile() here. Currently these are unused.
|
||||
*/
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
* of the NWP to apply the new mode along with the updated features.
|
||||
*
|
||||
* @param[in] oper_mode Wi-Fi operating mode to switch to.
|
||||
* @param[in] hidden_ssid SSID and its length (used only in WIFI_AP_MODE).
|
||||
* @param[in] max_num_sta Maximum number of supported stations (only for WIFI_AP_MODE).
|
||||
*
|
||||
* @return 0 on success, negative error code on failure.
|
||||
*/
|
||||
int siwx91x_nwp_mode_switch(uint8_t oper_mode);
|
||||
int siwx91x_nwp_mode_switch(uint8_t oper_mode, bool hidden_ssid, uint8_t max_num_sta);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue