On Thu, Dec 4, 2008 at 5:21 AM, Larry Finger <Larry.Finger@xxxxxxxxxxxx> wrote: > The current wireless statistics for the RTL8187 poorly indicate the signal > strength and quality. With testing, I found that the AGC value is inversely > correlated with the strength as in the RTL8187B. By implementing a similar > calculation, much more code becomes common to the two devices. > > Signed-off-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx> > Tested by: Martín Ernesto Barreyro <barreyromartin@xxxxxxxxx> > --- > > John, > > This is 2.6.29 material. > > Larry > --- > > Index: wireless-testing/drivers/net/wireless/rtl818x/rtl8187_dev.c > =================================================================== > --- wireless-testing.orig/drivers/net/wireless/rtl818x/rtl8187_dev.c > +++ wireless-testing/drivers/net/wireless/rtl818x/rtl8187_dev.c > @@ -313,29 +313,14 @@ static void rtl8187_rx_cb(struct urb *ur > struct rtl8187_rx_hdr *hdr = > (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); > flags = le32_to_cpu(hdr->flags); > - signal = hdr->signal & 0x7f; > + /* As with the RTL8187B below, the AGC is used to calculate > + * signal strength and quality. In this case, the scaling > + * constants are derived from the output of p54usb. > + */ > + quality = 130 - ((41 * hdr->agc) >> 6); > + signal = -4 - ((27 * hdr->agc) >> 6); > rx_status.antenna = (hdr->signal >> 7) & 1; > - rx_status.noise = hdr->noise; > rx_status.mactime = le64_to_cpu(hdr->mac_time); > - priv->quality = signal; > - rx_status.qual = priv->quality; > - priv->noise = hdr->noise; > - rate = (flags >> 20) & 0xF; > - if (rate > 3) { /* OFDM rate */ > - if (signal > 90) > - signal = 90; > - else if (signal < 25) > - signal = 25; > - signal = 90 - signal; > - } else { /* CCK rate */ > - if (signal > 95) > - signal = 95; > - else if (signal < 30) > - signal = 30; > - signal = 95 - signal; > - } > - rx_status.signal = signal; > - priv->signal = signal; > } else { > struct rtl8187b_rx_hdr *hdr = > (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); > @@ -353,18 +338,18 @@ static void rtl8187_rx_cb(struct urb *ur > */ > flags = le32_to_cpu(hdr->flags); > quality = 170 - hdr->agc; > - if (quality > 100) > - quality = 100; > signal = 14 - hdr->agc / 2; > - rx_status.qual = quality; > - priv->quality = quality; > - rx_status.signal = signal; > - priv->signal = signal; > rx_status.antenna = (hdr->rssi >> 7) & 1; > rx_status.mactime = le64_to_cpu(hdr->mac_time); > - rate = (flags >> 20) & 0xF; > } > > + if (quality > 100) > + quality = 100; > + rx_status.qual = quality; > + priv->quality = quality; > + rx_status.signal = signal; > + priv->signal = signal; > + rate = (flags >> 20) & 0xF; > skb_trim(skb, flags & 0x0FFF); > rx_status.rate_idx = rate; > rx_status.freq = dev->conf.channel->center_freq; > @@ -1294,6 +1279,7 @@ static int __devinit rtl8187_probe(struc > > priv->mode = NL80211_IFTYPE_MONITOR; > dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | > + IEEE80211_HW_SIGNAL_DBM | > IEEE80211_HW_RX_INCLUDES_FCS; > > eeprom.data = dev; > @@ -1409,13 +1395,8 @@ static int __devinit rtl8187_probe(struc > (*channel++).hw_value = txpwr >> 8; > } > > - if (priv->is_rtl8187b) { > + if (priv->is_rtl8187b) > printk(KERN_WARNING "rtl8187: 8187B chip detected.\n"); > - dev->flags |= IEEE80211_HW_SIGNAL_DBM; > - } else { > - dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC; > - dev->max_signal = 65; > - } > > /* > * XXX: Once this driver supports anything that requires > -- > To unsubscribe from this list: send the line "unsubscribe linux-wireless" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > BTW using RTL8187B's scaling constants for RTL8187L also work well with this patch - I get almost identical readings from my BCM4318 and my RTL8187L. (I haven't yet submitted my version of the patch because it's pretty messy, with #if 0'd code and such.) I wonder whether b43 or p54usb is more correct... However, it looks like the same algorithm is applicable for both RTL8187 variants. -- Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html