The TX/RX descriptor size is 16 byte.
When the cache line size is larger than 16 bytes, descriptors
flushed to RAM will flush more than one descriptor.
It is possible that it may mistakenly flush to other descriptor
that has been updated by MAC in RAM.

To avoid this issue, align the descriptors to cache line size.
Only one desc will be flushed or invalidated at a time.

Signed-off-by: Jacky Chou <jacky_c...@aspeedtech.com>
---
 drivers/net/ftgmac100.c | 13 ++++++++++++-
 drivers/net/ftgmac100.h |  5 +++--
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 256a519020..9fb8c12838 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -322,7 +322,7 @@ static int ftgmac100_start(struct udevice *dev)
        struct ftgmac100_data *priv = dev_get_priv(dev);
        struct ftgmac100 *ftgmac100 = priv->iobase;
        struct phy_device *phydev = priv->phydev;
-       unsigned int maccr;
+       unsigned int maccr, dblac, desc_size;
        ulong start, end;
        int ret;
        int i;
@@ -367,6 +367,17 @@ static int ftgmac100_start(struct udevice *dev)
        /* receive ring */
        writel((u32)priv->rxdes, &ftgmac100->rxr_badr);
 
+       /* Configure TX/RX decsriptor size
+        * This size is calculated based on cache line.
+        */
+       desc_size = ARCH_DMA_MINALIGN / FTGMAC100_DESC_UNIT;
+       /* The descriptor size is at least 2 descriptor units. */
+       if (desc_size < 2)
+               desc_size = 2;
+       dblac = readl(&ftgmac100->dblac) & ~GENMASK(19, 12);
+       dblac |= FTGMAC100_DBLAC_RXDES_SIZE(desc_size) | 
FTGMAC100_DBLAC_TXDES_SIZE(desc_size);
+       writel(dblac, &ftgmac100->dblac);
+
        /* poll receive descriptor automatically */
        writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
 
diff --git a/drivers/net/ftgmac100.h b/drivers/net/ftgmac100.h
index f7874ae68b..37c029aded 100644
--- a/drivers/net/ftgmac100.h
+++ b/drivers/net/ftgmac100.h
@@ -111,6 +111,7 @@ struct ftgmac100 {
 #define FTGMAC100_DBLAC_TXBURST_SIZE(x)        (((x) & 0x3) << 10)
 #define FTGMAC100_DBLAC_RXDES_SIZE(x)  (((x) & 0xf) << 12)
 #define FTGMAC100_DBLAC_TXDES_SIZE(x)  (((x) & 0xf) << 16)
+#define FTGMAC100_DESC_UNIT            8
 #define FTGMAC100_DBLAC_IFG_CNT(x)     (((x) & 0x7) << 20)
 #define FTGMAC100_DBLAC_IFG_INC                BIT(23)
 
@@ -183,7 +184,7 @@ struct ftgmac100_txdes {
        unsigned int    txdes1;
        unsigned int    txdes2; /* not used by HW */
        unsigned int    txdes3; /* TXBUF_BADR */
-} __aligned(16);
+} __aligned(ARCH_DMA_MINALIGN);
 
 #define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff)
 #define FTGMAC100_TXDES0_EDOTR         BIT(15)
@@ -209,7 +210,7 @@ struct ftgmac100_rxdes {
        unsigned int    rxdes1;
        unsigned int    rxdes2; /* not used by HW */
        unsigned int    rxdes3; /* RXBUF_BADR */
-} __aligned(16);
+} __aligned(ARCH_DMA_MINALIGN);
 
 #define FTGMAC100_RXDES0_VDBC(x)       ((x) & 0x3fff)
 #define FTGMAC100_RXDES0_EDORR         BIT(15)
-- 
2.25.1

Reply via email to