net: dsa: Fix network device registration order

[ Upstream commit e804441cfe0b60f6c430901946a69c01eac09df1 ]

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: 0071f56e46da ("dsa: Register netdev before phy")
Fixes: 91da11f870f0 ("net: Distributed Switch Architecture protocol support")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Florian Fainelli 2017-09-25 15:55:53 -07:00 committed by Greg Kroah-Hartman
parent b8990d2e77
commit 6eab1f8294

View File

@ -1269,26 +1269,32 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
p->old_duplex = -1;
ds->ports[port].netdev = slave_dev;
ret = register_netdev(slave_dev);
if (ret) {
netdev_err(master, "error %d registering interface %s\n",
ret, slave_dev->name);
ds->ports[port].netdev = NULL;
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_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(ds->ports[port].dn))
of_phy_deregister_fixed_link(ds->ports[port].dn);
out_free:
free_netdev(slave_dev);
ds->ports[port].netdev = NULL;
return ret;
}
void dsa_slave_destroy(struct net_device *slave_dev)