mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
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 commit68acb51f44
("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:68acb51f44
("net: Only call halt on a driver that has been init'ed") Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
This commit is contained in:
parent
db0dd72e27
commit
fa795f4525
1 changed files with 10 additions and 4 deletions
|
@ -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;
|
||||
|
||||
priv = dev_get_uclass_priv(current);
|
||||
if (!priv || !priv->running)
|
||||
return;
|
||||
|
||||
eth_get_ops(current)->stop(current);
|
||||
priv = dev_get_uclass_priv(current);
|
||||
if (priv)
|
||||
priv->state = ETH_STATE_PASSIVE;
|
||||
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) ||
|
||||
|
|
Loading…
Reference in a new issue