net: stmmac: don't set own bit too early for jumbo frames
Commit0e80bdc9a7
("stmmac: first frame prep at the end of xmit routine") overlooked jumbo frames when re-ordering the code, and as a result the own bit was not getting set anymore for the first jumbo frame descriptor. Commit487e2e22ab
("net: stmmac: Set OWN bit for jumbo frames") tried to fix this, but now the bit is getting set too early and the DMA may start while we are still setting up the remaining descriptors. And with the chain mode the own bit remains still unset. Fix by setting the own bit at the end of xmit also with jumbo frames. Fixes:0e80bdc9a7
("stmmac: first frame prep at the end of xmit routine") Fixes:487e2e22ab
("net: stmmac: Set OWN bit for jumbo frames") Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com> Acked-by: Jose Abreu <joabreu@synopsys.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9804501fa1
commit
80acbed9f8
|
@ -59,7 +59,7 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
||||||
|
|
||||||
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
||||||
stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
|
stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
|
||||||
STMMAC_RING_MODE, 1, false, skb->len);
|
STMMAC_RING_MODE, 0, false, skb->len);
|
||||||
tx_q->tx_skbuff[entry] = NULL;
|
tx_q->tx_skbuff[entry] = NULL;
|
||||||
entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
|
entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
||||||
tx_q->tx_skbuff_dma[entry].is_jumbo = true;
|
tx_q->tx_skbuff_dma[entry].is_jumbo = true;
|
||||||
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
||||||
stmmac_prepare_tx_desc(priv, desc, 1, nopaged_len, csum,
|
stmmac_prepare_tx_desc(priv, desc, 1, nopaged_len, csum,
|
||||||
STMMAC_RING_MODE, 1, true, skb->len);
|
STMMAC_RING_MODE, 0, true, skb->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_q->cur_tx = entry;
|
tx_q->cur_tx = entry;
|
||||||
|
|
|
@ -3216,14 +3216,16 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
stmmac_prepare_tx_desc(priv, first, 1, nopaged_len,
|
stmmac_prepare_tx_desc(priv, first, 1, nopaged_len,
|
||||||
csum_insertion, priv->mode, 1, last_segment,
|
csum_insertion, priv->mode, 1, last_segment,
|
||||||
skb->len);
|
skb->len);
|
||||||
|
} else {
|
||||||
/* The own bit must be the latest setting done when prepare the
|
stmmac_set_tx_owner(priv, first);
|
||||||
* descriptor and then barrier is needed to make sure that
|
|
||||||
* all is coherent before granting the DMA engine.
|
|
||||||
*/
|
|
||||||
wmb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The own bit must be the latest setting done when prepare the
|
||||||
|
* descriptor and then barrier is needed to make sure that
|
||||||
|
* all is coherent before granting the DMA engine.
|
||||||
|
*/
|
||||||
|
wmb();
|
||||||
|
|
||||||
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
|
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
|
||||||
|
|
||||||
stmmac_enable_dma_transmission(priv, priv->ioaddr);
|
stmmac_enable_dma_transmission(priv, priv->ioaddr);
|
||||||
|
|
Loading…
Reference in New Issue