[PATCH v2] package: libiwinfo: fix noise reading for radios sharing a wiphy

Valeriy Kosikhin vkosikhin at gmail.com
Fri Apr 18 09:12:56 PDT 2025


On some devices (e.g., the Banana Pi BPI-R4 with the BE14 Wi-Fi board),
the driver registers multiple radios under a single wiphy. As a result,
the NL80211 survey dump returns the same data set regardless of which
interface is queried.

Currently, libiwinfo determines the noise value by selecting the entry
marked with the IN_USE flag. However, when multiple interfaces share a
wiphy, several entries may simultaneously have this flag set. This
causes libiwinfo to return the same noise value for all interfaces,
typically corresponding to the highest frequency in use.

This patch adds a frequency match check to ensure the noise value
corresponds to the interface’s actual frequency. The existing IN_USE
check is retained as a fallback.

Signed-off-by: Valeriy Kosikhin <vkosikhin at gmail.com>
---
Changes in v2:
- Minor correction to the commit message
- Resent to fix formatting broken by Gmail

 iwinfo_nl80211.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index dc4ff93..c530a35 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -1660,7 +1660,11 @@ static int nl80211_get_signal(const char *ifname, int *buf)
 
 static int nl80211_get_noise_cb(struct nl_msg *msg, void *arg)
 {
-	int8_t *noise = arg;
+	struct {
+		int8_t *noise;
+		int *freq;
+	} *args = arg;
+
 	struct nlattr **tb = nl80211_parse(msg);
 	struct nlattr *si[NL80211_SURVEY_INFO_MAX + 1];
 
@@ -1676,22 +1680,33 @@ static int nl80211_get_noise_cb(struct nl_msg *msg, void *arg)
 	                     tb[NL80211_ATTR_SURVEY_INFO], sp))
 		return NL_SKIP;
 
-	if (!si[NL80211_SURVEY_INFO_NOISE])
+	if (!si[NL80211_SURVEY_INFO_NOISE] || !si[NL80211_SURVEY_INFO_FREQUENCY])
 		return NL_SKIP;
 
-	if (!*noise || si[NL80211_SURVEY_INFO_IN_USE])
-		*noise = (int8_t)nla_get_u8(si[NL80211_SURVEY_INFO_NOISE]);
+	if (!*args->noise ||
+		(nla_get_u32(si[NL80211_SURVEY_INFO_FREQUENCY]) == *args->freq &&
+		si[NL80211_SURVEY_INFO_IN_USE])) {
+			*args->noise = (int8_t)nla_get_u8(si[NL80211_SURVEY_INFO_NOISE]);
+	}
 
 	return NL_SKIP;
 }
 
-
 static int nl80211_get_noise(const char *ifname, int *buf)
 {
 	int8_t noise = 0;
+	int freq = 0;
+
+	struct {
+		int8_t *noise;
+		int *freq;
+	} args = { .noise = &noise, .freq = &freq };
+
+	if (nl80211_get_frequency(ifname, &freq) < 0)
+		goto out;
 
 	if (nl80211_request(ifname, NL80211_CMD_GET_SURVEY, NLM_F_DUMP,
-	                    nl80211_get_noise_cb, &noise))
+	                    nl80211_get_noise_cb, &args))
 		goto out;
 
 	*buf = noise;
-- 
2.45.2




More information about the openwrt-devel mailing list