OSDN Git Service

net: dsa: mv88e6xxx: move link forcing to mac_prepare/mac_finish
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Thu, 25 May 2023 10:38:50 +0000 (11:38 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 May 2023 09:39:40 +0000 (10:39 +0100)
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>
drivers/net/dsa/mv88e6xxx/chip.c

index 64a2f2f..5bbe95f 100644 (file)
@@ -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,