[PATCH net-next v2 5/8] net: phy: introduce optional polling interface for PHY statistics

Oleksij Rempel posted 8 patches 12 months ago
There is a newer version of this series
[PATCH net-next v2 5/8] net: phy: introduce optional polling interface for PHY statistics
Posted by Oleksij Rempel 12 months ago
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@pengutronix.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
Re: [PATCH net-next v2 5/8] net: phy: introduce optional polling interface for PHY statistics
Posted by Oleksij Rempel 12 months ago
On Thu, Dec 19, 2024 at 02:25:31PM +0100, Oleksij Rempel wrote:
> 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.

The commit message is out of date. PHY_POLL_STATS should be removed.

> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.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
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |