diff options
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/port.c | 65 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/port.h | 12 |
2 files changed, 77 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index a41bca17cba1..a9a308051d7c 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -533,6 +533,71 @@ int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) return 0; } +int mv88e6250_port_link_state(struct mv88e6xxx_chip *chip, int port, + struct phylink_link_state *state) +{ + int err; + u16 reg; + + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); + if (err) + return err; + + if (port < 5) { + switch (reg & MV88E6250_PORT_STS_PORTMODE_MASK) { + case MV88E6250_PORT_STS_PORTMODE_PHY_10_HALF: + state->speed = SPEED_10; + state->duplex = DUPLEX_HALF; + break; + case MV88E6250_PORT_STS_PORTMODE_PHY_100_HALF: + state->speed = SPEED_100; + state->duplex = DUPLEX_HALF; + break; + case MV88E6250_PORT_STS_PORTMODE_PHY_10_FULL: + state->speed = SPEED_10; + state->duplex = DUPLEX_FULL; + break; + case MV88E6250_PORT_STS_PORTMODE_PHY_100_FULL: + state->speed = SPEED_100; + state->duplex = DUPLEX_FULL; + break; + default: + state->speed = SPEED_UNKNOWN; + state->duplex = DUPLEX_UNKNOWN; + break; + } + } else { + switch (reg & MV88E6250_PORT_STS_PORTMODE_MASK) { + case MV88E6250_PORT_STS_PORTMODE_MII_10_HALF: + state->speed = SPEED_10; + state->duplex = DUPLEX_HALF; + break; + case MV88E6250_PORT_STS_PORTMODE_MII_100_HALF: + state->speed = SPEED_100; + state->duplex = DUPLEX_HALF; + break; + case MV88E6250_PORT_STS_PORTMODE_MII_10_FULL: + state->speed = SPEED_10; + state->duplex = DUPLEX_FULL; + break; + case MV88E6250_PORT_STS_PORTMODE_MII_100_FULL: + state->speed = SPEED_100; + state->duplex = DUPLEX_FULL; + break; + default: + state->speed = SPEED_UNKNOWN; + state->duplex = DUPLEX_UNKNOWN; + break; + } + } + + state->link = !!(reg & MV88E6250_PORT_STS_LINK); + state->an_enabled = 1; + state->an_complete = state->link; + + return 0; +} + int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, struct phylink_link_state *state) { diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index 1957e3e1cf47..3a89c2868cec 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h @@ -23,6 +23,16 @@ #define MV88E6XXX_PORT_STS_MY_PAUSE 0x4000 #define MV88E6XXX_PORT_STS_HD_FLOW 0x2000 #define MV88E6XXX_PORT_STS_PHY_DETECT 0x1000 +#define MV88E6250_PORT_STS_LINK 0x1000 +#define MV88E6250_PORT_STS_PORTMODE_MASK 0x0f00 +#define MV88E6250_PORT_STS_PORTMODE_PHY_10_HALF 0x0800 +#define MV88E6250_PORT_STS_PORTMODE_PHY_100_HALF 0x0900 +#define MV88E6250_PORT_STS_PORTMODE_PHY_10_FULL 0x0a00 +#define MV88E6250_PORT_STS_PORTMODE_PHY_100_FULL 0x0b00 +#define MV88E6250_PORT_STS_PORTMODE_MII_10_HALF 0x0c00 +#define MV88E6250_PORT_STS_PORTMODE_MII_100_HALF 0x0d00 +#define MV88E6250_PORT_STS_PORTMODE_MII_10_FULL 0x0e00 +#define MV88E6250_PORT_STS_PORTMODE_MII_100_FULL 0x0f00 #define MV88E6XXX_PORT_STS_LINK 0x0800 #define MV88E6XXX_PORT_STS_DUPLEX 0x0400 #define MV88E6XXX_PORT_STS_SPEED_MASK 0x0300 @@ -333,6 +343,8 @@ int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port, struct phylink_link_state *state); +int mv88e6250_port_link_state(struct mv88e6xxx_chip *chip, int port, + struct phylink_link_state *state); int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, struct phylink_link_state *state); int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port); |