net: dsa: Fix network device registration order
We cannot be registering the network device first, then setting its carrier off and finally connecting it to a PHY, doing that leaves a window during which the carrier is at best inconsistent, and at worse the device is not usable without a down/up sequence since the network device is visible to user space with possibly no PHY device attached. Re-order steps so that they make logical sense. This fixes some devices where the port was not usable after e.g: an unbind then bind of the driver. Fixes:0071f56e46
("dsa: Register netdev before phy") Fixes:91da11f870
("net: Distributed Switch Architecture protocol support") Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
db06ae4194
commit
e804441cfe
|
@ -1301,28 +1301,33 @@ int dsa_slave_create(struct dsa_port *port, const char *name)
|
||||||
p->old_duplex = -1;
|
p->old_duplex = -1;
|
||||||
|
|
||||||
port->netdev = slave_dev;
|
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);
|
netif_carrier_off(slave_dev);
|
||||||
|
|
||||||
ret = dsa_slave_phy_setup(p, slave_dev);
|
ret = dsa_slave_phy_setup(p, slave_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
netdev_err(master, "error %d setting up slave phy\n", ret);
|
netdev_err(master, "error %d setting up slave phy\n", ret);
|
||||||
unregister_netdev(slave_dev);
|
goto out_free;
|
||||||
free_percpu(p->stats64);
|
}
|
||||||
free_netdev(slave_dev);
|
|
||||||
return ret;
|
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;
|
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)
|
void dsa_slave_destroy(struct net_device *slave_dev)
|
||||||
|
|
Loading…
Reference in New Issue