[PATCH] net: dwc_eth_qos: Revert some changes of commit 3a97da12ee7b

2021-05-30 Thread Daniil Stas
Revert some changes of commit 3a97da12ee7b ("net: dwc_eth_qos: add dwc
eqos for imx support") that were probably added by mistake.

One of these changes can lead to received data corruption (enabling
FUP and FEP bits). Another causes invalid register rxq_ctrl0 settings
for some platforms. And another makes some writes at unknown memory
location.

Fixes: 3a97da12ee7b ("net: dwc_eth_qos: add dwc eqos for imx support")
Signed-off-by: Daniil Stas 
Cc: Ye Li 
Cc: Fugang Duan 
Cc: Peng Fan 
Cc: Ramon Fried 
Cc: Joe Hershberger 
Cc: Patrice Chotard 
Cc: Patrick Delaunay 
---
 drivers/net/dwc_eth_qos.c | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 2f088c758f..b012bed517 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -172,8 +172,6 @@ struct eqos_mtl_regs {
 #define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK  0x3f
 #define EQOS_MTL_RXQ0_OPERATION_MODE_EHFC  BIT(7)
 #define EQOS_MTL_RXQ0_OPERATION_MODE_RSF   BIT(5)
-#define EQOS_MTL_RXQ0_OPERATION_MODE_FEP   BIT(4)
-#define EQOS_MTL_RXQ0_OPERATION_MODE_FUP   BIT(3)
 
 #define EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16
 #define EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK  0x7fff
@@ -1222,7 +1220,6 @@ static int eqos_start(struct udevice *dev)
}
 
/* Configure MTL */
-   writel(0x60, >mtl_regs->txq0_quantum_weight - 0x100);
 
/* Enable Store and Forward mode for TX */
/* Program Tx operating mode */
@@ -1236,9 +1233,7 @@ static int eqos_start(struct udevice *dev)
 
/* Enable Store and Forward mode for RX, since no jumbo frame */
setbits_le32(>mtl_regs->rxq0_operation_mode,
-EQOS_MTL_RXQ0_OPERATION_MODE_RSF |
-EQOS_MTL_RXQ0_OPERATION_MODE_FEP |
-EQOS_MTL_RXQ0_OPERATION_MODE_FUP);
+EQOS_MTL_RXQ0_OPERATION_MODE_RSF);
 
/* Transmit/Receive queue fifo size; use all RAM for 1 queue */
val = readl(>mac_regs->hw_feature1);
@@ -1314,12 +1309,6 @@ static int eqos_start(struct udevice *dev)
eqos->config->config_mac <<
EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
 
-   clrsetbits_le32(>mac_regs->rxq_ctrl0,
-   EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
-   EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
-   0x2 <<
-   EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
-
/* Multicast and Broadcast Queue Enable */
setbits_le32(>mac_regs->unused_0a4,
 0x0010);
-- 
2.31.1



Re: [PATCH] spi: stm32_qspi: Fix short data write operation

2021-05-24 Thread Daniil Stas
On Mon, 24 May 2021 09:40:05 +0200
Patrice CHOTARD  wrote:

> Hi Daniil
> 
> On 5/24/21 12:24 AM, Daniil Stas wrote:
> > TCF flag only means that all data was sent to FIFO. To check if the
> > data was sent out of FIFO we should also wait for the BUSY flag to
> > be cleared. Otherwise there is a race condition which can lead to
> > inability to write short (one byte long) data.
> > 
> > Signed-off-by: Daniil Stas 
> > Cc: Patrick Delaunay 
> > Cc: Patrice Chotard 
> > ---
> >  drivers/spi/stm32_qspi.c | 29 +++--
> >  1 file changed, 15 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
> > index 4acc9047b9..8f4aabc3d1 100644
> > --- a/drivers/spi/stm32_qspi.c
> > +++ b/drivers/spi/stm32_qspi.c
> > @@ -148,23 +148,24 @@ static int _stm32_qspi_wait_cmd(struct
> > stm32_qspi_priv *priv, const struct spi_mem_op *op)
> >  {
> > u32 sr;
> > -   int ret;
> > -
> > -   if (!op->data.nbytes)
> > -   return _stm32_qspi_wait_for_not_busy(priv);
> > +   int ret = 0;
> >  
> > -   ret = readl_poll_timeout(>regs->sr, sr,
> > -sr & STM32_QSPI_SR_TCF,
> > -STM32_QSPI_CMD_TIMEOUT_US);
> > -   if (ret) {
> > -   log_err("cmd timeout (stat:%#x)\n", sr);
> > -   } else if (readl(>regs->sr) & STM32_QSPI_SR_TEF) {
> > -   log_err("transfer error (stat:%#x)\n", sr);
> > -   ret = -EIO;
> > +   if (op->data.nbytes) {
> > +   ret = readl_poll_timeout(>regs->sr, sr,
> > +sr & STM32_QSPI_SR_TCF,
> > +
> > STM32_QSPI_CMD_TIMEOUT_US);
> > +   if (ret) {
> > +   log_err("cmd timeout (stat:%#x)\n", sr);
> > +   } else if (readl(>regs->sr) &
> > STM32_QSPI_SR_TEF) {
> > +   log_err("transfer error (stat:%#x)\n", sr);
> > +   ret = -EIO;
> > +   }
> > +   /* clear flags */
> > +   writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF,
> > >regs->fcr); }
> >  
> > -   /* clear flags */
> > -   writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF,
> > >regs->fcr);
> > +   if (!ret)
> > +   ret = _stm32_qspi_wait_for_not_busy(priv);
> >  
> > return ret;
> >  }
> >   
> 
> Have you got a simple test to reproduce the described race condition ?
> 
> Thanks
> Patrice

Hi, Patrice

I found this issue on an stm32mp153 based board.
To reproduce it you need to set qspi peripheral clock to a low
value (for example 24 MHz).
Then you can test it in the u-boot console:

STM32MP> clk dump
Clocks:
...
- CK_PER : 24 MHz
...
- QSPI(10) => parent CK_PER(30)
...

STM32MP> sf probe
SF: Detected w25q32jv with page size 256 Bytes, erase size 64 KiB, total 4 MiB
STM32MP> sf erase 0x0030 +1
SF: 65536 bytes @ 0x30 Erased: OK
STM32MP> sf read 0xc410 0x30 10
device 0 offset 0x30, size 0x10
SF: 16 bytes @ 0x30 Read: OK
STM32MP> md.b 0xc410
c410: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...
STM32MP> mw.b 0xc420 55
STM32MP> sf write 0xc420 0x0030 1
device 0 offset 0x30, size 0x1
SF: 1 bytes @ 0x30 Written: OK
STM32MP> sf read 0xc410 0x0030 10
device 0 offset 0x30, size 0x10
SF: 16 bytes @ 0x30 Read: OK
STM32MP> md.b 0xc410
c410: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...


With my patch applied the last command result would be:
STM32MP> md.b 0xc410
c410: 55 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffU...

Thanks,
Daniil


[PATCH] spi: stm32_qspi: Fix short data write operation

2021-05-23 Thread Daniil Stas
TCF flag only means that all data was sent to FIFO. To check if the
data was sent out of FIFO we should also wait for the BUSY flag to be
cleared. Otherwise there is a race condition which can lead to
inability to write short (one byte long) data.

Signed-off-by: Daniil Stas 
Cc: Patrick Delaunay 
Cc: Patrice Chotard 
---
 drivers/spi/stm32_qspi.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 4acc9047b9..8f4aabc3d1 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -148,23 +148,24 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv 
*priv,
const struct spi_mem_op *op)
 {
u32 sr;
-   int ret;
-
-   if (!op->data.nbytes)
-   return _stm32_qspi_wait_for_not_busy(priv);
+   int ret = 0;
 
-   ret = readl_poll_timeout(>regs->sr, sr,
-sr & STM32_QSPI_SR_TCF,
-STM32_QSPI_CMD_TIMEOUT_US);
-   if (ret) {
-   log_err("cmd timeout (stat:%#x)\n", sr);
-   } else if (readl(>regs->sr) & STM32_QSPI_SR_TEF) {
-   log_err("transfer error (stat:%#x)\n", sr);
-   ret = -EIO;
+   if (op->data.nbytes) {
+   ret = readl_poll_timeout(>regs->sr, sr,
+sr & STM32_QSPI_SR_TCF,
+STM32_QSPI_CMD_TIMEOUT_US);
+   if (ret) {
+   log_err("cmd timeout (stat:%#x)\n", sr);
+   } else if (readl(>regs->sr) & STM32_QSPI_SR_TEF) {
+   log_err("transfer error (stat:%#x)\n", sr);
+   ret = -EIO;
+   }
+   /* clear flags */
+   writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, 
>regs->fcr);
}
 
-   /* clear flags */
-   writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, >regs->fcr);
+   if (!ret)
+   ret = _stm32_qspi_wait_for_not_busy(priv);
 
return ret;
 }
-- 
2.31.0



[PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts

2021-05-23 Thread Daniil Stas
Disabling clk_ck clock leads to link up status loss in phy, which
leads to auto-negotiation restart before each network command
execution.

This issue is especially big for PXE boot protocol because of
auto-negotiation restarts before each configuration filename trial.

To avoid this issue don't disable clk_ck clock after it was enabled.

Signed-off-by: Daniil Stas 
Cc: Ramon Fried 
Cc: Joe Hershberger 
Cc: Patrick Delaunay 
Cc: Patrice Chotard 
---
 drivers/net/dwc_eth_qos.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index e8242ca4e1..2f088c758f 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -321,6 +321,7 @@ struct eqos_priv {
void *rx_pkt;
bool started;
bool reg_access_ok;
+   bool clk_ck_enabled;
 };
 
 /*
@@ -591,12 +592,13 @@ static int eqos_start_clks_stm32(struct udevice *dev)
goto err_disable_clk_rx;
}
 
-   if (clk_valid(>clk_ck)) {
+   if (clk_valid(>clk_ck) && !eqos->clk_ck_enabled) {
ret = clk_enable(>clk_ck);
if (ret < 0) {
pr_err("clk_enable(clk_ck) failed: %d", ret);
goto err_disable_clk_tx;
}
+   eqos->clk_ck_enabled = true;
}
 #endif
 
@@ -648,8 +650,6 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
clk_disable(>clk_tx);
clk_disable(>clk_rx);
clk_disable(>clk_master_bus);
-   if (clk_valid(>clk_ck))
-   clk_disable(>clk_ck);
 #endif
 
debug("%s: OK\n", __func__);
-- 
2.31.0



Re: [PATCH 5/8] net: dwc_eth_qos: add dwc eqos for imx support

2021-05-04 Thread Daniil Stas
Hi, i think there are some issues with this patch.

> @@ -1131,6 +1205,7 @@ static int eqos_start(struct udevice *dev)
>   }
>  
>   /* Configure MTL */
> + writel(0x60, >mtl_regs->txq0_quantum_weight - 0x100);
>  
>   /* Enable Store and Forward mode for TX */
>   /* Program Tx operating mode */

What is this address: >mtl_regs->txq0_quantum_weight - 0x100?
Isn't it outside of MTL registers range?

> @@ -1144,7 +1219,9 @@ static int eqos_start(struct udevice *dev)
>  
>   /* Enable Store and Forward mode for RX, since no jumbo frame */
>   setbits_le32(>mtl_regs->rxq0_operation_mode,
> -  EQOS_MTL_RXQ0_OPERATION_MODE_RSF);
> +  EQOS_MTL_RXQ0_OPERATION_MODE_RSF |
> +  EQOS_MTL_RXQ0_OPERATION_MODE_FEP |
> +  EQOS_MTL_RXQ0_OPERATION_MODE_FUP);
>  
>   /* Transmit/Receive queue fifo size; use all RAM for 1 queue */
>   val = readl(>mac_regs->hw_feature1);

Why do you set FEP and FUP bits? It can lead to data corruption as they
allow accepting erroneous packets.

I think these options should only be used in some debugging mode but not
in production.

> @@ -1220,6 +1297,19 @@ static int eqos_start(struct udevice *dev)
>   eqos->config->config_mac <<
>   EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
>  
> + clrsetbits_le32(>mac_regs->rxq_ctrl0,
> + EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
> + EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
> + 0x2 <<
> + EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
> +

This line just overrides the value set in the previous line.
Is it a mistake?

> + /* enable promise mode */
> + setbits_le32(>mac_regs->unused_004[1],
> +  0x1);
> +

Isn't this mode also useful only for debugging?