diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/b43legacy/dma.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/b43legacy/dma.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 38 |
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 | ||
1242 | static int dma_tx_fragment(struct b43legacy_dmaring *ring, | 1243 | static 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 | ||
1517 | void 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 | |||
1536 | static void dma_rx(struct b43legacy_dmaring *ring, | 1530 | static void dma_rx(struct b43legacy_dmaring *ring, |
1537 | int *slot) | 1531 | int *slot) |
1538 | { | 1532 | { |