aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2011-11-04 05:15:00 -0400
committerDavid S. Miller <davem@davemloft.net>2011-11-04 17:31:47 -0400
commitba1142e4fb291c7bf124d93596351dca8d226a0f (patch)
treedc20e27d52a515cfad594d2d137e61a3983d7de5 /drivers
parentb9e454826f22e17d1945bd282834c87aef8d0f95 (diff)
tg3: Fix 4k skb error recovery path
On the error recovery resource unwind path, it is possible for the driver to attempt to unmap a fragment that hadn't been mapped. This patch fixes the problem by correcting the "last" parameter supplied. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 507b73b979fe..3a7517910eed 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6507,7 +6507,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
6507 txb = &tnapi->tx_buffers[entry]; 6507 txb = &tnapi->tx_buffers[entry];
6508 } 6508 }
6509 6509
6510 for (i = 0; i < last; i++) { 6510 for (i = 0; i <= last; i++) {
6511 const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 6511 const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
6512 6512
6513 entry = NEXT_TX(entry); 6513 entry = NEXT_TX(entry);
@@ -6568,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
6568 if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, 6568 if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
6569 new_skb->len, base_flags, 6569 new_skb->len, base_flags,
6570 mss, vlan)) { 6570 mss, vlan)) {
6571 tg3_tx_skb_unmap(tnapi, save_entry, 0); 6571 tg3_tx_skb_unmap(tnapi, save_entry, -1);
6572 dev_kfree_skb(new_skb); 6572 dev_kfree_skb(new_skb);
6573 ret = -1; 6573 ret = -1;
6574 } 6574 }
@@ -6758,11 +6758,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
6758 6758
6759 if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags | 6759 if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
6760 ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), 6760 ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
6761 mss, vlan)) 6761 mss, vlan)) {
6762 would_hit_hwbug = 1; 6762 would_hit_hwbug = 1;
6763
6764 /* Now loop through additional data fragments, and queue them. */ 6763 /* Now loop through additional data fragments, and queue them. */
6765 if (skb_shinfo(skb)->nr_frags > 0) { 6764 } else if (skb_shinfo(skb)->nr_frags > 0) {
6766 u32 tmp_mss = mss; 6765 u32 tmp_mss = mss;
6767 6766
6768 if (!tg3_flag(tp, HW_TSO_1) && 6767 if (!tg3_flag(tp, HW_TSO_1) &&
@@ -6831,7 +6830,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
6831 return NETDEV_TX_OK; 6830 return NETDEV_TX_OK;
6832 6831
6833dma_error: 6832dma_error:
6834 tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); 6833 tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
6835 tnapi->tx_buffers[tnapi->tx_prod].skb = NULL; 6834 tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
6836drop: 6835drop:
6837 dev_kfree_skb(skb); 6836 dev_kfree_skb(skb);
@@ -7284,7 +7283,8 @@ static void tg3_free_rings(struct tg3 *tp)
7284 if (!skb) 7283 if (!skb)
7285 continue; 7284 continue;
7286 7285
7287 tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags); 7286 tg3_tx_skb_unmap(tnapi, i,
7287 skb_shinfo(skb)->nr_frags - 1);
7288 7288
7289 dev_kfree_skb_any(skb); 7289 dev_kfree_skb_any(skb);
7290 } 7290 }
@@ -11523,7 +11523,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback)
11523 break; 11523 break;
11524 } 11524 }
11525 11525
11526 tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0); 11526 tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, -1);
11527 dev_kfree_skb(skb); 11527 dev_kfree_skb(skb);
11528 11528
11529 if (tx_idx != tnapi->tx_prod) 11529 if (tx_idx != tnapi->tx_prod)