]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
net: ti: am65-cpsw-nuss: avoid errors due to imbalanced start()/stop()
authorMatthias Schiffer <matthias.schiffer@ew.tq-group.com>
Fri, 26 Apr 2024 08:02:25 +0000 (10:02 +0200)
committerTom Rini <trini@konsulko.com>
Wed, 15 May 2024 16:46:47 +0000 (10:46 -0600)
The eth-uclass state machine doesn't prevent imbalanced start()/stop()
calls - to the contrary, it even provides eth_init_state_only() and
eth_halt_state_only() functions that change the state without any calls
into the driver. This means that the driver must be robust against
duplicate start() and stop() calls as well as send/recv calls while the
interface is down.

We decide not to print error messages but just to return an error in the
latter case, as trying to send packets on a disabled interface commonly
happens when the netconsole is still active after the Ethernet has been
halted during bootm.

Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
drivers/net/ti/am65-cpsw-nuss.c

index 335c8bee3fefb29281169a631821f4a27781f94e..e0968f6e6fcca516d18d8ef1b6bf665496f5f0e2 100644 (file)
@@ -327,6 +327,9 @@ static int am65_cpsw_start(struct udevice *dev)
        struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
        int ret, i;
 
+       if (common->started)
+               return 0;
+
        ret = power_domain_on(&common->pwrdmn);
        if (ret) {
                dev_err(dev, "power_domain_on() failed %d\n", ret);
@@ -487,6 +490,9 @@ static int am65_cpsw_send(struct udevice *dev, void *packet, int length)
        struct ti_udma_drv_packet_data packet_data;
        int ret;
 
+       if (!common->started)
+               return -ENETDOWN;
+
        packet_data.pkt_type = AM65_CPSW_CPPI_PKT_TYPE;
        packet_data.dest_tag = priv->port_id;
        ret = dma_send(&common->dma_tx, packet, length, &packet_data);
@@ -503,6 +509,9 @@ static int am65_cpsw_recv(struct udevice *dev, int flags, uchar **packetp)
        struct am65_cpsw_priv *priv = dev_get_priv(dev);
        struct am65_cpsw_common *common = priv->cpsw_common;
 
+       if (!common->started)
+               return -ENETDOWN;
+
        /* try to receive a new packet */
        return dma_receive(&common->dma_rx, (void **)packetp, NULL);
 }