Skip to content

Commit 32cd651

Browse files
Ryceancurrykuba-moo
authored andcommitted
net: phy: broadcom: Save PHY counters during suspend
The PHY counters can be lost if the PHY is reset during suspend. We need to save the values into the shadow counters or the accounting will be incorrect over multiple suspend and resume cycles. Fixes: 820ee17 ("net: phy: broadcom: Add support code for reading PHY counters") Signed-off-by: Justin Chen <justin.chen@broadcom.com> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Link: https://patch.msgid.link/20260505173926.2870069-1-justin.chen@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 9032f76 commit 32cd651

4 files changed

Lines changed: 29 additions & 0 deletions

File tree

drivers/net/phy/bcm-phy-lib.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,15 @@ void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
563563
}
564564
EXPORT_SYMBOL_GPL(bcm_phy_get_stats);
565565

566+
void bcm_phy_update_stats_shadow(struct phy_device *phydev, u64 *shadow)
567+
{
568+
unsigned int i;
569+
570+
for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
571+
bcm_phy_get_stat(phydev, shadow, i);
572+
}
573+
EXPORT_SYMBOL_GPL(bcm_phy_update_stats_shadow);
574+
566575
void bcm_phy_r_rc_cal_reset(struct phy_device *phydev)
567576
{
568577
/* Reset R_CAL/RC_CAL Engine */

drivers/net/phy/bcm-phy-lib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ int bcm_phy_get_sset_count(struct phy_device *phydev);
8585
void bcm_phy_get_strings(struct phy_device *phydev, u8 *data);
8686
void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
8787
struct ethtool_stats *stats, u64 *data);
88+
void bcm_phy_update_stats_shadow(struct phy_device *phydev, u64 *shadow);
8889
void bcm_phy_r_rc_cal_reset(struct phy_device *phydev);
8990
int bcm_phy_28nm_a0b0_afe_config_init(struct phy_device *phydev);
9091
int bcm_phy_enable_jumbo(struct phy_device *phydev);

drivers/net/phy/bcm7xxx.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,17 @@ static void bcm7xxx_28nm_get_phy_stats(struct phy_device *phydev,
807807
bcm_phy_get_stats(phydev, priv->stats, stats, data);
808808
}
809809

810+
static int bcm7xxx_28nm_suspend(struct phy_device *phydev)
811+
{
812+
struct bcm7xxx_phy_priv *priv = phydev->priv;
813+
814+
mutex_lock(&phydev->lock);
815+
bcm_phy_update_stats_shadow(phydev, priv->stats);
816+
mutex_unlock(&phydev->lock);
817+
818+
return genphy_suspend(phydev);
819+
}
820+
810821
static int bcm7xxx_28nm_probe(struct phy_device *phydev)
811822
{
812823
struct bcm7xxx_phy_priv *priv;
@@ -849,6 +860,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev)
849860
.flags = PHY_IS_INTERNAL, \
850861
.config_init = bcm7xxx_28nm_config_init, \
851862
.resume = bcm7xxx_28nm_resume, \
863+
.suspend = bcm7xxx_28nm_suspend, \
852864
.get_tunable = bcm7xxx_28nm_get_tunable, \
853865
.set_tunable = bcm7xxx_28nm_set_tunable, \
854866
.get_sset_count = bcm_phy_get_sset_count, \
@@ -866,6 +878,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev)
866878
.flags = PHY_IS_INTERNAL, \
867879
.config_init = bcm7xxx_28nm_ephy_config_init, \
868880
.resume = bcm7xxx_28nm_ephy_resume, \
881+
.suspend = bcm7xxx_28nm_suspend, \
869882
.get_sset_count = bcm_phy_get_sset_count, \
870883
.get_strings = bcm_phy_get_strings, \
871884
.get_stats = bcm7xxx_28nm_get_phy_stats, \
@@ -902,6 +915,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev)
902915
.config_aneg = genphy_config_aneg, \
903916
.read_status = genphy_read_status, \
904917
.resume = bcm7xxx_16nm_ephy_resume, \
918+
.suspend = bcm7xxx_28nm_suspend, \
905919
}
906920

907921
static struct phy_driver bcm7xxx_driver[] = {

drivers/net/phy/broadcom.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,13 @@ static int bcm54xx_set_wakeup_irq(struct phy_device *phydev, bool state)
592592

593593
static int bcm54xx_suspend(struct phy_device *phydev)
594594
{
595+
struct bcm54xx_phy_priv *priv = phydev->priv;
595596
int ret = 0;
596597

598+
mutex_lock(&phydev->lock);
599+
bcm_phy_update_stats_shadow(phydev, priv->stats);
600+
mutex_unlock(&phydev->lock);
601+
597602
bcm54xx_ptp_stop(phydev);
598603

599604
/* Acknowledge any Wake-on-LAN interrupt prior to suspend */

0 commit comments

Comments
 (0)