diff options
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/port.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/port.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index c7630dab18a8..542201214c36 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -392,17 +392,14 @@ phy_interface_t mv88e6390x_port_max_speed_mode(int port) return PHY_INTERFACE_MODE_NA; } -int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, - phy_interface_t mode) +static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) { u8 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. */ @@ -484,9 +481,65 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, return 0; } +int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) +{ + if (port != 9 && port != 10) + return -EOPNOTSUPP; + + return mv88e6xxx_port_set_cmode(chip, port, mode); +} + int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode) { + if (port != 9 && port != 10) + return -EOPNOTSUPP; + + 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 mv88e6xxx_port_set_cmode(chip, port, mode); +} + +int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, int port) +{ + int err, addr; + u16 reg, bits; + + if (port != 5) + return -EOPNOTSUPP; + + addr = chip->info->port_base_addr + port; + + err = mv88e6xxx_port_hidden_read(chip, 0x7, addr, 0, ®); + if (err) + return err; + + bits = MV88E6341_PORT_RESERVED_1A_FORCE_CMODE | + MV88E6341_PORT_RESERVED_1A_SGMII_AN; + + if ((reg & bits) == bits) + return 0; + + reg |= bits; + return mv88e6xxx_port_hidden_write(chip, 0x7, addr, 0, reg); +} + +int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) +{ + if (port != 5) + return -EOPNOTSUPP; + switch (mode) { case PHY_INTERFACE_MODE_NA: return 0; @@ -498,7 +551,7 @@ int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, break; } - return mv88e6390x_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode); } int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) |