[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