/*
  * Link tuning
  */
-static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
 {
        u32 reg;
        u8 bbp;
         * Update FCS error count from register.
         */
        rt2x00pci_register_read(rt2x00dev, CNT0, ®);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2400pci_bbp_read(rt2x00dev, 39, &bbp);
-       rt2x00dev->link.false_cca = bbp;
+       qual->false_cca = bbp;
 }
 
 static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
         */
        rt2400pci_bbp_read(rt2x00dev, 13, ®);
 
-       if (rt2x00dev->link.false_cca > 512 && reg < 0x20) {
+       if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
                rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
                rt2x00dev->link.vgc_level = reg;
-       } else if (rt2x00dev->link.false_cca < 100 && reg > 0x08) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
                rt2400pci_bbp_write(rt2x00dev, 13, --reg);
                rt2x00dev->link.vgc_level = reg;
        }
 
 /*
  * Link tuning
  */
-static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
 {
        u32 reg;
 
         * Update FCS error count from register.
         */
        rt2x00pci_register_read(rt2x00dev, CNT0, ®);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2x00pci_register_read(rt2x00dev, CNT3, ®);
-       rt2x00dev->link.false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
+       qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
 }
 
 static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
         * R17 is inside the dynamic tuning range,
         * start tuning the link based on the false cca counter.
         */
-       if (rt2x00dev->link.false_cca > 512 && r17 < 0x40) {
+       if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
                rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
                rt2x00dev->link.vgc_level = r17;
-       } else if (rt2x00dev->link.false_cca < 100 && r17 > 0x32) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
                rt2500pci_bbp_write(rt2x00dev, 17, --r17);
                rt2x00dev->link.vgc_level = r17;
        }
 
 /*
  * Link tuning
  */
-static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
 {
        u16 reg;
 
         * Update FCS error count from register.
         */
        rt2500usb_register_read(rt2x00dev, STA_CSR0, ®);
-       rt2x00dev->link.rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2500usb_register_read(rt2x00dev, STA_CSR3, ®);
-       rt2x00dev->link.false_cca =
-           rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
+       qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
 }
 
 static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
        if (r17 > up_bound) {
                rt2500usb_bbp_write(rt2x00dev, 17, up_bound);
                rt2x00dev->link.vgc_level = up_bound;
-       } else if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+       } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
                rt2500usb_bbp_write(rt2x00dev, 17, ++r17);
                rt2x00dev->link.vgc_level = r17;
-       } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
                rt2500usb_bbp_write(rt2x00dev, 17, --r17);
                rt2x00dev->link.vgc_level = r17;
        }
 
 };
 
 /*
- * To optimize the quality of the link we need to store
- * the quality of received frames and periodically
- * optimize the link.
+ * Quality statistics about the currently active link.
  */
-struct link {
-       /*
-        * Link tuner counter
-        * The number of times the link has been tuned
-        * since the radio has been switched on.
-        */
-       u32 count;
-
+struct link_qual {
        /*
         * Statistics required for Link tuning.
         * For the average RSSI value we use the "Walking average" approach.
         * the new values correctly allowing a effective link tuning.
         */
        int avg_rssi;
-       int vgc_level;
        int false_cca;
 
        /*
 #define WEIGHT_RSSI    20
 #define WEIGHT_RX      40
 #define WEIGHT_TX      40
+};
+
+/*
+ * To optimize the quality of the link we need to store
+ * the quality of received frames and periodically
+ * optimize the link.
+ */
+struct link {
+       /*
+        * Link tuner counter
+        * The number of times the link has been tuned
+        * since the radio has been switched on.
+        */
+       u32 count;
+
+       /*
+        * Quality measurement values.
+        */
+       struct link_qual qual;
+
+       /*
+        * Active VGC level
+        */
+       int vgc_level;
 
        /*
         * Work structure for scheduling periodic link tuning.
 
 /*
  * Clear all counters inside the link structure.
- * This can be easiest achieved by memsetting everything
- * except for the work structure at the end.
  */
 static inline void rt2x00_clear_link(struct link *link)
 {
-       memset(link, 0x00, sizeof(*link) - sizeof(link->work));
-       link->rx_percentage = 50;
-       link->tx_percentage = 50;
+       link->count = 0;
+       memset(&link->qual, 0, sizeof(link->qual));
+       link->qual.rx_percentage = 50;
+       link->qual.tx_percentage = 50;
 }
 
+
 /*
  * Update the rssi using the walking average approach.
  */
 static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
 {
-       if (!link->avg_rssi)
-               link->avg_rssi = rssi;
+       if (!link->qual.avg_rssi)
+               link->qual.avg_rssi = rssi;
        else
-               link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8;
+               link->qual.avg_rssi = ((link->qual.avg_rssi * 7) + rssi) / 8;
 }
 
 /*
  */
 static inline int rt2x00_get_link_rssi(struct link *link)
 {
-       return (link->avg_rssi && link->rx_success) ? link->avg_rssi : -128;
+       if (link->qual.avg_rssi && link->qual.rx_success)
+               return link->qual.avg_rssi;
+       return -128;
 }
 
 /*
        int (*set_device_state) (struct rt2x00_dev *rt2x00dev,
                                 enum dev_state state);
        int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
-       void (*link_stats) (struct rt2x00_dev *rt2x00dev);
+       void (*link_stats) (struct rt2x00_dev *rt2x00dev,
+                           struct link_qual *qual);
        void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
        void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
 
 
                rt2x00lib_start_link_tuner(rt2x00dev);
 }
 
-static void rt2x00lib_precalculate_link_signal(struct link *link)
+static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
 {
-       if (link->rx_failed || link->rx_success)
-               link->rx_percentage =
-                   (link->rx_success * 100) /
-                   (link->rx_failed + link->rx_success);
+       if (qual->rx_failed || qual->rx_success)
+               qual->rx_percentage =
+                   (qual->rx_success * 100) /
+                   (qual->rx_failed + qual->rx_success);
        else
-               link->rx_percentage = 50;
+               qual->rx_percentage = 50;
 
-       if (link->tx_failed || link->tx_success)
-               link->tx_percentage =
-                   (link->tx_success * 100) /
-                   (link->tx_failed + link->tx_success);
+       if (qual->tx_failed || qual->tx_success)
+               qual->tx_percentage =
+                   (qual->tx_success * 100) /
+                   (qual->tx_failed + qual->tx_success);
        else
-               link->tx_percentage = 50;
+               qual->tx_percentage = 50;
 
-       link->rx_success = 0;
-       link->rx_failed = 0;
-       link->tx_success = 0;
-       link->tx_failed = 0;
+       qual->rx_success = 0;
+       qual->rx_failed = 0;
+       qual->tx_success = 0;
+       qual->tx_failed = 0;
 }
 
 static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
         * defines to calculate the current link signal.
         */
        signal = ((WEIGHT_RSSI * rssi_percentage) +
-                 (WEIGHT_TX * rt2x00dev->link.tx_percentage) +
-                 (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100;
+                 (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) +
+                 (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100;
 
        return (signal > 100) ? 100 : signal;
 }
        /*
         * Update statistics.
         */
-       rt2x00dev->ops->lib->link_stats(rt2x00dev);
+       rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
 
        rt2x00dev->low_level_stats.dot11FCSErrorCount +=
-           rt2x00dev->link.rx_failed;
+           rt2x00dev->link.qual.rx_failed;
 
        /*
         * Only perform the link tuning when Link tuning
         * Precalculate a portion of the link signal which is
         * in based on the tx/rx success/failure counters.
         */
-       rt2x00lib_precalculate_link_signal(&rt2x00dev->link);
+       rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
 
        /*
         * Increase tuner counter, and reschedule the next link tuner run.
        tx_status->ack_signal = 0;
        tx_status->excessive_retries = (status == TX_FAIL_RETRY);
        tx_status->retry_count = retry;
-       rt2x00dev->link.tx_success += success;
-       rt2x00dev->link.tx_failed += retry + fail;
+       rt2x00dev->link.qual.tx_success += success;
+       rt2x00dev->link.qual.tx_failed += retry + fail;
 
        if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) {
                if (success)
        }
 
        rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
-       rt2x00dev->link.rx_success++;
+       rt2x00dev->link.qual.rx_success++;
        rx_status->rate = val;
        rx_status->signal =
            rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
 
 /*
  * Link tuning
  */
-static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
+                              struct link_qual *qual)
 {
        u32 reg;
 
         * Update FCS error count from register.
         */
        rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®);
-       rt2x00dev->link.false_cca =
-           rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
+       qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
 static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
         * r17 does not yet exceed upper limit, continue and base
         * the r17 tuning on the false CCA count.
         */
-       if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+       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.false_cca < 100 && r17 > low_bound) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
                if (--r17 < low_bound)
                        r17 = low_bound;
                rt61pci_bbp_write(rt2x00dev, 17, r17);
 
 /*
  * Link tuning
  */
-static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
+                              struct link_qual *qual)
 {
        u32 reg;
 
         * Update FCS error count from register.
         */
        rt73usb_register_read(rt2x00dev, STA_CSR0, ®);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt73usb_register_read(rt2x00dev, STA_CSR1, ®);
-       reg = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
-       rt2x00dev->link.false_cca =
-           rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
+       qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
 static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
         * r17 does not yet exceed upper limit, continue and base
         * the r17 tuning on the false CCA count.
         */
-       if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+       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.false_cca < 100 && r17 > low_bound) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
                r17 -= 4;
                if (r17 < low_bound)
                        r17 = low_bound;