Merge branch 'mv88e6xxx-Add-SERDES-PCS-registers-to-ethtool-dump'
Andrew Lunn says: ==================== mv88e6xxx: Add SERDES/PCS registers to ethtool -d ethtool -d will dump the registers of an interface. For mv88e6xxx switch ports, this dump covers the port specific registers. Extend this with the SERDES/PCS registers, if a port has a SERDES. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
c1b18f20d5
@ -1018,7 +1018,14 @@ static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
|
||||
|
||||
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
|
||||
{
|
||||
return 32 * sizeof(u16);
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
int len;
|
||||
|
||||
len = 32 * sizeof(u16);
|
||||
if (chip->info->ops->serdes_get_regs_len)
|
||||
len += chip->info->ops->serdes_get_regs_len(chip, port);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
|
||||
@ -1043,6 +1050,9 @@ static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
|
||||
p[i] = reg;
|
||||
}
|
||||
|
||||
if (chip->info->ops->serdes_get_regs)
|
||||
chip->info->ops->serdes_get_regs(chip, port, &p[i]);
|
||||
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
}
|
||||
|
||||
@ -3664,6 +3674,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.serdes_get_lane = mv88e6352_serdes_get_lane,
|
||||
.serdes_power = mv88e6352_serdes_power,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
@ -3758,6 +3770,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
|
||||
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
|
||||
.serdes_irq_status = mv88e6352_serdes_irq_status,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
@ -3847,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,
|
||||
@ -3901,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,
|
||||
@ -3954,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,
|
||||
@ -4008,6 +4028,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
|
||||
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
|
||||
.serdes_irq_status = mv88e6352_serdes_irq_status,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
@ -4103,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,
|
||||
@ -4388,6 +4412,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
.serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
|
||||
.serdes_get_strings = mv88e6352_serdes_get_strings,
|
||||
.serdes_get_stats = mv88e6352_serdes_get_stats,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
|
||||
@ -4446,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,
|
||||
};
|
||||
|
||||
@ -4501,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,
|
||||
|
@ -517,6 +517,11 @@ struct mv88e6xxx_ops {
|
||||
int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
|
||||
uint64_t *data);
|
||||
|
||||
/* SERDES registers for ethtool */
|
||||
int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip, int port);
|
||||
void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port,
|
||||
void *_p);
|
||||
|
||||
/* Address Translation Unit operations */
|
||||
int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash);
|
||||
int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
|
||||
|
@ -237,6 +237,29 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
|
||||
return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
|
||||
}
|
||||
|
||||
int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
if (!mv88e6352_port_has_serdes(chip, port))
|
||||
return 0;
|
||||
|
||||
return 32 * sizeof(u16);
|
||||
}
|
||||
|
||||
void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
|
||||
{
|
||||
u16 *p = _p;
|
||||
u16 reg;
|
||||
int i;
|
||||
|
||||
if (!mv88e6352_port_has_serdes(chip, port))
|
||||
return;
|
||||
|
||||
for (i = 0 ; i < 32; i++) {
|
||||
mv88e6352_serdes_read(chip, i, ®);
|
||||
p[i] = reg;
|
||||
}
|
||||
}
|
||||
|
||||
u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
u8 cmode = chip->ports[port].cmode;
|
||||
@ -652,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], ®);
|
||||
p[i] = reg;
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,11 @@ int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
|
||||
int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
|
||||
uint64_t *data);
|
||||
|
||||
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,
|
||||
int port)
|
||||
|
Loading…
Reference in New Issue
Block a user