net: ethernet: ti: cpsw: fix runtime_pm while add/kill vlan [Linux 4.18]

This Linux kernel change "net: ethernet: ti: cpsw: fix runtime_pm while add/kill vlan" is included in the Linux 4.18 release. This change is authored by Ivan Khoronzhuk <ivan.khoronzhuk [at] linaro.org> on Fri Aug 10 15:47:09 2018 +0300. The commit for this change in Linux stable tree is 803c4f6 (patch).

net: ethernet: ti: cpsw: fix runtime_pm while add/kill vlan

It's exclusive with normal behaviour but if try to set vlan to one of
the reserved values is made, the cpsw runtime pm is broken.

Fixes: a6c5d14f5136 ("drivers: net: cpsw: ndev: fix accessing to suspended device")
Signed-off-by: Ivan Khoronzhuk <[email protected]>
Signed-off-by: David S. Miller <[email protected]>

There are 11 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/ethernet/ti/cpsw.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 9edac67..3e34cb8 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2086,14 +2086,16 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
        int i;

        for (i = 0; i < cpsw->data.slaves; i++) {
-           if (vid == cpsw->slaves[i].port_vlan)
-               return -EINVAL;
+           if (vid == cpsw->slaves[i].port_vlan) {
+               ret = -EINVAL;
+               goto err;
+           }
        }
    }

    dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
    ret = cpsw_add_vlan_ale_entry(priv, vid);
-
+err:
    pm_runtime_put(cpsw->dev);
    return ret;
 }
@@ -2119,7 +2121,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,

        for (i = 0; i < cpsw->data.slaves; i++) {
            if (vid == cpsw->slaves[i].port_vlan)
-               return -EINVAL;
+               goto err;
        }
    }

@@ -2129,6 +2131,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
                  HOST_PORT_NUM, ALE_VLAN, vid);
    ret |= cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast,
                  0, ALE_VLAN, vid);
+err:
    pm_runtime_put(cpsw->dev);
    return ret;
 }

Leave a Reply

Your email address will not be published. Required fields are marked *