mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: phy: smsc: Implement PHY statistics
Most of the PHYs supported by the SMSC driver have a counter of symbol errors. This is 16 bit wide and wraps around when it reaches its maximum value. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-By: Woojung Huh <Woojung.Huh@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									386e2e4bd7
								
							
						
					
					
						commit
						030a89028d
					
				
					 1 changed files with 72 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -25,6 +25,16 @@
 | 
			
		|||
#include <linux/netdevice.h>
 | 
			
		||||
#include <linux/smscphy.h>
 | 
			
		||||
 | 
			
		||||
struct smsc_hw_stat {
 | 
			
		||||
	const char *string;
 | 
			
		||||
	u8 reg;
 | 
			
		||||
	u8 bits;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct smsc_hw_stat smsc_hw_stats[] = {
 | 
			
		||||
	{ "phy_symbol_errors", 26, 16},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct smsc_phy_priv {
 | 
			
		||||
	bool energy_enable;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +153,48 @@ static int lan87xx_read_status(struct phy_device *phydev)
 | 
			
		|||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int smsc_get_sset_count(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	return ARRAY_SIZE(smsc_hw_stats);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void smsc_get_strings(struct phy_device *phydev, u8 *data)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) {
 | 
			
		||||
		memcpy(data + i * ETH_GSTRING_LEN,
 | 
			
		||||
		       smsc_hw_stats[i].string, ETH_GSTRING_LEN);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef UINT64_MAX
 | 
			
		||||
#define UINT64_MAX              (u64)(~((u64)0))
 | 
			
		||||
#endif
 | 
			
		||||
static u64 smsc_get_stat(struct phy_device *phydev, int i)
 | 
			
		||||
{
 | 
			
		||||
	struct smsc_hw_stat stat = smsc_hw_stats[i];
 | 
			
		||||
	int val;
 | 
			
		||||
	u64 ret;
 | 
			
		||||
 | 
			
		||||
	val = phy_read(phydev, stat.reg);
 | 
			
		||||
	if (val < 0)
 | 
			
		||||
		ret = UINT64_MAX;
 | 
			
		||||
	else
 | 
			
		||||
		ret = val;
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void smsc_get_stats(struct phy_device *phydev,
 | 
			
		||||
			   struct ethtool_stats *stats, u64 *data)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++)
 | 
			
		||||
		data[i] = smsc_get_stat(phydev, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int smsc_phy_probe(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	struct device *dev = &phydev->mdio.dev;
 | 
			
		||||
| 
						 | 
				
			
			@ -206,6 +258,11 @@ static struct phy_driver smsc_phy_driver[] = {
 | 
			
		|||
	.ack_interrupt	= smsc_phy_ack_interrupt,
 | 
			
		||||
	.config_intr	= smsc_phy_config_intr,
 | 
			
		||||
 | 
			
		||||
	/* Statistics */
 | 
			
		||||
	.get_sset_count = smsc_get_sset_count,
 | 
			
		||||
	.get_strings	= smsc_get_strings,
 | 
			
		||||
	.get_stats	= smsc_get_stats,
 | 
			
		||||
 | 
			
		||||
	.suspend	= genphy_suspend,
 | 
			
		||||
	.resume		= genphy_resume,
 | 
			
		||||
}, {
 | 
			
		||||
| 
						 | 
				
			
			@ -228,6 +285,11 @@ static struct phy_driver smsc_phy_driver[] = {
 | 
			
		|||
	.ack_interrupt	= smsc_phy_ack_interrupt,
 | 
			
		||||
	.config_intr	= smsc_phy_config_intr,
 | 
			
		||||
 | 
			
		||||
	/* Statistics */
 | 
			
		||||
	.get_sset_count = smsc_get_sset_count,
 | 
			
		||||
	.get_strings	= smsc_get_strings,
 | 
			
		||||
	.get_stats	= smsc_get_stats,
 | 
			
		||||
 | 
			
		||||
	.suspend	= genphy_suspend,
 | 
			
		||||
	.resume		= genphy_resume,
 | 
			
		||||
}, {
 | 
			
		||||
| 
						 | 
				
			
			@ -271,6 +333,11 @@ static struct phy_driver smsc_phy_driver[] = {
 | 
			
		|||
	.ack_interrupt	= smsc_phy_ack_interrupt,
 | 
			
		||||
	.config_intr	= smsc_phy_config_intr,
 | 
			
		||||
 | 
			
		||||
	/* Statistics */
 | 
			
		||||
	.get_sset_count = smsc_get_sset_count,
 | 
			
		||||
	.get_strings	= smsc_get_strings,
 | 
			
		||||
	.get_stats	= smsc_get_stats,
 | 
			
		||||
 | 
			
		||||
	.suspend	= genphy_suspend,
 | 
			
		||||
	.resume		= genphy_resume,
 | 
			
		||||
}, {
 | 
			
		||||
| 
						 | 
				
			
			@ -293,6 +360,11 @@ static struct phy_driver smsc_phy_driver[] = {
 | 
			
		|||
	.ack_interrupt	= smsc_phy_ack_interrupt,
 | 
			
		||||
	.config_intr	= smsc_phy_config_intr,
 | 
			
		||||
 | 
			
		||||
	/* Statistics */
 | 
			
		||||
	.get_sset_count = smsc_get_sset_count,
 | 
			
		||||
	.get_strings	= smsc_get_strings,
 | 
			
		||||
	.get_stats	= smsc_get_stats,
 | 
			
		||||
 | 
			
		||||
	.suspend	= genphy_suspend,
 | 
			
		||||
	.resume		= genphy_resume,
 | 
			
		||||
} };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue