rt2x00: add USB ID for the Linksys WUSB200.
[linux-2.6-block.git] / drivers / net / wireless / rt2x00 / rt73usb.c
index 934f8e03c5aae99fa9f6175d0c509d48fc245a48..96a8d69f8790480b8fee654beebf60b4e5efbda2 100644 (file)
@@ -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,
@@ -55,113 +55,35 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
  * between each attampt. When the busy bit is still set at that time,
  * the access attempt is considered to have failed,
  * and we will print an error.
- * The _lock versions must be used if you already hold the usb_cache_mutex
+ * 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)
 {
        u32 reg;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       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->usb_cache_mutex);
-
-       return;
-
-exit_fail:
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       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);
+       }
 
-       ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -169,123 +91,95 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
-
-       /*
-        * Wait until the BBP becomes ready.
-        */
-       reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
-               goto exit_fail;
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
-        * 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->usb_cache_mutex);
-
-       return;
-
-exit_fail:
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 
-       ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
-       *value = 0xff;
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 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->usb_cache_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->usb_cache_mutex);
-       ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
-       return;
-
-rf_write:
-       reg = 0;
-       rt2x00_set_field32(&reg, PHY_CSR4_VALUE, value);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
-        * 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);
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
-}
-
-#ifdef CONFIG_RT2X00_LIB_DEBUGFS
-#define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-
-static void rt73usb_read_csr(struct rt2x00_dev *rt2x00dev,
-                            const unsigned int word, u32 *data)
-{
-       rt73usb_register_read(rt2x00dev, CSR_OFFSET(word), data);
-}
+       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->chip, RF5225) ||
+                                        rt2x00_rf(&rt2x00dev->chip, 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);
+       }
 
-static void rt73usb_write_csr(struct rt2x00_dev *rt2x00dev,
-                             const unsigned int word, u32 data)
-{
-       rt73usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
 static const struct rt2x00debug rt73usb_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt73usb_read_csr,
-               .write          = rt73usb_write_csr,
+               .read           = rt2x00usb_register_read,
+               .write          = rt2x00usb_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u32),
                .word_count     = CSR_REG_SIZE / sizeof(u32),
        },
        .eeprom = {
                .read           = rt2x00_eeprom_read,
                .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
                .word_size      = sizeof(u16),
                .word_count     = EEPROM_SIZE / sizeof(u16),
        },
        .bbp    = {
                .read           = rt73usb_bbp_read,
                .write          = rt73usb_bbp_write,
+               .word_base      = BBP_BASE,
                .word_size      = sizeof(u8),
                .word_count     = BBP_SIZE / sizeof(u8),
        },
        .rf     = {
                .read           = rt2x00_rf_read,
                .write          = rt73usb_rf_write,
+               .word_base      = RF_BASE,
                .word_size      = sizeof(u32),
                .word_count     = RF_SIZE / sizeof(u32),
        },
@@ -341,10 +235,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;
 }
@@ -387,7 +281,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)
@@ -424,16 +318,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);
                }
 
                /*
@@ -456,12 +350,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;
 }
@@ -486,10 +380,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;
                }
@@ -517,14 +411,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));
 
                /*
@@ -532,9 +426,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
@@ -557,21 +451,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;
@@ -588,7 +482,7 @@ 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,
@@ -606,7 +500,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,
@@ -625,16 +519,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) {
@@ -642,7 +536,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));
        }
 
@@ -651,7 +545,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));
        }
 }
@@ -661,95 +555,26 @@ static void rt73usb_config_erp(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_RX_ACK_TIMEOUT, erp->ack_timeout);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       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_PREAMBLE,
                           !!erp->short_preamble);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-}
-
-static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u16 eeprom;
-       short lna_gain = 0;
-
-       if (libconf->band == IEEE80211_BAND_2GHZ) {
-               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
-                       lna_gain += 14;
-
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
-               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
-       } else {
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
-               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
-       }
-
-       rt2x00dev->lna_gain = lna_gain;
-}
-
-static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
-                                  const int basic_rate_mask)
-{
-       rt73usb_register_write(rt2x00dev, TXRX_CSR5, basic_rate_mask);
-}
-
-static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
-                                  struct rf_channel *rf, const int txpower)
-{
-       u8 r3;
-       u8 r94;
-       u8 smart;
-
-       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));
-
-       rt73usb_bbp_read(rt2x00dev, 3, &r3);
-       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
-       rt73usb_bbp_write(rt2x00dev, 3, r3);
-
-       r94 = 6;
-       if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
-               r94 += txpower - MAX_TXPOWER;
-       else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
-               r94 += txpower;
-       rt73usb_bbp_write(rt2x00dev, 94, r94);
-
-       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 
-       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
-       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
-       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
 
-       udelay(10);
-}
-
-static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
-                                  const int txpower)
-{
-       struct rf_channel rf;
-
-       rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
-       rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
-       rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
-       rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
-
-       rt73usb_config_channel(rt2x00dev, &rf, txpower);
+       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);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg);
 }
 
 static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -869,8 +694,8 @@ static const struct antenna_sel antenna_sel_bg[] = {
        { 98,  { 0x48, 0x48 } },
 };
 
-static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                  struct antenna_setup *ant)
+static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
+                              struct antenna_setup *ant)
 {
        const struct antenna_sel *sel;
        unsigned int lna;
@@ -895,14 +720,14 @@ static void rt73usb_config_antenna(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))
@@ -912,33 +737,111 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
                rt73usb_config_antenna_2x(rt2x00dev, ant);
 }
 
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
+static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
                                    struct rt2x00lib_conf *libconf)
+{
+       u16 eeprom;
+       short lna_gain = 0;
+
+       if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+                       lna_gain += 14;
+
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
+               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
+       } else {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
+               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
+       }
+
+       rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
+                                  struct rf_channel *rf, const int txpower)
+{
+       u8 r3;
+       u8 r94;
+       u8 smart;
+
+       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));
+
+       rt73usb_bbp_read(rt2x00dev, 3, &r3);
+       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
+       rt73usb_bbp_write(rt2x00dev, 3, r3);
+
+       r94 = 6;
+       if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
+               r94 += txpower - MAX_TXPOWER;
+       else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
+               r94 += txpower;
+       rt73usb_bbp_write(rt2x00dev, 94, r94);
+
+       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       udelay(10);
+}
+
+static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
+                                  const int txpower)
+{
+       struct rf_channel rf;
+
+       rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
+       rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
+       rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
+       rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
+
+       rt73usb_config_channel(rt2x00dev, &rf, txpower);
+}
+
+static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+                                      struct rt2x00lib_conf *libconf)
 {
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
-       rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, libconf->slot_time);
-       rt73usb_register_write(rt2x00dev, MAC_CSR9, 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);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+}
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR8, &reg);
-       rt2x00_set_field32(&reg, MAC_CSR8_SIFS, libconf->sifs);
-       rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
-       rt2x00_set_field32(&reg, MAC_CSR8_EIFS, libconf->eifs);
-       rt73usb_register_write(rt2x00dev, MAC_CSR8, reg);
+static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
+                                   struct rt2x00lib_conf *libconf)
+{
+       u32 reg;
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+       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);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 
-       rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00usb_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);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 }
 
 static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
@@ -948,16 +851,15 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
        /* Always recalculate LNA gain before changing configuration */
        rt73usb_config_lna_gain(rt2x00dev, libconf);
 
