Re: [PATCH net] net: stmmac: Set DMA buffer size in HW

2018-06-27 Thread Jose Abreu
David,

On 27-06-2018 15:03, Jose Abreu wrote:
> This is clearly a bug.

You will probably have an hard time backporting this because of
the way the callbacks are handled now.

I can send you a patch based on some -stable branch if you prefer.

Thanks and Best Regards,
Jose Miguel Abreu


[PATCH net] net: stmmac: Set DMA buffer size in HW

2018-06-27 Thread Jose Abreu
This is clearly a bug.

We need to set the DMA buffer size in the HW otherwise corruption can
occur when receiving packets.

This is probably not occuring because of small MTU values and because HW
has a default value internally (which currently is bigger than default
buffer size).

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Vitor Soares 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c  | 12 
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h  |  2 ++
 drivers/net/ethernet/stmicro/stmmac/hwif.h|  3 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  2 ++
 4 files changed, 19 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index d37f17ca62fe..65bc3556bd8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -407,6 +407,16 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool 
en, u32 chan)
}
 }
 
+static void dwmac4_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan)
+{
+   u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
+
+   value &= ~DMA_RBSZ_MASK;
+   value |= (bfsize << DMA_RBSZ_SHIFT) & DMA_RBSZ_MASK;
+
+   writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
+}
+
 const struct stmmac_dma_ops dwmac4_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
@@ -431,6 +441,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
.set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
.set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
.enable_tso = dwmac4_enable_tso,
+   .set_bfsize = dwmac4_set_bfsize,
 };
 
 const struct stmmac_dma_ops dwmac410_dma_ops = {
@@ -457,4 +468,5 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
.set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
.set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
.enable_tso = dwmac4_enable_tso,
+   .set_bfsize = dwmac4_set_bfsize,
 };
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index c63c1fe3f26b..22a4a6dbb1a4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -120,6 +120,8 @@
 
 /* DMA Rx Channel X Control register defines */
 #define DMA_CONTROL_SR BIT(0)
+#define DMA_RBSZ_MASK  GENMASK(14, 1)
+#define DMA_RBSZ_SHIFT 1
 
 /* Interrupt status per channel */
 #define DMA_CHAN_STATUS_REBGENMASK(21, 19)
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h 
b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index e44e7b26ce82..fe8b536b13f8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -183,6 +183,7 @@ struct stmmac_dma_ops {
void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
+   void (*set_bfsize)(void __iomem *ioaddr, int bfsize, u32 chan);
 };
 
 #define stmmac_reset(__priv, __args...) \
@@ -235,6 +236,8 @@ struct stmmac_dma_ops {
stmmac_do_void_callback(__priv, dma, set_tx_tail_ptr, __args)
 #define stmmac_enable_tso(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, enable_tso, __args)
+#define stmmac_set_dma_bfsize(__priv, __args...) \
+   stmmac_do_void_callback(__priv, dma, set_bfsize, __args)
 
 struct mac_device_info;
 struct net_device;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index cba46b62a1cd..60f59abab009 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1804,6 +1804,8 @@ static void stmmac_dma_operation_mode(struct stmmac_priv 
*priv)
 
stmmac_dma_rx_mode(priv, priv->ioaddr, rxmode, chan,
rxfifosz, qmode);
+   stmmac_set_dma_bfsize(priv, priv->ioaddr, priv->dma_buf_sz,
+   chan);
}
 
for (chan = 0; chan < tx_channels_count; chan++) {
-- 
2.7.4