diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2011-07-27 10:20:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-28 01:39:31 -0400 |
commit | 0d681b27b0efc962a3038a316e78373de7bfe1ce (patch) | |
tree | 0ff87deba13d372b5f8262e741dc121c0e07f32f | |
parent | 13350ea78bd687a229af0f6052d2f45aa50a6524 (diff) |
tg3: Generalize tg3_skb_error_unmap()
In the following patches, unmapping skb fragments will get just as
complicated as mapping them. This patch generalizes
tg3_skb_error_unmap() and makes it the one-stop-shop for skb unmapping.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/tg3.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0f5bcf79d727..3f69f1ace267 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -5913,13 +5913,15 @@ static inline void tg3_tx_set_bd(struct tg3_napi *tnapi, u32 entry, | |||
5913 | txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT); | 5913 | txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT); |
5914 | } | 5914 | } |
5915 | 5915 | ||
5916 | static void tg3_skb_error_unmap(struct tg3_napi *tnapi, | 5916 | static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) |
5917 | struct sk_buff *skb, int last) | ||
5918 | { | 5917 | { |
5919 | int i; | 5918 | int i; |
5920 | u32 entry = tnapi->tx_prod; | 5919 | struct sk_buff *skb; |
5921 | struct tg3_tx_ring_info *txb = &tnapi->tx_buffers[entry]; | 5920 | struct tg3_tx_ring_info *txb = &tnapi->tx_buffers[entry]; |
5922 | 5921 | ||
5922 | skb = txb->skb; | ||
5923 | txb->skb = NULL; | ||
5924 | |||
5923 | pci_unmap_single(tnapi->tp->pdev, | 5925 | pci_unmap_single(tnapi->tp->pdev, |
5924 | dma_unmap_addr(txb, mapping), | 5926 | dma_unmap_addr(txb, mapping), |
5925 | skb_headlen(skb), | 5927 | skb_headlen(skb), |
@@ -6227,7 +6229,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6227 | } | 6229 | } |
6228 | 6230 | ||
6229 | if (would_hit_hwbug) { | 6231 | if (would_hit_hwbug) { |
6230 | tg3_skb_error_unmap(tnapi, skb, i); | 6232 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); |
6231 | 6233 | ||
6232 | /* If the workaround fails due to memory/mapping | 6234 | /* If the workaround fails due to memory/mapping |
6233 | * failure, silently drop this packet. | 6235 | * failure, silently drop this packet. |
@@ -6264,7 +6266,7 @@ out_unlock: | |||
6264 | return NETDEV_TX_OK; | 6266 | return NETDEV_TX_OK; |
6265 | 6267 | ||
6266 | dma_error: | 6268 | dma_error: |
6267 | tg3_skb_error_unmap(tnapi, skb, i); | 6269 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); |
6268 | dev_kfree_skb(skb); | 6270 | dev_kfree_skb(skb); |
6269 | tnapi->tx_buffers[tnapi->tx_prod].skb = NULL; | 6271 | tnapi->tx_buffers[tnapi->tx_prod].skb = NULL; |
6270 | return NETDEV_TX_OK; | 6272 | return NETDEV_TX_OK; |
@@ -6597,35 +6599,13 @@ static void tg3_free_rings(struct tg3 *tp) | |||
6597 | if (!tnapi->tx_buffers) | 6599 | if (!tnapi->tx_buffers) |
6598 | continue; | 6600 | continue; |
6599 | 6601 | ||
6600 | for (i = 0; i < TG3_TX_RING_SIZE; ) { | 6602 | for (i = 0; i < TG3_TX_RING_SIZE; i++) { |
6601 | struct tg3_tx_ring_info *txp; | 6603 | struct sk_buff *skb = tnapi->tx_buffers[i].skb; |
6602 | struct sk_buff *skb; | ||
6603 | unsigned int k; | ||
6604 | 6604 | ||
6605 | txp = &tnapi->tx_buffers[i]; | 6605 | if (!skb) |
6606 | skb = txp->skb; | ||
6607 | |||
6608 | if (skb == NULL) { | ||
6609 | i++; | ||
6610 | continue; | 6606 | continue; |
6611 | } | ||
6612 | 6607 | ||
6613 | pci_unmap_single(tp->pdev, | 6608 | tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags); |
6614 | dma_unmap_addr(txp, mapping), | ||
6615 | skb_headlen(skb), | ||
6616 | PCI_DMA_TODEVICE); | ||
6617 | txp->skb = NULL; | ||
6618 | |||
6619 | i++; | ||
6620 | |||
6621 | for (k = 0; k < skb_shinfo(skb)->nr_frags; k++) { | ||
6622 | txp = &tnapi->tx_buffers[i & (TG3_TX_RING_SIZE - 1)]; | ||
6623 | pci_unmap_page(tp->pdev, | ||
6624 | dma_unmap_addr(txp, mapping), | ||
6625 | skb_shinfo(skb)->frags[k].size, | ||
6626 | PCI_DMA_TODEVICE); | ||
6627 | i++; | ||
6628 | } | ||
6629 | 6609 | ||
6630 | dev_kfree_skb_any(skb); | 6610 | dev_kfree_skb_any(skb); |
6631 | } | 6611 | } |
@@ -11358,6 +11338,10 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) | |||
11358 | return -EIO; | 11338 | return -EIO; |
11359 | } | 11339 | } |
11360 | 11340 | ||
11341 | val = tnapi->tx_prod; | ||
11342 | tnapi->tx_buffers[val].skb = skb; | ||
11343 | dma_unmap_addr_set(&tnapi->tx_buffers[val], mapping, map); | ||
11344 | |||
11361 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | 11345 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | |
11362 | rnapi->coal_now); | 11346 | rnapi->coal_now); |
11363 | 11347 | ||
@@ -11389,7 +11373,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) | |||
11389 | break; | 11373 | break; |
11390 | } | 11374 | } |
11391 | 11375 | ||
11392 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); | 11376 | tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0); |
11393 | dev_kfree_skb(skb); | 11377 | dev_kfree_skb(skb); |
11394 | 11378 | ||
11395 | if (tx_idx != tnapi->tx_prod) | 11379 | if (tx_idx != tnapi->tx_prod) |