/*
  * TX data initialization
  */
+static void rt2400pci_write_beacon(struct queue_entry *entry)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       u32 word;
+       u32 reg;
+
+       /*
+        * Disable beaconing while we are reloading the beacon data,
+        * otherwise we might be sending out invalid data.
+        */
+       rt2x00pci_register_read(rt2x00dev, CSR14, ®);
+       rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
+       rt2x00_set_field32(®, CSR14_TBCN, 0);
+       rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
+       rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+       /*
+        * Replace rt2x00lib allocated descriptor with the
+        * pointer to the _real_ hardware descriptor.
+        * After that, map the beacon to DMA and update the
+        * descriptor.
+        */
+       memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
+       skbdesc->desc = entry_priv->desc;
+
+       rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+
+       rt2x00_desc_read(entry_priv->desc, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+       rt2x00_desc_write(entry_priv->desc, 1, word);
+}
+
 static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
                                    const enum data_queue_qid queue)
 {
        return tsf;
 }
 
-static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
-       struct queue_entry_priv_pci *entry_priv;
-       struct skb_frame_desc *skbdesc;
-       struct txentry_desc txdesc;
-       u32 reg;
-
-       if (unlikely(!intf->beacon))
-               return -ENOBUFS;
-       entry_priv = intf->beacon->priv_data;
-
-       /*
-        * Copy all TX descriptor information into txdesc,
-        * after that we are free to use the skb->cb array
-        * for our information.
-        */
-       intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
-
-       /*
-        * Fill in skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-       skbdesc->desc = entry_priv->desc;
-       skbdesc->desc_len = intf->beacon->queue->desc_size;
-       skbdesc->entry = intf->beacon;
-
-       /*
-        * Disable beaconing while we are reloading the beacon data,
-        * otherwise we might be sending out invalid data.
-        */
-       rt2x00pci_register_read(rt2x00dev, CSR14, ®);
-       rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
-       rt2x00_set_field32(®, CSR14_TBCN, 0);
-       rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
-       rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-
-       /*
-        * Enable beacon generation.
-        * Write entire beacon with descriptor to register,
-        * and kick the beacon generator.
-        */
-       rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb);
-       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
-       rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
-
-       return 0;
-}
-
 static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        .link_tuner             = rt2400pci_link_tuner,
        .write_tx_desc          = rt2400pci_write_tx_desc,
        .write_tx_data          = rt2x00pci_write_tx_data,
+       .write_beacon           = rt2400pci_write_beacon,
        .kick_tx_queue          = rt2400pci_kick_tx_queue,
        .fill_rxdone            = rt2400pci_fill_rxdone,
-       .beacon_update          = rt2400pci_beacon_update,
        .config_filter          = rt2400pci_config_filter,
        .config_intf            = rt2400pci_config_intf,
        .config_erp             = rt2400pci_config_erp,
 
 /*
  * TX data initialization
  */
+static void rt2500pci_write_beacon(struct queue_entry *entry)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       u32 word;
+       u32 reg;
+
+       /*
+        * Disable beaconing while we are reloading the beacon data,
+        * otherwise we might be sending out invalid data.
+        */
+       rt2x00pci_register_read(rt2x00dev, CSR14, ®);
+       rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
+       rt2x00_set_field32(®, CSR14_TBCN, 0);
+       rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
+       rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+       /*
+        * Replace rt2x00lib allocated descriptor with the
+        * pointer to the _real_ hardware descriptor.
+        * After that, map the beacon to DMA and update the
+        * descriptor.
+        */
+       memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
+       skbdesc->desc = entry_priv->desc;
+
+       rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+
+       rt2x00_desc_read(entry_priv->desc, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+       rt2x00_desc_write(entry_priv->desc, 1, word);
+}
+
 static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
                                    const enum data_queue_qid queue)
 {
        return tsf;
 }
 
