All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next] dsa: mv88e6xxx: Timeout based on iterations
@ 2016-08-17 21:27 Andrew Lunn
  2016-08-17 23:08 ` Vivien Didelot
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Lunn @ 2016-08-17 21:27 UTC (permalink / raw)
  To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn

The mv88e6xxx driver times out operations on the switch based on
looping until an elapsed wall clock time is reached. However, if
usleep_range() sleeps much longer than expected, it could timeout with
an error without actually checking to see if the devices has completed
the operation. So replace the elapsed time with a fixed upper bound on
the number of loops.

Testing on various switches has shown that switches takes either 0 or
1 iteration, so a maximum of 16 iterations is a safe limit.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index a230fcba5b64..ac8e9af4879f 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -309,9 +309,9 @@ static int mv88e6xxx_serdes_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
 static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg,
 			  u16 mask)
 {
-	unsigned long timeout = jiffies + HZ / 10;
+	int i;
 
-	while (time_before(jiffies, timeout)) {
+	for (i = 0; i < 16; i++) {
 		u16 val;
 		int err;
 
@@ -375,7 +375,7 @@ static int _mv88e6xxx_reg_write(struct mv88e6xxx_chip *chip, int addr,
 static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip)
 {
 	int ret;
-	unsigned long timeout;
+	int i;
 
 	ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL);
 	if (ret < 0)
@@ -386,8 +386,7 @@ static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip)
 	if (ret)
 		return ret;
 
-	timeout = jiffies + 1 * HZ;
-	while (time_before(jiffies, timeout)) {
+	for (i = 0; i < 16; i++) {
 		ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS);
 		if (ret < 0)
 			return ret;
@@ -403,8 +402,7 @@ static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip)
 
 static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip)
 {
-	int ret, err;
-	unsigned long timeout;
+	int ret, err, i;
 
 	ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL);
 	if (ret < 0)
@@ -415,8 +413,7 @@ static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip)
 	if (err)
 		return err;
 
-	timeout = jiffies + 1 * HZ;
-	while (time_before(jiffies, timeout)) {
+	for (i = 0; i < 16; i++) {
 		ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS);
 		if (ret < 0)
 			return ret;
-- 
2.8.1

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

* Re: [PATCH net-next] dsa: mv88e6xxx: Timeout based on iterations
  2016-08-17 21:27 [PATCH net-next] dsa: mv88e6xxx: Timeout based on iterations Andrew Lunn
@ 2016-08-17 23:08 ` Vivien Didelot
  2016-08-18 18:39   ` Andrew Lunn
  0 siblings, 1 reply; 3+ messages in thread
From: Vivien Didelot @ 2016-08-17 23:08 UTC (permalink / raw)
  To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> The mv88e6xxx driver times out operations on the switch based on
> looping until an elapsed wall clock time is reached. However, if
> usleep_range() sleeps much longer than expected, it could timeout with
> an error without actually checking to see if the devices has completed
> the operation. So replace the elapsed time with a fixed upper bound on
> the number of loops.
>
> Testing on various switches has shown that switches takes either 0 or
> 1 iteration, so a maximum of 16 iterations is a safe limit.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  drivers/net/dsa/mv88e6xxx/chip.c | 15 ++++++---------
>  1 file changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index a230fcba5b64..ac8e9af4879f 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -309,9 +309,9 @@ static int mv88e6xxx_serdes_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
>  static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg,
>  			  u16 mask)
>  {
> -	unsigned long timeout = jiffies + HZ / 10;
> +	int i;
>  
> -	while (time_before(jiffies, timeout)) {
> +	for (i = 0; i < 16; i++) {
>  		u16 val;
>  		int err;
>  

Since we remove the elapsed time here, can we use mv88e6xxx_wait in
mv88e6xxx_update? It'd be good to have a consistent wait routine
everywhere.

Thanks,

        Vivien

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

* Re: [PATCH net-next] dsa: mv88e6xxx: Timeout based on iterations
  2016-08-17 23:08 ` Vivien Didelot
@ 2016-08-18 18:39   ` Andrew Lunn
  0 siblings, 0 replies; 3+ messages in thread
From: Andrew Lunn @ 2016-08-18 18:39 UTC (permalink / raw)
  To: Vivien Didelot; +Cc: David Miller, netdev

> >  static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg,
> >  			  u16 mask)
> >  {
> > -	unsigned long timeout = jiffies + HZ / 10;
> > +	int i;
> >  
> > -	while (time_before(jiffies, timeout)) {
> > +	for (i = 0; i < 16; i++) {
> >  		u16 val;
> >  		int err;
> >  
> 
> Since we remove the elapsed time here, can we use mv88e6xxx_wait in
> mv88e6xxx_update? It'd be good to have a consistent wait routine
> everywhere.

Hi Vivien

Yes, it looks like that should work. I will add a second patch to do
this.

	Andrew

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

end of thread, other threads:[~2016-08-19  2:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-17 21:27 [PATCH net-next] dsa: mv88e6xxx: Timeout based on iterations Andrew Lunn
2016-08-17 23:08 ` Vivien Didelot
2016-08-18 18:39   ` Andrew Lunn

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.