aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2018-03-28 17:50:28 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-29 15:04:22 -0400
commit65f60e4582bd321f4df1433a22f717f18e60f721 (patch)
tree9f2577306ba82031773faea60ffc8381c1ebc47a
parent7ae665f132a62e67ccef1ef0994acba51abc2400 (diff)
net: dsa: mv88e6xxx: Keep ATU/VTU violation statistics
Count the numbers of various ATU and VTU violation statistics and return them as part of the ethtool -S statistics. 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>
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c50
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.h13
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1_atu.c12
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1_vtu.c8
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.c15
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.h8
6 files changed, 78 insertions, 28 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 9a5d786b4885..3d2091099f7f 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -723,6 +723,24 @@ static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
723 STATS_TYPE_BANK0 | STATS_TYPE_BANK1); 723 STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
724} 724}
725 725
726static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
727 "atu_member_violation",
728 "atu_miss_violation",
729 "atu_full_violation",
730 "vtu_member_violation",
731 "vtu_miss_violation",
732};
733
734static void mv88e6xxx_atu_vtu_get_strings(uint8_t *data)
735{
736 unsigned int i;
737
738 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
739 strlcpy(data + i * ETH_GSTRING_LEN,
740 mv88e6xxx_atu_vtu_stats_strings[i],
741 ETH_GSTRING_LEN);
742}
743
726static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, 744static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
727 uint8_t *data) 745 uint8_t *data)
728{ 746{
@@ -736,9 +754,12 @@ static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
736 754
737 if (chip->info->ops->serdes_get_strings) { 755 if (chip->info->ops->serdes_get_strings) {
738 data += count * ETH_GSTRING_LEN; 756 data += count * ETH_GSTRING_LEN;
739 chip->info->ops->serdes_get_strings(chip, port, data); 757 count = chip->info->ops->serdes_get_strings(chip, port, data);
740 } 758 }
741 759
760 data += count * ETH_GSTRING_LEN;
761 mv88e6xxx_atu_vtu_get_strings(data);
762
742 mutex_unlock(&chip->reg_lock); 763 mutex_unlock(&chip->reg_lock);
743} 764}
744 765
@@ -783,10 +804,13 @@ static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port)
783 if (chip->info->ops->serdes_get_sset_count) 804 if (chip->info->ops->serdes_get_sset_count)
784 serdes_count = chip->info->ops->serdes_get_sset_count(chip, 805 serdes_count = chip->info->ops->serdes_get_sset_count(chip,
785 port); 806 port);
786 if (serdes_count < 0) 807 if (serdes_count < 0) {
787 count = serdes_count; 808 count = serdes_count;
788 else 809 goto out;
789 count += serdes_count; 810 }
811 count += serdes_count;
812 count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
813
790out: 814out:
791 mutex_unlock(&chip->reg_lock); 815 mutex_unlock(&chip->reg_lock);
792 816
@@ -841,6 +865,16 @@ static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
841 0); 865 0);
842} 866}
843 867
868static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
869 uint64_t *data)
870{
871 *data++ = chip->ports[port].atu_member_violation;
872 *data++ = chip->ports[port].atu_miss_violation;
873 *data++ = chip->ports[port].atu_full_violation;
874 *data++ = chip->ports[port].vtu_member_violation;
875 *data++ = chip->ports[port].vtu_miss_violation;
876}
877
844static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port, 878static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
845 uint64_t *data) 879 uint64_t *data)
846{ 880{
@@ -849,12 +883,14 @@ static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
849 if (chip->info->ops->stats_get_stats) 883 if (chip->info->ops->stats_get_stats)
850 count = chip->info->ops->stats_get_stats(chip, port, data); 884 count = chip->info->ops->stats_get_stats(chip, port, data);
851 885
886 mutex_lock(&chip->reg_lock);
852 if (chip->info->ops->serdes_get_stats) { 887 if (chip->info->ops->serdes_get_stats) {
853 data += count; 888 data += count;
854 mutex_lock(&chip->reg_lock); 889 count = chip->info->ops->serdes_get_stats(chip, port, data);
855 chip->info->ops->serdes_get_stats(chip, port, data);
856 mutex_unlock(&chip->reg_lock);
857 } 890 }
891 data += count;
892 mv88e6xxx_atu_vtu_get_stats(chip, port, data);
893 mutex_unlock(&chip->reg_lock);
858} 894}
859 895
860static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, 896static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index bad211014e91..80490f66bc06 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -194,6 +194,11 @@ struct mv88e6xxx_port_hwtstamp {
194 194
195struct mv88e6xxx_port { 195struct mv88e6xxx_port {
196 u64 serdes_stats[2]; 196 u64 serdes_stats[2];
197 u64 atu_member_violation;
198 u64 atu_miss_violation;
199 u64 atu_full_violation;
200 u64 vtu_member_violation;
201 u64 vtu_miss_violation;
197}; 202};
198 203
199struct mv88e6xxx_chip { 204struct mv88e6xxx_chip {
@@ -409,10 +414,10 @@ struct mv88e6xxx_ops {
409 414
410 /* Statistics from the SERDES interface */ 415 /* Statistics from the SERDES interface */
411 int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); 416 int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
412 void (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, 417 int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port,
413 uint8_t *data); 418 uint8_t *data);
414 void (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, 419 int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
415 uint64_t *data); 420 uint64_t *data);
416 421
417 /* VLAN Translation Unit operations */ 422 /* VLAN Translation Unit operations */
418 int (*vtu_getnext)(struct mv88e6xxx_chip *chip, 423 int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
index 20d941f4273b..307410898fc9 100644
--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
+++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
@@ -336,8 +336,6 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
336 if (err) 336 if (err)
337 goto out; 337 goto out;
338 338
339 mutex_unlock(&chip->reg_lock);
340
341 if (val & MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION) { 339 if (val & MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION) {
342 dev_err_ratelimited(chip->dev, 340 dev_err_ratelimited(chip->dev,
343 "ATU age out violation for %pM\n", 341 "ATU age out violation for %pM\n",
@@ -348,17 +346,23 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
348 dev_err_ratelimited(chip->dev, 346 dev_err_ratelimited(chip->dev,
349 "ATU member violation for %pM portvec %x\n", 347 "ATU member violation for %pM portvec %x\n",
350 entry.mac, entry.portvec); 348 entry.mac, entry.portvec);
349 chip->ports[entry.portvec].atu_member_violation++;
351 } 350 }
352 351
353 if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) 352 if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
354 dev_err_ratelimited(chip->dev, 353 dev_err_ratelimited(chip->dev,
355 "ATU miss violation for %pM portvec %x\n", 354 "ATU miss violation for %pM portvec %x\n",
356 entry.mac, entry.portvec); 355 entry.mac, entry.portvec);
356 chip->ports[entry.portvec].atu_miss_violation++;
357 }
357 358
358 if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) 359 if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
359 dev_err_ratelimited(chip->dev, 360 dev_err_ratelimited(chip->dev,
360 "ATU full violation for %pM portvec %x\n", 361 "ATU full violation for %pM portvec %x\n",
361 entry.mac, entry.portvec); 362 entry.mac, entry.portvec);
363 chip->ports[entry.portvec].atu_full_violation++;
364 }
365 mutex_unlock(&chip->reg_lock);
362 366
363 return IRQ_HANDLED; 367 return IRQ_HANDLED;
364 368
diff --git a/drivers/net/dsa/mv88e6xxx/global1_vtu.c b/drivers/net/dsa/mv88e6xxx/global1_vtu.c
index 7997961647de..2cbaf946e7ed 100644
--- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c
+++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c
@@ -539,18 +539,20 @@ static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
539 if (err) 539 if (err)
540 goto out; 540 goto out;
541 541
542 mutex_unlock(&chip->reg_lock);
543
544 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK; 542 spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
545 543
546 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) { 544 if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
547 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n", 545 dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
548 entry.vid, spid); 546 entry.vid, spid);
547 chip->ports[spid].vtu_member_violation++;
549 } 548 }
550 549
551 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) 550 if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
552 dev_err_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n", 551 dev_err_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
553 entry.vid, spid); 552 entry.vid, spid);
553 chip->ports[spid].vtu_miss_violation++;
554 }
555 mutex_unlock(&chip->reg_lock);
554 556
555 return IRQ_HANDLED; 557 return IRQ_HANDLED;
556 558
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index b6166424216a..fb058fd35c0d 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -106,20 +106,21 @@ int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
106 return 0; 106 return 0;
107} 107}
108 108
109void mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 109int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
110 int port, uint8_t *data) 110 int port, uint8_t *data)
111{ 111{
112 struct mv88e6352_serdes_hw_stat *stat; 112 struct mv88e6352_serdes_hw_stat *stat;
113 int i; 113 int i;
114 114
115 if (!mv88e6352_port_has_serdes(chip, port)) 115 if (!mv88e6352_port_has_serdes(chip, port))
116 return; 116 return 0;
117 117
118 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { 118 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
119 stat = &mv88e6352_serdes_hw_stats[i]; 119 stat = &mv88e6352_serdes_hw_stats[i];
120 memcpy(data + i * ETH_GSTRING_LEN, stat->string, 120 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
121 ETH_GSTRING_LEN); 121 ETH_GSTRING_LEN);
122 } 122 }
123 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
123} 124}
124 125
125static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip, 126static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
@@ -149,8 +150,8 @@ static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
149 return val; 150 return val;
150} 151}
151 152
152void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 153int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
153 uint64_t *data) 154 uint64_t *data)
154{ 155{
155 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; 156 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
156 struct mv88e6352_serdes_hw_stat *stat; 157 struct mv88e6352_serdes_hw_stat *stat;
@@ -158,7 +159,7 @@ void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
158 int i; 159 int i;
159 160
160 if (!mv88e6352_port_has_serdes(chip, port)) 161 if (!mv88e6352_port_has_serdes(chip, port))
161 return; 162 return 0;
162 163
163 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > 164 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
164 ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); 165 ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
@@ -169,6 +170,8 @@ void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
169 mv88e6xxx_port->serdes_stats[i] += value; 170 mv88e6xxx_port->serdes_stats[i] += value;
170 data[i] = mv88e6xxx_port->serdes_stats[i]; 171 data[i] = mv88e6xxx_port->serdes_stats[i];
171 } 172 }
173
174 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
172} 175}
173 176
174/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ 177/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 641baa75f910..1897c01c6e19 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -45,8 +45,8 @@
45int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); 45int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
46int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); 46int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
47int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); 47int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
48void mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 48int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
49 int port, uint8_t *data); 49 int port, uint8_t *data);
50void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 50int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
51 uint64_t *data); 51 uint64_t *data);
52#endif 52#endif