aboutsummaryrefslogtreecommitdiff
path: root/lib/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/parser.c')
0 files changed, 0 insertions, 0 deletions
t_bit, bool force_bit) { u16 reg, ctrl; int err; switch (speed) { case 10: ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10; break; case 100: ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100; break; case 200: if (alt_bit) ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 | MV88E6390_PORT_MAC_CTL_ALTSPEED; else ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200; break; case 1000: ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000; break; case 2500: if (alt_bit) ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 | MV88E6390_PORT_MAC_CTL_ALTSPEED; else ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000; break; case 10000: /* all bits set, fall through... */ case SPEED_UNFORCED: ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED; break; default: return -EOPNOTSUPP; } err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); if (err) return err; reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK; if (alt_bit) reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED; if (force_bit) { reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED; if (speed != SPEED_UNFORCED) ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED; } reg |= ctrl; err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg); if (err) return err; if (speed) dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed); else dev_dbg(chip->dev, "p%d: Speed unforced\n", port); return 0; } /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */ int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = 200; if (speed > 200) return -EOPNOTSUPP; /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */ return mv88e6xxx_port_set_speed(chip, port, speed, false, false); } /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */ int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = 1000; if (speed == 200 || speed > 1000) return -EOPNOTSUPP; return mv88e6xxx_port_set_speed(chip, port, speed, false, false); } /* Support 10, 100 Mbps (e.g. 88E6250 family) */ int mv88e6250_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = 100; if (speed > 100) return -EOPNOTSUPP; return mv88e6xxx_port_set_speed(chip, port, speed, false, false); } /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */ int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = port < 5 ? 1000 : 2500; if (speed > 2500) return -EOPNOTSUPP; if (speed == 200 && port != 0) return -EOPNOTSUPP; if (speed == 2500 && port < 5) return -EOPNOTSUPP; return mv88e6xxx_port_set_speed(chip, port, speed, !port, true); } phy_interface_t mv88e6341_port_max_speed_mode(int port) { if (port == 5) return PHY_INTERFACE_MODE_2500BASEX; return PHY_INTERFACE_MODE_NA; } /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */ int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = 1000; if (speed > 1000) return -EOPNOTSUPP; if (speed == 200 && port < 5) return -EOPNOTSUPP; return mv88e6xxx_port_set_speed(chip, port, speed, true, false); } /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */ int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = port < 9 ? 1000 : 2500; if (speed > 2500) return -EOPNOTSUPP; if (speed == 200 && port != 0) return -EOPNOTSUPP; if (speed == 2500 && port < 9) return -EOPNOTSUPP; return mv88e6xxx_port_set_speed(chip, port, speed, true, true); } phy_interface_t mv88e6390_port_max_speed_mode(int port) { if (port == 9 || port == 10) return PHY_INTERFACE_MODE_2500BASEX; return PHY_INTERFACE_MODE_NA; } /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */ int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { if (speed == SPEED_MAX) speed = port < 9 ? 1000 : 10000; if (speed == 200 && port != 0) return -EOPNOTSUPP; if (speed >= 2500 && port < 9) return -EOPNOTSUPP; return mv88e6xxx_port_set_speed(chip, port, speed, true, true); } phy_interface_t mv88e6390x_port_max_speed_mode(int port) { if (port == 9 || port == 10) return PHY_INTERFACE_MODE_XAUI; return PHY_INTERFACE_MODE_NA; } int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode) { int lane; u16 cmode; u16 reg; int err; if (port != 9 && port != 10) return -EOPNOTSUPP; /* Default to a slow mode, so freeing up SERDES interfaces for * other ports which might use them for SFPs. */ if (mode == PHY_INTERFACE_MODE_NA) mode = PHY_INTERFACE_MODE_1000BASEX; switch (mode) { case PHY_INTERFACE_MODE_1000BASEX: cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X; break; case PHY_INTERFACE_MODE_SGMII: cmode = MV88E6XXX_PORT_STS_CMODE_SGMII; break; case PHY_INTERFACE_MODE_2500BASEX: cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX; break; case PHY_INTERFACE_MODE_XGMII: case PHY_INTERFACE_MODE_XAUI: cmode = MV88E6XXX_PORT_STS_CMODE_XAUI; break; case PHY_INTERFACE_MODE_RXAUI: cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI; break; default: cmode = 0; } /* cmode doesn't change, nothing to do for us */ if (cmode == chip->ports[port].cmode) return 0; lane = mv88e6390x_serdes_get_lane(chip, port); if (lane < 0 && lane != -ENODEV) return lane; if (lane >= 0) { if (chip->ports[port].serdes_irq) { err = mv88e6390_serdes_irq_disable(chip, port, lane); if (err) return err; } err = mv88e6390x_serdes_power(chip, port, false); if (err) return err; } chip->ports[port].cmode = 0; if (cmode) { err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); if (err) return err; reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK; reg |= cmode; err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); if (err) return err; chip->ports[port].cmode = cmode; lane = mv88e6390x_serdes_get_lane(chip, port); if (lane < 0) return lane; err = mv88e6390x_serdes_power(chip, port, true); if (err) return err; if (chip->ports[port].serdes_irq) { err = mv88e6390_serdes_irq_enable(chip, port, lane); if (err) return err; } } return 0; } int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode) { switch (mode) { case PHY_INTERFACE_MODE_NA: return 0; case PHY_INTERFACE_MODE_XGMII: case PHY_INTERFACE_MODE_XAUI: case PHY_INTERFACE_MODE_RXAUI: return -EINVAL; default: break; } return mv88e6390x_port_set_cmode(chip, port, mode); } int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, in