[patch] fix madwifi strength



As madwifi[-ng] users are painfully aware, the Atheros driver spits out
some whack figures for strength.  The driver maintainers have been
hesitant to fix the values.

You can find a lot of this discussion by Googling for madwifi, RSSI,
strength, and so on.

One good description of the problem was on this very list:

http://mail.gnome.org/archives/networkmanager-list/2005-February/msg00063.html

Basically, the driver reports a maximum quality of 92, but the quality
itself can never reach this.  Thus taking the quality as a ratio xx/92
is misleading.  A foot from the AP returns numbers like 45/92.
Obviously way off.  The above email points out that a more accurate
maximum value is 60.

Thus, attached are two solutions.  Unfortunately, both put in a
madwifi-specific hack.  But the actual code is simple.

The "alt" version of the patch follows the above email and, for madwifi
only, replaces the maximum quality with "60".

The non-alt version of the patch simply uses the alternative
signal-based calculation already in place.

The former is theoretically more accurate, but it has the downside that
if the driver is ever fixed or changed, we are hardcoding a possible
wrong maximum.

The latter does not have this problem, but may be less accurate.

In practice, I see nearly identical values from both patches (which is a
nice vindication of both approaches).  So I would go with the latter,
which is simpler, and won't break if madwifi changes.

I don't know if Dan is willing to take a driver-specific hack like this.
I know he aims for the utopia of drivers not sucking wolf teat.  I would
be happy to commit this if not.  Otherwise, I post it here for personal
enjoyment.

	Robert Love


? src/.nm-device-802-11-wireless.c.swp
Index: src/nm-device-802-11-wireless.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/nm-device-802-11-wireless.c,v
retrieving revision 1.25
diff -u -r1.25 nm-device-802-11-wireless.c
--- src/nm-device-802-11-wireless.c	24 Jan 2006 00:46:52 -0000	1.25
+++ src/nm-device-802-11-wireless.c	24 Jan 2006 17:48:03 -0000
@@ -121,7 +121,8 @@
                                       guint8 **out_res_buf,
                                       guint32 *data_len);
 
-static int	wireless_qual_to_percent (const struct iw_quality *qual,
+static int	wireless_qual_to_percent (NMDevice *dev,
+								 const struct iw_quality *qual,
                                          const struct iw_quality *max_qual,
                                          const struct iw_quality *avg_qual);
 
@@ -1017,7 +1018,8 @@
  *
  */
 static int
-wireless_qual_to_percent (const struct iw_quality *qual,
+wireless_qual_to_percent (NMDevice *dev,
+					 const struct iw_quality *qual,
                           const struct iw_quality *max_qual,
                           const struct iw_quality *avg_qual)
 {
@@ -1046,7 +1048,12 @@
 	 * are free to use whatever they want to calculate "Link Quality".
 	 */
 	if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
-		percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
+	{
+		if (!strcmp (nm_device_get_driver (dev), "ath_pci"))
+			percent = (int) (100 * ((double) qual->qual / 62.0f));
+		else
+			percent = (int) (100 * ((double) qual->qual / (double) max_qual->qual));
+	}
 
 	/* If the driver doesn't specify a complete and valid quality, we have two options:
 	 *
@@ -1172,7 +1179,7 @@
 #endif
 		if (iw_get_stats (nm_dev_sock_get_fd (sk), iface, &stats, &range, has_range) == 0)
 		{
-			percent = wireless_qual_to_percent (&stats.qual, (const iwqual *)(&self->priv->max_qual),
+			percent = wireless_qual_to_percent (NM_DEVICE (self), &stats.qual, (const iwqual *)(&self->priv->max_qual),
 					(const iwqual *)(&self->priv->avg_qual));
 		}
 		nm_dev_sock_close (sk);
@@ -3193,7 +3200,8 @@
 			     nm_ap_set_freq (ap, iw_freq2float(&(iwe->u.freq)));
 				break;
 			case IWEVQUAL:
-				nm_ap_set_strength (ap, wireless_qual_to_percent (&(iwe->u.qual),
+				nm_ap_set_strength (ap, wireless_qual_to_percent (&dev->parent,
+									&(iwe->u.qual),
 									(const iwqual *)(&dev->priv->max_qual),
 									(const iwqual *)(&dev->priv->avg_qual)));
 				break;
? src/.nm-device-802-11-wireless.c.swp
Index: src/nm-device-802-11-wireless.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/nm-device-802-11-wireless.c,v
retrieving revision 1.25
diff -u -r1.25 nm-device-802-11-wireless.c
--- src/nm-device-802-11-wireless.c	24 Jan 2006 00:46:52 -0000	1.25
+++ src/nm-device-802-11-wireless.c	24 Jan 2006 17:47:21 -0000
@@ -121,7 +121,8 @@
                                       guint8 **out_res_buf,
                                       guint32 *data_len);
 
-static int	wireless_qual_to_percent (const struct iw_quality *qual,
+static int	wireless_qual_to_percent (NMDevice *dev,
+								 const struct iw_quality *qual,
                                          const struct iw_quality *max_qual,
                                          const struct iw_quality *avg_qual);
 
@@ -1017,7 +1018,8 @@
  *
  */
 static int
-wireless_qual_to_percent (const struct iw_quality *qual,
+wireless_qual_to_percent (NMDevice *dev,
+					 const struct iw_quality *qual,
                           const struct iw_quality *max_qual,
                           const struct iw_quality *avg_qual)
 {
@@ -1112,7 +1114,7 @@
 	}
 
 	/* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */
-	if ((percent < 1) && (level_percent >= 0))
+	if ((percent < 1 || !strcmp (nm_device_get_driver (dev), "ath_pci")) && (level_percent >= 0))
 		percent = level_percent;
 
 #ifdef IW_QUAL_DEBUG
@@ -1172,7 +1174,7 @@
 #endif
 		if (iw_get_stats (nm_dev_sock_get_fd (sk), iface, &stats, &range, has_range) == 0)
 		{
-			percent = wireless_qual_to_percent (&stats.qual, (const iwqual *)(&self->priv->max_qual),
+			percent = wireless_qual_to_percent (NM_DEVICE (self), &stats.qual, (const iwqual *)(&self->priv->max_qual),
 					(const iwqual *)(&self->priv->avg_qual));
 		}
 		nm_dev_sock_close (sk);
@@ -3193,7 +3195,8 @@
 			     nm_ap_set_freq (ap, iw_freq2float(&(iwe->u.freq)));
 				break;
 			case IWEVQUAL:
-				nm_ap_set_strength (ap, wireless_qual_to_percent (&(iwe->u.qual),
+				nm_ap_set_strength (ap, wireless_qual_to_percent (&dev->parent,
+									&(iwe->u.qual),
 									(const iwqual *)(&dev->priv->max_qual),
 									(const iwqual *)(&dev->priv->avg_qual)));
 				break;


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