diff mbox series

[2/5] net: ti: am65-cpsw-nuss: avoid errors due to imbalanced start()/stop()

Message ID 5aa919346ec1039c0f3a25f07bf04d6274810702.1714117337.git.matthias.schiffer@ew.tq-group.com
State New
Delegated to: Tom Rini
Headers show
Series [1/5] net: eth-uclass: guard against reentrant eth_init()/eth_halt() calls | expand

Commit Message

Matthias Schiffer April 26, 2024, 8:02 a.m. UTC
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 | 9 +++++++++
 1 file changed, 9 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index b151e25d6a4..4a57e945a3a 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -328,6 +328,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);
@@ -488,6 +491,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);
@@ -504,6 +510,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);
 }