Hi, On 1/6/25 20:09, E Shattow wrote: > > > On 1/6/25 07:43, Jerome Forissier wrote: >> >> >> On 1/4/25 04:05, E Shattow wrote: >>> On 1/3/25 09:58, E Shattow wrote: >>>> >>>> >>>> On 1/3/25 02:03, Jerome Forissier wrote: >>>>> >>>>> >>>>> On 1/3/25 02:52, E Shattow wrote: >>>>>> >>>>>> >>>>>> On 1/2/25 17:40, Tom Rini wrote: >>>>>>> On Thu, Jan 02, 2025 at 05:34:57PM -0800, E Shattow wrote: >>>>>>> >>>>>>>> Tom sorry about sending this reply twice, struggle here is with >>>>>>>> Thunderbird >>>>>>>> mail UI sometimes hiding "Reply All" and it missed the mail list first >>>>>>>> time >>>>>>>> around. >>>>>>> >>>>>>> No problem. >>>>>>> >>>>>>>> On 1/2/25 14:47, Tom Rini wrote: >>>>>>>>> On Thu, Jan 02, 2025 at 02:26:06PM -0800, E Shattow wrote: >>>>>>>>>> Problem: 'dhcp' must be ran twice when the network cable is plugged >>>>>>>>>> into a >>>>>>>>>> port other than the first network port. >>>>>>>>>> >>>>>>>>>> Network cable plugged into bottom (first) Ethernet port: >>>>>>>>>> 1. Power on >>>>>>>>>> 2. StarFive # dhcp >>>>>>>>>> >>>>>>>>>> ethernet@16030000 Waiting for PHY auto negotiation to >>>>>>>>>> complete....... done >>>>>>>>>> DHCP client bound to address 192.168.2.51 (3678 ms) >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Network cable plugged into top (second) Ethernet port: >>>>>>>>>> 1. Power on >>>>>>>>>> 2. StarFive # dhcp >>>>>>>>>> ethernet@16030000 Waiting for PHY auto negotiation to >>>>>>>>>> complete......... >>>>>>>>>> TIMEOUT ! >>>>>>>>>> phy_startup() failed: -110 >>>>>>>>>> FAILED: -110 >>>>>>>>>> ethernet@16040000 Waiting for PHY auto negotiation to complete...... >>>>>>>>>> done >>>>>>>>>> ethernet@16030000 Waiting for PHY auto negotiation to >>>>>>>>>> complete......... >>>>>>>>>> TIMEOUT ! >>>>>>>>>> phy_startup() failed: -110 >>>>>>>>>> FAILED: -110 >>>>>>>>>> Could not start ethernet@16030000 >>>>>>>>>> 3. StarFive # dhcp >>>>>>>>>> DHCP client bound to address 192.168.2.77 (31 ms) >>>>>>>>> >>>>>>>>> What happens when you set ethact to 1 first? >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> '1' literal does not seem to do something so I guess it is meant the >>>>>>>> id of >>>>>>>> the first ethernet interface: >>>>>>> >>>>>>> Yes, I misspoke sorry. >>>>>>> >>>>>>>> From power-on: >>>>>>>> >>>>>>>> ... >>>>>>>> starfive_7110_pcie pcie@2b000000: Starfive PCIe bus probed. >>>>>>>> starfive_7110_pcie pcie@2c000000: Starfive PCIe bus probed. >>>>>>>> In: serial@10000000 >>>>>>>> Out: serial@10000000 >>>>>>>> Err: serial@10000000 >>>>>>>> Net: eth0: ethernet@16030000, eth1: ethernet@16040000 >>>>>>>> starting USB... >>>>>>>> No USB controllers found >>>>>>>> Working FDT set to ff700a10 >>>>>>>> StarFive # env print ethact >>>>>>>> ## Error: "ethact" not defined >>>>>>>> StarFive # env set ethact 1 >>>>>>>> StarFive # dhcp >>>>>>>> ethernet@16030000 Waiting for PHY auto negotiation to complete......... >>>>>>>> TIMEOUT ! >>>>>>>> phy_startup() failed: -110 >>>>>>>> FAILED: -110 >>>>>>>> ethernet@16040000 Waiting for PHY auto negotiation to complete...... >>>>>>>> done >>>>>>>> EQOS_DMA_MODE_SWR stuck >>>>>>>> FAILED: -110 >>>>>>>> Could not start ethernet@16030000 >>>>>>>> >>>>>>>> Again, from power-on: >>>>>>>> >>>>>>>> starfive_7110_pcie pcie@2b000000: Starfive PCIe bus probed. >>>>>>>> starfive_7110_pcie pcie@2c000000: Starfive PCIe bus probed. >>>>>>>> In: serial@10000000 >>>>>>>> Out: serial@10000000 >>>>>>>> Err: serial@10000000 >>>>>>>> Net: eth0: ethernet@16030000, eth1: ethernet@16040000 >>>>>>>> starting USB... >>>>>>>> No USB controllers found >>>>>>>> Working FDT set to ff700a10 >>>>>>>> StarFive # env print ethact >>>>>>>> ## Error: "ethact" not defined >>>>>>>> StarFive # env set ethact ethernet@16040000 >>>>>>>> StarFive # dhcp >>>>>>>> ethernet@16040000 Waiting for PHY auto negotiation to complete...... >>>>>>>> done >>>>>>>> DHCP client bound to address 192.168.2.77 (149 ms) >>>>>>> >>>>>>> So then yes, the second interface works when ethact is set to use that >>>>>>> directly. This is the same behavior as the legacy stack I believe. >>>>>>> >>>>>> >>>>>> Legacy stack does actually rotate and complete successfully when ethact >>>>>> environment variable does not exist and (eventually) configure the >>>>>> second interface though. Here with LwIP the procedure fails. >>>>>> >>>>>> Notice that here it starts with ethernet@16030000, then rotates to >>>>>> ethernet@16040000 unsuccessfully, and back again to ethernet@16030000 >>>>>> before (again) failing and giving up. There is a network cable plugged >>>>>> into 'ethernet@16040000' port and if we try the command again the >>>>>> environment variable ethact retained 'ethact=ethernet@16040000' from the >>>>>> failed procedure so you're right it works as it should... except that it >>>>>> totally failed to do what was expected the first time. >>>>> >>>>> That's unexpected indeed. >>>>> >>>>>> Is this exposing a problem with this board network driver and behavior >>>>>> or is it something with LwIP ? >>>>> Hard to tell at this point. One thing I know for sure is that lwIP expects >>>>> eth_set_current() (called from do_dhcp()) to actually pick a valid >>>>> interface if there is one. So it should definitely select >>>>> ethernet@16040000 >>>>> in your scenario. Adding debug prints to eth_set_current(), >>>>> eth_current_changed() etc. should help. >>>>> >>>>> Thanks, >>>> >>>> StarFive # dhcp >>>> !!! eth_set_current(): entered function >>>> !!! eth_set_current(): conditional 1 >>>> !!! eth_set_current(): conditional 2 >>>> !!! eth_set_current(): conditional 5 >>>> !!! eth_current_changed(): entered function >>>> !!! eth_current_changed(): conditional 2 >>>> !!! eth_current_changed(): conditional 3 >>>> !!! eth_current_changed(): leaving function >>>> !!! eth_set_current(): leaving function >>>> ethernet@16030000 Waiting for PHY auto negotiation to complete......... >>>> TIMEOUT ! >>>> phy_startup() failed: -110 >>>> FAILED: -110 >>>> !!! eth_current_changed(): entered function >>>> !!! eth_current_changed(): conditional 2 >>>> !!! eth_current_changed(): conditional 3 >>>> !!! eth_current_changed(): leaving function >>>> ethernet@16040000 Waiting for PHY auto negotiation to complete...... done >>>> ethernet@16030000 Waiting for PHY auto negotiation to complete......... >>>> TIMEOUT ! >>>> phy_startup() failed: -110 >>>> FAILED: -110 >>>> Could not start ethernet@16030000 >>>> StarFive # >>>> >>>> For reference the modified functions: >>>> >>>> void eth_current_changed(void) >>>> { >>>> char *act = env_get("ethact"); >>>> char *ethrotate; >>>> >>>> printf("!!! eth_current_changed(): entered function\n"); >>>> /* >>>> * The call to eth_get_dev() below has a side effect of rotating >>>> * ethernet device if uc_priv->current == NULL. This is not what >>>> * we want when 'ethrotate' variable is 'no'. >>>> */ >>>> ethrotate = env_get("ethrotate"); >>>> if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) >>>> { >>>> printf("!!! eth_current_changed(): conditional 1\n"); >>>> return; >>>> } >>>> >>>> /* update current ethernet name */ >>>> if (eth_get_dev()) { >>>> printf("!!! eth_current_changed(): conditional 2\n"); >>>> if (act == NULL || strcmp(act, eth_get_name()) != 0) >>>> { >>>> printf("!!! eth_current_changed(): conditional 3\n"); >>>> env_set("ethact", eth_get_name()); >>>> } >>>> } >>>> /* >>>> * remove the variable completely if there is no active >>>> * interface >>>> */ >>>> else if (act != NULL) >>>> { >>>> printf("!!! eth_current_changed(): conditional 4\n"); >>>> env_set("ethact", NULL); >>>> } >>>> printf("!!! eth_current_changed(): leaving function\n"); >>>> } >>>> >>>> void eth_set_current(void) >>>> { >>>> static char *act; >>>> static int env_changed_id; >>>> int env_id; >>>> >>>> printf("!!! eth_set_current(): entered function\n"); >>>> env_id = env_get_id(); >>>> if ((act == NULL) || (env_changed_id != env_id)) { >>>> printf("!!! eth_set_current(): conditional 1\n"); >>>> act = env_get("ethact"); >>>> env_changed_id = env_id; >>>> } >>>> >>>> if (act == NULL) { >>>> printf("!!! eth_set_current(): conditional 2\n"); >>>> char *ethprime = env_get("ethprime"); >>>> void *dev = NULL; >>>> >>>> if (ethprime) >>>> { >>>> printf("!!! eth_set_current(): conditional 3\n"); >>>> dev = eth_get_dev_by_name(ethprime); >>>> } >>>> if (dev) >>>> { >>>> printf("!!! eth_set_current(): conditional 4\n"); >>>> eth_set_dev(dev); >>>> } >>>> else >>>> { >>>> printf("!!! eth_set_current(): conditional 5\n"); >>>> eth_set_dev(NULL); >>>> } >>>> } else { >>>> printf("!!! eth_set_current(): conditional 6\n"); >>>> eth_set_dev(eth_get_dev_by_name(act)); >>>> } >>>> >>>> eth_current_changed(); >>>> printf("!!! eth_set_current(): leaving function\n"); >>>> } >>>> >>>> Hopefully this is enough to make sense of it? Let me know, thanks! >>>> >>>> -E >>> >>> Postscript I've narrowed it down a bit to net/lwip/net-lwip.c:new_netif() >>> where returning from eth_init() the eth_get_dev() is the second interface >>> (with network cable plugged in) but variable reference udev is still the >>> first interface (with no network cable) when the call to lwip_init() is >>> made. So lwip_init() tries and fails on the first interface even though we >>> already know from eth_init() which interface is valid and ready. >>> >>> So that is what is happening but I don't know what you would want to do to >>> fix this? >> >> Perhaps eth_init() has to be called before eth_set_current()/ >> eth_get_dev()? Can you please try the following patch: >> >> ---8<-------8<-------8<-------8<-------8<-------8<-------8<---- >> diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c >> index b863047f598..a6fb3824af1 100644 >> --- a/net/lwip/net-lwip.c >> +++ b/net/lwip/net-lwip.c >> @@ -127,18 +127,10 @@ static int get_udev_ipv4_info(struct udevice *dev, >> ip4_addr_t *ip, >> return 0; >> } >> -static struct netif *new_netif(struct udevice *udev, bool with_ip) >> +static void net_lwip_init(void) >> { >> - unsigned char enetaddr[ARP_HLEN]; >> - char hwstr[MAC_ADDR_STRLEN]; >> - ip4_addr_t ip, mask, gw; >> - struct netif *netif; >> - int ret = 0; >> static bool first_call = true; >> - if (!udev) >> - return NULL; >> - >> if (first_call) { >> eth_init_rings(); >> /* Pick a valid active device, if any */ >> @@ -146,6 +138,18 @@ static struct netif *new_netif(struct udevice *udev, >> bool with_ip) >> lwip_init(); >> first_call = false; >> } >> +} >> + >> +static struct netif *new_netif(struct udevice *udev, bool with_ip) >> +{ >> + unsigned char enetaddr[ARP_HLEN]; >> + char hwstr[MAC_ADDR_STRLEN]; >> + ip4_addr_t ip, mask, gw; >> + struct netif *netif; >> + int ret = 0; >> + >> + if (!udev) >> + return NULL; >> if (eth_start_udev(udev) < 0) { >> log_err("Could not start %s\n", udev->name); >> @@ -198,11 +202,15 @@ static struct netif *new_netif(struct udevice *udev, >> bool with_ip) >> struct netif *net_lwip_new_netif(struct udevice *udev) >> { >> + net_lwip_init(); >> + >> return new_netif(udev, true); >> } >> struct netif *net_lwip_new_netif_noip(struct udevice *udev) >> { >> + net_lwip_init(); >> + >> return new_netif(udev, false); >> } >> ---8<-------8<-------8<-------8<-------8<-------8<-------8<---- >> >> Thanks, > > Testing with commands: > > env set test_url http://ipv4.download.thinkbroadband.com/5MB.zip > echo "TEST dhcp" > dhcp > echo "TEST wget" > wget ${test_url} > echo "TEST dhcp" > dhcp > echo "TEST wget" > wget ${test_url} > > env set test_url http://ipv4.download.thinkbroadband.com/5MB.zip;echo "TEST > dhcp";dhcp;echo "TEST wget";wget ${test_url};echo "TEST dhcp";dhcp;echo "TEST > wget";wget ${test_url} > > # Without patch, board power-on for network cable in ethernet@16030000: > TEST dhcp > ethernet@16030000 Waiting for PHY auto negotiation to complete...... done > DHCP client bound to address 192.168.2.51 (568 ms) > TEST wget > ################################################## > 5242880 bytes transferred in 2632 ms (1.9 MiB/s) > Bytes transferred = 5242880 (500000 hex) > TEST dhcp > DHCP client bound to address 192.168.2.51 (255 ms) > TEST wget > ################################################## > 5242880 bytes transferred in 10763 ms (475.6 KiB/s) > Bytes transferred = 5242880 (500000 hex) > > > # With patch, board power-on for network cable in ethernet@16030000: > TEST dhcp > ethernet@16030000 Waiting for PHY auto negotiation to complete...... done > DHCP client bound to address 192.168.2.51 (620 ms) > TEST wget > ################################################## > 5242880 bytes transferred in 1580 ms (3.2 MiB/s) > Bytes transferred = 5242880 (500000 hex) > TEST dhcp > DHCP client bound to address 192.168.2.51 (42 ms) > TEST wget > ################################################## > 5242880 bytes transferred in 1580 ms (3.2 MiB/s) > Bytes transferred = 5242880 (500000 hex) > > > # Without patch, board power-on for network cable in ethernet@16040000: > TEST dhcp > ethernet@16030000 Waiting for PHY auto negotiation to complete......... > TIMEOUT ! > phy_startup() failed: -110 > FAILED: -110 > ethernet@16040000 Waiting for PHY auto negotiation to complete...... done > ethernet@16030000 Waiting for PHY auto negotiation to complete......... > TIMEOUT ! > phy_startup() failed: -110 > FAILED: -110 > Could not start ethernet@16030000 > TEST wget > TEST dhcp > DHCP client bound to address 192.168.2.77 (33 ms) > TEST wget > ################################################## > 5242880 bytes transferred in 1490 ms (3.4 MiB/s) > Bytes transferred = 5242880 (500000 hex) > > > # With patch, board power-on for network cable in ethernet@16040000: > TEST dhcp > ethernet@16030000 Waiting for PHY auto negotiation to complete......... > TIMEOUT ! > phy_startup() failed: -110 > FAILED: -110 > ethernet@16040000 Waiting for PHY auto negotiation to complete...... done > ethernet@16030000 Waiting for PHY auto negotiation to complete......... > TIMEOUT ! > phy_startup() failed: -110 > FAILED: -110 > Could not start ethernet@16030000 > TEST wget > TEST dhcp > DHCP client bound to address 192.168.2.77 (24 ms) > TEST wget > ################################################## > 5242880 bytes transferred in 1938 ms (2.6 MiB/s) > Bytes transferred = 5242880 (500000 hex) > > > This appears no change in outcome with patch applied?
Please check [1] and let me know if it works for you. [1] https://lists.denx.de/pipermail/u-boot/2025-January/578982.html Thanks, -- Jerome > > -E