diff mbox series

[1/2] Add more nl80211 info to wpa_signal_info

Message ID 20221130233310.3559058-1-druth@chromium.org
State Accepted
Headers show
Series [1/2] Add more nl80211 info to wpa_signal_info | expand

Commit Message

David Ruth Nov. 30, 2022, 11:33 p.m. UTC
Facilitate emitting more station information over D-Bus for use by the
connection manager.

* Add storage for more NL80211_STA_INFO_* fields to data structures, and
  move them through the system.
* Reorder NL80211_STA_INFO_* fields in driver_nl80211.c to match the
  ordering in nl80211.h.
* Convert signal field to an integer to support holding WPA_INVALID_NOISE
  and avoid changing logging.

* Add fields to hostap_sta_driver_data to capture more information
	* fcs_error_count
	* beacon_loss_count
	* expected_throughput
	* rx_drop_misc
	* rx_mpdus
	* rx_hemcs
	* tx_hemcs
	* rx_he_nss
	* tx_he_nss
	* avg_signal
	* avg_beacon_signal
	* avg_ack_signal
* Add hostap_sta_driver_data to wpa_signal_info and remove redundant
  fields
  	* Change logging when printing txrate to handle unsigned long
	  value

Signed-off-by: David Ruth <druth@chromium.org>
---

 src/ap/ctrl_iface_ap.c                  |   2 +-
 src/drivers/driver.h                    |  29 ++--
 src/drivers/driver_nl80211.c            | 192 ++++++++++++------------
 src/drivers/driver_nl80211.h            |   2 +-
 src/drivers/driver_nl80211_event.c      |   8 +-
 src/drivers/driver_wext.c               |   4 +-
 wpa_supplicant/bgscan_learn.c           |   2 +-
 wpa_supplicant/bgscan_simple.c          |   2 +-
 wpa_supplicant/ctrl_iface.c             |  26 ++--
 wpa_supplicant/dbus/dbus_new_handlers.c |   8 +-
 wpa_supplicant/events.c                 |  18 +--
 wpa_supplicant/wpa_supplicant.c         |  12 +-
 12 files changed, 159 insertions(+), 146 deletions(-)

Comments

Jouni Malinen Dec. 3, 2022, 11:44 a.m. UTC | #1
On Wed, Nov 30, 2022 at 11:33:09PM +0000, David Ruth wrote:
> Facilitate emitting more station information over D-Bus for use by the
> connection manager.
> 
> * Add storage for more NL80211_STA_INFO_* fields to data structures, and
>   move them through the system.
> * Reorder NL80211_STA_INFO_* fields in driver_nl80211.c to match the
>   ordering in nl80211.h.
> * Convert signal field to an integer to support holding WPA_INVALID_NOISE
>   and avoid changing logging.

Thanks, both patches applied with fixes and cleanup.
diff mbox series

Patch

diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index a02917c5f..6d379d444 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -131,7 +131,7 @@  static int hostapd_get_sta_info(struct hostapd_data *hapd,
 		len += ret;
 
 	ret = os_snprintf(buf + len, buflen - len, "tx_rate_info=%lu",
-			  data.current_tx_rate);
+			  data.current_tx_rate / 100);
 	if (os_snprintf_error(buflen - len, ret))
 		return len;
 	len += ret;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 0b019e3af..c594abb9e 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2231,11 +2231,16 @@  struct hostapd_data;
 #define STA_DRV_DATA_RX_SHORT_GI BIT(7)
 #define STA_DRV_DATA_LAST_ACK_RSSI BIT(8)
 #define STA_DRV_DATA_CONN_TIME BIT(9)
