]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/wireless/rt2x00/rt2800lib.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / net / wireless / rt2x00 / rt2800lib.c
index 5f00e00789d823bad28752516a4789da7057d8f9..54917a28139813713904cc03e9f77c67f40e7588 100644 (file)
@@ -277,13 +277,17 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
        unsigned int i;
        u32 reg;
 
+       /*
+        * Some devices are really slow to respond here. Wait a whole second
+        * before timing out.
+        */
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
                if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
                    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
                        return 0;
 
-               msleep(1);
+               msleep(10);
        }
 
        ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
@@ -483,7 +487,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
                           txdesc->key_idx : 0xff);
        rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
                           txdesc->length);
-       rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid);
+       rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid);
        rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
        rt2x00_desc_write(txwi, 1, word);
 
@@ -727,7 +731,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
         * that the TX_STA_FIFO stack has a size of 16. We stick to our
         * tx ring size for now.
         */
-       for (i = 0; i < TX_ENTRIES; i++) {
+       for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
                rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
                if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
                        break;
@@ -768,6 +772,7 @@ void rt2800_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;
 
        /*
@@ -802,11 +807,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
        rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
 
        /*
-        * Write entire beacon with TXWI to register.
+        * Write entire beacon with TXWI 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);
-       rt2800_register_multiwrite(rt2x00dev, beacon_base,
-                                  entry->skb->data, entry->skb->len);
+       rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
+                                  entry->skb->len + padding_len);
 
        /*
         * Enable beaconing again.
@@ -824,7 +831,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 }
 EXPORT_SYMBOL_GPL(rt2800_write_beacon);
 
-static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
+static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
                                       unsigned int beacon_base)
 {
        int i;
@@ -1144,6 +1151,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
                        struct rt2x00intf_conf *conf, const unsigned int flags)
 {
        u32 reg;
+       bool update_bssid = false;
 
        if (flags & CONFIG_UPDATE_TYPE) {
                /*
@@ -1173,6 +1181,16 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
        }
 
        if (flags & CONFIG_UPDATE_MAC) {
+               if (flags & CONFIG_UPDATE_TYPE &&
+                   conf->sync == TSF_SYNC_AP_NONE) {
+                       /*
+                        * The BSSID register has to be set to our own mac
+                        * address in AP mode.
+                        */
+                       memcpy(conf->bssid, conf->mac, sizeof(conf->mac));
+                       update_bssid = true;
+               }
+
                if (!is_zero_ether_addr((const u8 *)conf->mac)) {
                        reg = le32_to_cpu(conf->mac[1]);
                        rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
@@ -1183,7 +1201,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
                                              conf->mac, sizeof(conf->mac));
        }
 
-       if (flags & CONFIG_UPDATE_BSSID) {
+       if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) {
                if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
                        reg = le32_to_cpu(conf->bssid[1]);
                        rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
@@ -1529,7 +1547,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
            rt2x00_rf(rt2x00dev, RF3020) ||
            rt2x00_rf(rt2x00dev, RF3021) ||
            rt2x00_rf(rt2x00dev, RF3022) ||
-           rt2x00_rf(rt2x00dev, RF3052))
+           rt2x00_rf(rt2x00dev, RF3052) ||
+           rt2x00_rf(rt2x00dev, RF3320))
                rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
        else
                rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -1609,6 +1628,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        }
 
        msleep(1);
+
+       /*
+        * Clear channel statistic counters
+        */
+       rt2800_register_read(rt2x00dev, CH_IDLE_STA, &reg);
+       rt2800_register_read(rt2x00dev, CH_BUSY_STA, &reg);
+       rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
 }
 
 static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
@@ -1914,8 +1940,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
                if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
                    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
                    rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
-                       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
-                       if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
+                       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+                       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
                                rt2800_register_write(rt2x00dev, TX_SW_CFG2,
                                                      0x0000002c);
                        else
@@ -2097,7 +2123,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
                rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
        }
 
-       rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+       /*
+        * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1
+        * although it is reserved.
+        */
+       rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, &reg);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
+       rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0);
+       rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
+
        rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
 
        rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
@@ -2134,7 +2176,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
                                         SHARED_KEY_MODE_ENTRY(i), 0);
 
        for (i = 0; i < 256; i++) {
-               u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+               static const u32 wcid[2] = { 0xffffffff, 0x00ffffff };
                rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
                                              wcid, sizeof(wcid));
 
@@ -2227,6 +2269,17 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4);
        rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
 
+       /*
+        * Set up channel statistics timer
+        */
+       rt2800_register_read(rt2x00dev, CH_TIME_CFG, &reg);
+       rt2x00_set_field32(&reg, CH_TIME_CFG_EIFS_BUSY, 1);
+       rt2x00_set_field32(&reg, CH_TIME_CFG_NAV_BUSY, 1);
+       rt2x00_set_field32(&reg, CH_TIME_CFG_RX_BUSY, 1);
+       rt2x00_set_field32(&reg, CH_TIME_CFG_TX_BUSY, 1);
+       rt2x00_set_field32(&reg, CH_TIME_CFG_TMR_EN, 1);
+       rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg);
+
        return 0;
 }
 
