]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: pcs: xpcs: move PCS reset to .pcs_pre_config()
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tue, 1 Oct 2024 16:04:10 +0000 (17:04 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 3 Oct 2024 00:31:59 +0000 (17:31 -0700)
Move the PCS reset to .pcs_pre_config() rather than at creation time,
which means we call the reset function with the interface that we're
actually going to be using to talk to the downstream device.

Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> # sja1105
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tested-by: for them?
Link: https://patch.msgid.link/E1svfMA-005ZI3-Va@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/pcs/pcs-xpcs.c
include/linux/pcs/pcs-xpcs.h

index 82463f9d50c85c3e5bb9d7498125e2ae3e673337..7c6c40ddf722e3000f438eeed1e852eff40a0a01 100644 (file)
@@ -659,6 +659,30 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
 }
 EXPORT_SYMBOL_GPL(xpcs_config_eee);
 
+static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface)
+{
+       struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
+       const struct dw_xpcs_compat *compat;
+       int ret;
+
+       if (!xpcs->need_reset)
+               return;
+
+       compat = xpcs_find_compat(xpcs->desc, interface);
+       if (!compat) {
+               dev_err(&xpcs->mdiodev->dev, "unsupported interface %s\n",
+                       phy_modes(interface));
+               return;
+       }
+
+       ret = xpcs_soft_reset(xpcs, compat);
+       if (ret)
+               dev_err(&xpcs->mdiodev->dev, "soft reset failed: %pe\n",
+                       ERR_PTR(ret));
+
+       xpcs->need_reset = false;
+}
+
 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
                                      unsigned int neg_mode)
 {
@@ -1365,6 +1389,7 @@ static const struct dw_xpcs_desc xpcs_desc_list[] = {
 
 static const struct phylink_pcs_ops xpcs_phylink_ops = {
        .pcs_validate = xpcs_validate,
+       .pcs_pre_config = xpcs_pre_config,
        .pcs_config = xpcs_config,
        .pcs_get_state = xpcs_get_state,
        .pcs_an_restart = xpcs_an_restart,
@@ -1460,18 +1485,12 @@ static int xpcs_init_id(struct dw_xpcs *xpcs)
 
 static int xpcs_init_iface(struct dw_xpcs *xpcs, phy_interface_t interface)
 {
-       const struct dw_xpcs_compat *compat;
-
-       compat = xpcs_find_compat(xpcs->desc, interface);
-       if (!compat)
-               return -EINVAL;
-
-       if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
+       if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
                xpcs->pcs.poll = false;
-               return 0;
-       }
+       else
+               xpcs->need_reset = true;
 
-       return xpcs_soft_reset(xpcs, compat);
+       return 0;
 }
 
 static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
index b4a4eb6c8866a759dacc7090c6918db5b2db541f..fd75d0605bb6948e4ae3d9b77e1ef24228ecb4b4 100644 (file)
@@ -61,6 +61,7 @@ struct dw_xpcs {
        struct clk_bulk_data clks[DW_XPCS_NUM_CLKS];
        struct phylink_pcs pcs;
        phy_interface_t interface;
+       bool need_reset;
 };
 
 int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);