mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-29 20:46:41 +07:00
net: dsa: mv88e6xxx: check for mode change in port_setup_mac
The mv88e6xxx_port_setup_mac checks if the requested MAC settings are different from the current ones, and if not, does nothing (since chaning them requires putting the link down). In this check it only looks if the triplet [link, speed, duplex] is being changed. This patch adds support to also check if the mode parameter (of type phy_interface_t) is requested to be changed. The current mode is computed by the ->port_link_state() method, and if it is different from PHY_INTERFACE_MODE_NA, we check for equality with the requested mode. In the implementations of the mv88e6250_port_link_state() method we set the current mode to PHY_INTERFACE_MODE_NA - so the code does not check for mode change on 6250. In the mv88e6352_port_link_state() method, we use the cached cmode of the port to determine the mode as phy_interface_t (and if it is not enough, eg. for RGMII, we also look at the port control register for RX/TX timings). Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
13b18f1d28
commit
927441adea
@ -417,7 +417,9 @@ int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link,
|
||||
*/
|
||||
if (state.link == link &&
|
||||
state.speed == speed &&
|
||||
state.duplex == duplex)
|
||||
state.duplex == duplex &&
|
||||
(state.interface == mode ||
|
||||
state.interface == PHY_INTERFACE_MODE_NA))
|
||||
return 0;
|
||||
|
||||
/* Port's MAC control must not be changed unless the link is down */
|
||||
|
@ -590,6 +590,7 @@ int mv88e6250_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
state->link = !!(reg & MV88E6250_PORT_STS_LINK);
|
||||
state->an_enabled = 1;
|
||||
state->an_complete = state->link;
|
||||
state->interface = PHY_INTERFACE_MODE_NA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -600,6 +601,43 @@ int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
int err;
|
||||
u16 reg;
|
||||
|
||||
switch (chip->ports[port].cmode) {
|
||||
case MV88E6XXX_PORT_STS_CMODE_RGMII:
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL,
|
||||
®);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if ((reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK) &&
|
||||
(reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK))
|
||||
state->interface = PHY_INTERFACE_MODE_RGMII_ID;
|
||||
else if (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK)
|
||||
state->interface = PHY_INTERFACE_MODE_RGMII_RXID;
|
||||
else if (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK)
|
||||
state->interface = PHY_INTERFACE_MODE_RGMII_TXID;
|
||||
else
|
||||
state->interface = PHY_INTERFACE_MODE_RGMII;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
|
||||
state->interface = PHY_INTERFACE_MODE_1000BASEX;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_CMODE_SGMII:
|
||||
state->interface = PHY_INTERFACE_MODE_SGMII;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
|
||||
state->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_CMODE_XAUI:
|
||||
state->interface = PHY_INTERFACE_MODE_XAUI;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_CMODE_RXAUI:
|
||||
state->interface = PHY_INTERFACE_MODE_RXAUI;
|
||||
break;
|
||||
default:
|
||||
/* we do not support other cmode values here */
|
||||
state->interface = PHY_INTERFACE_MODE_NA;
|
||||
}
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020
|
||||
#define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010
|
||||
#define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f
|
||||
#define MV88E6XXX_PORT_STS_CMODE_RGMII 0x0007
|
||||
#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008
|
||||
#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009
|
||||
#define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a
|
||||
|
Loading…
Reference in New Issue
Block a user