[kernel/f15] zd1211rw: fix invalid signal values from device (rhbz 720093)

John W. Linville linville at fedoraproject.org
Tue Jul 12 19:19:57 UTC 2011


commit af3abd43a548a42c86c500fd072a9d28889639dc
Author: John W. Linville <linville at tuxdriver.com>
Date:   Tue Jul 12 15:17:54 2011 -0400

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

 kernel.spec                                        |    7 ++
 ...1rw-fix-invalid-signal-values-from-device.patch |   82 ++++++++++++++++++++
 2 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 7bbad73..41d8f48 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -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 at tuxdriver.com>
+- zd1211rw: fix invalid signal values from device (rhbz 720093)
+
 * Wed Jul 06 2011 Chuck Ebbert <cebbert at 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.
diff --git a/linux-2.6-zd1211rw-fix-invalid-signal-values-from-device.patch b/linux-2.6-zd1211rw-fix-invalid-signal-values-from-device.patch
new file mode 100644
index 0000000..f91ceb8
--- /dev/null
+++ b/linux-2.6-zd1211rw-fix-invalid-signal-values-from-device.patch
@@ -0,0 +1,82 @@
+commit 7a1d6564a15183cb5994656040966df09af8390f
+Author: Jussi Kivilinna <jussi.kivilinna at 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 at mbnet.fi>
+    Signed-off-by: John W. Linville <linville at 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);
+ 


More information about the scm-commits mailing list