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

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
Loading
Loading
Loading
Loading
+23 −20
Original line number Diff line number Diff line
@@ -272,14 +272,6 @@ int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
	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 {
	char string[ETH_GSTRING_LEN];
	int sizeof_stat;
@@ -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)
{
	if (mv88e6352_port_has_serdes(chip, port))
		return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
	int err;

	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 port, uint8_t *data)
{
	struct mv88e6352_serdes_hw_stat *stat;
	int i;
	int err, i;

	if (!mv88e6352_port_has_serdes(chip, port))
		return 0;
	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
	if (err <= 0)
		return err;

	for (i = 0; i < ARRAY_SIZE(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,
{
	struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
	struct mv88e6352_serdes_hw_stat *stat;
	int i, err;
	u64 value;
	int i;

	if (!mv88e6352_port_has_serdes(chip, port))
		return 0;
	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
	if (err <= 0)
		return err;

	BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
		     ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
@@ -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)
{
	if (!mv88e6352_port_has_serdes(chip, port))
		return 0;
	int err;

	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);
}
@@ -432,7 +434,8 @@ void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
	int err;
	int i;

	if (!mv88e6352_port_has_serdes(chip, port))
	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
	if (err <= 0)
		return;

	for (i = 0 ; i < 32; i++) {