RFC: workaround quality bug in zd1201 hardware

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I saw in zd1201.c that there's a hardware bug related to quality
statistics:
 /* Unfortunatly the quality and noise reported is useless. 
    they seem to be accumulators that increase until you
    read them, unless we poll on a fixed interval we can't
    use them
  */

Given that I couldn't find any spec for the zd1201, I tried the
following patch to see if we could cheat by updating commsquality while
scanning. The idea is to use the values we find during scan and copy
them to zd->iwstats; this can be useful because there are a lots of
tools out there that perform scanning periodically (netapplet,
NetworkManager, ...).

Unfortunately this doesn't work perfectly, because it looks like the
scale is different when reporting AP quality on scanning and
"normal" quality.

Maybe this can be made useful with a simple conversion ?
If anyone that has more knowledge on 802.11b than I have could give me
an hint, it'd be appreciated.

Thanks!
Signed-off-by: Colin Leroy <[email protected]>
--- a/drivers/usb/net/zd1201.c	2005-03-23 15:17:12.000000000 +0100
+++ b/drivers/usb/net/zd1201.c	2005-03-23 15:17:50.000000000 +0100
@@ -1160,6 +1160,7 @@
 		return -EIO;
 
 	for(i=8; i<zd->rxlen; i+=62) {
+		const char *ap_essid;
 		iwe.cmd = SIOCGIWAP;
 		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 		memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
@@ -1169,6 +1170,7 @@
 		iwe.u.data.length = zd->rxdata[i+16];
 		iwe.u.data.flags = 1;
 		cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
+		ap_essid = zd->rxdata+i+18;
 
 		iwe.cmd = SIOCGIWMODE;
 		if (zd->rxdata[i+14]&0x01)
@@ -1204,6 +1206,17 @@
 		iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
 		iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
 		iwe.u.qual.updated = 7;
+
+		if (ap_essid && zd->essid && !strcmp(ap_essid, zd->essid)) {
+			/* hack: work around hardware bug, update current 
+			 * link quality using the scan result. 
+			 */
+			zd->iwstats.qual.qual = iwe.u.qual.qual;
+			zd->iwstats.qual.level = iwe.u.qual.level;
+			zd->iwstats.qual.noise = iwe.u.qual.noise;
+			zd->iwstats.qual.updated = 2;
+		}
+
 		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
 	}
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux