diff options
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 16 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.c | 55 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.h | 7 |
3 files changed, 61 insertions, 17 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 2b4a723c8306..7627ea61e0ea 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2233,26 +2233,34 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, mv88e6xxx_reg_unlock(chip); } -static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, int dev, +static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, + int tree_index, int sw_index, int port, struct net_device *br) { struct mv88e6xxx_chip *chip = ds->priv; int err; + if (tree_index != ds->dst->index) + return 0; + mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_pvt_map(chip, dev, port); + err = mv88e6xxx_pvt_map(chip, sw_index, port); mv88e6xxx_reg_unlock(chip); return err; } -static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds, int dev, +static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds, + int tree_index, int sw_index, int port, struct net_device *br) { struct mv88e6xxx_chip *chip = ds->priv; + if (tree_index != ds->dst->index) + return; + mv88e6xxx_reg_lock(chip); - if (mv88e6xxx_pvt_map(chip, dev, port)) + if (mv88e6xxx_pvt_map(chip, sw_index, port)) dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n"); mv88e6xxx_reg_unlock(chip); } diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 2098f19b534d..9c07b4f3d345 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -534,21 +534,21 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, int err; err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, - MV88E6390_PCS_CONTROL_1, &val); + MV88E6390_10G_CTRL1, &val); if (err) return err; if (up) - new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET | - MV88E6390_PCS_CONTROL_1_LOOPBACK | - MV88E6390_PCS_CONTROL_1_PDOWN); + new_val = val & ~(MDIO_CTRL1_RESET | + MDIO_PCS_CTRL1_LOOPBACK | + MDIO_CTRL1_LPOWER); else - new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN; + new_val = val | MDIO_CTRL1_LPOWER; if (val != new_val) err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, - MV88E6390_PCS_CONTROL_1, new_val); + MV88E6390_10G_CTRL1, new_val); return err; } @@ -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 7990cadba4c2..14315f26228a 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -40,11 +40,8 @@ #define MV88E6390_PORT10_LANE3 0x17 /* 10GBASE-R and 10GBASE-X4/X2 */ -#define MV88E6390_PCS_CONTROL_1 0x1000 -#define MV88E6390_PCS_CONTROL_1_RESET BIT(15) -#define MV88E6390_PCS_CONTROL_1_LOOPBACK BIT(14) -#define MV88E6390_PCS_CONTROL_1_SPEED BIT(13) -#define MV88E6390_PCS_CONTROL_1_PDOWN BIT(11) +#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) |