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: Chris Packham <chris.packham@alliedtelesis.co.nz> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0f614511fa
commit
4efe766290
|
@ -727,8 +727,8 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
|||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) && ops->port_set_link)
|
||||
err = ops->port_set_link(chip, port, LINK_FORCED_DOWN);
|
||||
mode == MLO_AN_FIXED) && ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, false);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
if (err)
|
||||
|
@ -768,8 +768,8 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (ops->port_set_link)
|
||||
err = ops->port_set_link(chip, port, LINK_FORCED_UP);
|
||||
if (ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, true);
|
||||
}
|
||||
error:
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
@ -3210,6 +3210,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
@ -3249,6 +3250,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6185_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6185_port_set_egress_floods,
|
||||
|
@ -3279,6 +3281,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6185_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
@ -3317,6 +3320,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6352_port_set_egress_floods,
|
||||
|
@ -3351,6 +3355,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
@ -3392,6 +3397,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6341_port_max_speed_mode,
|
||||
|
@ -3443,6 +3449,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
@ -3484,6 +3491,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
|||
.phy_read = mv88e6165_phy_read,
|
||||
.phy_write = mv88e6165_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
|
@ -3518,6 +3526,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -3560,6 +3569,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -3611,6 +3621,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -3653,6 +3664,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -3706,6 +3718,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6185_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6185_port_set_egress_floods,
|
||||
|
@ -3743,6 +3756,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
@ -3802,6 +3816,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
|
||||
|
@ -3861,6 +3876,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
@ -3920,6 +3936,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -3978,6 +3995,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -4015,6 +4033,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
@ -4076,6 +4095,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
@ -4118,6 +4138,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
@ -4158,6 +4179,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6341_port_max_speed_mode,
|
||||
|
@ -4211,6 +4233,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -4251,6 +4274,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -4295,6 +4319,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
@ -4355,6 +4380,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
@ -4418,6 +4444,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
|
||||
|
|
|
@ -417,6 +417,10 @@ struct mv88e6xxx_ops {
|
|||
*/
|
||||
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_OFF 0
|
||||
|
||||
|
|
|
@ -162,6 +162,42 @@ int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
|
|||
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,
|
||||
int port, int speed, bool alt_bit,
|
||||
bool force_bit, int duplex)
|
||||
|
|
|
@ -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_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 speed, int duplex);
|
||||
int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
|
||||
|
|
Loading…
Reference in New Issue