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:
parent
2f29cb67b7
commit
601a9fab80
1 changed files with 122 additions and 4 deletions
|
@ -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 = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue