On Thu, Mar 19, 2020 at 04:06:52PM +0100, Andrew Lunn wrote: > > Oh, I forgot to mention on the library point - that's what has already > > been created in: > > > > "net: phylink: pcs: add 802.3 clause 45 helpers" > > "net: phylink: pcs: add 802.3 clause 22 helpers" > > > > which add library implementations for the pcs_get_state(), pcs_config() > > and pcs_an_restart() methods. > > > > What remains is vendor specific - for pcs_link_up(), there is no > > standard, since it requires fiddling with vendor specific registers to > > program, e.g. the speed in SGMII mode when in-band is not being used. > > The selection between different PCS is also vendor specific. > > > > It would have been nice to use these helpers for Marvell DSA switches > > too, but the complexities of DSA taking a multi-layered approach rather > > than a library approach, plus the use of paging makes it very > > difficult. > > > > So, basically on the library point, "already considered and > > implemented". > > Hi Russell > > The 6390X family of switches has two PCSs, one for 1000BaseX/SGMII and > a second one for 10GBaseR. So at some point there is going to be a > mux, but maybe it will be internal to mv88e6xxx and not shareable. Or > internal to DSA, and shareable between DSA drivers. We will see. This is what I came up with, but I'm not really able to test it with my ZII platforms. See the attached patch and the patch below. I haven't polished them yet - been a little otherwise occupied as I'm sure you can imagine given the situation. diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 8cef46ee1d2f..59bd3f447386 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -631,8 +631,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; @@ -654,6 +654,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 12013f22df10..3af236f4b3c8 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) -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 10.2Mbps down 587kbps up