mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
efi_loader: fix status management in network stack
The network should start in status EfiSimpleNetworkStopped. Add and correct status checks in the simple network protocol. Correct the unit test: * Shutdown() and Stop() during setup if needed * invoke Shutdown() before Stop() when tearing down Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
5947b49b09
commit
72a8f1685a
2 changed files with 105 additions and 14 deletions
|
@ -1,8 +1,18 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* EFI application network access support
|
||||
* Simple network protocol
|
||||
* PXE base code protocol
|
||||
*
|
||||
* Copyright (c) 2016 Alexander Graf
|
||||
* Copyright (c) 2016 Alexander Graf
|
||||
*
|
||||
* The simple network protocol has the following statuses and services
|
||||
* to move between them:
|
||||
*
|
||||
* Start(): EfiSimpleNetworkStopped -> EfiSimpleNetworkStarted
|
||||
* Initialize(): EfiSimpleNetworkStarted -> EfiSimpleNetworkInitialized
|
||||
* Shutdown(): EfiSimpleNetworkInitialized -> EfiSimpleNetworkStarted
|
||||
* Stop(): EfiSimpleNetworkStarted -> EfiSimpleNetworkStopped
|
||||
* Reset(): EfiSimpleNetworkInitialized -> EfiSimpleNetworkInitialized
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
@ -99,10 +109,13 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (this->mode->state == EFI_NETWORK_STOPPED)
|
||||
if (this->mode->state == EFI_NETWORK_STOPPED) {
|
||||
ret = EFI_NOT_STARTED;
|
||||
else
|
||||
} else {
|
||||
/* Disable hardware and put it into the reset state */
|
||||
eth_halt();
|
||||
this->mode->state = EFI_NETWORK_STOPPED;
|
||||
}
|
||||
out:
|
||||
return EFI_EXIT(ret);
|
||||
}
|
||||
|
@ -133,6 +146,15 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
|
|||
goto out;
|
||||
}
|
||||
|
||||
switch (this->mode->state) {
|
||||
case EFI_NETWORK_INITIALIZED:
|
||||
case EFI_NETWORK_STARTED:
|
||||
break;
|
||||
default:
|
||||
r = EFI_NOT_STARTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Setup packet buffers */
|
||||
net_init();
|
||||
/* Disable hardware and put it into the reset state */
|
||||
|
@ -169,9 +191,31 @@ out:
|
|||
static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
|
||||
int extended_verification)
|
||||
{
|
||||
efi_status_t ret;
|
||||
|
||||
EFI_ENTRY("%p, %x", this, extended_verification);
|
||||
|
||||
return EFI_EXIT(EFI_CALL(efi_net_initialize(this, 0, 0)));
|
||||
/* Check parameters */
|
||||
if (!this) {
|
||||
ret = EFI_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (this->mode->state) {
|
||||
case EFI_NETWORK_INITIALIZED:
|
||||
break;
|
||||
case EFI_NETWORK_STOPPED:
|
||||
ret = EFI_NOT_STARTED;
|
||||
goto out;
|
||||
default:
|
||||
ret = EFI_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
this->mode->state = EFI_NETWORK_STARTED;
|
||||
ret = EFI_CALL(efi_net_initialize(this, 0, 0));
|
||||
out:
|
||||
return EFI_EXIT(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,10 +240,21 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
|
|||
goto out;
|
||||
}
|
||||
|
||||
switch (this->mode->state) {
|
||||
case EFI_NETWORK_INITIALIZED:
|
||||
break;
|
||||
case EFI_NETWORK_STOPPED:
|
||||
ret = EFI_NOT_STARTED;
|
||||
goto out;
|
||||
default:
|
||||
ret = EFI_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
eth_halt();
|
||||
this->int_status = 0;
|
||||
wait_for_packet->is_signaled = false;
|
||||
this->mode->state = EFI_NETWORK_STOPPED;
|
||||
this->mode->state = EFI_NETWORK_STARTED;
|
||||
|
||||
out:
|
||||
return EFI_EXIT(ret);
|
||||
|
@ -779,7 +834,7 @@ efi_status_t efi_net_register(void)
|
|||
netobj->net.transmit = efi_net_transmit;
|
||||
netobj->net.receive = efi_net_receive;
|
||||
netobj->net.mode = &netobj->net_mode;
|
||||
netobj->net_mode.state = EFI_NETWORK_STARTED;
|
||||
netobj->net_mode.state = EFI_NETWORK_STOPPED;
|
||||
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
|
||||
netobj->net_mode.hwaddr_size = ARP_HLEN;
|
||||
netobj->net_mode.media_header_size = ETHER_HDR_SIZE;
|
||||
|
|
|
@ -228,6 +228,26 @@ static int setup(const efi_handle_t handle,
|
|||
efi_st_error("WaitForPacket event missing\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (net->mode->state == EFI_NETWORK_INITIALIZED) {
|
||||
/*
|
||||
* Shut down network adapter.
|
||||
*/
|
||||
ret = net->shutdown(net);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to shut down network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
}
|
||||
if (net->mode->state == EFI_NETWORK_STARTED) {
|
||||
/*
|
||||
* Stop network adapter.
|
||||
*/
|
||||
ret = net->stop(net);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to stop network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Start network adapter.
|
||||
*/
|
||||
|
@ -236,6 +256,10 @@ static int setup(const efi_handle_t handle,
|
|||
efi_st_error("Failed to start network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (net->mode->state != EFI_NETWORK_STARTED) {
|
||||
efi_st_error("Failed to start network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Initialize network adapter.
|
||||
*/
|
||||
|
@ -244,6 +268,10 @@ static int setup(const efi_handle_t handle,
|
|||
efi_st_error("Failed to initialize network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (net->mode->state != EFI_NETWORK_INITIALIZED) {
|
||||
efi_st_error("Failed to initialize network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
return EFI_ST_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -411,6 +439,18 @@ static int teardown(void)
|
|||
}
|
||||
}
|
||||
if (net) {
|
||||
/*
|
||||
* Shut down network adapter.
|
||||
*/
|
||||
ret = net->shutdown(net);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to shut down network adapter\n");
|
||||
exit_status = EFI_ST_FAILURE;
|
||||
}
|
||||
if (net->mode->state != EFI_NETWORK_STARTED) {
|
||||
efi_st_error("Failed to shutdown network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Stop network adapter.
|
||||
*/
|
||||
|
@ -419,13 +459,9 @@ static int teardown(void)
|
|||
efi_st_error("Failed to stop network adapter\n");
|
||||
exit_status = EFI_ST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Shut down network adapter.
|
||||
*/
|
||||
ret = net->shutdown(net);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to shut down network adapter\n");
|
||||
exit_status = EFI_ST_FAILURE;
|
||||
if (net->mode->state != EFI_NETWORK_STOPPED) {
|
||||
efi_st_error("Failed to stop network adapter\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue