Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: Keep ATU/VTU violation statistics
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed Mar 29, 2018
1 parent 7ae665f commit 65f60e4
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 28 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
8 changes: 5 additions & 3 deletions drivers/net/dsa/mv88e6xxx/global1_vtu.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,18 +539,20 @@ 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)
if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
dev_err_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 65f60e4

Please sign in to comment.