rt2x00: remove get_tx_stats() mac80211 op
[safe/jmp/linux-2.6] / drivers / net / wireless / rt2x00 / rt73usb.c
index d1a63e0..3781eb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
-       Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+       Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
        <http://rt2x00.serialmonkey.com>
 
        This program is free software; you can redistribute it and/or modify
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 /*
  * Register access.
  * All access to the CSR registers will go through the methods
- * rt73usb_register_read and rt73usb_register_write.
+ * rt2x00usb_register_read and rt2x00usb_register_write.
  * BBP and RF register require indirect register access,
  * and use the CSR registers BBPCSR and RFCSR to achieve this.
  * These indirect registers work with busy bits,
@@ -57,78 +57,10 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
  * and we will print an error.
  * The _lock versions must be used if you already hold the csr_mutex
  */
-static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
-                                        const unsigned int offset, u32 *value)
-{
-       __le32 reg;
-       rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
-                                     USB_VENDOR_REQUEST_IN, offset,
-                                     &reg, sizeof(u32), REGISTER_TIMEOUT);
-       *value = le32_to_cpu(reg);
-}
-
-static inline void rt73usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
-                                             const unsigned int offset, u32 *value)
-{
-       __le32 reg;
-       rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
-                                      USB_VENDOR_REQUEST_IN, offset,
-                                      &reg, sizeof(u32), REGISTER_TIMEOUT);
-       *value = le32_to_cpu(reg);
-}
-
-static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev,
-                                             const unsigned int offset,
-                                             void *value, const u32 length)
-{
-       rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
-                                     USB_VENDOR_REQUEST_IN, offset,
-                                     value, length,
-                                     REGISTER_TIMEOUT32(length));
-}
-
-static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev,
-                                         const unsigned int offset, u32 value)
-{
-       __le32 reg = cpu_to_le32(value);
-       rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
-                                     USB_VENDOR_REQUEST_OUT, offset,
-                                     &reg, sizeof(u32), REGISTER_TIMEOUT);
-}
-
-static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
-                                              const unsigned int offset, u32 value)
-{
-       __le32 reg = cpu_to_le32(value);
-       rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
-                                      USB_VENDOR_REQUEST_OUT, offset,
-                                     &reg, sizeof(u32), REGISTER_TIMEOUT);
-}
-
-static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
-                                              const unsigned int offset,
-                                              void *value, const u32 length)
-{
-       rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
-                                     USB_VENDOR_REQUEST_OUT, offset,
-                                     value, length,
-                                     REGISTER_TIMEOUT32(length));
-}
-
-static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev)
-{
-       u32 reg;
-       unsigned int i;
-
-       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt73usb_register_read_lock(rt2x00dev, PHY_CSR3, &reg);
-               if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY))
-                       break;
-               udelay(REGISTER_BUSY_DELAY);
-       }
-
-       return reg;
-}
+#define WAIT_FOR_BBP(__dev, __reg) \
+       rt2x00usb_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg))
+#define WAIT_FOR_RF(__dev, __reg) \
+       rt2x00usb_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg))
 
 static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
                              const unsigned int word, const u8 value)
@@ -138,30 +70,20 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
        mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
-        * Wait until the BBP becomes ready.
+        * Wait until the BBP becomes available, afterwards we
+        * can safely write the new data into the register.
         */
-       reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
-               goto exit_fail;
-
-       /*
-        * Write the data into the BBP.
-        */
-       reg = 0;
-       rt2x00_set_field32(&reg, PHY_CSR3_VALUE, value);
-       rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
-       rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
-       rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
-
-       rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
-       mutex_unlock(&rt2x00dev->csr_mutex);
-
-       return;
+       if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, PHY_CSR3_VALUE, value);
+               rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
+               rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
+               rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
+
+               rt2x00usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
+       }
 
-exit_fail:
        mutex_unlock(&rt2x00dev->csr_mutex);
-
-       ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
 }
 
 static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -172,79 +94,56 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
        mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
-        * Wait until the BBP becomes ready.
-        */
-       reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
-               goto exit_fail;
-
-       /*
-        * Write the request into the BBP.
+        * Wait until the BBP becomes available, afterwards we
+        * can safely write the read request into the register.
+        * After the data has been written, we wait until hardware
+        * returns the correct value, if at any time the register
+        * doesn't become available in time, reg will be 0xffffffff
+        * which means we return 0xff to the caller.
         */
-       reg = 0;
-       rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
-       rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
-       rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 1);
+       if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
+               rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
+               rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 1);
 
-       rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
+               rt2x00usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
 
-       /*
-        * Wait until the BBP becomes ready.
-        */
-       reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
-               goto exit_fail;
+               WAIT_FOR_BBP(rt2x00dev, &reg);
+       }
 
        *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
-       mutex_unlock(&rt2x00dev->csr_mutex);
-
-       return;
 
-exit_fail:
        mutex_unlock(&rt2x00dev->csr_mutex);