@@ -2344,10 +2397,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
            rt2x00_rt(rt2x00dev, RT3390)) {
                rt2800_bbp_read(rt2x00dev, 138, &value);
 
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
-               if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
                        value |= 0x20;
-               if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
                        value &= ~0x02;
 
                rt2800_bbp_write(rt2x00dev, 138, value);
@@ -2559,8 +2612,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
                if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
                    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
-                       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
-                       if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
+                       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+                       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
                                rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
                        else
                                rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
@@ -2633,10 +2686,10 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
        if (rt2x00_rt(rt2x00dev, RT3090)) {
                rt2800_bbp_read(rt2x00dev, 138, &bbp);
 
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
-               if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
                        rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
-               if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
                        rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1);
 
                rt2800_bbp_write(rt2x00dev, 138, bbp);
@@ -2735,16 +2788,16 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize LED control
         */
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
-       rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
+       rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
                           word & 0xff, (word >> 8) & 0xff);
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
-       rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
+       rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
                           word & 0xff, (word >> 8) & 0xff);
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
-       rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
+       rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
                           word & 0xff, (word >> 8) & 0xff);
 
        return 0;
@@ -2838,38 +2891,41 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
                EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
        if (word == 0xffff) {
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
-               rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
                EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
        } else if (rt2x00_rt(rt2x00dev, RT2860) ||
                   rt2x00_rt(rt2x00dev, RT2872)) {
                /*
                 * There is a max of 2 RX streams for RT28x0 series
                 */
-               if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
-                       rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
-               rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+               if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
+                       rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
        }
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
        if (word == 0xffff) {
-               rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0);
-               rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0);
-               rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_CARDBUS_ACCEL, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_2G, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_5G, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_WPS_PBC, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_2G, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_5G, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BROADBAND_EXT_LNA, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_ANT_DIVERSITY, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
                EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
        }
 
@@ -2884,9 +2940,9 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
                                   LED_MODE_TXRX_ACTIVITY);
                rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
                rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
-               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
-               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
-               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
                EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word);
        }
 
@@ -2950,12 +3006,12 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Read EEPROM word for configuration.
         */
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
 
        /*
         * Identify RF chipset.
         */
-       value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+       value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
        rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
 
        rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
@@ -2981,7 +3037,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
            !rt2x00_rf(rt2x00dev, RF2020) &&
            !rt2x00_rf(rt2x00dev, RF3021) &&
            !rt2x00_rf(rt2x00dev, RF3022) &&
-           !rt2x00_rf(rt2x00dev, RF3052)) {
+           !rt2x00_rf(rt2x00dev, RF3052) &&
+           !rt2x00_rf(rt2x00dev, RF3320)) {
                ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
                return -ENODEV;
        }
@@ -2990,9 +3047,9 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
         * Identify default antenna configuration.
         */
        rt2x00dev->default_ant.tx =
-           rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
+           rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH);
        rt2x00dev->default_ant.rx =
-           rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
+           rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
 
        /*
         * Read frequency offset and RF programming sequence.
@@ -3003,17 +3060,17 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Read external LNA informations.
         */
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
 
-       if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
                __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-       if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
                __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
 
        /*
         * Detect if this device has an hardware controlled radio.
         */
-       if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO))
                __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
 
        /*
@@ -3225,7 +3282,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        rt2x00dev->hw->max_report_rates = 7;
        rt2x00dev->hw->max_rate_tries = 1;
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
 
        /*
         * Initialize hw_mode information.
@@ -3245,7 +3302,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        } else if (rt2x00_rf(rt2x00dev, RF3020) ||
                   rt2x00_rf(rt2x00dev, RF2020) ||
                   rt2x00_rf(rt2x00dev, RF3021) ||
-                  rt2x00_rf(rt2x00dev, RF3022)) {
+                  rt2x00_rf(rt2x00dev, RF3022) ||
+                  rt2x00_rf(rt2x00dev, RF3320)) {
                spec->num_channels = 14;
                spec->channels = rf_vals_3x;
        } else if (rt2x00_rf(rt2x00dev, RF3052)) {
@@ -3268,11 +3326,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
            IEEE80211_HT_CAP_SGI_20 |
            IEEE80211_HT_CAP_SGI_40;
 
-       if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2)
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2)
                spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC;
 
        spec->ht.cap |=
-           rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) <<
+           rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) <<
                IEEE80211_HT_CAP_RX_STBC_SHIFT;
 
        spec->ht.ampdu_factor = 3;
@@ -3280,10 +3338,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        spec->ht.mcs.tx_params =
            IEEE80211_HT_MCS_TX_DEFINED |
            IEEE80211_HT_MCS_TX_RX_DIFF |
-           ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+           ((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) <<
                IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
 
-       switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+       switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) {
        case 3:
                spec->ht.mcs.rx_mask[2] = 0xff;
        case 2:
@@ -3502,6 +3560,37 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 }
 EXPORT_SYMBOL_GPL(rt2800_ampdu_action);
 
+int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
+                     struct survey_info *survey)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+       u32 idle, busy, busy_ext;
+
+       if (idx != 0)
+               return -ENOENT;
+
+       survey->channel = conf->channel;
+
+       rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle);
+       rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy);
+       rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext);
+
+       if (idle || busy) {
+               survey->filled = SURVEY_INFO_CHANNEL_TIME |
+                                SURVEY_INFO_CHANNEL_TIME_BUSY |
+                                SURVEY_INFO_CHANNEL_TIME_EXT_BUSY;
+
+               survey->channel_time = (idle + busy) / 1000;
+               survey->channel_time_busy = busy / 1000;
+               survey->channel_time_ext_busy = busy_ext / 1000;
+       }
+
+       return 0;
+
+}
+EXPORT_SYMBOL_GPL(rt2800_get_survey);
+
 MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("Ralink RT2800 library");