]> err.no Git - linux-2.6/blobdiff - drivers/net/wireless/rt2x00/rt61pci.c
rt2x00: Add new D-Link USB ID
[linux-2.6] / drivers / net / wireless / rt2x00 / rt61pci.c
index 19ae8f49d9c8d112b53a9224a155e1e64c1889ae..93ea212fedd51358f7e893688186895e7f858c58 100644 (file)
        Supported chipsets: RT2561, RT2561s, RT2661.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt61pci"
-
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -322,7 +317,8 @@ static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type,
         */
        rt2x00pci_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_TBTT_ENABLE,
+                         (tsf_sync == TSF_SYNC_BEACON));
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, tsf_sync);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
@@ -422,40 +418,24 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
        rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
        rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
-                         !rt2x00_rf(&rt2x00dev->chip, RF5225));
-
-       /*
-        * Configure the TX antenna.
-        */
-       switch (ant->tx) {
-       case ANTENNA_A:
-               rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
-               break;
-       case ANTENNA_SW_DIVERSITY:
-       case ANTENNA_HW_DIVERSITY:
-               /*
-                * NOTE: We should never come here because rt2x00lib is
-                * supposed to catch this and send us the correct antenna
-                * explicitely. However we are nog going to bug about this.
-                * Instead, just default to antenna B.
-                */
-       case ANTENNA_B:
-               rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
-               break;
-       }
+                         rt2x00_rf(&rt2x00dev->chip, RF5325));
 
        /*
         * Configure the RX antenna.
         */
        switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
                                  (rt2x00dev->curr_hwmode != HWMODE_A));
                break;
        case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+               if (rt2x00dev->curr_hwmode == HWMODE_A)
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+               else
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                break;
        case ANTENNA_SW_DIVERSITY:
                /*
@@ -465,8 +445,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
                 * Instead, just default to antenna B.
                 */
        case ANTENNA_B:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+               if (rt2x00dev->curr_hwmode == HWMODE_A)
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+               else
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                break;
        }
 
@@ -487,39 +471,20 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
        rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
        rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
-                         !rt2x00_rf(&rt2x00dev->chip, RF2527));
+                         rt2x00_rf(&rt2x00dev->chip, RF2529));
        rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
                          !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
 
-       /*
-        * Configure the TX antenna.
-        */
-       switch (ant->tx) {
-       case ANTENNA_A:
-               rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
-               break;
-       case ANTENNA_SW_DIVERSITY:
-       case ANTENNA_HW_DIVERSITY:
-               /*
-                * NOTE: We should never come here because rt2x00lib is
-                * supposed to catch this and send us the correct antenna
-                * explicitely. However we are nog going to bug about this.
-                * Instead, just default to antenna B.
-                */
-       case ANTENNA_B:
-               rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
-               break;
-       }
-
        /*
         * Configure the RX antenna.
         */
        switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
                break;
        case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                break;
        case ANTENNA_SW_DIVERSITY:
                /*
@@ -529,7 +494,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
                 * Instead, just default to antenna B.
                 */
        case ANTENNA_B:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                break;
        }
 
@@ -545,62 +511,38 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
 
        rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
 
-       if (p1 != 0xff) {
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT4, !!p1);
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT12, 0);
-               rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
-       }
-       if (p2 != 0xff) {
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT3, !p2);
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT11, 0);
-               rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
-       }
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT4, p1);
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT12, 0);
+
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT3, !p2);
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT11, 0);
+
+       rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
 }
 
 static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
                                        struct antenna_setup *ant)
 {
-       u16 eeprom;
        u8 r3;
        u8 r4;
        u8 r77;
-       u8 rx_ant;
 
        rt61pci_bbp_read(rt2x00dev, 3, &r3);
        rt61pci_bbp_read(rt2x00dev, 4, &r4);
        rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
-       rx_ant = !!(rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) & 2);
-
-       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
-
-       /*
-        * Configure the TX antenna.
+       /* FIXME: Antenna selection for the rf 2529 is very confusing in the
+        * legacy driver. The code below should be ok for non-diversity setups.
         */
-       switch (ant->tx) {
-       case ANTENNA_A:
-               rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
-               break;
-       case ANTENNA_SW_DIVERSITY:
-       case ANTENNA_HW_DIVERSITY:
-               /*
-                * NOTE: We should never come here because rt2x00lib is
-                * supposed to catch this and send us the correct antenna
-                * explicitely. However we are nog going to bug about this.
-                * Instead, just default to antenna B.
-                */
-       case ANTENNA_B:
-               rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
-               break;
-       }
 
        /*
         * Configure the RX antenna.
         */
        switch (ant->rx) {
        case ANTENNA_A:
-               rt61pci_config_antenna_2529_rx(rt2x00dev, 0, rx_ant);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+               rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
                break;
        case ANTENNA_SW_DIVERSITY:
        case ANTENNA_HW_DIVERSITY:
@@ -611,27 +553,12 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
                 * Instead, just default to antenna B.
                 */
        case ANTENNA_B:
-               rt61pci_config_antenna_2529_rx(rt2x00dev, 1, rx_ant);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+               rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
                break;
        }
 
