diff options
Diffstat (limited to 'net/dsa')
| -rw-r--r-- | net/dsa/Makefile | 1 | ||||
| -rw-r--r-- | net/dsa/dsa2.c | 7 | ||||
| -rw-r--r-- | net/dsa/slave.c | 31 | 
3 files changed, 23 insertions, 16 deletions
| diff --git a/net/dsa/Makefile b/net/dsa/Makefile index fcce25da937c..3d3c74193d06 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0  # the core  obj-$(CONFIG_NET_DSA) += dsa_core.o  dsa_core-y += dsa.o dsa2.o legacy.o port.o slave.o switch.o diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 873af0108e24..045d8a176279 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -496,14 +496,15 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,  		if (!ethernet)  			return -EINVAL;  		ethernet_dev = of_find_net_device_by_node(ethernet); +		if (!ethernet_dev) +			return -EPROBE_DEFER;  	} else {  		ethernet_dev = dsa_dev_to_net_device(ds->cd->netdev[index]); +		if (!ethernet_dev) +			return -EPROBE_DEFER;  		dev_put(ethernet_dev);  	} -	if (!ethernet_dev) -		return -EPROBE_DEFER; -  	if (!dst->cpu_dp) {  		dst->cpu_dp = port;  		dst->cpu_dp->netdev = ethernet_dev; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 2afa99506f8b..865e29e62bad 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1301,28 +1301,33 @@ int dsa_slave_create(struct dsa_port *port, const char *name)  	p->old_duplex = -1;  	port->netdev = slave_dev; -	ret = register_netdev(slave_dev); -	if (ret) { -		netdev_err(master, "error %d registering interface %s\n", -			   ret, slave_dev->name); -		port->netdev = NULL; -		free_percpu(p->stats64); -		free_netdev(slave_dev); -		return ret; -	}  	netif_carrier_off(slave_dev);  	ret = dsa_slave_phy_setup(p, slave_dev);  	if (ret) {  		netdev_err(master, "error %d setting up slave phy\n", ret); -		unregister_netdev(slave_dev); -		free_percpu(p->stats64); -		free_netdev(slave_dev); -		return ret; +		goto out_free; +	} + +	ret = register_netdev(slave_dev); +	if (ret) { +		netdev_err(master, "error %d registering interface %s\n", +			   ret, slave_dev->name); +		goto out_phy;  	}  	return 0; + +out_phy: +	phy_disconnect(p->phy); +	if (of_phy_is_fixed_link(p->dp->dn)) +		of_phy_deregister_fixed_link(p->dp->dn); +out_free: +	free_percpu(p->stats64); +	free_netdev(slave_dev); +	port->netdev = NULL; +	return ret;  }  void dsa_slave_destroy(struct net_device *slave_dev) |