Commit 4efe7662 authored by Chris Packham's avatar Chris Packham Committed by Jakub Kicinski

net: dsa: mv88e6xxx: Don't force link when using in-band-status

When a port is configured with 'managed = "in-band-status"' switch chips
like the 88E6390 need to propagate the SERDES link state to the MAC
because the link state is not correctly detected. This causes problems
on the 88E6185/88E6097 where the link partner won't see link state
changes because we're forcing the link.

To address this introduce a new device specific op port_sync_link() and
push the logic from mv88e6xxx_mac_link_up() into that. Provide an
implementation for the 88E6185 like devices which doesn't force the
link.
Signed-off-by: default avatarChris Packham <chris.packham@alliedtelesis.co.nz>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 0f614511
This diff is collapsed.
...@@ -417,6 +417,10 @@ struct mv88e6xxx_ops { ...@@ -417,6 +417,10 @@ struct mv88e6xxx_ops {
*/ */
int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link); int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
/* Synchronise the port link state with that of the SERDES
*/
int (*port_sync_link)(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
#define PAUSE_ON 1 #define PAUSE_ON 1
#define PAUSE_OFF 0 #define PAUSE_OFF 0
......
...@@ -162,6 +162,42 @@ int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link) ...@@ -162,6 +162,42 @@ int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
return 0; return 0;
} }
int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
{
const struct mv88e6xxx_ops *ops = chip->info->ops;
int err = 0;
int link;
if (isup)
link = LINK_FORCED_UP;
else
link = LINK_FORCED_DOWN;
if (ops->port_set_link)
err = ops->port_set_link(chip, port, link);
return err;
}
int mv88e6185_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
{
const struct mv88e6xxx_ops *ops = chip->info->ops;
int err = 0;
int link;
if (mode == MLO_AN_INBAND)
link = LINK_UNFORCED;
else if (isup)
link = LINK_FORCED_UP;
else
link = LINK_FORCED_DOWN;
if (ops->port_set_link)
err = ops->port_set_link(chip, port, link);
return err;
}
static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip, static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
int port, int speed, bool alt_bit, int port, int speed, bool alt_bit,
bool force_bit, int duplex) bool force_bit, int duplex)
......
...@@ -298,6 +298,9 @@ int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, ...@@ -298,6 +298,9 @@ int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link); int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link);
int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
int mv88e6185_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
int mv88e6065_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port, int mv88e6065_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
int speed, int duplex); int speed, int duplex);
int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port, int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment