diff mbox series

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

Message ID 20250418161338.1684427-1-vkosikhin@gmail.com
State New
Headers show
Series [v2] package: libiwinfo: fix noise reading for radios sharing a wiphy | expand

Commit Message

Valeriy Kosikhin April 18, 2025, 4:12 p.m. UTC
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@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(-)

Comments

Valeriy Kosikhin June 23, 2025, 12:43 p.m. UTC | #1
Hi, Daniel!

Would you take a look at a libiwinfo patch I submitted a while ago?
It seems to fall within your area of expertise, and I have no Idea who else to ping
for a review.

Patchwork link:
https://patchwork.ozlabs.org/project/openwrt/patch/20250418161338.1684427-1-vkosikhin@gmail.com/

--
Best regards
Valeriy Kosikhin


> On 18 Apr 2025, at 19:12, Valeriy Kosikhin <vkosikhin@gmail.com> wrote:
> 
> 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@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
>
diff mbox series

Patch

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;