diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2020-06-30 13:28:08 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-06-30 23:05:10 +0300 |
commit | 2d1f90f9ba8348ebc85fe57a0034509b21570a85 (patch) | |
tree | 5edb4534002ac075e68a2f6955b8195d68c71f8f /drivers/net/dsa/bcm_sf2.c | |
parent | bcd763b714e6738c1d66e74221d4150c35bf8fc1 (diff) | |
download | linux-2d1f90f9ba8348ebc85fe57a0034509b21570a85.tar.xz |
net: dsa/bcm_sf2: fix incorrect usage of state->link
state->link has never been valid in mac_config() implementations -
while it may be correct in some calls, it is not true that it can be
relied upon.
Fix bcm_sf2 to use the correct method of handling forced link status.
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/bcm_sf2.c')
-rw-r--r-- | drivers/net/dsa/bcm_sf2.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 946e41f020a5..5a8759d2de6c 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -618,8 +618,6 @@ force_link: break; } - if (state->link) - reg |= LINK_STS; if (state->duplex == DUPLEX_FULL) reg |= DUPLX_MODE; @@ -650,6 +648,20 @@ static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) { + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); + u32 reg, offset; + + if (port != core_readl(priv, CORE_IMP0_PRT_ID)) { + if (priv->type == BCM7445_DEVICE_ID) + offset = CORE_STS_OVERRIDE_GMIIP_PORT(port); + else + offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port); + + reg = core_readl(priv, offset); + reg &= ~LINK_STS; + core_writel(priv, reg, offset); + } + bcm_sf2_sw_mac_link_set(ds, port, interface, false); } @@ -662,9 +674,21 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port, { struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct ethtool_eee *p = &priv->dev->ports[port].eee; + u32 reg, offset; bcm_sf2_sw_mac_link_set(ds, port, interface, true); + if (port != core_readl(priv, CORE_IMP0_PRT_ID)) { + if (priv->type == BCM7445_DEVICE_ID) + offset = CORE_STS_OVERRIDE_GMIIP_PORT(port); + else + offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port); + + reg = core_readl(priv, offset); + reg |= LINK_STS; + core_writel(priv, reg, offset); + } + if (mode == MLO_AN_PHY && phydev) p->eee_enabled = b53_eee_init(ds, port, phydev); } |