Add support for multiple efi_net_obj structs in efi_net.c. This comes in preparation for an EFI network driver supporting multiple network interfaces. For now the EFI network stack still registers a single ethernet udevice as an EFI network device even if multiple are present, namely the one that was the current device at the moment of EFI initialization.
Signed-off-by: Adriano Cordova <adriano.cord...@canonical.com> --- include/efi_loader.h | 5 +- lib/efi_loader/efi_http.c | 4 +- lib/efi_loader/efi_net.c | 260 +++++++++++++++++++++++++++----------- 3 files changed, 196 insertions(+), 73 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index a65edae3440..83a4d5b747f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -140,8 +140,11 @@ void efi_net_set_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw, struct udevice *dev); +#if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL) efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buffer, - u32 *status_code, ulong *file_size, char *headers_buffer); + u32 *status_code, ulong *file_size, char *headers_buffer, + struct efi_service_binding_protocol *parent); +#endif #define MAX_HTTP_HEADERS_SIZE SZ_64K #define MAX_HTTP_HEADERS 100 #define MAX_HTTP_HEADER_NAME 128 diff --git a/lib/efi_loader/efi_http.c b/lib/efi_loader/efi_http.c index 60309ee3112..189317fe2d2 100644 --- a/lib/efi_loader/efi_http.c +++ b/lib/efi_loader/efi_http.c @@ -36,6 +36,7 @@ static const efi_guid_t efi_http_guid = EFI_HTTP_PROTOCOL_GUID; struct efi_http_instance { struct efi_http_protocol http; efi_handle_t handle; + struct efi_service_binding_protocol *parent; bool configured; void *http_load_addr; ulong file_size; @@ -243,7 +244,7 @@ static efi_status_t EFIAPI efi_http_request(struct efi_http_protocol *this, ret = efi_net_do_request(url_8, current_method, &http_instance->http_load_addr, &http_instance->status_code, &http_instance->file_size, - http_instance->headers_buffer); + http_instance->headers_buffer, http_instance->parent); if (ret != EFI_SUCCESS) goto out; @@ -408,6 +409,7 @@ static efi_status_t EFIAPI efi_http_service_binding_create_child( goto failure_to_add_protocol; } + new_instance->parent = this; efi_add_handle(new_instance->handle); *child_handle = new_instance->handle; diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 2fac39ae513..b539ae071c7 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -24,19 +24,13 @@ #include <vsprintf.h> #include <net.h> +#define MAX_EFI_NET_OBJS 10 #define MAX_NUM_DHCP_ENTRIES 10 #define MAX_NUM_DP_ENTRIES 10 const efi_guid_t efi_net_guid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; static const efi_guid_t efi_pxe_base_code_protocol_guid = EFI_PXE_BASE_CODE_PROTOCOL_GUID; -static void *new_tx_packet; -static void *transmit_buffer; -static uchar **receive_buffer; -static size_t *receive_lengths; -static int rx_packet_idx; -static int rx_packet_num; -static struct efi_net_obj *netobj; struct dp_entry { struct efi_device_path *net_dp; @@ -70,16 +64,6 @@ struct dhcp_entry { static struct dhcp_entry dhcp_cache[MAX_NUM_DHCP_ENTRIES]; static int next_dhcp_entry; -/* - * The notification function of this event is called in every timer cycle - * to check if a new network packet has been received. - */ -static struct efi_event *network_timer_event; -/* - * This event is signaled when a packet has been received. - */ -static struct efi_event *wait_for_packet; - /** * struct efi_net_obj - EFI object representing a network interface * @@ -105,13 +89,32 @@ struct efi_net_obj { #if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL) struct efi_service_binding_protocol http_service_binding; #endif + void *new_tx_packet; + void *transmit_buffer; + uchar **receive_buffer; + size_t *receive_lengths; + int rx_packet_idx; + int rx_packet_num; + /* + * This event is signaled when a packet has been received. + */ + struct efi_event *wait_for_packet; + /* + * The notification function of this event is called in every timer cycle + * to check if a new network packet has been received. + */ + struct efi_event *network_timer_event; + int efi_seq_num; }; -/* +static int curr_efi_net_obj; +static struct efi_net_obj *net_objs[MAX_EFI_NET_OBJS]; + +/** * efi_netobj_is_active() - checks if a netobj is active in the efi subsystem * - * @netobj: pointer to efi_net_obj - * Return: true if active + * @netobj: pointer to efi_net_obj + * Return: true if active */ static bool efi_netobj_is_active(struct efi_net_obj *netobj) { @@ -121,6 +124,25 @@ static bool efi_netobj_is_active(struct efi_net_obj *netobj) return true; } +/* + * efi_netobj_from_snp() - get efi_net_obj from simple network protocol + * + * + * @snp: pointer to the simple network protocol + * Return: pointer to efi_net_obj, NULL on error + */ +static struct efi_net_obj *efi_netobj_from_snp(struct efi_simple_network *snp) +{ + int i; + + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && &net_objs[i]->net == snp) { + // Do not register duplicate devices + return net_objs[i]; + } + } + return NULL; +} /* * efi_net_start() - start the network interface @@ -135,6 +157,7 @@ static bool efi_netobj_is_active(struct efi_net_obj *netobj) static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this) { efi_status_t ret = EFI_SUCCESS; + struct efi_net_obj *nt; EFI_ENTRY("%p", this); /* Check parameters */ @@ -143,11 +166,13 @@ static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this) goto out; } + nt = efi_netobj_from_snp(this); + if (this->mode->state != EFI_NETWORK_STOPPED) { ret = EFI_ALREADY_STARTED; } else { this->int_status = 0; - wait_for_packet->is_signaled = false; + nt->wait_for_packet->is_signaled = false; this->mode->state = EFI_NETWORK_STARTED; } out: @@ -167,6 +192,7 @@ out: static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this) { efi_status_t ret = EFI_SUCCESS; + struct efi_net_obj *nt; EFI_ENTRY("%p", this); @@ -176,15 +202,17 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this) goto out; } + nt = efi_netobj_from_snp(this); + if (this->mode->state == EFI_NETWORK_STOPPED) { ret = EFI_NOT_STARTED; } else { /* Disable hardware and put it into the reset state */ - eth_set_dev(netobj->dev); + eth_set_dev(nt->dev); env_set("ethact", eth_get_name()); eth_halt(); /* Clear cache of packets */ - rx_packet_num = 0; + nt->rx_packet_num = 0; this->mode->state = EFI_NETWORK_STOPPED; } out: @@ -208,6 +236,7 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, { int ret; efi_status_t r = EFI_SUCCESS; + struct efi_net_obj *nt; EFI_ENTRY("%p, %lx, %lx", this, extra_rx, extra_tx); @@ -216,6 +245,7 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, r = EFI_INVALID_PARAMETER; goto out; } + nt = efi_netobj_from_snp(this); switch (this->mode->state) { case EFI_NETWORK_INITIALIZED: @@ -229,12 +259,12 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, /* Setup packet buffers */ net_init(); /* Clear cache of packets */ - rx_packet_num = 0; + nt->rx_packet_num = 0; /* Set the net device corresponding to the efi net object */ - eth_set_dev(netobj->dev); + eth_set_dev(nt->dev); env_set("ethact", eth_get_name()); /* Get hardware ready for send and receive operations */ - ret = eth_start_udev(netobj->dev); + ret = eth_start_udev(nt->dev); if (ret < 0) { eth_halt(); this->mode->state = EFI_NETWORK_STOPPED; @@ -242,7 +272,7 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, goto out; } else { this->int_status = 0; - wait_for_packet->is_signaled = false; + nt->wait_for_packet->is_signaled = false; this->mode->state = EFI_NETWORK_INITIALIZED; } out: @@ -303,6 +333,7 @@ out: static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this) { efi_status_t ret = EFI_SUCCESS; + struct efi_net_obj *nt; EFI_ENTRY("%p", this); @@ -311,6 +342,7 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this) ret = EFI_INVALID_PARAMETER; goto out; } + nt = efi_netobj_from_snp(this); switch (this->mode->state) { case EFI_NETWORK_INITIALIZED: @@ -323,12 +355,12 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this) goto out; } - eth_set_dev(netobj->dev); + eth_set_dev(nt->dev); env_set("ethact", eth_get_name()); eth_halt(); this->int_status = 0; - wait_for_packet->is_signaled = false; + nt->wait_for_packet->is_signaled = false; this->mode->state = EFI_NETWORK_STARTED; out: @@ -504,6 +536,7 @@ 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; + struct efi_net_obj *nt; EFI_ENTRY("%p, %p, %p", this, int_status, txbuf); @@ -515,6 +548,8 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this, goto out; } + nt = efi_netobj_from_snp(this); + switch (this->mode->state) { case EFI_NETWORK_STOPPED: ret = EFI_NOT_STARTED; @@ -531,9 +566,9 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this, this->int_status = 0; } if (txbuf) - *txbuf = new_tx_packet; + *txbuf = nt->new_tx_packet; - new_tx_packet = NULL; + nt->new_tx_packet = NULL; out: return EFI_EXIT(ret); } @@ -560,6 +595,7 @@ static efi_status_t EFIAPI efi_net_transmit struct efi_mac_address *dest_addr, u16 *protocol) { efi_status_t ret = EFI_SUCCESS; + struct efi_net_obj *nt; EFI_ENTRY("%p, %lu, %lu, %p, %p, %p, %p", this, (unsigned long)header_size, (unsigned long)buffer_size, @@ -573,6 +609,8 @@ static efi_status_t EFIAPI efi_net_transmit goto out; } + nt = efi_netobj_from_snp(this); + /* We do not support jumbo packets */ if (buffer_size > PKTSIZE_ALIGN) { ret = EFI_INVALID_PARAMETER; @@ -617,14 +655,14 @@ static efi_status_t EFIAPI efi_net_transmit break; } - eth_set_dev(netobj->dev); + eth_set_dev(nt->dev); env_set("ethact", eth_get_name()); /* Ethernet packets always fit, just bounce */ - memcpy(transmit_buffer, buffer, buffer_size); - net_send_packet(transmit_buffer, buffer_size); + memcpy(nt->transmit_buffer, buffer, buffer_size); + net_send_packet(nt->transmit_buffer, buffer_size); - new_tx_packet = buffer; + nt->new_tx_packet = buffer; this->int_status |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; out: return EFI_EXIT(ret); @@ -655,6 +693,7 @@ static efi_status_t EFIAPI efi_net_receive struct ethernet_hdr *eth_hdr; size_t hdr_size = sizeof(struct ethernet_hdr); u16 protlen; + struct efi_net_obj *nt; EFI_ENTRY("%p, %p, %p, %p, %p, %p, %p", this, header_size, buffer_size, buffer, src_addr, dest_addr, protocol); @@ -668,6 +707,8 @@ static efi_status_t EFIAPI efi_net_receive goto out; } + nt = efi_netobj_from_snp(this); + switch (this->mode->state) { case EFI_NETWORK_STOPPED: ret = EFI_NOT_STARTED; @@ -679,16 +720,16 @@ static efi_status_t EFIAPI efi_net_receive break; } - if (!rx_packet_num) { + if (!nt->rx_packet_num) { ret = EFI_NOT_READY; goto out; } /* Fill export parameters */ - eth_hdr = (struct ethernet_hdr *)receive_buffer[rx_packet_idx]; + eth_hdr = (struct ethernet_hdr *)nt->receive_buffer[nt->rx_packet_idx]; protlen = ntohs(eth_hdr->et_protlen); if (protlen == 0x8100) { hdr_size += 4; - protlen = ntohs(*(u16 *)&receive_buffer[rx_packet_idx][hdr_size - 2]); + protlen = ntohs(*(u16 *)&nt->receive_buffer[nt->rx_packet_idx][hdr_size - 2]); } if (header_size) *header_size = hdr_size; @@ -698,20 +739,20 @@ static efi_status_t EFIAPI efi_net_receive memcpy(src_addr, eth_hdr->et_src, ARP_HLEN); if (protocol) *protocol = protlen; - if (*buffer_size < receive_lengths[rx_packet_idx]) { + if (*buffer_size < nt->receive_lengths[nt->rx_packet_idx]) { /* Packet doesn't fit, try again with bigger buffer */ - *buffer_size = receive_lengths[rx_packet_idx]; + *buffer_size = nt->receive_lengths[nt->rx_packet_idx]; ret = EFI_BUFFER_TOO_SMALL; goto out; } /* Copy packet */ - memcpy(buffer, receive_buffer[rx_packet_idx], - receive_lengths[rx_packet_idx]); - *buffer_size = receive_lengths[rx_packet_idx]; - rx_packet_idx = (rx_packet_idx + 1) % ETH_PACKETS_BATCH_RECV; - rx_packet_num--; - if (rx_packet_num) - wait_for_packet->is_signaled = true; + memcpy(buffer, nt->receive_buffer[nt->rx_packet_idx], + nt->receive_lengths[nt->rx_packet_idx]); + *buffer_size = nt->receive_lengths[nt->rx_packet_idx]; + nt->rx_packet_idx = (nt->rx_packet_idx + 1) % ETH_PACKETS_BATCH_RECV; + nt->rx_packet_num--; + if (nt->rx_packet_num) + nt->wait_for_packet->is_signaled = true; else this->int_status &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT; out: @@ -730,6 +771,7 @@ void efi_net_set_dhcp_ack(void *pkt, int len) { struct efi_pxe_packet **dhcp_ack; struct udevice *dev; + int i; dhcp_ack = &dhcp_cache[next_dhcp_entry].dhcp_ack; @@ -750,6 +792,12 @@ void efi_net_set_dhcp_ack(void *pkt, int len) dhcp_cache[next_dhcp_entry].dev = dev; next_dhcp_entry++; next_dhcp_entry %= MAX_NUM_DHCP_ENTRIES; + + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && net_objs[i]->dev == dev) { + net_objs[i]->pxe_mode.dhcp_ack = **dhcp_ack; + } + } } /** @@ -763,6 +811,11 @@ void efi_net_set_dhcp_ack(void *pkt, int len) static void efi_net_push(void *pkt, int len) { int rx_packet_next; + struct efi_net_obj *nt; + + nt = net_objs[curr_efi_net_obj]; + if (!nt) + return; /* Check that we at least received an Ethernet header */ if (len < sizeof(struct ethernet_hdr)) @@ -773,15 +826,15 @@ static void efi_net_push(void *pkt, int len) return; /* Can't store more than pre-alloced buffer */ - if (rx_packet_num >= ETH_PACKETS_BATCH_RECV) + if (nt->rx_packet_num >= ETH_PACKETS_BATCH_RECV) return; - rx_packet_next = (rx_packet_idx + rx_packet_num) % + rx_packet_next = (nt->rx_packet_idx + nt->rx_packet_num) % ETH_PACKETS_BATCH_RECV; - memcpy(receive_buffer[rx_packet_next], pkt, len); - receive_lengths[rx_packet_next] = len; + memcpy(nt->receive_buffer[rx_packet_next], pkt, len); + nt->receive_lengths[rx_packet_next] = len; - rx_packet_num++; + nt->rx_packet_num++; } /** @@ -796,6 +849,7 @@ static void EFIAPI efi_network_timer_notify(struct efi_event *event, void *context) { struct efi_simple_network *this = (struct efi_simple_network *)context; + struct efi_net_obj *nt; EFI_ENTRY("%p, %p", event, context); @@ -806,16 +860,19 @@ static void EFIAPI efi_network_timer_notify(struct efi_event *event, if (!this || this->mode->state != EFI_NETWORK_INITIALIZED) goto out; - if (!rx_packet_num) { - eth_set_dev(netobj->dev); + nt = efi_netobj_from_snp(this); + curr_efi_net_obj = nt->efi_seq_num; + + if (!nt->rx_packet_num) { + eth_set_dev(nt->dev); env_set("ethact", eth_get_name()); push_packet = efi_net_push; eth_rx(); push_packet = NULL; - if (rx_packet_num) { + if (nt->rx_packet_num) { this->int_status |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT; - wait_for_packet->is_signaled = true; + nt->wait_for_packet->is_signaled = true; } } out: @@ -1011,9 +1068,19 @@ static struct efi_device_path *efi_netobj_get_dp(struct efi_net_obj *netobj) efi_status_t efi_net_do_start(struct udevice *dev) { efi_status_t r = EFI_SUCCESS; + struct efi_net_obj *netobj; struct efi_device_path *net_dp; + int i; + + netobj = NULL; + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && net_objs[i]->dev == dev) { + netobj = net_objs[i]; + break; + } + } - if (dev != netobj->dev ) + if (!efi_netobj_is_active(netobj)) return r; efi_net_dp_from_dev(&net_dp, netobj->dev, true); @@ -1056,6 +1123,11 @@ set_addr: efi_status_t efi_net_register(struct udevice *dev) { efi_status_t r; + int seq_num; + struct efi_net_obj *netobj; + void *transmit_buffer; + uchar **receive_buffer; + size_t *receive_lengths; int i, j; if (!dev) { @@ -1063,6 +1135,23 @@ efi_status_t efi_net_register(struct udevice *dev) return EFI_SUCCESS; } + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && net_objs[i]->dev == dev) { + // Do not register duplicate devices + return EFI_SUCCESS; + } + } + + seq_num = -1; + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (!net_objs[i]) { + seq_num = i; + break; + } + } + if (seq_num < 0) + return EFI_OUT_OF_RESOURCES; + /* We only expose the "active" network device, so one is enough */ netobj = calloc(1, sizeof(*netobj)); if (!netobj) @@ -1075,6 +1164,7 @@ efi_status_t efi_net_register(struct udevice *dev) if (!transmit_buffer) goto out_of_resources; transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, PKTALIGN); + netobj->transmit_buffer = transmit_buffer; /* Allocate a number of receive buffers */ receive_buffer = calloc(ETH_PACKETS_BATCH_RECV, @@ -1086,11 +1176,13 @@ efi_status_t efi_net_register(struct udevice *dev) if (!receive_buffer[i]) goto out_of_resources; } + netobj->receive_buffer = receive_buffer; receive_lengths = calloc(ETH_PACKETS_BATCH_RECV, sizeof(*receive_lengths)); if (!receive_lengths) goto out_of_resources; + netobj->receive_lengths = receive_lengths; /* Hook net up to the device list */ efi_add_handle(&netobj->header); @@ -1162,12 +1254,11 @@ efi_status_t efi_net_register(struct udevice *dev) */ r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_network_timer_notify, NULL, NULL, - &wait_for_packet); + &netobj->wait_for_packet); if (r != EFI_SUCCESS) { printf("ERROR: Failed to register network event\n"); return r; } - netobj->net.wait_for_packet = wait_for_packet; /* * Create a timer event. @@ -1179,13 +1270,13 @@ efi_status_t efi_net_register(struct udevice *dev) */ r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, efi_network_timer_notify, &netobj->net, NULL, - &network_timer_event); + &netobj->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 cycle */ - r = efi_set_timer(network_timer_event, EFI_TIMER_PERIODIC, 0); + r = efi_set_timer(netobj->network_timer_event, EFI_TIMER_PERIODIC, 0); if (r != EFI_SUCCESS) { printf("ERROR: Failed to set network timer\n"); return r; @@ -1202,6 +1293,8 @@ efi_status_t efi_net_register(struct udevice *dev) if (r != EFI_SUCCESS) goto failure_to_add_protocol; #endif + netobj->efi_seq_num = seq_num; + net_objs[seq_num] = netobj; return EFI_SUCCESS; failure_to_add_protocol: printf("ERROR: Failure to add protocol\n"); @@ -1233,8 +1326,10 @@ out_of_resources: efi_status_t efi_net_new_dp(const char *dev, const char *server, struct udevice *udev) { efi_status_t ret; + struct efi_net_obj *netobj; struct efi_device_path *old_net_dp, *new_net_dp; struct efi_device_path **dp; + int i; dp = &dp_cache[next_dp_entry].net_dp; @@ -1256,7 +1351,14 @@ efi_status_t efi_net_new_dp(const char *dev, const char *server, struct udevice // Free the old cache entry efi_free_pool(old_net_dp); - if (!netobj || netobj->dev != udev) + netobj = NULL; + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && net_objs[i]->dev == udev) { + netobj = net_objs[i]; + break; + } + } + if (!netobj) return EFI_SUCCESS; new_net_dp = efi_dp_dup(*dp); @@ -1290,10 +1392,13 @@ void efi_net_dp_from_dev(struct efi_device_path **dp, struct udevice *udev, bool if (cache_only) goto cache; - if (netobj && netobj->dev == udev) { - *dp = efi_netobj_get_dp(netobj); - if (*dp) - return; + // If a netobj matches: + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && net_objs[i]->dev == udev) { + *dp = efi_netobj_get_dp(net_objs[i]); + if (*dp) + return; + } } cache: // Search in the cache @@ -1527,27 +1632,40 @@ void efi_net_parse_headers(ulong *num_headers, struct http_header *headers) * @status_code: HTTP status code * @file_size: file size in bytes * @headers_buffer: headers buffer + * @parent: service binding protocol * Return: status code */ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buffer, - u32 *status_code, ulong *file_size, char *headers_buffer) + u32 *status_code, ulong *file_size, char *headers_buffer, + struct efi_service_binding_protocol *parent) { efi_status_t ret = EFI_SUCCESS; int wget_ret; static bool last_head; + struct udevice *dev; + int i; - if (!buffer || !file_size) + if (!buffer || !file_size || !parent) return EFI_ABORTED; efi_wget_info.method = (enum wget_http_method)method; efi_wget_info.headers = headers_buffer; + // Set corresponding udevice + dev = NULL; + for (i = 0; i < MAX_EFI_NET_OBJS; i++) { + if (net_objs[i] && &net_objs[i]->http_service_binding == parent) + dev = net_objs[i]->dev; + } + if (!dev) + return EFI_ABORTED; + switch (method) { case HTTP_METHOD_GET: ret = efi_net_set_buffer(buffer, last_head ? (size_t)efi_wget_info.hdr_cont_len : 0); if (ret != EFI_SUCCESS) goto out; - eth_set_dev(netobj->dev); + eth_set_dev(dev); env_set("ethact", eth_get_name()); wget_ret = wget_request((ulong)*buffer, url, &efi_wget_info); if ((ulong)efi_wget_info.hdr_cont_len > efi_wget_info.buffer_size) { @@ -1556,7 +1674,7 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf ret = efi_net_set_buffer(buffer, (size_t)efi_wget_info.hdr_cont_len); if (ret != EFI_SUCCESS) goto out; - eth_set_dev(netobj->dev); + eth_set_dev(dev); env_set("ethact", eth_get_name()); if (wget_request((ulong)*buffer, url, &efi_wget_info)) { efi_free_pool(*buffer); @@ -1577,7 +1695,7 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf ret = efi_net_set_buffer(buffer, 0); if (ret != EFI_SUCCESS) goto out; - eth_set_dev(netobj->dev); + eth_set_dev(dev); env_set("ethact", eth_get_name()); wget_request((ulong)*buffer, url, &efi_wget_info); *file_size = 0; -- 2.45.2