Commit 7e4d1c23 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'dpaa2-swtso-fixes'

Ioana Ciornei says:

====================
dpaa2-eth: software TSO fixes

This patch fixes the software TSO feature in dpaa2-eth.

There are multiple errors that I made in the initial submission of the
code, which I didn't caught since I was always running with passthough
IOMMU.

The bug report came in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215886



The bugs are in the Tx confirmation path, where I was trying to retrieve
a virtual address after DMA unmapping the area. Besides that, another
dma_unmap call was made with the wrong size.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 15d221d0 0a09c5b8
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -1097,6 +1097,7 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv,
	u32 fd_len = dpaa2_fd_get_len(fd);
	u32 fd_len = dpaa2_fd_get_len(fd);
	struct dpaa2_sg_entry *sgt;
	struct dpaa2_sg_entry *sgt;
	int should_free_skb = 1;
	int should_free_skb = 1;
	void *tso_hdr;
	int i;
	int i;


	fd_addr = dpaa2_fd_get_addr(fd);
	fd_addr = dpaa2_fd_get_addr(fd);
@@ -1135,20 +1136,21 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv,
			sgt = (struct dpaa2_sg_entry *)(buffer_start +
			sgt = (struct dpaa2_sg_entry *)(buffer_start +
							priv->tx_data_offset);
							priv->tx_data_offset);


			/* Unmap the SGT buffer */
			dma_unmap_single(dev, fd_addr, swa->tso.sgt_size,
					 DMA_BIDIRECTIONAL);

			/* Unmap and free the header */
			/* Unmap and free the header */
			tso_hdr = dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt));
			dma_unmap_single(dev, dpaa2_sg_get_addr(sgt), TSO_HEADER_SIZE,
			dma_unmap_single(dev, dpaa2_sg_get_addr(sgt), TSO_HEADER_SIZE,
					 DMA_TO_DEVICE);
					 DMA_TO_DEVICE);
			kfree(dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt)));
			kfree(tso_hdr);


			/* Unmap the other SG entries for the data */
			/* Unmap the other SG entries for the data */
			for (i = 1; i < swa->tso.num_sg; i++)
			for (i = 1; i < swa->tso.num_sg; i++)
				dma_unmap_single(dev, dpaa2_sg_get_addr(&sgt[i]),
				dma_unmap_single(dev, dpaa2_sg_get_addr(&sgt[i]),
						 dpaa2_sg_get_len(&sgt[i]), DMA_TO_DEVICE);
						 dpaa2_sg_get_len(&sgt[i]), DMA_TO_DEVICE);


			/* Unmap the SGT buffer */
			dma_unmap_single(dev, fd_addr, swa->sg.sgt_size,
					 DMA_BIDIRECTIONAL);

			if (!swa->tso.is_last_fd)
			if (!swa->tso.is_last_fd)
				should_free_skb = 0;
				should_free_skb = 0;
		} else {
		} else {