-       /*
-        * FIXME: We are using the default antenna setup to
-        * determine the remaining settings. This because we
-        * need to know what the EEPROM indicated.
-        * It is however unclear if this is required, and overall
-        * using the default antenna settings here is incorrect
-        * since mac80211 might have told us to use fixed settings.
-        */
-       if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-       else
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-
-       rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-                         (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) &&
-                         (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY));
-
        rt61pci_bbp_write(rt2x00dev, 77, r77);
        rt61pci_bbp_write(rt2x00dev, 3, r3);
        rt61pci_bbp_write(rt2x00dev, 4, r4);
@@ -676,8 +603,6 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
        unsigned int i;
        u32 reg;
 
-       rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
-
        if (rt2x00dev->curr_hwmode == HWMODE_A) {
                sel = antenna_sel_a;
                lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
@@ -686,15 +611,17 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
                lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
        }
 
+       for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
+               rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
+
+       rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
+
        rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG,
                           (rt2x00dev->curr_hwmode == HWMODE_B ||
                            rt2x00dev->curr_hwmode == HWMODE_G));
        rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A,
                           (rt2x00dev->curr_hwmode == HWMODE_A));
 
-       for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
-               rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
-
        rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
 
        if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
@@ -1062,80 +989,52 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
        return 0;
 }
 
-static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
+                                struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00dev->rx;
-       struct data_desc *rxd;
-       unsigned int i;
+       __le32 *rxd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
+       rt2x00_desc_read(rxd, 5, &word);
+       rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
+                          entry->data_dma);
+       rt2x00_desc_write(rxd, 5, word);
 
-       for (i = 0; i < ring->stats.limit; i++) {
-               rxd = ring->entry[i].priv;
-
-               rt2x00_desc_read(rxd, 5, &word);
-               rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(rxd, 5, word);
-
-               rt2x00_desc_read(rxd, 0, &word);
-               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-               rt2x00_desc_write(rxd, 0, word);
-       }
-
-       rt2x00_ring_index_clear(rt2x00dev->rx);
+       rt2x00_desc_read(rxd, 0, &word);
+       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+       rt2x00_desc_write(rxd, 0, word);
 }
 
-static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
+static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
+                                struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
-       struct data_desc *txd;
-       unsigned int i;
+       __le32 *txd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               txd = ring->entry[i].priv;
-
-               rt2x00_desc_read(txd, 1, &word);
-               rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
-               rt2x00_desc_write(txd, 1, word);
-
-               rt2x00_desc_read(txd, 5, &word);
-               rt2x00_set_field32(&word, TXD_W5_PID_TYPE, queue);
-               rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, i);
-               rt2x00_desc_write(txd, 5, word);
+       rt2x00_desc_read(txd, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
+       rt2x00_desc_write(txd, 1, word);
 
-               rt2x00_desc_read(txd, 6, &word);
-               rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(txd, 6, word);
+       rt2x00_desc_read(txd, 5, &word);
+       rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx);
+       rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx);
+       rt2x00_desc_write(txd, 5, word);
 
-               rt2x00_desc_read(txd, 0, &word);
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-               rt2x00_desc_write(txd, 0, word);
-       }
+       rt2x00_desc_read(txd, 6, &word);
+       rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
+                          entry->data_dma);
+       rt2x00_desc_write(txd, 6, word);
 
-       rt2x00_ring_index_clear(ring);
+       rt2x00_desc_read(txd, 0, &word);
+       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+       rt2x00_desc_write(txd, 0, word);
 }
 
 static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
 
-       /*
-        * Initialize rings.
-        */
-       rt61pci_init_rxring(rt2x00dev);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA2);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA3);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA4);
-
        /*
         * Initialize registers.
         */
@@ -1583,8 +1482,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
                rt61pci_disable_radio(rt2x00dev);
                break;
        case STATE_RADIO_RX_ON:
+       case STATE_RADIO_RX_ON_LINK:
+               rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+               break;
        case STATE_RADIO_RX_OFF:
-               rt61pci_toggle_rx(rt2x00dev, state);
+       case STATE_RADIO_RX_OFF_LINK:
+               rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
                break;
        case STATE_DEEP_SLEEP:
        case STATE_SLEEP:
