Skip to content

Commit

Permalink
Merge branch 'dsa-Add-ATU-VTU-statistics'
Browse files Browse the repository at this point in the history
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.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 29, 2018
2 parents 7ae665f + 7f20d83 commit e3e67a4
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 29 deletions.
50 changes: 43 additions & 7 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,24 @@ static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
}

static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
"atu_member_violation",
"atu_miss_violation",
"atu_full_violation",
"vtu_member_violation",
"vtu_miss_violation",
};

static void mv88e6xxx_atu_vtu_get_strings(uint8_t *data)
{
unsigned int i;

for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
strlcpy(data + i * ETH_GSTRING_LEN,
mv88e6xxx_atu_vtu_stats_strings[i],
ETH_GSTRING_LEN);
}

static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
uint8_t *data)
{
Expand All @@ -736,9 +754,12 @@ static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,

if (chip->info->ops->serdes_get_strings) {
data += count * ETH_GSTRING_LEN;
chip->info->ops->serdes_get_strings(chip, port, data);
count = chip->info->ops->serdes_get_strings(chip, port, data);
}

data += count * ETH_GSTRING_LEN;
mv88e6xxx_atu_vtu_get_strings(data);

mutex_unlock(&chip->reg_lock);
}

Expand Down Expand Up @@ -783,10 +804,13 @@ static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port)
if (chip->info->ops->serdes_get_sset_count)
serdes_count = chip->info->ops->serdes_get_sset_count(chip,
port);
if (serdes_count < 0)
if (serdes_count < 0) {
count = serdes_count;
else
count += serdes_count;
goto out;
}
count += serdes_count;
count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);

out:
mutex_unlock(&chip->reg_lock);

Expand Down Expand Up @@ -841,6 +865,16 @@ static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
0);
}

static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
{
*data++ = chip->ports[port].atu_member_violation;
*data++ = chip->ports[port].atu_miss_violation;
*data++ = chip->ports[port].atu_full_violation;
*data++ = chip->ports[port].vtu_member_violation;
*data++ = chip->ports[port].vtu_miss_violation;
}

static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
{
Expand All @@ -849,12 +883,14 @@ static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
if (chip->info->ops->stats_get_stats)
count = chip->info->ops->stats_get_stats(chip, port, data);

mutex_lock(&chip->reg_lock);
if (chip->info->ops->serdes_get_stats) {
data += count;
mutex_lock(&chip->reg_lock);
chip->info->ops->serdes_get_stats(chip, port, data);
mutex_unlock(&chip->reg_lock);
count = chip->info->ops->serdes_get_stats(chip, port, data);
}
data += count;
mv88e6xxx_atu_vtu_get_stats(chip, port, data);
mutex_unlock(&chip->reg_lock);
}

static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
Expand Down
13 changes: 9 additions & 4 deletions drivers/net/dsa/mv88e6xxx/chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ struct mv88e6xxx_port_hwtstamp {

struct mv88e6xxx_port {
u64 serdes_stats[2];
u64 atu_member_violation;
u64 atu_miss_violation;
u64 atu_full_violation;
u64 vtu_member_violation;
u64 vtu_miss_violation;
};

struct mv88e6xxx_chip {
Expand Down Expand Up @@ -409,10 +414,10 @@ struct mv88e6xxx_ops {

/* Statistics from the SERDES interface */
int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
void (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port,
uint8_t *data);
void (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port,
uint8_t *data);
int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);

/* VLAN Translation Unit operations */
int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
Expand Down
12 changes: 8 additions & 4 deletions drivers/net/dsa/mv88e6xxx/global1_atu.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,6 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
if (err)
goto out;

mutex_unlock(&chip->reg_lock);

if (val & MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION) {
dev_err_ratelimited(chip->dev,
"ATU age out violation for %pM\n",
Expand All @@ -348,17 +346,23 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
dev_err_ratelimited(chip->dev,
"ATU member violation for %pM portvec %x\n",
entry.mac, entry.portvec);
chip->ports[entry.portvec].atu_member_violation++;
}

if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION)
if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
dev_err_ratelimited(chip->dev,
"ATU miss violation for %pM portvec %x\n",
entry.mac, entry.portvec);
chip->ports[entry.portvec].atu_miss_violation++;
}

if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION)
if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
dev_err_ratelimited(chip->dev,
"ATU full violation for %pM portvec %x\n",
entry.mac, entry.portvec);
chip->ports[entry.portvec].atu_full_violation++;
}
mutex_unlock(&chip->reg_lock);

return IRQ_HANDLED;

Expand Down
11 changes: 7 additions & 4 deletions drivers/net/dsa/mv88e6xxx/global1_vtu.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,18 +539,21 @@ static irqreturn_t mv88e6xxx_g1_vtu_prob_irq_thread_fn(int irq, void *dev_id)
if (err)
goto out;

mutex_unlock(&chip->reg_lock);

spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;

if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
entry.vid, spid);
chip->ports[spid].vtu_member_violation++;
}

if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION)
dev_err_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
entry.vid, spid);
chip->ports[spid].vtu_miss_violation++;
}

mutex_unlock(&chip->reg_lock);

return IRQ_HANDLED;

Expand Down
15 changes: 9 additions & 6 deletions drivers/net/dsa/mv88e6xxx/serdes.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,21 @@ int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
return 0;
}

void mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data)
int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data)
{
struct mv88e6352_serdes_hw_stat *stat;
int i;

if (!mv88e6352_port_has_serdes(chip, port))
return;
return 0;

for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
stat = &mv88e6352_serdes_hw_stats[i];
memcpy(data + i * ETH_GSTRING_LEN, stat->string,
ETH_GSTRING_LEN);
}
return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
}

static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
Expand Down Expand Up @@ -149,16 +150,16 @@ static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
return val;
}

void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
{
struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
struct mv88e6352_serdes_hw_stat *stat;
u64 value;
int i;

if (!mv88e6352_port_has_serdes(chip, port))
return;
return 0;

BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
Expand All @@ -169,6 +170,8 @@ void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
mv88e6xxx_port->serdes_stats[i] += value;
data[i] = mv88e6xxx_port->serdes_stats[i];
}

return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
}

/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/dsa/mv88e6xxx/serdes.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
void mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data);
void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data);
int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
#endif

0 comments on commit e3e67a4

Please sign in to comment.