-
-       ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
-       *value = 0xff;
 }
 
 static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, const u32 value)
 {
        u32 reg;
-       unsigned int i;
-
-       if (!word)
-               return;
 
        mutex_lock(&rt2x00dev->csr_mutex);
 
-       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, &reg);
-               if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
-                       goto rf_write;
-               udelay(REGISTER_BUSY_DELAY);
-       }
-
-       mutex_unlock(&rt2x00dev->csr_mutex);
-       ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
-       return;
-
-rf_write:
-       reg = 0;
-       rt2x00_set_field32(&reg, PHY_CSR4_VALUE, value);
-
        /*
-        * RF5225 and RF2527 contain 21 bits per RF register value,
-        * all others contain 20 bits.
+        * Wait until the RF becomes available, afterwards we
+        * can safely write the new data into the register.
         */
-       rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS,
-                          20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-                                rt2x00_rf(&rt2x00dev->chip, RF2527)));
-       rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
-       rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
-
-       rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
-       rt2x00_rf_write(rt2x00dev, word, value);
+       if (WAIT_FOR_RF(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, PHY_CSR4_VALUE, value);
+               /*
+                * RF5225 and RF2527 contain 21 bits per RF register value,
+                * all others contain 20 bits.
+                */
+               rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS,
+                                  20 + (rt2x00_rf(rt2x00dev, RF5225) ||
+                                        rt2x00_rf(rt2x00dev, RF2527)));
+               rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
+               rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
+
+               rt2x00usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
+               rt2x00_rf_write(rt2x00dev, word, value);
+       }
 
        mutex_unlock(&rt2x00dev->csr_mutex);
 }
@@ -253,8 +152,8 @@ rf_write:
 static const struct rt2x00debug rt73usb_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt73usb_register_read,
-               .write          = rt73usb_register_write,
+               .read           = rt2x00usb_register_read,
+               .write          = rt2x00usb_register_write,
                .flags          = RT2X00DEBUGFS_OFFSET,
                .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u32),
@@ -284,6 +183,14 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
+static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+       return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
+}
+
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
                                   enum led_brightness brightness)
@@ -333,10 +240,10 @@ static int rt73usb_blink_set(struct led_classdev *led_cdev,
            container_of(led_cdev, struct rt2x00_led, led_dev);
        u32 reg;
 
-       rt73usb_register_read(led->rt2x00dev, MAC_CSR14, &reg);
+       rt2x00usb_register_read(led->rt2x00dev, MAC_CSR14, &reg);
        rt2x00_set_field32(&reg, MAC_CSR14_ON_PERIOD, *delay_on);
        rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, *delay_off);
-       rt73usb_register_write(led->rt2x00dev, MAC_CSR14, reg);
+       rt2x00usb_register_write(led->rt2x00dev, MAC_CSR14, reg);
 
        return 0;
 }
@@ -379,7 +286,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
                 */
                mask = (0xf << crypto->bssidx);
 
-               rt73usb_register_read(rt2x00dev, SEC_CSR0, &reg);
+               rt2x00usb_register_read(rt2x00dev, SEC_CSR0, &reg);
                reg &= mask;
 
                if (reg && reg == mask)
@@ -416,16 +323,16 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
                        field.bit_offset = (3 * key->hw_key_idx);
                        field.bit_mask = 0x7 << field.bit_offset;
 
-                       rt73usb_register_read(rt2x00dev, SEC_CSR1, &reg);
+                       rt2x00usb_register_read(rt2x00dev, SEC_CSR1, &reg);
                        rt2x00_set_field32(&reg, field, crypto->cipher);
-                       rt73usb_register_write(rt2x00dev, SEC_CSR1, reg);
+                       rt2x00usb_register_write(rt2x00dev, SEC_CSR1, reg);
                } else {
                        field.bit_offset = (3 * (key->hw_key_idx - 8));
                        field.bit_mask = 0x7 << field.bit_offset;
 
-                       rt73usb_register_read(rt2x00dev, SEC_CSR5, &reg);
+                       rt2x00usb_register_read(rt2x00dev, SEC_CSR5, &reg);
                        rt2x00_set_field32(&reg, field, crypto->cipher);
-                       rt73usb_register_write(rt2x00dev, SEC_CSR5, reg);
+                       rt2x00usb_register_write(rt2x00dev, SEC_CSR5, reg);
                }
 
                /*
@@ -448,12 +355,12 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
         */
        mask = 1 << key->hw_key_idx;
 
-       rt73usb_register_read(rt2x00dev, SEC_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, SEC_CSR0, &reg);
        if (crypto->cmd == SET_KEY)
                reg |= mask;
        else if (crypto->cmd == DISABLE_KEY)
                reg &= ~mask;
-       rt73usb_register_write(rt2x00dev, SEC_CSR0, reg);
+       rt2x00usb_register_write(rt2x00dev, SEC_CSR0, reg);
 
        return 0;
 }
@@ -478,10 +385,10 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                 * When both registers are full, we drop the key,
                 * otherwise we use the first invalid entry.
                 */
-               rt73usb_register_read(rt2x00dev, SEC_CSR2, &reg);
+               rt2x00usb_register_read(rt2x00dev, SEC_CSR2, &reg);
                if (reg && reg == ~0) {
                        key->hw_key_idx = 32;
-                       rt73usb_register_read(rt2x00dev, SEC_CSR3, &reg);
+                       rt2x00usb_register_read(rt2x00dev, SEC_CSR3, &reg);
                        if (reg && reg == ~0)
                                return -ENOSPC;
                }
@@ -509,14 +416,14 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                /*
                 * Send the address and cipher type to the hardware register.
                 * This data fits within the CSR cache size, so we can use
-                * rt73usb_register_multiwrite() directly.
+                * rt2x00usb_register_multiwrite() directly.
                 */
                memset(&addr_entry, 0, sizeof(addr_entry));
                memcpy(&addr_entry, crypto->address, ETH_ALEN);
                addr_entry.cipher = crypto->cipher;
 
                reg = PAIRWISE_TA_ENTRY(key->hw_key_idx);
-               rt73usb_register_multiwrite(rt2x00dev, reg,
+               rt2x00usb_register_multiwrite(rt2x00dev, reg,
                                            &addr_entry, sizeof(addr_entry));
 
                /*
@@ -524,9 +431,9 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                 * without this received frames will not be decrypted
                 * by the hardware.
                 */
-               rt73usb_register_read(rt2x00dev, SEC_CSR4, &reg);
+               rt2x00usb_register_read(rt2x00dev, SEC_CSR4, &reg);
                reg |= (1 << crypto->bssidx);
-               rt73usb_register_write(rt2x00dev, SEC_CSR4, reg);
+               rt2x00usb_register_write(rt2x00dev, SEC_CSR4, reg);
 
                /*
                 * The driver does not support the IV/EIV generation
@@ -549,21 +456,21 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
        if (key->hw_key_idx < 32) {
                mask = 1 << key->hw_key_idx;
 
-               rt73usb_register_read(rt2x00dev, SEC_CSR2, &reg);
+               rt2x00usb_register_read(rt2x00dev, SEC_CSR2, &reg);
                if (crypto->cmd == SET_KEY)
                        reg |= mask;
                else if (crypto->cmd == DISABLE_KEY)
                        reg &= ~mask;
-               rt73usb_register_write(rt2x00dev, SEC_CSR2, reg);
+               rt2x00usb_register_write(rt2x00dev, SEC_CSR2, reg);
        } else {
                mask = 1 << (key->hw_key_idx - 32);
 
-               rt73usb_register_read(rt2x00dev, SEC_CSR3, &reg);
+               rt2x00usb_register_read(rt2x00dev, SEC_CSR3, &reg);
                if (crypto->cmd == SET_KEY)
                        reg |= mask;
                else if (crypto->cmd == DISABLE_KEY)
                        reg &= ~mask;
-               rt73usb_register_write(rt2x00dev, SEC_CSR3, reg);
+               rt2x00usb_register_write(rt2x00dev, SEC_CSR3, reg);
        }
 
        return 0;
@@ -580,13 +487,13 @@ static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev,
         * and broadcast frames will always be accepted since
         * there is no filter for it at this time.
         */
-       rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC,
                           !(filter_flags & FIF_FCSFAIL));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
                           !(filter_flags & FIF_PLCPFAIL));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
-                          !(filter_flags & FIF_CONTROL));
+                          !(filter_flags & (FIF_CONTROL | FIF_PSPOLL)));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
                           !(filter_flags & FIF_PROMISC_IN_BSS));
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
@@ -598,7 +505,7 @@ static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BROADCAST, 0);
        rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS,
                           !(filter_flags & FIF_CONTROL));
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 }
 
 static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
@@ -617,16 +524,16 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
                 * bits which (when set to 0) will invalidate the entire beacon.
                 */
                beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
-               rt73usb_register_write(rt2x00dev, beacon_base, 0);
+               rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
 
                /*
                 * Enable synchronisation.
                 */
-               rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+               rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
                rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
                rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
                rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
-               rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
        }
 
        if (flags & CONFIG_UPDATE_MAC) {
@@ -634,7 +541,7 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
                rt2x00_set_field32(&reg, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff);
                conf->mac[1] = cpu_to_le32(reg);
 
-               rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2,
+               rt2x00usb_register_multiwrite(rt2x00dev, MAC_CSR2,
                                            conf->mac, sizeof(conf->mac));
        }
 
@@ -643,7 +550,7 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
                rt2x00_set_field32(&reg, MAC_CSR5_BSS_ID_MASK, 3);
                conf->bssid[1] = cpu_to_le32(reg);
 
-               rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4,
+               rt2x00usb_register_multiwrite(rt2x00dev, MAC_CSR4,
                                            conf->bssid, sizeof(conf->bssid));
        }
 }
@@ -653,26 +560,33 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32);
+       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
        rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
-       rt73usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+                          erp->beacon_int * 16);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
        rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
-       rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR8, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR8, &reg);
        rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
        rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
        rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
-       rt73usb_register_write(rt2x00dev, MAC_CSR8, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg);
 }
 
 static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -818,20 +732,18 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
        for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
                rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
 
-       rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, PHY_CSR0, &reg);
 
        rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG,
                           (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ));
        rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A,
                           (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ));
 
-       rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
+       rt2x00usb_register_write(rt2x00dev, PHY_CSR0, reg);
 
