summaryrefslogtreecommitdiff
path: root/net/eth_bootdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/eth_bootdev.c')
-rw-r--r--net/eth_bootdev.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index b735966d2bc..13e5fcd3bdf 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)
@@ -23,7 +27,7 @@ static int eth_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
int ret;
/* Must be an Ethernet device */
- ret = bootflow_iter_uses_network(iter);
+ ret = bootflow_iter_check_net(iter);
if (ret)
return log_msg_ret("net", ret);
@@ -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);
@@ -78,7 +60,36 @@ static int eth_bootdev_bind(struct udevice *dev)
{
struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
- ucp->prio = BOOTDEVP_4_NET_BASE;
+ ucp->prio = BOOTDEVP_6_NET_BASE;
+
+ 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;
}
@@ -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_6_NET_BASE,
+ .uclass = UCLASS_ETH,
+ .hunt = eth_bootdev_hunt,
+ .drv = DM_DRIVER_REF(eth_bootdev),
+};