]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/net/wireless/rt2x00/rt73usb.c
rt2x00: Refactor beacon code to make use of start- and stop_queue
[linux-2.6.git] / drivers / net / wireless / rt2x00 / rt73usb.c
index 6521dac7ec4a45fa4b271ee389cf0ca81ca2bc0a..330353ec5c96f2624f7701084e17bbde6fddb234 100644 (file)
@@ -1,5 +1,5 @@
 /*
-       Copyright (C) 2004 - 2009 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
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "rt2x00.h"
@@ -39,7 +40,7 @@
 /*
  * Allow hardware encryption to be disabled.
  */
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
@@ -122,9 +123,6 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       if (!word)
-               return;
-
        mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
@@ -139,8 +137,8 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
                 * 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)));
+                                  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);
 
@@ -186,7 +184,6 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
@@ -194,9 +191,6 @@ static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
        rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
        return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
 }
-#else
-#define rt73usb_rfkill_poll    NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
@@ -276,7 +270,6 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
 {
        struct hw_key_entry key_entry;
        struct rt2x00_field32 field;
-       int timeout;
        u32 mask;
        u32 reg;
 
@@ -312,12 +305,8 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
                       sizeof(key_entry.rx_mic));
 
                reg = SHARED_KEY_ENTRY(key->hw_key_idx);
-               timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
-               rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
-                                                   USB_VENDOR_REQUEST_OUT, reg,
-                                                   &key_entry,
-                                                   sizeof(key_entry),
-                                                   timeout);
+               rt2x00usb_register_multiwrite(rt2x00dev, reg,
+                                             &key_entry, sizeof(key_entry));
 
                /*
                 * The cipher types are stored over 2 registers.
@@ -346,7 +335,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
                 * The driver does not support the IV/EIV generation
                 * in hardware. However it doesn't support the IV/EIV
                 * inside the ieee80211 frame either, but requires it
-                * to be provided seperately for the descriptor.
+                * to be provided separately for the descriptor.
                 * rt2x00lib will cut the IV/EIV data out of all frames
                 * given to us by mac80211, but we must tell mac80211
                 * to generate the IV/EIV data.
@@ -378,7 +367,6 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
 {
        struct hw_pairwise_ta_entry addr_entry;
        struct hw_key_entry key_entry;
-       int timeout;
        u32 mask;
        u32 reg;
 
@@ -413,17 +401,11 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                       sizeof(key_entry.rx_mic));
 
                reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
-               timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
-               rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
-                                                   USB_VENDOR_REQUEST_OUT, reg,
-                                                   &key_entry,
-                                                   sizeof(key_entry),
-                                                   timeout);
+               rt2x00usb_register_multiwrite(rt2x00dev, reg,
+                                             &key_entry, sizeof(key_entry));
 
                /*
                 * Send the address and cipher type to the hardware register.
-                * This data fits within the CSR cache size, so we can use
-                * rt2x00usb_register_multiwrite() directly.
                 */
                memset(&addr_entry, 0, sizeof(addr_entry));
                memcpy(&addr_entry, crypto->address, ETH_ALEN);
@@ -446,7 +428,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                 * The driver does not support the IV/EIV generation
                 * in hardware. However it doesn't support the IV/EIV
                 * inside the ieee80211 frame either, but requires it
-                * to be provided seperately for the descriptor.
+                * to be provided separately for the descriptor.
                 * rt2x00lib will cut the IV/EIV data out of all frames
                 * given to us by mac80211, but we must tell mac80211
                 * to generate the IV/EIV data.
@@ -500,7 +482,7 @@ static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev,
        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,
@@ -520,26 +502,14 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00intf_conf *conf,
                                const unsigned int flags)
 {
-       unsigned int beacon_base;
        u32 reg;
 
        if (flags & CONFIG_UPDATE_TYPE) {
-               /*
-                * Clear current synchronisation setup.
-                * For the Beacon base registers we only need to clear
-                * the first byte since that byte contains the VALID and OWNER
-                * bits which (when set to 0) will invalidate the entire beacon.
-                */
-               beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
-               rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
-
                /*
                 * Enable synchronisation.
                 */
                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);
                rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
        }
 
@@ -563,30 +533,46 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
-                              struct rt2x00lib_erp *erp)
+                              struct rt2x00lib_erp *erp,
+                              u32 changed)
 {
        u32 reg;
 
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+       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);
 
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
-                          !!erp->short_preamble);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               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);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+       }
 
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+       if (changed & BSS_CHANGED_BASIC_RATES)
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR5,
+                                        erp->basic_rates);
 
-       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);
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               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);
+       }
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               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);
 
-       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);
+               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,
@@ -741,11 +727,9 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
 
        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);
 }
 
@@ -779,8 +763,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);
@@ -830,6 +813,9 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        u32 reg;
 
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1);
+       rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_STEP, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0);
        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,
@@ -837,25 +823,6 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 }
 
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u32 reg;
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-}
-
 static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -867,7 +834,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
                rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
-                                  libconf->conf->beacon_int - 10);
+                                  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);
@@ -882,15 +849,15 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
                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);
+
+               rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+                                           USB_MODE_WAKEUP, REGISTER_TIMEOUT);
        }
 }
 
@@ -909,8 +876,6 @@ 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);
 }
@@ -961,7 +926,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
        /*
         * Determine r17 bounds.
         */
-       if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+       if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
                low_bound = 0x28;
                up_bound = 0x48;
 
@@ -1053,6 +1018,55 @@ dynamic_cca_tune:
                                max_t(u8, qual->vgc_level - 4, low_bound));
 }
 
+/*
+ * Queue handlers.
+ */
+static void rt73usb_start_queue(struct data_queue *queue)
+{
+       struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+       u32 reg;
+
+       switch (queue->qid) {
+       case QID_RX:
+               rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+               rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 0);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+               break;
+       case QID_BEACON:
+               rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+               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);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+               break;
+       default:
+               break;
+       }
+}
+
+static void rt73usb_stop_queue(struct data_queue *queue)
+{
+       struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+       u32 reg;
+
+       switch (queue->qid) {
+       case QID_RX:
+               rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+               rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+               break;
+       case QID_BEACON:
+               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);
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+               break;
+       default:
+               break;
+       }
+}
+
 /*
  * Firmware functions
  */
@@ -1115,11 +1129,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
        /*
         * Write firmware to device.
         */
-       rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
-                                           USB_VENDOR_REQUEST_OUT,
-                                           FIRMWARE_IMAGE_BASE,
-                                           data, len,
-                                           REGISTER_TIMEOUT32(len));
+       rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, data, len);
 
        /*
         * Send firmware request to device to load firmware,
@@ -1231,8 +1241,7 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
        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);
        rt2x00usb_register_write(rt2x00dev, PHY_CSR1, reg);
 
@@ -1352,18 +1361,6 @@ static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)
 /*
  * Device state switch handlers.
  */
-static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
-                             enum dev_state state)
-{
-       u32 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));
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-}
-
 static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
        /*
@@ -1390,7 +1387,7 @@ static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 
 static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 {
-       u32 reg;
+       u32 reg, reg2;
        unsigned int i;
        char put_to_sleep;
 
@@ -1407,10 +1404,11 @@ 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++) {
-               rt2x00usb_register_read(rt2x00dev, MAC_CSR12, &reg);
-               state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR12, &reg2);
+               state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
                if (state == !put_to_sleep)
                        return 0;
+               rt2x00usb_register_write(rt2x00dev, MAC_CSR12, reg);
                msleep(10);
        }
 
@@ -1429,14 +1427,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
        case STATE_RADIO_OFF:
                rt73usb_disable_radio(rt2x00dev);
                break;
-       case STATE_RADIO_RX_ON:
-       case STATE_RADIO_RX_ON_LINK:
-       case STATE_RADIO_RX_OFF:
-       case STATE_RADIO_RX_OFF_LINK:
-               rt73usb_toggle_rx(rt2x00dev, state);
-               break;
        case STATE_RADIO_IRQ_ON:
+       case STATE_RADIO_IRQ_ON_ISR:
        case STATE_RADIO_IRQ_OFF:
+       case STATE_RADIO_IRQ_OFF_ISR:
                /* No support, but no error either */
                break;
        case STATE_DEEP_SLEEP:
@@ -1460,45 +1454,16 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 /*
  * TX descriptor initialization
  */
-static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                 struct sk_buff *skb,
+static void rt73usb_write_tx_desc(struct queue_entry *entry,
                                  struct txentry_desc *txdesc)
 {
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-       __le32 *txd = skbdesc->desc;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       __le32 *txd = (__le32 *) entry->skb->data;
        u32 word;
 
        /*
         * Start writing the descriptor words.
         */
-       rt2x00_desc_read(txd, 1, &word);
-       rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
-       rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
-       rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
-       rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
-       rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
-       rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
-                          test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
-       rt2x00_desc_write(txd, 1, word);
-
-       rt2x00_desc_read(txd, 2, &word);
-       rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal);
-       rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service);
-       rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low);
-       rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high);
-       rt2x00_desc_write(txd, 2, word);
-
-       if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) {
-               _rt2x00_desc_write(txd, 3, skbdesc->iv[0]);
-               _rt2x00_desc_write(txd, 4, skbdesc->iv[1]);
-       }
-
-       rt2x00_desc_read(txd, 5, &word);
-       rt2x00_set_field32(&word, TXD_W5_TX_POWER,
-                          TXPOWER_TO_DEV(rt2x00dev->tx_power));
-       rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
-       rt2x00_desc_write(txd, 5, word);
-
        rt2x00_desc_read(txd, 0, &word);
        rt2x00_set_field32(&word, TXD_W0_BURST,
                           test_bit(ENTRY_TXD_BURST, &txdesc->flags));
@@ -1519,48 +1484,102 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
                           test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
        rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
-       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
+       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
        rt2x00_set_field32(&word, TXD_W0_BURST2,
                           test_bit(ENTRY_TXD_BURST, &txdesc->flags));
        rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
        rt2x00_desc_write(txd, 0, word);
+
+       rt2x00_desc_read(txd, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
+       rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
+       rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+       rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
+       rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
+       rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
+                          test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
+       rt2x00_desc_write(txd, 1, word);
+
+       rt2x00_desc_read(txd, 2, &word);
+       rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal);
+       rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service);
+       rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low);
+       rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high);
+       rt2x00_desc_write(txd, 2, word);
+
+       if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) {
+               _rt2x00_desc_write(txd, 3, skbdesc->iv[0]);
+               _rt2x00_desc_write(txd, 4, skbdesc->iv[1]);
+       }
+
+       rt2x00_desc_read(txd, 5, &word);
+       rt2x00_set_field32(&word, TXD_W5_TX_POWER,
+                          TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
+       rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
+       rt2x00_desc_write(txd, 5, word);
+
+       /*
+        * Register descriptor details in skb frame descriptor.
+        */
+       skbdesc->flags |= SKBDESC_DESC_IN_SKB;
+       skbdesc->desc = txd;
+       skbdesc->desc_len = TXD_DESC_SIZE;
 }
 
 /*
  * TX data initialization
  */
-static void rt73usb_write_beacon(struct queue_entry *entry)
+static void rt73usb_write_beacon(struct queue_entry *entry,
+                                struct txentry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        unsigned int beacon_base;
+       unsigned int padding_len;
        u32 reg;
 
-       /*
-        * Add the descriptor in front of the skb.
-        */
-       skb_push(entry->skb, entry->queue->desc_size);
-       memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
-       skbdesc->desc = entry->skb->data;
-
        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        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);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
        /*
-        * Write entire beacon with descriptor to register.
+        * Add space for the descriptor in front of the skb.
+        */
+       skb_push(entry->skb, TXD_DESC_SIZE);
+       memset(entry->skb->data, 0, TXD_DESC_SIZE);
+
+       /*
+        * Write the TX descriptor for the beacon.
+        */
+       rt73usb_write_tx_desc(entry, txdesc);
+
+       /*
+        * Dump beacon to userspace through debugfs.
         */
