diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-02-28 01:33:55 +0300 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-05 22:39:35 +0300 |
commit | 24776cfd5559d3171054d3a7ea76d5febc54b03d (patch) | |
tree | d36c10070b18c9303b79e5bf6aee536d4c25cb45 | |
parent | e79c1ba84c68de9161d541bd2bcc8ea65c89955c (diff) | |
download | linux-24776cfd5559d3171054d3a7ea76d5febc54b03d.tar.xz |
mac80211: Fix quality reporting for wireless stats
Since "mac80211/cfg80211: move iwrange handler to cfg80211", the
results for link quality from "iwlist scan" and "iwconfig" commands
have been very different. The results are now consistent.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Reported- and tested-by: Larry Finger <larry.finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | net/mac80211/wext.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index f6924fc065d3..935c63ed3dfa 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -886,21 +886,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, return ret; } -static u8 ieee80211_get_wstats_flags(struct ieee80211_local *local) -{ - u8 wstats_flags = 0; - - wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | - IEEE80211_HW_SIGNAL_DBM) ? - IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; - wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? - IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; - if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) - wstats_flags |= IW_QUAL_DBM; - - return wstats_flags; -} - /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) { @@ -922,10 +907,45 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev wstats->qual.noise = 0; wstats->qual.updated = IW_QUAL_ALL_INVALID; } else { - wstats->qual.level = sta->last_signal; - wstats->qual.qual = sta->last_qual; - wstats->qual.noise = sta->last_noise; - wstats->qual.updated = ieee80211_get_wstats_flags(local); + wstats->qual.updated = 0; + /* + * mirror what cfg80211 does for iwrange/scan results, + * otherwise userspace gets confused. + */ + if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | + IEEE80211_HW_SIGNAL_DBM)) { + wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED; + wstats->qual.updated |= IW_QUAL_QUAL_UPDATED; + } else { + wstats->qual.updated |= IW_QUAL_LEVEL_INVALID; + wstats->qual.updated |= IW_QUAL_QUAL_INVALID; + } + + if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) { + wstats->qual.level = sta->last_signal; + wstats->qual.qual = sta->last_signal; + } else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { + int sig = sta->last_signal; + + wstats->qual.updated |= IW_QUAL_DBM; + wstats->qual.level = sig; + if (sig < -110) + sig = -110; + else if (sig > -40) + sig = -40; + wstats->qual.qual = sig + 110; + } + + if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { + /* + * This assumes that if driver reports noise, it also + * reports signal in dBm. + */ + wstats->qual.noise = sta->last_noise; + wstats->qual.updated |= IW_QUAL_NOISE_UPDATED; + } else { + wstats->qual.updated |= IW_QUAL_NOISE_INVALID; + } } rcu_read_unlock(); |