From 7019bba4330750a29d87b6ce70ac6fabc007b3dc Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Apr 2020 09:21:39 +0100 Subject: [PATCH] net: dsa: mv88e6xxx: 88e6390 10G serdes support Add support for reading and reporting the 10G link status on the 88e6390 in addition to the 1000BASE-X/2500BASE-X/SGMII status. Signed-off-by: Russell King Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/serdes.c | 43 ++++++++++++++++++++++++++++-- drivers/net/dsa/mv88e6xxx/serdes.h | 1 + 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 33d9923cf7c5..9c07b4f3d345 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -748,8 +748,8 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, MV88E6390_SGMII_BMCR, bmcr); } -int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, - u8 lane, struct phylink_link_state *state) +static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, + int port, u8 lane, struct phylink_link_state *state) { u16 lpa, status; int err; @@ -771,6 +771,45 @@ int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state); } +static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, + int port, u8 lane, struct phylink_link_state *state) +{ + u16 status; + int err; + + err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, + MV88E6390_10G_STAT1, &status); + if (err) + return err; + + state->link = !!(status & MDIO_STAT1_LSTATUS); + if (state->link) { + state->speed = SPEED_10000; + state->duplex = DUPLEX_FULL; + } + + return 0; +} + +int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, + u8 lane, struct phylink_link_state *state) +{ + switch (state->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane, + state); + case PHY_INTERFACE_MODE_XAUI: + case PHY_INTERFACE_MODE_RXAUI: + return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane, + state); + + default: + return -EOPNOTSUPP; + } +} + int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, u8 lane) { diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index 71e3c3d0a24e..14315f26228a 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -41,6 +41,7 @@ /* 10GBASE-R and 10GBASE-X4/X2 */ #define MV88E6390_10G_CTRL1 (0x1000 + MDIO_CTRL1) +#define MV88E6390_10G_STAT1 (0x1000 + MDIO_STAT1) /* 1000BASE-X and SGMII */ #define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR) -- 2.34.1