[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241219132534.725051-6-o.rempel@pengutronix.de>
Date: Thu, 19 Dec 2024 14:25:31 +0100
From: Oleksij Rempel <o.rempel@...gutronix.de>
To: "David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Andrew Lunn <andrew+netdev@...n.ch>,
Heiner Kallweit <hkallweit1@...il.com>,
Jonathan Corbet <corbet@....net>
Cc: Oleksij Rempel <o.rempel@...gutronix.de>,
kernel@...gutronix.de,
linux-kernel@...r.kernel.org,
netdev@...r.kernel.org,
Simon Horman <horms@...nel.org>,
Russell King <linux@...linux.org.uk>,
Maxime Chevallier <maxime.chevallier@...tlin.com>,
linux-doc@...r.kernel.org
Subject: [PATCH net-next v2 5/8] net: phy: introduce optional polling interface for PHY statistics
Add an optional polling interface for PHY statistics to simplify driver
implementation. Drivers can request the PHYlib to handle the polling
task by explicitly setting the `PHY_POLL_STATS` flag in their driver
configuration.
Signed-off-by: Oleksij Rempel <o.rempel@...gutronix.de>
---
changes v2:
- drop PHY_POLL_STATS
- add function comments
---
drivers/net/phy/phy.c | 20 ++++++++++++++++++++
include/linux/phy.h | 21 +++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 107a35f402b3..7f6d304105f5 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1442,6 +1442,23 @@ static int phy_enable_interrupts(struct phy_device *phydev)
return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
}
+/**
+ * phy_update_stats - Update PHY device statistics if supported.
+ * @phydev: Pointer to the PHY device structure.
+ *
+ * If the PHY driver provides an update_stats callback, this function
+ * invokes it to update the PHY statistics. If not, it returns 0.
+ *
+ * Return: 0 on success, or a negative error code if the callback fails.
+ */
+static int phy_update_stats(struct phy_device *phydev)
+{
+ if (!phydev->drv->update_stats)
+ return 0;
+
+ return phydev->drv->update_stats(phydev);
+}
+
/**
* phy_request_interrupt - request and enable interrupt for a PHY device
* @phydev: target phy_device struct
@@ -1511,6 +1528,9 @@ static enum phy_state_work _phy_state_machine(struct phy_device *phydev)
case PHY_RUNNING:
err = phy_check_link_status(phydev);
func = &phy_check_link_status;
+
+ if (!err)
+ err = phy_update_stats(phydev);
break;
case PHY_CABLETEST:
err = phydev->drv->cable_test_get_status(phydev, &finished);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index e1554ac16ce2..b3e4a164bfb7 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1180,6 +1180,24 @@ struct phy_driver {
*/
void (*get_link_stats)(struct phy_device *dev,
struct ethtool_link_ext_stats *link_stats);
+
+ /**
+ * update_stats - Trigger periodic statistics updates.
+ * @dev: The PHY device for which statistics updates are triggered.
+ *
+ * Periodically gathers statistics from the PHY device to update locally
+ * maintained 64-bit counters. This is necessary for PHYs that implement
+ * reduced-width counters (e.g., 16-bit or 32-bit) which can overflow
+ * more frequently compared to 64-bit counters. By invoking this
+ * callback, drivers can fetch the current counter values, handle
+ * overflow detection, and accumulate the results into local 64-bit
+ * counters for accurate reporting through the `get_phy_stats` and
+ * `get_link_stats` interfaces.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+ int (*update_stats)(struct phy_device *dev);
+
/** @get_sset_count: Number of statistic counters */
int (*get_sset_count)(struct phy_device *dev);
/** @get_strings: Names of the statistic counters */
@@ -1670,6 +1688,9 @@ static inline bool phy_polling_mode(struct phy_device *phydev)
if (phydev->drv->flags & PHY_POLL_CABLE_TEST)
return true;
+ if (phydev->drv->update_stats)
+ return true;
+
return phydev->irq == PHY_POLL;
}
--
2.39.5
Powered by blists - more mailing lists