lkml.org 
[lkml]   [2019]   [May]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 067/113] net: dsa: mv88e6xxx: fix few issues in mv88e6390x_port_set_cmode
    Date
    [ Upstream commit 5ceaeb99ffb4dc002d20f6ac243c19a85e2c7a76 ]

    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>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/net/dsa/mv88e6xxx/port.c | 24 ++++++++++++++++--------
    1 file changed, 16 insertions(+), 8 deletions(-)

    diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
    index 7fffce734f0a5..fdeddbfa829da 100644
    --- a/drivers/net/dsa/mv88e6xxx/port.c
    +++ b/drivers/net/dsa/mv88e6xxx/port.c
    @@ -379,18 +379,22 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
    return 0;

    lane = mv88e6390x_serdes_get_lane(chip, port);
    - if (lane < 0)
    + if (lane < 0 && lane != -ENODEV)
    return lane;

    - if (chip->ports[port].serdes_irq) {
    - err = mv88e6390_serdes_irq_disable(chip, port, lane);
    + if (lane >= 0) {
    + if (chip->ports[port].serdes_irq) {
    + err = mv88e6390_serdes_irq_disable(chip, port, lane);
    + if (err)
    + return err;
    + }
    +
    + err = mv88e6390x_serdes_power(chip, port, false);
    if (err)
    return err;
    }

    - err = mv88e6390x_serdes_power(chip, port, false);
    - if (err)
    - return err;
    + chip->ports[port].cmode = 0;

    if (cmode) {
    err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
    @@ -404,6 +408,12 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
    if (err)
    return err;

    + chip->ports[port].cmode = cmode;
    +
    + lane = mv88e6390x_serdes_get_lane(chip, port);
    + if (lane < 0)
    + return lane;
    +
    err = mv88e6390x_serdes_power(chip, port, true);
    if (err)
    return err;
    @@ -415,8 +425,6 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
    }
    }

    - chip->ports[port].cmode = cmode;
    -
    return 0;
    }

    --
    2.20.1


    \
     
     \ /
      Last update: 2019-05-15 13:49    [W:4.131 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site