#define TBTT_TIMER                     0x1124
 
 /*
- * INT_TIMER_CFG:
+ * INT_TIMER_CFG: timer configuration
+ * PRE_TBTT_TIMER: leadtime to tbtt for pretbtt interrupt in units of 1/16 TU
+ * GP_TIMER: period of general purpose timer in units of 1/16 TU
  */
 #define INT_TIMER_CFG                  0x1128
+#define INT_TIMER_CFG_PRE_TBTT_TIMER   FIELD32(0x0000ffff)
+#define INT_TIMER_CFG_GP_TIMER         FIELD32(0xffff0000)
 
 /*
  * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
  */
 #define INT_TIMER_EN                   0x112c
+#define INT_TIMER_EN_PRE_TBTT_TIMER    FIELD32(0x00000001)
+#define INT_TIMER_EN_GP_TIMER          FIELD32(0x00000002)
 
 /*
  * CH_IDLE_STA: channel idle time
 
                rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE,
                                   (conf->sync == TSF_SYNC_BEACON));
                rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+               /*
+                * Enable pre tbtt interrupt for beaconing modes
+                */
+               rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®);
+               rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER,
+                                  (conf->sync == TSF_SYNC_BEACON));
+               rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+
        }
 
        if (flags & CONFIG_UPDATE_MAC) {
        rt2800_register_read(rt2x00dev, TX_STA_CNT1, ®);
        rt2800_register_read(rt2x00dev, TX_STA_CNT2, ®);
 
+       /*
+        * Setup leadtime for pre tbtt interrupt to 6ms
+        */
+       rt2800_register_read(rt2x00dev, INT_TIMER_CFG, ®);
+       rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4);
+       rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2800_init_registers);
 
        u32 reg = rt2x00dev->irqvalue[0];
 
        /*
-        * 1 - Rx ring done interrupt.
+        * 1 - Pre TBTT interrupt.
+        */
+       if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
+               rt2x00lib_pretbtt(rt2x00dev);
+
+       /*
+        * 2 - Beacondone interrupt.
+        */
+       if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT))
+               rt2x00lib_beacondone(rt2x00dev);
+
+       /*
+        * 3 - Rx ring done interrupt.
         */
        if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE))
                rt2x00pci_rxdone(rt2x00dev);
 
+       /*
+        * 4 - Tx done interrupt.
+        */
        if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
                rt2800pci_txdone(rt2x00dev);
 
        /*
-        * Current beacon was sent out, fetch the next one
+        * 5 - Auto wakeup interrupt.
         */
-       if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT))
-               rt2x00lib_beacondone(rt2x00dev);
-
        if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
                rt2800pci_wakeup(rt2x00dev);
 
        __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
        __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
 
+       /*
+        * This device has a pre tbtt interrupt and thus fetches
+        * a new beacon directly prior to transmission.
+        */
+       __set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags);
+
        /*
         * This device requires firmware.
         */
 
        CONFIG_SUPPORT_HW_CRYPTO,
        DRIVER_SUPPORT_CONTROL_FILTERS,
        DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
+       DRIVER_SUPPORT_PRE_TBTT_INTERRUPT,
        DRIVER_SUPPORT_LINK_TUNING,
        DRIVER_SUPPORT_WATCHDOG,
 
  * Interrupt context handlers.
  */
 void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_txdone(struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc);
 void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 
        }
 }
 
-static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
-                                     struct ieee80211_vif *vif)
+static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
+                                       struct ieee80211_vif *vif)
 {
        struct rt2x00_dev *rt2x00dev = data;
 
        ieee80211_iterate_active_interfaces(rt2x00dev->hw,
                                            rt2x00lib_bc_buffer_iter,
                                            rt2x00dev);
+       /*
+        * Devices with pre tbtt interrupt don't need to update the beacon
+        * here as they will fetch the next beacon directly prior to
+        * transmission.
+        */
+       if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags))
+               return;
 
        /* fetch next beacon */
        ieee80211_iterate_active_interfaces(rt2x00dev->hw,
-                                           rt2x00lib_beacondone_iter,
+                                           rt2x00lib_beaconupdate_iter,
                                            rt2x00dev);
-
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
 
+void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
+{
+       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               return;
+
+       /* fetch next beacon */
+       ieee80211_iterate_active_interfaces(rt2x00dev->hw,
+                                           rt2x00lib_beaconupdate_iter,
+                                           rt2x00dev);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
+
 void rt2x00lib_txdone(struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc)
 {