net: dwc_eth_qos: Correctly wrap around TX descriptor tail pointer
authorMarek Vasut <marex@denx.de>
Mon, 23 Mar 2020 01:03:50 +0000 (02:03 +0100)
committermarex <marex@desktop.lan>
Fri, 1 May 2020 10:35:21 +0000 (12:35 +0200)
This code programs the next descriptor in the TX descriptor ring into
the hardware as the last valid TX descriptor. The problem is that if
the currenty descriptor is the last one in the array, the code will
not wrap around correctly and use TX descriptor 0 again, but instead
will use TX descriptor at address right past the TX descriptor ring,
which is the first descriptor in the RX ring.

Fix this by adding the necessary wrap-around.

Reviewed-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Joe Hershberger <joe.hershberger@ni.com>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Patrick Delaunay <patrick.delaunay@st.com>
Cc: Ramon Fried <rfried.dev@gmail.com>
Cc: Stephen Warren <swarren@nvidia.com>
drivers/net/dwc_eth_qos.c

index 4f24520691034759b71cd1ccdb24d76223d8be08..e2fb690a1c26511d8f82ab38a3099a7318880a2b 100644 (file)
@@ -1419,7 +1419,8 @@ static int eqos_send(struct udevice *dev, void *packet, int length)
        tx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_FD | EQOS_DESC3_LD | length;
        eqos->config->ops->eqos_flush_desc(tx_desc);
 
-       writel((ulong)(tx_desc + 1), &eqos->dma_regs->ch0_txdesc_tail_pointer);
+       writel((ulong)(&(eqos->tx_descs[eqos->tx_desc_idx])),
+               &eqos->dma_regs->ch0_txdesc_tail_pointer);
 
        for (i = 0; i < 1000000; i++) {
                eqos->config->ops->eqos_inval_desc(tx_desc);