Since we have phylib we have no instance which polls for a link. This means that network boot often bails out after a powercycle or phy reset. This changes the link status behaviour to: - Always check for a link if the last link test was unsuccesful - If the last check was succesful, check for a link when the last check is longer than 5 seconds ago - Try to get a link for 5 seconds. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- net/eth.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/net/eth.c b/net/eth.c index f3d7bfe..5af2d09 100644 --- a/net/eth.c +++ b/net/eth.c @@ -128,9 +128,10 @@ int eth_complete(struct string_list *sl, char *instr) /* * Check for link if we haven't done so for longer. */ -static int eth_carrier_check(int force) +static int eth_carrier_check(void) { int ret; + uint64_t s; if (!IS_ENABLED(CONFIG_PHYLIB)) return 0; @@ -138,14 +139,31 @@ static int eth_carrier_check(int force) if (!eth_current->phydev) return 0; - if (force || is_timeout(last_link_check, 5 * SECOND)) { + /* + * If we recently succesfully checked for a link just bail + * out. + */ + if (!is_timeout(last_link_check, 5 * SECOND) && + eth_current->phydev->link) + return 0; + + s = get_time_ns(); + + /* + * Poll for a link until we get one or we have a timeout. + */ + while (!is_timeout(s, 5 * SECOND)) { ret = phy_update_status(eth_current->phydev); if (ret) return ret; - last_link_check = get_time_ns(); + + if (eth_current->phydev->link) { + last_link_check = get_time_ns(); + return 0; + } } - return eth_current->phydev->link ? 0 : -ENETDOWN; + return -ENETDOWN; } /* @@ -168,7 +186,7 @@ static int eth_check_open(void) eth_current->active = 1; - return eth_carrier_check(1); + return eth_carrier_check(); } int eth_send(void *packet, int length) @@ -179,7 +197,7 @@ int eth_send(void *packet, int length) if (ret) return ret; - ret = eth_carrier_check(0); + ret = eth_carrier_check(); if (ret) return ret; @@ -196,7 +214,7 @@ int eth_rx(void) if (ret) return ret; - ret = eth_carrier_check(0); + ret = eth_carrier_check(); if (ret) return ret; -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox