U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Garrett <mjg59@srcf.ucam.org>
To: u-boot@lists.denx.de
Cc: "Matthew Garrett" <mgarrett@aurora.tech>,
	"Boon Khai Ng" <boon.khai.ng@intel.com>,
	"Caleb Connolly" <caleb.connolly@linaro.org>,
	"Christophe ROULLIER" <christophe.roullier@foss.st.com>,
	"Gabor Juhos" <j4g8y7@gmail.com>,
	"Hanyuan Zhao" <hanyuan-z@qq.com>,
	"Heinrich Schuchardt" <xypron.glpk@gmx.de>,
	"Ilias Apalodimas" <ilias.apalodimas@linaro.org>,
	"Janis Danisevskis" <jdanisevskis@aurora.tech>,
	"Jerome Forissier" <jerome.forissier@linaro.org>,
	"Joe Hershberger" <joe.hershberger@ni.com>,
	"Marek Vasut" <marex@denx.de>,
	"Neil Armstrong" <neil.armstrong@linaro.org>,
	"Philip Oberfichtner" <pro@denx.de>,
	"Ramon Fried" <rfried.dev@gmail.com>,
	"Robert Marko" <robert.marko@sartura.hr>,
	"Romain Naour" <romain.naour@smile.fr>,
	"Simon Glass" <sjg@chromium.org>, "Tom Rini" <trini@konsulko.com>,
	"Vincent Stehlé" <vincent.stehle@arm.com>
Subject: [PATCH 05/10] Add EFI network driver
Date: Sat, 23 Nov 2024 11:55:04 -0800	[thread overview]
Message-ID: <20241123195616.305687-6-mjg59@srcf.ucam.org> (raw)
In-Reply-To: <20241123195616.305687-1-mjg59@srcf.ucam.org>

From: Matthew Garrett <mgarrett@aurora.tech>

Add a driver that makes use of the UEFI Simple Network Protocol to
support network access when using the UEFI app implementation, and hook
up the app code to instantiate it for probed devices.

Signed-off-by: Matthew Garrett <mgarrett@aurora.tech>
---

 drivers/net/Kconfig    |   7 +++
 drivers/net/Makefile   |   1 +
 drivers/net/efi_net.c  | 110 +++++++++++++++++++++++++++++++++++++++++
 include/efi.h          |  12 +++++
 lib/efi/efi_app_init.c |  67 +++++++++++++++++++++++++
 5 files changed, 197 insertions(+)
 create mode 100644 drivers/net/efi_net.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 576cd2d50ad..693d00fa2e3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -333,6 +333,13 @@ config EEPRO100
 	  This driver supports Intel(R) PRO/100 82557/82559/82559ER fast
 	  ethernet family of adapters.
 
+config EFI_NET
+        bool "UEFI firmware-based networking support"
+	depends on EFI_APP
+	help
+	  This driver allows the use of UEFI-provided network interfaces
+	  as network devices within U-Boot.
+
 config ESSEDMA
 	bool "Qualcomm ESS Edma support"
 	depends on DM_ETH && ARCH_IPQ40XX
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index f5ab1f5dedf..f58c62cdb40 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_DWC_ETH_QOS_STM32) += dwc_eth_qos_stm32.o
 obj-$(CONFIG_E1000) += e1000.o
 obj-$(CONFIG_E1000_SPI) += e1000_spi.o
 obj-$(CONFIG_EEPRO100) += eepro100.o
+obj-$(CONFIG_EFI_NET) += efi_net.o
 obj-$(CONFIG_ESSEDMA) += essedma.o
 obj-$(CONFIG_ETHOC) += ethoc.o
 obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
diff --git a/drivers/net/efi_net.c b/drivers/net/efi_net.c
new file mode 100644
index 00000000000..370056040f3
--- /dev/null
+++ b/drivers/net/efi_net.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Aurora Innovation, Inc. Copyright 2022.
+ *
+ */
+
+#include <config.h>
+#include <dm.h>
+#include <efi.h>
+#include <efi_api.h>
+#include <malloc.h>
+#include <net.h>
+
+struct efi_net_priv {
+	void *buffer;
+};
+
+static int efi_net_bind(struct udevice *dev)
+{
+	struct efi_net_plat *plat = dev_get_plat(dev);
+	struct efi_net_priv *priv = dev_get_priv(dev);
+	efi_status_t status;
+
+	priv->buffer = malloc(PKTSIZE);
+
+	status = plat->snp->start(plat->snp);
+	if (status != EFI_SUCCESS)
+		return -ENOENT;
+
+	return 0;
+}
+
+static int efi_net_init(struct udevice *dev)
+{
+	struct efi_net_plat *plat = dev_get_plat(dev);
+	efi_status_t status;
+
+	status = plat->snp->initialize(plat->snp, 0, 0);
+	if (status != EFI_SUCCESS)
+		return -ENOENT;
+
+	return 0;
+}
+
+static void efi_net_halt(struct udevice *dev)
+{
+	struct efi_net_plat *plat = dev_get_plat(dev);
+
+	plat->snp->shutdown(plat->snp);
+	plat->snp->stop(plat->snp);
+}
+
+static int efi_net_send(struct udevice *dev, void *packet, int length)
+{
+	struct efi_net_plat *plat = dev_get_plat(dev);
+	efi_status_t status;
+
+	status = plat->snp->transmit(plat->snp, 0, length, packet, NULL, NULL,
+				     NULL);
+	if (status != EFI_SUCCESS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int efi_net_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct efi_net_plat *plat = dev_get_plat(dev);
+	struct efi_net_priv *priv = dev_get_priv(dev);
+	efi_status_t status;
+	size_t size = PKTSIZE;
+
+	status = plat->snp->receive(plat->snp, 0, &size, priv->buffer, NULL,
+				    NULL, NULL);
+	if (status == EFI_NOT_READY)
+		return -EAGAIN;
+	else if (status != EFI_SUCCESS)
+		return -EINVAL;
+
+	*packetp = priv->buffer;
+
+	return 0;
+}
+
+static int efi_net_read_hwaddr(struct udevice *dev)
+{
+	struct efi_net_plat *plat = dev_get_plat(dev);
+
+	memcpy(plat->eth_pdata.enetaddr,
+	       (void *)&plat->snp->mode->permanent_address, ARP_HLEN);
+
+	return 0;
+}
+
+static const struct eth_ops efi_net_ops = {
+	.start	= efi_net_init,
+	.stop	= efi_net_halt,
+	.send	= efi_net_send,
+	.recv	= efi_net_recv,
+	.read_rom_hwaddr = efi_net_read_hwaddr,
+};
+
+U_BOOT_DRIVER(efi_net) = {
+	.name	= "efi_net",
+	.id	= UCLASS_ETH,
+	.bind	= efi_net_bind,
+	.ops	= &efi_net_ops,
+	.plat_auto = sizeof(struct efi_net_plat),
+	.priv_auto = sizeof(struct efi_net_priv),
+};
diff --git a/include/efi.h b/include/efi.h
index 1d06230439f..3c4c321362f 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -16,6 +16,7 @@
 #ifndef _EFI_H
 #define _EFI_H
 
+#include <net.h>
 #include <linux/linkage.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -494,6 +495,17 @@ struct efi_media_plat {
 	struct efi_device_path *device_path;
 };
 
+/*
+ * EFI attributes of the udevice handled by efi_net driver
+ *
+ * @handle: handle of the controller on which this driver is installed
+ */
+struct efi_net_plat {
+	struct eth_pdata eth_pdata;
+	efi_handle_t handle;
+	struct efi_simple_network *snp;
+};
+
 /* Base address of the EFI image */
 extern char image_base[];
 
diff --git a/lib/efi/efi_app_init.c b/lib/efi/efi_app_init.c
index c5e4192fe06..bc09eb063a1 100644
--- a/lib/efi/efi_app_init.c
+++ b/lib/efi/efi_app_init.c
@@ -183,6 +183,70 @@ static int setup_block(void)
 	return 0;
 }
 
+/**
+ * setup_net() - Find all network devices and setup EFI devices for them
+ *
+ * Return: 0 if found, -ENOSYS if there is no boot-services table, -ENOTSUPP
+ *	if a required protocol is not supported
+ */
+static int setup_net(void)
+{
+	efi_guid_t efi_snp_guid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
+	struct efi_boot_services *boot = efi_get_boot();
+	efi_uintn_t num_handles;
+	efi_handle_t *handle;
+	int ret, i;
+
+	if (!boot)
+		return log_msg_ret("sys", -ENOSYS);
+
+	/* Find all devices which support the simple network protocol */
+	ret = boot->locate_handle_buffer(BY_PROTOCOL, &efi_snp_guid, NULL,
+				  &num_handles, &handle);
+
+	if (ret)
+		return 0;
+	log_debug("Found %d net handles:\n", (int)num_handles);
+
+	for (i = 0; i < num_handles; i++) {
+		struct efi_simple_network *snp;
+		struct efi_net_plat *plat;
+		struct udevice *dev;
+		char name[18];
+
+		ret = boot->handle_protocol(handle[i], &efi_snp_guid,
+					    (void **)&snp);
+
+		if (ret != EFI_SUCCESS) {
+			log_warning("- snp %d failed (ret=0x%x\n", i, ret);
+			continue;
+		}
+
+		plat = malloc(sizeof(*plat));
+		if (!plat) {
+			log_warning("- snp %d failed to alloc platform data", i);
+			continue;
+		}
+		plat->handle = handle[i];
+		plat->snp = snp;
+		ret = device_bind(dm_root(), DM_DRIVER_GET(efi_net), "efi_net",
+				  plat, ofnode_null(), &dev);
+		if (ret) {
+			log_warning("- bind snp %d failed (ret=0x%x)\n", i,
+				    ret);
+			continue;
+		}
+
+		snprintf(name, sizeof(name), "efi_net_%x", dev_seq(dev));
+		device_set_name(dev, name);
+
+		printf("%2d: %-12s\n", i, dev->name);
+	}
+	boot->free_pool(handle);
+
+	return 0;
+}
+
 /**
  * board_early_init_r() - Scan for UEFI devices that should be available
  *
@@ -199,6 +263,9 @@ int board_early_init_r(void)
 		ret = setup_block();
 		if (ret)
 			return ret;
+		ret = setup_net();
+		if (ret)
+			return ret;
 	}
 
 	return 0;
-- 
2.47.0


  parent reply	other threads:[~2024-11-23 21:50 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-23 19:54 [PATCH 00/10] Improve UEFI app support Matthew Garrett
2024-11-23 19:55 ` [PATCH 01/10] Add EFI handover support to bootm Matthew Garrett
2024-11-24 14:43   ` Heinrich Schuchardt
2024-11-24 19:29     ` Matthew Garrett
2024-11-24 19:51       ` Heinrich Schuchardt
2024-12-08 23:06         ` Simon Glass
2024-11-25 13:46       ` Ilias Apalodimas
2024-12-01 16:12   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` [PATCH 02/10] Add part_find command Matthew Garrett
2024-12-01 16:12   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-12-10  8:21   ` Heinrich Schuchardt
2024-12-10 16:16     ` Simon Glass
2024-11-23 19:55 ` [PATCH 03/10] Add a command to find a load address Matthew Garrett
2024-11-24 15:56   ` Tom Rini
2024-12-01 16:12   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` [PATCH 04/10] Hook up EFI env variable support in the EFI app Matthew Garrett
2024-12-01 16:12   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` Matthew Garrett [this message]
2024-12-01 16:12   ` [PATCH 05/10] Add EFI network driver Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` [PATCH 06/10] Add UEFI TPM2 driver Matthew Garrett
2024-12-01 16:12   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` [PATCH 07/10] Support separate DTB files with the UEFI app Matthew Garrett
2024-11-25 13:55   ` Ilias Apalodimas
2024-12-01 16:14   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` [PATCH 08/10] Use the correct ramdisk address Matthew Garrett
2024-12-01 16:14   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-11-23 19:55 ` [PATCH 09/10] Fix efi_bind_block Matthew Garrett
2024-11-25 13:40   ` Ilias Apalodimas
2024-12-09  2:28     ` Simon Glass
2024-12-01 16:14   ` Simon Glass
2024-12-08 15:29     ` Simon Glass
2024-12-10  8:45   ` Heinrich Schuchardt
2024-12-10 16:17     ` Simon Glass
2024-12-10 17:11       ` Tom Rini
2024-12-11 17:50         ` Janis Danisevskis
2024-12-11 17:59           ` Ilias Apalodimas
2024-12-11 20:23           ` Simon Glass
2024-12-11 22:28             ` Janis Danisevskis
2024-11-23 19:55 ` [PATCH 10/10] Add command to set an environment variable to an EFI variable Matthew Garrett
2024-11-24 14:58   ` Heinrich Schuchardt
2024-12-01 16:14     ` Simon Glass
2024-12-08 15:29       ` Simon Glass
2024-12-09  2:28     ` Simon Glass
2024-11-24 14:40 ` [PATCH 00/10] Improve UEFI app support Heinrich Schuchardt
2024-12-01 16:15 ` Simon Glass
2024-12-08 15:28   ` Simon Glass
2024-12-08 15:51     ` Tom Rini
2024-12-08 18:50       ` Tom Rini
2024-12-08 23:07       ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241123195616.305687-6-mjg59@srcf.ucam.org \
    --to=mjg59@srcf.ucam.org \
    --cc=boon.khai.ng@intel.com \
    --cc=caleb.connolly@linaro.org \
    --cc=christophe.roullier@foss.st.com \
    --cc=hanyuan-z@qq.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=j4g8y7@gmail.com \
    --cc=jdanisevskis@aurora.tech \
    --cc=jerome.forissier@linaro.org \
    --cc=joe.hershberger@ni.com \
    --cc=marex@denx.de \
    --cc=mgarrett@aurora.tech \
    --cc=neil.armstrong@linaro.org \
    --cc=pro@denx.de \
    --cc=rfried.dev@gmail.com \
    --cc=robert.marko@sartura.hr \
    --cc=romain.naour@smile.fr \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=vincent.stehle@arm.com \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox