From fa795f452541ce07b33be603de36cac3c5d7dfcf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 4 Nov 2020 14:45:14 +0100 Subject: net: eth-uclass: avoid running start() twice without stop() Running the start() handler twice without a stop() inbetween completely breaks communication for some ethernet drivers like fec_mxc. eth_halt() is called before each eth_init(). Due to the switch to eth_is_active() in commit 68acb51f442f ("net: Only call halt on a driver that has been init'ed"), this is not sufficient anymore when netconsole is active: eth_init_state_only()/eth_halt_state_only() manipulate the state check that is performed by eth_is_active() without actually calling into the driver. The issue can be triggered by starting a network operation (e.g. ping or tftp) while netconsole is active. Add an additional "running" flag that reflects the actual state of the driver and use it to ensure that eth_halt() actually stops the device as it is supposed to. Fixes: 68acb51f442f ("net: Only call halt on a driver that has been init'ed") Signed-off-by: Matthias Schiffer --- net/eth-uclass.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'net/eth-uclass.c') diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 0156324032..7c2454f5ae 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR; */ struct eth_device_priv { enum eth_state_t state; + bool running; }; /** @@ -290,6 +291,7 @@ int eth_init(void) dev_get_uclass_priv(current); priv->state = ETH_STATE_ACTIVE; + priv->running = true; return 0; } } else { @@ -319,13 +321,16 @@ void eth_halt(void) struct eth_device_priv *priv; current = eth_get_dev(); - if (!current || !eth_is_active(current)) + if (!current) return; - eth_get_ops(current)->stop(current); priv = dev_get_uclass_priv(current); - if (priv) - priv->state = ETH_STATE_PASSIVE; + if (!priv || !priv->running) + return; + + eth_get_ops(current)->stop(current); + priv->state = ETH_STATE_PASSIVE; + priv->running = false; } int eth_is_active(struct udevice *dev) @@ -534,6 +539,7 @@ static int eth_post_probe(struct udevice *dev) #endif priv->state = ETH_STATE_INIT; + priv->running = false; /* Check if the device has a valid MAC address in device tree */ if (!eth_dev_get_mac_address(dev, pdata->enetaddr) || -- cgit v1.2.3 From 1231184caacad32c180d7e2338a645f7dfe9571a Mon Sep 17 00:00:00 2001 From: David Wu Date: Fri, 8 Jan 2021 10:53:05 +0800 Subject: net: eth-uclass: Change uclass driver name to ethernet dev_read_alias_seq() used uc_drv->name compared to alias stem string, Ethernet's alias stem uses "ethernet", which does not match the eth-uclass driver name "eth", can not get the correct index of ethernet alias namer. So it seems change uclass driver name to match the alias stem is a more reasonable way. Signed-off-by: David Wu Reviewed-by: Simon Glass --- net/eth-uclass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/eth-uclass.c') diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 7c2454f5ae..8a22d8bf59 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -597,8 +597,8 @@ static int eth_pre_remove(struct udevice *dev) return 0; } -UCLASS_DRIVER(eth) = { - .name = "eth", +UCLASS_DRIVER(ethernet) = { + .name = "ethernet", .id = UCLASS_ETH, .post_bind = eth_post_bind, .pre_unbind = eth_pre_unbind, -- cgit v1.2.3