diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2006-06-29 23:48:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-07-10 14:19:41 -0400 |
commit | 4221f980a4931364be7ffd81c4f16784990f6f8b (patch) | |
tree | ab7f3b768a28ff306c95a8dac6c9a7e0182a8da3 /drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |
parent | 2087da5dc12c497123d5fb8949ceed9021b673ec (diff) |
[PATCH] bcm43xx: improved statistics
This patch improves the statistics returned from
bcm43xx_get_wireless_stats. The signal level comes from smoothing the
"rssi" value returned by the firmware after it is converted into a
dBm value by the driver. The quality value is a hack derived from the
smoothed level and an assumed RX_POWER_MAX of -10 dBM. The noise value
is still the one calculated from the clean-room formula. On my system,
this is roughly -65 dBm, which seems too high.
The revised version uses the ieee80211 spinlock to protect traversing
of the network list.
Signed-Off-By: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/bcm43xx/bcm43xx_wx.c')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index ebe2a8469a78..8ffd760dc830 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
@@ -47,6 +47,9 @@ | |||
47 | #define BCM43xx_WX_VERSION 18 | 47 | #define BCM43xx_WX_VERSION 18 |
48 | 48 | ||
49 | #define MAX_WX_STRING 80 | 49 | #define MAX_WX_STRING 80 |
50 | /* FIXME: the next line is a guess as to what the maximum value of RX power | ||
51 | (in dBm) might be */ | ||
52 | #define RX_POWER_MAX -10 | ||
50 | 53 | ||
51 | 54 | ||
52 | static int bcm43xx_wx_get_name(struct net_device *net_dev, | 55 | static int bcm43xx_wx_get_name(struct net_device *net_dev, |
@@ -228,14 +231,14 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, | |||
228 | 231 | ||
229 | range->max_qual.qual = 100; | 232 | range->max_qual.qual = 100; |
230 | /* TODO: Real max RSSI */ | 233 | /* TODO: Real max RSSI */ |
231 | range->max_qual.level = 3; | 234 | range->max_qual.level = 0; |
232 | range->max_qual.noise = 100; | 235 | range->max_qual.noise = 0; |
233 | range->max_qual.updated = 7; | 236 | range->max_qual.updated = IW_QUAL_ALL_UPDATED; |
234 | 237 | ||
235 | range->avg_qual.qual = 70; | 238 | range->avg_qual.qual = 50; |
236 | range->avg_qual.level = 2; | 239 | range->avg_qual.level = 0; |
237 | range->avg_qual.noise = 40; | 240 | range->avg_qual.noise = 0; |
238 | range->avg_qual.updated = 7; | 241 | range->avg_qual.updated = IW_QUAL_ALL_UPDATED; |
239 | 242 | ||
240 | range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; | 243 | range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; |
241 | range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; | 244 | range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; |
@@ -840,6 +843,9 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d | |||
840 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 843 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
841 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 844 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
842 | struct iw_statistics *wstats; | 845 | struct iw_statistics *wstats; |
846 | struct ieee80211_network *network = NULL; | ||
847 | static int tmp_level = 0; | ||
848 | unsigned long flags; | ||
843 | 849 | ||
844 | wstats = &bcm->stats.wstats; | 850 | wstats = &bcm->stats.wstats; |
845 | if (!mac->associated) { | 851 | if (!mac->associated) { |
@@ -857,16 +863,25 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d | |||
857 | wstats->qual.level = 0; | 863 | wstats->qual.level = 0; |
858 | wstats->qual.noise = 0; | 864 | wstats->qual.noise = 0; |
859 | wstats->qual.updated = 7; | 865 | wstats->qual.updated = 7; |
860 | wstats->qual.updated |= IW_QUAL_NOISE_INVALID | | 866 | wstats->qual.updated |= IW_QUAL_ALL_UPDATED; |
861 | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; | ||
862 | return wstats; | 867 | return wstats; |
863 | } | 868 | } |
864 | /* fill in the real statistics when iface associated */ | 869 | /* fill in the real statistics when iface associated */ |
865 | wstats->qual.qual = 100; // TODO: get the real signal quality | 870 | spin_lock_irqsave(&mac->ieee->lock, flags); |
866 | wstats->qual.level = 3 - bcm->stats.link_quality; | 871 | list_for_each_entry(network, &mac->ieee->network_list, list) { |
872 | if (!memcmp(mac->associnfo.bssid, network->bssid, ETH_ALEN)) { | ||
873 | if (!tmp_level) /* get initial value */ | ||
874 | tmp_level = network->stats.rssi; | ||
875 | else /* smooth results */ | ||
876 | tmp_level = (7 * tmp_level + network->stats.rssi)/8; | ||
877 | break; | ||
878 | } | ||
879 | } | ||
880 | spin_unlock_irqrestore(&mac->ieee->lock, flags); | ||
881 | wstats->qual.level = tmp_level; | ||
882 | wstats->qual.qual = 100 + tmp_level - RX_POWER_MAX; // TODO: get the real signal quality | ||
867 | wstats->qual.noise = bcm->stats.noise; | 883 | wstats->qual.noise = bcm->stats.noise; |
868 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | | 884 | wstats->qual.updated = IW_QUAL_ALL_UPDATED; |
869 | IW_QUAL_NOISE_UPDATED; | ||
870 | wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; | 885 | wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; |
871 | wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; | 886 | wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; |
872 | wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; | 887 | wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; |