@@ -854,6 +854,9 @@ struct dsa_switch_ops {
*/
int (*port_setup)(struct dsa_switch *ds, int port);
void (*port_teardown)(struct dsa_switch *ds, int port);
+ struct fwnode_handle *(*port_get_fwnode)(struct dsa_switch *ds,
+ int port,
+ struct fwnode_handle *h);
u32 (*get_phy_flags)(struct dsa_switch *ds, int port);
@@ -1693,6 +1693,15 @@ int dsa_port_phylink_create(struct dsa_port *dp)
ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
fwnode = of_fwnode_handle(dp->dn);
+ if (ds->ops->port_get_fwnode) {
+ fwnode = ds->ops->port_get_fwnode(ds, dp->index, fwnode);
+ if (IS_ERR(fwnode)) {
+ dev_err(ds->dev,
+ "Failed to get fwnode for port %d: %pe\n",
+ dp->index, fwnode);
+ return PTR_ERR(fwnode);
+ }
+ }
mode = fwnode_get_phy_mode(fwnode);
if (mode < 0)
@@ -1700,6 +1709,9 @@ int dsa_port_phylink_create(struct dsa_port *dp)
pl = phylink_create(&dp->pl_config, fwnode, mode,
&dsa_port_phylink_mac_ops);
+
+ fwnode_remove_software_node(fwnode);
+
if (IS_ERR(pl)) {
pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
return PTR_ERR(pl);
Add a method to dsa_switch_ops to allow a switch driver to override the fwnode used to setup phylink for a port. This will be used for the Marvell 88e6xxx driver to provide its "maximum interface" and "maximum speed" mode to keep compatibility with existing behaviour for CPU and DSA ports via a swnode-backed fwnode. We need to release the swnode after phylink_create() has completed no matter what the outcome was. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> --- include/net/dsa.h | 3 +++ net/dsa/port.c | 12 ++++++++++++ 2 files changed, 15 insertions(+)