Skip to content

Commit

Permalink
Merge branch 'ethtool-phy-stats'
Browse files Browse the repository at this point in the history
Andrew Lunn says:

====================
Ethtool support for phy stats

This patchset add ethtool support for reading statistics from the PHY.
The Marvell and Micrel Phys are then extended to report receiver
packet errors and idle errors.

v2:
  Fix linking when phylib is not enabled.
v3:
  Inline helpers into ethtool.c, so fixing when phylib is a module.
v4:
  Add missing static
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 31, 2015
2 parents a3748a9 + 2b2427d commit ccac042
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 1 deletion.
135 changes: 135 additions & 0 deletions drivers/net/phy/marvell.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,22 @@ MODULE_DESCRIPTION("Marvell PHY driver");
MODULE_AUTHOR("Andy Fleming");
MODULE_LICENSE("GPL");

struct marvell_hw_stat {
const char *string;
u8 page;
u8 reg;
u8 bits;
};

static struct marvell_hw_stat marvell_hw_stats[] = {
{ "phy_receive_errors", 0, 21, 16},
{ "phy_idle_errors", 0, 10, 8 },
};

struct marvell_priv {
u64 stats[ARRAY_SIZE(marvell_hw_stats)];
};

static int marvell_ack_interrupt(struct phy_device *phydev)
{
int err;
Expand Down Expand Up @@ -986,19 +1002,90 @@ static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *w
return 0;
}

static int marvell_get_sset_count(struct phy_device *phydev)
{
return ARRAY_SIZE(marvell_hw_stats);
}

static void marvell_get_strings(struct phy_device *phydev, u8 *data)
{
int i;

for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
memcpy(data + i * ETH_GSTRING_LEN,
marvell_hw_stats[i].string, ETH_GSTRING_LEN);
}
}

#ifndef UINT64_MAX
#define UINT64_MAX (u64)(~((u64)0))
#endif
static u64 marvell_get_stat(struct phy_device *phydev, int i)
{
struct marvell_hw_stat stat = marvell_hw_stats[i];
struct marvell_priv *priv = phydev->priv;
int err, oldpage;
u64 val;

oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
stat.page);
if (err < 0)
return UINT64_MAX;

val = phy_read(phydev, stat.reg);
if (val < 0) {
val = UINT64_MAX;
} else {
val = val & ((1 << stat.bits) - 1);
priv->stats[i] += val;
val = priv->stats[i];
}

phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);

return val;
}

static void marvell_get_stats(struct phy_device *phydev,
struct ethtool_stats *stats, u64 *data)
{
int i;

for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++)
data[i] = marvell_get_stat(phydev, i);
}

static int marvell_probe(struct phy_device *phydev)
{
struct marvell_priv *priv;

priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

phydev->priv = priv;

return 0;
}

static struct phy_driver marvell_drivers[] = {
{
.phy_id = MARVELL_PHY_ID_88E1101,
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1101",
.features = PHY_GBIT_FEATURES,
.probe = marvell_probe,
.flags = PHY_HAS_INTERRUPT,
.config_aneg = &marvell_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1007,13 +1094,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1112",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1111_config_init,
.config_aneg = &marvell_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1022,13 +1113,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1111",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1111_config_init,
.config_aneg = &marvell_config_aneg,
.read_status = &marvell_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1037,13 +1132,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1118",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1118_config_init,
.config_aneg = &m88e1118_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = {.owner = THIS_MODULE,},
},
{
Expand All @@ -1052,13 +1151,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1121R",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_aneg = &m88e1121_config_aneg,
.read_status = &marvell_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.did_interrupt = &m88e1121_did_interrupt,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1067,6 +1170,7 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1318S",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_aneg = &m88e1318_config_aneg,
.read_status = &marvell_read_status,
.ack_interrupt = &marvell_ack_interrupt,
Expand All @@ -1076,6 +1180,9 @@ static struct phy_driver marvell_drivers[] = {
.set_wol = &m88e1318_set_wol,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1084,13 +1191,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1145",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1145_config_init,
.config_aneg = &marvell_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1099,13 +1210,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1149R",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1149_config_init,
.config_aneg = &m88e1118_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1114,13 +1229,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1240",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1111_config_init,
.config_aneg = &marvell_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1129,13 +1248,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1116R",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_init = &m88e1116r_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1144,13 +1267,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1510",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_aneg = &m88e1510_config_aneg,
.read_status = &marvell_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.did_interrupt = &m88e1121_did_interrupt,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1159,13 +1286,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1540",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_aneg = &m88e1510_config_aneg,
.read_status = &marvell_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
.did_interrupt = &m88e1121_did_interrupt,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
{
Expand All @@ -1174,6 +1305,7 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E3016",
.features = PHY_BASIC_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.probe = marvell_probe,
.config_aneg = &genphy_config_aneg,
.config_init = &m88e3016_config_init,
.aneg_done = &marvell_aneg_done,
Expand All @@ -1183,6 +1315,9 @@ static struct phy_driver marvell_drivers[] = {
.did_interrupt = &m88e1121_did_interrupt,
.resume = &genphy_resume,
.suspend = &genphy_suspend,
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.driver = { .owner = THIS_MODULE },
},
};
Expand Down
Loading

0 comments on commit ccac042

Please sign in to comment.