From: Greg Kroah-Hartman <gre...@linuxfoundation.org>

From: Joakim Zhang <qiangqing.zh...@nxp.com>

commit 396e13e11577b614db77db0bbb6fca935b94eb1b upstream.

In current driver, buffer2 available only when hardware supports split
header. Wrongly set buffer2 valid in stmmac_rx_refill when refill buffer
address. You can see that desc3 is 0x81000000 after initialization, but
turn out to be 0x83000000 after refill.

Fixes: 67afd6d1cfdf ("net: stmmac: Add Split Header support and enable it in 
XGMAC cores")
Signed-off-by: Joakim Zhang <qiangqing.zh...@nxp.com>
Signed-off-by: Jakub Kicinski <k...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c   |    9 +++++++--
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c |    2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h           |    2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c    |    8 ++++++--
 4 files changed, 15 insertions(+), 6 deletions(-)

--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -499,10 +499,15 @@ static void dwmac4_get_rx_header_len(str
        *len = le32_to_cpu(p->des2) & RDES2_HL;
 }
 
-static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
+static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool 
buf2_valid)
 {
        p->des2 = cpu_to_le32(lower_32_bits(addr));
-       p->des3 = cpu_to_le32(upper_32_bits(addr) | RDES3_BUFFER2_VALID_ADDR);
+       p->des3 = cpu_to_le32(upper_32_bits(addr));
+
+       if (buf2_valid)
+               p->des3 |= cpu_to_le32(RDES3_BUFFER2_VALID_ADDR);
+       else
+               p->des3 &= cpu_to_le32(~RDES3_BUFFER2_VALID_ADDR);
 }
 
 static void dwmac4_set_tbs(struct dma_edesc *p, u32 sec, u32 nsec)
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -292,7 +292,7 @@ static void dwxgmac2_get_rx_header_len(s
                *len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL;
 }
 
-static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
+static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool 
is_valid)
 {
        p->des2 = cpu_to_le32(lower_32_bits(addr));
        p->des3 = cpu_to_le32(upper_32_bits(addr));
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -91,7 +91,7 @@ struct stmmac_desc_ops {
        int (*get_rx_hash)(struct dma_desc *p, u32 *hash,
                           enum pkt_hash_types *type);
        void (*get_rx_header_len)(struct dma_desc *p, unsigned int *len);
-       void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr);
+       void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr, bool 
buf2_valid);
        void (*set_sarc)(struct dma_desc *p, u32 sarc_type);
        void (*set_vlan_tag)(struct dma_desc *p, u16 tag, u16 inner_tag,
                             u32 inner_type);
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1279,9 +1279,10 @@ static int stmmac_init_rx_buffers(struct
                        return -ENOMEM;
 
                buf->sec_addr = page_pool_get_dma_addr(buf->sec_page);
-               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr);
+               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true);
        } else {
                buf->sec_page = NULL;
+               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false);
        }
 
        buf->addr = page_pool_get_dma_addr(buf->page);
@@ -3618,7 +3619,10 @@ static inline void stmmac_rx_refill(stru
                                           DMA_FROM_DEVICE);
 
                stmmac_set_desc_addr(priv, p, buf->addr);
-               stmmac_set_desc_sec_addr(priv, p, buf->sec_addr);
+               if (priv->sph)
+                       stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true);
+               else
+                       stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false);
                stmmac_refill_desc3(priv, rx_q, p);
 
                rx_q->rx_count_frames++;


Reply via email to