vmxnet3 has a 16Kbytes limit per tx descriptor, that happened to work as long as we provided PAGE_SIZE fragments. Our stack can now build larger fragments, so we need to split them to the 16kbytes boundary.
Unified · Split
| @@ -744,28 +744,43 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, · 743 unmodified lines | ||
| 744 | 744 | |
| 745 | 745 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
| 746 | 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 | − tbi->map_type = VMXNET3_MAP_PAGE; | |
| 750 | − tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, | |
| 751 | − 0, skb_frag_size(frag), | |
| 752 | − DMA_TO_DEVICE); | |
| 749 | + buf_offset = 0; | |
| 750 | + len = skb_frag_size(frag); | |
| 751 | + while (len) { | |
| 752 | + tbi = tq->buf_info + tq->tx_ring.next2fill; | |
| 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; | |
| 757 | − BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); | |
| 767 | + gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; | |
| 768 | + BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); | |
| 758 | 769 | |
| 759 | − gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); | |
| 760 | − gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); | |
| 761 | − gdesc->dword[3] = 0; | |
| 770 | + gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); | |
| 771 | + gdesc->dword[2] = cpu_to_le32(dw2); | |
| 772 | + gdesc->dword[3] = 0; | |
| 762 | 773 | |
| 763 | − dev_dbg(&adapter->netdev->dev, | |
| 764 | − "txd[%u]: 0x%llu %u %u\n", | |
| 765 | − tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), | |
| 766 | − le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); | |
| 767 | − vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); | |
| 768 | − dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; | |
| 774 | + dev_dbg(&adapter->netdev->dev, | |
| 775 | + "txd[%u]: 0x%llu %u %u\n", | |
| 776 | + tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), | |
| 777 | + le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); | |
| 778 | + vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); | |
| 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 | 786 | ctx->eop_txd = gdesc; |
| @@ -886,6 +901,18 @@ vmxnet3_prepare_tso(struct sk_buff *skb, · 114 unmodified lines | ||
| 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 | 918 | * Transmits a pkt thru a given tq |
| @@ -914,9 +941,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, · 22 unmodified lines | ||
| 914 | 941 | union Vmxnet3_GenericDesc tempTxDesc; |
| 915 | 942 | #endif |
| 916 | 943 | |
| 917 | − /* conservatively estimate # of descriptors to use */ | |
| 918 | − count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + | |
| 919 | − skb_shinfo(skb)->nr_frags + 1; | |
| 944 | + count = txd_estimate(skb); | |
| 920 | 945 | |
| 921 | 946 | ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); |
| 922 | 947 | |