]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.13.6/net-dsa-fix-network-device-registration-order.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.13.6 / net-dsa-fix-network-device-registration-order.patch
CommitLineData
014275a0
GKH
1From foo@baz Mon Oct 9 09:32:35 CEST 2017
2From: Florian Fainelli <f.fainelli@gmail.com>
3Date: Mon, 25 Sep 2017 15:55:53 -0700
4Subject: net: dsa: Fix network device registration order
5
6From: Florian Fainelli <f.fainelli@gmail.com>
7
8
9[ Upstream commit e804441cfe0b60f6c430901946a69c01eac09df1 ]
10
11We cannot be registering the network device first, then setting its
12carrier off and finally connecting it to a PHY, doing that leaves a
13window during which the carrier is at best inconsistent, and at worse
14the device is not usable without a down/up sequence since the network
15device is visible to user space with possibly no PHY device attached.
16
17Re-order steps so that they make logical sense. This fixes some devices
18where the port was not usable after e.g: an unbind then bind of the
19driver.
20
21Fixes: 0071f56e46da ("dsa: Register netdev before phy")
22Fixes: 91da11f870f0 ("net: Distributed Switch Architecture protocol support")
23Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
24Signed-off-by: David S. Miller <davem@davemloft.net>
25Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26---
27 net/dsa/slave.c | 28 +++++++++++++++++-----------
28 1 file changed, 17 insertions(+), 11 deletions(-)
29
30--- a/net/dsa/slave.c
31+++ b/net/dsa/slave.c
32@@ -1180,26 +1180,32 @@ int dsa_slave_create(struct dsa_switch *
33 p->old_duplex = -1;
34
35 ds->ports[port].netdev = slave_dev;
36- ret = register_netdev(slave_dev);
37- if (ret) {
38- netdev_err(master, "error %d registering interface %s\n",
39- ret, slave_dev->name);
40- ds->ports[port].netdev = NULL;
41- free_netdev(slave_dev);
42- return ret;
43- }
44
45 netif_carrier_off(slave_dev);
46
47 ret = dsa_slave_phy_setup(p, slave_dev);
48 if (ret) {
49 netdev_err(master, "error %d setting up slave phy\n", ret);
50- unregister_netdev(slave_dev);
51- free_netdev(slave_dev);
52- return ret;
53+ goto out_free;
54+ }
55+
56+ ret = register_netdev(slave_dev);
57+ if (ret) {
58+ netdev_err(master, "error %d registering interface %s\n",
59+ ret, slave_dev->name);
60+ goto out_phy;
61 }
62
63 return 0;
64+
65+out_phy:
66+ phy_disconnect(p->phy);
67+ if (of_phy_is_fixed_link(p->dp->dn))
68+ of_phy_deregister_fixed_link(p->dp->dn);
69+out_free:
70+ free_netdev(slave_dev);
71+ ds->ports[port].netdev = NULL;
72+ return ret;
73 }
74
75 void dsa_slave_destroy(struct net_device *slave_dev)