diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 35901630a65c..507b73b979fe 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 | ||