-       if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
-           rt2x00_rf(&rt2x00dev->chip, RF5225))
+       if (rt2x00_rf(rt2x00dev, RF5226) || rt2x00_rf(rt2x00dev, RF5225))
                rt73usb_config_antenna_5x(rt2x00dev, ant);
-       else if (rt2x00_rf(&rt2x00dev->chip, RF2528) ||
-                rt2x00_rf(&rt2x00dev->chip, RF2527))
+       else if (rt2x00_rf(rt2x00dev, RF2528) || rt2x00_rf(rt2x00dev, RF2527))
                rt73usb_config_antenna_2x(rt2x00dev, ant);
 }
 
@@ -865,8 +777,7 @@ static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
        rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
 
-       smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-                 rt2x00_rf(&rt2x00dev->chip, RF2527));
+       smart = !(rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527));
 
        rt73usb_bbp_read(rt2x00dev, 3, &r3);
        rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
@@ -915,31 +826,50 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
                           libconf->conf->long_frame_max_tx_count);
        rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
                           libconf->conf->short_frame_max_tx_count);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 }
 
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
+static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
+                               struct rt2x00lib_conf *libconf)
 {
+       enum dev_state state =
+           (libconf->conf->flags & IEEE80211_CONF_PS) ?
+               STATE_SLEEP : STATE_AWAKE;
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       if (state == STATE_SLEEP) {
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
+               rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+                                  rt2x00dev->beacon_int - 10);
+               rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
+                                  libconf->conf->listen_interval - 1);
+               rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+               /* We must first disable autowake before it can be enabled */
+               rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+               rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+               rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+               rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+               rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+                                           USB_MODE_SLEEP, REGISTER_TIMEOUT);
+       } else {
+               rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+                                           USB_MODE_WAKEUP, REGISTER_TIMEOUT);
+
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
+               rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+               rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+               rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+               rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+               rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+       }
 }
 
 static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
@@ -957,8 +887,8 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
                rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt73usb_config_retry_limit(rt2x00dev, libconf);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt73usb_config_duration(rt2x00dev, libconf);
+       if (flags & IEEE80211_CONF_CHANGE_PS)
+               rt73usb_config_ps(rt2x00dev, libconf);
 }
 
 /*
@@ -972,31 +902,38 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
        /*
         * Update FCS error count from register.
         */
-       rt73usb_register_read(rt2x00dev, STA_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, STA_CSR0, &reg);
        qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
-       rt73usb_register_read(rt2x00dev, STA_CSR1, &reg);
+       rt2x00usb_register_read(rt2x00dev, STA_CSR1, &reg);
        qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
-static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+                                  struct link_qual *qual, u8 vgc_level)
 {
-       rt73usb_bbp_write(rt2x00dev, 17, 0x20);
-       rt2x00dev->link.vgc_level = 0x20;
+       if (qual->vgc_level != vgc_level) {
+               rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+               qual->vgc_level = vgc_level;
+               qual->vgc_level_reg = vgc_level;
+       }
+}
+
+static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+                               struct link_qual *qual)
+{
+       rt73usb_set_vgc(rt2x00dev, qual, 0x20);
 }
 
-static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+                              struct link_qual *qual, const u32 count)
 {
-       int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
-       u8 r17;
        u8 up_bound;
        u8 low_bound;
 
-       rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
        /*
         * Determine r17 bounds.
         */
@@ -1009,10 +946,10 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
                        up_bound += 0x10;
                }
        } else {
-               if (rssi > -82) {
+               if (qual->rssi > -82) {
                        low_bound = 0x1c;
                        up_bound = 0x40;
-               } else if (rssi > -84) {
+               } else if (qual->rssi > -84) {
                        low_bound = 0x1c;
                        up_bound = 0x20;
                } else {
@@ -1036,37 +973,32 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
        /*
         * Special big-R17 for very short distance
         */
-       if (rssi > -35) {
-               if (r17 != 0x60)
-                       rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+       if (qual->rssi > -35) {
+               rt73usb_set_vgc(rt2x00dev, qual, 0x60);
                return;
        }
 
        /*
         * Special big-R17 for short distance
         */
-       if (rssi >= -58) {
-               if (r17 != up_bound)
-                       rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+       if (qual->rssi >= -58) {
+               rt73usb_set_vgc(rt2x00dev, qual, 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);
+       if (qual->rssi >= -66) {
+               rt73usb_set_vgc(rt2x00dev, qual, 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);
+       if (qual->rssi >= -74) {
+               rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x08);
                return;
        }
 
@@ -1074,12 +1006,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
         * Special case: Change up_bound based on the rssi.
         * Lower up_bound when rssi is weaker then -74 dBm.
         */
-       up_bound -= 2 * (-74 - rssi);
+       up_bound -= 2 * (-74 - qual->rssi);
        if (low_bound > up_bound)
                up_bound = low_bound;
 
-       if (r17 > up_bound) {
-               rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+       if (qual->vgc_level > up_bound) {
+               rt73usb_set_vgc(rt2x00dev, qual, up_bound);
                return;
        }
 
@@ -1089,17 +1021,12 @@ dynamic_cca_tune:
         * 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 ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+               rt73usb_set_vgc(rt2x00dev, qual,
+                               min_t(u8, qual->vgc_level + 4, up_bound));
+       else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+               rt73usb_set_vgc(rt2x00dev, qual,
+                               max_t(u8, qual->vgc_level - 4, low_bound));
 }
 
 /*
@@ -1110,25 +1037,37 @@ static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
        return FIRMWARE_RT2571;
 }
 
-static u16 rt73usb_get_firmware_crc(const void *data, const size_t len)
+static int rt73usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+                                 const u8 *data, const size_t len)
 {
+       u16 fw_crc;
        u16 crc;
 
        /*
-        * Use the crc itu-t algorithm.
+        * Only support 2kb firmware files.
+        */
+       if (len != 2048)
+               return FW_BAD_LENGTH;
+
+       /*
         * The last 2 bytes in the firmware array are the crc checksum itself,
         * this means that we should never pass those 2 bytes to the crc
         * algorithm.
         */
+       fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+       /*
+        * Use the crc itu-t algorithm.
+        */
        crc = crc_itu_t(0, data, len - 2);
        crc = crc_itu_t_byte(crc, 0);
        crc = crc_itu_t_byte(crc, 0);
 
-       return crc;
+       return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
 }
 
-static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
-                                const size_t len)
+static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+                                const u8 *data, const size_t len)
 {
        unsigned int i;
        int status;
@@ -1138,7 +1077,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
         * Wait for stable hardware.
         */
        for (i = 0; i < 100; i++) {
-               rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
                if (reg)
                        break;
                msleep(1);
@@ -1180,13 +1119,13 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_AUTO_TX_SEQ, 1);
        rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 0);
        rt2x00_set_field32(&reg, TXRX_CSR0_TX_WITHOUT_WAITING, 0);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */
        rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID0_VALID, 1);
        rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID1, 30); /* Rssi */
@@ -1195,12 +1134,12 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID2_VALID, 1);
        rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID3, 30); /* Rssi */
        rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID3_VALID, 1);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR1, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR1, reg);
 
        /*
         * CCK TXD BBP registers
         */
-       rt73usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID0, 13);
        rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID0_VALID, 1);
        rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID1, 12);
@@ -1209,77 +1148,76 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID2_VALID, 1);
        rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID3, 10);
        rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID3_VALID, 1);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR2, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR2, reg);
 
        /*
         * OFDM TXD BBP registers
         */
-       rt73usb_register_read(rt2x00dev, TXRX_CSR3, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR3, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID0, 7);
        rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID0_VALID, 1);
        rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID1, 6);
        rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID1_VALID, 1);
        rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID2, 5);
        rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID2_VALID, 1);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR3, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR3, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR7, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR7, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_6MBS, 59);
        rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_9MBS, 53);
        rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_12MBS, 49);
        rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_18MBS, 46);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR7, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR7, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR8, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR8, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_24MBS, 44);
        rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_36MBS, 42);
        rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_48MBS, 42);
        rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_54MBS, 42);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR8, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
-       rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR6, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR6, &reg);
        rt2x00_set_field32(&reg, MAC_CSR6_MAX_FRAME_UNIT, 0xfff);
-       rt73usb_register_write(rt2x00dev, MAC_CSR6, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR6, reg);
 
-       rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00000718);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR10, 0x00000718);
 
        if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
                return -EBUSY;
 
-       rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
 
        /*
         * Invalidate all Shared Keys (SEC_CSR0),
         * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
         */
-       rt73usb_register_write(rt2x00dev, SEC_CSR0, 0x00000000);
-       rt73usb_register_write(rt2x00dev, SEC_CSR1, 0x00000000);
-       rt73usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000);
+       rt2x00usb_register_write(rt2x00dev, SEC_CSR0, 0x00000000);
+       rt2x00usb_register_write(rt2x00dev, SEC_CSR1, 0x00000000);
+       rt2x00usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000);
 
        reg = 0x000023b0;
-       if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-           rt2x00_rf(&rt2x00dev->chip, RF2527))
+       if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527))
                rt2x00_set_field32(&reg, PHY_CSR1_RF_RPI, 1);
-       rt73usb_register_write(rt2x00dev, PHY_CSR1, reg);
+       rt2x00usb_register_write(rt2x00dev, PHY_CSR1, reg);
 
-       rt73usb_register_write(rt2x00dev, PHY_CSR5, 0x00040a06);
-       rt73usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606);
-       rt73usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408);
+       rt2x00usb_register_write(rt2x00dev, PHY_CSR5, 0x00040a06);
+       rt2x00usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606);
+       rt2x00usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
        rt2x00_set_field32(&reg, MAC_CSR9_CW_SELECT, 0);
-       rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
 
        /*
         * Clear all beacons
@@ -1287,36 +1225,36 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
         * the first byte since that byte contains the VALID and OWNER
         * bits which (when set to 0) will invalidate the entire beacon.
         */
-       rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
-       rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
-       rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
-       rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
 
        /*
         * We must clear the error counters.
         * These registers are cleared on read,
         * so we may pass a useless variable to store the value.
         */