+#define STA_DRV_DATA_TX_HE_MCS BIT(10)
+#define STA_DRV_DATA_RX_HE_MCS BIT(11)
+#define STA_DRV_DATA_TX_HE_NSS BIT(12)
+#define STA_DRV_DATA_RX_HE_NSS BIT(13)
 
 struct hostap_sta_driver_data {
 	unsigned long rx_packets, tx_packets;
 	unsigned long long rx_bytes, tx_bytes;
 	unsigned long long rx_airtime, tx_airtime;
+	unsigned long long beacons_count;
 	int bytes_64bit; /* whether 64-bit byte counters are supported */
 	unsigned long current_tx_rate;
 	unsigned long current_rx_rate;
@@ -2248,13 +2253,25 @@  struct hostap_sta_driver_data {
 	s8 last_ack_rssi;
 	unsigned long backlog_packets;
 	unsigned long backlog_bytes;
-	s8 signal;
+	unsigned long fcs_error_count;
+	unsigned long beacon_loss_count;
+	unsigned long expected_throughput;
+	unsigned long rx_drop_misc;
+	unsigned long rx_mpdus;
+	int signal;
+	u8 rx_hemcs;
+	u8 tx_hemcs;
 	u8 rx_vhtmcs;
 	u8 tx_vhtmcs;
 	u8 rx_mcs;
 	u8 tx_mcs;
+	u8 rx_he_nss;
+	u8 tx_he_nss;
 	u8 rx_vht_nss;
 	u8 tx_vht_nss;
+	s8 avg_signal;
+	s8 avg_beacon_signal;
+	s8 avg_ack_signal;
 };
 
 struct hostapd_sta_add_params {
@@ -2381,11 +2398,8 @@  enum smps_mode {
  * @frequency: control frequency
  * @above_threshold: true if the above threshold was crossed
  *	(relevant for a CQM event)
- * @current_signal: in dBm
- * @avg_signal: in dBm
- * @avg_beacon_signal: in dBm
+ * @data: sta information
  * @current_noise: %WPA_INVALID_NOISE if not supported
- * @current_txrate: current TX rate
  * @chanwidth: channel width
  * @center_frq1: center frequency for the first segment
  * @center_frq2: center frequency for the second segment (if relevant)
@@ -2393,11 +2407,8 @@  enum smps_mode {
 struct wpa_signal_info {
 	u32 frequency;
 	int above_threshold;
-	int current_signal;
-	int avg_signal;
-	int avg_beacon_signal;
+	struct hostap_sta_driver_data data;
 	int current_noise;
-	int current_txrate;
 	enum chan_width chanwidth;
 	int center_frq1;
 	int center_frq2;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index c3e6594f3..ffdcade09 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1638,86 +1638,6 @@  try_again:
 }
 
 
-static int get_link_signal(struct nl_msg *msg, void *arg)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
-	static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
-		[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
-		[NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
-		[NL80211_STA_INFO_BEACON_SIGNAL_AVG] = { .type = NLA_U8 },
-	};
-	struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
-	static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
-		[NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
-		[NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
-		[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
-		[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
-	};
-	struct wpa_signal_info *sig_change = arg;
-
-	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-		  genlmsg_attrlen(gnlh, 0), NULL);
-	if (!tb[NL80211_ATTR_STA_INFO] ||
-	    nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
-			     tb[NL80211_ATTR_STA_INFO], policy))
-		return NL_SKIP;
-	if (!sinfo[NL80211_STA_INFO_SIGNAL])
-		return NL_SKIP;
-
-	sig_change->current_signal =
-		(s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
-
-	if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
-		sig_change->avg_signal =
-			(s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
-	else
-		sig_change->avg_signal = 0;
-
-	if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG])
-		sig_change->avg_beacon_signal =
-			(s8)
-			nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]);
-	else
-		sig_change->avg_beacon_signal = 0;
-
-	if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
-		if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
-				     sinfo[NL80211_STA_INFO_TX_BITRATE],
-				     rate_policy)) {
-			sig_change->current_txrate = 0;
-		} else {
-			if (rinfo[NL80211_RATE_INFO_BITRATE]) {
-				sig_change->current_txrate =
-					nla_get_u16(rinfo[
-					     NL80211_RATE_INFO_BITRATE]) * 100;
-			}
-		}
-	}
-
-	return NL_SKIP;
-}
-
-
-int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
-			    const u8 *bssid, struct wpa_signal_info *sig)
-{
-	struct nl_msg *msg;
-
-	sig->current_signal = -WPA_INVALID_NOISE;
-	sig->current_txrate = 0;
-
-	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_STATION)) ||
-	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) {
-		nlmsg_free(msg);
-		return -ENOBUFS;
-	}
-
-	return send_and_recv_msgs(drv, msg, get_link_signal, sig, NULL, NULL);
-}
-
-
 static int get_link_noise(struct nl_msg *msg, void *arg)
 {
 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
@@ -7214,14 +7134,24 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 		[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
-		[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
-		[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
-		[NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_RX_BYTES64] = { .type = NLA_U64 },
 		[NL80211_STA_INFO_TX_BYTES64] = { .type = NLA_U64 },
 		[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
-		[NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 },
+		[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_TX_RETRIES] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
+		[NL80211_STA_INFO_BEACON_LOSS] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_EXPECTED_THROUGHPUT] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_RX_DROP_MISC] = { .type = NLA_U64 },
+		[NL80211_STA_INFO_BEACON_RX] = { .type = NLA_U64 },
+		[NL80211_STA_INFO_BEACON_SIGNAL_AVG] = { .type = NLA_U8},
 		[NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 },
+		[NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 },
+		[NL80211_STA_INFO_ACK_SIGNAL_AVG] = { .type = NLA_S8 },
+		[NL80211_STA_INFO_RX_MPDUS] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_FCS_ERROR_COUNT] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_TX_DURATION] = { .type = NLA_U64 },
 		[NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 },
 	};
