rt2x00: Reduce calls to bbp_read()

The link_tuner() function will always call bbp_read()
at the start of the function. Because this is an
indirect register access has some costs attached
to it (especially for USB hardware).

We already store the value read from the register
into the vgc_level value inside the link structure.
Instead of reading from the register we can read that
field directly and base the tuner on that value.

This reduces the time the registers are locked with
the csr_mutex and speeds up the link_tuner processing.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ae3b31d..b544314 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -924,21 +924,27 @@
 	qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+	if (rt2x00dev->link.vgc_level != vgc_level) {
+		rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+		rt2x00dev->link.vgc_level = vgc_level;
+		rt2x00dev->link.vgc_level_reg = vgc_level;
+	}
+}
+
 static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
 {
-	rt73usb_bbp_write(rt2x00dev, 17, 0x20);
-	rt2x00dev->link.vgc_level = 0x20;
+	rt73usb_set_vgc(rt2x00dev, 0x20);
 }
 
 static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
 {
-	int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
-	u8 r17;
+	struct link *link = &rt2x00dev->link;
+	int rssi = rt2x00_get_link_rssi(link);
 	u8 up_bound;
 	u8 low_bound;
 
-	rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
 	/*
 	 * Determine r17 bounds.
 	 */
@@ -979,8 +985,7 @@
 	 * Special big-R17 for very short distance
 	 */
 	if (rssi > -35) {
-		if (r17 != 0x60)
-			rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+		rt73usb_set_vgc(rt2x00dev, 0x60);
 		return;
 	}
 
@@ -988,8 +993,7 @@
 	 * Special big-R17 for short distance
 	 */
 	if (rssi >= -58) {
-		if (r17 != up_bound)
-			rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+		rt73usb_set_vgc(rt2x00dev, up_bound);
 		return;
 	}
 
@@ -997,9 +1001,7 @@
 	 * Special big-R17 for middle-short distance
 	 */
 	if (rssi >= -66) {
-		low_bound += 0x10;
-		if (r17 != low_bound)
-			rt73usb_bbp_write(rt2x00dev, 17, low_bound);
+		rt73usb_set_vgc(rt2x00dev, low_bound + 0x10);
 		return;
 	}
 
@@ -1007,8 +1009,7 @@
 	 * Special mid-R17 for middle distance
 	 */
 	if (rssi >= -74) {
-		if (r17 != (low_bound + 0x10))
-			rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
+		rt73usb_set_vgc(rt2x00dev, low_bound + 0x08);
 		return;
 	}
 
@@ -1020,8 +1021,8 @@
 	if (low_bound > up_bound)
 		up_bound = low_bound;
 
-	if (r17 > up_bound) {
-		rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+	if (link->vgc_level > up_bound) {
+		rt73usb_set_vgc(rt2x00dev, up_bound);
 		return;
 	}
 
@@ -1031,17 +1032,12 @@
 	 * r17 does not yet exceed upper limit, continue and base
 	 * the r17 tuning on the false CCA count.
 	 */
-	if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
-		r17 += 4;
-		if (r17 > up_bound)
-			r17 = up_bound;
-		rt73usb_bbp_write(rt2x00dev, 17, r17);
-	} else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
-		r17 -= 4;
-		if (r17 < low_bound)
-			r17 = low_bound;
-		rt73usb_bbp_write(rt2x00dev, 17, r17);
-	}
+	if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
+		rt73usb_set_vgc(rt2x00dev,
+				min_t(u8, link->vgc_level + 4, up_bound));
+	else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
+		rt73usb_set_vgc(rt2x00dev,
+				max_t(u8, link->vgc_level - 4, low_bound));
 }
 
 /*