summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/mv88e6xxx
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2023-05-25 11:38:50 +0100
committerDavid S. Miller <davem@davemloft.net>2023-05-26 10:39:40 +0100
commit267d7692f6cd5c9b8796324cdd54db594ca8d3e4 (patch)
treef153403dd85604db59a125b699b1426f35985426 /drivers/net/dsa/mv88e6xxx
parentdd805cf3e80e038aeb06902399ce9bd6fafb4ff3 (diff)
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>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx')
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 64a2f2f83735..5bbe95fa951c 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -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,