qual->false_cca = bbp;
 }
 
+static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+       rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
+       rt2x00dev->link.vgc_level = vgc_level;
+       rt2x00dev->link.vgc_level_reg = vgc_level;
+}
+
 static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
 {
-       rt2400pci_bbp_write(rt2x00dev, 13, 0x08);
-       rt2x00dev->link.vgc_level = 0x08;
+       rt2400pci_set_vgc(rt2x00dev, 0x08);
 }
 
 static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
 {
-       u8 reg;
+       struct link *link = &rt2x00dev->link;
 
        /*
         * The link tuner should not run longer then 60 seconds,
         * and should run once every 2 seconds.
         */
-       if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1))
+       if (link->count > 60 || !(link->count & 1))
                return;
 
        /*
         * Base r13 link tuning on the false cca count.
         */
-       rt2400pci_bbp_read(rt2x00dev, 13, ®);
-
-       if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
-               rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
-               rt2x00dev->link.vgc_level = reg;
-       } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
-               rt2400pci_bbp_write(rt2x00dev, 13, --reg);
-               rt2x00dev->link.vgc_level = reg;
-       }
+       if ((link->qual.false_cca > 512) && (link->vgc_level < 0x20))
+               rt2400pci_set_vgc(rt2x00dev, ++link->vgc_level);
+       else if ((link->qual.false_cca < 100) && (link->vgc_level > 0x08))
+               rt2400pci_set_vgc(rt2x00dev, --link->vgc_level);
 }
 
 /*
 
        qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
 }
 
+static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+       if (rt2x00dev->link.vgc_level_reg != vgc_level) {
+               rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
+               rt2x00dev->link.vgc_level_reg = vgc_level;
+       }
+}
+
 static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
 {
-       rt2500pci_bbp_write(rt2x00dev, 17, 0x48);
-       rt2x00dev->link.vgc_level = 0x48;
+       rt2500pci_set_vgc(rt2x00dev, 0x48);
 }
 
 static void rt2500pci_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);
 
        /*
         * To prevent collisions with MAC ASIC on chipsets
         * seconds while being associated.
         */
        if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
-           rt2x00dev->intf_associated &&
-           rt2x00dev->link.count > 20)
+           rt2x00dev->intf_associated && link->count > 20)
                return;
 
-       rt2500pci_bbp_read(rt2x00dev, 17, &r17);
-
        /*
         * Chipset versions C and lower should directly continue
         * to the dynamic CCA tuning. Chipset version D and higher
         * then corrupt the R17 tuning. To remidy this the tuning should
         * be stopped (While making sure the R17 value will not exceed limits)
         */
-       if (rssi < -80 && rt2x00dev->link.count > 20) {
-               if (r17 >= 0x41) {
-                       r17 = rt2x00dev->link.vgc_level;
-                       rt2500pci_bbp_write(rt2x00dev, 17, r17);
-               }
+       if (rssi < -80 && link->count > 20) {
+               if (link->vgc_level_reg >= 0x41)
+                       rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
                return;
        }
 
         * Special big-R17 for short distance
         */
        if (rssi >= -58) {
-               if (r17 != 0x50)
-                       rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
+               rt2500pci_set_vgc(rt2x00dev, 0x50);
                return;
        }
 
         * Special mid-R17 for middle distance
         */
        if (rssi >= -74) {
-               if (r17 != 0x41)
-                       rt2500pci_bbp_write(rt2x00dev, 17, 0x41);
+               rt2500pci_set_vgc(rt2x00dev, 0x41);
                return;
        }
 
         * Leave short or middle distance condition, restore r17
         * to the dynamic tuning range.
         */
-       if (r17 >= 0x41) {
-               rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level);
+       if (link->vgc_level_reg >= 0x41) {
+               rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
                return;
        }
 
         * R17 is inside the dynamic tuning range,
         * start tuning the link based on the false cca counter.
         */
-       if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
-               rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
-               rt2x00dev->link.vgc_level = r17;
-       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
-               rt2500pci_bbp_write(rt2x00dev, 17, --r17);
-               rt2x00dev->link.vgc_level = r17;
+       if (link->qual.false_cca > 512 && link->vgc_level_reg < 0x40) {
+               rt2500pci_set_vgc(rt2x00dev, ++link->vgc_level_reg);
+               link->vgc_level = link->vgc_level_reg;
+       } else if (link->qual.false_cca < 100 && link->vgc_level_reg > 0x32) {
+               rt2500pci_set_vgc(rt2x00dev, --link->vgc_level_reg);
+               link->vgc_level = link->vgc_level_reg;
        }
 }
 
 
        struct link_ant ant;
 
        /*
-        * Active VGC level
+        * Active VGC level (for false cca tuning)
         */
-       int vgc_level;
+       u8 vgc_level;
+
+       /*
+        * VGC level as configured in register
+        */
+       u8 vgc_level_reg;
 
        /*
         * Work structure for scheduling periodic link tuning.
 
        qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
+static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+       if (rt2x00dev->link.vgc_level != vgc_level) {
+               rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
+               rt2x00dev->link.vgc_level = vgc_level;
+               rt2x00dev->link.vgc_level_reg = vgc_level;
+       }
+}
+
 static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
 {
-       rt61pci_bbp_write(rt2x00dev, 17, 0x20);
-       rt2x00dev->link.vgc_level = 0x20;
+       rt61pci_set_vgc(rt2x00dev, 0x20);
 }
 
 static void rt61pci_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;
 
-       rt61pci_bbp_read(rt2x00dev, 17, &r17);
-
        /*
         * Determine r17 bounds.
         */
         * Special big-R17 for very short distance
         */
        if (rssi >= -35) {
-               if (r17 != 0x60)
-                       rt61pci_bbp_write(rt2x00dev, 17, 0x60);
+               rt61pci_set_vgc(rt2x00dev, 0x60);
                return;
        }
 
         * Special big-R17 for short distance
         */
        if (rssi >= -58) {
-               if (r17 != up_bound)
-                       rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+               rt61pci_set_vgc(rt2x00dev, up_bound);
                return;
        }
 
         * Special big-R17 for middle-short distance
         */
        if (rssi >= -66) {
-               low_bound += 0x10;
-               if (r17 != low_bound)
-                       rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+               rt61pci_set_vgc(rt2x00dev, low_bound + 0x10);
                return;
        }
 
         * Special mid-R17 for middle distance
         */
        if (rssi >= -74) {
-               low_bound += 0x08;
-               if (r17 != low_bound)
-                       rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+               rt61pci_set_vgc(rt2x00dev, low_bound + 0x08);
                return;
        }
 
        if (low_bound > up_bound)
                up_bound = low_bound;
 
-       if (r17 > up_bound) {
-               rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+       if (link->vgc_level > up_bound) {
+               rt61pci_set_vgc(rt2x00dev, up_bound);
                return;
        }
 
         * 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) {
-               if (++r17 > up_bound)
-                       r17 = up_bound;
-               rt61pci_bbp_write(rt2x00dev, 17, r17);
-       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
-               if (--r17 < low_bound)
-                       r17 = low_bound;
-               rt61pci_bbp_write(rt2x00dev, 17, r17);
-       }
+       if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
+               rt61pci_set_vgc(rt2x00dev, ++link->vgc_level);
+       else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
+               rt61pci_set_vgc(rt2x00dev, --link->vgc_level);
 }
 
 /*
 
        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.
         */
         * 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;
        }
 
         * 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;
        }
 
         * 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;
        }
 
         * 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;
        }
 
        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;
        }
 
         * 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));
 }
 
 /*