diff options
author | Andrew Lunn <andrew@lunn.ch> | 2016-08-18 18:01:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-08-19 20:14:07 -0400 |
commit | 6441e6695acfce66499c186c591f319a3b125de7 (patch) | |
tree | 6176d51df774454eb72af38c718cc4acb1f7f85b /drivers/net/dsa | |
parent | 7a7e780cd702fb39edc9af96e75e0cc2b00234f2 (diff) |
dsa: mv88e6xxx: Timeout based on iterations, not time
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 15 |
1 files 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) | |||
309 | static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, | 309 | static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, |
310 | u16 mask) | 310 | u16 mask) |
311 | { | 311 | { |
312 | unsigned long timeout = jiffies + HZ / 10; | 312 | int i; |
313 | 313 | ||
314 | while (time_before(jiffies, timeout)) { | 314 | for (i = 0; i < 16; i++) { |
315 | u16 val; | 315 | u16 val; |
316 | int err; | 316 | int err; |
317 | 317 | ||
@@ -375,7 +375,7 @@ static int _mv88e6xxx_reg_write(struct mv88e6xxx_chip *chip, int addr, | |||
375 | static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) | 375 | static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) |
376 | { | 376 | { |
377 | int ret; | 377 | int ret; |
378 | unsigned long timeout; | 378 | int i; |
379 | 379 | ||
380 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL); | 380 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL); |
381 | if (ret < 0) | 381 | if (ret < 0) |
@@ -386,8 +386,7 @@ static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) | |||
386 | if (ret) | 386 | if (ret) |
387 | return ret; | 387 | return ret; |
388 | 388 | ||
389 | timeout = jiffies + 1 * HZ; | 389 | for (i = 0; i < 16; i++) { |
390 | while (time_before(jiffies, timeout)) { | ||
391 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS); | 390 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS); |
392 | if (ret < 0) | 391 | if (ret < 0) |
393 | return ret; | 392 | return ret; |
@@ -403,8 +402,7 @@ static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) | |||
403 | 402 | ||
404 | static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip) | 403 | static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip) |
405 | { | 404 | { |
406 | int ret, err; | 405 | int ret, err, i; |
407 | unsigned long timeout; | ||
408 | 406 | ||
409 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL); | 407 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL); |
410 | if (ret < 0) | 408 | if (ret < 0) |
@@ -415,8 +413,7 @@ static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip) | |||
415 | if (err) | 413 | if (err) |
416 | return err; | 414 | return err; |
417 | 415 | ||
418 | timeout = jiffies + 1 * HZ; | 416 | for (i = 0; i < 16; i++) { |
419 | while (time_before(jiffies, timeout)) { | ||
420 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS); | 417 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS); |
421 | if (ret < 0) | 418 | if (ret < 0) |
422 | return ret; | 419 | return ret; |