All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts
@ 2021-05-23 22:24 Daniil Stas
  2021-05-23 22:24 ` [PATCH] spi: stm32_qspi: Fix short data write operation Daniil Stas
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Daniil Stas @ 2021-05-23 22:24 UTC (permalink / raw)
  To: u-boot
  Cc: Daniil Stas, Ramon Fried, Joe Hershberger, Patrick Delaunay,
	Patrice Chotard

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 <daniil.stas@posteo.net>
Cc: Ramon Fried <rfried.dev@gmail.com>
Cc: Joe Hershberger <joe.hershberger@ni.com>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: Patrice Chotard <patrice.chotard@foss.st.com>
---
 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(&eqos->clk_ck)) {
+	if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
 		ret = clk_enable(&eqos->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(&eqos->clk_tx);
 	clk_disable(&eqos->clk_rx);
 	clk_disable(&eqos->clk_master_bus);
-	if (clk_valid(&eqos->clk_ck))
-		clk_disable(&eqos->clk_ck);
 #endif
 
 	debug("%s: OK\n", __func__);
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH] spi: stm32_qspi: Fix short data write operation
  2021-05-23 22:24 [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Daniil Stas
@ 2021-05-23 22:24 ` Daniil Stas
  2021-05-24  7:40   ` Patrice CHOTARD
  2021-06-01 15:31   ` Patrick DELAUNAY
  2021-05-24  8:30 ` [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Patrice CHOTARD
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 11+ messages in thread
From: Daniil Stas @ 2021-05-23 22:24 UTC (permalink / raw)
  To: u-boot; +Cc: Daniil Stas, Patrick Delaunay, Patrice Chotard

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 <daniil.stas@posteo.net>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: Patrice Chotard <patrice.chotard@foss.st.com>
---
 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(&priv->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(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
-		log_err("transfer error (stat:%#x)\n", sr);
-		ret = -EIO;
+	if (op->data.nbytes) {
+		ret = readl_poll_timeout(&priv->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(&priv->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, &priv->regs->fcr);
 	}
 
-	/* clear flags */
-	writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr);
+	if (!ret)
+		ret = _stm32_qspi_wait_for_not_busy(priv);
 
 	return ret;
 }
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] spi: stm32_qspi: Fix short data write operation
  2021-05-23 22:24 ` [PATCH] spi: stm32_qspi: Fix short data write operation Daniil Stas
@ 2021-05-24  7:40   ` Patrice CHOTARD
  2021-05-24 12:53     ` Daniil Stas
  2021-06-01 15:31   ` Patrick DELAUNAY
  1 sibling, 1 reply; 11+ messages in thread
From: Patrice CHOTARD @ 2021-05-24  7:40 UTC (permalink / raw)
  To: Daniil Stas, u-boot; +Cc: Patrick Delaunay

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 <daniil.stas@posteo.net>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> ---
>  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(&priv->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(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
> -		log_err("transfer error (stat:%#x)\n", sr);
> -		ret = -EIO;
> +	if (op->data.nbytes) {
> +		ret = readl_poll_timeout(&priv->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(&priv->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, &priv->regs->fcr);
>  	}
>  
> -	/* clear flags */
> -	writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts
  2021-05-23 22:24 [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Daniil Stas
  2021-05-23 22:24 ` [PATCH] spi: stm32_qspi: Fix short data write operation Daniil Stas
@ 2021-05-24  8:30 ` Patrice CHOTARD
  2021-05-25  6:53 ` Ramon Fried
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Patrice CHOTARD @ 2021-05-24  8:30 UTC (permalink / raw)
  To: Daniil Stas, u-boot, Christophe ROULLIER
  Cc: Ramon Fried, Joe Hershberger, Patrick Delaunay

Hi Daniil

+Christophe

Thanks
Patrice

