]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/rt2x00/rt2x00queue.c
Merge branch 'core-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / rt2x00 / rt2x00queue.c
index c0f97c53e5ce5aabfb8d675142364ed376fef62f..451d410ecdae4fae126ab835bdadd5647a4f13b8 100644 (file)
@@ -100,8 +100,21 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
 {
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
 
-       skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len,
-                                         DMA_TO_DEVICE);
+       /*
+        * If device has requested headroom, we should make sure that
+        * is also mapped to the DMA so it can be used for transfering
+        * additional descriptor information to the hardware.
+        */
+       skb_push(skb, rt2x00dev->hw->extra_tx_headroom);
+
+       skbdesc->skb_dma =
+           dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+
+       /*
+        * Restore data pointer to original location again.
+        */
+       skb_pull(skb, rt2x00dev->hw->extra_tx_headroom);
+
        skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
@@ -117,7 +130,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
        }
 
        if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
-               dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+               /*
+                * Add headroom to the skb length, it has been removed
+                * by the driver, but it was actually mapped to DMA.
+                */
+               dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
+                                skb->len + rt2x00dev->hw->extra_tx_headroom,
                                 DMA_TO_DEVICE);
                skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
        }
@@ -137,7 +155,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
-       struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
        struct ieee80211_rate *rate =
            ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
@@ -260,16 +277,22 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
         * sequence counter given by mac80211.
         */
        if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               spin_lock_irqsave(&intf->seqlock, irqflags);
+               if (likely(tx_info->control.vif)) {
+                       struct rt2x00_intf *intf;
+
+                       intf = vif_to_intf(tx_info->control.vif);
+
+                       spin_lock_irqsave(&intf->seqlock, irqflags);
 
-               if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
-                       intf->seqno += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
+                       if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
+                               intf->seqno += 0x10;
+                       hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+                       hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
 
-               spin_unlock_irqrestore(&intf->seqlock, irqflags);
+                       spin_unlock_irqrestore(&intf->seqlock, irqflags);
 
-               __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
+                       __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
+               }
        }
 
        /*
@@ -351,12 +374,12 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct txentry_desc txdesc;
        struct skb_frame_desc *skbdesc;
-       unsigned int iv_len = IEEE80211_SKB_CB(skb)->control.iv_len;
+       unsigned int iv_len = 0;
 
        if (unlikely(rt2x00queue_full(queue)))
                return -EINVAL;
 
-       if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
+       if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
                ERROR(queue->rt2x00dev,
                      "Arrived at non-free entry in the non-full queue %d.\n"
                      "Please file bug report to %s.\n",
@@ -372,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        entry->skb = skb;
        rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
+       if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
+               iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+
        /*
         * All information is retreived from the skb->cb array,
         * now we should claim ownership of the driver part of that
@@ -387,8 +413,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
         * the frame so we can provide it to the driver seperately.
         */
        if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
-           !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags))
+           !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
                rt2x00crypto_tx_remove_iv(skb, iv_len);
+       }
 
        /*
         * It could be possible that the queue was corrupted and this
@@ -396,7 +423,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
         * the frame to mac80211 because the skb->cb has now been tainted.
         */
        if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
-               __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+               clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
                dev_kfree_skb_any(entry->skb);
                entry->skb = NULL;
                return 0;
@@ -405,7 +432,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
                rt2x00queue_map_txskb(queue->rt2x00dev, skb);
 
-       __set_bit(ENTRY_DATA_PENDING, &entry->flags);
+       set_bit(ENTRY_DATA_PENDING, &entry->flags);
 
        rt2x00queue_index_inc(queue, Q_INDEX);
        rt2x00queue_write_tx_descriptor(entry, &txdesc);
@@ -718,6 +745,7 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
 
        queue->rt2x00dev = rt2x00dev;
        queue->qid = qid;
+       queue->txop = 0;
        queue->aifs = 2;
        queue->cw_min = 5;
        queue->cw_max = 10;