@@ -7233,6 +7163,8 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 		[NL80211_RATE_INFO_VHT_MCS] = { .type = NLA_U8 },
 		[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
 		[NL80211_RATE_INFO_VHT_NSS] = { .type = NLA_U8 },
+		[NL80211_RATE_INFO_HE_MCS] = { .type = NLA_U8 },
+		[NL80211_RATE_INFO_HE_NSS] = { .type = NLA_U8 },
 	};
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -7275,28 +7207,56 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 			nla_get_u64(stats[NL80211_STA_INFO_TX_BYTES64]);
 		data->bytes_64bit = 1;
 	}
+	if (stats[NL80211_STA_INFO_SIGNAL])
+		data->signal = (s8) nla_get_u8(stats[NL80211_STA_INFO_SIGNAL]);
 	if (stats[NL80211_STA_INFO_RX_PACKETS])
 		data->rx_packets =
 			nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
 	if (stats[NL80211_STA_INFO_TX_PACKETS])
 		data->tx_packets =
 			nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
-	if (stats[NL80211_STA_INFO_RX_DURATION])
-		data->rx_airtime =
-			nla_get_u64(stats[NL80211_STA_INFO_RX_DURATION]);
-	if (stats[NL80211_STA_INFO_TX_DURATION])
-		data->tx_airtime =
-			nla_get_u64(stats[NL80211_STA_INFO_TX_DURATION]);
+	if (stats[NL80211_STA_INFO_TX_RETRIES])
+		data->tx_retry_count =
+			nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
 	if (stats[NL80211_STA_INFO_TX_FAILED])
 		data->tx_retry_failed =
 			nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
-	if (stats[NL80211_STA_INFO_SIGNAL])
-		data->signal = nla_get_u8(stats[NL80211_STA_INFO_SIGNAL]);
+	if (stats[NL80211_STA_INFO_SIGNAL_AVG])
+		data->avg_signal =
+			(s8) nla_get_u8(stats[NL80211_STA_INFO_SIGNAL_AVG]);
+	if (stats[NL80211_STA_INFO_BEACON_LOSS])
+		data->beacon_loss_count =
+			nla_get_u32(stats[NL80211_STA_INFO_BEACON_LOSS]);
+	if (stats[NL80211_STA_INFO_EXPECTED_THROUGHPUT])
+		data->expected_throughput =
+			nla_get_u32(stats[NL80211_STA_INFO_EXPECTED_THROUGHPUT]);
+	if (stats[NL80211_STA_INFO_RX_DROP_MISC])
+		data->rx_drop_misc =
+			nla_get_u32(stats[NL80211_STA_INFO_RX_DROP_MISC]);
+	if (stats[NL80211_STA_INFO_BEACON_RX])
+		data->beacons_count =
+			nla_get_u64(stats[NL80211_STA_INFO_BEACON_RX]);
+	if (stats[NL80211_STA_INFO_BEACON_SIGNAL_AVG])
+		data->avg_beacon_signal =
+			(s8) nla_get_u8(stats[NL80211_STA_INFO_BEACON_SIGNAL_AVG]);
+	if (stats[NL80211_STA_INFO_RX_DURATION])
+		data->rx_airtime =
+			nla_get_u64(stats[NL80211_STA_INFO_RX_DURATION]);
 	if (stats[NL80211_STA_INFO_ACK_SIGNAL]) {
 		data->last_ack_rssi =
 			nla_get_u8(stats[NL80211_STA_INFO_ACK_SIGNAL]);
 		data->flags |= STA_DRV_DATA_LAST_ACK_RSSI;
 	}
+	if (stats[NL80211_STA_INFO_ACK_SIGNAL_AVG])
+		data->avg_ack_signal = nla_get_s8(stats[NL80211_STA_INFO_ACK_SIGNAL_AVG]);
+	if (stats[NL80211_STA_INFO_RX_MPDUS])
+		data->rx_mpdus = nla_get_u32(stats[NL80211_STA_INFO_RX_MPDUS]);
+	if (stats[NL80211_STA_INFO_FCS_ERROR_COUNT])
+		data->fcs_error_count =
+			nla_get_u32(stats[NL80211_STA_INFO_FCS_ERROR_COUNT]);
+	if (stats[NL80211_STA_INFO_TX_DURATION])
+		data->tx_airtime =
+			nla_get_u64(stats[NL80211_STA_INFO_TX_DURATION]);
 
 	if (stats[NL80211_STA_INFO_CONNECTED_TIME]) {
 		data->connected_sec =
@@ -7315,6 +7275,10 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 			data->current_tx_rate =
 				nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
 
+		// Convert from 100kbps to kbps; it's a more convenient
+		// unit.  It's also safe up until ~1Tbps.
+		data->current_tx_rate = data->current_tx_rate * 100;
+
 		if (rate[NL80211_RATE_INFO_MCS]) {
 			data->tx_mcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
 			data->flags |= STA_DRV_DATA_TX_MCS;
@@ -7331,6 +7295,14 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 				nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
 			data->flags |= STA_DRV_DATA_TX_VHT_NSS;
 		}
+		if (rate[NL80211_RATE_INFO_HE_MCS]) {
+			data->tx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]);
+			data->flags |= STA_DRV_DATA_TX_HE_MCS;
+		}
+		if (rate[NL80211_RATE_INFO_HE_NSS]) {
+			data->tx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]);
+			data->flags |= STA_DRV_DATA_TX_HE_NSS;
+		}
 	}
 
 	if (stats[NL80211_STA_INFO_RX_BITRATE] &&
@@ -7344,6 +7316,10 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 			data->current_rx_rate =
 				nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
 
+		// Convert from 100kbps to kbps; it's a more convenient
+		// unit.  It's also safe up until ~1Tbps.
+		data->current_rx_rate = data->current_rx_rate * 100;
+
 		if (rate[NL80211_RATE_INFO_MCS]) {
 			data->rx_mcs =
 				nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
@@ -7361,6 +7337,14 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 				nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
 			data->flags |= STA_DRV_DATA_RX_VHT_NSS;
 		}
+		if (rate[NL80211_RATE_INFO_HE_MCS]) {
+			data->rx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]);
+			data->flags |= STA_DRV_DATA_RX_HE_MCS;
+		}
+		if (rate[NL80211_RATE_INFO_HE_NSS]) {
+			data->rx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]);
+			data->flags |= STA_DRV_DATA_RX_HE_NSS;
+		}
 	}
 
 	if (stats[NL80211_STA_INFO_TID_STATS])
@@ -7369,6 +7353,24 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 	return NL_SKIP;
 }
 
+int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
+			    const u8 *bssid, struct hostap_sta_driver_data *data)
+{
+	struct nl_msg *msg;
+
+	data->signal = -WPA_INVALID_NOISE;
+	data->current_tx_rate = 0;
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_STATION)) ||
+	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) {
+		nlmsg_free(msg);
+		return -ENOBUFS;
+	}
+
+	return send_and_recv_msgs(drv, msg, get_sta_handler, data, NULL, NULL);
+}
+
+
 static int i802_read_sta_data(struct i802_bss *bss,
 			      struct hostap_sta_driver_data *data,
 			      const u8 *addr)
@@ -8783,12 +8785,12 @@  static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
 	int res;
 
 	os_memset(si, 0, sizeof(*si));
-	res = nl80211_get_link_signal(drv, drv->bssid, si);
+	res = nl80211_get_link_signal(drv, drv->bssid, &si->data);
 	if (res) {
 		if (drv->nlmode != NL80211_IFTYPE_ADHOC &&
 		    drv->nlmode != NL80211_IFTYPE_MESH_POINT)
 			return res;
-		si->current_signal = 0;
+		si->data.signal = 0;
 	}
 
 	res = nl80211_get_channel_width(drv, si);
@@ -8937,7 +8939,7 @@  static int nl80211_mlo_signal_poll(void *priv,
 
 		res = nl80211_get_link_signal(drv,
 					      drv->sta_mlo_info.links[i].bssid,
-					      &mlo_si->links[i]);
+					      &mlo_si->links[i].data);
 		if (res != 0)
 			return res;
 
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 0740e064a..24387c0f8 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -269,7 +269,7 @@  int is_ap_interface(enum nl80211_iftype nlmode);
 int is_sta_interface(enum nl80211_iftype nlmode);
 int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv);
 int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
-			    const u8 *bssid, struct wpa_signal_info *sig);
+			    const u8 *bssid, struct hostap_sta_driver_data *data);
 int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
 			   struct wpa_signal_info *sig_change);
 int nl80211_get_wiphy_index(struct i802_bss *bss);
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index c10c31a37..8243e99fb 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1834,11 +1834,11 @@  static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
 	 * nl80211_get_link_signal() and nl80211_get_link_noise() set default
 	 * values in case querying the driver fails.
 	 */
-	res = nl80211_get_link_signal(drv, drv->bssid, &ed.signal_change);
+	res = nl80211_get_link_signal(drv, drv->bssid, &ed.signal_change.data);
 	if (res == 0) {
-		wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %d",
-			   ed.signal_change.current_signal,
-			   ed.signal_change.current_txrate);
+		wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %lu",
+			   ed.signal_change.data.signal,
+			   ed.signal_change.data.current_tx_rate);
 	} else {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Querying the driver for signal info failed");
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 0f0ad1f53..cf201fe86 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -2424,7 +2424,7 @@  static int wpa_driver_wext_signal_poll(void *priv, struct wpa_signal_info *si)
 	struct iwreq iwr;
 
 	os_memset(si, 0, sizeof(*si));
-	si->current_signal = -WPA_INVALID_NOISE;
+	si->data.signal = -WPA_INVALID_NOISE;
 	si->current_noise = WPA_INVALID_NOISE;
 	si->chanwidth = CHAN_WIDTH_UNKNOWN;
 
@@ -2440,7 +2440,7 @@  static int wpa_driver_wext_signal_poll(void *priv, struct wpa_signal_info *si)
 		return -1;
 	}
 
-	si->current_signal = stats.qual.level -
+	si->data.signal = stats.qual.level -
 		((stats.qual.updated & IW_QUAL_DBM) ? 0x100 : 0);
 	si->current_noise = stats.qual.noise -
 		((stats.qual.updated & IW_QUAL_DBM) ? 0x100 : 0);
diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c
index cb732f709..75bdec1c0 100644
--- a/wpa_supplicant/bgscan_learn.c
+++ b/wpa_supplicant/bgscan_learn.c
@@ -422,7 +422,7 @@  static void * bgscan_learn_init(struct wpa_supplicant *wpa_s,
 		/* Poll for signal info to set initial scan interval */
 		struct wpa_signal_info siginfo;
 		if (wpa_drv_signal_poll(wpa_s, &siginfo) == 0 &&
-		    siginfo.current_signal >= data->signal_threshold)
+		    siginfo.data.signal >= data->signal_threshold)
 			data->scan_interval = data->long_interval;
 	}
 
diff --git a/wpa_supplicant/bgscan_simple.c b/wpa_supplicant/bgscan_simple.c
index 41a26df0d..5a8f97c2a 100644
--- a/wpa_supplicant/bgscan_simple.c
+++ b/wpa_supplicant/bgscan_simple.c
@@ -137,7 +137,7 @@  static void * bgscan_simple_init(struct wpa_supplicant *wpa_s,
 		/* Poll for signal info to set initial scan interval */
 		struct wpa_signal_info siginfo;
 		if (wpa_drv_signal_poll(wpa_s, &siginfo) == 0 &&
-		    siginfo.current_signal >= data->signal_threshold)
+		    siginfo.data.signal >= data->signal_threshold)
 			data->scan_interval = data->long_interval;
 	}
 	wpa_printf(MSG_DEBUG, "bgscan simple: Init scan interval: %d",
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index e91bf4ebe..49fc8caaf 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -8101,9 +8101,9 @@  static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
 	pos = buf;
 	end = buf + buflen;
 
-	ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%d\n"
+	ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%lu\n"
 			  "NOISE=%d\nFREQUENCY=%u\n",
-			  si.current_signal, si.current_txrate / 1000,
+			  si.data.signal, si.data.current_tx_rate / 1000,
 			  si.current_noise, si.frequency);
 	if (os_snprintf_error(end - pos, ret))
 		return -1;
@@ -8133,17 +8133,17 @@  static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
 		pos += ret;
 	}
 
-	if (si.avg_signal) {
+	if (si.data.avg_signal) {
 		ret = os_snprintf(pos, end - pos,
-				  "AVG_RSSI=%d\n", si.avg_signal);
+				  "AVG_RSSI=%d\n", si.data.avg_signal);
 		if (os_snprintf_error(end - pos, ret))
 			return -1;
 		pos += ret;
 	}
 
-	if (si.avg_beacon_signal) {
+	if (si.data.avg_beacon_signal) {
 		ret = os_snprintf(pos, end - pos,
-				  "AVG_BEACON_RSSI=%d\n", si.avg_beacon_signal);
+				  "AVG_BEACON_RSSI=%d\n", si.data.avg_beacon_signal);
 		if (os_snprintf_error(end - pos, ret))
 			return -1;
 		pos += ret;
@@ -11565,10 +11565,10 @@  static int wpas_ctrl_iface_mlo_signal_poll(struct wpa_supplicant *wpa_s,
 			continue;
 
 		ret = os_snprintf(pos, end - pos,
-				  "LINK_ID=%d\nRSSI=%d\nLINKSPEED=%d\n"
+				  "LINK_ID=%d\nRSSI=%d\nLINKSPEED=%lu\n"
 				  "NOISE=%d\nFREQUENCY=%u\n",
-				  i, mlo_si.links[i].current_signal,
-				  mlo_si.links[i].current_txrate / 1000,
+				  i, mlo_si.links[i].data.signal,
+				  mlo_si.links[i].data.current_tx_rate / 1000,
 				  mlo_si.links[i].current_noise,
 				  mlo_si.links[i].frequency);
 		if (os_snprintf_error(end - pos, ret))
@@ -11600,19 +11600,19 @@  static int wpas_ctrl_iface_mlo_signal_poll(struct wpa_supplicant *wpa_s,
 			pos += ret;
 		}
 
-		if (mlo_si.links[i].avg_signal) {
+		if (mlo_si.links[i].data.avg_signal) {
 			ret = os_snprintf(pos, end - pos,
 					  "AVG_RSSI=%d\n",
-					  mlo_si.links[i].avg_signal);
+					  mlo_si.links[i].data.avg_signal);
 			if (os_snprintf_error(end - pos, ret))
 				return -1;
 			pos += ret;
 		}
 
-		if (mlo_si.links[i].avg_beacon_signal) {
+		if (mlo_si.links[i].data.avg_beacon_signal) {
 			ret = os_snprintf(pos, end - pos,
 					  "AVG_BEACON_RSSI=%d\n",
-					  mlo_si.links[i].avg_beacon_signal);
+					  mlo_si.links[i].data.avg_beacon_signal);
 			if (os_snprintf_error(end - pos, ret))
 				return -1;
 			pos += ret;
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index b45ab4022..69fdf6036 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1969,9 +1969,9 @@  DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
 					      "a{sv}", &variant_iter) ||
 	    !wpa_dbus_dict_open_write(&variant_iter, &iter_dict) ||
 	    !wpa_dbus_dict_append_int32(&iter_dict, "rssi",
-					si.current_signal) ||
+					si.data.signal) ||
 	    !wpa_dbus_dict_append_int32(&iter_dict, "linkspeed",
-					si.current_txrate / 1000) ||
+					si.data.current_tx_rate / 1000) ||
 	    !wpa_dbus_dict_append_int32(&iter_dict, "noise",
 					si.current_noise) ||
 	    !wpa_dbus_dict_append_uint32(&iter_dict, "frequency",
@@ -1985,9 +1985,9 @@  DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
 					  si.center_frq1) ||
 	      !wpa_dbus_dict_append_int32(&iter_dict, "center-frq2",
 					  si.center_frq2))) ||
