diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index d10a8012f387..2822684c505e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -100,8 +100,21 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
100 | { | 100 | { |
101 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 101 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
102 | 102 | ||
103 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, | 103 | /* |
104 | DMA_TO_DEVICE); | 104 | * If device has requested headroom, we should make sure that |
105 | * is also mapped to the DMA so it can be used for transfering | ||
106 | * additional descriptor information to the hardware. | ||
107 | */ | ||
108 | skb_push(skb, rt2x00dev->hw->extra_tx_headroom); | ||
109 | |||
110 | skbdesc->skb_dma = | ||
111 | dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); | ||
112 | |||
113 | /* | ||
114 | * Restore data pointer to original location again. | ||
115 | */ | ||
116 | skb_pull(skb, rt2x00dev->hw->extra_tx_headroom); | ||
117 | |||
105 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | 118 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; |
106 | } | 119 | } |
107 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); | 120 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); |
@@ -117,7 +130,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
117 | } | 130 | } |
118 | 131 | ||
119 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { | 132 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { |
120 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | 133 | /* |
134 | * Add headroom to the skb length, it has been removed | ||
135 | * by the driver, but it was actually mapped to DMA. | ||
136 | */ | ||
137 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, | ||
138 | skb->len + rt2x00dev->hw->extra_tx_headroom, | ||
121 | DMA_TO_DEVICE); | 139 | DMA_TO_DEVICE); |
122 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; | 140 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; |
123 | } | 141 | } |