net: bcmgenet: Fix EEE implementation
authorFlorian Fainelli <florian.fainelli@broadcom.com>
Tue, 6 Jun 2023 21:43:47 +0000 (14:43 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 8 Jun 2023 04:53:14 +0000 (21:53 -0700)
We had a number of short comings:

- EEE must be re-evaluated whenever the state machine detects a link
  change as wight be switching from a link partner with EEE
  enabled/disabled

- tx_lpi_enabled controls whether EEE should be enabled/disabled for the
  transmit path, which applies to the TBUF block

- We do not need to forcibly enable EEE upon system resume, as the PHY
  state machine will trigger a link event that will do that, too

Fixes: 6ef398ea60d9 ("net: bcmgenet: add EEE support")
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://lore.kernel.org/r/20230606214348.2408018-1-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmmii.c

index eca0c92..2b5761a 100644 (file)
@@ -1272,7 +1272,8 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
        }
 }
 
-static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
+void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
+                            bool tx_lpi_enabled)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
        u32 off = priv->hw_params->tbuf_offset + TBUF_ENERGY_CTRL;
@@ -1292,7 +1293,7 @@ static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
 
        /* Enable EEE and switch to a 27Mhz clock automatically */
        reg = bcmgenet_readl(priv->base + off);
-       if (enable)
+       if (tx_lpi_enabled)
                reg |= TBUF_EEE_EN | TBUF_PM_EN;
        else
                reg &= ~(TBUF_EEE_EN | TBUF_PM_EN);
@@ -1313,6 +1314,7 @@ static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
 
        priv->eee.eee_enabled = enable;
        priv->eee.eee_active = enable;
+       priv->eee.tx_lpi_enabled = tx_lpi_enabled;
 }
 
 static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e)
@@ -1328,6 +1330,7 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e)
 
        e->eee_enabled = p->eee_enabled;
        e->eee_active = p->eee_active;
+       e->tx_lpi_enabled = p->tx_lpi_enabled;
        e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER);
 
        return phy_ethtool_get_eee(dev->phydev, e);
@@ -1337,7 +1340,6 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
        struct ethtool_eee *p = &priv->eee;
-       int ret = 0;
 
        if (GENET_IS_V1(priv))
                return -EOPNOTSUPP;
@@ -1348,16 +1350,11 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e)
        p->eee_enabled = e->eee_enabled;
 
        if (!p->eee_enabled) {
-               bcmgenet_eee_enable_set(dev, false);
+               bcmgenet_eee_enable_set(dev, false, false);
        } else {
-               ret = phy_init_eee(dev->phydev, false);
-               if (ret) {
-                       netif_err(priv, hw, dev, "EEE initialization failed\n");
-                       return ret;
-               }
-
+               p->eee_active = phy_init_eee(dev->phydev, false) >= 0;
                bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
-               bcmgenet_eee_enable_set(dev, true);
+               bcmgenet_eee_enable_set(dev, p->eee_active, e->tx_lpi_enabled);
        }
 
        return phy_ethtool_set_eee(dev->phydev, e);
@@ -4279,9 +4276,6 @@ static int bcmgenet_resume(struct device *d)
        if (!device_may_wakeup(d))
                phy_resume(dev->phydev);
 
-       if (priv->eee.eee_enabled)
-               bcmgenet_eee_enable_set(dev, true);
-
        bcmgenet_netif_start(dev);
 
        netif_device_attach(dev);
index 946f6e2..1985c0e 100644 (file)
@@ -703,4 +703,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
 void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
                               enum bcmgenet_power_mode mode);
 
+void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
+                            bool tx_lpi_enabled);
+
 #endif /* __BCMGENET_H__ */
index be04290..c15ed0a 100644 (file)
@@ -87,6 +87,11 @@ static void bcmgenet_mac_config(struct net_device *dev)
                reg |= CMD_TX_EN | CMD_RX_EN;
        }
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+       priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
+       bcmgenet_eee_enable_set(dev,
+                               priv->eee.eee_enabled && priv->eee.eee_active,
+                               priv->eee.tx_lpi_enabled);
 }
 
 /* setup netdev link state when PHY link status change and