}
                txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
-               rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
+               rt2x00lib_txdone(entry, &txdesc);
        }
 }
 
 
                }
                txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
-               rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
+               rt2x00lib_txdone(entry, &txdesc);
        }
 }
 
 
        return ((size * 8 * 10) % rate);
 }
 
-/**
- * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @queue: The queue for which the skb will be applicable.
- */
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
-                                       struct queue_entry *entry);
-
 /**
  * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  */
 void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
 
-/**
- * rt2x00queue_unmap_skb - Unmap a skb from DMA.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to unmap.
- */
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
-
-/**
- * rt2x00queue_free_skb - free a skb
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to free.
- */
-void rt2x00queue_free_skb(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.
 struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
                                          enum queue_index index);
 
-/**
- * rt2x00queue_index_inc - Index incrementation function
- * @queue: Queue (&struct data_queue) to perform the action on.
- * @index: Index type (&enum queue_index) to perform the action on.
- *
- * This function will increase the requested index on the queue,
- * it will grab the appropriate locks and handle queue overflow events by
- * resetting the index to the start of the queue.
- */
-void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
-
-
 /*
  * Interrupt context handlers.
  */
 
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+       enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
+
+       /*
+        * Unmap the skb.
+        */
+       rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
 
        /*
         * Send frame to debugfs immediately, after this call is completed
                ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
        else
                dev_kfree_skb_irq(entry->skb);
+
+       /*
+        * Make this entry available for reuse.
+        */
        entry->skb = NULL;
+       entry->flags = 0;
+
+       rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
+
+       __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+       rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+
+       /*
+        * If the data queue was below the threshold before the txdone
+        * handler we must make sure the packet queue in the mac80211 stack
+        * is reenabled when the txdone handler has finished.
+        */
+       if (!rt2x00queue_threshold(entry->queue))
+               ieee80211_wake_queue(rt2x00dev->hw, qid);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
 
         * Replace the skb with the freshly allocated one.
         */
        entry->skb = skb;
+       entry->flags = 0;
+
+       rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
+
+       rt2x00queue_index_inc(entry->queue, Q_INDEX);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
 
 
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                      struct ieee80211_conf *conf, const int force_config);
 
-/*
- * Queue handlers.
+/**
+ * DOC: Queue handlers
+ */
+
+/**
+ * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @queue: The queue for which the skb will be applicable.
+ */
+struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
+                                       struct queue_entry *entry);
+
+/**
+ * rt2x00queue_unmap_skb - Unmap a skb from DMA.
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to unmap.
+ */
+void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_free_skb - free a skb
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to free.
+ */
+void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_free_skb - free a skb
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to free.
+ */
+void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_write_tx_frame - Write TX frame to hardware
+ * @queue: Queue over which the frame should be send
+ * @skb: The skb to send
  */
 int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_index_inc - Index incrementation function
+ * @queue: Queue (&struct data_queue) to perform the action on.
+ * @index: Index type (&enum queue_index) to perform the action on.
+ *
+ * This function will increase the requested index on the queue,
+ * it will grab the appropriate locks and handle queue overflow events by
+ * resetting the index to the start of the queue.
+ */
+void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
+
 void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
 void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
 int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
 
         * Fill in skb descriptor
         */
        skbdesc = get_skb_frame_desc(entry->skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->desc = entry_priv->desc;
        skbdesc->desc_len = entry->queue->desc_size;
-       skbdesc->entry = entry;
-
-       rt2x00queue_map_txskb(entry->queue->rt2x00dev, entry->skb);
 
        return 0;
 }
                 * Send the frame to rt2x00lib for further processing.
                 */
                rt2x00lib_rxdone(rt2x00dev, entry);
-
-               /*
-                * Reset the RXD for this entry.
-                */
-               rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
-
-               rt2x00queue_index_inc(queue, Q_INDEX);
        }
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
 
-void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
-                     struct txdone_entry_desc *txdesc)
-{
-       struct queue_entry_priv_pci *entry_priv = entry->priv_data;
-       enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
-       u32 word;
-
-       /*
-        * Unmap the skb.
-        */
-       rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
-
-       rt2x00lib_txdone(entry, txdesc);
-
-       /*
-        * Make this entry available for reuse.
-        */
-       entry->flags = 0;
-
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0);
-       rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
-
-       __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-       rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
-
-       /*
-        * If the data queue was below the threshold before the txdone
-        * handler we must make sure the packet queue in the mac80211 stack
-        * is reenabled when the txdone handler has finished.
-        */
-       if (!rt2x00queue_threshold(entry->queue))
-               ieee80211_wake_queue(rt2x00dev->hw, qid);
-
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
-
 /*
  * Device initialization handlers.
  */
 
  */
 void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
 