@@ -1604,12 +1507,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                 struct data_desc *txd,
-                                 struct txdata_entry_desc *desc,
-                                 struct ieee80211_hdr *ieee80211hdr,
-                                 unsigned int length,
-                                 struct ieee80211_tx_control *control)
+                                   struct sk_buff *skb,
+                                   struct txdata_entry_desc *desc,
+                                   struct ieee80211_tx_control *control)
 {
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       __le32 *txd = skbdesc->desc;
        u32 word;
 
        /*
@@ -1638,7 +1541,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_desc_write(txd, 5, word);
 
        rt2x00_desc_read(txd, 11, &word);
-       rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, length);
+       rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len);
        rt2x00_desc_write(txd, 11, word);
 
        rt2x00_desc_read(txd, 0, &word);
@@ -1647,7 +1550,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
                           test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_ACK,
-                          !(control->flags & IEEE80211_TXCTL_NO_ACK));
+                          test_bit(ENTRY_TXD_ACK, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_OFDM,
@@ -1657,7 +1560,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                           !!(control->flags &
                              IEEE80211_TXCTL_LONG_RETRY_LIMIT));
        rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
-       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
+       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_set_field32(&word, TXD_W0_BURST,
                           test_bit(ENTRY_TXD_BURST, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
@@ -1748,7 +1651,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 static void rt61pci_fill_rxdone(struct data_entry *entry,
                                struct rxdata_entry_desc *desc)
 {
-       struct data_desc *rxd = entry->priv;
+       __le32 *rxd = entry->priv;
        u32 word0;
        u32 word1;
 
@@ -1766,8 +1669,7 @@ static void rt61pci_fill_rxdone(struct data_entry *entry,
        desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);
        desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
-
-       return;
+       desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 }
 
 /*
@@ -1778,7 +1680,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
        struct data_ring *ring;
        struct data_entry *entry;
        struct data_entry *entry_done;
-       struct data_desc *txd;
+       __le32 *txd;
        u32 word;
        u32 reg;
        u32 old_reg;
@@ -1838,7 +1740,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
                        WARNING(rt2x00dev,
                                "TX status report missed for entry %p\n",
                                entry_done);
-                       rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0);
+                       rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
+                                        0);
                        entry_done = rt2x00_get_data_entry_done(ring);
                }
 
@@ -1848,24 +1751,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
                tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT);
                retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
 
-               rt2x00lib_txdone(entry, tx_status, retry);
-
-               /*
-                * Make this entry available for reuse.
-                */
-               entry->flags = 0;
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_desc_write(txd, 0, word);
-               rt2x00_ring_index_done_inc(entry->ring);
-
-               /*
-                * If the data ring was full before the txdone handler
-                * we must make sure the packet queue in the mac80211 stack
-                * is reenabled when the txdone handler has finished.
-                */
-               if (!rt2x00_ring_full(ring))
-                       ieee80211_wake_queue(rt2x00dev->hw,
-                                            entry->tx_status.control.queue);
+               rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
        }
 }
 
@@ -2398,7 +2284,6 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,
                                     struct dev_addr_list *mc_list)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct interface *intf = &rt2x00dev->interface;
        u32 reg;
 
        /*
@@ -2417,22 +2302,19 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
-        * - Some filters are set based on interface type.
+        * - Multicast filter seems to kill broadcast traffic so never use it.
         */
-       if (mc_count)
-               *total_flags |= FIF_ALLMULTI;
+       *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
-       if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
-               *total_flags |= FIF_PROMISC_IN_BSS;
 
        /*
         * Check if there is any work left for us.
         */
-       if (intf->filter == *total_flags)
+       if (rt2x00dev->packet_filter == *total_flags)
                return;
-       intf->filter = *total_flags;
+       rt2x00dev->packet_filter = *total_flags;
 
        /*
         * Start configuration steps.
@@ -2499,6 +2381,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                          struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
 
        /*
         * Just in case the ieee80211 doesn't set this,
@@ -2506,6 +2391,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
 
        /*
         * We need to append the descriptor in front of the
@@ -2519,15 +2406,23 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        /*
-        * First we create the beacon.
+        * Add the descriptor in front of the skb.
+        */
+       skb_push(skb, ring->desc_size);
+       memset(skb->data, 0, ring->desc_size);
+
+       /*
+        * Fill in skb descriptor
         */
-       skb_push(skb, TXD_DESC_SIZE);
-       memset(skb->data, 0, TXD_DESC_SIZE);
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        TXD_DESC_SIZE),
-                               skb->len - TXD_DESC_SIZE, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Write entire beacon with descriptor to register,
@@ -2551,7 +2446,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
        .configure_filter       = rt61pci_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt61pci_set_retry_limit,
-       .erp_ie_changed         = rt2x00mac_erp_ie_changed,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt61pci_get_tsf,
@@ -2566,6 +2461,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
        .load_firmware          = rt61pci_load_firmware,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
+       .init_rxentry           = rt61pci_init_rxentry,
+       .init_txentry           = rt61pci_init_txentry,
        .set_device_state       = rt61pci_set_device_state,
        .rfkill_poll            = rt61pci_rfkill_poll,
        .link_stats             = rt61pci_link_stats,
@@ -2583,7 +2480,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
 };
 
 static const struct rt2x00_ops rt61pci_ops = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .rxd_size       = RXD_DESC_SIZE,
        .txd_size       = TXD_DESC_SIZE,
        .eeprom_size    = EEPROM_SIZE,
@@ -2620,7 +2517,7 @@ MODULE_FIRMWARE(FIRMWARE_RT2661);
 MODULE_LICENSE("GPL");
 
 static struct pci_driver rt61pci_driver = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .id_table       = rt61pci_device_table,
        .probe          = rt2x00pci_probe,
        .remove         = __devexit_p(rt2x00pci_remove),