diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/vmxnet3/vmxnet3_drv.c | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index ce9d4f2c9776..0ae1bcc6da73 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
| @@ -744,28 +744,43 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, | |||
| 744 | 744 | ||
| 745 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 745 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
| 746 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; | 746 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; |
| 747 | u32 buf_size; | ||
| 747 | 748 | ||
| 748 | tbi = tq->buf_info + tq->tx_ring.next2fill; | 749 | buf_offset = 0; |
| 749 | tbi->map_type = VMXNET3_MAP_PAGE; | 750 | len = skb_frag_size(frag); |
| 750 | tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, | 751 | while (len) { |
| 751 | 0, skb_frag_size(frag), | 752 | tbi = tq->buf_info + tq->tx_ring.next2fill; |
| 752 | DMA_TO_DEVICE); | 753 | if (len < VMXNET3_MAX_TX_BUF_SIZE) { |
| 754 | buf_size = len; | ||
| 755 | dw2 |= len; | ||
| 756 | } else { | ||
| 757 | buf_size = VMXNET3_MAX_TX_BUF_SIZE; | ||
| 758 | /* spec says that for TxDesc.len, 0 == 2^14 */ | ||
| 759 | } | ||
| 760 | tbi->map_type = VMXNET3_MAP_PAGE; | ||
| 761 | tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, | ||
| 762 | buf_offset, buf_size, | ||
| 763 | DMA_TO_DEVICE); | ||
| 753 | 764 | ||
| 754 | tbi->len = skb_frag_size(frag); | 765 | tbi->len = buf_size; |
| 755 | 766 | ||
| 756 | gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; | 767 | gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; |
| 757 | BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); | 768 | BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); |
| 758 | 769 | ||
| 759 | gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); | 770 | gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); |
| 760 | gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); | 771 | gdesc->dword[2] = cpu_to_le32(dw2); |
| 761 | gdesc->dword[3] = 0; | 772 | gdesc->dword[3] = 0; |
| 762 | 773 | ||
| 763 | dev_dbg(&adapter->netdev->dev, | 774 | dev_dbg(&adapter->netdev->dev, |
| 764 | "txd[%u]: 0x%llu %u %u\n", | 775 | "txd[%u]: 0x%llu %u %u\n", |
| 765 | tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), | 776 | tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), |
| 766 | le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); | 777 | le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); |
| 767 | vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); | 778 | vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); |
| 768 | dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; | 779 | dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; |
| 780 | |||
| 781 | len -= buf_size; | ||
| 782 | buf_offset += buf_size; | ||
| 783 | } | ||
| 769 | } | 784 | } |
| 770 | 785 | ||
| 771 | ctx->eop_txd = gdesc; | 786 | ctx->eop_txd = gdesc; |
| @@ -886,6 +901,18 @@ vmxnet3_prepare_tso(struct sk_buff *skb, | |||
| 886 | } | 901 | } |
| 887 | } | 902 | } |
| 888 | 903 | ||
| 904 | static int txd_estimate(const struct sk_buff *skb) | ||
| 905 | { | ||
| 906 | int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1; | ||
| 907 | int i; | ||
| 908 | |||
| 909 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | ||
| 910 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; | ||
| 911 | |||
| 912 | count += VMXNET3_TXD_NEEDED(skb_frag_size(frag)); | ||
| 913 | } | ||
| 914 | return count; | ||
| 915 | } | ||
| 889 | 916 | ||
| 890 | /* | 917 | /* |
| 891 | * Transmits a pkt thru a given tq | 918 | * Transmits a pkt thru a given tq |
| @@ -914,9 +941,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 914 | union Vmxnet3_GenericDesc tempTxDesc; | 941 | union Vmxnet3_GenericDesc tempTxDesc; |
| 915 | #endif | 942 | #endif |
| 916 | 943 | ||
| 917 | /* conservatively estimate # of descriptors to use */ | 944 | count = txd_estimate(skb); |
| 918 | count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + | ||
| 919 | skb_shinfo(skb)->nr_frags + 1; | ||
| 920 | 945 | ||
| 921 | ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); | 946 | ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); |
| 922 | 947 | ||
