lkml.org 
[lkml]   [2017]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 068/105] net: dsa: Fix network device registration order
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Florian Fainelli <f.fainelli@gmail.com>


    [ 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>
    ---
    net/dsa/slave.c | 28 +++++++++++++++++-----------
    1 file changed, 17 insertions(+), 11 deletions(-)

    --- a/net/dsa/slave.c
    +++ b/net/dsa/slave.c
    @@ -1269,26 +1269,32 @@ int dsa_slave_create(struct dsa_switch *
    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)

    \
     
     \ /
      Last update: 2017-10-10 22:51    [W:3.895 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site