[PATCH 09/21] efi_loader: efi_net: Let efi_net_obj store pointers to efi_simple_network, efi_simple_network_mode, and the efi handle
Adriano Cordova
adrianox at gmail.com
Wed Jan 22 18:08:46 CET 2025
This way the protocol and the handle can be externally provided. This comes
in preparation to support ConnectController.
Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
---
lib/efi_loader/efi_net.c | 117 +++++++++++++++++++++++++--------------
1 file changed, 74 insertions(+), 43 deletions(-)
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 6bae5a5cd7..3e39cdf212 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -63,7 +63,7 @@ static int next_dp_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
@@ -73,10 +73,10 @@ static int next_dp_entry;
* @http_service_binding: Http service binding protocol interface
*/
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)
@@ -114,7 +114,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;
@@ -132,7 +132,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];
}
@@ -1014,21 +1014,21 @@ efi_status_t efi_netobj_set_dp(struct efi_net_obj *netobj, struct efi_device_pat
return EFI_OUT_OF_RESOURCES;
phandler = NULL;
- efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler);
+ efi_search_protocol(netobj->handle, &efi_guid_device_path, &phandler);
// If the device path protocol is not yet installed, install it
if (!phandler)
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;
@@ -1050,7 +1050,7 @@ static struct efi_device_path *efi_netobj_get_dp(struct efi_net_obj *netobj)
return NULL;
phandler = NULL;
- efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler);
+ efi_search_protocol(netobj->handle, &efi_guid_device_path, &phandler);
if (phandler && phandler->protocol_interface)
return efi_dp_dup(phandler->protocol_interface);
@@ -1151,6 +1151,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);
@@ -1183,41 +1193,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)
* 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");
@@ -1281,13 +1294,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
@@ -1384,6 +1397,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);
@@ -1432,9 +1451,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)
@@ -1445,17 +1461,32 @@ int efi_net_unregister(void *ctx, struct event *event)
return -1;
phandler = NULL;
- efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler);
+ efi_search_protocol(netobj->handle, &efi_guid_device_path, &phandler);
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.43.0
More information about the U-Boot
mailing list