Message ID | E1gqnmR-0007eF-87@rmk-PC.armlinux.org.uk |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | [net-next,1/2] net: marvell: mvpp2: use phy_interface_mode_is_8023z() helper | expand |
From: Russell King <rmk+kernel@armlinux.org.uk> Date: Mon, 04 Feb 2019 23:35:59 +0000 > Sven Auhagen reports that if he changes a SFP+ module for a SFP module > on the Macchiatobin Single Shot, the link does not come back up. For > Sven, it is as easy as: > > - Insert a SFP+ module connected, and use ping6 to verify link is up. > - Remove SFP+ module > - Insert SFP 1000base-X module use ping6 to verify link is up: Link > up event did not trigger and the link is down > > but that doesn't show the problem for me. Locally, this has been > reproduced by: > > - Boot with no modules. > - Insert SFP+ module, confirm link is up. > - Replace module with 25000base-X module. Confirm link is up. > - Set remote end down, link is reported as dropped at both ends. > - Set remote end up, link is reported up at remote end, but not local > end due to lack of link interrupt. > > Fix this by setting up both GMAC and XLG interrupts for port 0, but > only unmasking the appropriate interrupt according to the current mode > set in the mac_config() method. However, only do the mask/unmask > dance when we are really changing the link mode to avoid missing any > link interrupts. > > Tested-by: Sven Auhagen <sven.auhagen@voleatech.de> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Applied.
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index c54ed19dcdae..d8974c446f8e 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1133,7 +1133,8 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) { u32 val; - if (phy_interface_mode_is_rgmii(port->phy_interface) || + if (port->phylink || + phy_interface_mode_is_rgmii(port->phy_interface) || phy_interface_mode_is_8023z(port->phy_interface) || port->phy_interface == PHY_INTERFACE_MODE_SGMII) { val = readl(port->base + MVPP22_GMAC_INT_MASK); @@ -4635,6 +4636,7 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode, const struct phylink_link_state *state) { struct mvpp2_port *port = netdev_priv(dev); + bool change_interface = port->phy_interface != state->interface; /* Check for invalid configuration */ if (state->interface == PHY_INTERFACE_MODE_10GKR && port->gop_id != 0) { @@ -4644,14 +4646,16 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode, /* Make sure the port is disabled when reconfiguring the mode */ mvpp2_port_disable(port); + if (change_interface) { + mvpp22_gop_mask_irq(port); - if (port->priv->hw_version == MVPP22 && - port->phy_interface != state->interface) { - port->phy_interface = state->interface; + if (port->priv->hw_version == MVPP22) { + port->phy_interface = state->interface; - /* Reconfigure the serdes lanes */ - phy_power_off(port->comphy); - mvpp22_mode_reconfigure(port); + /* Reconfigure the serdes lanes */ + phy_power_off(port->comphy); + mvpp22_mode_reconfigure(port); + } } /* mac (re)configuration */ @@ -4665,6 +4669,9 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode, if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK) mvpp2_port_loopback_set(port, state); + if (change_interface) + mvpp22_gop_unmask_irq(port); + mvpp2_port_enable(port); }