zd1211rw: fix invalid signal values from device (rhbz 720093)

This commit is contained in:
John W. Linville 2011-07-12 15:17:54 -04:00
parent c2a198def5
commit af3abd43a5
2 changed files with 89 additions and 0 deletions

View File

@ -783,6 +783,8 @@ Patch12420: crypto-aesni_intel-merge-with-fpu_ko.patch
Patch12430: nl80211-fix-check-for-valid-ssid-size-in-scan-operations.patch
Patch12431: nl80211-fix-overflow-in-ssid_len.patch.patch
Patch12440: linux-2.6-zd1211rw-fix-invalid-signal-values-from-device.patch
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@ -1342,6 +1344,8 @@ ApplyPatch bluetooth-prevent-buffer-overflow-in-l2cap-config-request.patch
ApplyPatch nl80211-fix-check-for-valid-ssid-size-in-scan-operations.patch
ApplyPatch nl80211-fix-overflow-in-ssid_len.patch.patch
ApplyPatch linux-2.6-zd1211rw-fix-invalid-signal-values-from-device.patch
# Misc fixes
# The input layer spews crap no-one cares about.
ApplyPatch linux-2.6-input-kill-stupid-messages.patch
@ -2075,6 +2079,9 @@ fi
# and build.
%changelog
* Tue Jul 12 2011 John W. Linville <linville@tuxdriver.com>
- zd1211rw: fix invalid signal values from device (rhbz 720093)
* Wed Jul 06 2011 Chuck Ebbert <cebbert@redhat.com> 2.6.38.8-35
- Revert SCSI/block patches from 2.6.38.6 that caused more problems
than they fixed; drop band-aid patch attempting to fix the fix.

View File

@ -0,0 +1,82 @@
commit 7a1d6564a15183cb5994656040966df09af8390f
Author: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Date: Mon Jun 20 14:42:28 2011 +0300
zd1211rw: fix invalid signal values from device
Driver uses IEEE80211_HW_SIGNAL_UNSPEC and so signal values reported to
mac80211 should be in range 0..100. Sometimes device return out of range
values. These out of range values can then trigger warning in
cfg80211_inform_bss_frame.
This patch adds checks to enforce range returned from driver to
mac80211 be in 0..100 range.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 5463ca9..9a1b013 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -37,9 +37,15 @@ typedef u16 __nocast zd_addr_t;
if (net_ratelimit()) \
dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
} while (0)
+# define dev_dbg_f_cond(dev, cond, fmt, args...) ({ \
+ bool __cond = !!(cond); \
+ if (unlikely(__cond)) \
+ dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
+})
#else
# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
# define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0)
+# define dev_dbg_f_cond(dev, cond, fmt, args...) do { (void)(dev); } while (0)
#endif /* DEBUG */
#ifdef DEBUG
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 5037c8b..5de28bf 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -160,6 +160,22 @@ static int zd_reg2alpha2(u8 regdomain, char *alpha2)
return 1;
}
+static int zd_check_signal(struct ieee80211_hw *hw, int signal)
+{
+ struct zd_mac *mac = zd_hw_mac(hw);
+
+ dev_dbg_f_cond(zd_mac_dev(mac), signal < 0 || signal > 100,
+ "%s: signal value from device not in range 0..100, "
+ "but %d.\n", __func__, signal);
+
+ if (signal < 0)
+ signal = 0;
+ else if (signal > 100)
+ signal = 100;
+
+ return signal;
+}
+
int zd_mac_preinit_hw(struct ieee80211_hw *hw)
{
int r;
@@ -461,7 +477,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
if (i<IEEE80211_TX_MAX_RATES)
info->status.rates[i].idx = -1; /* terminate */
- info->status.ack_signal = ackssi;
+ info->status.ack_signal = zd_check_signal(hw, ackssi);
ieee80211_tx_status_irqsafe(hw, skb);
}
@@ -982,7 +998,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
stats.band = IEEE80211_BAND_2GHZ;
- stats.signal = status->signal_strength;
+ stats.signal = zd_check_signal(hw, status->signal_strength);
rate = zd_rx_rate(buffer, status);