diff mbox series

[net] net: stmmac: Fix a race in EEE enable callback

Message ID fb866bb5dd8a11326fab8e6d393f2a37eed5073f.1550496861.git.joabreu@synopsys.com
State Accepted
Delegated to: David Miller
Headers show
Series [net] net: stmmac: Fix a race in EEE enable callback | expand

Commit Message

Jose Abreu Feb. 18, 2019, 1:35 p.m. UTC
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>
---
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

Comments

David Miller Feb. 19, 2019, 1:40 a.m. UTC | #1
From: Jose Abreu <jose.abreu@synopsys.com>
Date: Mon, 18 Feb 2019 14:35:03 +0100

> 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")

Applied and queued up for -stable, thanks.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 5d85742a2be0..3c749c327cbd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -696,25 +696,27 @@  static int stmmac_ethtool_op_set_eee(struct net_device *dev,
 				     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(dev->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)