forked from Openwrt/openwrt
2df8a0ccb0
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
82 lines
2.3 KiB
Diff
82 lines
2.3 KiB
Diff
From bfac8c490d605bea03b1f1927582b6f396462164 Mon Sep 17 00:00:00 2001
|
|
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
|
Date: Mon, 27 Jun 2022 12:44:43 +0100
|
|
Subject: [PATCH] net: phylink: disable PCS polling over major configuration
|
|
|
|
While we are performing a major configuration, there is no point having
|
|
the PCS polling timer running. Stop it before we begin preparing for
|
|
the configuration change, and restart it only once we've successfully
|
|
completed the change.
|
|
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
---
|
|
drivers/net/phy/phylink.c | 30 ++++++++++++++++++++----------
|
|
1 file changed, 20 insertions(+), 10 deletions(-)
|
|
|
|
--- a/drivers/net/phy/phylink.c
|
|
+++ b/drivers/net/phy/phylink.c
|
|
@@ -759,6 +759,18 @@ static void phylink_resolve_flow(struct
|
|
}
|
|
}
|
|
|
|
+static void phylink_pcs_poll_stop(struct phylink *pl)
|
|
+{
|
|
+ if (pl->cfg_link_an_mode == MLO_AN_INBAND)
|
|
+ del_timer(&pl->link_poll);
|
|
+}
|
|
+
|
|
+static void phylink_pcs_poll_start(struct phylink *pl)
|
|
+{
|
|
+ if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
|
|
+ mod_timer(&pl->link_poll, jiffies + HZ);
|
|
+}
|
|
+
|
|
static void phylink_mac_config(struct phylink *pl,
|
|
const struct phylink_link_state *state)
|
|
{
|
|
@@ -790,6 +802,7 @@ static void phylink_major_config(struct
|
|
const struct phylink_link_state *state)
|
|
{
|
|
struct phylink_pcs *pcs = NULL;
|
|
+ bool pcs_changed = false;
|
|
int err;
|
|
|
|
phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
|
|
@@ -802,8 +815,12 @@ static void phylink_major_config(struct
|
|
pcs);
|
|
return;
|
|
}
|
|
+
|
|
+ pcs_changed = pcs && pl->pcs != pcs;
|
|
}
|
|
|
|
+ phylink_pcs_poll_stop(pl);
|
|
+
|
|
if (pl->mac_ops->mac_prepare) {
|
|
err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
|
|
state->interface);
|
|
@@ -817,8 +834,10 @@ static void phylink_major_config(struct
|
|
/* If we have a new PCS, switch to the new PCS after preparing the MAC
|
|
* for the change.
|
|
*/
|
|
- if (pcs)
|
|
- phylink_set_pcs(pl, pcs);
|
|
+ if (pcs_changed) {
|
|
+ pl->pcs = pcs;
|
|
+ pl->pcs_ops = pcs->ops;
|
|
+ }
|
|
|
|
phylink_mac_config(pl, state);
|
|
|
|
@@ -844,6 +863,8 @@ static void phylink_major_config(struct
|
|
phylink_err(pl, "mac_finish failed: %pe\n",
|
|
ERR_PTR(err));
|
|
}
|
|
+
|
|
+ phylink_pcs_poll_start(pl);
|
|
}
|
|
|
|
/*
|