Commit 7f7d32bc authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by David S. Miller

net: dsa: mv88e6xxx: improve 88e6352 serdes statistics detection

The decision whether to report serdes statistics currently depends on
the cached C_Mode value for the port, read at probe time or updated by
configuration. However, port 4 can be in "automedia" mode when it is
used as a serdes port, meaning it switches between the internal PHY and
the serdes, changing the read-only C_Mode value depending on which
first gains link. Consequently, the C_Mode value read at probe does not
accurately reflect whether the port has the serdes associated with it.

In "net: dsa: mv88e6xxx: add mv88e6352_g2_scratch_port_has_serdes()",
we added a way to read the hardware configuration to determine which
port has the serdes associated with it. Use this to determine which
port reports the serdes statistics.
Reviewed-by: default avatarMarek Behún <kabel@kernel.org>
Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2ee84cfe
...@@ -272,14 +272,6 @@ int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) ...@@ -272,14 +272,6 @@ int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
return lane; return lane;
} }
static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
{
if (mv88e6xxx_serdes_get_lane(chip, port) >= 0)
return true;
return false;
}
struct mv88e6352_serdes_hw_stat { struct mv88e6352_serdes_hw_stat {
char string[ETH_GSTRING_LEN]; char string[ETH_GSTRING_LEN];
int sizeof_stat; int sizeof_stat;
...@@ -293,20 +285,24 @@ static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = { ...@@ -293,20 +285,24 @@ static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
{ {
if (mv88e6352_port_has_serdes(chip, port)) int err;
return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
return 0; err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
if (err <= 0)
return err;
return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
} }
int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data) int port, uint8_t *data)
{ {
struct mv88e6352_serdes_hw_stat *stat; struct mv88e6352_serdes_hw_stat *stat;
int i; int err, i;
if (!mv88e6352_port_has_serdes(chip, port)) err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
return 0; if (err <= 0)
return err;
for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) { for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
stat = &mv88e6352_serdes_hw_stats[i]; stat = &mv88e6352_serdes_hw_stats[i];
...@@ -348,11 +344,12 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, ...@@ -348,11 +344,12 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
{ {
struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
struct mv88e6352_serdes_hw_stat *stat; struct mv88e6352_serdes_hw_stat *stat;
int i, err;
u64 value; u64 value;
int i;
if (!mv88e6352_port_has_serdes(chip, port)) err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
return 0; if (err <= 0)
return err;
BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
...@@ -419,8 +416,13 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) ...@@ -419,8 +416,13 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port) int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
{ {
if (!mv88e6352_port_has_serdes(chip, port)) int err;
return 0;
mv88e6xxx_reg_lock(chip);
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
mv88e6xxx_reg_unlock(chip);
if (err <= 0)
return err;
return 32 * sizeof(u16); return 32 * sizeof(u16);
} }
...@@ -432,7 +434,8 @@ void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) ...@@ -432,7 +434,8 @@ void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
int err; int err;
int i; int i;
if (!mv88e6352_port_has_serdes(chip, port)) err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
if (err <= 0)
return; return;
for (i = 0 ; i < 32; i++) { for (i = 0 ; i < 32; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment