Commit 350db8a5 authored by Shinas Rasheed's avatar Shinas Rasheed Committed by David S. Miller
Browse files

octeon_ep: fix tx dma unmap len values in SG



Lengths of SG pointers are kept in the following order in
the SG entries in hardware.
 63      48|47     32|31     16|15       0
 -----------------------------------------
 |  Len 0  |  Len 1  |  Len 2  |  Len 3  |
 -----------------------------------------
 |                Ptr 0                  |
 -----------------------------------------
 |                Ptr 1                  |
 -----------------------------------------
 |                Ptr 2                  |
 -----------------------------------------
 |                Ptr 3                  |
 -----------------------------------------
Dma pointers have to be unmapped based on their
respective lengths given in this format.

Fixes: 37d79d05 ("octeon_ep: add Tx/Rx processing and interrupt support")
Signed-off-by: default avatarShinas Rasheed <srasheed@marvell.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e0b65f9b
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -734,13 +734,13 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
dma_map_sg_err:
	if (si > 0) {
		dma_unmap_single(iq->dev, sglist[0].dma_ptr[0],
				 sglist[0].len[0], DMA_TO_DEVICE);
		sglist[0].len[0] = 0;
				 sglist[0].len[3], DMA_TO_DEVICE);
		sglist[0].len[3] = 0;
	}
	while (si > 1) {
		dma_unmap_page(iq->dev, sglist[si >> 2].dma_ptr[si & 3],
			       sglist[si >> 2].len[si & 3], DMA_TO_DEVICE);
		sglist[si >> 2].len[si & 3] = 0;
			       sglist[si >> 2].len[3 - (si & 3)], DMA_TO_DEVICE);
		sglist[si >> 2].len[3 - (si & 3)] = 0;
		si--;
	}
	tx_buffer->gather = 0;
+4 −4
Original line number Diff line number Diff line
@@ -69,12 +69,12 @@ int octep_iq_process_completions(struct octep_iq *iq, u16 budget)
		compl_sg++;

		dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0],
				 tx_buffer->sglist[0].len[0], DMA_TO_DEVICE);
				 tx_buffer->sglist[0].len[3], DMA_TO_DEVICE);

		i = 1; /* entry 0 is main skb, unmapped above */
		while (frags--) {
			dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3],
				       tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE);
				       tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE);
			i++;
		}

@@ -131,13 +131,13 @@ static void octep_iq_free_pending(struct octep_iq *iq)

		dma_unmap_single(iq->dev,
				 tx_buffer->sglist[0].dma_ptr[0],
				 tx_buffer->sglist[0].len[0],
				 tx_buffer->sglist[0].len[3],
				 DMA_TO_DEVICE);

		i = 1; /* entry 0 is main skb, unmapped above */
		while (frags--) {
			dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3],
				       tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE);
				       tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE);
			i++;
		}

+15 −1
Original line number Diff line number Diff line
@@ -17,7 +17,21 @@
#define TX_BUFTYPE_NET_SG        2
#define NUM_TX_BUFTYPES          3

/* Hardware format for Scatter/Gather list */
/* Hardware format for Scatter/Gather list
 *
 * 63      48|47     32|31     16|15       0
 * -----------------------------------------
 * |  Len 0  |  Len 1  |  Len 2  |  Len 3  |
 * -----------------------------------------
 * |                Ptr 0                  |
 * -----------------------------------------
 * |                Ptr 1                  |
 * -----------------------------------------
 * |                Ptr 2                  |
 * -----------------------------------------
 * |                Ptr 3                  |
 * -----------------------------------------
 */
struct octep_tx_sglist_desc {
	u16 len[4];
	dma_addr_t dma_ptr[4];