Skip to content

Commit 04ec4e6

Browse files
Russell King (Oracle)kuba-moo
authored andcommitted
net: dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports
Martyn Welch reports that his CPU port is unable to link where it has been necessary to use one of the switch ports with an internal PHY for the CPU port. The reason behind this is the port control register is left forcing the link down, preventing traffic flow. This occurs because during initialisation, phylink expects the link to be down, and DSA forces the link down by synthesising a call to the DSA drivers phylink_mac_link_down() method, but we don't touch the forced-link state when we later reconfigure the port. Resolve this by also unforcing the link state when we are operating in PHY mode and the PPU is set to poll the PHY to retrieve link status information. Reported-by: Martyn Welch <[email protected]> Tested-by: Martyn Welch <[email protected]> Fixes: 3be98b2 ("net: dsa: Down cpu/dsa ports phylink will control") Cc: <[email protected]> # 5.7: 2b29cb9: net: dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's" Signed-off-by: Russell King (Oracle) <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 1996178 commit 04ec4e6

File tree

1 file changed

+34
-30
lines changed
  • drivers/net/dsa/mv88e6xxx

1 file changed

+34
-30
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -698,44 +698,48 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
698698
{
699699
struct mv88e6xxx_chip *chip = ds->priv;
700700
struct mv88e6xxx_port *p;
701-
int err;
701+
int err = 0;
702702

703703
p = &chip->ports[port];
704704

705-
/* FIXME: is this the correct test? If we're in fixed mode on an
706-
* internal port, why should we process this any different from
707-
* PHY mode? On the other hand, the port may be automedia between
708-
* an internal PHY and the serdes...
709-
*/
710-
if ((mode == MLO_AN_PHY) && mv88e6xxx_phy_is_internal(ds, port))
711-
return;
712-
713705
mv88e6xxx_reg_lock(chip);
714-
/* In inband mode, the link may come up at any time while the link
715-
* is not forced down. Force the link down while we reconfigure the
716-
* interface mode.
717-
*/
718-
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
719-
chip->info->ops->port_set_link)
720-
chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
721-
722-
err = mv88e6xxx_port_config_interface(chip, port, state->interface);
723-
if (err && err != -EOPNOTSUPP)
724-
goto err_unlock;
725706

726-
err = mv88e6xxx_serdes_pcs_config(chip, port, mode, state->interface,
727-
state->advertising);
728-
/* FIXME: we should restart negotiation if something changed - which
729-
* is something we get if we convert to using phylinks PCS operations.
730-
*/
731-
if (err > 0)
732-
err = 0;
707+
if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
708+
/* In inband mode, the link may come up at any time while the
709+
* link is not forced down. Force the link down while we
710+
* reconfigure the interface mode.
711+
*/
712+
if (mode == MLO_AN_INBAND &&
713+
p->interface != state->interface &&
714+
chip->info->ops->port_set_link)
715+
chip->info->ops->port_set_link(chip, port,
716+
LINK_FORCED_DOWN);
717+
718+
err = mv88e6xxx_port_config_interface(chip, port,
719+
state->interface);
720+
if (err && err != -EOPNOTSUPP)
721+
goto err_unlock;
722+
723+
err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
724+
state->interface,
725+
state->advertising);
726+
/* FIXME: we should restart negotiation if something changed -
727+
* which is something we get if we convert to using phylinks
728+
* PCS operations.
729+
*/
730+
if (err > 0)
731+
err = 0;
732+
}
733733

734734
/* Undo the forced down state above after completing configuration
735-
* irrespective of its state on entry, which allows the link to come up.
735+
* irrespective of its state on entry, which allows the link to come
736+
* up in the in-band case where there is no separate SERDES. Also
737+
* ensure that the link can come up if the PPU is in use and we are
738+
* in PHY mode (we treat the PPU as an effective in-band mechanism.)
736739
*/
737-
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
738-
chip->info->ops->port_set_link)
740+
if (chip->info->ops->port_set_link &&
741+
((mode == MLO_AN_INBAND && p->interface != state->interface) ||
742+
(mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
739743
chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
740744

741745
p->interface = state->interface;

0 commit comments

Comments
 (0)