This way the protocol and the handle can be externally provided. This comes in preparation to support ConnectController.
Signed-off-by: Adriano Cordova <[email protected]> --- lib/efi_loader/efi_net.c | 119 ++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 44 deletions(-) diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index d84fa6c2bc6..a40d319a27f 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -67,7 +67,7 @@ static int next_dhcp_entry; /** * struct efi_net_obj - EFI object representing a network interface * - * @header: EFI object header + * @handle: EFI object handle * @dev: net udevice * @net: simple network protocol interface * @net_mode: status of the network interface @@ -86,10 +86,10 @@ static int next_dhcp_entry; * @efi_seq_num: sequence number of the EFI net object. */ struct efi_net_obj { - struct efi_object header; + efi_handle_t handle; struct udevice *dev; - struct efi_simple_network net; - struct efi_simple_network_mode net_mode; + struct efi_simple_network *net; + struct efi_simple_network_mode *net_mode; struct efi_pxe_base_code_protocol pxe; struct efi_pxe_mode pxe_mode; #if IS_ENABLED(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) @@ -120,7 +120,7 @@ static struct efi_net_obj *net_objs[MAX_EFI_NET_OBJS]; */ static bool efi_netobj_is_active(struct efi_net_obj *netobj) { - if (!netobj || !efi_search_obj(&netobj->header)) + if (!netobj || !efi_search_obj(netobj->handle)) return false; return true; @@ -138,7 +138,7 @@ 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) { + if (net_objs[i] && net_objs[i]->net == snp) { // Do not register duplicate devices return net_objs[i]; } @@ -1020,7 +1020,7 @@ efi_status_t efi_netobj_set_dp(struct efi_net_obj *netobj, struct efi_device_pat return EFI_OUT_OF_RESOURCES; phandler = NULL; - ret = efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler); + ret = efi_search_protocol(netobj->handle, &efi_guid_device_path, &phandler); if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND) return ret; @@ -1029,14 +1029,14 @@ efi_status_t efi_netobj_set_dp(struct efi_net_obj *netobj, struct efi_device_pat goto add; // If it is already installed, try to update it - ret = efi_reinstall_protocol_interface(&netobj->header, &efi_guid_device_path, + ret = efi_reinstall_protocol_interface(netobj->handle, &efi_guid_device_path, phandler->protocol_interface, new_net_dp); if (ret != EFI_SUCCESS) return ret; return EFI_SUCCESS; add: - ret = efi_add_protocol(&netobj->header, &efi_guid_device_path, + ret = efi_add_protocol(netobj->handle, &efi_guid_device_path, new_net_dp); if (ret != EFI_SUCCESS) return ret; @@ -1059,7 +1059,7 @@ static struct efi_device_path *efi_netobj_get_dp(struct efi_net_obj *netobj) return NULL; phandler = NULL; - r = efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler); + r = efi_search_protocol(netobj->handle, &efi_guid_device_path, &phandler); if (r != EFI_SUCCESS && r != EFI_NOT_FOUND) return NULL; @@ -1161,6 +1161,16 @@ static int efi_netobj_init(struct efi_net_obj *netobj) return 0; } + if (!netobj->net) + netobj->net = calloc(1, sizeof(*netobj->net)); + if (!netobj->net) + goto out_of_resources; + + if (!netobj->net_mode) + netobj->net_mode = calloc(1, sizeof(*netobj->net_mode)); + if (!netobj->net_mode) + goto out_of_resources; + /* Allocate an aligned transmit buffer */ if (!netobj->transmit_buffer) { transmit_buffer = calloc(1, PKTSIZE_ALIGN + PKTALIGN); @@ -1193,41 +1203,44 @@ static int efi_netobj_init(struct efi_net_obj *netobj) } /* Hook net up to the device list */ - efi_add_handle(&netobj->header); + efi_add_handle(netobj->handle); + if (efi_link_dev(netobj->handle, dev)) + goto out_of_resources; /* Fill in object data */ - r = efi_add_protocol(&netobj->header, &efi_net_guid, - &netobj->net); + r = efi_add_protocol(netobj->handle, &efi_net_guid, + netobj->net); if (r != EFI_SUCCESS) goto failure_to_add_protocol; - r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid, + r = efi_add_protocol(netobj->handle, &efi_pxe_base_code_protocol_guid, &netobj->pxe); if (r != EFI_SUCCESS) goto failure_to_add_protocol; - netobj->net.revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION; - netobj->net.start = efi_net_start; - netobj->net.stop = efi_net_stop; - netobj->net.initialize = efi_net_initialize; - netobj->net.reset = efi_net_reset; - netobj->net.shutdown = efi_net_shutdown; - netobj->net.receive_filters = efi_net_receive_filters; - netobj->net.station_address = efi_net_station_address; - netobj->net.statistics = efi_net_statistics; - netobj->net.mcastiptomac = efi_net_mcastiptomac; - netobj->net.nvdata = efi_net_nvdata; - netobj->net.get_status = efi_net_get_status; - netobj->net.transmit = efi_net_transmit; - netobj->net.receive = efi_net_receive; - netobj->net.mode = &netobj->net_mode; - netobj->net_mode.state = EFI_NETWORK_STOPPED; + netobj->net->revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION; + netobj->net->start = efi_net_start; + netobj->net->stop = efi_net_stop; + netobj->net->initialize = efi_net_initialize; + netobj->net->reset = efi_net_reset; + netobj->net->shutdown = efi_net_shutdown; + netobj->net->receive_filters = efi_net_receive_filters; + netobj->net->station_address = efi_net_station_address; + netobj->net->statistics = efi_net_statistics; + netobj->net->mcastiptomac = efi_net_mcastiptomac; + netobj->net->nvdata = efi_net_nvdata; + netobj->net->get_status = efi_net_get_status; + netobj->net->transmit = efi_net_transmit; + netobj->net->receive = efi_net_receive; + + netobj->net->mode = netobj->net_mode; + netobj->net_mode->state = EFI_NETWORK_STOPPED; if (dev_get_plat(dev)) - memcpy(netobj->net_mode.current_address.mac_addr, + memcpy(netobj->net_mode->current_address.mac_addr, ((struct eth_pdata *)dev_get_plat(dev))->enetaddr, 6); - netobj->net_mode.hwaddr_size = ARP_HLEN; - netobj->net_mode.media_header_size = ETHER_HDR_SIZE; - netobj->net_mode.max_packet_size = PKTSIZE; - netobj->net_mode.if_type = ARP_ETHER; + netobj->net_mode->hwaddr_size = ARP_HLEN; + netobj->net_mode->media_header_size = ETHER_HDR_SIZE; + netobj->net_mode->max_packet_size = PKTSIZE; + netobj->net_mode->if_type = ARP_ETHER; netobj->pxe.revision = EFI_PXE_BASE_CODE_PROTOCOL_REVISION; netobj->pxe.start = efi_pxe_base_code_start; @@ -1267,7 +1280,7 @@ static int efi_netobj_init(struct efi_net_obj *netobj) printf("ERROR: Failed to register network event\n"); return -1; } - netobj->net.wait_for_packet = netobj->wait_for_packet; + netobj->net->wait_for_packet = netobj->wait_for_packet; /* * Create a timer event. * @@ -1277,7 +1290,7 @@ static int efi_netobj_init(struct efi_net_obj *netobj) * 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, &netobj->net, NULL, + efi_network_timer_notify, netobj->net, NULL, &netobj->network_timer_event); if (r != EFI_SUCCESS) { printf("ERROR: Failed to register network event\n"); @@ -1291,13 +1304,13 @@ static int efi_netobj_init(struct efi_net_obj *netobj) } #if IS_ENABLED(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) - r = efi_ipconfig_register(&netobj->header, &netobj->ip4_config2); + r = efi_ipconfig_register(netobj->handle, &netobj->ip4_config2); if (r != EFI_SUCCESS) goto failure_to_add_protocol; #endif #ifdef CONFIG_EFI_HTTP_PROTOCOL - r = efi_http_register(&netobj->header, &netobj->http_service_binding); + r = efi_http_register(netobj->handle, &netobj->http_service_binding); if (r != EFI_SUCCESS) goto failure_to_add_protocol; #endif @@ -1394,6 +1407,12 @@ int efi_net_register(void *ctx, struct event *event) if (!netobj) goto out_of_resources; + netobj->handle = calloc(1, sizeof(*netobj->handle)); + if (!netobj->handle) { + free(netobj); + goto out_of_resources; + } + netobj->dev = dev; netobj->efi_seq_num = seq_num; printf("efi_net registered device number %d\n", netobj->efi_seq_num); @@ -1442,9 +1461,6 @@ int efi_net_unregister(void *ctx, struct event *event) if (!netobj) return 0; - // Mark as free in the list - netobj->dev = NULL; - if (efi_netobj_is_active(netobj)) { ret = EFI_CALL(efi_close_event(netobj->wait_for_packet)); if (ret != EFI_SUCCESS) @@ -1455,19 +1471,34 @@ int efi_net_unregister(void *ctx, struct event *event) return -1; phandler = NULL; - ret = efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler); + ret = efi_search_protocol(netobj->handle, &efi_guid_device_path, &phandler); if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND) return -1; if (phandler && phandler->protocol_interface) interface = phandler->protocol_interface; - ret = efi_delete_handle(&netobj->header); + ret = efi_delete_handle(netobj->handle); if (ret != EFI_SUCCESS) return -1; efi_free_pool(interface); } + if (netobj->net) { + if (netobj->net->mode) + free(netobj->net->mode); + free(netobj->net); + } + + if (netobj->net_mode) + free(netobj->net_mode); + + // Mark as free in the list + netobj->handle = NULL; + netobj->dev = NULL; + netobj->net = NULL; + netobj->net_mode = NULL; + return 0; } -- 2.48.1

