[PATCH 31/71] bootstd: Add a hunter for ethernet

Simon Glass sjg at chromium.org
Wed Dec 7 09:50:57 CET 2022


Sometimes ethernet devices are attached to PCI. Since it is quick to scan,
add this into the ethernet hunter.

Run dhcp to establish the network connection. Drop this from the bootdev
since that is not needed now. Update a log message for clarity.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 net/eth_bootdev.c   | 64 +++++++++++++++++++++++++++++----------------
 test/boot/bootdev.c | 17 +++++++-----
 2 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index b735966d2bc..fdf48f00131 100644
--- a/net/eth_bootdev.c
+++ b/net/eth_bootdev.c
@@ -6,6 +6,8 @@
  * Written by Simon Glass <sjg at chromium.org>
  */
 
+#define LOG_CATEGORY UCLASS_BOOTSTD
+
 #include <common.h>
 #include <bootdev.h>
 #include <bootflow.h>
@@ -13,8 +15,10 @@
 #include <bootmeth.h>
 #include <distro.h>
 #include <dm.h>
+#include <init.h>
 #include <log.h>
 #include <net.h>
+#include <test/test.h>
 
 static int eth_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 			    struct bootflow *bflow)
@@ -41,30 +45,8 @@ static int eth_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 	if (!bflow->name)
 		return log_msg_ret("name", -ENOMEM);
 
-	/*
-	 * There is not a direct interface to the network stack so run
-	 * everything through the command-line interpreter for now.
-	 *
-	 * Don't bother checking the result of dhcp. It can fail with:
-	 *
-	 * DHCP client bound to address 192.168.4.50 (4 ms)
-	 * *** Warning: no boot file name; using 'C0A80432.img'
-	 * Using smsc95xx_eth device
-	 * TFTP from server 192.168.4.1; our IP address is 192.168.4.50
-	 * Filename 'C0A80432.img'.
-	 * Load address: 0x200000
-	 * Loading: *
-	 * TFTP error: 'File not found' (1)
-	 *
-	 * This is not a real failure, since we don't actually care if the
-	 * boot file exists.
-	 */
-	log_debug("running dhcp\n");
-	run_command("dhcp", 0);
-	bflow->state = BOOTFLOWST_MEDIA;
-
 	/* See distro_pxe_read_bootflow() for the standard impl of this */
-	log_debug("dhcp complete - reading bootflow with method %s\n",
+	log_debug("dhcp complete - reading bootflow with method '%s'\n",
 		  bflow->method->name);
 	ret = bootmeth_read_bootflow(bflow->method, bflow);
 	log_debug("reading bootflow returned %d\n", ret);
@@ -83,6 +65,35 @@ static int eth_bootdev_bind(struct udevice *dev)
 	return 0;
 }
 
+static int eth_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	int ret;
+
+	if (!test_eth_enabled())
+		return 0;
+
+	/* init PCI first since this is often used to provide Ehternet */
+	if (IS_ENABLED(CONFIG_PCI)) {
+		ret = pci_init();
+		if (ret)
+			log_warning("Failed to init PCI (%dE)\n", ret);
+	}
+
+	/*
+	 * Ethernet devices can also come from USB, but that is a higher
+	 * priority (BOOTDEVP_5_SCAN_SLOW) than ethernet, so it should have been
+	 * enumerated already. If something like 'bootflow scan dhcp' is used
+	 * then the user will need to run 'usb start' first.
+	 */
+	if (IS_ENABLED(CONFIG_CMD_DHCP)) {
+		ret = dhcp_run(0, NULL, false);
+		if (ret)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 struct bootdev_ops eth_bootdev_ops = {
 	.get_bootflow	= eth_get_bootflow,
 };
@@ -99,3 +110,10 @@ U_BOOT_DRIVER(eth_bootdev) = {
 	.bind		= eth_bootdev_bind,
 	.of_match	= eth_bootdev_ids,
 };
+
+BOOTDEV_HUNTER(eth_bootdev_hunt) = {
+	.prio		= BOOTDEVP_4_NET_BASE,
+	.uclass		= UCLASS_ETH,
+	.hunt		= eth_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(eth_bootdev),
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 78cb0ac628a..32a31c44609 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -238,9 +238,10 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	bootdev_list_hunters(std);
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("  50        ethernet         eth_bootdev");
 	ut_assert_nextline("  10        mmc              mmc_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 2)");
+	ut_assert_nextline("(total hunters: 3)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -248,8 +249,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb at 1: scanning bus usb at 1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is second in the list, so bit 1 */
-	ut_asserteq(BIT(1), std->hunters_used);
+	/* USB is third in the list, so bit 2 */
+	ut_asserteq(BIT(2), std->hunters_used);
 
 	return 0;
 }
@@ -269,11 +270,14 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 2)");
+	ut_assert_skip_to_line("(total hunters: 3)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
+	sandbox_set_eth_enable(false);
+
 	ut_assertok(run_command("bootdev hunt", 0));
+	ut_assert_nextline("Hunting with: ethernet");
 	ut_assert_nextline("Hunting with: mmc");
 	ut_assert_nextline("Hunting with: usb");
 	ut_assert_nextline(
@@ -284,13 +288,14 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
 	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
 
-	ut_assert_nextline("(total hunters: 2)");
+	ut_assert_nextline("(total hunters: 3)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(1, 0), std->hunters_used);
+	ut_asserteq(GENMASK(2, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.rc0.267.gcb52ba06e7-goog



More information about the U-Boot mailing list