On 5/24/21 12:24 AM, Daniil Stas wrote:
> 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 <daniil.stas@posteo.net>
> Cc: Ramon Fried <rfried.dev@gmail.com>
> Cc: Joe Hershberger <joe.hershberger@ni.com>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> ---
>  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(&eqos->clk_ck)) {
> +	if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
>  		ret = clk_enable(&eqos->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(&eqos->clk_tx);
>  	clk_disable(&eqos->clk_rx);
>  	clk_disable(&eqos->clk_master_bus);
> -	if (clk_valid(&eqos->clk_ck))
> -		clk_disable(&eqos->clk_ck);
>  #endif
>  
>  	debug("%s: OK\n", __func__);
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] spi: stm32_qspi: Fix short data write operation
  2021-05-24  7:40   ` Patrice CHOTARD
@ 2021-05-24 12:53     ` Daniil Stas
  2021-05-25 16:02       ` Patrice CHOTARD
  0 siblings, 1 reply; 11+ messages in thread
From: Daniil Stas @ 2021-05-24 12:53 UTC (permalink / raw)
  To: Patrice CHOTARD; +Cc: u-boot, Patrick Delaunay

On Mon, 24 May 2021 09:40:05 +0200
Patrice CHOTARD <patrice.chotard@foss.st.com> 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 <daniil.stas@posteo.net>
> > Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> > Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> > ---
> >  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(&priv->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(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
> > -		log_err("transfer error (stat:%#x)\n", sr);
> > -		ret = -EIO;
> > +	if (op->data.nbytes) {
> > +		ret = readl_poll_timeout(&priv->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(&priv->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,
> > &priv->regs->fcr); }
> >  
> > -	/* clear flags */
> > -	writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF,
> > &priv->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 0x00300000 +1
SF: 65536 bytes @ 0x300000 Erased: OK
STM32MP> sf read 0xc4100000 0x300000 10
device 0 offset 0x300000, size 0x10
SF: 16 bytes @ 0x300000 Read: OK
STM32MP> md.b 0xc4100000
c4100000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
...
STM32MP> mw.b 0xc4200000 55
STM32MP> sf write 0xc4200000 0x00300000 1
device 0 offset 0x300000, size 0x1
SF: 1 bytes @ 0x300000 Written: OK
STM32MP> sf read 0xc4100000 0x00300000 10
device 0 offset 0x300000, size 0x10
SF: 16 bytes @ 0x300000 Read: OK
STM32MP> md.b 0xc4100000
c4100000: 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 0xc4100000
c4100000: 55 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    U...............

Thanks,
Daniil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts
  2021-05-23 22:24 [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Daniil Stas
  2021-05-23 22:24 ` [PATCH] spi: stm32_qspi: Fix short data write operation Daniil Stas
  2021-05-24  8:30 ` [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Patrice CHOTARD
@ 2021-05-25  6:53 ` Ramon Fried
  2021-06-01 15:26 ` Patrick DELAUNAY
  2021-06-12 18:36 ` Ramon Fried
  4 siblings, 0 replies; 11+ messages in thread
From: Ramon Fried @ 2021-05-25  6:53 UTC (permalink / raw)
  To: Daniil Stas
  Cc: U-Boot Mailing List, Joe Hershberger, Patrick Delaunay, Patrice Chotard

On Mon, May 24, 2021 at 1:18 AM Daniil Stas <daniil.stas@posteo.net> wrote:
>
> 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 <daniil.stas@posteo.net>
> Cc: Ramon Fried <rfried.dev@gmail.com>
> Cc: Joe Hershberger <joe.hershberger@ni.com>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> ---
>  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(&eqos->clk_ck)) {
> +       if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
>                 ret = clk_enable(&eqos->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(&eqos->clk_tx);
>         clk_disable(&eqos->clk_rx);
>         clk_disable(&eqos->clk_master_bus);
> -       if (clk_valid(&eqos->clk_ck))
> -               clk_disable(&eqos->clk_ck);
>  #endif
>
>         debug("%s: OK\n", __func__);
> --
> 2.31.0
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com >

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] spi: stm32_qspi: Fix short data write operation
  2021-05-24 12:53     ` Daniil Stas
@ 2021-05-25 16:02       ` Patrice CHOTARD
  2021-06-18  8:01         ` Patrice CHOTARD
  0 siblings, 1 reply; 11+ messages in thread
From: Patrice CHOTARD @ 2021-05-25 16:02 UTC (permalink / raw)
  To: Daniil Stas; +Cc: u-boot, Patrick Delaunay

Hi Daniil

On 5/24/21 2:53 PM, Daniil Stas wrote:
> On Mon, 24 May 2021 09:40:05 +0200
> Patrice CHOTARD <patrice.chotard@foss.st.com> 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 <daniil.stas@posteo.net>
>>> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
>>> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
>>> ---
>>>  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(&priv->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(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
>>> -		log_err("transfer error (stat:%#x)\n", sr);
>>> -		ret = -EIO;
>>> +	if (op->data.nbytes) {
>>> +		ret = readl_poll_timeout(&priv->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(&priv->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,
>>> &priv->regs->fcr); }
>>>  
>>> -	/* clear flags */
>>> -	writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF,
>>> &priv->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 0x00300000 +1
> SF: 65536 bytes @ 0x300000 Erased: OK
> STM32MP> sf read 0xc4100000 0x300000 10
> device 0 offset 0x300000, size 0x10
> SF: 16 bytes @ 0x300000 Read: OK
> STM32MP> md.b 0xc4100000
> c4100000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
> ...
> STM32MP> mw.b 0xc4200000 55
> STM32MP> sf write 0xc4200000 0x00300000 1
> device 0 offset 0x300000, size 0x1
> SF: 1 bytes @ 0x300000 Written: OK
> STM32MP> sf read 0xc4100000 0x00300000 10
> device 0 offset 0x300000, size 0x10
> SF: 16 bytes @ 0x300000 Read: OK
> STM32MP> md.b 0xc4100000
> c4100000: 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 0xc4100000
> c4100000: 55 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    U...............
> 
> Thanks,
> Daniil
> 

Thanks for the detailed informations, i also reproduced this issue on a stm32mp157c-ev1 board.

Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Patrice



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts
  2021-05-23 22:24 [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Daniil Stas
                   ` (2 preceding siblings ...)
  2021-05-25  6:53 ` Ramon Fried
@ 2021-06-01 15:26 ` Patrick DELAUNAY
  2021-06-12 18:36 ` Ramon Fried
  4 siblings, 0 replies; 11+ messages in thread
From: Patrick DELAUNAY @ 2021-06-01 15:26 UTC (permalink / raw)
  To: Daniil Stas, u-boot
  Cc: Ramon Fried, Joe Hershberger, Patrice Chotard, Christophe ROULLIER

Hi,

On 5/24/21 12:24 AM, Daniil Stas wrote:
> 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 <daniil.stas@posteo.net>
> Cc: Ramon Fried <rfried.dev@gmail.com>
> Cc: Joe Hershberger <joe.hershberger@ni.com>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> ---
>   drivers/net/dwc_eth_qos.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] spi: stm32_qspi: Fix short data write operation
  2021-05-23 22:24 ` [PATCH] spi: stm32_qspi: Fix short data write operation Daniil Stas
  2021-05-24  7:40   ` Patrice CHOTARD
@ 2021-06-01 15:31   ` Patrick DELAUNAY
  1 sibling, 0 replies; 11+ messages in thread
From: Patrick DELAUNAY @ 2021-06-01 15:31 UTC (permalink / raw)
  To: Daniil Stas, u-boot; +Cc: Patrice Chotard

Hi,

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 <daniil.stas@posteo.net>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> ---
>   drivers/spi/stm32_qspi.c | 29 +++++++++++++++--------------
>   1 file changed, 15 insertions(+), 14 deletions(-)
>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts
  2021-05-23 22:24 [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Daniil Stas
                   ` (3 preceding siblings ...)
  2021-06-01 15:26 ` Patrick DELAUNAY
@ 2021-06-12 18:36 ` Ramon Fried
  4 siblings, 0 replies; 11+ messages in thread
From: Ramon Fried @ 2021-06-12 18:36 UTC (permalink / raw)
  To: Daniil Stas, u-boot; +Cc: Joe Hershberger, Patrick Delaunay, Patrice Chotard

On Mon May 24, 2021 at 1:24 AM IDT, Daniil Stas wrote:
> 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 <daniil.stas@posteo.net>
> Cc: Ramon Fried <rfried.dev@gmail.com>
> Cc: Joe Hershberger <joe.hershberger@ni.com>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
> ---
> 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(&eqos->clk_ck)) {
> + if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
> ret = clk_enable(&eqos->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(&eqos->clk_tx);
> clk_disable(&eqos->clk_rx);
> clk_disable(&eqos->clk_master_bus);
> - if (clk_valid(&eqos->clk_ck))
> - clk_disable(&eqos->clk_ck);
> #endif
>  
> debug("%s: OK\n", __func__);
> --
> 2.31.0

Applied to u-boot-net/master, thanks!

Best regards,
Ramon Fried

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] spi: stm32_qspi: Fix short data write operation
  2021-05-25 16:02       ` Patrice CHOTARD
@ 2021-06-18  8:01         ` Patrice CHOTARD
  0 siblings, 0 replies; 11+ messages in thread
From: Patrice CHOTARD @ 2021-06-18  8:01 UTC (permalink / raw)
  To: Daniil Stas; +Cc: u-boot, Patrick Delaunay



On 5/25/21 6:02 PM, Patrice CHOTARD wrote:
> Hi Daniil
> 
> On 5/24/21 2:53 PM, Daniil Stas wrote:
>> On Mon, 24 May 2021 09:40:05 +0200
>> Patrice CHOTARD <patrice.chotard@foss.st.com> 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 <daniil.stas@posteo.net>
>>>> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
>>>> Cc: Patrice Chotard <patrice.chotard@foss.st.com>
>>>> ---
>>>>  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(&priv->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(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
>>>> -		log_err("transfer error (stat:%#x)\n", sr);
>>>> -		ret = -EIO;
>>>> +	if (op->data.nbytes) {
>>>> +		ret = readl_poll_timeout(&priv->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(&priv->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,
>>>> &priv->regs->fcr); }
>>>>  
>>>> -	/* clear flags */
>>>> -	writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF,
>>>> &priv->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 0x00300000 +1
>> SF: 65536 bytes @ 0x300000 Erased: OK
>> STM32MP> sf read 0xc4100000 0x300000 10
>> device 0 offset 0x300000, size 0x10
>> SF: 16 bytes @ 0x300000 Read: OK
>> STM32MP> md.b 0xc4100000
>> c4100000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
>> ...
>> STM32MP> mw.b 0xc4200000 55
>> STM32MP> sf write 0xc4200000 0x00300000 1
>> device 0 offset 0x300000, size 0x1
>> SF: 1 bytes @ 0x300000 Written: OK
>> STM32MP> sf read 0xc4100000 0x00300000 10
>> device 0 offset 0x300000, size 0x10
>> SF: 16 bytes @ 0x300000 Read: OK
>> STM32MP> md.b 0xc4100000
>> c4100000: 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 0xc4100000
>> c4100000: 55 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    U...............
>>
>> Thanks,
>> Daniil
>>
> 
> Thanks for the detailed informations, i also reproduced this issue on a stm32mp157c-ev1 board.
> 
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Patrice
> 
> 
Applied on u-boot-stm32/next

Thanks

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-06-18  8:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-23 22:24 [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Daniil Stas
2021-05-23 22:24 ` [PATCH] spi: stm32_qspi: Fix short data write operation Daniil Stas
2021-05-24  7:40   ` Patrice CHOTARD
2021-05-24 12:53     ` Daniil Stas
2021-05-25 16:02       ` Patrice CHOTARD
2021-06-18  8:01         ` Patrice CHOTARD
2021-06-01 15:31   ` Patrick DELAUNAY
2021-05-24  8:30 ` [PATCH] net: dwc_eth_qos: Fix needless phy auto-negotiation restarts Patrice CHOTARD
2021-05-25  6:53 ` Ramon Fried
2021-06-01 15:26 ` Patrick DELAUNAY
2021-06-12 18:36 ` Ramon Fried

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.