On Mon, 6 Jan 2025 09:32:55 +0100 Oleksij Rempel wrote: > + /** > + * @get_link_stats: Retrieve link statistics. > + * @dev: The PHY device for which the statistics are retrieved. > + * @link_stats: structure where link-specific stats will be stored. > + * > + * Retrieves link-related statistics for the given PHY device. The input > + * structure is pre-initialized with `ETHTOOL_STAT_NOT_SET`, and the > + * driver must only modify members corresponding to supported > + * statistics. Unmodified members will remain set to > + * `ETHTOOL_STAT_NOT_SET` and will not be returned to userspace. > + * > + * Return: 0 on success or a negative error code on failure. These get callbacks return void > + */ > + void (*get_link_stats)(struct phy_device *dev, > + struct ethtool_link_ext_stats *link_stats); > /** @get_sset_count: Number of statistic counters */ > int (*get_sset_count)(struct phy_device *dev); > /** @get_strings: Names of the statistic counters */ > @@ -1777,6 +1810,49 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev) > return phydev->is_pseudo_fixed_link; > } > > +/** > + * phy_ethtool_get_phy_stats - Retrieve standardized PHY statistics > + * @phydev: Pointer to the PHY device > + * @phy_stats: Pointer to ethtool_eth_phy_stats structure > + * @phydev_stats: Pointer to ethtool_phy_stats structure > + * > + * Fetches PHY statistics using a kernel-defined interface for consistent > + * diagnostics. Unlike phy_ethtool_get_stats(), which allows custom stats, > + * this function enforces a standardized format for better interoperability. > + */ > +static inline void phy_ethtool_get_phy_stats(struct phy_device *phydev, > + struct ethtool_eth_phy_stats *phy_stats, > + struct ethtool_phy_stats *phydev_stats) > +{ > + if (!phydev->drv || !phydev->drv->get_phy_stats) > + return; > + > + mutex_lock(&phydev->lock); > + phydev->drv->get_phy_stats(phydev, phy_stats, phydev_stats); > + mutex_unlock(&phydev->lock); > +} > + > +/** > + * phy_ethtool_get_link_ext_stats - Retrieve extended link statistics for a PHY > + * @phydev: Pointer to the PHY device > + * @link_stats: Pointer to the structure to store extended link statistics > + * > + * Populates the ethtool_link_ext_stats structure with link down event counts > + * and additional driver-specific link statistics, if available. > + */ > +static inline void phy_ethtool_get_link_ext_stats(struct phy_device *phydev, > + struct ethtool_link_ext_stats *link_stats) > +{ > + link_stats->link_down_events = READ_ONCE(phydev->link_down_events); > + > + if (!phydev->drv || !phydev->drv->get_link_stats) > + return; > + > + mutex_lock(&phydev->lock); > + phydev->drv->get_link_stats(phydev, link_stats); > + mutex_unlock(&phydev->lock); > +} Do these have to be static inlines? Seemds like it will just bloat the header, and make alignment more painful.