aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2019-03-23 14:41:32 -0400
committerDavid S. Miller <davem@davemloft.net>2019-03-28 00:53:50 -0400
commit5ceaeb99ffb4dc002d20f6ac243c19a85e2c7a76 (patch)
treec150bcef76e6f3704a61c986a8aefbfaca4d285b /drivers/net/dsa
parent1a9df9e29c2afecf6e3089442d429b377279ca3c (diff)
net: dsa: mv88e6xxx: fix few issues in mv88e6390x_port_set_cmode
This patches fixes few issues in mv88e6390x_port_set_cmode(). 1. When entering the function the old cmode may be 0, in this case mv88e6390x_serdes_get_lane() returns -ENODEV. As result we bail out and have no chance to set a new mode. Therefore deal properly with -ENODEV. 2. Once we have disabled power and irq, let's set the cached cmode to 0. This reflects the actual status and is cleaner if we bail out with an error in the following function calls. 3. The cached cmode is used by mv88e6390x_serdes_get_lane(), mv88e6390_serdes_power_lane() and mv88e6390_serdes_irq_enable(). Currently we set the cached mode to the new one at the very end of the function only, means until then we use the old one what may be wrong. 4. When calling mv88e6390_serdes_irq_enable() we use the lane value belonging to the old cmode. Get the lane belonging to the new cmode before calling this function. It's hard to provide a good "Fixes" tag because quite a few smaller changes have been done to the code in question recently. Fixes: d235c48b40d3 ("net: dsa: mv88e6xxx: power serdes on/off for 10G interfaces on 6390X") Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index dce84a2a65c7..c44b2822e4dd 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -427,18 +427,22 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
427 return 0; 427 return 0;
428 428
429 lane = mv88e6390x_serdes_get_lane(chip, port); 429 lane = mv88e6390x_serdes_get_lane(chip, port);
430 if (lane < 0) 430 if (lane < 0 && lane != -ENODEV)
431 return lane; 431 return lane;
432 432
433 if (chip->ports[port].serdes_irq) { 433 if (lane >= 0) {
434 err = mv88e6390_serdes_irq_disable(chip, port, lane); 434 if (chip->ports[port].serdes_irq) {
435 err = mv88e6390_serdes_irq_disable(chip, port, lane);
436 if (err)
437 return err;
438 }
439
440 err = mv88e6390x_serdes_power(chip, port, false);
435 if (err) 441 if (err)
436 return err; 442 return err;
437 } 443 }
438 444
439 err = mv88e6390x_serdes_power(chip, port, false); 445 chip->ports[port].cmode = 0;
440 if (err)
441 return err;
442 446
443 if (cmode) { 447 if (cmode) {
444 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg); 448 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
@@ -452,6 +456,12 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
452 if (err) 456 if (err)
453 return err; 457 return err;
454 458
459 chip->ports[port].cmode = cmode;
460
461 lane = mv88e6390x_serdes_get_lane(chip, port);
462 if (lane < 0)
463 return lane;
464
455 err = mv88e6390x_serdes_power(chip, port, true); 465 err = mv88e6390x_serdes_power(chip, port, true);
456 if (err) 466 if (err)
457 return err; 467 return err;
@@ -463,8 +473,6 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
463 } 473 }
464 } 474 }
465 475
466 chip->ports[port].cmode = cmode;
467
468 return 0; 476 return 0;
469} 477}
470 478