diff options
author | Stefan Chulski | 2019-08-15 18:08:41 -0400 |
---|---|---|
committer | Joe Hershberger | 2019-12-09 09:47:42 -0600 |
commit | 13b725fd24bd7d6acdd7cb7c3c4238d0b305985e (patch) | |
tree | bc42b0f1a9ab38c9b364ff8f3d8aa35b45ee9b9a /drivers/net | |
parent | 5efb69298be40b1f277157b41e38442ab50eb4f2 (diff) |
net: mvpp2x: fix traffic stuck after PHY start error
Issue:
- Network stuck if autonegotion fails.
Issue root cause:
- When autonegotiation fails during port open procedure, the packet
processor configuration does not finish and open procedure exits
with error.
- However, this doesn't prevent u-boot network framework from
calling send and receive procedures.
- Using transmit and receive functions of misconfigured packet
processor will cause traffic to get stuck.
Fix:
- Continue packet processor configuration even if autonegotiation
fails. Only error message is triggered in this case.
- Exit transmit and receive functions if there is no PHY link
indication.
- U-boot network framework now calls open procedure again during next
transmit initiation.
Signed-off-by: Stefan Chulski <stefanc@marvell.com>
Reviewed-by: Igal Liberman <igall@marvell.com>
Tested-by: Igal Liberman <igall@marvell.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mvpp2.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index 8148c03d22c..4ee765872cd 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -4495,7 +4495,7 @@ static void mvpp2_stop_dev(struct mvpp2_port *port) gop_port_enable(port, 0); } -static int mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port) +static void mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port) { struct phy_device *phy_dev; @@ -4505,7 +4505,7 @@ static int mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port) port->phy_dev = phy_dev; if (!phy_dev) { netdev_err(port->dev, "cannot connect to phy\n"); - return -ENODEV; + return; } phy_dev->supported &= PHY_GBIT_FEATURES; phy_dev->advertising = phy_dev->supported; @@ -4517,18 +4517,14 @@ static int mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port) phy_config(phy_dev); phy_startup(phy_dev); - if (!phy_dev->link) { + if (!phy_dev->link) printf("%s: No link\n", phy_dev->dev->name); - return -1; - } - - port->init = 1; + else + port->init = 1; } else { mvpp2_egress_enable(port); mvpp2_ingress_enable(port); } - - return 0; } static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port) @@ -4568,10 +4564,7 @@ static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port) } if (port->phy_node) { - err = mvpp2_phy_connect(dev, port); - if (err < 0) - return err; - + mvpp2_phy_connect(dev, port); mvpp2_link_event(port); } else { mvpp2_egress_enable(port); @@ -5176,6 +5169,10 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) struct mvpp2_rx_queue *rxq; u8 *data; + if (port->phy_node) + if (!port->phy_dev->link) + return 0; + /* Process RX packets */ rxq = port->rxqs[0]; @@ -5241,6 +5238,10 @@ static int mvpp2_send(struct udevice *dev, void *packet, int length) int tx_done; int timeout; + if (port->phy_node) + if (!port->phy_dev->link) + return 0; + txq = port->txqs[0]; aggr_txq = &port->priv->aggr_txqs[smp_processor_id()]; |