Skip to content

Commit 908c344

Browse files
nbuchwitzkuba-moo
authored andcommitted
net: bcmgenet: fix broken EEE by converting to phylib-managed state
The bcmgenet EEE implementation is broken in several ways. phy_support_eee() is never called, so the PHY never advertises EEE and phylib never sets phydev->enable_tx_lpi. bcmgenet_mac_config() checks priv->eee.eee_enabled to decide whether to enable the MAC LPI logic, but that field is never initialised to true, so the MAC never enters Low Power Idle even when EEE is negotiated - wasting the power savings EEE is designed to provide. The only way to get EEE working at all is a manual 'ethtool --set-eee eth0 eee on' after every link-up, and even then bcmgenet_get_eee() immediately clobbers the reported state because phy_ethtool_get_eee() overwrites eee_enabled and tx_lpi_enabled with the uninitialised PHY eee_cfg values. Finally, bcmgenet_mac_config() is only called on link-up, so EEE is never disabled in hardware on link-down. Fix all of this by removing the MAC-side EEE state tracking (priv->eee) and aligning with the pattern used by other non-phylink MAC drivers such as FEC. Call phy_support_eee() in bcmgenet_mii_probe() so the PHY advertises EEE link modes and phylib tracks negotiation state. Move the EEE hardware control to bcmgenet_mii_setup(), which is called on every link event, and drive it directly from phydev->enable_tx_lpi - the flag phylib sets when EEE is negotiated and the user has not disabled it. This enables EEE automatically once the link partner agrees and disables it cleanly on link-down. Make bcmgenet_get_eee() and bcmgenet_set_eee() pure passthroughs to phy_ethtool_get_eee() and phy_ethtool_set_eee(), with the MAC hardware register read/written for tx_lpi_timer. Drop struct ethtool_keee eee from struct bcmgenet_priv. Fixes: fe0d4fd ("net: phy: Keep track of EEE configuration") Link: https://lore.kernel.org/netdev/d352039f-4cbb-41e6-9aeb-0b4f3941b54c@lunn.ch/ Suggested-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Tested-by: Florian Fainelli <florian.fainelli@broadcom.com> Link: https://patch.msgid.link/20260310054935.1238594-1-nb@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 5788527 commit 908c344

3 files changed

Lines changed: 18 additions & 28 deletions

File tree

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,8 +1342,7 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
13421342
}
13431343
}
13441344

1345-
void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
1346-
bool tx_lpi_enabled)
1345+
void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
13471346
{
13481347
struct bcmgenet_priv *priv = netdev_priv(dev);
13491348
u32 off = priv->hw_params->tbuf_offset + TBUF_ENERGY_CTRL;
@@ -1363,7 +1362,7 @@ void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
13631362

13641363
/* Enable EEE and switch to a 27Mhz clock automatically */
13651364
reg = bcmgenet_readl(priv->base + off);
1366-
if (tx_lpi_enabled)
1365+
if (enable)
13671366
reg |= TBUF_EEE_EN | TBUF_PM_EN;
13681367
else
13691368
reg &= ~(TBUF_EEE_EN | TBUF_PM_EN);
@@ -1382,48 +1381,42 @@ void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
13821381
priv->clk_eee_enabled = false;
13831382
}
13841383

1385-
priv->eee.eee_enabled = enable;
1386-
priv->eee.tx_lpi_enabled = tx_lpi_enabled;
13871384
}
13881385

13891386
static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_keee *e)
13901387
{
13911388
struct bcmgenet_priv *priv = netdev_priv(dev);
1392-
struct ethtool_keee *p = &priv->eee;
1389+
int ret;
13931390

13941391
if (GENET_IS_V1(priv))
13951392
return -EOPNOTSUPP;
13961393

13971394
if (!dev->phydev)
13981395
return -ENODEV;
13991396

1400-
e->tx_lpi_enabled = p->tx_lpi_enabled;
1397+
ret = phy_ethtool_get_eee(dev->phydev, e);
1398+
if (ret)
1399+
return ret;
1400+
1401+
/* tx_lpi_timer is maintained by the MAC hardware register; the
1402+
* PHY-level eee_cfg timer is not set for GENET.
1403+
*/
14011404
e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER);
14021405

1403-
return phy_ethtool_get_eee(dev->phydev, e);
1406+
return 0;
14041407
}
14051408

14061409
static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e)
14071410
{
14081411
struct bcmgenet_priv *priv = netdev_priv(dev);
1409-
struct ethtool_keee *p = &priv->eee;
1410-
bool active;
14111412

14121413
if (GENET_IS_V1(priv))
14131414
return -EOPNOTSUPP;
14141415

14151416
if (!dev->phydev)
14161417
return -ENODEV;
14171418

1418-
p->eee_enabled = e->eee_enabled;
1419-
1420-
if (!p->eee_enabled) {
1421-
bcmgenet_eee_enable_set(dev, false, false);
1422-
} else {
1423-
active = phy_init_eee(dev->phydev, false) >= 0;
1424-
bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
1425-
bcmgenet_eee_enable_set(dev, active, e->tx_lpi_enabled);
1426-
}
1419+
bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
14271420

14281421
return phy_ethtool_set_eee(dev->phydev, e);
14291422
}

drivers/net/ethernet/broadcom/genet/bcmgenet.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,6 @@ struct bcmgenet_priv {
665665
u8 sopass[SOPASS_MAX];
666666

667667
struct bcmgenet_mib_counters mib;
668-
669-
struct ethtool_keee eee;
670668
};
671669

672670
static inline bool bcmgenet_has_40bits(struct bcmgenet_priv *priv)
@@ -749,7 +747,6 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
749747
int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
750748
enum bcmgenet_power_mode mode);
751749

752-
void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
753-
bool tx_lpi_enabled);
750+
void bcmgenet_eee_enable_set(struct net_device *dev, bool enable);
754751

755752
#endif /* __BCMGENET_H__ */

drivers/net/ethernet/broadcom/genet/bcmmii.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ static void bcmgenet_mac_config(struct net_device *dev)
2929
struct bcmgenet_priv *priv = netdev_priv(dev);
3030
struct phy_device *phydev = dev->phydev;
3131
u32 reg, cmd_bits = 0;
32-
bool active;
3332

3433
/* speed */
3534
if (phydev->speed == SPEED_1000)
@@ -90,10 +89,6 @@ static void bcmgenet_mac_config(struct net_device *dev)
9089
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
9190
spin_unlock_bh(&priv->reg_lock);
9291

93-
active = phy_init_eee(phydev, 0) >= 0;
94-
bcmgenet_eee_enable_set(dev,
95-
priv->eee.eee_enabled && active,
96-
priv->eee.tx_lpi_enabled);
9792
}
9893

9994
/* setup netdev link state when PHY link status change and
@@ -113,6 +108,8 @@ void bcmgenet_mii_setup(struct net_device *dev)
113108
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
114109
}
115110

111+
bcmgenet_eee_enable_set(dev, phydev->enable_tx_lpi);
112+
116113
phy_print_status(phydev);
117114
}
118115

@@ -412,6 +409,9 @@ int bcmgenet_mii_probe(struct net_device *dev)
412409
/* Indicate that the MAC is responsible for PHY PM */
413410
dev->phydev->mac_managed_pm = true;
414411

412+
if (!GENET_IS_V1(priv))
413+
phy_support_eee(dev->phydev);
414+
415415
return 0;
416416
}
417417

0 commit comments

Comments
 (0)