Skip to content

Commit d2fa47d

Browse files
lunndavem330
authored andcommitted
phy: marvell: Add ethtool statistics counters
The PHY counters receiver errors and errors while idle. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent f3a4094 commit d2fa47d

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

drivers/net/phy/marvell.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,22 @@ MODULE_DESCRIPTION("Marvell PHY driver");
137137
MODULE_AUTHOR("Andy Fleming");
138138
MODULE_LICENSE("GPL");
139139

140+
struct marvell_hw_stat {
141+
const char *string;
142+
u8 page;
143+
u8 reg;
144+
u8 bits;
145+
};
146+
147+
static struct marvell_hw_stat marvell_hw_stats[] = {
148+
{ "phy_receive_errors", 0, 21, 16},
149+
{ "phy_idle_errors", 0, 10, 8 },
150+
};
151+
152+
struct marvell_priv {
153+
u64 stats[ARRAY_SIZE(marvell_hw_stats)];
154+
};
155+
140156
static int marvell_ack_interrupt(struct phy_device *phydev)
141157
{
142158
int err;
@@ -986,19 +1002,90 @@ static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *w
9861002
return 0;
9871003
}
9881004

1005+
static int marvell_get_sset_count(struct phy_device *phydev)
1006+
{
1007+
return ARRAY_SIZE(marvell_hw_stats);
1008+
}
1009+
1010+
static void marvell_get_strings(struct phy_device *phydev, u8 *data)
1011+
{
1012+
int i;
1013+
1014+
for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
1015+
memcpy(data + i * ETH_GSTRING_LEN,
1016+
marvell_hw_stats[i].string, ETH_GSTRING_LEN);
1017+
}
1018+
}
1019+
1020+
#ifndef UINT64_MAX
1021+
#define UINT64_MAX (u64)(~((u64)0))
1022+
#endif
1023+
static u64 marvell_get_stat(struct phy_device *phydev, int i)
1024+
{
1025+
struct marvell_hw_stat stat = marvell_hw_stats[i];
1026+
struct marvell_priv *priv = phydev->priv;
1027+
int err, oldpage;
1028+
u64 val;
1029+
1030+
oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
1031+
err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
1032+
stat.page);
1033+
if (err < 0)
1034+
return UINT64_MAX;
1035+
1036+
val = phy_read(phydev, stat.reg);
1037+
if (val < 0) {
1038+
val = UINT64_MAX;
1039+
} else {
1040+
val = val & ((1 << stat.bits) - 1);
1041+
priv->stats[i] += val;
1042+
val = priv->stats[i];
1043+
}
1044+
1045+
phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
1046+
1047+
return val;
1048+
}
1049+
1050+
static void marvell_get_stats(struct phy_device *phydev,
1051+
struct ethtool_stats *stats, u64 *data)
1052+
{
1053+
int i;
1054+
1055+
for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++)
1056+
data[i] = marvell_get_stat(phydev, i);
1057+
}
1058+
1059+
static int marvell_probe(struct phy_device *phydev)
1060+
{
1061+
struct marvell_priv *priv;
1062+
1063+
priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
1064+
if (!priv)
1065+
return -ENOMEM;
1066+
1067+
phydev->priv = priv;
1068+
1069+
return 0;
1070+
}
1071+
9891072
static struct phy_driver marvell_drivers[] = {
9901073
{
9911074
.phy_id = MARVELL_PHY_ID_88E1101,
9921075
.phy_id_mask = MARVELL_PHY_ID_MASK,
9931076
.name = "Marvell 88E1101",
9941077
.features = PHY_GBIT_FEATURES,
1078+
.probe = marvell_probe,
9951079
.flags = PHY_HAS_INTERRUPT,
9961080
.config_aneg = &marvell_config_aneg,
9971081
.read_status = &genphy_read_status,
9981082
.ack_interrupt = &marvell_ack_interrupt,
9991083
.config_intr = &marvell_config_intr,
10001084
.resume = &genphy_resume,
10011085
.suspend = &genphy_suspend,
1086+
.get_sset_count = marvell_get_sset_count,
1087+
.get_strings = marvell_get_strings,
1088+
.get_stats = marvell_get_stats,
10021089
.driver = { .owner = THIS_MODULE },
10031090
},
10041091
{
@@ -1007,13 +1094,17 @@ static struct phy_driver marvell_drivers[] = {
10071094
.name = "Marvell 88E1112",
10081095
.features = PHY_GBIT_FEATURES,
10091096
.flags = PHY_HAS_INTERRUPT,
1097+
.probe = marvell_probe,
10101098
.config_init = &m88e1111_config_init,
10111099
.config_aneg = &marvell_config_aneg,
10121100
.read_status = &genphy_read_status,
10131101
.ack_interrupt = &marvell_ack_interrupt,
10141102
.config_intr = &marvell_config_intr,
10151103
.resume = &genphy_resume,
10161104
.suspend = &genphy_suspend,
1105+
.get_sset_count = marvell_get_sset_count,
1106+
.get_strings = marvell_get_strings,
1107+
.get_stats = marvell_get_stats,
10171108
.driver = { .owner = THIS_MODULE },
10181109
},
10191110
{
@@ -1022,13 +1113,17 @@ static struct phy_driver marvell_drivers[] = {
10221113
.name = "Marvell 88E1111",
10231114
.features = PHY_GBIT_FEATURES,
10241115
.flags = PHY_HAS_INTERRUPT,
1116+
.probe = marvell_probe,
10251117
.config_init = &m88e1111_config_init,
10261118
.config_aneg = &marvell_config_aneg,
10271119
.read_status = &marvell_read_status,
10281120
.ack_interrupt = &marvell_ack_interrupt,
10291121
.config_intr = &marvell_config_intr,
10301122
.resume = &genphy_resume,
10311123
.suspend = &genphy_suspend,
1124+
.get_sset_count = marvell_get_sset_count,
1125+
.get_strings = marvell_get_strings,
1126+
.get_stats = marvell_get_stats,
10321127
.driver = { .owner = THIS_MODULE },
10331128
},
10341129
{
@@ -1037,13 +1132,17 @@ static struct phy_driver marvell_drivers[] = {
10371132
.name = "Marvell 88E1118",
10381133
.features = PHY_GBIT_FEATURES,
10391134
.flags = PHY_HAS_INTERRUPT,
1135+
.probe = marvell_probe,
10401136
.config_init = &m88e1118_config_init,
10411137
.config_aneg = &m88e1118_config_aneg,
10421138
.read_status = &genphy_read_status,
10431139
.ack_interrupt = &marvell_ack_interrupt,
10441140
.config_intr = &marvell_config_intr,
10451141
.resume = &genphy_resume,
10461142
.suspend = &genphy_suspend,
1143+
.get_sset_count = marvell_get_sset_count,
1144+
.get_strings = marvell_get_strings,
1145+
.get_stats = marvell_get_stats,
10471146
.driver = {.owner = THIS_MODULE,},
10481147
},
10491148
{
@@ -1052,13 +1151,17 @@ static struct phy_driver marvell_drivers[] = {
10521151
.name = "Marvell 88E1121R",
10531152
.features = PHY_GBIT_FEATURES,
10541153
.flags = PHY_HAS_INTERRUPT,
1154+
.probe = marvell_probe,
10551155
.config_aneg = &m88e1121_config_aneg,
10561156
.read_status = &marvell_read_status,
10571157
.ack_interrupt = &marvell_ack_interrupt,
10581158
.config_intr = &marvell_config_intr,
10591159
.did_interrupt = &m88e1121_did_interrupt,
10601160
.resume = &genphy_resume,
10611161
.suspend = &genphy_suspend,
1162+
.get_sset_count = marvell_get_sset_count,
1163+
.get_strings = marvell_get_strings,
1164+
.get_stats = marvell_get_stats,
10621165
.driver = { .owner = THIS_MODULE },
10631166
},
10641167
{
@@ -1067,6 +1170,7 @@ static struct phy_driver marvell_drivers[] = {
10671170
.name = "Marvell 88E1318S",
10681171
.features = PHY_GBIT_FEATURES,
10691172
.flags = PHY_HAS_INTERRUPT,
1173+
.probe = marvell_probe,
10701174
.config_aneg = &m88e1318_config_aneg,
10711175
.read_status = &marvell_read_status,
10721176
.ack_interrupt = &marvell_ack_interrupt,
@@ -1076,6 +1180,9 @@ static struct phy_driver marvell_drivers[] = {
10761180
.set_wol = &m88e1318_set_wol,
10771181
.resume = &genphy_resume,
10781182
.suspend = &genphy_suspend,
1183+
.get_sset_count = marvell_get_sset_count,
1184+
.get_strings = marvell_get_strings,
1185+
.get_stats = marvell_get_stats,
10791186
.driver = { .owner = THIS_MODULE },
10801187
},
10811188
{
@@ -1084,13 +1191,17 @@ static struct phy_driver marvell_drivers[] = {
10841191
.name = "Marvell 88E1145",
10851192
.features = PHY_GBIT_FEATURES,
10861193
.flags = PHY_HAS_INTERRUPT,
1194+
.probe = marvell_probe,
10871195
.config_init = &m88e1145_config_init,
10881196
.config_aneg = &marvell_config_aneg,
10891197
.read_status = &genphy_read_status,
10901198
.ack_interrupt = &marvell_ack_interrupt,
10911199
.config_intr = &marvell_config_intr,
10921200
.resume = &genphy_resume,
10931201
.suspend = &genphy_suspend,
1202+
.get_sset_count = marvell_get_sset_count,
1203+
.get_strings = marvell_get_strings,
1204+
.get_stats = marvell_get_stats,
10941205
.driver = { .owner = THIS_MODULE },
10951206
},
10961207
{
@@ -1099,13 +1210,17 @@ static struct phy_driver marvell_drivers[] = {
10991210
.name = "Marvell 88E1149R",
11001211
.features = PHY_GBIT_FEATURES,
11011212
.flags = PHY_HAS_INTERRUPT,
1213+
.probe = marvell_probe,
11021214
.config_init = &m88e1149_config_init,
11031215
.config_aneg = &m88e1118_config_aneg,
11041216
.read_status = &genphy_read_status,
11051217
.ack_interrupt = &marvell_ack_interrupt,
11061218
.config_intr = &marvell_config_intr,
11071219
.resume = &genphy_resume,
11081220
.suspend = &genphy_suspend,
1221+
.get_sset_count = marvell_get_sset_count,
1222+
.get_strings = marvell_get_strings,
1223+
.get_stats = marvell_get_stats,
11091224
.driver = { .owner = THIS_MODULE },
11101225
},
11111226
{
@@ -1114,13 +1229,17 @@ static struct phy_driver marvell_drivers[] = {
11141229
.name = "Marvell 88E1240",
11151230
.features = PHY_GBIT_FEATURES,
11161231
.flags = PHY_HAS_INTERRUPT,
1232+
.probe = marvell_probe,
11171233
.config_init = &m88e1111_config_init,
11181234
.config_aneg = &marvell_config_aneg,
11191235
.read_status = &genphy_read_status,
11201236
.ack_interrupt = &marvell_ack_interrupt,
11211237
.config_intr = &marvell_config_intr,
11221238
.resume = &genphy_resume,
11231239
.suspend = &genphy_suspend,
1240+
.get_sset_count = marvell_get_sset_count,
1241+
.get_strings = marvell_get_strings,
1242+
.get_stats = marvell_get_stats,
11241243
.driver = { .owner = THIS_MODULE },
11251244
},
11261245
{
@@ -1129,13 +1248,17 @@ static struct phy_driver marvell_drivers[] = {
11291248
.name = "Marvell 88E1116R",
11301249
.features = PHY_GBIT_FEATURES,
11311250
.flags = PHY_HAS_INTERRUPT,
1251+
.probe = marvell_probe,
11321252
.config_init = &m88e1116r_config_init,
11331253
.config_aneg = &genphy_config_aneg,
11341254
.read_status = &genphy_read_status,
11351255
.ack_interrupt = &marvell_ack_interrupt,
11361256
.config_intr = &marvell_config_intr,
11371257
.resume = &genphy_resume,
11381258
.suspend = &genphy_suspend,
1259+
.get_sset_count = marvell_get_sset_count,
1260+
.get_strings = marvell_get_strings,
1261+
.get_stats = marvell_get_stats,
11391262
.driver = { .owner = THIS_MODULE },
11401263
},
11411264
{
@@ -1144,13 +1267,17 @@ static struct phy_driver marvell_drivers[] = {
11441267
.name = "Marvell 88E1510",
11451268
.features = PHY_GBIT_FEATURES,
11461269
.flags = PHY_HAS_INTERRUPT,
1270+
.probe = marvell_probe,
11471271
.config_aneg = &m88e1510_config_aneg,
11481272
.read_status = &marvell_read_status,
11491273
.ack_interrupt = &marvell_ack_interrupt,
11501274
.config_intr = &marvell_config_intr,
11511275
.did_interrupt = &m88e1121_did_interrupt,
11521276
.resume = &genphy_resume,
11531277
.suspend = &genphy_suspend,
1278+
.get_sset_count = marvell_get_sset_count,
1279+
.get_strings = marvell_get_strings,
1280+
.get_stats = marvell_get_stats,
11541281
.driver = { .owner = THIS_MODULE },
11551282
},
11561283
{
@@ -1159,13 +1286,17 @@ static struct phy_driver marvell_drivers[] = {
11591286
.name = "Marvell 88E1540",
11601287
.features = PHY_GBIT_FEATURES,
11611288
.flags = PHY_HAS_INTERRUPT,
1289+
.probe = marvell_probe,
11621290
.config_aneg = &m88e1510_config_aneg,
11631291
.read_status = &marvell_read_status,
11641292
.ack_interrupt = &marvell_ack_interrupt,
11651293
.config_intr = &marvell_config_intr,
11661294
.did_interrupt = &m88e1121_did_interrupt,
11671295
.resume = &genphy_resume,
11681296
.suspend = &genphy_suspend,
1297+
.get_sset_count = marvell_get_sset_count,
1298+
.get_strings = marvell_get_strings,
1299+
.get_stats = marvell_get_stats,
11691300
.driver = { .owner = THIS_MODULE },
11701301
},
11711302
{
@@ -1174,6 +1305,7 @@ static struct phy_driver marvell_drivers[] = {
11741305
.name = "Marvell 88E3016",
11751306
.features = PHY_BASIC_FEATURES,
11761307
.flags = PHY_HAS_INTERRUPT,
1308+
.probe = marvell_probe,
11771309
.config_aneg = &genphy_config_aneg,
11781310
.config_init = &m88e3016_config_init,
11791311
.aneg_done = &marvell_aneg_done,
@@ -1183,6 +1315,9 @@ static struct phy_driver marvell_drivers[] = {
11831315
.did_interrupt = &m88e1121_did_interrupt,
11841316
.resume = &genphy_resume,
11851317
.suspend = &genphy_suspend,
1318+
.get_sset_count = marvell_get_sset_count,
1319+
.get_strings = marvell_get_strings,
1320+
.get_stats = marvell_get_stats,
11861321
.driver = { .owner = THIS_MODULE },
11871322
},
11881323
};

0 commit comments

Comments
 (0)