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. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e3e67a4f07
@ -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)
|
||||
{
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
@ -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,
|
||||
|
@ -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 {
|
||||
@ -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,
|
||||
|
@ -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",
|
||||
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
@ -149,8 +150,8 @@ 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;
|
||||
@ -158,7 +159,7 @@ void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
|
||||
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));
|
||||
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user