Skip to content
Snippets Groups Projects
Commit a20f9970 authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller
Browse files

net: dsa: Don't instantiate phylink for CPU/DSA ports unless needed


By default, DSA drivers should configure CPU and DSA ports to their
maximum speed. In many configurations this is sufficient to make the
link work.

In some cases it is necessary to configure the link to run slower,
e.g. because of limitations of the SoC it is connected to. Or back to
back PHYs are used and the PHY needs to be driven in order to
establish link. In this case, phylink is used.

Only instantiate phylink if it is required. If there is no PHY, or no
fixed link properties, phylink can upset a link which works in the
default configuration.

Fixes: 0e279218 ("net: dsa: Use PHYLINK for the CPU/DSA ports")
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 46e4c421
No related branches found
No related tags found
No related merge requests found
...@@ -648,9 +648,14 @@ static int dsa_port_phylink_register(struct dsa_port *dp) ...@@ -648,9 +648,14 @@ static int dsa_port_phylink_register(struct dsa_port *dp)
int dsa_port_link_register_of(struct dsa_port *dp) int dsa_port_link_register_of(struct dsa_port *dp)
{ {
struct dsa_switch *ds = dp->ds; struct dsa_switch *ds = dp->ds;
struct device_node *phy_np;
if (!ds->ops->adjust_link) if (!ds->ops->adjust_link) {
phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
if (of_phy_is_fixed_link(dp->dn) || phy_np)
return dsa_port_phylink_register(dp); return dsa_port_phylink_register(dp);
return 0;
}
dev_warn(ds->dev, dev_warn(ds->dev,
"Using legacy PHYLIB callbacks. Please migrate to PHYLINK!\n"); "Using legacy PHYLIB callbacks. Please migrate to PHYLINK!\n");
...@@ -665,11 +670,12 @@ void dsa_port_link_unregister_of(struct dsa_port *dp) ...@@ -665,11 +670,12 @@ void dsa_port_link_unregister_of(struct dsa_port *dp)
{ {
struct dsa_switch *ds = dp->ds; struct dsa_switch *ds = dp->ds;
if (!ds->ops->adjust_link) { if (!ds->ops->adjust_link && dp->pl) {
rtnl_lock(); rtnl_lock();
phylink_disconnect_phy(dp->pl); phylink_disconnect_phy(dp->pl);
rtnl_unlock(); rtnl_unlock();
phylink_destroy(dp->pl); phylink_destroy(dp->pl);
dp->pl = NULL;
return; return;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment