Skip to content

Commit

Permalink
drivers: net: cpsw: ethtool: fix accessing to suspended device
Browse files Browse the repository at this point in the history
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through ethtool interfce. In this case
ethtool operations, requiring registers access, will cause L3 errors and
CPSW crash.

ethtool callbcaks which need to access CPSW registers now:
.set_coalesce(), .get_ethtool_stats(), .set_pauseparam(), .get_regs()

Hence, fix it by adding .begin()/.complete() ethtool callbacks, which
will be called before/after each ethtool operation runs, and do CPSW
RPM handling in these callbacks. That way CPSW will be active while
handling ethtool requests.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Grygorii Strashko authored and David S. Miller committed Jun 28, 2016
1 parent 74556f5 commit 7898b1d
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1905,10 +1905,33 @@ static int cpsw_set_pauseparam(struct net_device *ndev,
priv->tx_pause = pause->tx_pause ? true : false;

for_each_slave(priv, _cpsw_adjust_link, priv, &link);

return 0;
}

static int cpsw_ethtool_op_begin(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
int ret;

ret = pm_runtime_get_sync(&priv->pdev->dev);
if (ret < 0) {
cpsw_err(priv, drv, "ethtool begin failed %d\n", ret);
pm_runtime_put_noidle(&priv->pdev->dev);
}

return ret;
}

static void cpsw_ethtool_op_complete(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
int ret;

ret = pm_runtime_put(&priv->pdev->dev);
if (ret < 0)
cpsw_err(priv, drv, "ethtool complete failed %d\n", ret);
}

static const struct ethtool_ops cpsw_ethtool_ops = {
.get_drvinfo = cpsw_get_drvinfo,
.get_msglevel = cpsw_get_msglevel,
Expand All @@ -1928,6 +1951,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
.set_wol = cpsw_set_wol,
.get_regs_len = cpsw_get_regs_len,
.get_regs = cpsw_get_regs,
.begin = cpsw_ethtool_op_begin,
.complete = cpsw_ethtool_op_complete,
};

static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
Expand Down

0 comments on commit 7898b1d

Please sign in to comment.