diff --git a/kernel.spec b/kernel.spec index 0365cf4c0..c0794ad7e 100644 --- a/kernel.spec +++ b/kernel.spec @@ -853,6 +853,9 @@ Patch13703: posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch Patch13704: via-ioctl-prevent-reading-uninit-memory.patch +Patch13710: rtl8180-improve-signal-reporting-for-rtl8185-hardware.patch +Patch13711: rtl8180-improve-signal-reporting-for-actual-rtl8180-hardware.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1624,6 +1627,9 @@ ApplyPatch posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch # rhbz#648671 (CVE-2010-4082) ApplyPatch via-ioctl-prevent-reading-uninit-memory.patch +ApplyPatch rtl8180-improve-signal-reporting-for-rtl8185-hardware.patch +ApplyPatch rtl8180-improve-signal-reporting-for-actual-rtl8180-hardware.patch + # END OF PATCH APPLICATIONS %endif @@ -2245,6 +2251,10 @@ fi %changelog +* Wed Nov 24 2010 John W. Linville +- rtl8180: improve signal reporting for rtl8185 hardware +- rtl8180: improve signal reporting for actual rtl8180 hardware + * Tue Nov 23 2010 Kyle McMartin - zero struct memory in ipc compat (CVE-2010-4073) (#648658) - zero struct memory in ipc shm (CVE-2010-4072) (#648656) diff --git a/rtl8180-improve-signal-reporting-for-actual-rtl8180-hardware.patch b/rtl8180-improve-signal-reporting-for-actual-rtl8180-hardware.patch new file mode 100644 index 000000000..328820187 --- /dev/null +++ b/rtl8180-improve-signal-reporting-for-actual-rtl8180-hardware.patch @@ -0,0 +1,166 @@ +commit 8b73fb8e29e9ae0458d36cc0dc25e2717587dfd4 +Author: John W. Linville +Date: Wed Jul 21 16:26:40 2010 -0400 + + rtl8180: improve signal reporting for actual rtl8180 hardware + + Adapted from Realtek-provided driver... + + Signed-off-by: John W. Linville + Tested-by: Pauli Nieminen + +diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c +index 31808f9..d8b186a 100644 +--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c +@@ -103,7 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) + { + struct rtl8180_priv *priv = dev->priv; + unsigned int count = 32; +- u8 signal; ++ u8 signal, agc, sq; + + while (count--) { + struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; +@@ -132,12 +132,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) + + rx_status.antenna = (flags2 >> 15) & 1; + rx_status.rate_idx = (flags >> 20) & 0xF; +- /* TODO: improve signal/rssi reporting for !rtl8185 */ +- signal = (flags2 >> 17) & 0x7F; +- if (rx_status.rate_idx > 3) +- signal = 90 - clamp_t(u8, signal, 25, 90); +- else +- signal = 95 - clamp_t(u8, signal, 30, 95); ++ agc = (flags2 >> 17) & 0x7F; ++ if (priv->r8185) { ++ if (rx_status.rate_idx > 3) ++ signal = 90 - clamp_t(u8, agc, 25, 90); ++ else ++ signal = 95 - clamp_t(u8, agc, 30, 95); ++ } else { ++ sq = flags2 & 0xff; ++ signal = priv->rf->calc_rssi(agc, sq); ++ } + rx_status.signal = signal; + rx_status.freq = dev->conf.channel->center_freq; + rx_status.band = dev->conf.channel->band; +diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c +index 947ee55..5cab9df 100644 +--- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c ++++ b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c +@@ -69,6 +69,15 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) + rtl8180_write_phy(dev, 0x10, ant); + } + ++static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) ++{ ++ if (agc > 60) ++ return 65; ++ ++ /* TODO(?): just return agc (or agc + 5) to avoid mult / div */ ++ return 65 * agc / 60; ++} ++ + static void grf5101_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) + { +@@ -176,5 +185,6 @@ const struct rtl818x_rf_ops grf5101_rf_ops = { + .name = "GCT", + .init = grf5101_rf_init, + .stop = grf5101_rf_stop, +- .set_chan = grf5101_rf_set_channel ++ .set_chan = grf5101_rf_set_channel, ++ .calc_rssi = grf5101_rf_calc_rssi, + }; +diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180_max2820.c +index 6c825fd..16c4655 100644 +--- a/drivers/net/wireless/rtl818x/rtl8180_max2820.c ++++ b/drivers/net/wireless/rtl818x/rtl8180_max2820.c +@@ -74,6 +74,22 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) + rtl8180_write_phy(dev, 0x10, ant); + } + ++static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) ++{ ++ bool odd; ++ ++ odd = !!(agc & 1); ++ ++ agc >>= 1; ++ if (odd) ++ agc += 76; ++ else ++ agc += 66; ++ ++ /* TODO: change addends above to avoid mult / div below */ ++ return 65 * agc / 100; ++} ++ + static void max2820_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) + { +@@ -148,5 +164,6 @@ const struct rtl818x_rf_ops max2820_rf_ops = { + .name = "Maxim", + .init = max2820_rf_init, + .stop = max2820_rf_stop, +- .set_chan = max2820_rf_set_channel ++ .set_chan = max2820_rf_set_channel, ++ .calc_rssi = max2820_rf_calc_rssi, + }; +diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c +index cea4e0c..d064fcc 100644 +--- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c ++++ b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c +@@ -76,6 +76,31 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) + + } + ++static u8 sa2400_rf_rssi_map[] = { ++ 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, ++ 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, ++ 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, ++ 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, ++ 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, ++ 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, ++ 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, ++ 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, ++ 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, ++ 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, ++}; ++ ++static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) ++{ ++ if (sq == 0x80) ++ return 1; ++ ++ if (sq > 78) ++ return 32; ++ ++ /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ ++ return 65 * sa2400_rf_rssi_map[sq] / 100; ++} ++ + static void sa2400_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) + { +@@ -198,5 +223,6 @@ const struct rtl818x_rf_ops sa2400_rf_ops = { + .name = "Philips", + .init = sa2400_rf_init, + .stop = sa2400_rf_stop, +- .set_chan = sa2400_rf_set_channel ++ .set_chan = sa2400_rf_set_channel, ++ .calc_rssi = sa2400_rf_calc_rssi, + }; +diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h +index 8522490..22d9384 100644 +--- a/drivers/net/wireless/rtl818x/rtl818x.h ++++ b/drivers/net/wireless/rtl818x/rtl818x.h +@@ -193,6 +193,7 @@ struct rtl818x_rf_ops { + void (*stop)(struct ieee80211_hw *); + void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); + void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *); ++ u8 (*calc_rssi)(u8 agc, u8 sq); + }; + + /** diff --git a/rtl8180-improve-signal-reporting-for-rtl8185-hardware.patch b/rtl8180-improve-signal-reporting-for-rtl8185-hardware.patch new file mode 100644 index 000000000..f2ba26319 --- /dev/null +++ b/rtl8180-improve-signal-reporting-for-rtl8185-hardware.patch @@ -0,0 +1,43 @@ +commit 8b74964c73ca9eed7078388d871cc7fae973cb63 +Author: John W. Linville +Date: Mon Jul 19 16:35:20 2010 -0400 + + rtl8180: improve signal reporting for rtl8185 hardware + + The existing code seemed to be somewhat based on the datasheet, but + varied substantially from the vendor-provided driver. This mirrors the + handling of the rtl8185 case from that driver, but still neglects the + specifics for the rtl8180 hardware. Those details are a bit muddled... + + Signed-off-by: John W. Linville + +diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c +index 4270502..31808f9 100644 +--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c +@@ -103,6 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) + { + struct rtl8180_priv *priv = dev->priv; + unsigned int count = 32; ++ u8 signal; + + while (count--) { + struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; +@@ -130,10 +131,14 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) + skb_put(skb, flags & 0xFFF); + + rx_status.antenna = (flags2 >> 15) & 1; +- /* TODO: improve signal/rssi reporting */ +- rx_status.signal = (flags2 >> 8) & 0x7F; +- /* XXX: is this correct? */ + rx_status.rate_idx = (flags >> 20) & 0xF; ++ /* TODO: improve signal/rssi reporting for !rtl8185 */ ++ signal = (flags2 >> 17) & 0x7F; ++ if (rx_status.rate_idx > 3) ++ signal = 90 - clamp_t(u8, signal, 25, 90); ++ else ++ signal = 95 - clamp_t(u8, signal, 30, 95); ++ rx_status.signal = signal; + rx_status.freq = dev->conf.channel->center_freq; + rx_status.band = dev->conf.channel->band; + rx_status.mactime = le64_to_cpu(entry->tsft);