This way the protocol and the handle can be externally provided. This comes
in preparation to support ConnectController.

Signed-off-by: Adriano Cordova <adriano.cord...@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

Reply via email to