Support setting the device path with efi_dp_from_eth, efi_dp_from_ipv4,
and efi_dp_from_http to an ethernet device other than the current
ethernet udevice. Calling eth_dp_from_eth with eth_get_dev() as the
argument recovers the pevious functionality.

Signed-off-by: Adriano Cordova <adriano.cord...@canonical.com>
---
 include/efi_loader.h             | 10 +++++-----
 lib/efi_loader/efi_bootbin.c     |  3 ++-
 lib/efi_loader/efi_device_path.c | 21 ++++++++++++---------
 lib/efi_loader/efi_net.c         | 24 ++++++++++++++----------
 4 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index 97152bbb6a..8be52e2766 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -128,9 +128,9 @@ static inline void efi_set_bootdev(const char *dev, const 
char *devnr,
 
 #if CONFIG_IS_ENABLED(NETDEVICES) && CONFIG_IS_ENABLED(EFI_LOADER)
 /* Call this to update the current device path of the efi net device */
-efi_status_t efi_net_set_dp(const char *dev, const char *server);
+efi_status_t efi_net_set_dp(const char *dev, const char *server, struct 
udevice *udev);
 /* Call this to get the current device path of the efi net device */
-void efi_net_get_dp(struct efi_device_path **dp);
+void efi_net_get_dp(struct efi_device_path **dp, struct udevice *udev);
 void efi_net_get_addr(struct efi_ipv4_address *ip,
                      struct efi_ipv4_address *mask,
                      struct efi_ipv4_address *gw);
@@ -150,7 +150,7 @@ struct http_header {
 
 void efi_net_parse_headers(ulong *num_headers, struct http_header *headers);
 #else
-static inline void efi_net_get_dp(struct efi_device_path **dp) { }
+static inline void efi_net_get_dp(struct efi_device_path **dp, struct udevice 
*udev) { }
 static inline void efi_net_get_addr(struct efi_ipv4_address *ip,
                                     struct efi_ipv4_address *mask,
                                     struct efi_ipv4_address *gw) { }
@@ -918,8 +918,8 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc 
*desc, int part);
 struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
 struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
                                         const char *path);
-struct efi_device_path *efi_dp_from_eth(void);
-struct efi_device_path *efi_dp_from_http(const char *server);
+struct efi_device_path *efi_dp_from_eth(struct udevice *dev);
+struct efi_device_path *efi_dp_from_http(const char *server, struct udevice 
*dev);
 struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
                                        uint64_t start_address,
                                        size_t size);
diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c
index b677bbc312..b6b40c030f 100644
--- a/lib/efi_loader/efi_bootbin.c
+++ b/lib/efi_loader/efi_bootbin.c
@@ -13,6 +13,7 @@
 #include <image.h>
 #include <log.h>
 #include <malloc.h>
+#include <net.h>
 
 static struct efi_device_path *bootefi_image_path;
 static struct efi_device_path *bootefi_device_path;
@@ -95,7 +96,7 @@ void efi_set_bootdev(const char *dev, const char *devnr, 
const char *path,
 
 #if IS_ENABLED(CONFIG_NETDEVICES)
        if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) {
-               ret = efi_net_set_dp(dev, devnr);
+               ret = efi_net_set_dp(dev, devnr, eth_get_dev());
                if (ret != EFI_SUCCESS)
                        goto error;
        }
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index c0633a736b..4a5d50fdf5 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -954,20 +954,20 @@ struct efi_device_path *efi_dp_from_uart(void)
        return buf;
 }
 
-struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
+struct efi_device_path __maybe_unused *efi_dp_from_eth(struct udevice *dev)
 {
        void *buf, *start;
        unsigned dpsize = 0;
 
-       assert(eth_get_dev());
+       assert(dev);
 
-       dpsize += dp_size(eth_get_dev());
+       dpsize += dp_size(dev);
 
        start = buf = efi_alloc(dpsize + sizeof(END));
        if (!buf)
                return NULL;
 
-       buf = dp_fill(buf, eth_get_dev());
+       buf = dp_fill(buf, dev);
 
        *((struct efi_device_path *)buf) = END;
 
@@ -984,11 +984,13 @@ struct efi_device_path __maybe_unused 
*efi_dp_from_eth(void)
  * @ip:                IPv4 local address
  * @mask:      network mask
  * @srv:       IPv4 remote/server address
+ * @dev:       net udevice
  * Return:     pointer to device path, NULL on error
  */
 static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
                                         struct efi_ipv4_address *mask,
-                                        struct efi_ipv4_address *srv)
+                                        struct efi_ipv4_address *srv,
+                                        struct udevice *dev)
 {
        struct efi_device_path *dp1, *dp2, *pos;
        struct {
@@ -1010,7 +1012,7 @@ static struct efi_device_path *efi_dp_from_ipv4(struct 
efi_ipv4_address *ip,
        pos = &dp.end;
        memcpy(pos, &END, sizeof(END));
 
-       dp1 = efi_dp_from_eth();
+       dp1 = efi_dp_from_eth(dev);
        if (!dp1)
                return NULL;
 
@@ -1029,9 +1031,10 @@ static struct efi_device_path *efi_dp_from_ipv4(struct 
efi_ipv4_address *ip,
  * and an END node.
  *
  * @server:    URI of remote server
+ * @dev:       net udevice
  * Return:     pointer to HTTP device path, NULL on error
  */
-struct efi_device_path *efi_dp_from_http(const char *server)
+struct efi_device_path *efi_dp_from_http(const char *server, struct udevice 
*dev)
 {
        struct efi_device_path *dp1, *dp2;
        struct efi_device_path_uri *uridp;
@@ -1047,7 +1050,7 @@ struct efi_device_path *efi_dp_from_http(const char 
*server)
 
        efi_net_get_addr(&ip, &mask, NULL);
 
-       dp1 = efi_dp_from_ipv4(&ip, &mask, NULL);
+       dp1 = efi_dp_from_ipv4(&ip, &mask, NULL, dev);
        if (!dp1)
                return NULL;
 
@@ -1186,7 +1189,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char 
*devnr,
                                     (uintptr_t)image_addr, image_size);
        } else if (IS_ENABLED(CONFIG_NETDEVICES) &&
                   (!strcmp(dev, "Net") || !strcmp(dev, "Http"))) {
-               efi_net_get_dp(&dp);
+               efi_net_get_dp(&dp, eth_get_dev());
        } else if (!strcmp(dev, "Uart")) {
                dp = efi_dp_from_uart();
        } else {
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index f0cf317d4f..a399f6f593 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -949,10 +949,12 @@ efi_status_t efi_net_register(void)
                             &netobj->net);
        if (r != EFI_SUCCESS)
                goto failure_to_add_protocol;
-       if (!net_dp)
-               efi_net_set_dp("Net", NULL);
-       r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
-                            net_dp);
+
+       if (net_dp)
+               r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
+                                    net_dp);
+       else
+               r = efi_net_set_dp("Net", NULL, eth_get_dev());
        if (r != EFI_SUCCESS)
                goto failure_to_add_protocol;
        r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid,
@@ -1068,17 +1070,18 @@ out_of_resources:
  *
  * @dev:       dev to set the device path from
  * @server:    remote server address
+ * @udev:      net udevice
  * Return:     status code
  */
-efi_status_t efi_net_set_dp(const char *dev, const char *server)
+efi_status_t efi_net_set_dp(const char *dev, const char *server, struct 
udevice *udev)
 {
        efi_free_pool(net_dp);
 
        net_dp = NULL;
        if (!strcmp(dev, "Net"))
-               net_dp = efi_dp_from_eth();
+               net_dp = efi_dp_from_eth(udev);
        else if (!strcmp(dev, "Http"))
-               net_dp = efi_dp_from_http(server);
+               net_dp = efi_dp_from_http(server, udev);
 
        if (!net_dp)
                return EFI_OUT_OF_RESOURCES;
@@ -1091,14 +1094,15 @@ efi_status_t efi_net_set_dp(const char *dev, const char 
*server)
  *
  * Produce a copy of the current device path
  *
- * @dp:                copy of the current device path, or NULL on error
+ * @dp:                copy of the current device path
+ * @udev:      net udevice
  */
-void efi_net_get_dp(struct efi_device_path **dp)
+void efi_net_get_dp(struct efi_device_path **dp, struct udevice *udev)
 {
        if (!dp)
                return;
        if (!net_dp)
-               efi_net_set_dp("Net", NULL);
+               efi_net_set_dp("Net", NULL, udev);
        if (net_dp)
                *dp = efi_dp_dup(net_dp);
 }
-- 
2.43.0

Reply via email to