-       rt73usb_register_read(rt2x00dev, STA_CSR0, &reg);
-       rt73usb_register_read(rt2x00dev, STA_CSR1, &reg);
-       rt73usb_register_read(rt2x00dev, STA_CSR2, &reg);
+       rt2x00usb_register_read(rt2x00dev, STA_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, STA_CSR1, &reg);
+       rt2x00usb_register_read(rt2x00dev, STA_CSR2, &reg);
 
        /*
         * Reset MAC and BBP registers.
         */
-       rt73usb_register_read(rt2x00dev, MAC_CSR1, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR1, &reg);
        rt2x00_set_field32(&reg, MAC_CSR1_SOFT_RESET, 1);
        rt2x00_set_field32(&reg, MAC_CSR1_BBP_RESET, 1);
-       rt73usb_register_write(rt2x00dev, MAC_CSR1, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR1, reg);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR1, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR1, &reg);
        rt2x00_set_field32(&reg, MAC_CSR1_SOFT_RESET, 0);
        rt2x00_set_field32(&reg, MAC_CSR1_BBP_RESET, 0);
-       rt73usb_register_write(rt2x00dev, MAC_CSR1, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR1, reg);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR1, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR1, &reg);
        rt2x00_set_field32(&reg, MAC_CSR1_HOST_READY, 1);
-       rt73usb_register_write(rt2x00dev, MAC_CSR1, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR1, reg);
 
        return 0;
 }
@@ -1394,11 +1332,11 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
                           (state == STATE_RADIO_RX_OFF) ||
                           (state == STATE_RADIO_RX_OFF_LINK));
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 }
 
 static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
@@ -1415,12 +1353,12 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
 
 static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
-       rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
 
        /*
         * Disable synchronisation.
         */
-       rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, 0);
 
        rt2x00usb_disable_radio(rt2x00dev);
 }
@@ -1433,10 +1371,10 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 
        put_to_sleep = (state != STATE_AWAKE);
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR12, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR12, &reg);
        rt2x00_set_field32(&reg, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep);
        rt2x00_set_field32(&reg, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep);
-       rt73usb_register_write(rt2x00dev, MAC_CSR12, reg);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR12, reg);
 
        /*
         * Device is not guaranteed to be in the requested state yet.
@@ -1444,7 +1382,7 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
         * device has entered the correct state.
         */
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt73usb_register_read(rt2x00dev, MAC_CSR12, &reg);
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR12, &reg);
                state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
                if (state == !put_to_sleep)
                        return 0;
@@ -1526,8 +1464,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_desc_write(txd, 2, word);
 
        if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) {
-               _rt2x00_desc_write(txd, 3, skbdesc->iv);
-               _rt2x00_desc_write(txd, 4, skbdesc->eiv);
+               _rt2x00_desc_write(txd, 3, skbdesc->iv[0]);
+               _rt2x00_desc_write(txd, 4, skbdesc->iv[1]);
        }
 
        rt2x00_desc_read(txd, 5, &word);
@@ -1547,7 +1485,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
        rt2x00_set_field32(&word, TXD_W0_OFDM,
-                          test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+                          (txdesc->rate_mode == RATE_MODE_OFDM));
        rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
        rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
                           test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1584,11 +1522,9 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
-       rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
-       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
        /*
         * Write entire beacon with descriptor to register.
@@ -1606,8 +1542,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
        entry->skb = NULL;
 }
 
-static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
-                                  struct sk_buff *skb)
+static int rt73usb_get_tx_data_len(struct queue_entry *entry)
 {
        int length;
 
@@ -1615,8 +1550,8 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
         * The length _must_ be a multiple of 4,
         * but it must _not_ be a multiple of the USB packet size.
         */
-       length = roundup(skb->len, 4);
-       length += (4 * !(length % rt2x00dev->usb_maxpacket));
+       length = roundup(entry->skb->len, 4);
+       length += (4 * !(length % entry->queue->usb_maxpacket));
 
        return length;
 }
@@ -1635,14 +1570,14 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
         * For Wi-Fi faily generated beacons between participating stations.
         * Set TBTT phase adaptive adjustment step to 8us (default 16us)
         */
-       rt73usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
        if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
                rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
                rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
                rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
-               rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
        }
 }
 
@@ -1717,9 +1652,12 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
        }
 
        if (rxdesc->cipher != CIPHER_NONE) {
-               _rt2x00_desc_read(rxd, 2, &rxdesc->iv);
-               _rt2x00_desc_read(rxd, 3, &rxdesc->eiv);
+               _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]);
+               _rt2x00_desc_read(rxd, 3, &rxdesc->iv[1]);
+               rxdesc->dev_flags |= RXDONE_CRYPTO_IV;
+
                _rt2x00_desc_read(rxd, 4, &rxdesc->icv);
+               rxdesc->dev_flags |= RXDONE_CRYPTO_ICV;
 
                /*
                 * Hardware has stripped IV/EIV data from 802.11 frame during
@@ -1881,18 +1819,20 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
         * Identify RF chipset.
         */
        value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
-       rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
        rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
+       rt2x00_print_chip(rt2x00dev);
 
