Skip to content

Commit f2bc1c2

Browse files
oleremPaolo Abeni
authored andcommitted
net: phy: introduce optional polling interface for PHY statistics
Add an optional polling interface for PHY statistics to simplify driver implementation. Signed-off-by: Oleksij Rempel <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 7d66c74 commit f2bc1c2

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

drivers/net/phy/phy.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,23 @@ static int phy_enable_interrupts(struct phy_device *phydev)
14411441
return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
14421442
}
14431443

1444+
/**
1445+
* phy_update_stats - Update PHY device statistics if supported.
1446+
* @phydev: Pointer to the PHY device structure.
1447+
*
1448+
* If the PHY driver provides an update_stats callback, this function
1449+
* invokes it to update the PHY statistics. If not, it returns 0.
1450+
*
1451+
* Return: 0 on success, or a negative error code if the callback fails.
1452+
*/
1453+
static int phy_update_stats(struct phy_device *phydev)
1454+
{
1455+
if (!phydev->drv->update_stats)
1456+
return 0;
1457+
1458+
return phydev->drv->update_stats(phydev);
1459+
}
1460+
14441461
/**
14451462
* phy_request_interrupt - request and enable interrupt for a PHY device
14461463
* @phydev: target phy_device struct
@@ -1510,6 +1527,9 @@ static enum phy_state_work _phy_state_machine(struct phy_device *phydev)
15101527
case PHY_RUNNING:
15111528
err = phy_check_link_status(phydev);
15121529
func = &phy_check_link_status;
1530+
1531+
if (!err)
1532+
err = phy_update_stats(phydev);
15131533
break;
15141534
case PHY_CABLETEST:
15151535
err = phydev->drv->cable_test_get_status(phydev, &finished);

include/linux/phy.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,24 @@ struct phy_driver {
11731173
*/
11741174
void (*get_link_stats)(struct phy_device *dev,
11751175
struct ethtool_link_ext_stats *link_stats);
1176+
1177+
/**
1178+
* @update_stats: Trigger periodic statistics updates.
1179+
* @dev: The PHY device for which statistics updates are triggered.
1180+
*
1181+
* Periodically gathers statistics from the PHY device to update locally
1182+
* maintained 64-bit counters. This is necessary for PHYs that implement
1183+
* reduced-width counters (e.g., 16-bit or 32-bit) which can overflow
1184+
* more frequently compared to 64-bit counters. By invoking this
1185+
* callback, drivers can fetch the current counter values, handle
1186+
* overflow detection, and accumulate the results into local 64-bit
1187+
* counters for accurate reporting through the `get_phy_stats` and
1188+
* `get_link_stats` interfaces.
1189+
*
1190+
* Return: 0 on success or a negative error code on failure.
1191+
*/
1192+
int (*update_stats)(struct phy_device *dev);
1193+
11761194
/** @get_sset_count: Number of statistic counters */
11771195
int (*get_sset_count)(struct phy_device *dev);
11781196
/** @get_strings: Names of the statistic counters */
@@ -1663,6 +1681,9 @@ static inline bool phy_polling_mode(struct phy_device *phydev)
16631681
if (phydev->drv->flags & PHY_POLL_CABLE_TEST)
16641682
return true;
16651683

1684+
if (phydev->drv->update_stats)
1685+
return true;
1686+
16661687
return phydev->irq == PHY_POLL;
16671688
}
16681689

0 commit comments

Comments
 (0)