aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43legacy/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43legacy/dma.c')
-rw-r--r--drivers/net/wireless/b43legacy/dma.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 866403415811..e91520d0312e 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -37,6 +37,7 @@
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <linux/slab.h>
40#include <net/dst.h> 41#include <net/dst.h>
41 42
42/* 32bit DMA ops. */ 43/* 32bit DMA ops. */
@@ -1240,8 +1241,9 @@ struct b43legacy_dmaring *parse_cookie(struct b43legacy_wldev *dev,
1240} 1241}
1241 1242
1242static int dma_tx_fragment(struct b43legacy_dmaring *ring, 1243static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1243 struct sk_buff *skb) 1244 struct sk_buff **in_skb)
1244{ 1245{
1246 struct sk_buff *skb = *in_skb;
1245 const struct b43legacy_dma_ops *ops = ring->ops; 1247 const struct b43legacy_dma_ops *ops = ring->ops;
1246 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1248 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1247 u8 *header; 1249 u8 *header;
@@ -1305,8 +1307,14 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1305 } 1307 }
1306 1308
1307 memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); 1309 memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
1310 memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb));
1311 bounce_skb->dev = skb->dev;
1312 skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb));
1313 info = IEEE80211_SKB_CB(bounce_skb);
1314
1308 dev_kfree_skb_any(skb); 1315 dev_kfree_skb_any(skb);
1309 skb = bounce_skb; 1316 skb = bounce_skb;
1317 *in_skb = bounce_skb;
1310 meta->skb = skb; 1318 meta->skb = skb;
1311 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); 1319 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1312 if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { 1320 if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
@@ -1360,8 +1368,10 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1360 struct sk_buff *skb) 1368 struct sk_buff *skb)
1361{ 1369{
1362 struct b43legacy_dmaring *ring; 1370 struct b43legacy_dmaring *ring;
1371 struct ieee80211_hdr *hdr;
1363 int err = 0; 1372 int err = 0;
1364 unsigned long flags; 1373 unsigned long flags;
1374 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1365 1375
1366 ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); 1376 ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
1367 spin_lock_irqsave(&ring->lock, flags); 1377 spin_lock_irqsave(&ring->lock, flags);
@@ -1386,7 +1396,11 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1386 goto out_unlock; 1396 goto out_unlock;
1387 } 1397 }
1388 1398
1389 err = dma_tx_fragment(ring, skb); 1399 /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
1400 * into the skb data or cb now. */
1401 hdr = NULL;
1402 info = NULL;
1403 err = dma_tx_fragment(ring, &skb);
1390 if (unlikely(err == -ENOKEY)) { 1404 if (unlikely(err == -ENOKEY)) {
1391 /* Drop this packet, as we don't have the encryption key 1405 /* Drop this packet, as we don't have the encryption key
1392 * anymore and must not transmit it unencrypted. */ 1406 * anymore and must not transmit it unencrypted. */
@@ -1398,7 +1412,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1398 b43legacyerr(dev->wl, "DMA tx mapping failure\n"); 1412 b43legacyerr(dev->wl, "DMA tx mapping failure\n");
1399 goto out_unlock; 1413 goto out_unlock;
1400 } 1414 }
1401 ring->nr_tx_packets++;
1402 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1415 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1403 should_inject_overflow(ring)) { 1416 should_inject_overflow(ring)) {
1404 /* This TX ring is full. */ 1417 /* This TX ring is full. */
@@ -1514,25 +1527,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1514 spin_unlock(&ring->lock); 1527 spin_unlock(&ring->lock);
1515} 1528}
1516 1529
1517void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
1518 struct ieee80211_tx_queue_stats *stats)
1519{
1520 const int nr_queues = dev->wl->hw->queues;
1521 struct b43legacy_dmaring *ring;
1522 unsigned long flags;
1523 int i;
1524
1525 for (i = 0; i < nr_queues; i++) {
1526 ring = priority_to_txring(dev, i);
1527
1528 spin_lock_irqsave(&ring->lock, flags);
1529 stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
1530 stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
1531 stats[i].count = ring->nr_tx_packets;
1532 spin_unlock_irqrestore(&ring->lock, flags);
1533 }
1534}
1535
1536static void dma_rx(struct b43legacy_dmaring *ring, 1530static void dma_rx(struct b43legacy_dmaring *ring,
1537 int *slot) 1531 int *slot)
1538{ 1532{