-       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
+       if (!rt2x00_check_rev(rt2x00dev, 0x000ffff0, 0x25730) ||
+           rt2x00_check_rev(rt2x00dev, 0x0000000f, 0)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
 
-       if (!rt2x00_rf(&rt2x00dev->chip, RF5226) &&
-           !rt2x00_rf(&rt2x00dev->chip, RF2528) &&
-           !rt2x00_rf(&rt2x00dev->chip, RF5225) &&
-           !rt2x00_rf(&rt2x00dev->chip, RF2527)) {
+       if (!rt2x00_rf(rt2x00dev, RF5226) &&
+           !rt2x00_rf(rt2x00dev, RF2528) &&
+           !rt2x00_rf(rt2x00dev, RF5225) &&
+           !rt2x00_rf(rt2x00dev, RF2527)) {
                ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
                return -ENODEV;
        }
@@ -1912,6 +1852,12 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
                __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
 
        /*
+        * Detect if this device has an hardware controlled radio.
+        */
+       if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+               __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+
+       /*
         * Read frequency offset.
         */
        rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
@@ -2116,8 +2062,9 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
         */
        rt2x00dev->hw->flags =
            IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-           IEEE80211_HW_SIGNAL_DBM;
-       rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
+           IEEE80211_HW_SIGNAL_DBM |
+           IEEE80211_HW_SUPPORTS_PS |
+           IEEE80211_HW_PS_NULLFUNC_STACK;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
        SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2130,17 +2077,17 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
-       if (rt2x00_rf(&rt2x00dev->chip, RF2528)) {
+       if (rt2x00_rf(rt2x00dev, RF2528)) {
                spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
                spec->channels = rf_vals_bg_2528;
-       } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) {
+       } else if (rt2x00_rf(rt2x00dev, RF5226)) {
                spec->supported_bands |= SUPPORT_BAND_5GHZ;
                spec->num_channels = ARRAY_SIZE(rf_vals_5226);
                spec->channels = rf_vals_5226;
-       } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) {
+       } else if (rt2x00_rf(rt2x00dev, RF2527)) {
                spec->num_channels = 14;
                spec->channels = rf_vals_5225_2527;
-       } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) {
+       } else if (rt2x00_rf(rt2x00dev, RF5225)) {
                spec->supported_bands |= SUPPORT_BAND_5GHZ;
                spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
                spec->channels = rf_vals_5225_2527;
@@ -2191,10 +2138,15 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * This device has multiple filters for control frames,
+        * but has no a separate filter for PS Poll frames.
+        */
+       __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+
+       /*
         * This device requires firmware.
         */
        __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-       __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
        if (!modparam_nohwcrypt)
                __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
 
@@ -2217,6 +2169,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
        struct rt2x00_field32 field;
        int retval;
        u32 reg;
+       u32 offset;
 
        /*
         * First pass the configuration through rt2x00lib, that will
@@ -2228,67 +2181,56 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
        if (retval)
                return retval;
 
+       /*
+        * We only need to perform additional register initialization
+        * for WMM queues/
+        */
+       if (queue_idx >= 4)
+               return 0;
+
        queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
 
        /* Update WMM TXOP register */
-       if (queue_idx < 2) {
-               field.bit_offset = queue_idx * 16;
-               field.bit_mask = 0xffff << field.bit_offset;
-
-               rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
-               rt2x00_set_field32(&reg, field, queue->txop);
-               rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
-       } else if (queue_idx < 4) {
-               field.bit_offset = (queue_idx - 2) * 16;
-               field.bit_mask = 0xffff << field.bit_offset;
-
-               rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
-               rt2x00_set_field32(&reg, field, queue->txop);
-               rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
-       }
+       offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
+       field.bit_offset = (queue_idx & 1) * 16;
+       field.bit_mask = 0xffff << field.bit_offset;
+
+       rt2x00usb_register_read(rt2x00dev, offset, &reg);
+       rt2x00_set_field32(&reg, field, queue->txop);
+       rt2x00usb_register_write(rt2x00dev, offset, reg);
 
        /* Update WMM registers */
        field.bit_offset = queue_idx * 4;
        field.bit_mask = 0xf << field.bit_offset;
 
-       rt73usb_register_read(rt2x00dev, AIFSN_CSR, &reg);
+       rt2x00usb_register_read(rt2x00dev, AIFSN_CSR, &reg);
        rt2x00_set_field32(&reg, field, queue->aifs);
-       rt73usb_register_write(rt2x00dev, AIFSN_CSR, reg);
+       rt2x00usb_register_write(rt2x00dev, AIFSN_CSR, reg);
 
-       rt73usb_register_read(rt2x00dev, CWMIN_CSR, &reg);
+       rt2x00usb_register_read(rt2x00dev, CWMIN_CSR, &reg);
        rt2x00_set_field32(&reg, field, queue->cw_min);
-       rt73usb_register_write(rt2x00dev, CWMIN_CSR, reg);
+       rt2x00usb_register_write(rt2x00dev, CWMIN_CSR, reg);
 
-       rt73usb_register_read(rt2x00dev, CWMAX_CSR, &reg);
+       rt2x00usb_register_read(rt2x00dev, CWMAX_CSR, &reg);
        rt2x00_set_field32(&reg, field, queue->cw_max);
-       rt73usb_register_write(rt2x00dev, CWMAX_CSR, reg);
+       rt2x00usb_register_write(rt2x00dev, CWMAX_CSR, reg);
 
        return 0;
 }
 