-static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
-       struct queue_entry_priv_pci *entry_priv;
-       struct skb_frame_desc *skbdesc;
-       struct txentry_desc txdesc;
-       u32 reg;
-
-       if (unlikely(!intf->beacon))
-               return -ENOBUFS;
-
-       entry_priv = intf->beacon->priv_data;
-
-       /*
-        * Copy all TX descriptor information into txdesc,
-        * after that we are free to use the skb->cb array
-        * for our information.
-        */
-       intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
-
-       /*
-        * Fill in skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-       skbdesc->desc = entry_priv->desc;
-       skbdesc->desc_len = intf->beacon->queue->desc_size;
-       skbdesc->entry = intf->beacon;
-
-       /*
-        * Disable beaconing while we are reloading the beacon data,
-        * otherwise we might be sending out invalid data.
-        */
-       rt2x00pci_register_read(rt2x00dev, CSR14, ®);
-       rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
-       rt2x00_set_field32(®, CSR14_TBCN, 0);
-       rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
-       rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-
-       /*
-        * Enable beacon generation.
-        * Write entire beacon with descriptor to register,
-        * and kick the beacon generator.
-        */
-       rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb);
-       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
-       rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
-
-       return 0;
-}
-
 static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        .link_tuner             = rt2500pci_link_tuner,
        .write_tx_desc          = rt2500pci_write_tx_desc,
        .write_tx_data          = rt2x00pci_write_tx_data,
+       .write_beacon           = rt2500pci_write_beacon,
        .kick_tx_queue          = rt2500pci_kick_tx_queue,
        .fill_rxdone            = rt2500pci_fill_rxdone,
-       .beacon_update          = rt2500pci_beacon_update,
        .config_filter          = rt2500pci_config_filter,
        .config_intf            = rt2500pci_config_intf,
        .config_erp             = rt2500pci_config_erp,
 
        rt2x00_desc_write(txd, 0, word);
 }
 
+/*
+ * TX data initialization
+ */
+static void rt2500usb_beacondone(struct urb *urb);
+
+static void rt2500usb_write_beacon(struct queue_entry *entry)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+       struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       int pipe = usb_sndbulkpipe(usb_dev, 1);
+       int length;
+       u16 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.
+        */
+       rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
+       rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0);
+       rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0);
+       rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0);
+       rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+
+       /*
+        * USB devices cannot blindly pass the skb->len as the
+        * length of the data to usb_fill_bulk_urb. Pass the skb
+        * to the driver to determine what the length should be.
+        */
+       length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);
+
+       usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe,
+                         entry->skb->data, length, rt2500usb_beacondone,
+                         entry);
+
+       /*
+        * Second we need to create the guardian byte.
+        * We only need a single byte, so lets recycle
+        * the 'flags' field we are not using for beacons.
+        */
+       bcn_priv->guardian_data = 0;
+       usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe,
+                         &bcn_priv->guardian_data, 1, rt2500usb_beacondone,
+                         entry);
+
+       /*
+        * Send out the guardian byte.
+        */
+       usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);
+}
+
 static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
                                     struct sk_buff *skb)
 {
        return length;
 }
 
-/*
- * TX data initialization
- */
 static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
                                    const enum data_queue_qid queue)
 {
        return 0;
 }
 
-/*
- * IEEE80211 stack callback functions.
- */
-static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
-       struct queue_entry_priv_usb_bcn *bcn_priv;
-       struct skb_frame_desc *skbdesc;
-       struct txentry_desc txdesc;
-       int pipe = usb_sndbulkpipe(usb_dev, 1);
-       int length;
-       u16 reg;
-
-       if (unlikely(!intf->beacon))
-               return -ENOBUFS;
-
-       bcn_priv = intf->beacon->priv_data;
-
-       /*
-        * Copy all TX descriptor information into txdesc,
-        * after that we are free to use the skb->cb array
-        * for our information.
-        */
-       intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
-
-       /*
-        * Add the descriptor in front of the skb.
-        */
-       skb_push(skb, intf->beacon->queue->desc_size);
-       memset(skb->data, 0, intf->beacon->queue->desc_size);
-
-       /*
-        * Fill in skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-       skbdesc->desc = skb->data;
-       skbdesc->desc_len = intf->beacon->queue->desc_size;
-       skbdesc->entry = intf->beacon;
-
-       /*
-        * Disable beaconing while we are reloading the beacon data,
-        * otherwise we might be sending out invalid data.
-        */
-       rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
-       rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0);
-       rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0);
-       rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0);
-       rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-
-       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
-
-       /*
-        * USB devices cannot blindly pass the skb->len as the
-        * length of the data to usb_fill_bulk_urb. Pass the skb
-        * to the driver to determine what the length should be.
-        */
-       length = rt2500usb_get_tx_data_len(rt2x00dev, skb);
-
-       usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe,
-                         skb->data, length, rt2500usb_beacondone,
-                         intf->beacon);
-
-       /*
-        * Second we need to create the guardian byte.
-        * We only need a single byte, so lets recycle
-        * the 'flags' field we are not using for beacons.
-        */
-       bcn_priv->guardian_data = 0;
-       usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe,
-                         &bcn_priv->guardian_data, 1, rt2500usb_beacondone,
-                         intf->beacon);
-
-       /*
-        * Send out the guardian byte.
-        */
-       usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);
-
-       /*
-        * Enable beacon generation.
-        */
-       rt2500usb_kick_tx_queue(rt2x00dev, QID_BEACON);
-
-       return 0;
-}
-
 static const struct ieee80211_ops rt2500usb_mac80211_ops = {
        .tx                     = rt2x00mac_tx,
        .start                  = rt2x00mac_start,
        .link_tuner             = rt2500usb_link_tuner,
        .write_tx_desc          = rt2500usb_write_tx_desc,
        .write_tx_data          = rt2x00usb_write_tx_data,
+       .write_beacon           = rt2500usb_write_beacon,
        .get_tx_data_len        = rt2500usb_get_tx_data_len,
        .kick_tx_queue          = rt2500usb_kick_tx_queue,
        .fill_rxdone            = rt2500usb_fill_rxdone,
-       .beacon_update          = rt2500usb_beacon_update,
        .config_filter          = rt2500usb_config_filter,
        .config_intf            = rt2500usb_config_intf,
        .config_erp             = rt2500usb_config_erp,
 
                               struct sk_buff *skb,
                               struct txentry_desc *txdesc);
        int (*write_tx_data) (struct queue_entry *entry);
+       void (*write_beacon) (struct queue_entry *entry);
        int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev,
                                struct sk_buff *skb);
        void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
        /*
         * Configuration handlers.
         */
-       int (*beacon_update) (struct ieee80211_hw *hw, struct sk_buff *bcn);
-
        void (*config_filter) (struct rt2x00_dev *rt2x00dev,
                               const unsigned int filter_flags);
        void (*config_intf) (struct rt2x00_dev *rt2x00dev,
  */
 void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
 
-/**
- * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
- * @entry: The entry which will be used to transfer the TX frame.
- * @txdesc: rt2x00 TX descriptor which will be initialized by this function.
- *
- * This function will initialize the &struct txentry_desc based on information
- * from mac80211. This descriptor can then be used by rt2x00lib and the drivers
- * to correctly initialize the hardware descriptor.
- * Note that before calling this function the skb->cb array must be untouched
- * by rt2x00lib. Only after this function completes will it be save to
- * overwrite the skb->cb information.
- * The reason for this is that mac80211 writes its own tx information into
- * the skb->cb array, and this function will use that information to initialize
- * the &struct txentry_desc structure.
- */
-void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
-                                     struct txentry_desc *txdesc);
-
-/**
- * rt2x00queue_write_tx_descriptor - Write TX descriptor to hardware
- * @entry: The entry which will be used to transfer the TX frame.
- * @txdesc: TX descriptor which will be used to write hardware descriptor
- *
- * This function will write a TX descriptor initialized by
- * &rt2x00queue_create_tx_descriptor to the hardware. After this call
- * has completed the frame is now owned by the hardware, the hardware
- * queue will have automatically be kicked unless this frame was generated
- * by rt2x00lib, in which case the frame is "special" and must be kicked
- * by the caller.
- */
-void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
-                                    struct txentry_desc *txdesc);
-
 /**
  * rt2x00queue_get_queue - Convert queue index to queue pointer
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
 
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
                return;
 
-       if (delayed_flags & DELAYED_UPDATE_BEACON) {
-               struct ieee80211_if_conf conf;
-               conf.bssid = conf.ssid = NULL;
-               conf.ssid_len = 0;
-               conf.changed = IEEE80211_IFCC_BEACON;
-               rt2x00dev->ops->hw->config_interface(rt2x00dev->hw, vif, &conf);
-       }
+       if (delayed_flags & DELAYED_UPDATE_BEACON)
+               rt2x00queue_update_beacon(rt2x00dev, vif);
 
        if (delayed_flags & DELAYED_CONFIG_ERP)
                rt2x00lib_config_erp(rt2x00dev, intf, &conf);
 
  */
 int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
 
+/**
+ * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @vif: Interface for which the beacon should be updated.
+ */
+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+                             struct ieee80211_vif *vif);
+
 /**
  * rt2x00queue_index_inc - Index incrementation function
  * @queue: Queue (&struct data_queue) to perform the action on.
 
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct rt2x00_intf *intf = vif_to_intf(vif);
-       struct sk_buff *beacon;
-       int status;
+       int update_bssid = 0;
+       int status = 0;
 
        /*
         * Mac80211 might be calling this function while we are trying
        spin_lock(&intf->lock);
 
        /*
-        * If the interface does not work in master mode,
-        * then the bssid value in the interface structure
-        * should now be set.
-        *
         * conf->bssid can be NULL if coming from the internal
         * beacon update routine.
         */
-       if (conf->bssid && vif->type != IEEE80211_IF_TYPE_AP)
+       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
+               update_bssid = 1;
                memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
+       }
 
        spin_unlock(&intf->lock);
 
         * values as arguments we make keep access to rt2x00_intf thread safe
         * even without the lock.
         */
-       rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, conf->bssid);
+       rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
+                             update_bssid ? conf->bssid : NULL);
 
        /*
-        * We only need to initialize the beacon when in master/ibss mode.
+        * Update the beacon.
         */
-       if ((vif->type != IEEE80211_IF_TYPE_AP &&
-            vif->type != IEEE80211_IF_TYPE_IBSS) ||
-           !(conf->changed & IEEE80211_IFCC_BEACON))
-               return 0;
-
-       beacon = ieee80211_beacon_get(rt2x00dev->hw, vif);
-       if (!beacon)
-               return -ENOMEM;
-
-       status = rt2x00dev->ops->lib->beacon_update(rt2x00dev->hw, beacon);
-       if (status)
-               dev_kfree_skb(beacon);
+       if (conf->changed & IEEE80211_IFCC_BEACON)
+               status = rt2x00queue_update_beacon(rt2x00dev, vif);
 
        return status;
 }
 
        dev_kfree_skb_any(skb);
 }
 
-void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
-                                     struct txentry_desc *txdesc)
+static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
+                                            struct txentry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
                        txdesc->signal |= 0x08;
        }
 }
-EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor);
 
-void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
-                                    struct txentry_desc *txdesc)
+static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
+                                           struct txentry_desc *txdesc)
 {
        struct data_queue *queue = entry->queue;
        struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
            !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
                rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
 }
-EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor);
 
 int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 {
        return 0;
 }
 
+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+                             struct ieee80211_vif *vif)
+{
+       struct rt2x00_intf *intf = vif_to_intf(vif);
+       struct skb_frame_desc *skbdesc;
+       struct txentry_desc txdesc;
+       __le32 desc[16];
+
+       if (unlikely(!intf->beacon))
+               return -ENOBUFS;
+
+       intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
+       if (!intf->beacon->skb)
+               return -ENOMEM;
+
+       /*
+        * Copy all TX descriptor information into txdesc,
+        * after that we are free to use the skb->cb array
+        * for our information.
+        */
+       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
+
+       /*
+        * For the descriptor we use a local array from where the
+        * driver can move it to the correct location required for
+        * the hardware.
+        */
+       memset(desc, 0, sizeof(desc));
+
+       /*
+        * Fill in skb descriptor
+        */
+       skbdesc = get_skb_frame_desc(intf->beacon->skb);
+       memset(skbdesc, 0, sizeof(*skbdesc));
+       skbdesc->desc = desc;
+       skbdesc->desc_len = intf->beacon->queue->desc_size;
+       skbdesc->entry = intf->beacon;
+
+       /*
+        * Write TX descriptor into reserved room in front of the beacon.
+        */
+       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
+
+       /*
+        * Send beacon to hardware.
+        * Also enable beacon generation, which might have been disabled
+        * by the driver during the config_beacon() callback function.
+        */
+       rt2x00dev->ops->lib->write_beacon(intf->beacon);
+       rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
+
+       return 0;
+}
+
 struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
                                         const enum data_queue_qid queue)
 {
 
 /*
  * TX data initialization
  */
+static void rt61pci_write_beacon(struct queue_entry *entry)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       unsigned int beacon_base;
+       u32 reg;
+
+       /*
+        * Disable beaconing while we are reloading the beacon data,
+        * otherwise we might be sending out invalid data.
+        */
+       rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
+       rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
+       rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
+       rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
+       rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+       /*
+        * Write entire beacon with descriptor to register.
+        */
+       beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+       rt2x00pci_register_multiwrite(rt2x00dev,
+                                     beacon_base,
+                                     skbdesc->desc, skbdesc->desc_len);
+       rt2x00pci_register_multiwrite(rt2x00dev,
+                                     beacon_base + skbdesc->desc_len,
+                                     entry->skb->data, entry->skb->len);
+
+       /*
+        * Clean up beacon skb.
+        */
+       dev_kfree_skb_any(entry->skb);
+       entry->skb = NULL;
+}
+
 static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
                                  const enum data_queue_qid queue)
 {
        return tsf;
 }
 
-static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
-       struct queue_entry_priv_pci *entry_priv;
-       struct skb_frame_desc *skbdesc;
-       struct txentry_desc txdesc;
-       unsigned int beacon_base;
-       u32 reg;
-
-       if (unlikely(!intf->beacon))
-               return -ENOBUFS;
-
-       /*
-        * Copy all TX descriptor information into txdesc,
-        * after that we are free to use the skb->cb array
-        * for our information.
-        */
-       intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
-
-       entry_priv = intf->beacon->priv_data;
-       memset(entry_priv->desc, 0, intf->beacon->queue->desc_size);
-
-       /*
-        * Fill in skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-       skbdesc->desc = entry_priv->desc;
-       skbdesc->desc_len = intf->beacon->queue->desc_size;
-       skbdesc->entry = intf->beacon;
-
-       /*
-        * Disable beaconing while we are reloading the beacon data,
-        * otherwise we might be sending out invalid data.
-        */
-       rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
-       rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
-       rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
-       rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
-       rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
-
-       /*
-        * Write entire beacon with descriptor to register,
-        * and kick the beacon generator.
-        */
-       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
-       beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
-       rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
-                                     skbdesc->desc, skbdesc->desc_len);
-       rt2x00pci_register_multiwrite(rt2x00dev,
-                                     beacon_base + skbdesc->desc_len,
-                                     skb->data, skb->len);
-       rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON);
-
-       /*
-        * Clean up beacon skb.
-        */
-       dev_kfree_skb_any(skb);
-       intf->beacon->skb = NULL;
-
-       return 0;
-}
-
 static const struct ieee80211_ops rt61pci_mac80211_ops = {
        .tx                     = rt2x00mac_tx,
        .start                  = rt2x00mac_start,
        .link_tuner             = rt61pci_link_tuner,
        .write_tx_desc          = rt61pci_write_tx_desc,
        .write_tx_data          = rt2x00pci_write_tx_data,
+       .write_beacon           = rt61pci_write_beacon,
        .kick_tx_queue          = rt61pci_kick_tx_queue,
        .fill_rxdone            = rt61pci_fill_rxdone,
-       .beacon_update          = rt61pci_beacon_update,
        .config_filter          = rt61pci_config_filter,
        .config_intf            = rt61pci_config_intf,
        .config_erp             = rt61pci_config_erp,
 
        rt2x00_desc_write(txd, 0, word);
 }
 
+/*
+ * TX data initialization
+ */
+static void rt73usb_write_beacon(struct queue_entry *entry)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       unsigned int beacon_base;
+       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.
+        */
+       rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
+       rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
+       rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
+       rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
+       rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+       /*
+        * Write entire beacon with descriptor to register.
+        */
+       beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+       rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
+                                USB_VENDOR_REQUEST_OUT, beacon_base, 0,
+                                entry->skb->data, entry->skb->len,
+                                REGISTER_TIMEOUT32(entry->skb->len));
+
+       /*
+        * Clean up the beacon skb.
+        */
+       dev_kfree_skb(entry->skb);
+       entry->skb = NULL;
+}
+
 static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
                                   struct sk_buff *skb)
 {
        return length;
 }
 
-/*
- * TX data initialization
- */
 static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
                                  const enum data_queue_qid queue)
 {
 #define rt73usb_get_tsf        NULL
 #endif
 
-static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
-       struct skb_frame_desc *skbdesc;
-       struct txentry_desc txdesc;
-       unsigned int beacon_base;
-       u32 reg;
-
-       if (unlikely(!intf->beacon))
-               return -ENOBUFS;
-
-       /*
-        * Copy all TX descriptor information into txdesc,
-        * after that we are free to use the skb->cb array
-        * for our information.
-        */
-       intf->beacon->skb = skb;
-       rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
-
-       /*
-        * Add the descriptor in front of the skb.
-        */
-       skb_push(skb, intf->beacon->queue->desc_size);
-       memset(skb->data, 0, intf->beacon->queue->desc_size);
-
-       /*
-        * Fill in skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-       skbdesc->desc = skb->data;
-       skbdesc->desc_len = intf->beacon->queue->desc_size;
-       skbdesc->entry = intf->beacon;
-
-       /*
-        * Disable beaconing while we are reloading the beacon data,
-        * otherwise we might be sending out invalid data.
-        */
-       rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
-       rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
-       rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
-       rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-
-       /*
-        * Write entire beacon with descriptor to register,
-        * and kick the beacon generator.
-        */
-       rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
-       beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
-       rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
-                                USB_VENDOR_REQUEST_OUT, beacon_base, 0,
-                                skb->data, skb->len,
-                                REGISTER_TIMEOUT32(skb->len));
-       rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON);
-
-       /*
-        * Clean up the beacon skb.
-        */
-       dev_kfree_skb(skb);
-       intf->beacon->skb = NULL;
-
-       return 0;
-}
-
 static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .tx                     = rt2x00mac_tx,
        .start                  = rt2x00mac_start,
        .link_tuner             = rt73usb_link_tuner,
        .write_tx_desc          = rt73usb_write_tx_desc,
        .write_tx_data          = rt2x00usb_write_tx_data,
+       .write_beacon           = rt73usb_write_beacon,
        .get_tx_data_len        = rt73usb_get_tx_data_len,
        .kick_tx_queue          = rt73usb_kick_tx_queue,
        .fill_rxdone            = rt73usb_fill_rxdone,
-       .beacon_update          = rt73usb_beacon_update,
        .config_filter          = rt73usb_config_filter,
        .config_intf            = rt73usb_config_intf,
        .config_erp             = rt73usb_config_erp,