+       rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+       /*
+        * Write entire beacon with descriptor and padding to register.
+        */
+       padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
+       skb_pad(entry->skb, padding_len);
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
-       rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
-                                           USB_VENDOR_REQUEST_OUT, beacon_base,
-                                           entry->skb->data, entry->skb->len,
-                                           REGISTER_TIMEOUT32(entry->skb->len));
+       rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+                                     entry->skb->len + padding_len);
+
+       /*
+        * Enable beaconing again.
+        *
+        * For Wi-Fi faily generated beacons between participating stations.
+        * Set TBTT phase adaptive adjustment step to 8us (default 16us)
+        */
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
        /*
         * Clean up the beacon skb.
@@ -1569,43 +1588,45 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
        entry->skb = NULL;
 }
 
-static int rt73usb_get_tx_data_len(struct queue_entry *entry)
+static void rt73usb_clear_beacon(struct queue_entry *entry)
 {
-       int length;
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       unsigned int beacon_base;
+       u32 reg;
 
        /*
-        * The length _must_ be a multiple of 4,
-        * but it must _not_ be a multiple of the USB packet size.
+        * Disable beaconing while we are reloading the beacon data,
+        * otherwise we might be sending out invalid data.
         */
-       length = roundup(entry->skb->len, 4);
-       length += (4 * !(length % entry->queue->usb_maxpacket));
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
-       return length;
+       /*
+        * Clear beacon.
+        */
+       beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+       rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
+
+       /*
+        * Enable beaconing again.
+        */
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 }
 
-static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
-                                 const enum data_queue_qid queue)
+static int rt73usb_get_tx_data_len(struct queue_entry *entry)
 {
-       u32 reg;
-
-       if (queue != QID_BEACON) {
-               rt2x00usb_kick_tx_queue(rt2x00dev, queue);
-               return;
-       }
+       int length;
 
        /*
-        * For Wi-Fi faily generated beacons between participating stations.
-        * Set TBTT phase adaptive adjustment step to 8us (default 16us)
+        * The length _must_ be a multiple of 4,
+        * but it must _not_ be a multiple of the USB packet size.
         */
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+       length = roundup(entry->skb->len, 4);
+       length += (4 * !(length % entry->queue->usb_maxpacket));
 
-       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);
-               rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-       }
+       return length;
 }
 
 /*
@@ -1631,7 +1652,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
                return 0;
        }
 
-       if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+       if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
                if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
                        if (lna == 3 || lna == 2)
                                offset += 10;
@@ -1671,12 +1692,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
        if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
                rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
-       if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
-               rxdesc->cipher =
-                   rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
-               rxdesc->cipher_status =
-                   rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
-       }
+       rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
+       rxdesc->cipher_status = rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
 
        if (rxdesc->cipher != CIPHER_NONE) {
                _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]);
@@ -1688,7 +1705,7 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
 
                /*
                 * Hardware has stripped IV/EIV data from 802.11 frame during
-                * decryption. It has provided the data seperately but rt2x00lib
+                * decryption. It has provided the data separately but rt2x00lib
                 * should decide if it should be reinserted.
                 */
                rxdesc->flags |= RX_FLAG_IV_STRIPPED;
@@ -1847,17 +1864,18 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
        rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
-       rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
+       rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
+                       value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
 
-       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
+       if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 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;
        }
@@ -1879,10 +1897,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Detect if this device has an hardware controlled radio.
         */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
        if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
                __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
        /*
         * Read frequency offset.
@@ -2086,13 +2102,17 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 
        /*
         * Initialize all hw fields.
+        *
+        * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
+        * capable of sending the buffered frames out after the DTIM
+        * transmission using rt2x00lib_beacondone. This will send out
+        * multicast and broadcast traffic immediately instead of buffering it
+        * infinitly and thus dropping it after some time.
         */
        rt2x00dev->hw->flags =
-           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
            IEEE80211_HW_SIGNAL_DBM |
            IEEE80211_HW_SUPPORTS_PS |
            IEEE80211_HW_PS_NULLFUNC_STACK;
-       rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
        SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2105,17 +2125,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;
@@ -2124,20 +2144,24 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        /*
         * Create channel information array
         */
-       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
 
        spec->channels_info = info;
 
        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
-       for (i = 0; i < 14; i++)
-               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+       for (i = 0; i < 14; i++) {
+               info[i].max_power = MAX_TXPOWER;
+               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+       }
 
        if (spec->num_channels > 14) {
                tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
-               for (i = 14; i < spec->num_channels; i++)
-                       info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               for (i = 14; i < spec->num_channels; i++) {
+                       info[i].max_power = MAX_TXPOWER;
+                       info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               }
        }
 
        return 0;
@@ -2165,13 +2189,20 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
        if (retval)
                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);
+       __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+       __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
 
        /*
         * Set the rssi offset.
@@ -2241,13 +2272,6 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
        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;
@@ -2261,9 +2285,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
 
        return tsf;
 }
-#else
-#define rt73usb_get_tsf        NULL
-#endif
 
 static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .tx                     = rt2x00mac_tx,
@@ -2272,14 +2293,17 @@ 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,
+       .sw_scan_start          = rt2x00mac_sw_scan_start,
+       .sw_scan_complete       = rt2x00mac_sw_scan_complete,
        .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,
+       .flush                  = rt2x00mac_flush,
 };
 
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2295,12 +2319,15 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .link_stats             = rt73usb_link_stats,
        .reset_tuner            = rt73usb_reset_tuner,
        .link_tuner             = rt73usb_link_tuner,
+       .watchdog               = rt2x00usb_watchdog,
+       .start_queue            = rt73usb_start_queue,
+       .kick_queue             = rt2x00usb_kick_queue,
+       .stop_queue             = rt73usb_stop_queue,
+       .flush_queue            = rt2x00usb_flush_queue,
        .write_tx_desc          = rt73usb_write_tx_desc,
-       .write_tx_data          = rt2x00usb_write_tx_data,
        .write_beacon           = rt73usb_write_beacon,
+       .clear_beacon           = rt73usb_clear_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,
@@ -2312,40 +2339,41 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 };
 
 static const struct data_queue_desc rt73usb_queue_rx = {
-       .entry_num              = RX_ENTRIES,
+       .entry_num              = 32,
        .data_size              = DATA_FRAME_SIZE,
        .desc_size              = RXD_DESC_SIZE,
        .priv_size              = sizeof(struct queue_entry_priv_usb),
 };
 
 static const struct data_queue_desc rt73usb_queue_tx = {
-       .entry_num              = TX_ENTRIES,
+       .entry_num              = 32,
        .data_size              = DATA_FRAME_SIZE,
        .desc_size              = TXD_DESC_SIZE,
        .priv_size              = sizeof(struct queue_entry_priv_usb),
 };
 
 static const struct data_queue_desc rt73usb_queue_bcn = {
-       .entry_num              = 4 * BEACON_ENTRIES,
+       .entry_num              = 4,
        .data_size              = MGMT_FRAME_SIZE,
        .desc_size              = TXINFO_SIZE,
        .priv_size              = sizeof(struct queue_entry_priv_usb),
 };
 
 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 */
 };
 
@@ -2354,7 +2382,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 */
@@ -2367,9 +2406,16 @@ 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) },
+       { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* CEIVA */
+       { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
        /* CNet */
        { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
@@ -2382,6 +2428,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 */
@@ -2390,6 +2441,7 @@ 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 */
@@ -2397,27 +2449,47 @@ static struct usb_device_id rt73usb_device_table[] = {
        { 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) },
+       { USB_DEVICE(0x0812, 0x3101), 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, }
 };