-#if 0
-/*
- * Mac80211 demands get_tsf must be atomic.
- * This is not possible for rt73usb since all register access
- * functions require sleeping. Untill mac80211 no longer needs
- * get_tsf to be atomic, this function should be disabled.
- */
 static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        u64 tsf;
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR13, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR13, &reg);
        tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32;
-       rt73usb_register_read(rt2x00dev, TXRX_CSR12, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR12, &reg);
        tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER);
 
        return tsf;
 }
-#else
-#define rt73usb_get_tsf        NULL
-#endif
 
 static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .tx                     = rt2x00mac_tx,
@@ -2297,25 +2239,26 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
+       .set_tim                = rt2x00mac_set_tim,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt73usb_conf_tx,
-       .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt73usb_get_tsf,
+       .rfkill_poll            = rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .probe_hw               = rt73usb_probe_hw,
        .get_firmware_name      = rt73usb_get_firmware_name,
-       .get_firmware_crc       = rt73usb_get_firmware_crc,
+       .check_firmware         = rt73usb_check_firmware,
        .load_firmware          = rt73usb_load_firmware,
        .initialize             = rt2x00usb_initialize,
        .uninitialize           = rt2x00usb_uninitialize,
        .clear_entry            = rt2x00usb_clear_entry,
        .set_device_state       = rt73usb_set_device_state,
+       .rfkill_poll            = rt73usb_rfkill_poll,
        .link_stats             = rt73usb_link_stats,
        .reset_tuner            = rt73usb_reset_tuner,
        .link_tuner             = rt73usb_link_tuner,
@@ -2324,6 +2267,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .write_beacon           = rt73usb_write_beacon,
        .get_tx_data_len        = rt73usb_get_tx_data_len,
        .kick_tx_queue          = rt73usb_kick_tx_queue,
+       .kill_tx_queue          = rt2x00usb_kill_tx_queue,
        .fill_rxdone            = rt73usb_fill_rxdone,
        .config_shared_key      = rt73usb_config_shared_key,
        .config_pairwise_key    = rt73usb_config_pairwise_key,
@@ -2356,19 +2300,20 @@ static const struct data_queue_desc rt73usb_queue_bcn = {
 };
 
 static const struct rt2x00_ops rt73usb_ops = {
-       .name           = KBUILD_MODNAME,
-       .max_sta_intf   = 1,
-       .max_ap_intf    = 4,
-       .eeprom_size    = EEPROM_SIZE,
-       .rf_size        = RF_SIZE,
-       .tx_queues      = NUM_TX_QUEUES,
-       .rx             = &rt73usb_queue_rx,
-       .tx             = &rt73usb_queue_tx,
-       .bcn            = &rt73usb_queue_bcn,
-       .lib            = &rt73usb_rt2x00_ops,
-       .hw             = &rt73usb_mac80211_ops,
+       .name                   = KBUILD_MODNAME,
+       .max_sta_intf           = 1,
+       .max_ap_intf            = 4,
+       .eeprom_size            = EEPROM_SIZE,
+       .rf_size                = RF_SIZE,
+       .tx_queues              = NUM_TX_QUEUES,
+       .extra_tx_headroom      = TXD_DESC_SIZE,
+       .rx                     = &rt73usb_queue_rx,
+       .tx                     = &rt73usb_queue_tx,
+       .bcn                    = &rt73usb_queue_bcn,
+       .lib                    = &rt73usb_rt2x00_ops,
+       .hw                     = &rt73usb_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-       .debugfs        = &rt73usb_rt2x00debug,
+       .debugfs                = &rt73usb_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
@@ -2377,7 +2322,18 @@ static const struct rt2x00_ops rt73usb_ops = {
  */
 static struct usb_device_id rt73usb_device_table[] = {
        /* AboCom */
+       { USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* AL */
+       { USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Amigo */
+       { USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* AMIT  */
+       { USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Askey */
        { USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) },
        /* ASUS */
@@ -2390,8 +2346,13 @@ static struct usb_device_id rt73usb_device_table[] = {
        { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Billionton */
        { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Buffalo */
+       { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
        /* CNet */
        { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
@@ -2404,6 +2365,11 @@ static struct usb_device_id rt73usb_device_table[] = {
        { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Edimax */
+       { USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* EnGenius */
+       { USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Gemtek */
        { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Gigabyte */
@@ -2412,33 +2378,54 @@ static struct usb_device_id rt73usb_device_table[] = {
        /* Huawei-3Com */
        { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Hercules */
+       { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Linksys */
        { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) },
        /* MSI */
+       { USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Ovislink */
+       { USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Ralink */
+       { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Qcom */
        { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Samsung */
+       { USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Senao */
        { USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Sitecom */
-       { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Surecom */
        { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Tilgin */
+       { USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Philips */
+       { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Planex */
        { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* WideTell */
+       { USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Zcom */
+       { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* ZyXEL */
+       { USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) },
        { 0, }
 };