aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2011-07-27 10:20:49 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-28 01:39:31 -0400
commit0d681b27b0efc962a3038a316e78373de7bfe1ce (patch)
tree0ff87deba13d372b5f8262e741dc121c0e07f32f
parent13350ea78bd687a229af0f6052d2f45aa50a6524 (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.c48
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
5916static void tg3_skb_error_unmap(struct tg3_napi *tnapi, 5916static 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
6266dma_error: 6268dma_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)