Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: fix in-band AN link establishment
Browse files Browse the repository at this point in the history
If in-band negotiation or fixed-link modes are specified for a DSA
port, the DSA code will force the link down during initialisation. For
fixed-link mode, this is fine, as phylink will manage the link state.
However, for in-band mode, phylink expects the PCS to detect link,
which will not happen if the link is forced down.

There is a related issue that in in-band mode, the link could come up
while we are making configuration changes, so we should force the link
down prior to reconfiguring the interface mode.

This patch addresses both issues.

Fixes: 3be98b2 ("net: dsa: Down cpu/dsa ports phylink will control")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Russell King authored and David S. Miller committed Jul 20, 2020
1 parent a463fa2 commit fad5819
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
22 changes: 19 additions & 3 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,8 +664,11 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
const struct phylink_link_state *state)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct mv88e6xxx_port *p;
int err;

p = &chip->ports[port];

/* FIXME: is this the correct test? If we're in fixed mode on an
* internal port, why should we process this any different from
* PHY mode? On the other hand, the port may be automedia between
Expand All @@ -675,10 +678,14 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
return;

mv88e6xxx_reg_lock(chip);
/* FIXME: should we force the link down here - but if we do, how
* do we restore the link force/unforce state? The driver layering
* gets in the way.
/* In inband mode, the link may come up at any time while the link
* is not forced down. Force the link down while we reconfigure the
* interface mode.
*/
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
chip->info->ops->port_set_link)
chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);

err = mv88e6xxx_port_config_interface(chip, port, state->interface);
if (err && err != -EOPNOTSUPP)
goto err_unlock;
Expand All @@ -691,6 +698,15 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
if (err > 0)
err = 0;

/* Undo the forced down state above after completing configuration
* irrespective of its state on entry, which allows the link to come up.
*/
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
chip->info->ops->port_set_link)
chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);

p->interface = state->interface;

err_unlock:
mv88e6xxx_reg_unlock(chip);

Expand Down
1 change: 1 addition & 0 deletions drivers/net/dsa/mv88e6xxx/chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ struct mv88e6xxx_port {
u64 atu_full_violation;
u64 vtu_member_violation;
u64 vtu_miss_violation;
phy_interface_t interface;
u8 cmode;
bool mirror_ingress;
bool mirror_egress;
Expand Down

0 comments on commit fad5819

Please sign in to comment.