mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
net: dsa: mv88e6xxx: move link forcing to mac_prepare/mac_finish
Move the link forcing out of mac_config() and into the mac_prepare() and mac_finish() methods. This results in no change to the order in which these operations are performed, but does mean when we convert mv88e6xxx to phylink_pcs support, we will continue to preserve this ordering. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
dd805cf3e8
commit
267d7692f6
1 changed files with 45 additions and 20 deletions
|
@ -841,29 +841,38 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
|
|||
}
|
||||
}
|
||||
|
||||
static int mv88e6xxx_mac_prepare(struct dsa_switch *ds, int port,
|
||||
unsigned int mode, phy_interface_t interface)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
int err = 0;
|
||||
|
||||
/* 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 &&
|
||||
chip->ports[port].interface != interface &&
|
||||
chip->info->ops->port_set_link) {
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
err = chip->info->ops->port_set_link(chip, port,
|
||||
LINK_FORCED_DOWN);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
||||
unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
struct mv88e6xxx_port *p;
|
||||
int err = 0;
|
||||
|
||||
p = &chip->ports[port];
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
|
||||
if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
|
||||
/* 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)
|
||||
|
@ -880,24 +889,38 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
|||
err = 0;
|
||||
}
|
||||
|
||||
err_unlock:
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_mac_finish(struct dsa_switch *ds, int port,
|
||||
unsigned int mode, phy_interface_t interface)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
int err = 0;
|
||||
|
||||
/* Undo the forced down state above after completing configuration
|
||||
* irrespective of its state on entry, which allows the link to come
|
||||
* up in the in-band case where there is no separate SERDES. Also
|
||||
* ensure that the link can come up if the PPU is in use and we are
|
||||
* in PHY mode (we treat the PPU as an effective in-band mechanism.)
|
||||
*/
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
|
||||
if (chip->info->ops->port_set_link &&
|
||||
((mode == MLO_AN_INBAND && p->interface != state->interface) ||
|
||||
((mode == MLO_AN_INBAND &&
|
||||
chip->ports[port].interface != interface) ||
|
||||
(mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
|
||||
chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
|
||||
err = chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
|
||||
|
||||
p->interface = state->interface;
|
||||
|
||||
err_unlock:
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
|
||||
chip->ports[port].interface = interface;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
||||
|
@ -7002,7 +7025,9 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
|||
.port_teardown = mv88e6xxx_port_teardown,
|
||||
.phylink_get_caps = mv88e6xxx_get_caps,
|
||||
.phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
|
||||
.phylink_mac_prepare = mv88e6xxx_mac_prepare,
|
||||
.phylink_mac_config = mv88e6xxx_mac_config,
|
||||
.phylink_mac_finish = mv88e6xxx_mac_finish,
|
||||
.phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
|
||||
.phylink_mac_link_down = mv88e6xxx_mac_link_down,
|
||||
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
|
||||
|
|
Loading…
Reference in a new issue