Skip to content

Commit

Permalink
drivers: wifi: siwx91x: Add Wi-Fi status and statistics
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ArunmaniAlagarsamy2710 committed Mar 10, 2025
1 parent 7eea242 commit 26ebdd8
Showing 1 changed file with 122 additions and 4 deletions.
126 changes: 122 additions & 4 deletions drivers/wifi/siwx91x/siwx91x_wifi.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,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)
Expand Down Expand Up @@ -573,6 +659,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;
Expand Down Expand Up @@ -616,6 +731,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 = {
Expand Down

0 comments on commit 26ebdd8

Please sign in to comment.