From: Baruch Siach baruch@tkos.co.il
[ Upstream commit f7a48b68abd9b20ce1ac6298aaaa3c4d158271dd ]
mv88e6xxx_port_set_cmode() relies on cmode stored in struct mv88e6xxx_port to skip cmode update when the requested value matches the cached value. It turns out that mv88e6xxx_port_hidden_write() might change the port cmode setting as a side effect, so we can't rely on the cached value to determine that cmode update in not necessary.
Force cmode update in mv88e6341_port_set_cmode(), to make serdes configuration work again. Other mv88e6xxx_port_set_cmode() callers keep the current behaviour.
This fixes serdes configuration of the 6141 switch on SolidRun Clearfog GT-8K.
Fixes: 7a3007d22e8 ("net: dsa: mv88e6xxx: fully support SERDES on Topaz family") Reported-by: Denis Odintsov d.odintsov@traviangames.com Signed-off-by: Baruch Siach baruch@tkos.co.il Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -393,7 +393,7 @@ phy_interface_t mv88e6390x_port_max_spee }
static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, - phy_interface_t mode) + phy_interface_t mode, bool force) { u8 lane; u16 cmode; @@ -427,8 +427,8 @@ static int mv88e6xxx_port_set_cmode(stru cmode = 0; }
- /* cmode doesn't change, nothing to do for us */ - if (cmode == chip->ports[port].cmode) + /* cmode doesn't change, nothing to do for us unless forced */ + if (cmode == chip->ports[port].cmode && !force) return 0;
lane = mv88e6xxx_serdes_get_lane(chip, port); @@ -484,7 +484,7 @@ int mv88e6390x_port_set_cmode(struct mv8 if (port != 9 && port != 10) return -EOPNOTSUPP;
- return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, false); }
int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, @@ -504,7 +504,7 @@ int mv88e6390_port_set_cmode(struct mv88 break; }
- return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, false); }
static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, @@ -555,7 +555,7 @@ int mv88e6341_port_set_cmode(struct mv88 if (err) return err;
- return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, true); }
int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)