net: mvpp2x: fix traffic stuck after PHY start error
authorStefan Chulski <stefanc@marvell.com>
Thu, 15 Aug 2019 22:08:41 +0000 (18:08 -0400)
committerJoe Hershberger <joe.hershberger@ni.com>
Mon, 9 Dec 2019 15:47:42 +0000 (09:47 -0600)
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>
drivers/net/mvpp2.c

index 8148c03d22ce67e440187616a93e789bb5e1155d..4ee765872cd55509bcf169dd47dd271f66def928 100644 (file)
@@ -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()];