-       if (flags & CONFIG_UPDATE_PHYMODE)
-               rt73usb_config_phymode(rt2x00dev, libconf->basic_rates);
-       if (flags & CONFIG_UPDATE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt73usb_config_channel(rt2x00dev, &libconf->rf,
                                       libconf->conf->power_level);
-       if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
+       if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
+           !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
                rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
-       if (flags & CONFIG_UPDATE_ANTENNA)
-               rt73usb_config_antenna(rt2x00dev, &libconf->ant);
-       if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
+       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);
 }
 
@@ -972,13 +874,13 @@ 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);
 }
 
@@ -1138,7 +1040,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 +1082,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 +1097,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 +1111,77 @@ 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))
                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 +1189,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 +1296,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 +1317,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 +1335,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 +1346,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 +1428,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);
@@ -1584,11 +1486,11 @@ 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);
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
        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 +1508,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 +1516,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 +1536,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);
        }
 }
 
@@ -1685,7 +1586,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 }
 
 static void rt73usb_fill_rxdone(struct queue_entry *entry,
-                               struct rxdone_entry_desc *rxdesc)
+                               struct rxdone_entry_desc *rxdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
@@ -1717,9 +1618,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
@@ -1781,10 +1685,8 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
        if (!is_valid_ether_addr(mac)) {
-               DECLARE_MAC_BUF(macbuf);
-
                random_ether_addr(mac);
-               EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+               EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -1883,7 +1785,7 @@ 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);
 
        if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
@@ -2211,20 +2113,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
-static int rt73usb_set_retry_limit(struct ieee80211_hw *hw,
-                                  u32 short_retry, u32 long_retry)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       u32 reg;
-
-       rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry);
-       rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       return 0;
-}
-
 static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
                           const struct ieee80211_tx_queue_params *params)
 {
@@ -2251,33 +2139,33 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
                field.bit_offset = queue_idx * 16;
                field.bit_mask = 0xffff << field.bit_offset;
 
-               rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
+               rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
                rt2x00_set_field32(&reg, field, queue->txop);
-               rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
+               rt2x00usb_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);
+               rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
                rt2x00_set_field32(&reg, field, queue->txop);
-               rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
+               rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR1, 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;
 }
@@ -2295,9 +2183,9 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
        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;
@@ -2317,7 +2205,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt73usb_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt73usb_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -2331,8 +2218,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .load_firmware          = rt73usb_load_firmware,
        .initialize             = rt2x00usb_initialize,
        .uninitialize           = rt2x00usb_uninitialize,
-       .init_rxentry           = rt2x00usb_init_rxentry,
-       .init_txentry           = rt2x00usb_init_txentry,
+       .clear_entry            = rt2x00usb_clear_entry,
        .set_device_state       = rt73usb_set_device_state,
        .link_stats             = rt73usb_link_stats,
        .reset_tuner            = rt73usb_reset_tuner,
@@ -2348,6 +2234,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .config_filter          = rt73usb_config_filter,
        .config_intf            = rt73usb_config_intf,
        .config_erp             = rt73usb_config_erp,
+       .config_ant             = rt73usb_config_ant,
        .config                 = rt73usb_config,
 };
 
@@ -2434,6 +2321,7 @@ static struct usb_device_id rt73usb_device_table[] = {
        /* 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, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },