Commit 9025944f authored by Shenwei Wang's avatar Shenwei Wang Committed by David S. Miller
Browse files

net: fec: add dma_wmb to ensure correct descriptor values



Two dma_wmb() are added in the XDP TX path to ensure proper ordering of
descriptor and buffer updates:
1. A dma_wmb() is added after updating the last BD to make sure
   the updates to rest of the descriptor are visible before
   transferring ownership to FEC.
2. A dma_wmb() is also added after updating the bdp to ensure these
   updates are visible before updating txq->bd.cur.
3. Start the xmit of the frame immediately right after configuring the
   tx descriptor.

Fixes: 6d6b39f1 ("net: fec: add initial XDP support")
Signed-off-by: default avatarShenwei Wang <shenwei.wang@nxp.com>
Reviewed-by: default avatarWei Fang <wei.fang@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3be5f6cd
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -3834,6 +3834,11 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
	index = fec_enet_get_bd_index(last_bdp, &txq->bd);
	txq->tx_skbuff[index] = NULL;

	/* Make sure the updates to rest of the descriptor are performed before
	 * transferring ownership.
	 */
	dma_wmb();

	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
	 * it's the last BD of the frame, and to put the CRC on the end.
	 */
@@ -3843,8 +3848,14 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
	/* If this was the last BD in the ring, start at the beginning again. */
	bdp = fec_enet_get_nextdesc(last_bdp, &txq->bd);

	/* Make sure the update to bdp are performed before txq->bd.cur. */
	dma_wmb();

	txq->bd.cur = bdp;

	/* Trigger transmission start */
	writel(0, txq->bd.reg_desc_active);

	return 0;
}

@@ -3873,12 +3884,6 @@ static int fec_enet_xdp_xmit(struct net_device *dev,
		sent_frames++;
	}

	/* Make sure the update to bdp and tx_skbuff are performed. */
	wmb();

	/* Trigger transmission start */
	writel(0, txq->bd.reg_desc_active);

	__netif_tx_unlock(nq);

	return sent_frames;