Commit bf3504ce authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: Add 6390 family PCS registers to ethtool -d



The mv88e6390 has upto 8 sets of PCS registers, depending on how ports
9 and 10 are configured. The can be spread over 8 ports. If a port has
a PCS register set, return it along with the port registers. The
register space is sparse, so hard code a list of registers which will
be returned. It can later be extended, if needed, by append to the end
of the list.

Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d3f88a24
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -3861,6 +3861,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
	.serdes_irq_status = mv88e6390_serdes_irq_status,
	.serdes_get_strings = mv88e6390_serdes_get_strings,
	.serdes_get_stats = mv88e6390_serdes_get_stats,
	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
	.serdes_get_regs = mv88e6390_serdes_get_regs,
	.phylink_validate = mv88e6390_phylink_validate,
	.gpio_ops = &mv88e6352_gpio_ops,
	.phylink_validate = mv88e6390_phylink_validate,
@@ -3915,6 +3917,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
	.serdes_irq_status = mv88e6390_serdes_irq_status,
	.serdes_get_strings = mv88e6390_serdes_get_strings,
	.serdes_get_stats = mv88e6390_serdes_get_stats,
	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
	.serdes_get_regs = mv88e6390_serdes_get_regs,
	.phylink_validate = mv88e6390_phylink_validate,
	.gpio_ops = &mv88e6352_gpio_ops,
	.phylink_validate = mv88e6390x_phylink_validate,
@@ -3968,6 +3972,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
	.serdes_irq_status = mv88e6390_serdes_irq_status,
	.serdes_get_strings = mv88e6390_serdes_get_strings,
	.serdes_get_stats = mv88e6390_serdes_get_stats,
	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
	.serdes_get_regs = mv88e6390_serdes_get_regs,
	.phylink_validate = mv88e6390_phylink_validate,
	.avb_ops = &mv88e6390_avb_ops,
	.ptp_ops = &mv88e6352_ptp_ops,
@@ -4119,6 +4125,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
	.serdes_irq_status = mv88e6390_serdes_irq_status,
	.serdes_get_strings = mv88e6390_serdes_get_strings,
	.serdes_get_stats = mv88e6390_serdes_get_stats,
	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
	.serdes_get_regs = mv88e6390_serdes_get_regs,
	.phylink_validate = mv88e6390_phylink_validate,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6390_avb_ops,
@@ -4464,6 +4472,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
	.serdes_get_strings = mv88e6390_serdes_get_strings,
	.serdes_get_stats = mv88e6390_serdes_get_stats,
	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
	.serdes_get_regs = mv88e6390_serdes_get_regs,
	.phylink_validate = mv88e6390_phylink_validate,
};

@@ -4519,6 +4529,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
	.serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
	.serdes_get_strings = mv88e6390_serdes_get_strings,
	.serdes_get_stats = mv88e6390_serdes_get_stats,
	.serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
	.serdes_get_regs = mv88e6390_serdes_get_regs,
	.gpio_ops = &mv88e6352_gpio_ops,
	.avb_ops = &mv88e6390_avb_ops,
	.ptp_ops = &mv88e6352_ptp_ops,
+54 −0
Original line number Diff line number Diff line
@@ -675,3 +675,57 @@ unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
{
	return irq_find_mapping(chip->g2_irq.domain, port);
}

static const u16 mv88e6390_serdes_regs[] = {
	/* SERDES common registers */
	0xf00a, 0xf00b, 0xf00c,
	0xf010, 0xf011, 0xf012, 0xf013,
	0xf016, 0xf017, 0xf018,
	0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
	0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
	0xf028, 0xf029,
	0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
	0xf038, 0xf039,
	/* SGMII */
	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
	0x2008,
	0x200f,
	0xa000, 0xa001, 0xa002, 0xa003,
	/* 10Gbase-X */
	0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
	0x1008,
	0x100e, 0x100f,
	0x1018, 0x1019,
	0x9000, 0x9001, 0x9002, 0x9003, 0x9004,
	0x9006,
	0x9010, 0x9011, 0x9012, 0x9013, 0x9014, 0x9015, 0x9016,
	/* 10Gbase-R */
	0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
	0x1028, 0x1029, 0x102a, 0x102b,
};

int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
{
	if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
		return 0;

	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
}

void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
{
	u16 *p = _p;
	int lane;
	u16 reg;
	int i;

	lane = mv88e6xxx_serdes_get_lane(chip, port);
	if (lane == 0)
		return;

	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
		mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
				      mv88e6390_serdes_regs[i], &reg);
		p[i] = reg;
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,

int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);

/* Return the (first) SERDES lane address a port is using, 0 otherwise. */
static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,