On Tue, 2008-03-18 at 15:10 +0100, Holger Schurig wrote: > I wasn't really satisfied with a graphical program that displayed > the link quality, the display was bit erratically. While changing > this, I noticed some other things which this and the next patch > addresses. > > However, for this patch I'm not sure if it goes into the right > direction. > > > This changes the quality calculation for wireless statistics to > only consider signal & noise, but not number of tx-retries. > Also changes a the rather complicated formular for quality to be > more like http://www.ces.clemson.edu/linux/signal_quality.shtml. > > Note that tx_retries are no longer used for the quality number. I > don't know of any other driver that does it, and tx_retries is > only increasing, so the quality would become smaller and > smaller ... which wouldn't reflect reality. I actually tried to emulate the ipw2200 quality calculations, and of course may have made some mistakes. The ipw2200 uses a combination of things to indicate quality, txretries being one of them. I still think txretries is a good thing to include, because if you have to keep retrying then something is definitely wrong. However, it should probably be a running average of the retries over the last 20 or 30 seconds or something, which was my mistake. > Questionable things: > > I also found that the average noise floor is -86 dBm, not -96 > dBm. So I changed this constant. Maybe this is wrong, what values > do your cards report? When possible, we should use a window-ed average of the cards reported noise from beacons or received frames instead of a constant, that's a further improvement though. > The wireless stats have SNR and noise floor to calcutate the > quality. However, the scanning logic (for "iwlist XXX scan") only > has a not-really-described dimensionless RSSI value. So the Well, when we had the (badly) averaged array values in there, the noise floor was available to the scan reporting. There are tables to map RSSI -> dBm for each part which should be in the firmware spec or seen in the driver code. We should definitely be using averaged noise floor and the RSSI converted to dBm/SNR in the scan function. > quality display for both outputs are a bit different, althought > not too much. I don't know any good method, not even from above > website, that would make both calculation results identical. > However, this was also not the case with the old code. We can't really make the identical since we can't use the received frames quality indicators when doing scan results, but we could as I said above use the converted RSSI and the averaged noise floor. Dan > > Index: wireless-testing/drivers/net/wireless/libertas/wext.c > =================================================================== > --- wireless-testing.orig/drivers/net/wireless/libertas/wext.c > 2008-03-18 13:42:42.000000000 +0100 > +++ wireless-testing/drivers/net/wireless/libertas/wext.c > 2008-03-18 13:42:55.000000000 +0100 > @@ -805,21 +805,8 @@ out: > > static struct iw_statistics *lbs_get_wireless_stats(struct > net_device *dev) > { > - enum { > - POOR = 30, > - FAIR = 60, > - GOOD = 80, > - VERY_GOOD = 90, > - EXCELLENT = 95, > - PERFECT = 100 > - }; > struct lbs_private *priv = dev->priv; > - u32 rssi_qual; > - u32 tx_qual; > - u32 quality = 0; > int stats_valid = 0; > - u8 rssi; > - u32 tx_retries; > struct cmd_ds_802_11_get_log log; > u16 snr, nf; > > @@ -838,24 +825,6 @@ static struct iw_statistics *lbs_get_wir > priv->wstats.qual.level = CAL_RSSI(snr, nf); > priv->wstats.qual.noise = CAL_NF(nf); > > - lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level); > - lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise); > - > - rssi = priv->wstats.qual.level - priv->wstats.qual.noise; > - if (rssi < 15) > - rssi_qual = rssi * POOR / 10; > - else if (rssi < 20) > - rssi_qual = (rssi - 15) * (FAIR - POOR) / 5 + POOR; > - else if (rssi < 30) > - rssi_qual = (rssi - 20) * (GOOD - FAIR) / 5 + FAIR; > - else if (rssi < 40) > - rssi_qual = (rssi - 30) * (VERY_GOOD - GOOD) / > - 10 + GOOD; > - else > - rssi_qual = (rssi - 40) * (PERFECT - VERY_GOOD) / > - 10 + VERY_GOOD; > - quality = rssi_qual; > - > /* Quality by TX errors */ > priv->wstats.discard.retries = priv->stats.tx_errors; > > @@ -863,28 +832,19 @@ static struct iw_statistics *lbs_get_wir > log.hdr.size = cpu_to_le16(sizeof(log)); > lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log); > > - tx_retries = le32_to_cpu(log.retry); > - > - if (tx_retries > 75) > - tx_qual = (90 - tx_retries) * POOR / 15; > - else if (tx_retries > 70) > - tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR; > - else if (tx_retries > 65) > - tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; > - else if (tx_retries > 50) > - tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / > - 15 + GOOD; > - else > - tx_qual = (50 - tx_retries) * > - (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; > - quality = min(quality, tx_qual); > - > priv->wstats.discard.code = le32_to_cpu(log.wepundecryptable); > - priv->wstats.discard.retries = tx_retries; > + priv->wstats.discard.retries = le32_to_cpu(log.retry); > priv->wstats.discard.misc = le32_to_cpu(log.ackfailure); > > /* Calculate quality */ > - priv->wstats.qual.qual = min_t(u8, quality, 100); > + /* see http://www.ces.clemson.edu/linux/signal_quality.shtml */ > + snr = priv->wstats.qual.level - priv->wstats.qual.noise; > + if (snr <= 0) > + priv->wstats.qual.qual = 0; > + else if (snr >= 40) > + priv->wstats.qual.qual = 100; > + else > + priv->wstats.qual.qual = 5*snr/2; > priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; > stats_valid = 1; > > Index: wireless-testing/drivers/net/wireless/libertas/defs.h > =================================================================== > --- wireless-testing.orig/drivers/net/wireless/libertas/defs.h > 2008-03-18 13:42:42.000000000 +0100 > +++ wireless-testing/drivers/net/wireless/libertas/defs.h > 2008-03-18 13:42:55.000000000 +0100 > @@ -208,12 +208,9 @@ static inline void lbs_deb_hex(unsigned > #define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME > > /** RSSI-related defines */ > -/* RSSI constants are used to implement 802.11 RSSI threshold > -* indication. if the Rx packet signal got too weak for 5 > consecutive > -* times, miniport driver (driver) will report this event to > wrapper > -*/ > > -#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96) > +/* This is the average noise level */ > +#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-86) > > /** RTS/FRAG related defines */ > #define MRVDRV_RTS_MIN_VALUE 0 -- 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