3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Abreu jose.abreu@synopsys.com
[ Upstream commit 8a7493e58ad688eb23b81e45461c5d314f4402f1 ]
We are saving the status of EEE even before we try to enable it. This leads to a race with XMIT function that tries to arm EEE timer before we set it up.
Fix this by only saving the EEE parameters after all operations are performed with success.
Signed-off-by: Jose Abreu joabreu@synopsys.com Fixes: d765955d2ae0 ("stmmac: add the Energy Efficient Ethernet support") Cc: Joao Pinto jpinto@synopsys.com Cc: David S. Miller davem@davemloft.net Cc: Giuseppe Cavallaro peppe.cavallaro@st.com Cc: Alexandre Torgue alexandre.torgue@st.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -614,25 +614,27 @@ static int stmmac_ethtool_op_set_eee(str struct ethtool_eee *edata) { struct stmmac_priv *priv = netdev_priv(dev); + int ret;
- priv->eee_enabled = edata->eee_enabled; - - if (!priv->eee_enabled) + if (!edata->eee_enabled) { stmmac_disable_eee_mode(priv); - else { + } else { /* We are asking for enabling the EEE but it is safe * to verify all by invoking the eee_init function. * In case of failure it will return an error. */ - priv->eee_enabled = stmmac_eee_init(priv); - if (!priv->eee_enabled) + edata->eee_enabled = stmmac_eee_init(priv); + if (!edata->eee_enabled) return -EOPNOTSUPP; - - /* Do not change tx_lpi_timer in case of failure */ - priv->tx_lpi_timer = edata->tx_lpi_timer; }
- return phy_ethtool_set_eee(priv->phydev, edata); + ret = phy_ethtool_set_eee(dev->phydev, edata); + if (ret) + return ret; + + priv->eee_enabled = edata->eee_enabled; + priv->tx_lpi_timer = edata->tx_lpi_timer; + return 0; }
static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv)