net: dsa: mv88e6xxx: add phylink support
Add rudimentary phylink support to mv88e6xxx. TODO: - needs to call phylink_mac_change() when the port link comes up/goes down. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
此提交包含在:
@@ -388,6 +388,19 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* mv88e6185 only has 3 bits for CMODE */
|
||||
static int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
int err;
|
||||
u16 reg;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return reg & MV88E6185_PORT_STS_CMODE_MASK;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
|
||||
{
|
||||
int err;
|
||||
@@ -402,7 +415,7 @@ int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
int err;
|
||||
@@ -423,7 +436,7 @@ int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
state->speed = SPEED_1000;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_SPEED_10000:
|
||||
if ((reg &MV88E6XXX_PORT_STS_CMODE_MASK) ==
|
||||
if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
|
||||
MV88E6XXX_PORT_STS_CMODE_2500BASEX)
|
||||
state->speed = SPEED_2500;
|
||||
else
|
||||
@@ -440,6 +453,45 @@ int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
|
||||
int cmode = mv88e6185_port_get_cmode(chip, port);
|
||||
|
||||
if (cmode < 0)
|
||||
return cmode;
|
||||
|
||||
/* When a port is in "Cross-chip serdes" mode, it uses
|
||||
* 1000Base-X full duplex mode, but there is no automatic
|
||||
* link detection. Use the sync OK status for link (as it
|
||||
* would do for 1000Base-X mode.)
|
||||
*/
|
||||
if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
|
||||
u16 mac;
|
||||
int err;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port,
|
||||
MV88E6XXX_PORT_MAC_CTL, &mac);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
|
||||
state->an_enabled = 1;
|
||||
state->an_complete =
|
||||
!!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
|
||||
state->duplex =
|
||||
state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
|
||||
state->speed =
|
||||
state->link ? SPEED_1000 : SPEED_UNKNOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return mv88e6352_port_link_state(chip, port, state);
|
||||
}
|
||||
|
||||
/* Offset 0x02: Jamming Control
|
||||
*
|
||||
* Do not limit the period of time that this port can be paused for by
|
||||
|
新增問題並參考
封鎖使用者