drivers: wifi: siwx91x: Add Wi-Fi status and statistics

This commit adds support for Wi-Fi status and statistics
functionalities:
- wifi status	  : Displays the current mode status.
- wifi statistics : Provides details on the transmitted and
                    received packet counts.

Signed-off-by: Arunmani Alagarsamy <arunmani.a@silabs.com>
This commit is contained in:
Arunmani Alagarsamy 2025-02-18 11:02:10 +05:30 committed by Carles Cufí
commit 601a9fab80

View file

@ -477,14 +477,100 @@ static int siwx91x_scan(const struct device *dev, struct wifi_scan_params *z_sca
static int siwx91x_status(const struct device *dev, struct wifi_iface_status *status)
{
sl_si91x_rsp_wireless_info_t wlan_info = { };
struct siwx91x_dev *sidev = dev->data;
int32_t rssi = -1;
sl_wifi_interface_t interface;
int32_t rssi;
int ret;
__ASSERT(status, "status cannot be NULL");
memset(status, 0, sizeof(*status));
status->state = sidev->state;
sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &rssi);
status->rssi = rssi;
return 0;
if (sidev->state <= WIFI_STATE_INACTIVE) {
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);
return -EIO;
}
strncpy(status->ssid, wlan_info.ssid, WIFI_SSID_MAX_LEN);
status->ssid_len = strlen(status->ssid);
memcpy(status->bssid, wlan_info.mac_address, WIFI_MAC_ADDR_LEN);
status->mfp = WIFI_MFP_UNKNOWN;
status->wpa3_ent_type = WIFI_WPA3_ENTERPRISE_NA;
if (interface & SL_WIFI_2_4GHZ_INTERFACE) {
status->band = WIFI_FREQ_BAND_2_4_GHZ;
}
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) == SL_WIFI_CLIENT_INTERFACE) {
sl_wifi_operational_statistics_t operational_statistics = { };
status->link_mode = WIFI_LINK_MODE_UNKNOWN;
status->iface_mode = WIFI_MODE_INFRA;
status->channel = wlan_info.channel_number;
status->twt_capable = true;
ret = sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &rssi);
if (ret) {
LOG_ERR("Failed to get signal strength: 0x%x", ret);
return -EINVAL;
}
status->rssi = rssi;
ret = sl_wifi_get_operational_statistics(SL_WIFI_CLIENT_INTERFACE,
&operational_statistics);
if (ret) {
LOG_ERR("Failed to get operational statistics: 0x%x", ret);
return -EINVAL;
}
status->beacon_interval = sys_get_le16(operational_statistics.beacon_interval);
status->dtim_period = operational_statistics.dtim_period;
} else if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) == SL_WIFI_AP_INTERFACE) {
sl_wifi_ap_configuration_t sl_ap_cfg = { };
ret = sl_wifi_get_ap_configuration(SL_WIFI_AP_INTERFACE, &sl_ap_cfg);
if (ret) {
LOG_ERR("Failed to get the AP configuration: 0x%x", ret);
return -EINVAL;
}
status->twt_capable = false;
status->link_mode = WIFI_4;
status->iface_mode = WIFI_MODE_AP;
status->channel = sl_ap_cfg.channel.channel;
status->beacon_interval = sl_ap_cfg.beacon_interval;
status->dtim_period = sl_ap_cfg.dtim_beacon_count;
wlan_info.sec_type = (uint8_t)sl_ap_cfg.security;
} else {
status->link_mode = WIFI_LINK_MODE_UNKNOWN;
status->iface_mode = WIFI_MODE_UNKNOWN;
status->channel = 0;
return -EINVAL;
}
switch (wlan_info.sec_type) {
case SL_WIFI_OPEN:
status->security = WIFI_SECURITY_TYPE_NONE;
break;
case SL_WIFI_WPA2:
status->security = WIFI_SECURITY_TYPE_PSK;
break;
case SL_WIFI_WPA3:
status->security = WIFI_SECURITY_TYPE_SAE;
break;
default:
status->security = WIFI_SECURITY_TYPE_UNKNOWN;
}
return ret;
}
static int siwx91x_mode(const struct device *dev, struct wifi_mode_info *mode)
@ -594,6 +680,35 @@ static void siwx91x_ethernet_init(struct net_if *iface)
}
}
#if defined(CONFIG_NET_STATISTICS_WIFI)
static int siwx91x_stats(const struct device *dev, struct net_stats_wifi *stats)
{
ARG_UNUSED(dev);
sl_wifi_interface_t 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);
return -EINVAL;
}
stats->multicast.rx = statistics.mcast_rx_count;
stats->multicast.tx = statistics.mcast_tx_count;
stats->unicast.rx = statistics.ucast_rx_count;
stats->unicast.tx = statistics.ucast_tx_count;
stats->sta_mgmt.beacons_rx = statistics.beacon_rx_count;
stats->sta_mgmt.beacons_miss = statistics.beacon_lost_count;
stats->overrun_count = statistics.overrun_count;
return ret;
}
#endif
static void siwx91x_iface_init(struct net_if *iface)
{
struct siwx91x_dev *sidev = iface->if_dev->dev->data;
@ -637,6 +752,9 @@ static const struct wifi_mgmt_ops siwx91x_mgmt = {
.ap_sta_disconnect = siwx91x_ap_sta_disconnect,
.iface_status = siwx91x_status,
.mode = siwx91x_mode,
#if defined(CONFIG_NET_STATISTICS_WIFI)
.get_stats = siwx91x_stats,
#endif
};
static const struct net_wifi_mgmt_offload siwx91x_api = {