aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Tenart <antoine.tenart@bootlin.com>2018-09-14 10:56:35 -0400
committerDavid S. Miller <davem@davemloft.net>2018-09-17 10:52:32 -0400
commit41948ccb4a856dddacfbd4d789d4fa8663fe41bb (patch)
tree0cd5917320f913a988068648b1431ce613cfc2f8
parent8540827ebac6b654ab2f69c8fbce9e4fbd6304a0 (diff)
net: mvpp2: let phylink manage the carrier state
Net drivers using phylink shouldn't mess with the link carrier themselves and should let phylink manage it. The mvpp2 driver wasn't following this best practice as the mac_config() function made calls to change the link carrier state. This led to wrongly reported carrier link state which then triggered other issues. This patch fixes this behaviour. But the PPv2 driver relied on this misbehaviour in two cases: for fixed links and when not using phylink (ACPI mode). The later was fixed by adding an explicit call to link_up(), which when the ACPI mode will use phylink should be removed. The fixed link case was relying on the mac_config() function to set the link up, as we found an issue in phylink_start() which assumes the carrier is off. If not, the link_up() function is never called. To fix this, a call to netif_carrier_off() is added just before phylink_start() so that we do not introduce a regression in the driver. Fixes: 4bb043262878 ("net: mvpp2: phylink support") Reported-by: Russell King <linux@armlinux.org.uk> Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 28500417843e..702fec82d806 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -58,6 +58,8 @@ static struct {
58 */ 58 */
59static void mvpp2_mac_config(struct net_device *dev, unsigned int mode, 59static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
60 const struct phylink_link_state *state); 60 const struct phylink_link_state *state);
61static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
62 phy_interface_t interface, struct phy_device *phy);
61 63
62/* Queue modes */ 64/* Queue modes */
63#define MVPP2_QDIST_SINGLE_MODE 0 65#define MVPP2_QDIST_SINGLE_MODE 0
@@ -3142,6 +3144,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
3142 mvpp22_mode_reconfigure(port); 3144 mvpp22_mode_reconfigure(port);
3143 3145
3144 if (port->phylink) { 3146 if (port->phylink) {
3147 netif_carrier_off(port->dev);
3145 phylink_start(port->phylink); 3148 phylink_start(port->phylink);
3146 } else { 3149 } else {
3147 /* Phylink isn't used as of now for ACPI, so the MAC has to be 3150 /* Phylink isn't used as of now for ACPI, so the MAC has to be
@@ -3150,9 +3153,10 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
3150 */ 3153 */
3151 struct phylink_link_state state = { 3154 struct phylink_link_state state = {
3152 .interface = port->phy_interface, 3155 .interface = port->phy_interface,
3153 .link = 1,
3154 }; 3156 };
3155 mvpp2_mac_config(port->dev, MLO_AN_INBAND, &state); 3157 mvpp2_mac_config(port->dev, MLO_AN_INBAND, &state);
3158 mvpp2_mac_link_up(port->dev, MLO_AN_INBAND, port->phy_interface,
3159 NULL);
3156 } 3160 }
3157 3161
3158 netif_tx_start_all_queues(port->dev); 3162 netif_tx_start_all_queues(port->dev);
@@ -4495,10 +4499,6 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
4495 return; 4499 return;
4496 } 4500 }
4497 4501
4498 netif_tx_stop_all_queues(port->dev);
4499 if (!port->has_phy)
4500 netif_carrier_off(port->dev);
4501
4502 /* Make sure the port is disabled when reconfiguring the mode */ 4502 /* Make sure the port is disabled when reconfiguring the mode */
4503 mvpp2_port_disable(port); 4503 mvpp2_port_disable(port);
4504 4504
@@ -4523,16 +4523,7 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
4523 if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK) 4523 if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK)
4524 mvpp2_port_loopback_set(port, state); 4524 mvpp2_port_loopback_set(port, state);
4525 4525
4526 /* If the port already was up, make sure it's still in the same state */ 4526 mvpp2_port_enable(port);
4527 if (state->link || !port->has_phy) {
4528 mvpp2_port_enable(port);
4529
4530 mvpp2_egress_enable(port);
4531 mvpp2_ingress_enable(port);
4532 if (!port->has_phy)
4533 netif_carrier_on(dev);
4534 netif_tx_wake_all_queues(dev);
4535 }
4536} 4527}
4537 4528
4538static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode, 4529static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,