History

Merge branch 'dsa-Add-ATU-VTU-statistics'

Andrew Lunn says: ==================== Add ATU/VTU statistics Previous patches have added basic support for Address Translation Unit and VLAN translation Unit violation interrupts. Add statistics counters for when these occur, which can be accessed using ethtool. Downgrade one of the particularly spammy warnings from VTU violations to debug only, now that we have a counter for it. ====================

David S. Miller committed 8 years ago

Commit e3e67a42 parents 7ae665f 7f20d836 files · +80 −29Browse files

Unified · Split

6 files
  1. drivers/net/dsa/mv88e6xxx/chip.c +43 −7
  2. drivers/net/dsa/mv88e6xxx/chip.h +9 −4
  3. drivers/net/dsa/mv88e6xxx/global1_atu.c +8 −4
  4. drivers/net/dsa/mv88e6xxx/global1_vtu.c +7 −4
  5. drivers/net/dsa/mv88e6xxx/serdes.c +9 −6
  6. drivers/net/dsa/mv88e6xxx/serdes.h +4 −4
drivers/net/dsa/mv88e6xxx/chip.c+43−7
@@ -723,6 +723,24 @@ static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip, · 722 unmodified lines
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, · 7 unmodified lines
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) · 38 unmodified lines
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 else809 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, · 48 unmodified lines
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, · 2 unmodified lines
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,
drivers/net/dsa/mv88e6xxx/chip.h+9−4
@@ -194,6 +194,11 @@ struct mv88e6xxx_port_hwtstamp { · 193 unmodified lines
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 { · 209 unmodified lines
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,
drivers/net/dsa/mv88e6xxx/global1_atu.c+8−4
@@ -336,8 +336,6 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id) · 335 unmodified lines
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) · 4 unmodified lines
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
drivers/net/dsa/mv88e6xxx/global1_vtu.c+7−4
@@ -539,18 +539,21 @@ static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id) · 538 unmodified lines
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_dbg_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
556 mutex_unlock(&chip->reg_lock);
554 557
555 return IRQ_HANDLED;558 return IRQ_HANDLED;
556 559
drivers/net/dsa/mv88e6xxx/serdes.c+9−6
@@ -106,20 +106,21 @@ int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) · 105 unmodified lines
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, · 23 unmodified lines
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, · 1 unmodified line
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, · 4 unmodified lines
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 */
drivers/net/dsa/mv88e6xxx/serdes.h+4−4
@@ -45,8 +45,8 @@ · 44 unmodified lines
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#endif52#endif