[U-Boot] [PATCH v2 1/1, for v2018.11-rc2] efi_loader: fix simple network protocol
Heinrich Schuchardt
xypron.glpk at gmx.de
Thu Oct 4 09:13:53 UTC 2018
We should not call eth_rx() before the network interface is initialized.
The services of the simple network protocol should check the state of
the network adapter.
Provide a correctly aligned transmit buffer not depending on
CONFIG_EFI_LOADER_BOUNCE_BUFFER.
Correct the unit test.
Add and correct comments.
Without this patch i.mx6 system Wandboard Quad rev B1 fails to execute
bootefi selftest.
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
v2:
match EFI_ENTRY() and EFI_EXIT() in efi_network_timer_notify()
update comments
---
lib/efi_loader/efi_net.c | 419 +++++++++++++++++++++++-----
lib/efi_selftest/efi_selftest_snp.c | 16 +-
2 files changed, 359 insertions(+), 76 deletions(-)
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index c4f35cd50d..a37eeaeeea 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -14,6 +14,8 @@ static const efi_guid_t efi_pxe_guid = EFI_PXE_GUID;
static struct efi_pxe_packet *dhcp_ack;
static bool new_rx_packet;
static void *new_tx_packet;
+static void *transmit_buffer;
+
/*
* The notification function of this event is called in every timer cycle
* to check if a new network packet has been received.
@@ -41,22 +43,68 @@ struct efi_net_obj {
struct efi_pxe_mode pxe_mode;
};
+/*
+ * efi_net_start() - start the network interface
+ *
+ * This function implements the Start service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p", this);
- return EFI_EXIT(EFI_SUCCESS);
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (this->mode->state != EFI_NETWORK_STOPPED)
+ ret = EFI_ALREADY_STARTED;
+ else
+ this->mode->state = EFI_NETWORK_STARTED;
+out:
+ return EFI_EXIT(ret);
}
+/*
+ * efi_net_stop() - stop the network interface
+ *
+ * This function implements the Stop service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p", this);
- return EFI_EXIT(EFI_SUCCESS);
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (this->mode->state == EFI_NETWORK_STOPPED)
+ ret = EFI_NOT_STARTED;
+ else
+ this->mode->state = EFI_NETWORK_STOPPED;
+out:
+ return EFI_EXIT(ret);
}
/*
- * Initialize network adapter and allocate transmit and receive buffers.
+ * efi_net_initialize() - initialize the network interface
*
* This function implements the Initialize service of the
* EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
@@ -65,7 +113,7 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
* @this: pointer to the protocol instance
* @extra_rx: extra receive buffer to be allocated
* @extra_tx: extra transmit buffer to be allocated
- * @return: status code
+ * Return: status code
*/
static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
ulong extra_rx, ulong extra_tx)
@@ -75,9 +123,10 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
EFI_ENTRY("%p, %lx, %lx", this, extra_rx, extra_tx);
+ /* Check parameters */
if (!this) {
r = EFI_INVALID_PARAMETER;
- goto error;
+ goto out;
}
/* Setup packet buffers */
@@ -90,32 +139,83 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
ret = eth_init();
if (ret < 0) {
eth_halt();
+ this->mode->state = EFI_NETWORK_STOPPED;
r = EFI_DEVICE_ERROR;
+ goto out;
+ } else {
+ this->mode->state = EFI_NETWORK_INITIALIZED;
}
-
-error:
+out:
return EFI_EXIT(r);
}
+/*
+ * efi_net_reset() - reinitialize the network interface
+ *
+ * This function implements the Reset service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * @extended_verification: execute exhaustive verification
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
int extended_verification)
{
EFI_ENTRY("%p, %x", this, extended_verification);
- return EFI_EXIT(EFI_SUCCESS);
+ return EFI_EXIT(EFI_CALL(efi_net_initialize(this, 0, 0)));
}
+/*
+ * efi_net_shutdown() - shut down the network interface
+ *
+ * This function implements the Shutdown service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p", this);
- return EFI_EXIT(EFI_SUCCESS);
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ eth_halt();
+ this->mode->state = EFI_NETWORK_STOPPED;
+
+out:
+ return EFI_EXIT(ret);
}
-static efi_status_t EFIAPI efi_net_receive_filters(
- struct efi_simple_network *this, u32 enable, u32 disable,
- int reset_mcast_filter, ulong mcast_filter_count,
- struct efi_mac_address *mcast_filter)
+/*
+ * efi_net_receive_filters() - mange multicast receive filters
+ *
+ * This function implements the ReceiveFilters service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * @enable: bit mask of receive filters to enable
+ * @disable: bit mask of receive filters to disable
+ * @reset_mcast_filter: true resets contents of the filters
+ * @mcast_filter_count: number of hardware MAC addresses in the new filters list
+ * @mcast_filter: list of new filters
+ * Return: status code
+ */
+static efi_status_t EFIAPI efi_net_receive_filters
+ (struct efi_simple_network *this, u32 enable, u32 disable,
+ int reset_mcast_filter, ulong mcast_filter_count,
+ struct efi_mac_address *mcast_filter)
{
EFI_ENTRY("%p, %x, %x, %x, %lx, %p", this, enable, disable,
reset_mcast_filter, mcast_filter_count, mcast_filter);
@@ -123,15 +223,40 @@ static efi_status_t EFIAPI efi_net_receive_filters(
return EFI_EXIT(EFI_UNSUPPORTED);
}
-static efi_status_t EFIAPI efi_net_station_address(
- struct efi_simple_network *this, int reset,
- struct efi_mac_address *new_mac)
+/*
+ * efi_net_station_address() - set the hardware MAC address
+ *
+ * This function implements the StationAddress service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * @reset: if true reset the address to default
+ * @new_mac: new MAC address
+ * Return: status code
+ */
+static efi_status_t EFIAPI efi_net_station_address
+ (struct efi_simple_network *this, int reset,
+ struct efi_mac_address *new_mac)
{
EFI_ENTRY("%p, %x, %p", this, reset, new_mac);
return EFI_EXIT(EFI_UNSUPPORTED);
}
+/*
+ * efi_net_statistics() - reset or collect statistics of the network interface
+ *
+ * This function implements the Statistics service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * @reset: if true, the statistics are reset
+ * @stat_size: size of the statistics table
+ * @stat_table: table to receive the statistics
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
int reset, ulong *stat_size,
void *stat_table)
@@ -141,6 +266,19 @@ static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
return EFI_EXIT(EFI_UNSUPPORTED);
}
+/*
+ * efi_net_mcastiptomac() - translate multicast IP address to MAC address
+ *
+ * This function implements the Statistics service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this: pointer to the protocol instance
+ * @ipv6: true if the IP address is an IPv6 address
+ * @ip: IP address
+ * @mac: MAC address
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
int ipv6,
struct efi_ip_address *ip,
@@ -151,6 +289,19 @@ static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
return EFI_EXIT(EFI_INVALID_PARAMETER);
}
+/**
+ * efi_net_nvdata() - read or write NVRAM
+ *
+ * This function implements the GetStatus service of the Simple Network
+ * Protocol. See the UEFI spec for details.
+ *
+ * @this: the instance of the Simple Network Protocol
+ * @readwrite: true for read, false for write
+ * @offset: offset in NVRAM
+ * @buffer_size: size of buffer
+ * @buffer: buffer
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this,
int read_write, ulong offset,
ulong buffer_size, char *buffer)
@@ -161,13 +312,42 @@ static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this,
return EFI_EXIT(EFI_UNSUPPORTED);
}
+/**
+ * efi_net_get_status() - get interrupt status
+ *
+ * This function implements the GetStatus service of the Simple Network
+ * Protocol. See the UEFI spec for details.
+ *
+ * @this: the instance of the Simple Network Protocol
+ * @int_status: interface status
+ * @txbuf: transmission buffer
+ */
static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
u32 *int_status, void **txbuf)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p, %p, %p", this, int_status, txbuf);
efi_timer_check();
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ switch (this->mode->state) {
+ case EFI_NETWORK_STOPPED:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ case EFI_NETWORK_STARTED:
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ default:
+ break;
+ }
+
if (int_status) {
/* We send packets synchronously, so nothing is outstanding */
*int_status = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
@@ -178,65 +358,103 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
*txbuf = new_tx_packet;
new_tx_packet = NULL;
-
- return EFI_EXIT(EFI_SUCCESS);
+out:
+ return EFI_EXIT(ret);
}
-static efi_status_t EFIAPI efi_net_transmit(struct efi_simple_network *this,
- size_t header_size, size_t buffer_size, void *buffer,
- struct efi_mac_address *src_addr,
- struct efi_mac_address *dest_addr, u16 *protocol)
+/**
+ * efi_net_transmit() - transmit a packet
+ *
+ * This function implements the Transmit service of the Simple Network Protocol.
+ * See the UEFI spec for details.
+ *
+ * @this: the instance of the Simple Network Protocol
+ * @header_size: size of the media header
+ * @buffer_size: size of the buffer to receive the packet
+ * @buffer: buffer to receive the packet
+ * @src_addr: source hardware MAC address
+ * @dest_addr: destination hardware MAC address
+ * @protocol: type of header to build
+ * Return: status code
+ */
+static efi_status_t EFIAPI efi_net_transmit
+ (struct efi_simple_network *this, size_t header_size,
+ size_t buffer_size, void *buffer,
+ struct efi_mac_address *src_addr,
+ struct efi_mac_address *dest_addr, u16 *protocol)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p, %lu, %lu, %p, %p, %p, %p", this,
(unsigned long)header_size, (unsigned long)buffer_size,
buffer, src_addr, dest_addr, protocol);
efi_timer_check();
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* We do not support jumbo packets */
+ if (buffer_size > PKTSIZE_ALIGN) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
if (header_size) {
- /* We would need to create the header if header_size != 0 */
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ /*
+ * TODO: We would need to create the header
+ * if header_size != 0
+ */
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ switch (this->mode->state) {
+ case EFI_NETWORK_STOPPED:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ case EFI_NETWORK_STARTED:
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ default:
+ break;
}
-#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
/* Ethernet packets always fit, just bounce */
- memcpy(efi_bounce_buffer, buffer, buffer_size);
- net_send_packet(efi_bounce_buffer, buffer_size);
-#else
- net_send_packet(buffer, buffer_size);
-#endif
+ memcpy(transmit_buffer, buffer, buffer_size);
+ net_send_packet(transmit_buffer, buffer_size);
new_tx_packet = buffer;
- return EFI_EXIT(EFI_SUCCESS);
-}
-
-static void efi_net_push(void *pkt, int len)
-{
- new_rx_packet = true;
- wait_for_packet->is_signaled = true;
+out:
+ return EFI_EXIT(ret);
}
-/*
- * Receive a packet from a network interface.
+/**
+ * efi_net_receive() - receive a packet from a network interface
*
* This function implements the Receive service of the Simple Network Protocol.
* See the UEFI spec for details.
*
- * @this the instance of the Simple Network Protocol
- * @header_size size of the media header
- * @buffer_size size of the buffer to receive the packet
- * @buffer buffer to receive the packet
- * @src_addr source MAC address
- * @dest_addr destination MAC address
- * @protocol protocol
- * @return status code
+ * @this: the instance of the Simple Network Protocol
+ * @header_size: size of the media header
+ * @buffer_size: size of the buffer to receive the packet
+ * @buffer: buffer to receive the packet
+ * @src_addr: source MAC address
+ * @dest_addr: destination MAC address
+ * @protocol: protocol
+ * Return: status code
*/
-static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
- size_t *header_size, size_t *buffer_size, void *buffer,
- struct efi_mac_address *src_addr,
- struct efi_mac_address *dest_addr, u16 *protocol)
+static efi_status_t EFIAPI efi_net_receive
+ (struct efi_simple_network *this, size_t *header_size,
+ size_t *buffer_size, void *buffer,
+ struct efi_mac_address *src_addr,
+ struct efi_mac_address *dest_addr, u16 *protocol)
{
+ efi_status_t ret = EFI_SUCCESS;
struct ethernet_hdr *eth_hdr;
size_t hdr_size = sizeof(struct ethernet_hdr);
u16 protlen;
@@ -244,14 +462,35 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
EFI_ENTRY("%p, %p, %p, %p, %p, %p, %p", this, header_size,
buffer_size, buffer, src_addr, dest_addr, protocol);
+ /* Execute events */
efi_timer_check();
- if (!new_rx_packet)
- return EFI_EXIT(EFI_NOT_READY);
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ switch (this->mode->state) {
+ case EFI_NETWORK_STOPPED:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ case EFI_NETWORK_STARTED:
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ default:
+ break;
+ }
+
+ if (!new_rx_packet) {
+ ret = EFI_NOT_READY;
+ goto out;
+ }
/* Check that we at least received an Ethernet header */
if (net_rx_packet_len < sizeof(struct ethernet_hdr)) {
new_rx_packet = false;
- return EFI_EXIT(EFI_NOT_READY);
+ ret = EFI_NOT_READY;
+ goto out;
}
/* Fill export parameters */
eth_hdr = (struct ethernet_hdr *)net_rx_packet;
@@ -269,18 +508,24 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
if (protocol)
*protocol = protlen;
if (*buffer_size < net_rx_packet_len) {
- /* Packet doesn't fit, try again with bigger buf */
+ /* Packet doesn't fit, try again with bigger buffer */
*buffer_size = net_rx_packet_len;
- return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
+ ret = EFI_BUFFER_TOO_SMALL;
+ goto out;
}
/* Copy packet */
memcpy(buffer, net_rx_packet, net_rx_packet_len);
*buffer_size = net_rx_packet_len;
new_rx_packet = false;
-
- return EFI_EXIT(EFI_SUCCESS);
+out:
+ return EFI_EXIT(ret);
}
+/**
+ * efi_net_set_dhcp_ack() - take note of a selected DHCP IP address
+ *
+ * This function is called by dhcp_handler().
+ */
void efi_net_set_dhcp_ack(void *pkt, int len)
{
int maxsize = sizeof(*dhcp_ack);
@@ -291,8 +536,22 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
memcpy(dhcp_ack, pkt, min(len, maxsize));
}
-/*
- * Check if a new network packet has been received.
+/**
+ * efi_net_push() - callback for received network packet
+ *
+ * This function is called when a network packet is received by eth_rx().
+ *
+ * @pkt: network packet
+ * @len: length
+ */
+static void efi_net_push(void *pkt, int len)
+{
+ new_rx_packet = true;
+ wait_for_packet->is_signaled = true;
+}
+
+/**
+ * efi_network_timer_notify() - check if a new network packet has been received
*
* This notification function is called in every timer cycle.
*
@@ -302,20 +561,34 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
static void EFIAPI efi_network_timer_notify(struct efi_event *event,
void *context)
{
+ struct efi_simple_network *this = (struct efi_simple_network *)context;
+
EFI_ENTRY("%p, %p", event, context);
+ /*
+ * Some network drivers do not support calling eth_rx() before
+ * initialization.
+ */
+ if (!this || this->mode->state != EFI_NETWORK_INITIALIZED)
+ goto out;
+
if (!new_rx_packet) {
push_packet = efi_net_push;
eth_rx();
push_packet = NULL;
}
+out:
EFI_EXIT(EFI_SUCCESS);
}
-/* This gets called from do_bootefi_exec(). */
+/**
+ * efi_net_register() - register the simple network protocol
+ *
+ * This gets called from do_bootefi_exec().
+ */
efi_status_t efi_net_register(void)
{
- struct efi_net_obj *netobj;
+ struct efi_net_obj *netobj = NULL;
efi_status_t r;
if (!eth_get_dev()) {
@@ -325,10 +598,15 @@ efi_status_t efi_net_register(void)
/* We only expose the "active" eth device, so one is enough */
netobj = calloc(1, sizeof(*netobj));
- if (!netobj) {
- printf("ERROR: Out of memory\n");
- return EFI_OUT_OF_RESOURCES;
- }
+ if (!netobj)
+ goto out_of_resources;
+
+ /* Allocate an aligned transmit buffer */
+ transmit_buffer = calloc(1, PKTSIZE_ALIGN + ARCH_DMA_MINALIGN);
+ if (!transmit_buffer)
+ goto out_of_resources;
+ transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer,
+ ARCH_DMA_MINALIGN);
/* Hook net up to the device list */
efi_add_handle(&netobj->header);
@@ -391,13 +669,13 @@ efi_status_t efi_net_register(void)
* iPXE is running at TPL_CALLBACK most of the time. Use a higher TPL.
*/
r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
- efi_network_timer_notify, NULL, NULL,
+ efi_network_timer_notify, &netobj->net, NULL,
&network_timer_event);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to register network event\n");
return r;
}
- /* Network is time critical, create event in every timer cyle */
+ /* Network is time critical, create event in every timer cycle */
r = efi_set_timer(network_timer_event, EFI_TIMER_PERIODIC, 0);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to set network timer\n");
@@ -408,4 +686,9 @@ efi_status_t efi_net_register(void)
failure_to_add_protocol:
printf("ERROR: Failure to add protocol\n");
return r;
+out_of_resources:
+ free(netobj);
+ /* free(transmit_buffer) not needed yet */
+ printf("ERROR: Out of memory\n");
+ return EFI_OUT_OF_RESOURCES;
}
diff --git a/lib/efi_selftest/efi_selftest_snp.c b/lib/efi_selftest/efi_selftest_snp.c
index 09bd53da82..e10a34ba64 100644
--- a/lib/efi_selftest/efi_selftest_snp.c
+++ b/lib/efi_selftest/efi_selftest_snp.c
@@ -103,7 +103,7 @@ static efi_status_t send_dhcp_discover(void)
struct dhcp p = {};
/*
- * Fill ethernet header
+ * Fill Ethernet header
*/
boottime->copy_mem(p.eth_hdr.et_dest, (void *)BROADCAST_MAC, ARP_HLEN);
boottime->copy_mem(p.eth_hdr.et_src, &net->mode->current_address,
@@ -229,19 +229,19 @@ static int setup(const efi_handle_t handle,
return EFI_ST_FAILURE;
}
/*
- * Initialize network adapter.
+ * Start network adapter.
*/
- ret = net->initialize(net, 0, 0);
- if (ret != EFI_SUCCESS) {
- efi_st_error("Failed to initialize network adapter\n");
+ ret = net->start(net);
+ if (ret != EFI_SUCCESS && ret != EFI_ALREADY_STARTED) {
+ efi_st_error("Failed to start network adapter\n");
return EFI_ST_FAILURE;
}
/*
- * Start network adapter.
+ * Initialize network adapter.
*/
- ret = net->start(net);
+ ret = net->initialize(net, 0, 0);
if (ret != EFI_SUCCESS) {
- efi_st_error("Failed to start network adapter\n");
+ efi_st_error("Failed to initialize network adapter\n");
return EFI_ST_FAILURE;
}
return EFI_ST_SUCCESS;
--
2.19.0
More information about the U-Boot
mailing list