diff options
33 files changed, 431 insertions, 278 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index cb787d32f14..01ab0c11f98 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -350,6 +350,8 @@ stages: sandbox64_clang: TEST_PY_BD: "sandbox64" OVERRIDE: "-O clang-18" + sandbox64_lwip: + TEST_PY_BD: "sandbox64_lwip" sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5f3418e482f..145bdad83bf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -290,6 +290,17 @@ sandbox64 with clang test.py: OVERRIDE: "-O clang-18" <<: *buildman_and_testpy_dfn +sandbox64_lwip test.py: + parallel: + matrix: + - HOST: "fast arm64" + - HOST: "fast amd64" + tags: + - ${HOST} + variables: + TEST_PY_BD: "sandbox64_lwip" + <<: *buildman_and_testpy_dfn + sandbox_spl test.py: variables: TEST_PY_BD: "sandbox_spl" diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index a2c19702d64..29197f56e95 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -8,6 +8,11 @@ stderr=serial,vidconsole ethaddr=02:00:11:22:33:44 eth6addr=02:00:11:22:33:47 ipaddr=192.0.2.1 +ipaddr2=192.0.2.3 +ipaddr3=192.0.2.4 +ipaddr5=192.0.2.6 +ipaddr6=192.0.2.7 +ipaddr7=192.0.2.8 /* * These are used for distro boot which is not supported. But once bootmethod diff --git a/cmd/net.c b/cmd/net.c index 79525f73a51..eaa1de5295f 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -456,8 +456,7 @@ static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, } #if defined(CONFIG_CMD_PING) -static int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { if (argc < 2) return CMD_RET_USAGE; diff --git a/cmd/pxe.c b/cmd/pxe.c index 37b8dea6ad6..0f26b3b4219 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -13,7 +13,6 @@ #include "pxe_utils.h" -#ifdef CONFIG_CMD_NET const char *pxe_default_paths[] = { #ifdef CONFIG_SYS_SOC #ifdef CONFIG_SYS_BOARD @@ -331,5 +330,3 @@ U_BOOT_CMD(pxe, 4, 1, do_pxe, "get [" USE_IP6_CMD_PARAM "] - try to retrieve a pxe file using tftp\n" "pxe boot [pxefile_addr_r] [-ipv6] - boot from the pxe file at pxefile_addr_r\n" ); - -#endif /* CONFIG_CMD_NET */ diff --git a/common/board_r.c b/common/board_r.c index 65d74e3c092..bc6fd6448c2 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -509,7 +509,7 @@ static int initr_boot_led_on(void) return 0; } -#if defined(CONFIG_CMD_NET) +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) static int initr_net(void) { puts("Net: "); @@ -779,7 +779,7 @@ static void initcall_run_r(void) #if CONFIG_IS_ENABLED(PCI_ENDPOINT) INITCALL(pci_ep_init); #endif -#if CONFIG_IS_ENABLED(CMD_NET) +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) WATCHDOG_RESET(); INITCALL(initr_net); #endif diff --git a/configs/sandbox64_lwip_defconfig b/configs/sandbox64_lwip_defconfig new file mode 100644 index 00000000000..0e92728533f --- /dev/null +++ b/configs/sandbox64_lwip_defconfig @@ -0,0 +1,5 @@ +#include <configs/sandbox64_defconfig> + +CONFIG_SANDBOX=y + +CONFIG_NET_LWIP=y diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 8c907c3b032..e6e43ae936a 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -427,14 +427,8 @@ static int scmi_bind_protocols(struct udevice *dev) break; case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN: if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI) && - scmi_protocol_is_supported(dev, protocol_id)) { - node = ofnode_find_subnode(node, "regulators"); - if (!ofnode_valid(node)) { - dev_err(dev, "no regulators node\n"); - return -ENXIO; - } + scmi_protocol_is_supported(dev, protocol_id)) drv = DM_DRIVER_GET(scmi_voltage_domain); - } break; default: break; diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 9af84da1599..2f4dc5bd887 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -83,6 +83,19 @@ int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us) return dm_mmc_wait_dat0(mmc->dev, state, timeout_us); } +void dm_mmc_send_init_stream(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->send_init_stream) + ops->send_init_stream(dev); +} + +void mmc_send_init_stream(struct mmc *mmc) +{ + dm_mmc_send_init_stream(mmc->dev); +} + static int dm_mmc_get_wp(struct udevice *dev) { struct dm_mmc_ops *ops = mmc_get_ops(dev); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 47139e0a911..cdcf2e0c8fe 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1663,6 +1663,10 @@ static int mmc_execute_tuning(struct mmc *mmc, uint opcode) } #endif +static void mmc_send_init_stream(struct mmc *mmc) +{ +} + static int mmc_set_ios(struct mmc *mmc) { int ret = 0; @@ -2550,7 +2554,7 @@ static int mmc_startup(struct mmc *mmc) /* * For MMC cards, set the Relative Address. - * For SD cards, get the Relatvie Address. + * For SD cards, get the Relative Address. * This also puts the cards into Standby State */ if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ @@ -2929,6 +2933,8 @@ int mmc_get_op_cond(struct mmc *mmc, bool quiet) retry: mmc_set_initial_state(mmc); + mmc_send_init_stream(mmc); + /* Reset the Card */ err = mmc_go_idle(mmc); diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index e66ab25d02a..92bc72b267c 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -780,6 +780,14 @@ tuning_error: return ret; } #endif + +static void omap_hsmmc_send_init_stream(struct udevice *dev) +{ + struct omap_hsmmc_data *priv = dev_get_priv(dev); + struct hsmmc *mmc_base = priv->base_addr; + + mmc_init_stream(mmc_base); +} #endif static void mmc_enable_irq(struct mmc *mmc, struct mmc_cmd *cmd) @@ -1515,9 +1523,10 @@ static const struct dm_mmc_ops omap_hsmmc_ops = { .get_wp = omap_hsmmc_getwp, #endif #if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) - .execute_tuning = omap_hsmmc_execute_tuning, + .execute_tuning = omap_hsmmc_execute_tuning, #endif - .wait_dat0 = omap_hsmmc_wait_dat0, + .send_init_stream = omap_hsmmc_send_init_stream, + .wait_dat0 = omap_hsmmc_wait_dat0, }; #else static const struct mmc_ops omap_hsmmc_ops = { diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a0a7890bd26..4434d364777 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -48,7 +48,6 @@ config DM_DSA bool "Enable Driver Model for DSA switches" depends on DM_MDIO depends on PHY_FIXED - depends on !NET_LWIP help Enable driver model for DSA switches @@ -358,7 +357,7 @@ config ESSEDMA config ETH_SANDBOX depends on SANDBOX - depends on NET + depends on NET || NET_LWIP default y bool "Sandbox: Mocked Ethernet driver" help @@ -367,17 +366,6 @@ config ETH_SANDBOX This driver is particularly useful in the test/dm/eth.c tests -config ETH_SANDBOX_LWIP - depends on SANDBOX - depends on NET_LWIP - default y - bool "Sandbox: Mocked Ethernet driver (for NET_LWIP)" - help - This driver is meant as a replacement for ETH_SANDBOX when - the network stack is NET_LWIP rather than NET. It currently - does nothing, i.e. it drops the sent packets and never receives - data. - config ETH_SANDBOX_RAW depends on SANDBOX depends on NET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 3244d39036d..67bba3a8536 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o obj-$(CONFIG_ETH_SANDBOX) += sandbox.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw-bus.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o -obj-$(CONFIG_ETH_SANDBOX_LWIP) += sandbox-lwip.o obj-$(CONFIG_FEC_MXC) += fec_mxc.o obj-$(CONFIG_FMAN_ENET) += fm/ obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o diff --git a/drivers/net/sandbox-lwip.c b/drivers/net/sandbox-lwip.c deleted file mode 100644 index 3721033c310..00000000000 --- a/drivers/net/sandbox-lwip.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2015 National Instruments - * - * (C) Copyright 2015 - * Joe Hershberger <joe.hershberger@ni.com> - */ - -#include <dm.h> -#include <log.h> -#include <malloc.h> -#include <net.h> -#include <asm/eth.h> -#include <asm/global_data.h> -#include <asm/test.h> - -DECLARE_GLOBAL_DATA_PTR; - -static int sb_lwip_eth_start(struct udevice *dev) -{ - debug("eth_sandbox_lwip: Start\n"); - - return 0; -} - -static int sb_lwip_eth_send(struct udevice *dev, void *packet, int length) -{ - debug("eth_sandbox_lwip: Send packet %d\n", length); - - return -ENOTSUPP; -} - -static int sb_lwip_eth_recv(struct udevice *dev, int flags, uchar **packetp) -{ - return -EAGAIN; -} - -static int sb_lwip_eth_free_pkt(struct udevice *dev, uchar *packet, int length) -{ - return 0; -} - -static void sb_lwip_eth_stop(struct udevice *dev) -{ -} - -static int sb_lwip_eth_write_hwaddr(struct udevice *dev) -{ - return 0; -} - -static const struct eth_ops sb_eth_ops = { - .start = sb_lwip_eth_start, - .send = sb_lwip_eth_send, - .recv = sb_lwip_eth_recv, - .free_pkt = sb_lwip_eth_free_pkt, - .stop = sb_lwip_eth_stop, - .write_hwaddr = sb_lwip_eth_write_hwaddr, -}; - -static int sb_lwip_eth_remove(struct udevice *dev) -{ - return 0; -} - -static int sb_lwip_eth_of_to_plat(struct udevice *dev) -{ - return 0; -} - -static const struct udevice_id sb_eth_ids[] = { - { .compatible = "sandbox,eth" }, - { } -}; - -U_BOOT_DRIVER(eth_sandbox) = { - .name = "eth_lwip_sandbox", - .id = UCLASS_ETH, - .of_match = sb_eth_ids, - .of_to_plat = sb_lwip_eth_of_to_plat, - .remove = sb_lwip_eth_remove, - .ops = &sb_eth_ops, - .priv_auto = 0, - .plat_auto = sizeof(struct eth_pdata), -}; diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c index fe3627db6e3..2011fd31f41 100644 --- a/drivers/net/sandbox.c +++ b/drivers/net/sandbox.c @@ -9,13 +9,84 @@ #include <dm.h> #include <log.h> #include <malloc.h> -#include <net.h> #include <asm/eth.h> #include <asm/global_data.h> #include <asm/test.h> +#include <asm/types.h> + +/* + * Structure definitions for network protocols. Since this file is used for + * both NET and NET_LWIP, and given that the two network stacks do have + * conflicting types (for instance struct icmp_hdr), it is on purpose that the + * structures are defined locally with minimal dependencies -- <asm/types.h> is + * included for the bit types and that's it. + */ + +#define ETHADDR_LEN 6 +#define IP4_LEN 4 + +struct ethhdr { + u8 dst[ETHADDR_LEN]; + u8 src[ETHADDR_LEN]; + u16 protlen; +} __attribute__((packed)); + +#define ETHHDR_SIZE (sizeof(struct ethhdr)) + +struct arphdr { + u16 htype; + u16 ptype; + u8 hlen; + u8 plen; + u16 op; +} __attribute__((packed)); + +#define ARPHDR_SIZE (sizeof(struct arphdr)) + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +struct arpdata { + u8 sha[ETHADDR_LEN]; + u32 spa; + u8 tha[ETHADDR_LEN]; + u32 tpa; +} __attribute__((packed)); + +#define ARPDATA_SIZE (sizeof(struct arpdata)) + +struct iphdr { + u8 hl_v; + u8 tos; + u16 len; + u16 id; + u16 off; + u8 ttl; + u8 prot; + u16 sum; + u32 src; + u32 dst; +} __attribute__((packed)); + +#define IPHDR_SIZE (sizeof(struct iphdr)) + +struct icmphdr { + u8 type; + u8 code; + u16 checksum; + u16 id; + u16 sequence; +} __attribute__((packed)); + +#define ICMPHDR_SIZE (sizeof(struct icmphdr)) + +#define ICMP_ECHO_REQUEST 8 +#define ICMP_ECHO_REPLY 0 +#define IPPROTO_ICMP 1 DECLARE_GLOBAL_DATA_PTR; +static const u8 null_ethaddr[6]; static bool skip_timeout; /* @@ -59,17 +130,19 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet, unsigned int len) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth = packet; - struct arp_hdr *arp; - struct ethernet_hdr *eth_recv; - struct arp_hdr *arp_recv; - - if (ntohs(eth->et_protlen) != PROT_ARP) + struct ethhdr *eth = packet; + struct arphdr *arp; + struct arpdata *arpd; + struct ethhdr *eth_recv; + struct arphdr *arp_recv; + struct arpdata *arp_recvd; + + if (ntohs(eth->protlen) != PROT_ARP) return -EAGAIN; - arp = packet + ETHER_HDR_SIZE; + arp = packet + ETHHDR_SIZE; - if (ntohs(arp->ar_op) != ARPOP_REQUEST) + if (ntohs(arp->op) != ARP_REQUEST) return -EAGAIN; /* Don't allow the buffer to overrun */ @@ -77,27 +150,29 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet, return 0; /* store this as the assumed IP of the fake host */ - priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa); + arpd = (struct arpdata *)(arp + 1); + priv->fake_host_ipaddr.s_addr = arpd->tpa; /* Formulate a fake response */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_ARP); - - arp_recv = (void *)eth_recv + ETHER_HDR_SIZE; - arp_recv->ar_hrd = htons(ARP_ETHER); - arp_recv->ar_pro = htons(PROT_IP); - arp_recv->ar_hln = ARP_HLEN; - arp_recv->ar_pln = ARP_PLEN; - arp_recv->ar_op = htons(ARPOP_REPLY); - memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); - memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN); - net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa); - - priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + ARP_HDR_SIZE; + memcpy(eth_recv->dst, eth->src, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_ARP); + + arp_recv = (void *)eth_recv + ETHHDR_SIZE; + arp_recv->htype = htons(ARP_ETHER); + arp_recv->ptype = htons(PROT_IP); + arp_recv->hlen = ETHADDR_LEN; + arp_recv->plen = IP4_LEN; + arp_recv->op = htons(ARP_REPLY); + arp_recvd = (struct arpdata *)(arp_recv + 1); + memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN); + arp_recvd->spa = priv->fake_host_ipaddr.s_addr; + memcpy(&arp_recvd->tha, &arpd->sha, ETHADDR_LEN); + arp_recvd->tpa = arpd->spa; + + priv->recv_packet_length[priv->recv_packets] = ETHHDR_SIZE + + ARPHDR_SIZE + ARPDATA_SIZE; ++priv->recv_packets; return 0; @@ -114,22 +189,22 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, unsigned int len) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth = packet; - struct ip_udp_hdr *ip; - struct icmp_hdr *icmp; - struct ethernet_hdr *eth_recv; - struct ip_udp_hdr *ipr; - struct icmp_hdr *icmpr; - - if (ntohs(eth->et_protlen) != PROT_IP) + struct ethhdr *eth = packet; + struct iphdr *ip; + struct icmphdr *icmp; + struct ethhdr *eth_recv; + struct iphdr *ipr; + struct icmphdr *icmpr; + + if (ntohs(eth->protlen) != PROT_IP) return -EAGAIN; - ip = packet + ETHER_HDR_SIZE; + ip = packet + ETHHDR_SIZE; - if (ip->ip_p != IPPROTO_ICMP) + if (ip->prot != IPPROTO_ICMP) return -EAGAIN; - icmp = (struct icmp_hdr *)&ip->udp_src; + icmp = (struct icmphdr *)(ip + 1); if (icmp->type != ICMP_ECHO_REQUEST) return -EAGAIN; @@ -141,19 +216,19 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, /* reply to the ping */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; memcpy(eth_recv, packet, len); - ipr = (void *)eth_recv + ETHER_HDR_SIZE; - icmpr = (struct icmp_hdr *)&ipr->udp_src; - memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - ipr->ip_sum = 0; - ipr->ip_off = 0; - net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src); - net_write_ip((void *)&ipr->ip_src, priv->fake_host_ipaddr); - ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + ipr = (void *)eth_recv + ETHHDR_SIZE; + icmpr = (struct icmphdr *)(ipr + 1); + memcpy(eth_recv->dst, eth->src, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + ipr->sum = 0; + ipr->off = 0; + ipr->dst = ip->src; + ipr->src = priv->fake_host_ipaddr.s_addr; + ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE); icmpr->type = ICMP_ECHO_REPLY; icmpr->checksum = 0; - icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE); priv->recv_packet_length[priv->recv_packets] = len; ++priv->recv_packets; @@ -171,8 +246,9 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, int sandbox_eth_recv_arp_req(struct udevice *dev) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth_recv; - struct arp_hdr *arp_recv; + struct ethhdr *eth_recv; + struct arphdr *arp_recv; + struct arpdata *arp_recvd; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -180,23 +256,24 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) /* Formulate a fake request */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, net_bcast_ethaddr, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_ARP); - - arp_recv = (void *)eth_recv + ETHER_HDR_SIZE; - arp_recv->ar_hrd = htons(ARP_ETHER); - arp_recv->ar_pro = htons(PROT_IP); - arp_recv->ar_hln = ARP_HLEN; - arp_recv->ar_pln = ARP_PLEN; - arp_recv->ar_op = htons(ARPOP_REQUEST); - memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); - memcpy(&arp_recv->ar_tha, net_null_ethaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_tpa, net_ip); + memcpy(eth_recv->dst, net_bcast_ethaddr, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_ARP); + + arp_recv = (void *)eth_recv + ETHHDR_SIZE; + arp_recv->htype = htons(ARP_ETHER); + arp_recv->ptype = htons(PROT_IP); + arp_recv->hlen = ETHADDR_LEN; + arp_recv->plen = IP4_LEN; + arp_recv->op = htons(ARP_REQUEST); + arp_recvd = (struct arpdata *)(arp_recv + 1); + memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN); + arp_recvd->spa = priv->fake_host_ipaddr.s_addr; + memcpy(&arp_recvd->tha, null_ethaddr, ETHADDR_LEN); + arp_recvd->tpa = net_ip.s_addr; priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + ARP_HDR_SIZE; + ETHHDR_SIZE + ARPHDR_SIZE + ARPDATA_SIZE; ++priv->recv_packets; return 0; @@ -212,9 +289,10 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) int sandbox_eth_recv_ping_req(struct udevice *dev) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth_recv; - struct ip_udp_hdr *ipr; - struct icmp_hdr *icmpr; + struct eth_pdata *pdata = dev_get_plat(dev); + struct ethhdr *eth_recv; + struct iphdr *ipr; + struct icmphdr *icmpr; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -223,31 +301,31 @@ int sandbox_eth_recv_ping_req(struct udevice *dev) /* Formulate a fake ping */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_IP); + memcpy(eth_recv->dst, pdata->enetaddr, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_IP); - ipr = (void *)eth_recv + ETHER_HDR_SIZE; - ipr->ip_hl_v = 0x45; - ipr->ip_len = htons(IP_ICMP_HDR_SIZE); - ipr->ip_off = htons(IP_FLAGS_DFRAG); - ipr->ip_p = IPPROTO_ICMP; - ipr->ip_sum = 0; - net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr); - net_write_ip(&ipr->ip_dst, net_ip); - ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + ipr = (void *)eth_recv + ETHHDR_SIZE; + ipr->hl_v = 0x45; + ipr->len = htons(IPHDR_SIZE + ICMPHDR_SIZE); + ipr->off = htons(IP_FLAGS_DFRAG); + ipr->prot = IPPROTO_ICMP; + ipr->sum = 0; + ipr->src = priv->fake_host_ipaddr.s_addr; + ipr->dst = net_ip.s_addr; + ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE); - icmpr = (struct icmp_hdr *)&ipr->udp_src; + icmpr = (struct icmphdr *)(ipr + 1); icmpr->type = ICMP_ECHO_REQUEST; icmpr->code = 0; icmpr->checksum = 0; - icmpr->un.echo.id = 0; - icmpr->un.echo.sequence = htons(1); - icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + icmpr->id = 0; + icmpr->sequence = htons(1); + icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE); priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE; + ETHHDR_SIZE + IPHDR_SIZE + ICMPHDR_SIZE; ++priv->recv_packets; return 0; @@ -398,7 +476,7 @@ static int sb_eth_write_hwaddr(struct udevice *dev) debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name, pdata->enetaddr); - memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ARP_HLEN); + memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ETHADDR_LEN); return 0; } diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c index 99f6506f162..79db1a6a8aa 100644 --- a/drivers/power/regulator/scmi_regulator.c +++ b/drivers/power/regulator/scmi_regulator.c @@ -175,12 +175,19 @@ U_BOOT_DRIVER(scmi_regulator) = { static int scmi_regulator_bind(struct udevice *dev) { struct driver *drv; + ofnode regul_node; ofnode node; int ret; + regul_node = ofnode_find_subnode(dev_ofnode(dev), "regulators"); + if (!ofnode_valid(regul_node)) { + dev_err(dev, "no regulators node\n"); + return -ENXIO; + } + drv = DM_DRIVER_GET(scmi_regulator); - ofnode_for_each_subnode(node, dev_ofnode(dev)) { + ofnode_for_each_subnode(node, regul_node) { ret = device_bind(dev, drv, ofnode_get_name(node), NULL, node, NULL); if (ret) diff --git a/include/mmc.h b/include/mmc.h index 52cacfd0eab..eead666ae44 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -494,6 +494,14 @@ struct dm_mmc_ops { int (*set_ios)(struct udevice *dev); /** + * send_init_stream() - send the initialization stream: 74 clock cycles + * This is used after power up before sending the first command + * + * @dev: Device to update + */ + void (*send_init_stream)(struct udevice *dev); + + /** * get_cd() - See whether a card is present * * @dev: Device to check @@ -572,6 +580,7 @@ struct dm_mmc_ops { /* Transition functions for compatibility */ int mmc_set_ios(struct mmc *mmc); +void mmc_send_init_stream(struct mmc *mmc); int mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); int mmc_execute_tuning(struct mmc *mmc, uint opcode); diff --git a/include/net-common.h b/include/net-common.h index 30860f5975a..e536968a92b 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -471,6 +471,9 @@ static inline struct in_addr env_get_ip(char *var) int net_init(void); +/* Called when a network operation fails to know if it should be re-tried */ +int net_start_again(void); + /* NET compatibility */ enum proto_t; int net_loop(enum proto_t protocol); @@ -490,6 +493,18 @@ int net_loop(enum proto_t protocol); */ int dhcp_run(ulong addr, const char *fname, bool autoload); + +/** + * do_ping - Run the ping command + * + * @cmdtp: Unused + * @flag: Command flags (CMD_FLAG_...) + * @argc: Number of arguments + * @argv: List of arguments + * Return: result (see enum command_ret_t) + */ +int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); + /** * do_tftpb - Run the tftpboot command * diff --git a/include/net-legacy.h b/include/net-legacy.h index bc0f0cde9fe..51780999a88 100644 --- a/include/net-legacy.h +++ b/include/net-legacy.h @@ -347,9 +347,6 @@ extern int net_ntp_time_offset; /* offset time from UTC */ int net_loop(enum proto_t); -/* Load failed. Start again. */ -int net_start_again(void); - /* Get size of the ethernet header when we send */ int net_eth_hdr_size(void); diff --git a/include/net-lwip.h b/include/net-lwip.h index 64e5c720560..b762956e8fd 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -10,7 +10,14 @@ enum proto_t { TFTPGET }; -void net_lwip_set_current(void); +static inline int eth_is_on_demand_init(void) +{ + return 1; +} + +int eth_init_state_only(void); /* Set active state */ + +int net_lwip_eth_start(void); struct netif *net_lwip_new_netif(struct udevice *udev); struct netif *net_lwip_new_netif_noip(struct udevice *udev); void net_lwip_remove_netif(struct netif *netif); @@ -27,7 +34,6 @@ bool wget_validate_uri(char *uri); int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); -int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]); #endif /* __NET_LWIP_H__ */ diff --git a/include/net6.h b/include/net6.h index 1ed989e584a..2ceeaba0639 100644 --- a/include/net6.h +++ b/include/net6.h @@ -90,6 +90,16 @@ struct udp_hdr { 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x02 } } } +/* + * With IPv6, the broadcast MAC address is not used. Instead, it should use + * the multicast address (see RFC RFC2464 section 7) + */ +#define IPV6_ALL_NODE_ETH_ADDR(_ip6_addr) {0x33, \ + 0x33, \ + _ip6_addr.in6_u.u6_addr8[12], \ + _ip6_addr.in6_u.u6_addr8[13], \ + _ip6_addr.in6_u.u6_addr8[14], \ + _ip6_addr.in6_u.u6_addr8[15]} #define IPV6_LINK_LOCAL_PREFIX 0xfe80 #define IPV6_LINK_LOCAL_MASK 0xffb0 /* The first 10-bit of address mask. */ diff --git a/net/Makefile b/net/Makefile index 41edbacabc9..d63f62b7c8a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o obj-$(CONFIG_CMD_DNS) += dns.o -obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o obj-$(CONFIG_IPV6) += ndisc.o obj-$(CONFIG_$(PHASE_)DM_ETH) += net.o @@ -39,6 +38,7 @@ CFLAGS_eth_common.o += -Wno-format-extra-args endif ifeq ($(filter y,$(CONFIG_NET) $(CONFIG_NET_LWIP)),y) +obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_$(PHASE_)DM_ETH) += eth-uclass.o obj-$(CONFIG_$(PHASE_)BOOTDEV_ETH) += eth_bootdev.o obj-$(CONFIG_DM_MDIO) += mdio-uclass.o diff --git a/net/dhcpv6.c b/net/dhcpv6.c index 54619ee6983..0c2de75ba1d 100644 --- a/net/dhcpv6.c +++ b/net/dhcpv6.c @@ -29,6 +29,10 @@ int updated_sol_max_rt_ms = SOL_MAX_RT_MS; /* state machine parameters/variables */ struct dhcp6_sm_params sm_params; +/* DHCPv6 all server IP6 address */ +const struct in6_addr dhcp_mcast_ip6 = DHCP6_MULTICAST_ADDR; +/* IPv6 multicast ethernet address */ +const u8 net_dhcp6_mcast_ethaddr[6] = IPV6_ALL_NODE_ETH_ADDR(dhcp_mcast_ip6); static void dhcp6_state_machine(bool timeout, uchar *rx_pkt, unsigned int len); @@ -171,7 +175,6 @@ static int dhcp6_add_option(int option_id, uchar *pkt) */ static void dhcp6_send_solicit_packet(void) { - struct in6_addr dhcp_bcast_ip6; int len = 0; uchar *pkt; uchar *dhcp_pkt_start_ptr; @@ -200,9 +203,8 @@ static void dhcp6_send_solicit_packet(void) len = pkt - dhcp_pkt_start_ptr; /* send UDP packet to DHCP6 multicast address */ - string_to_ip6(DHCP6_MULTICAST_ADDR, sizeof(DHCP6_MULTICAST_ADDR), &dhcp_bcast_ip6); net_set_udp_handler(dhcp6_handler); - net_send_udp_packet6((uchar *)net_bcast_ethaddr, &dhcp_bcast_ip6, + net_send_udp_packet6((uchar *)net_dhcp6_mcast_ethaddr, (struct in6_addr *)&dhcp_mcast_ip6, PORT_DHCP6_S, PORT_DHCP6_C, len); } @@ -218,7 +220,6 @@ static void dhcp6_send_solicit_packet(void) */ static void dhcp6_send_request_packet(void) { - struct in6_addr dhcp_bcast_ip6; int len = 0; uchar *pkt; uchar *dhcp_pkt_start_ptr; @@ -252,9 +253,8 @@ static void dhcp6_send_request_packet(void) len = pkt - dhcp_pkt_start_ptr; /* send UDP packet to DHCP6 multicast address */ - string_to_ip6(DHCP6_MULTICAST_ADDR, strlen(DHCP6_MULTICAST_ADDR), &dhcp_bcast_ip6); net_set_udp_handler(dhcp6_handler); - net_send_udp_packet6((uchar *)net_bcast_ethaddr, &dhcp_bcast_ip6, + net_send_udp_packet6((uchar *)net_dhcp6_mcast_ethaddr, (struct in6_addr *)&dhcp_mcast_ip6, PORT_DHCP6_S, PORT_DHCP6_C, len); } @@ -473,8 +473,7 @@ static int dhcp6_check_advertise_packet(uchar *rx_pkt, unsigned int len) * server UID, save the new server UID and preference */ if (!sm_params.server_uid.uid_ptr || - (sm_params.server_uid.uid_ptr && - sm_params.server_uid.preference < sm_params.rx_status.preference)) { + sm_params.server_uid.preference < sm_params.rx_status.preference) { rx_uid_size = sm_params.rx_status.server_uid_size; if (sm_params.server_uid.uid_ptr) free(sm_params.server_uid.uid_ptr); diff --git a/net/dhcpv6.h b/net/dhcpv6.h index 65c8e4c71d3..d41a3c30615 100644 --- a/net/dhcpv6.h +++ b/net/dhcpv6.h @@ -40,7 +40,13 @@ /* vendor-class-data to send in vendor clas option */ #define DHCP6_VCI_STRING "U-Boot" -#define DHCP6_MULTICAST_ADDR "ff02::1:2" /* DHCP multicast address */ +/* + * All-DHCPv6 server multicast address + */ +#define DHCP6_MULTICAST_ADDR { { { 0xFF, 0x02, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x01, 0x00, 0x02 } } } /* DHCP6 States supported */ enum dhcp6_state { diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index 3b7e4700c6e..92bd7067a7f 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -115,7 +115,8 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int ret; struct udevice *dev; - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; dev = eth_get_dev(); if (!dev) { diff --git a/net/lwip/dns.c b/net/lwip/dns.c index 149bdb784dc..19172ac959a 100644 --- a/net/lwip/dns.c +++ b/net/lwip/dns.c @@ -121,7 +121,8 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc == 3) var = argv[2]; - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; return dns_loop(eth_get_dev(), name, var); } diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 6b7b696dbf0..f05c4cd3f64 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -14,6 +14,7 @@ #include <lwip/init.h> #include <lwip/prot/etharp.h> #include <net.h> +#include <timer.h> /* xx:xx:xx:xx:xx:xx\0 */ #define MAC_ADDR_STRLEN 18 @@ -21,6 +22,8 @@ #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) void (*push_packet)(void *, int len) = 0; #endif +static int net_try_count; +static int net_restarted; int net_restart_wrap; static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN]; uchar *net_rx_packets[PKTBUFSRX]; @@ -134,18 +137,27 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, return 0; } -/* Initialize the lwIP stack and the ethernet devices and set current device */ -void net_lwip_set_current(void) +/* + * Initialize the network stack if needed and start the current device if valid + */ +int net_lwip_eth_start(void) { - static bool init_done; - - if (!init_done) { - eth_init_rings(); - eth_init(); - lwip_init(); - init_done = true; + int ret; + + net_init(); + if (eth_is_on_demand_init()) { + eth_halt(); + eth_set_current(); + ret = eth_init(); + if (ret < 0) { + eth_halt(); + return ret; + } + } else { + eth_init_state_only(); } - eth_set_current(); + + return 0; } static struct netif *new_netif(struct udevice *udev, bool with_ip) @@ -224,11 +236,20 @@ void net_lwip_remove_netif(struct netif *netif) free(netif); } +/* + * Initialize the network buffers, an ethernet device, and the lwIP stack + * (once). + */ int net_init(void) { - eth_set_current(); + static bool init_done; - net_lwip_new_netif(eth_get_dev()); + if (!init_done) { + eth_init_rings(); + eth_init(); + lwip_init(); + init_done = true; + } return 0; } @@ -319,5 +340,48 @@ int net_loop(enum proto_t protocol) u32_t sys_now(void) { +#if CONFIG_IS_ENABLED(SANDBOX_TIMER) + return timer_early_get_count(); +#else return get_timer(0); +#endif +} + +int net_start_again(void) +{ + char *nretry; + int retry_forever = 0; + unsigned long retrycnt = 0; + + nretry = env_get("netretry"); + if (nretry) { + if (!strcmp(nretry, "yes")) + retry_forever = 1; + else if (!strcmp(nretry, "no")) + retrycnt = 0; + else if (!strcmp(nretry, "once")) + retrycnt = 1; + else + retrycnt = simple_strtoul(nretry, NULL, 0); + } else { + retrycnt = 0; + retry_forever = 0; + } + + if ((!retry_forever) && (net_try_count > retrycnt)) { + eth_halt(); + /* + * We don't provide a way for the protocol to return an error, + * but this is almost always the reason. + */ + return -ETIMEDOUT; + } + + net_try_count++; + + eth_halt(); +#if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER) + eth_try_another(!net_restarted); +#endif + return eth_init(); } diff --git a/net/lwip/ping.c b/net/lwip/ping.c index c586a96806d..d8042ceecf9 100644 --- a/net/lwip/ping.c +++ b/net/lwip/ping.c @@ -168,10 +168,13 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (!ipaddr_aton(argv[1], &addr)) return CMD_RET_USAGE; - net_lwip_set_current(); - - if (ping_loop(eth_get_dev(), &addr) < 0) - return CMD_RET_FAILURE; +restart: + if (net_lwip_eth_start() < 0 || ping_loop(eth_get_dev(), &addr) < 0) { + if (net_start_again() == 0) + goto restart; + else + return CMD_RET_FAILURE; + } return CMD_RET_SUCCESS; } diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index 123d66b5dba..4f9b2049187 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -280,7 +280,10 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) goto out; } - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) { + ret = CMD_RET_FAILURE; + goto out; + } if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0) ret = CMD_RET_FAILURE; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index ec098148835..a3b82908877 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -471,7 +471,11 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) int wget_do_request(ulong dst_addr, char *uri) { - net_lwip_set_current(); + int ret; + + ret = net_lwip_eth_start(); + if (ret < 0) + return ret; if (!wget_info) wget_info = &default_wget_info; diff --git a/test/dm/Makefile b/test/dm/Makefile index 3afcc26ca57..917dafe7d22 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -46,9 +46,7 @@ obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o obj-$(CONFIG_DM_DSA) += dsa.o obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o -ifdef CONFIG_NET obj-$(CONFIG_DM_ETH) += eth.o -endif obj-$(CONFIG_EXTCON) += extcon.o ifneq ($(CONFIG_EFI_PARTITION),) obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o diff --git a/test/dm/dsa.c b/test/dm/dsa.c index c6b4e12a758..9a31ae39d95 100644 --- a/test/dm/dsa.c +++ b/test/dm/dsa.c @@ -63,15 +63,15 @@ DM_TEST(dm_test_dsa_probe, UTF_SCAN_FDT); */ static int dm_test_dsa(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.2.3.5"); + char *argv[] = { "ping", "1.1.2.2" }; env_set("ethact", "eth2"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", "lan0"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", "lan1"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", ""); diff --git a/test/dm/eth.c b/test/dm/eth.c index 467495863e1..1087ae9572d 100644 --- a/test/dm/eth.c +++ b/test/dm/eth.c @@ -171,18 +171,18 @@ DM_TEST(dm_test_ip6_make_lladdr, UTF_SCAN_FDT); static int dm_test_eth(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; env_set("ethact", "eth@10002000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth@10003000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; @@ -191,22 +191,23 @@ DM_TEST(dm_test_eth, UTF_SCAN_FDT); static int dm_test_eth_alias(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; + env_set("ethact", "eth0"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth6"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); /* Expected to fail since eth1 is not defined in the device tree */ env_set("ethact", "eth1"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); return 0; @@ -215,18 +216,18 @@ DM_TEST(dm_test_eth_alias, UTF_SCAN_FDT); static int dm_test_eth_prime(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; /* Expected to be "eth@10003000" because of ethprime variable */ env_set("ethact", NULL); env_set("ethprime", "eth5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); /* Expected to be "eth@10002000" because it is first */ env_set("ethact", NULL); env_set("ethprime", NULL); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); return 0; @@ -249,6 +250,7 @@ DM_TEST(dm_test_eth_prime, UTF_SCAN_FDT); */ static int dm_test_eth_act(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; struct udevice *dev[DM_TEST_ETH_NUM]; const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000", "sbe5", "eth@10004000"}; @@ -258,7 +260,6 @@ static int dm_test_eth_act(struct unit_test_state *uts) int i; memset(ethaddr, '\0', sizeof(ethaddr)); - net_ping_ip = string_to_ip("1.1.2.2"); /* Prepare the test scenario */ for (i = 0; i < DM_TEST_ETH_NUM; i++) { @@ -281,7 +282,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) env_set("ethact", ethname[0]); /* Segment fault might happen if something is wrong */ - ut_asserteq(-ENODEV, net_loop(PING)); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); for (i = 0; i < DM_TEST_ETH_NUM; i++) { /* Restore the env */ @@ -334,15 +335,17 @@ DM_TEST(dm_test_ethaddr, UTF_SCAN_FDT); /* The asserts include a return on fail; cleanup in the caller */ static int _dm_test_eth_rotate1(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* Make sure that the default is to rotate to the next interface */ env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); /* If ethrotate is no, then we should fail on a bad MAC */ env_set("ethact", "eth@10004000"); env_set("ethrotate", "no"); - ut_asserteq(-EINVAL, net_loop(PING)); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; @@ -350,14 +353,16 @@ static int _dm_test_eth_rotate1(struct unit_test_state *uts) static int _dm_test_eth_rotate2(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* Make sure we can skip invalid devices */ env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); /* Make sure we can handle device name which is not eth# */ env_set("ethact", "sbe5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("sbe5", env_get("ethact")); return 0; @@ -368,9 +373,6 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) char ethaddr[18]; int retval; - /* Set target IP to mock ping */ - net_ping_ip = string_to_ip("1.1.2.2"); - /* Invalidate eth1's MAC address */ memset(ethaddr, '\0', sizeof(ethaddr)); strncpy(ethaddr, env_get("eth6addr"), 17); @@ -396,6 +398,7 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) /* Restore the env */ env_set("ethaddr", ethaddr); } + /* Restore the env */ env_set(".flags", NULL); @@ -406,26 +409,28 @@ DM_TEST(dm_test_eth_rotate, UTF_SCAN_FDT); /* The asserts include a return on fail; cleanup in the caller */ static int _dm_test_net_retry(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* - * eth1 is disabled and netretry is yes, so the ping should succeed and - * the active device should be eth0 + * eth0 is disabled and netretry is yes, so the ping should succeed and + * the active device should be eth1 */ - sandbox_eth_disable_response(1, true); - env_set("ethact", "lan1"); + sandbox_eth_disable_response(0, true); + env_set("ethact", "eth@10002000"); env_set("netretry", "yes"); sandbox_eth_skip_timeout(); - ut_assertok(net_loop(PING)); - ut_asserteq_str("eth@10002000", env_get("ethact")); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); + ut_asserteq_str("eth@10003000", env_get("ethact")); /* - * eth1 is disabled and netretry is no, so the ping should fail and the - * active device should be eth1 + * eth0 is disabled and netretry is no, so the ping should fail and the + * active device should be eth0 */ - env_set("ethact", "lan1"); + env_set("ethact", "eth@10002000"); env_set("netretry", "no"); sandbox_eth_skip_timeout(); - ut_asserteq(-ENONET, net_loop(PING)); - ut_asserteq_str("lan1", env_get("ethact")); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); + ut_asserteq_str("eth@10002000", env_get("ethact")); return 0; } @@ -434,8 +439,6 @@ static int dm_test_net_retry(struct unit_test_state *uts) { int retval; - net_ping_ip = string_to_ip("1.1.2.2"); - retval = _dm_test_net_retry(uts); /* Restore the env */ @@ -446,6 +449,7 @@ static int dm_test_net_retry(struct unit_test_state *uts) } DM_TEST(dm_test_net_retry, UTF_SCAN_FDT); +#if CONFIG_IS_ENABLED(NET) static int sb_check_arp_reply(struct udevice *dev, void *packet, unsigned int len) { @@ -511,7 +515,9 @@ static int sb_with_async_arp_handler(struct udevice *dev, void *packet, return sb_check_arp_reply(dev, packet, len); } +#endif +#if CONFIG_IS_ENABLED(NET) static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) { net_ping_ip = string_to_ip("1.1.2.2"); @@ -529,7 +535,9 @@ static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_eth_async_arp_reply, UTF_SCAN_FDT); +#endif +#if CONFIG_IS_ENABLED(NET) static int sb_check_ping_reply(struct udevice *dev, void *packet, unsigned int len) { @@ -613,6 +621,7 @@ static int dm_test_eth_async_ping_reply(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_eth_async_ping_reply, UTF_SCAN_FDT); +#endif #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) |