mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-31 03:21:32 +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+
|
// 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>
|
#include <common.h>
|
||||||
|
@ -99,10 +109,13 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->mode->state == EFI_NETWORK_STOPPED)
|
if (this->mode->state == EFI_NETWORK_STOPPED) {
|
||||||
ret = EFI_NOT_STARTED;
|
ret = EFI_NOT_STARTED;
|
||||||
else
|
} else {
|
||||||
|
/* Disable hardware and put it into the reset state */
|
||||||
|
eth_halt();
|
||||||
this->mode->state = EFI_NETWORK_STOPPED;
|
this->mode->state = EFI_NETWORK_STOPPED;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
return EFI_EXIT(ret);
|
return EFI_EXIT(ret);
|
||||||
}
|
}
|
||||||
|
@ -133,6 +146,15 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
|
||||||
goto out;
|
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 */
|
/* Setup packet buffers */
|
||||||
net_init();
|
net_init();
|
||||||
/* Disable hardware and put it into the reset state */
|
/* 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,
|
static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
|
||||||
int extended_verification)
|
int extended_verification)
|
||||||
{
|
{
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
EFI_ENTRY("%p, %x", this, extended_verification);
|
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;
|
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();
|
eth_halt();
|
||||||
this->int_status = 0;
|
this->int_status = 0;
|
||||||
wait_for_packet->is_signaled = false;
|
wait_for_packet->is_signaled = false;
|
||||||
this->mode->state = EFI_NETWORK_STOPPED;
|
this->mode->state = EFI_NETWORK_STARTED;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return EFI_EXIT(ret);
|
return EFI_EXIT(ret);
|
||||||
|
@ -779,7 +834,7 @@ efi_status_t efi_net_register(void)
|
||||||
netobj->net.transmit = efi_net_transmit;
|
netobj->net.transmit = efi_net_transmit;
|
||||||
netobj->net.receive = efi_net_receive;
|
netobj->net.receive = efi_net_receive;
|
||||||
netobj->net.mode = &netobj->net_mode;
|
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);
|
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
|
||||||
netobj->net_mode.hwaddr_size = ARP_HLEN;
|
netobj->net_mode.hwaddr_size = ARP_HLEN;
|
||||||
netobj->net_mode.media_header_size = ETHER_HDR_SIZE;
|
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");
|
efi_st_error("WaitForPacket event missing\n");
|
||||||
return EFI_ST_FAILURE;
|
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.
|
* Start network adapter.
|
||||||
*/
|
*/
|
||||||
|
@ -236,6 +256,10 @@ static int setup(const efi_handle_t handle,
|
||||||
efi_st_error("Failed to start network adapter\n");
|
efi_st_error("Failed to start network adapter\n");
|
||||||
return EFI_ST_FAILURE;
|
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.
|
* Initialize network adapter.
|
||||||
*/
|
*/
|
||||||
|
@ -244,6 +268,10 @@ static int setup(const efi_handle_t handle,
|
||||||
efi_st_error("Failed to initialize network adapter\n");
|
efi_st_error("Failed to initialize network adapter\n");
|
||||||
return EFI_ST_FAILURE;
|
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;
|
return EFI_ST_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,6 +439,18 @@ static int teardown(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (net) {
|
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.
|
* Stop network adapter.
|
||||||
*/
|
*/
|
||||||
|
@ -419,13 +459,9 @@ static int teardown(void)
|
||||||
efi_st_error("Failed to stop network adapter\n");
|
efi_st_error("Failed to stop network adapter\n");
|
||||||
exit_status = EFI_ST_FAILURE;
|
exit_status = EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
/*
|
if (net->mode->state != EFI_NETWORK_STOPPED) {
|
||||||
* Shut down network adapter.
|
efi_st_error("Failed to stop network adapter\n");
|
||||||
*/
|
return EFI_ST_FAILURE;
|
||||||
ret = net->shutdown(net);
|
|
||||||
if (ret != EFI_SUCCESS) {
|
|
||||||
efi_st_error("Failed to shut down network adapter\n");
|
|
||||||
exit_status = EFI_ST_FAILURE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue