Skip to content

Commit 2b2427d

Browse files
lunndavem330
authored andcommitted
phy: micrel: 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 d2fa47d commit 2b2427d

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

drivers/net/phy/micrel.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@
7373

7474
#define PS_TO_REG 200
7575

76+
struct kszphy_hw_stat {
77+
const char *string;
78+
u8 reg;
79+
u8 bits;
80+
};
81+
82+
static struct kszphy_hw_stat kszphy_hw_stats[] = {
83+
{ "phy_receive_errors", 21, 16},
84+
{ "phy_idle_errors", 10, 8 },
85+
};
86+
7687
struct kszphy_type {
7788
u32 led_mode_reg;
7889
u16 interrupt_level_mask;
@@ -86,6 +97,7 @@ struct kszphy_priv {
8697
int led_mode;
8798
bool rmii_ref_clk_sel;
8899
bool rmii_ref_clk_sel_val;
100+
u64 stats[ARRAY_SIZE(kszphy_hw_stats)];
89101
};
90102

91103
static const struct kszphy_type ksz8021_type = {
@@ -569,6 +581,51 @@ ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
569581
{
570582
}
571583

584+
static int kszphy_get_sset_count(struct phy_device *phydev)
585+
{
586+
return ARRAY_SIZE(kszphy_hw_stats);
587+
}
588+
589+
static void kszphy_get_strings(struct phy_device *phydev, u8 *data)
590+
{
591+
int i;
592+
593+
for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) {
594+
memcpy(data + i * ETH_GSTRING_LEN,
595+
kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
596+
}
597+
}
598+
599+
#ifndef UINT64_MAX
600+
#define UINT64_MAX (u64)(~((u64)0))
601+
#endif
602+
static u64 kszphy_get_stat(struct phy_device *phydev, int i)
603+
{
604+
struct kszphy_hw_stat stat = kszphy_hw_stats[i];
605+
struct kszphy_priv *priv = phydev->priv;
606+
u64 val;
607+
608+
val = phy_read(phydev, stat.reg);
609+
if (val < 0) {
610+
val = UINT64_MAX;
611+
} else {
612+
val = val & ((1 << stat.bits) - 1);
613+
priv->stats[i] += val;
614+
val = priv->stats[i];
615+
}
616+
617+
return val;
618+
}
619+
620+
static void kszphy_get_stats(struct phy_device *phydev,
621+
struct ethtool_stats *stats, u64 *data)
622+
{
623+
int i;
624+
625+
for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++)
626+
data[i] = kszphy_get_stat(phydev, i);
627+
}
628+
572629
static int kszphy_probe(struct phy_device *phydev)
573630
{
574631
const struct kszphy_type *type = phydev->drv->driver_data;
@@ -642,6 +699,9 @@ static struct phy_driver ksphy_driver[] = {
642699
.read_status = genphy_read_status,
643700
.ack_interrupt = kszphy_ack_interrupt,
644701
.config_intr = kszphy_config_intr,
702+
.get_sset_count = kszphy_get_sset_count,
703+
.get_strings = kszphy_get_strings,
704+
.get_stats = kszphy_get_stats,
645705
.suspend = genphy_suspend,
646706
.resume = genphy_resume,
647707
.driver = { .owner = THIS_MODULE,},
@@ -659,6 +719,9 @@ static struct phy_driver ksphy_driver[] = {
659719
.read_status = genphy_read_status,
660720
.ack_interrupt = kszphy_ack_interrupt,
661721
.config_intr = kszphy_config_intr,
722+
.get_sset_count = kszphy_get_sset_count,
723+
.get_strings = kszphy_get_strings,
724+
.get_stats = kszphy_get_stats,
662725
.suspend = genphy_suspend,
663726
.resume = genphy_resume,
664727
.driver = { .owner = THIS_MODULE,},
@@ -676,6 +739,9 @@ static struct phy_driver ksphy_driver[] = {
676739
.read_status = genphy_read_status,
677740
.ack_interrupt = kszphy_ack_interrupt,
678741
.config_intr = kszphy_config_intr,
742+
.get_sset_count = kszphy_get_sset_count,
743+
.get_strings = kszphy_get_strings,
744+
.get_stats = kszphy_get_stats,
679745
.suspend = genphy_suspend,
680746
.resume = genphy_resume,
681747
.driver = { .owner = THIS_MODULE,},
@@ -693,6 +759,9 @@ static struct phy_driver ksphy_driver[] = {
693759
.read_status = genphy_read_status,
694760
.ack_interrupt = kszphy_ack_interrupt,
695761
.config_intr = kszphy_config_intr,
762+
.get_sset_count = kszphy_get_sset_count,
763+
.get_strings = kszphy_get_strings,
764+
.get_stats = kszphy_get_stats,
696765
.suspend = genphy_suspend,
697766
.resume = genphy_resume,
698767
.driver = { .owner = THIS_MODULE,},
@@ -710,6 +779,9 @@ static struct phy_driver ksphy_driver[] = {
710779
.read_status = genphy_read_status,
711780
.ack_interrupt = kszphy_ack_interrupt,
712781
.config_intr = kszphy_config_intr,
782+
.get_sset_count = kszphy_get_sset_count,
783+
.get_strings = kszphy_get_strings,
784+
.get_stats = kszphy_get_stats,
713785
.suspend = genphy_suspend,
714786
.resume = genphy_resume,
715787
.driver = { .owner = THIS_MODULE,},
@@ -727,6 +799,9 @@ static struct phy_driver ksphy_driver[] = {
727799
.read_status = genphy_read_status,
728800
.ack_interrupt = kszphy_ack_interrupt,
729801
.config_intr = kszphy_config_intr,
802+
.get_sset_count = kszphy_get_sset_count,
803+
.get_strings = kszphy_get_strings,
804+
.get_stats = kszphy_get_stats,
730805
.suspend = genphy_suspend,
731806
.resume = genphy_resume,
732807
.driver = { .owner = THIS_MODULE,},
@@ -743,6 +818,9 @@ static struct phy_driver ksphy_driver[] = {
743818
.read_status = genphy_read_status,
744819
.ack_interrupt = kszphy_ack_interrupt,
745820
.config_intr = kszphy_config_intr,
821+
.get_sset_count = kszphy_get_sset_count,
822+
.get_strings = kszphy_get_strings,
823+
.get_stats = kszphy_get_stats,
746824
.suspend = genphy_suspend,
747825
.resume = genphy_resume,
748826
.driver = { .owner = THIS_MODULE,},
@@ -759,6 +837,9 @@ static struct phy_driver ksphy_driver[] = {
759837
.read_status = genphy_read_status,
760838
.ack_interrupt = kszphy_ack_interrupt,
761839
.config_intr = kszphy_config_intr,
840+
.get_sset_count = kszphy_get_sset_count,
841+
.get_strings = kszphy_get_strings,
842+
.get_stats = kszphy_get_stats,
762843
.suspend = genphy_suspend,
763844
.resume = genphy_resume,
764845
.driver = { .owner = THIS_MODULE,},
@@ -773,6 +854,9 @@ static struct phy_driver ksphy_driver[] = {
773854
.read_status = genphy_read_status,
774855
.ack_interrupt = kszphy_ack_interrupt,
775856
.config_intr = kszphy_config_intr,
857+
.get_sset_count = kszphy_get_sset_count,
858+
.get_strings = kszphy_get_strings,
859+
.get_stats = kszphy_get_stats,
776860
.suspend = genphy_suspend,
777861
.resume = genphy_resume,
778862
.driver = { .owner = THIS_MODULE,},
@@ -788,6 +872,9 @@ static struct phy_driver ksphy_driver[] = {
788872
.read_status = genphy_read_status,
789873
.ack_interrupt = kszphy_ack_interrupt,
790874
.config_intr = kszphy_config_intr,
875+
.get_sset_count = kszphy_get_sset_count,
876+
.get_strings = kszphy_get_strings,
877+
.get_stats = kszphy_get_stats,
791878
.suspend = genphy_suspend,
792879
.resume = genphy_resume,
793880
.read_mmd_indirect = ksz9021_rd_mmd_phyreg,
@@ -805,6 +892,9 @@ static struct phy_driver ksphy_driver[] = {
805892
.read_status = ksz9031_read_status,
806893
.ack_interrupt = kszphy_ack_interrupt,
807894
.config_intr = kszphy_config_intr,
895+
.get_sset_count = kszphy_get_sset_count,
896+
.get_strings = kszphy_get_strings,
897+
.get_stats = kszphy_get_stats,
808898
.suspend = genphy_suspend,
809899
.resume = genphy_resume,
810900
.driver = { .owner = THIS_MODULE, },
@@ -817,6 +907,9 @@ static struct phy_driver ksphy_driver[] = {
817907
.config_init = kszphy_config_init,
818908
.config_aneg = ksz8873mll_config_aneg,
819909
.read_status = ksz8873mll_read_status,
910+
.get_sset_count = kszphy_get_sset_count,
911+
.get_strings = kszphy_get_strings,
912+
.get_stats = kszphy_get_stats,
820913
.suspend = genphy_suspend,
821914
.resume = genphy_resume,
822915
.driver = { .owner = THIS_MODULE, },
@@ -829,6 +922,9 @@ static struct phy_driver ksphy_driver[] = {
829922
.config_init = kszphy_config_init,
830923
.config_aneg = genphy_config_aneg,
831924
.read_status = genphy_read_status,
925+
.get_sset_count = kszphy_get_sset_count,
926+
.get_strings = kszphy_get_strings,
927+
.get_stats = kszphy_get_stats,
832928
.suspend = genphy_suspend,
833929
.resume = genphy_resume,
834930
.driver = { .owner = THIS_MODULE, },

0 commit comments

Comments
 (0)