-/**
- * rt2x00pci_txdone - Handle TX done events
- * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
- * @entry: Entry which has completed the transmission of a frame.
- * @desc: TX done descriptor
- */
-void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
-                     struct txdone_entry_desc *desc);
-
 /*
  * Device initialization handlers.
  */
 
 
        return skb;
 }
-EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb);
 
 void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
 {
                skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
        }
 }
-EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
 
 void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
 {
 
        dev_kfree_skb_any(skb);
 }
-EXPORT_SYMBOL_GPL(rt2x00queue_free_skb);
 
 void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
                                      struct txentry_desc *txdesc)
 {
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct txentry_desc txdesc;
+       struct skb_frame_desc *skbdesc;
 
        if (unlikely(rt2x00queue_full(queue)))
                return -EINVAL;
        entry->skb = skb;
        rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
+       /*
+        * skb->cb array is now ours and we are free to use it.
+        */
+       skbdesc = get_skb_frame_desc(entry->skb);
+       memset(skbdesc, 0, sizeof(*skbdesc));
+       skbdesc->entry = entry;
+
        if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
                __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
                return -EIO;
        }
 
+       if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
+               rt2x00queue_map_txskb(queue->rt2x00dev, skb);
+
        __set_bit(ENTRY_DATA_PENDING, &entry->flags);
 
        rt2x00queue_index_inc(queue, Q_INDEX);
 
        spin_unlock_irqrestore(&queue->lock, irqflags);
 }
-EXPORT_SYMBOL_GPL(rt2x00queue_index_inc);
 
 static void rt2x00queue_reset(struct data_queue *queue)
 {
 
 /**
  * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc
  *
+ * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
+ * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
  */
 enum skb_frame_desc_flags {
        SKBDESC_DMA_MAPPED_RX = (1 << 0),
 
        struct queue_entry *entry = (struct queue_entry *)urb->context;
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct txdone_entry_desc txdesc;
-       enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
 
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
-           !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+           !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
                return;
 
        /*
        txdesc.retry = 0;
 
        rt2x00lib_txdone(entry, &txdesc);
-
-       /*
-        * Make this entry available for reuse.
-        */
-       entry->flags = 0;
-       rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
-
-       /*
-        * If the data queue was below the threshold before the txdone
-        * handler we must make sure the packet queue in the mac80211 stack
-        * is reenabled when the txdone handler has finished.
-        */
-       if (!rt2x00queue_threshold(entry->queue))
-               ieee80211_wake_queue(rt2x00dev->hw, qid);
 }
 
 int rt2x00usb_write_tx_data(struct queue_entry *entry)
         * Fill in skb descriptor
         */
        skbdesc = get_skb_frame_desc(entry->skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->desc = entry->skb->data;
        skbdesc->desc_len = entry->queue->desc_size;
-       skbdesc->entry = entry;
 
        /*
         * USB devices cannot blindly pass the skb->len as the
        u8 rxd[32];
 
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
-           !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+           !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
                return;
 
        /*
         * to be actually valid, or if the urb is signaling
         * a problem.
         */
-       if (urb->actual_length < entry->queue->desc_size || urb->status)
-               goto skip_entry;
+       if (urb->actual_length < entry->queue->desc_size || urb->status) {
+               __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+               usb_submit_urb(urb, GFP_ATOMIC);
+               return;
+       }
 
        /*
         * Fill in desc fields of the skb descriptor
         * Send the frame to rt2x00lib for further processing.
         */
        rt2x00lib_rxdone(rt2x00dev, entry);
-
-       /*
-        * Reinitialize the urb.
-        */
-       urb->transfer_buffer = entry->skb->data;
-       urb->transfer_buffer_length = entry->skb->len;
-
-skip_entry:
-       if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) {
-               __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-               usb_submit_urb(urb, GFP_ATOMIC);
-       }
-
-       rt2x00queue_index_inc(entry->queue, Q_INDEX);
 }
 
 /*
 
                        __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
                        txdesc.retry = 0;
 
-                       rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc);
+                       rt2x00lib_txdone(entry_done, &txdesc);
                        entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
                }
 
                }
                txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
 
-               rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
+               rt2x00lib_txdone(entry, &txdesc);
        }
 }