drivers: wifi: siwx91x: Add interface state validation
This patch introduces validation checks to ensure Wi-Fi commands are executed only when the device is in a valid operational mode. - Restricts command execution if the device is not in an appropriate mode - Prevents reconfiguring the device when it is already in an active state - Enabled Advanced multiprobe setting as default. Signed-off-by: Arunmani Alagarsamy <arunmani.a@silabs.com>
This commit is contained in:
parent
151ca3a31f
commit
c8a29b3038
2 changed files with 47 additions and 35 deletions
|
@ -131,7 +131,7 @@ config WIFI_SILABS_SIWX91X_ADV_PASSIVE_SCAN_DURATION
|
|||
|
||||
config WIFI_SILABS_SIWX91X_ADV_MULTIPROBE
|
||||
int "Advanced multiprobe setting"
|
||||
default 0
|
||||
default 1
|
||||
help
|
||||
Configure the advanced multiprobe setting for WiFi scanning.
|
||||
When set to 1, multiple probe requests will be sent to all access
|
||||
|
|
|
@ -48,20 +48,6 @@ static int siwx91x_sl_to_z_mode(sl_wifi_interface_t interface)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int siwx91x_bandwidth(enum wifi_frequency_bandwidths bandwidth)
|
||||
{
|
||||
switch (bandwidth) {
|
||||
case WIFI_FREQ_BANDWIDTH_20MHZ:
|
||||
return SL_WIFI_BANDWIDTH_20MHz;
|
||||
case WIFI_FREQ_BANDWIDTH_40MHZ:
|
||||
return SL_WIFI_BANDWIDTH_40MHz;
|
||||
case WIFI_FREQ_BANDWIDTH_80MHZ:
|
||||
return SL_WIFI_BANDWIDTH_80MHz;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int siwx91x_map_ap_security(enum wifi_security_type security)
|
||||
{
|
||||
switch (security) {
|
||||
|
@ -154,10 +140,10 @@ static unsigned int siwx91x_on_join(sl_wifi_event_t event,
|
|||
|
||||
static int siwx91x_status(const struct device *dev, struct wifi_iface_status *status)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
sl_si91x_rsp_wireless_info_t wlan_info = { };
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
uint8_t join_config;
|
||||
sl_wifi_interface_t interface;
|
||||
int32_t rssi;
|
||||
int ret;
|
||||
|
||||
|
@ -170,7 +156,6 @@ static int siwx91x_status(const struct device *dev, struct wifi_iface_status *st
|
|||
return 0;
|
||||
}
|
||||
|
||||
interface = sl_wifi_get_default_interface();
|
||||
ret = sl_wifi_get_wireless_info(&wlan_info);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to get the wireless info: 0x%x", ret);
|
||||
|
@ -272,26 +257,36 @@ static int siwx91x_status(const struct device *dev, struct wifi_iface_status *st
|
|||
|
||||
static int siwx91x_disconnect(const struct device *dev)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
int ret;
|
||||
|
||||
ret = sl_wifi_disconnect(SL_WIFI_CLIENT_INTERFACE);
|
||||
if (ret) {
|
||||
if (sidev->state != WIFI_STATE_COMPLETED) {
|
||||
LOG_ERR("Command given in invalid state");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ret = sl_wifi_disconnect(interface);
|
||||
if (ret != SL_STATUS_OK) {
|
||||
LOG_ERR("Failed to disconnect: 0x%x", ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE)) {
|
||||
net_if_dormant_on(sidev->iface);
|
||||
}
|
||||
|
||||
sidev->state = WIFI_STATE_DISCONNECTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int siwx91x_ap_disable(const struct device *dev)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
int ret;
|
||||
|
||||
ret = sl_wifi_stop_ap(SL_WIFI_AP_2_4GHZ_INTERFACE);
|
||||
ret = sl_wifi_stop_ap(interface);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to disable Wi-Fi AP mode: 0x%x", ret);
|
||||
return -EIO;
|
||||
|
@ -393,6 +388,7 @@ static int siwx91x_disconnect_if_required(const struct device *dev,
|
|||
|
||||
static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_params *params)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
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";
|
||||
|
@ -404,7 +400,7 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
.keepalive_type = SL_SI91X_AP_NULL_BASED_KEEP_ALIVE,
|
||||
.rate_protocol = SL_WIFI_RATE_PROTOCOL_AUTO,
|
||||
.encryption = SL_WIFI_DEFAULT_ENCRYPTION,
|
||||
.ssid.length = params->ssid_length,
|
||||
.channel.bandwidth = SL_WIFI_BANDWIDTH_20MHz,
|
||||
.tdi_flags = SL_WIFI_TDI_NONE,
|
||||
.client_idle_timeout = 0xFF,
|
||||
.beacon_interval = 100,
|
||||
|
@ -415,6 +411,11 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
.is_11n_enabled = 1,
|
||||
};
|
||||
|
||||
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_AP_INTERFACE) {
|
||||
LOG_ERR("Interface not in AP mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sidev->state == WIFI_STATE_COMPLETED) {
|
||||
ret = siwx91x_ap_disable_if_required(dev, params);
|
||||
if (ret < 0) {
|
||||
|
@ -423,22 +424,20 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
}
|
||||
|
||||
if (params->band != WIFI_FREQ_BAND_UNKNOWN && params->band != WIFI_FREQ_BAND_2_4_GHZ) {
|
||||
LOG_ERR("Unsupported band");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (params->channel == WIFI_CHANNEL_ANY) {
|
||||
siwx91x_ap_cfg.channel.channel = SL_WIFI_AUTO_CHANNEL;
|
||||
} else {
|
||||
siwx91x_ap_cfg.channel.channel = params->channel;
|
||||
if (params->bandwidth != WIFI_FREQ_BANDWIDTH_20MHZ) {
|
||||
LOG_ERR("Unsupported bandwidth");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (siwx91x_bandwidth(params->bandwidth) < 0) {
|
||||
if (params->ssid_length == 0 || params->ssid_length > WIFI_SSID_MAX_LEN) {
|
||||
LOG_ERR("Invalid ssid length");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
siwx91x_ap_cfg.channel.bandwidth = siwx91x_bandwidth(params->bandwidth);
|
||||
strncpy(siwx91x_ap_cfg.ssid.value, params->ssid, params->ssid_length);
|
||||
|
||||
sec = siwx91x_map_ap_security(params->security);
|
||||
if (sec < 0) {
|
||||
LOG_ERR("Invalid security type");
|
||||
|
@ -446,7 +445,6 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
}
|
||||
|
||||
siwx91x_ap_cfg.security = sec;
|
||||
|
||||
if (params->security == WIFI_SECURITY_TYPE_NONE) {
|
||||
ret = sl_net_set_credential(siwx91x_ap_cfg.credential_id, SL_NET_WIFI_PSK,
|
||||
dummy_psk, strlen(dummy_psk));
|
||||
|
@ -460,11 +458,20 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
if (params->channel == WIFI_CHANNEL_ANY) {
|
||||
siwx91x_ap_cfg.channel.channel = SL_WIFI_AUTO_CHANNEL;
|
||||
} else {
|
||||
siwx91x_ap_cfg.channel.channel = params->channel;
|
||||
}
|
||||
|
||||
ret = sl_wifi_start_ap(SL_WIFI_AP_INTERFACE | SL_WIFI_2_4GHZ_INTERFACE, &siwx91x_ap_cfg);
|
||||
if (ret != SL_STATUS_OK) {
|
||||
LOG_ERR("Failed to enable AP mode: 0x%x", ret);
|
||||
|
@ -478,11 +485,17 @@ static int siwx91x_ap_enable(const struct device *dev, struct wifi_connect_req_p
|
|||
static int siwx91x_ap_sta_disconnect(const struct device *dev, const uint8_t *mac_addr)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
sl_mac_address_t mac = { };
|
||||
int ret;
|
||||
|
||||
__ASSERT(mac_addr, "mac_addr cannot be NULL");
|
||||
|
||||
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_AP_INTERFACE) {
|
||||
LOG_ERR("Interface not in AP mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(mac.octet, mac_addr, ARRAY_SIZE(mac.octet));
|
||||
|
||||
ret = sl_wifi_disconnect_ap_client(SL_WIFI_AP_INTERFACE | SL_WIFI_2_4GHZ_INTERFACE,
|
||||
|
@ -533,6 +546,7 @@ static sl_status_t siwx91x_on_ap_sta_disconnect(sl_wifi_event_t event, void *dat
|
|||
|
||||
static int siwx91x_connect(const struct device *dev, struct wifi_connect_req_params *params)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
sl_wifi_client_configuration_t wifi_config = {
|
||||
.bss_type = SL_WIFI_BSS_TYPE_INFRASTRUCTURE,
|
||||
.encryption = SL_WIFI_DEFAULT_ENCRYPTION,
|
||||
|
@ -620,7 +634,7 @@ static int siwx91x_connect(const struct device *dev, struct wifi_connect_req_par
|
|||
wifi_config.ssid.length = params->ssid_length,
|
||||
memcpy(wifi_config.ssid.value, params->ssid, params->ssid_length);
|
||||
|
||||
ret = sl_wifi_connect(SL_WIFI_CLIENT_INTERFACE, &wifi_config, 0);
|
||||
ret = sl_wifi_connect(interface, &wifi_config, 0);
|
||||
if (ret != SL_STATUS_IN_PROGRESS) {
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -755,6 +769,7 @@ siwx91x_configure_scan_dwell_time(sl_wifi_scan_type_t scan_type, uint16_t dwell_
|
|||
static int siwx91x_scan(const struct device *dev, struct wifi_scan_params *z_scan_config,
|
||||
scan_result_cb_t cb)
|
||||
{
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
sl_wifi_scan_configuration_t sl_scan_config = { };
|
||||
sl_wifi_advanced_scan_configuration_t advanced_scan_config = {
|
||||
.trigger_level = CONFIG_WIFI_SILABS_SIWX91X_ADV_SCAN_THRESHOLD,
|
||||
|
@ -772,13 +787,11 @@ static int siwx91x_scan(const struct device *dev, struct wifi_scan_params *z_sca
|
|||
#endif
|
||||
};
|
||||
struct siwx91x_dev *sidev = dev->data;
|
||||
sl_wifi_interface_t interface;
|
||||
sl_wifi_ssid_t ssid = { };
|
||||
int ret;
|
||||
|
||||
__ASSERT(z_scan_config, "z_scan_config cannot be NULL");
|
||||
|
||||
interface = sl_wifi_get_default_interface();
|
||||
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_CLIENT_INTERFACE) {
|
||||
LOG_ERR("Interface not in STA mode");
|
||||
return -EINVAL;
|
||||
|
@ -984,13 +997,12 @@ static void siwx91x_ethernet_init(struct net_if *iface)
|
|||
static int siwx91x_stats(const struct device *dev, struct net_stats_wifi *stats)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
sl_wifi_interface_t interface;
|
||||
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
|
||||
sl_wifi_statistics_t statistics = { };
|
||||
int ret;
|
||||
|
||||
__ASSERT(stats, "stats cannot be NULL");
|
||||
|
||||
interface = sl_wifi_get_default_interface();
|
||||
ret = sl_wifi_get_statistics(FIELD_GET(SIWX91X_INTERFACE_MASK, interface), &statistics);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to get stat: 0x%x", ret);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue