staging: fsl-dpaa2/ethsw: do not force user to bring interface down
authorIoana Ciornei <ioana.ciornei@nxp.com>
Tue, 13 Aug 2019 12:43:07 +0000 (15:43 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Aug 2019 14:46:25 +0000 (16:46 +0200)
Link settings can be changed only when the interface is down. Disable
and re-enable the interface, if necessary, behind the scenes so that we do
not force users to an if down/up sequence.

Reported-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Link: https://lore.kernel.org/r/1565700187-16048-11-git-send-email-ioana.ciornei@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c

index 0f9f834..4f0bff8 100644 (file)
@@ -88,16 +88,21 @@ ethsw_set_link_ksettings(struct net_device *netdev,
                         const struct ethtool_link_ksettings *link_ksettings)
 {
        struct ethsw_port_priv *port_priv = netdev_priv(netdev);
+       struct ethsw_core *ethsw = port_priv->ethsw_data;
        struct dpsw_link_cfg cfg = {0};
-       int err = 0;
-
-       /* Due to a temporary MC limitation, the DPSW port must be down
-        * in order to be able to change link settings. Taking steps to let
-        * the user know that.
-        */
-       if (netif_running(netdev)) {
-               netdev_info(netdev, "Sorry, interface must be brought down first.\n");
-               return -EACCES;
+       bool if_running;
+       int err = 0, ret;
+
+       /* Interface needs to be down to change link settings */
+       if_running = netif_running(netdev);
+       if (if_running) {
+               err = dpsw_if_disable(ethsw->mc_io, 0,
+                                     ethsw->dpsw_handle,
+                                     port_priv->idx);
+               if (err) {
+                       netdev_err(netdev, "dpsw_if_disable err %d\n", err);
+                       return err;
+               }
        }
 
        cfg.rate = link_ksettings->base.speed;
@@ -115,6 +120,15 @@ ethsw_set_link_ksettings(struct net_device *netdev,
                                   port_priv->idx,
                                   &cfg);
 
+       if (if_running) {
+               ret = dpsw_if_enable(ethsw->mc_io, 0,
+                                    ethsw->dpsw_handle,
+                                    port_priv->idx);
+               if (ret) {
+                       netdev_err(netdev, "dpsw_if_enable err %d\n", ret);
+                       return ret;
+               }
+       }
        return err;
 }