aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c47
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 35901630a65..507b73b979f 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6444,31 +6444,26 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
6444 hwbug = 1; 6444 hwbug = 1;
6445 6445
6446 if (tg3_flag(tp, 4K_FIFO_LIMIT)) { 6446 if (tg3_flag(tp, 4K_FIFO_LIMIT)) {
6447 u32 prvidx = *entry;
6447 u32 tmp_flag = flags & ~TXD_FLAG_END; 6448 u32 tmp_flag = flags & ~TXD_FLAG_END;
6448 while (len > TG3_TX_BD_DMA_MAX) { 6449 while (len > TG3_TX_BD_DMA_MAX && *budget) {
6449 u32 frag_len = TG3_TX_BD_DMA_MAX; 6450 u32 frag_len = TG3_TX_BD_DMA_MAX;
6450 len -= TG3_TX_BD_DMA_MAX; 6451 len -= TG3_TX_BD_DMA_MAX;
6451 6452
6452 if (len) { 6453 /* Avoid the 8byte DMA problem */
6453 tnapi->tx_buffers[*entry].fragmented = true; 6454 if (len <= 8) {
6454 /* Avoid the 8byte DMA problem */ 6455 len += TG3_TX_BD_DMA_MAX / 2;
6455 if (len <= 8) { 6456 frag_len = TG3_TX_BD_DMA_MAX / 2;
6456 len += TG3_TX_BD_DMA_MAX / 2;
6457 frag_len = TG3_TX_BD_DMA_MAX / 2;
6458 }
6459 } else
6460 tmp_flag = flags;
6461
6462 if (*budget) {
6463 tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
6464 frag_len, tmp_flag, mss, vlan);
6465 (*budget)--;
6466 *entry = NEXT_TX(*entry);
6467 } else {
6468 hwbug = 1;
6469 break;
6470 } 6457 }
6471 6458
6459 tnapi->tx_buffers[*entry].fragmented = true;
6460
6461 tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
6462 frag_len, tmp_flag, mss, vlan);
6463 *budget -= 1;
6464 prvidx = *entry;
6465 *entry = NEXT_TX(*entry);
6466
6472 map += frag_len; 6467 map += frag_len;
6473 } 6468 }
6474 6469
@@ -6476,10 +6471,11 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
6476 if (*budget) { 6471 if (*budget) {
6477 tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, 6472 tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
6478 len, flags, mss, vlan); 6473 len, flags, mss, vlan);
6479 (*budget)--; 6474 *budget -= 1;
6480 *entry = NEXT_TX(*entry); 6475 *entry = NEXT_TX(*entry);
6481 } else { 6476 } else {
6482 hwbug = 1; 6477 hwbug = 1;
6478 tnapi->tx_buffers[prvidx].fragmented = false;
6483 } 6479 }
6484 } 6480 }
6485 } else { 6481 } else {
@@ -6561,6 +6557,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
6561 dev_kfree_skb(new_skb); 6557 dev_kfree_skb(new_skb);
6562 ret = -1; 6558 ret = -1;
6563 } else { 6559 } else {
6560 u32 save_entry = *entry;
6561
6564 base_flags |= TXD_FLAG_END; 6562 base_flags |= TXD_FLAG_END;
6565 6563
6566 tnapi->tx_buffers[*entry].skb = new_skb; 6564 tnapi->tx_buffers[*entry].skb = new_skb;
@@ -6570,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
6570 if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, 6568 if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
6571 new_skb->len, base_flags, 6569 new_skb->len, base_flags,
6572 mss, vlan)) { 6570 mss, vlan)) {
6573 tg3_tx_skb_unmap(tnapi, *entry, 0); 6571 tg3_tx_skb_unmap(tnapi, save_entry, 0);
6574 dev_kfree_skb(new_skb); 6572 dev_kfree_skb(new_skb);
6575 ret = -1; 6573 ret = -1;
6576 } 6574 }
@@ -6786,11 +6784,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
6786 if (dma_mapping_error(&tp->pdev->dev, mapping)) 6784 if (dma_mapping_error(&tp->pdev->dev, mapping))
6787 goto dma_error; 6785 goto dma_error;
6788 6786
6789 if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, 6787 if (!budget ||
6788 tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
6790 len, base_flags | 6789 len, base_flags |
6791 ((i == last) ? TXD_FLAG_END : 0), 6790 ((i == last) ? TXD_FLAG_END : 0),
6792 tmp_mss, vlan)) 6791 tmp_mss, vlan)) {
6793 would_hit_hwbug = 1; 6792 would_hit_hwbug = 1;
6793 break;
6794 }
6794 } 6795 }
6795 } 6796 }
6796 6797