-	    (si.avg_signal &&
+	    (si.data.avg_signal &&
 	     !wpa_dbus_dict_append_int32(&iter_dict, "avg-rssi",
-					 si.avg_signal)) ||
+					 si.data.avg_signal)) ||
 	    !wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
 	    !dbus_message_iter_close_container(&iter, &variant_iter))
 		goto nomem;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index fe8ab50ff..ee2271d67 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2004,9 +2004,9 @@  int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
 	 * information about our currently associated AP.
 	 */
 	if (wpa_drv_signal_poll(wpa_s, &si) == 0 &&
-	    (si.avg_beacon_signal || si.avg_signal)) {
-		cur_level = si.avg_beacon_signal ? si.avg_beacon_signal :
-			si.avg_signal;
+	    (si.data.avg_beacon_signal || si.data.avg_signal)) {
+		cur_level = si.data.avg_beacon_signal ? si.data.avg_beacon_signal :
+			si.data.avg_signal;
 		cur_snr = wpas_get_snr_signal_info(si.frequency, cur_level,
 						   si.current_noise);
 
@@ -5769,18 +5769,18 @@  void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 		break;
 	case EVENT_SIGNAL_CHANGE:
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
-			"above=%d signal=%d noise=%d txrate=%d",
+			"above=%d signal=%d noise=%d txrate=%lu",
 			data->signal_change.above_threshold,
-			data->signal_change.current_signal,
+			data->signal_change.data.signal,
 			data->signal_change.current_noise,
-			data->signal_change.current_txrate);
+			data->signal_change.data.current_tx_rate);
 		wpa_bss_update_level(wpa_s->current_bss,
-				     data->signal_change.current_signal);
+				     data->signal_change.data.signal);
 		bgscan_notify_signal_change(
 			wpa_s, data->signal_change.above_threshold,
-			data->signal_change.current_signal,
+			data->signal_change.data.signal,
 			data->signal_change.current_noise,
-			data->signal_change.current_txrate);
+			data->signal_change.data.current_tx_rate);
 		break;
 	case EVENT_INTERFACE_MAC_CHANGED:
 		wpa_supplicant_update_mac_addr(wpa_s);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index fa91648d0..f86ca0f77 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -8888,17 +8888,17 @@  int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
 				continue;
 			wpa_printf(MSG_DEBUG,
 				   "Override driver signal_poll information: current_signal: %d->%d avg_signal: %d->%d avg_beacon_signal: %d->%d current_noise: %d->%d",
-				   si->current_signal,
+				   si->data.signal,
 				   dso->si_current_signal,
-				   si->avg_signal,
+				   si->data.avg_signal,
 				   dso->si_avg_signal,
-				   si->avg_beacon_signal,
+				   si->data.avg_beacon_signal,
 				   dso->si_avg_beacon_signal,
 				   si->current_noise,
 				   dso->si_current_noise);
-			si->current_signal = dso->si_current_signal;
-			si->avg_signal = dso->si_avg_signal;
-			si->avg_beacon_signal = dso->si_avg_beacon_signal;
+			si->data.signal = dso->si_current_signal;
+			si->data.avg_signal = dso->si_avg_signal;
+			si->data.avg_beacon_signal = dso->si_avg_beacon_signal;
 			si->current_noise = dso->si_current_noise;
 			break;
 		}