bootstd: Add a hunter for ethernet

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@chromium.org>
diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index b735966..fdf48f0 100644
--- a/net/eth_bootdev.c
+++ b/net/eth_bootdev.c
@@ -6,6 +6,8 @@
  * Written by Simon Glass <sjg@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 @@
 	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 @@
 	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 @@
 	.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 78cb0ac..32a31c4 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -238,9 +238,10 @@
 	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 @@
 		"Bus usb@1: scanning bus usb@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 @@
 	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 @@
 	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;
 }