* Interval defines
  */
 #define WATCHDOG_INTERVAL      round_jiffies_relative(HZ)
-#define LINK_TUNE_INTERVAL     round_jiffies_relative(HZ)
-#define AGC_INTERVAL           round_jiffies_relative(4 * HZ)
-#define VCO_INTERVAL           round_jiffies_relative(10 * HZ) /* 10 sec */
+#define LINK_TUNE_SECONDS      1
+#define LINK_TUNE_INTERVAL     round_jiffies_relative(LINK_TUNE_SECONDS * HZ)
+#define AGC_SECONDS            4
+#define VCO_SECONDS            10
 
 /*
  * rt2x00_rate: Per rate device information
  */
 void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev);
 
-/**
- * rt2x00link_start_agc - Start periodic gain calibration
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- */
-void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev);
-
-/**
- * rt2x00link_start_vcocal - Start periodic VCO calibration
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- */
-void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev);
-
-/**
- * rt2x00link_stop_agc - Stop periodic gain calibration
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- */
-void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev);
-
-/**
- * rt2x00link_stop_vcocal - Stop periodic VCO calibration
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- */
-void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev);
-
 /**
  * rt2x00link_register - Initialize link tuning & watchdog functionality
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
 
        struct link *link = &rt2x00dev->link;
 
        /*
-        * Link tuning should only be performed when
-        * an active sta interface exists. AP interfaces
-        * don't need link tuning and monitor mode interfaces
-        * should never have to work with link tuners.
+        * Single monitor mode interfaces should never have
+        * work with link tuners.
         */
-       if (!rt2x00dev->intf_sta_count)
+       if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)
                return;
 
-       /**
+       /*
         * While scanning, link tuning is disabled. By default
         * the most sensitive settings will be used to make sure
         * that all beacons and probe responses will be received
        qual->tx_failed = 0;
 }
 
-static void rt2x00link_tuner(struct work_struct *work)
+static void rt2x00link_tuner_sta(struct rt2x00_dev *rt2x00dev, struct link *link)
 {
-       struct rt2x00_dev *rt2x00dev =
-           container_of(work, struct rt2x00_dev, link.work.work);
-       struct link *link = &rt2x00dev->link;
        struct link_qual *qual = &rt2x00dev->link.qual;
 
-       /*
-        * When the radio is shutting down we should
-        * immediately cease all link tuning.
-        */
-       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
-           test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
-               return;
-
        /*
         * Update statistics.
         */
         */
        if (rt2x00lib_antenna_diversity(rt2x00dev))
                rt2x00link_reset_qual(rt2x00dev);
+}
+
+static void rt2x00link_tuner(struct work_struct *work)
+{
+       struct rt2x00_dev *rt2x00dev =
+           container_of(work, struct rt2x00_dev, link.work.work);
+       struct link *link = &rt2x00dev->link;
+
+       /*
+        * When the radio is shutting down we should
+        * immediately cease all link tuning.
+        */
+       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
+           test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
+               return;
+
+       if (rt2x00dev->intf_sta_count)
+               rt2x00link_tuner_sta(rt2x00dev, link);
+
+       if (rt2x00dev->ops->lib->gain_calibration &&
+           (link->count % (AGC_SECONDS / LINK_TUNE_SECONDS)) == 0)
+               rt2x00dev->ops->lib->gain_calibration(rt2x00dev);
+
+       if (rt2x00dev->ops->lib->vco_calibration &&
+           rt2x00_has_cap_vco_recalibration(rt2x00dev) &&
+           (link->count % (VCO_SECONDS / LINK_TUNE_SECONDS)) == 0)
+               rt2x00dev->ops->lib->vco_calibration(rt2x00dev);
 
        /*
         * Increase tuner counter, and reschedule the next link tuner run.
                                             WATCHDOG_INTERVAL);
 }
 
-void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev)
-{
-       struct link *link = &rt2x00dev->link;
-
-       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
-           rt2x00dev->ops->lib->gain_calibration)
-               ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                            &link->agc_work,
-                                            AGC_INTERVAL);
-}
-
-void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev)
-{
-       struct link *link = &rt2x00dev->link;
-
-       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
-           rt2x00dev->ops->lib->vco_calibration)
-               ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                            &link->vco_work,
-                                            VCO_INTERVAL);
-}
-
-void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev)
-{
-       cancel_delayed_work_sync(&rt2x00dev->link.agc_work);
-}
-
-void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev)
-{
-       cancel_delayed_work_sync(&rt2x00dev->link.vco_work);
-}
-
-static void rt2x00link_agc(struct work_struct *work)
-{
-       struct rt2x00_dev *rt2x00dev =
-           container_of(work, struct rt2x00_dev, link.agc_work.work);
-       struct link *link = &rt2x00dev->link;
-
-       /*
-        * When the radio is shutting down we should
-        * immediately cease the watchdog monitoring.
-        */
-       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-               return;
-
-       rt2x00dev->ops->lib->gain_calibration(rt2x00dev);
-
-       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
-               ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                            &link->agc_work,
-                                            AGC_INTERVAL);
-}
-
-static void rt2x00link_vcocal(struct work_struct *work)
-{
-       struct rt2x00_dev *rt2x00dev =
-           container_of(work, struct rt2x00_dev, link.vco_work.work);
-       struct link *link = &rt2x00dev->link;
-
-       /*
-        * When the radio is shutting down we should
-        * immediately cease the VCO calibration.
-        */
-       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-               return;
-
-       rt2x00dev->ops->lib->vco_calibration(rt2x00dev);
-
-       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
-               ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                            &link->vco_work,
-                                            VCO_INTERVAL);
-}
-
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
 {
-       INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc);
-       if (rt2x00_has_cap_vco_recalibration(rt2x00dev))
-               INIT_DELAYED_WORK(&rt2x00dev->link.vco_work, rt2x00link_vcocal);
        INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
        INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
 }