diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/eth.c | 28 | ||||
-rw-r--r-- | net/ifup.c | 103 |
2 files changed, 102 insertions, 29 deletions
@@ -176,13 +176,29 @@ int eth_complete(struct string_list *sl, char *instr) } #endif +int eth_carrier_poll_once(struct eth_device *edev) +{ + int ret; + + if (!IS_ENABLED(CONFIG_PHYLIB)) + return 0; + + if (!edev->phydev) + return 0; + + ret = phy_update_status(edev->phydev); + if (ret) + return ret; + + edev->last_link_check = get_time_ns(); + return edev->phydev->link ? 0 : -ENETDOWN; +} + /* * Check for link if we haven't done so for longer. */ static int eth_carrier_check(struct eth_device *edev, bool may_wait) { - int ret; - if (!IS_ENABLED(CONFIG_PHYLIB)) return 0; @@ -190,12 +206,8 @@ static int eth_carrier_check(struct eth_device *edev, bool may_wait) return 0; if (!edev->last_link_check || - is_timeout(edev->last_link_check, 5 * SECOND)) { - ret = phy_update_status(edev->phydev); - if (ret) - return ret; - edev->last_link_check = get_time_ns(); - } + is_timeout(edev->last_link_check, 5 * SECOND)) + eth_carrier_poll_once(edev); if (may_wait && !edev->phydev->link) { phy_wait_aneg_done(edev->phydev); diff --git a/net/ifup.c b/net/ifup.c index e4d5374db3..c491ea03c1 100644 --- a/net/ifup.c +++ b/net/ifup.c @@ -179,6 +179,28 @@ static void set_linux_bootarg(struct eth_device *edev) } } +static int ifup_edev_conf(struct eth_device *edev, unsigned flags) +{ + int ret; + + if (edev->global_mode == ETH_MODE_DHCP) { + if (IS_ENABLED(CONFIG_NET_DHCP)) { + ret = dhcp(edev, NULL); + } else { + dev_err(&edev->dev, "DHCP support not available\n"); + ret = -ENOSYS; + } + if (ret) + return ret; + } + + set_linux_bootarg(edev); + + edev->ifup = true; + + return 0; +} + int ifup_edev(struct eth_device *edev, unsigned flags) { int ret; @@ -205,22 +227,10 @@ int ifup_edev(struct eth_device *edev, unsigned flags) if (ret) return ret; - if (edev->global_mode == ETH_MODE_DHCP) { - if (IS_ENABLED(CONFIG_NET_DHCP)) { - ret = dhcp(edev, NULL); - } else { - dev_err(&edev->dev, "DHCP support not available\n"); - ret = -ENOSYS; - } - if (ret) - return ret; - } - - set_linux_bootarg(edev); - - edev->ifup = true; + if (flags & IFUP_FLAG_SKIP_CONF) + return 1; - return 0; + return ifup_edev_conf(edev, flags); } void ifdown_edev(struct eth_device *edev) @@ -260,9 +270,54 @@ int ifdown(const char *ethname) static int net_ifup_force_detect; -int ifup_all(unsigned flags) +static bool ifup_edev_need_conf(struct eth_device *edev) +{ + return edev->active && !edev->ifup && + edev->global_mode != ETH_MODE_DISABLED; +} + +static void __ifup_all_parallel(unsigned flags) { struct eth_device *edev; + unsigned netdev_count = 0; + u64 start; + int ret; + + for_each_netdev(edev) { + ret = ifup_edev(edev, flags | IFUP_FLAG_SKIP_CONF); + if (ret == 1) + netdev_count++; + } + + start = get_time_ns(); + while (netdev_count && !is_timeout(start, PHY_AN_TIMEOUT * SECOND)) { + for_each_netdev(edev) { + if (!ifup_edev_need_conf(edev)) + continue; + + ret = eth_carrier_poll_once(edev); + if (ret) + continue; + + ifup_edev_conf(edev, flags); + if (!edev->ifup) + continue; + + netdev_count--; + } + } +} + +static void __ifup_all_sequence(unsigned flags) +{ + struct eth_device *edev; + + for_each_netdev(edev) + ifup_edev(edev, flags); +} + +int ifup_all(unsigned flags) +{ DIR *dir; struct dirent *d; @@ -285,8 +340,10 @@ int ifup_all(unsigned flags) list_empty(&netdev_list)) device_detect_all(); - for_each_netdev(edev) - ifup_edev(edev, flags); + if (flags & IFUP_FLAG_PARALLEL) + __ifup_all_parallel(flags); + else + __ifup_all_sequence(flags); return 0; } @@ -315,14 +372,17 @@ BAREBOX_MAGICVAR(global.net.ifup_force_detect, static int do_ifup(int argc, char *argv[]) { int opt; - unsigned flags = 0; + unsigned flags = IFUP_FLAG_PARALLEL; int all = 0; - while ((opt = getopt(argc, argv, "af")) > 0) { + while ((opt = getopt(argc, argv, "asf")) > 0) { switch (opt) { case 'f': flags |= IFUP_FLAG_FORCE; break; + case 's': + flags &= ~IFUP_FLAG_PARALLEL; + break; case 'a': all = 1; break; @@ -346,13 +406,14 @@ BAREBOX_CMD_HELP_TEXT("/env/network/<intf> file. See Documentation/user/networki BAREBOX_CMD_HELP_TEXT("") BAREBOX_CMD_HELP_TEXT("Options:") BAREBOX_CMD_HELP_OPT ("-a", "bring up all interfaces") +BAREBOX_CMD_HELP_OPT ("-s", "bring up interfaces in sequence, not in parallel") BAREBOX_CMD_HELP_OPT ("-f", "Force. Configure even if ip already set") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(ifup) .cmd = do_ifup, BAREBOX_CMD_DESC("bring a network interface up") - BAREBOX_CMD_OPTS("[-af] [INTF]") + BAREBOX_CMD_OPTS("[-asf] [INTF]") BAREBOX_CMD_GROUP(CMD_GRP_NET) BAREBOX_CMD_COMPLETE(eth_complete) BAREBOX_CMD_HELP(cmd_ifup_help) |