net: dsa: mv88e6xxx: Add 6390 family PCS registers to ethtool -d
authorAndrew Lunn <andrew@lunn.ch>
Sun, 16 Feb 2020 17:54:15 +0000 (18:54 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 17 Feb 2020 04:00:21 +0000 (20:00 -0800)
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: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/serdes.c
drivers/net/dsa/mv88e6xxx/serdes.h

index cb284eb505c0f76e7466abaef52b17837cd87a29..4ec09cc8dcdcee546f891720faa3f42742d5929d 100644 (file)
@@ -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,
index 94704af224c8f21ce0afaae85a112c30e26d421e..238219787233e687703d8073935a2eccbaa1f412 100644 (file)
@@ -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;
+       }
+}
index bb06108ca0bca01403385fbfd69bc6b979830c87..1906b3ab29c680598802b1c03f226782a4966619 100644 (file)
@@ -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,