[PATCHv4 2/5] net/lwip: add lwip library for the network stack
Maxim Uvarov
maxim.uvarov at linaro.org
Fri Jul 28 16:26:40 CEST 2023
On Thu, 27 Jul 2023 at 19:29, Ilias Apalodimas <ilias.apalodimas at linaro.org>
wrote:
> Hi Maxim,
>
>
> This is too much for a single patch review. Can you pleas split it in
> something that's easier to review and comment.
>
> For example,
> #1 add the lwip library only
> #2-#5 add ping, wget, tcp and ping
>
> Some random comments below as well.
>
> On Fri, Jul 14, 2023 at 08:19:57PM +0600, Maxim Uvarov wrote:
> > This commit adds lwip library for the U-boot network
> > stack. Supported commands: ping, tftp, dhcp and wget.
> >
> > Signed-off-by: Maxim Uvarov <maxim.uvarov at linaro.org>
> > ---
> > .gitignore | 9 +
> > boot/bootmeth_pxe.c | 2 +-
> > cmd/net.c | 48 +----
> > cmd/pxe.c | 2 +-
> > include/net.h | 8 +-
> > lib/Kconfig | 2 +
> > lib/Makefile | 2 +
> > lib/lwip/Kconfig | 63 ++++++
> > lib/lwip/Makefile | 101 ++++++++++
> > lib/lwip/apps/dhcp/lwip-dhcp.c | 52 +++++
> > lib/lwip/apps/http/lwip-wget.c | 74 +++++++
> > lib/lwip/apps/ping/lwip_ping.c | 37 ++++
> > lib/lwip/apps/ping/lwip_ping.h | 24 +++
> > lib/lwip/apps/ping/ping.h | 35 ++++
> > lib/lwip/apps/tftp/lwip-tftp.c | 124 ++++++++++++
> > lib/lwip/cmd-lwip.c | 269 ++++++++++++++++++++++++++
> > lib/lwip/lwipopts.h | 203 +++++++++++++++++++
> > lib/lwip/port/if.c | 260 +++++++++++++++++++++++++
> > lib/lwip/port/include/arch/cc.h | 46 +++++
> > lib/lwip/port/include/arch/sys_arch.h | 59 ++++++
> > lib/lwip/port/include/limits.h | 0
> > lib/lwip/port/sys-arch.c | 20 ++
> > lib/lwip/ulwip.h | 9 +
> > net/Kconfig | 1 +
> > net/net.c | 24 +++
> > 25 files changed, 1430 insertions(+), 44 deletions(-)
> > create mode 100644 lib/lwip/Kconfig
> > create mode 100644 lib/lwip/Makefile
> > create mode 100644 lib/lwip/apps/dhcp/lwip-dhcp.c
> > create mode 100644 lib/lwip/apps/http/lwip-wget.c
> > create mode 100644 lib/lwip/apps/ping/lwip_ping.c
> > create mode 100644 lib/lwip/apps/ping/lwip_ping.h
> > create mode 100644 lib/lwip/apps/ping/ping.h
> > create mode 100644 lib/lwip/apps/tftp/lwip-tftp.c
> > create mode 100644 lib/lwip/cmd-lwip.c
> > create mode 100644 lib/lwip/lwipopts.h
> > create mode 100644 lib/lwip/port/if.c
> > create mode 100644 lib/lwip/port/include/arch/cc.h
> > create mode 100644 lib/lwip/port/include/arch/sys_arch.h
> > create mode 100644 lib/lwip/port/include/limits.h
> > create mode 100644 lib/lwip/port/sys-arch.c
> > create mode 100644 lib/lwip/ulwip.h
> >
> > diff --git a/.gitignore b/.gitignore
> > index eb769f144c..be3676c59e 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -104,3 +104,12 @@ __pycache__
> > # pylint files
> > /pylint.cur
> > /pylint.out/
> > +
> > +lib/lwip/lwip-external
> > +lib/lwip/apps/ping/ping.c
> > +lib/lwip/apps/http/http_client.c
> > +lib/lwip/apps/http/http_client.h
> > +lib/lwip/apps/tftp/tftp.c
> > +lib/lwip/apps/tftp/tftp_client.h
> > +lib/lwip/apps/tftp/tftp_common.h
> > +lib/lwip/apps/tftp/tftp_example.h
> > diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c
> > index e6992168c0..30331a9806 100644
> > --- a/boot/bootmeth_pxe.c
> > +++ b/boot/bootmeth_pxe.c
> > @@ -118,7 +118,7 @@ static int distro_pxe_read_file(struct udevice *dev,
> struct bootflow *bflow,
> > tftp_argv[1] = file_addr;
> > tftp_argv[2] = (void *)file_path;
> >
> > - if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv))
> > + if (do_lwip_tftp(ctx->cmdtp, 0, 3, tftp_argv))
> > return -ENOENT;
> > ret = pxe_get_file_size(&size);
> > if (ret)
> > diff --git a/cmd/net.c b/cmd/net.c
> > index 0e9f200ca9..6d704fba86 100644
> > --- a/cmd/net.c
> > +++ b/cmd/net.c
> > @@ -36,19 +36,9 @@ U_BOOT_CMD(
> > #endif
> >
> > #ifdef CONFIG_CMD_TFTPBOOT
> > -int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const
> argv[])
> > -{
> > - int ret;
> > -
> > - bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start");
> > - ret = netboot_common(TFTPGET, cmdtp, argc, argv);
> > - bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done");
> > - return ret;
> > -}
> > -
> > #if IS_ENABLED(CONFIG_IPV6)
> > U_BOOT_CMD(
> > - tftpboot, 4, 1, do_tftpb,
> > + tftpboot, 4, 1, do_lwip_tftp,
> > "boot image via network using TFTP protocol\n"
> > "To use IPv6 add -ipv6 parameter or use IPv6 hostIPaddr framed "
> > "with [] brackets",
> > @@ -56,7 +46,7 @@ U_BOOT_CMD(
> > );
> > #else
> > U_BOOT_CMD(
> > - tftpboot, 3, 1, do_tftpb,
> > + tftpboot, 3, 1, do_lwip_tftp,
> > "load file via network using TFTP protocol",
> > "[loadAddress] [[hostIPaddr:]bootfilename]"
> > );
> > @@ -112,7 +102,7 @@ U_BOOT_CMD(
> > static int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc,
> > char *const argv[])
> > {
> > - return netboot_common(DHCP, cmdtp, argc, argv);
> > + return do_lwip_dhcp();
> > }
> >
> > U_BOOT_CMD(
> > @@ -137,13 +127,11 @@ U_BOOT_CMD(
> > #endif
> >
> > #if defined(CONFIG_CMD_WGET)
> > -static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char *
> const argv[])
> > -{
> > - return netboot_common(WGET, cmdtp, argc, argv);
> > -}
> > +int do_lwip_wget(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[]);
> >
> > U_BOOT_CMD(
> > - wget, 3, 1, do_wget,
> > + wget, 3, 1, do_lwip_wget,
>
> I thought we agreed on keeping both the native u-boot stack and lwip until
> we can proove the later is useful. Do I remember this wrong? Same goes for
> all the other commands
>
> > "boot image via network using HTTP protocol",
> > "[loadAddress] [[hostIPaddr:]path and image name]"
> > );
> > @@ -376,28 +364,10 @@ 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[])
> > -{
> > - if (argc < 2)
> > - return CMD_RET_USAGE;
> > -
> > - net_ping_ip = string_to_ip(argv[1]);
> > - if (net_ping_ip.s_addr == 0)
> > - return CMD_RET_USAGE;
> > -
> > - if (net_loop(PING) < 0) {
> > - printf("ping failed; host %s is not alive\n", argv[1]);
> > - return CMD_RET_FAILURE;
> > - }
> > -
> > - printf("host %s is alive\n", argv[1]);
> > -
> > - return CMD_RET_SUCCESS;
> > -}
> > -
> > +extern int do_lwip_ping(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[]);
>
> Why extern? Cant we define it properly as part of our header file?
>
> > U_BOOT_CMD(
> > - ping, 2, 1, do_ping,
> > + ping, 2, 1, do_lwip_ping,
> > "send ICMP ECHO_REQUEST to network host",
> > "pingAddress"
> > );
> > diff --git a/cmd/pxe.c b/cmd/pxe.c
> > index db8e4697f2..bd4d6f5f2b 100644
> > --- a/cmd/pxe.c
> > +++ b/cmd/pxe.c
> > @@ -33,7 +33,7 @@ static int do_get_tftp(struct pxe_context *ctx, const
> char *file_path,
> > tftp_argv[1] = file_addr;
> > tftp_argv[2] = (void *)file_path;
> >
> > - if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv))
> > + if (do_lwip_tftp(ctx->cmdtp, 0, 3, tftp_argv))
> > return -ENOENT;
> > ret = pxe_get_file_size(sizep);
> > if (ret)
> > diff --git a/include/net.h b/include/net.h
> > index 1a99009959..6b573f3319 100644
> > --- a/include/net.h
> > +++ b/include/net.h
> > @@ -54,8 +54,10 @@ struct in_addr {
> > __be32 s_addr;
> > };
> >
> > +int do_lwip_dhcp(void);
> > +
> > /**
> > - * do_tftpb - Run the tftpboot command
> > + * do_lwip_tftp - Run the tftpboot command
> > *
> > * @cmdtp: Command information for tftpboot
> > * @flag: Command flags (CMD_FLAG_...)
> > @@ -63,7 +65,7 @@ struct in_addr {
> > * @argv: List of arguments
> > * Return: result (see enum command_ret_t)
> > */
> > -int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const
> argv[]);
> > +int do_lwip_tftp(struct cmd_tbl *cmdtp, int flag, int argc, char *const
> argv[]);
> >
> > /**
> > * An incoming packet handler.
> > @@ -561,7 +563,7 @@ extern int net_restart_wrap; /*
> Tried all network devices */
> >
> > enum proto_t {
> > BOOTP, RARP, ARP, TFTPGET, DHCP, PING, PING6, DNS, NFS, CDP,
> NETCONS,
> > - SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET
> > + SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET,
> LWIP
> > };
> >
> > extern char net_boot_file_name[1024];/* Boot File name */
> > diff --git a/lib/Kconfig b/lib/Kconfig
> > index 3c5a4ab386..7485a1f3bf 100644
> > --- a/lib/Kconfig
> > +++ b/lib/Kconfig
> > @@ -1031,3 +1031,5 @@ menu "FWU Multi Bank Updates"
> > source lib/fwu_updates/Kconfig
> >
> > endmenu
> > +
> > +source lib/lwip/Kconfig
> > diff --git a/lib/Makefile b/lib/Makefile
> > index d77b33e7f4..3b80a41187 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -91,6 +91,8 @@ obj-$(CONFIG_LIBAVB) += libavb/
> > obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += libfdt/
> > obj-$(CONFIG_$(SPL_TPL_)OF_REAL) += fdtdec_common.o fdtdec.o
> >
> > +obj-y += lwip/
> > +
> > ifdef CONFIG_SPL_BUILD
> > obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16-ccitt.o
> > obj-$(CONFIG_$(SPL_TPL_)HASH) += crc16-ccitt.o
> > diff --git a/lib/lwip/Kconfig b/lib/lwip/Kconfig
> > new file mode 100644
> > index 0000000000..3688ac3305
> > --- /dev/null
> > +++ b/lib/lwip/Kconfig
> > @@ -0,0 +1,63 @@
> > +menu "LWIP"
> > +config LWIP_LIB
> > + bool "Support LWIP library"
> > + help
> > + Selecting this option will enable the LWIP library code.
> > +
> > +menu "LWIP options"
> > +
> > +config LWIP_LIB_DEBUG
> > + bool "enable debug"
> > + default n
> > +
> > +config LWIP_LIB_NOASSERT
> > + bool "disable asserts"
> > + default y
> > + help
> > + Disabling asserts reduces binary size on 16k.
> > +
> > +config LWIP_LIB_TCP
>
> You need some useful help entry on all of those.
>
> > + bool "tcp"
> > + default y
> > +
> > +config LWIP_LIB_UDP
> > + bool "udp"
> > + default y
> > +
> > +config LWIP_LIB_DNS
> > + bool "dns"
> > + default n
> > +
> > +config LWIP_LIB_DHCP
> > + bool "dhcp"
> > + default y
> > +
> > +config LWIP_LIB_LOOPBACK
> > + bool "loopback"
> > + help
> > + Increases size on 1k.
> > +
> > +config LWIP_LIB_SOCKET
> > + bool "socket API"
> > +
> > +config LWIP_LIB_NETCONN
> > + bool "netconn API"
> > +
> > +config LWIP_LIB_MEM_SIZE
> > + int "mem size"
> > + default 1600
> > + range 1 4096
> > + help
> > + MEM_SIZE: the size of the heap memory. If the application will
> send
> > + a lot of data that needs to be copied, this should be set high.
> > +
> > +config LWIP_LIB_PBUF_LINK_HLEN
> > + int "pbuf link hlen"
> > + default 14
> > + range 4 1024
> > + help
> > + PBUF_LINK_HLEN: the number of bytes that should be allocated
> for a
> > + link level header. The default is 14, the standard value for
> Ethernet.
> > +endmenu
> > +
> > +endmenu
> > diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile
> > new file mode 100644
> > index 0000000000..e1a8a2a7b7
> > --- /dev/null
> > +++ b/lib/lwip/Makefile
> > @@ -0,0 +1,101 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +#
> > +# (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > +
> > +LWIPDIR=lwip-external/src
> > +
> > +ccflags-y += -I$(srctree)/lib/lwip/port/include
> > +ccflags-y += -I$(srctree)/lib/lwip/lwip-external/src/include
> -I$(srctree)/lib/lwip
> > +
> > +obj-$(CONFIG_NET) += $(LWIPDIR)/core/init.o \
> > + $(LWIPDIR)/core/def.o \
> > + $(LWIPDIR)/core/dns.o \
> > + $(LWIPDIR)/core/inet_chksum.o \
> > + $(LWIPDIR)/core/ip.o \
> > + $(LWIPDIR)/core/mem.o \
> > + $(LWIPDIR)/core/memp.o \
> > + $(LWIPDIR)/core/netif.o \
> > + $(LWIPDIR)/core/pbuf.o \
> > + $(LWIPDIR)/core/raw.o \
> > + $(LWIPDIR)/core/stats.o \
> > + $(LWIPDIR)/core/sys.o \
> > + $(LWIPDIR)/core/altcp.o \
> > + $(LWIPDIR)/core/altcp_alloc.o \
> > + $(LWIPDIR)/core/altcp_tcp.o \
> > + $(LWIPDIR)/core/tcp.o \
> > + $(LWIPDIR)/core/tcp_in.o \
> > + $(LWIPDIR)/core/tcp_out.o \
> > + $(LWIPDIR)/core/timeouts.o \
> > + $(LWIPDIR)/core/udp.o
> > +
> > +# IPv4
> > +obj-$(CONFIG_NET) += $(LWIPDIR)/core/ipv4/acd.o \
> > + $(LWIPDIR)/core/ipv4/autoip.o \
> > + $(LWIPDIR)/core/ipv4/dhcp.o \
> > + $(LWIPDIR)/core/ipv4/etharp.o \
> > + $(LWIPDIR)/core/ipv4/icmp.o \
> > + $(LWIPDIR)/core/ipv4/igmp.o \
> > + $(LWIPDIR)/core/ipv4/ip4_frag.o \
> > + $(LWIPDIR)/core/ipv4/ip4.o \
> > + $(LWIPDIR)/core/ipv4/ip4_addr.o
> > +# IPv6
> > +obj-$(CONFIG_NET) += $(LWIPDIR)/core/ipv6/dhcp6.o \
> > + $(LWIPDIR)/core/ipv6/ethip6.o \
> > + $(LWIPDIR)/core/ipv6/icmp6.o \
> > + $(LWIPDIR)/core/ipv6/inet6.o \
> > + $(LWIPDIR)/core/ipv6/ip6.o \
> > + $(LWIPDIR)/core/ipv6/ip6_addr.o \
> > + $(LWIPDIR)/core/ipv6/ip6_frag.o \
> > + $(LWIPDIR)/core/ipv6/mld6.o \
> > + $(LWIPDIR)/core/ipv6/nd6.o
> > +# API
> > +obj-$(CONFIG_NET) += $(LWIPDIR)/api/api_lib.o \
> > + $(LWIPDIR)/api/api_msg.o \
> > + $(LWIPDIR)/api/err.o \
> > + $(LWIPDIR)/api/if_api.o \
> > + $(LWIPDIR)/api/netbuf.o \
> > + $(LWIPDIR)/api/netdb.o \
> > + $(LWIPDIR)/api/netifapi.o \
> > + $(LWIPDIR)/api/sockets.o \
> > + $(LWIPDIR)/api/tcpip.o
> > +
> > +# Netdevs
> > +obj-$(CONFIG_NET) += $(LWIPDIR)/netif/ethernet.o
> > +
> > +obj-$(CONFIG_NET) += port/if.o
> > +obj-$(CONFIG_NET) += port/sys-arch.o
> > +
> > +obj-$(CONFIG_NET) += cmd-lwip.o
> > +
> > +
> > +ccflags-y += -I$(srctree)/lib/lwip/apps/ping
> > +.PHONY: $(obj)/apps/ping/ping.c
> > +$(obj)/apps/ping/ping.o: $(obj)/apps/ping/ping.c
> > +$(obj)/apps/ping/ping.c:
> > + cp $(srctree)/lib/lwip/lwip-external/contrib/apps/ping/ping.c
> $(obj)/apps/ping/ping.c
> > +
> > +obj-$(CONFIG_CMD_PING) += apps/ping/ping.o
> > +obj-$(CONFIG_CMD_PING) += apps/ping/lwip_ping.o
> > +
> > +$(obj)/apps/http/http_clinet.o: $(obj)/apps/http/http_client.c
> > +.PHONY: $(obj)/apps/http/http_client.c
> > +$(obj)/apps/http/http_client.c:
> > + cp $(srctree)/lib/lwip/lwip-external/src/apps/http/http_client.c
> $(obj)/apps/http/http_client.c
> > + cp
> $(srctree)/lib/lwip/lwip-external/src/include/lwip/apps/http_client.h
> $(obj)/apps/http/http_client.h
> > +
> > +obj-$(CONFIG_CMD_WGET) += apps/http/http_client.o
> > +obj-$(CONFIG_CMD_WGET) += apps/http/lwip-wget.o
> > +
> > +ccflags-y += -I$(CURDIR)/lib/lwip/apps/tftp
> > +$(obj)/apps/tftp/tftp.o: $(obj)/apps/tftp/tftp.c
> > +.PHONY: $(obj)/apps/tftp/tftp.c
> > +$(obj)/apps/tftp/tftp.c:
> > + cp $(srctree)/lib/lwip/lwip-external/src/apps/tftp/tftp.c
> $(obj)/apps/tftp/tftp.c
> > + cp
> $(srctree)/lib/lwip/lwip-external/src/include/lwip/apps/tftp_client.h
> $(obj)/apps/tftp/tftp_client.h
> > + cp
> $(srctree)/lib/lwip/lwip-external/src/include/lwip/apps/tftp_common.h
> $(obj)/apps/tftp/tftp_common.h
> > + cp
> $(srctree)/lib/lwip/lwip-external/contrib/examples/tftp/tftp_example.h
> $(obj)/apps/tftp/tftp_example.h
> > +
> > +obj-$(CONFIG_CMD_TFTPBOOT) += apps/tftp/tftp.o
> > +obj-$(CONFIG_CMD_TFTPBOOT) += apps/tftp/lwip-tftp.o
> > +
> > +obj-$(CONFIG_CMD_DHCP) += apps/dhcp/lwip-dhcp.o
> > diff --git a/lib/lwip/apps/dhcp/lwip-dhcp.c
> b/lib/lwip/apps/dhcp/lwip-dhcp.c
> > new file mode 100644
> > index 0000000000..2e4812c7dd
> > --- /dev/null
> > +++ b/lib/lwip/apps/dhcp/lwip-dhcp.c
> > @@ -0,0 +1,52 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <console.h>
> > +
> > +#include <lwip/dhcp.h>
> > +#include <lwip/prot/dhcp.h>
> > +
> > +#include "../../../lwip/ulwip.h"
> > +
> > +static struct dhcp dhcp;
> > +static bool dhcp_is_set;
> > +extern struct netif uboot_netif;
>
> Again why extern? I dont think it's sane to carry around the uboot_netif
> variable everytime we need to change a member. Instead we should functions
> doing that
>
yes, netif_get_by_index(1) can be used to get a default pointer to netif.
Changed that.
>
> > +
> > +static int ulwip_dhcp_tmo(void)
> > +{
> > + switch (dhcp.state) {
> > + case DHCP_STATE_BOUND:
> > + env_set("bootfile", dhcp.boot_file_name);
> > + env_set("ipaddr", ip4addr_ntoa(&dhcp.offered_ip_addr));
> > + env_set("netmask", ip4addr_ntoa(&dhcp.offered_sn_mask));
> > + env_set("serverip", ip4addr_ntoa(&dhcp.server_ip_addr));
> > + printf("DHCP client bound to address %s\n",
> ip4addr_ntoa(&dhcp.offered_ip_addr));
> > + break;
> > + default:
> > + return 0;
> > + }
> > +
> > + return 0;
> > +}
>
> The return value is always 0, why are we at least checking the result of
> env_set()?
>
>
Yes, thanks I did not check the error path here. Actually this chunk will
be changed when lwip will have a callback for changing states. That is in
progress. But for now I just registered a timeout to check if the state was
changed.
> > +
> > +int ulwip_dhcp(void)
> > +{
> > + int err;
> > +
> > + ulwip_set_tmo(ulwip_dhcp_tmo);
> > +
> > + if (!dhcp_is_set) {
> > + dhcp_set_struct(&uboot_netif, &dhcp);
> > + dhcp_is_set = true;
> > + }
> > + err = dhcp_start(&uboot_netif);
> > + if (err)
> > + printf("dhcp_start error %d\n", err);
> > +
> > + return err;
> > +}
> > diff --git a/lib/lwip/apps/http/lwip-wget.c
> b/lib/lwip/apps/http/lwip-wget.c
> > new file mode 100644
> > index 0000000000..0308b0b04a
> > --- /dev/null
> > +++ b/lib/lwip/apps/http/lwip-wget.c
> > @@ -0,0 +1,74 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <console.h>
> > +
> > +#include "http_client.h"
> > +#include "../../../lwip/ulwip.h"
> > +
> > +static ulong daddr;
> > +static httpc_connection_t settings;
> > +
> > +static err_t httpc_recv(void *arg, struct altcp_pcb *pcb, struct pbuf
> *p, err_t err)
> > +{
> > + struct pbuf *q;
> > + LWIP_UNUSED_ARG(err);
> > +
> > + if (!p)
> > + return ERR_BUF;
> > +
> > + for (q = p; q != NULL; q = q->next) {
> > + memcpy((void *)daddr, q->payload, q->len);
> > + printf("downloaded chunk size %d, to addr 0x%lx\n",
> q->len, daddr);
> > + daddr += q->len;
> > + }
> > + altcp_recved(pcb, p->tot_len);
> > + pbuf_free(p);
> > + return ERR_OK;
> > +}
> > +
> > +static void httpc_result(void *arg, httpc_result_t httpc_result, u32_t
> rx_content_len,
> > + u32_t srv_res, err_t err)
> > +{
> > + if (httpc_result == HTTPC_RESULT_OK) {
> > + printf("\n%d bytes successfully downloaded.\n",
> rx_content_len);
> > + env_set_ulong("filesize", rx_content_len);
> > + ulwip_exit(0);
> > + } else {
> > + printf("\nhttp eroror: %d\n", httpc_result);
> > + ulwip_exit(-1);
> > + }
> > +}
> > +
> > +int lwip_wget(ulong addr, char *url)
> > +{
> > + err_t err;
> > + int port = 80;
> > + char *server_name;
> > + httpc_state_t *connection;
> > +
> > + daddr = addr;
> > + server_name = env_get("serverip");
> > + if (!server_name) {
> > + printf("error: serverip variable has to be set\n");
> > + return CMD_RET_FAILURE;
> > + }
> > +
> > + printf("downloading %s to addr 0x%lx\n", url, addr);
> > + memset(&settings, 0, sizeof(httpc_connection_t));
>
> sizeof(settings) is preferred
>
> ok
> > + settings.result_fn = httpc_result;
> > + err = httpc_get_file_dns(server_name, port, url, &settings,
> > + httpc_recv, NULL, &connection);
> > + if (err != ERR_OK) {
> > + printf("httpc_init_connection failed\n");
> > + return err;
> > + }
> > +
> > + env_set_hex("fileaddr", addr);
> > + return 0;
> > +}
> > diff --git a/lib/lwip/apps/ping/lwip_ping.c
> b/lib/lwip/apps/ping/lwip_ping.c
> > new file mode 100644
> > index 0000000000..a05dc76326
> > --- /dev/null
> > +++ b/lib/lwip/apps/ping/lwip_ping.c
> > @@ -0,0 +1,37 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#include "lwip/opt.h"
> > +#include "lwip/ip_addr.h"
> > +#include "ping.h"
> > +
> > +#include "../../../lwip/ulwip.h"
>
> Please dont do this. Can't we just use -I or something and have this is a
> normal include path?
>
>
simple <ulwip.h> can be used. fixed.
> > +
> > +static ip_addr_t ip_target;
> > +
> > +static int ulwip_ping_tmo(void)
> > +{
> > +
> > + printf("ping failed; host %s is not alive\n",
> ipaddr_ntoa(&ip_target));
> > + return 0;
> > +}
> > +
> > +int lwip_ping_init(char *ping_addr)
> > +{
> > + int err;
> > +
> > + err = ipaddr_aton(ping_addr, &ip_target);
> > + if (err == 0) {
> > + printf("wrong ping addr string \"%s\" \n", ping_addr);
> > + return -1;
> > + }
> > +
> > + ulwip_set_tmo(ulwip_ping_tmo);
> > +
> > + ping_init(&ip_target);
> > +
> > + return 0;
> > +}
> > diff --git a/lib/lwip/apps/ping/lwip_ping.h
> b/lib/lwip/apps/ping/lwip_ping.h
> > new file mode 100644
> > index 0000000000..7f08095427
> > --- /dev/null
> > +++ b/lib/lwip/apps/ping/lwip_ping.h
> > @@ -0,0 +1,24 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#ifndef LWIP_PING_H
> > +#define LWIP_PING_H
> > +
> > +#include <lwip/ip_addr.h>
> > +
> > +/**
> > + * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is
> used
> > + */
> > +#ifndef PING_USE_SOCKETS
> > +#define PING_USE_SOCKETS 0
> > +#endif
> > +
> > +int lwip_ping_init(char *ping_addr);
> > +
> > +void ping_raw_init(void);
> > +void ping_send_now(void);
> > +
> > +#endif /* LWIP_PING_H */
> > diff --git a/lib/lwip/apps/ping/ping.h b/lib/lwip/apps/ping/ping.h
> > new file mode 100644
> > index 0000000000..0dd4bd78c7
> > --- /dev/null
> > +++ b/lib/lwip/apps/ping/ping.h
> > @@ -0,0 +1,35 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +#include "../../../lwip/ulwip.h"
> > +
> > +#include "lwip/prot/ip4.h"
> > +
> > +#define ip4_print_parts(a, b, c, d) \
> > + printf("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, a, b, c, d);
> > +
> > +#define ip4_print(ipaddr) \
> > + ip4_print_parts(\
> > + (u16_t)((ipaddr) != NULL ? ip4_addr1_16(ipaddr) :
> 0), \
> > + (u16_t)((ipaddr) != NULL ? ip4_addr2_16(ipaddr) :
> 0), \
> > + (u16_t)((ipaddr) != NULL ? ip4_addr3_16(ipaddr) :
> 0), \
> > + (u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) :
> 0))
> > +
> > +
> > +#define LWIP_DEBUG 1 /* ping_time is under ifdef*/
> > +#define PING_RESULT(cond) { \
> > + if (cond == 1) { \
> > + printf("host "); \
> > + ip4_print(addr); \
> > + printf(" is alive\n"); \
> > + printf(" %"U32_F" ms\n", (sys_now() - ping_time)); \
> > + ulwip_exit(0); \
> > + } else { \
> > + printf("ping failed; host "); \
> > + ip4_print(addr); \
> > + printf(" is not alive\n"); \
> > + ulwip_exit(-1); \
> > + } \
> > + } while (0);
> > +
> > +#include "lwip/ip_addr.h"
> > +void ping_init(const ip_addr_t *ping_addr);
> > diff --git a/lib/lwip/apps/tftp/lwip-tftp.c
> b/lib/lwip/apps/tftp/lwip-tftp.c
> > new file mode 100644
> > index 0000000000..511d82e600
> > --- /dev/null
> > +++ b/lib/lwip/apps/tftp/lwip-tftp.c
> > @@ -0,0 +1,124 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <console.h>
> > +
> > +#include "lwip/apps/tftp_client.h"
> > +#include "lwip/apps/tftp_server.h"
> > +#include <tftp_example.h>
> > +
> > +#include <string.h>
> > +
> > +#include "../../../lwip/ulwip.h"
> > +
> > +#if LWIP_UDP
> > +
> > +static ulong daddr;
> > +static ulong size;
> > +
> > +static void *tftp_open(const char *fname, const char *mode, u8_t
> is_write)
> > +{
> > + LWIP_UNUSED_ARG(mode);
> > + return NULL;
> > +}
> > +
> > +static void tftp_close(void *handle)
> > +{
> > + printf("\ndone\n");
> > + printf("Bytes transferred = %ld (0x%lx hex)\n", size, size);
> > +
> > + env_set_ulong("filesize", size);
> > + ulwip_exit(0);
> > +}
> > +
> > +static int tftp_read(void *handle, void *buf, int bytes)
> > +{
> > + return 0;
> > +}
> > +
> > +static int tftp_write(void *handle, struct pbuf *p)
> > +{
> > + struct pbuf *q;
> > +
> > + for (q = p; q != NULL; q = q->next) {
> > + memcpy((void *)daddr, q->payload, q->len);
> > + /* printf("downloaded chunk size %d, to addr 0x%lx\n",
> q->len, daddr); */
> > + daddr += q->len;
> > + size += q->len;
> > + printf("#");
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/* For TFTP client only */
> > +static void tftp_error(void *handle, int err, const char *msg, int size)
> > +{
> > + char message[100];
> > +
> > + LWIP_UNUSED_ARG(handle);
> > +
> > + memset(message, 0, sizeof(message));
> > + MEMCPY(message, msg, LWIP_MIN(sizeof(message)-1, (size_t)size));
> > +
> > + printf("TFTP error: %d (%s)", err, message);
> > +}
> > +
> > +static const struct tftp_context tftp = {
> > + tftp_open,
> > + tftp_close,
> > + tftp_read,
> > + tftp_write,
> > + tftp_error
> > +};
> > +
> > +int lwip_tftp(ulong addr, char *fname)
> > +{
> > + void *f = (void *)0x1; /*fake handle*/
> > + err_t err;
> > + ip_addr_t srv;
> > + int ret;
> > + char *server_ip;
> > +
> > + if (!fname || addr == 0)
> > + return CMD_RET_FAILURE;
> > +
> > + size = 0;
> > + daddr = addr;
> > + server_ip = env_get("serverip");
> > + if (!server_ip) {
> > + printf("error: serverip variable has to be set\n");
> > + return CMD_RET_FAILURE;
> > + }
> > +
> > + ret = ipaddr_aton(server_ip, &srv);
> > + LWIP_ASSERT("ipaddr_aton failed", ret == 1);
> > +
> > + printf("TFTP from server %s; our IP address is %s\n",
> > + server_ip, env_get("ipaddr"));
> > + printf("Filename '%s'.\n", fname);
> > + printf("Load address: 0x%lx\n", daddr);
> > + printf("Loading:");
> > +
> > + err = tftp_init_client(&tftp);
> > + if (!(err == ERR_OK || err == ERR_USE))
> > + printf("tftp_init_client err: %d\n", err);
> > +
> > + err = tftp_get(f, &srv, TFTP_PORT, fname, TFTP_MODE_OCTET);
> > + /* might return different errors, like routing problems */
> > + if (err != ERR_OK) {
> > + printf("tftp_get err=%d\n", err);
> > + }
> > + LWIP_ASSERT("tftp_get failed", err == ERR_OK);
> > +
> > + env_set_hex("fileaddr", addr);
> > + return err;
> > +}
> > +#else
> > +#error "UDP has to be supported"
> > +#endif /* LWIP_UDP */
> > diff --git a/lib/lwip/cmd-lwip.c b/lib/lwip/cmd-lwip.c
> > new file mode 100644
> > index 0000000000..625c8c53b8
> > --- /dev/null
> > +++ b/lib/lwip/cmd-lwip.c
> > @@ -0,0 +1,269 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Maxim Uvarov, maxim.uvarov at linaro.org
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <console.h>
> > +#include <display_options.h>
> > +#include <memalign.h>
> > +#include <net.h>
> > +#include <image.h>
> > +
> > +#include "apps/ping/lwip_ping.h"
> > +#include "ulwip.h"
> > +
> > +extern int uboot_lwip_init(void);
> > +extern int uboot_lwip_loop_is_done(void);
> > +
> > +static int do_lwip_info(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + printf("TBD: %s\n", __func__);
> > + return CMD_RET_SUCCESS;
> > +}
> > +
> > +static int do_lwip_init(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + if (!uboot_lwip_init())
> > + return CMD_RET_SUCCESS;
> > + return CMD_RET_FAILURE;
> > +}
> > +
> > +static int lwip_empty_tmo(void) { return 0; };
> > +int (*ulwip_tmo)(void) = lwip_empty_tmo;
> > +void ulwip_set_tmo(int (*tmo)(void))
> > +{
> > + ulwip_tmo = tmo;
> > +}
> > +
> > +static void ulwip_clear_tmo(void)
> > +{
> > + ulwip_tmo = lwip_empty_tmo;
> > +}
> > +
> > +static void ulwip_timeout_handler(void)
> > +{
> > + eth_halt();
> > + ulwip_tmo();
> > + net_set_state(NETLOOP_FAIL); /* we did not get the reply */
> > + ulwip_loop_set(0);
> > +}
> > +
> > +static int ulwip_loop(void)
> > +{
> > + ulwip_loop_set(1);
> > + if (net_loop(LWIP) < 0) {
> > + ulwip_loop_set(0);
> > + return CMD_RET_FAILURE;
> > + }
> > + ulwip_loop_set(0);
> > + return CMD_RET_SUCCESS;
> > +}
> > +
> > +#if defined(CONFIG_CMD_PING)
> > +int do_lwip_ping(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + if (argc < 2) {
> > + printf("argc = %d, error\n", argc);
> > + return CMD_RET_USAGE;
> > + }
> > +
> > + uboot_lwip_init();
> > +
> > + eth_init(); /* activate u-boot eth dev */
> > +
> > + printf("Using %s device\n", eth_get_name());
> > + printf("pinging addr: %s\n", argv[1]);
> > +
> > + net_set_timeout_handler(1000UL, ulwip_timeout_handler);
> > +
> > + if (lwip_ping_init(argv[1])) {
> > + printf("ping init fail\n");
> > + return CMD_RET_FAILURE;
> > + }
> > +
> > + ping_send_now();
> > +
> > + return ulwip_loop();
> > +}
> > +#endif /* CONFIG_CMD_PING */
> > +
> > +#if defined(CONFIG_CMD_WGET)
> > +extern int lwip_wget(ulong addr, char *url);
> > +
> > +int do_lwip_wget(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + char *url;
> > +
> > + if (argc < 2) {
> > + printf("argc = %d, error\n", argc);
> > + return CMD_RET_USAGE;
> > + }
> > + url = argv[1];
> > +
> > + uboot_lwip_init();
> > +
> > + eth_init(); /* activate u-boot eth dev */
> > +
> > + lwip_wget(image_load_addr, url);
> > +
> > + return ulwip_loop();
> > +}
> > +#endif
> > +
> > +#if defined(CONFIG_CMD_TFTPBOOT)
> > +extern int lwip_tftp(ulong addr, char *filename);
> > +
> > +int do_lwip_tftp(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + char *filename;
> > + ulong addr;
> > + char *end;
> > + int ret;
> > +
> > + switch (argc) {
> > + case 1:
> > + filename = env_get("bootfile");
> > + break;
> > + case 2:
> > + /*
> > + * Only one arg - accept two forms:
> > + * Just load address, or just boot file name. The latter
> > + * form must be written in a format which can not be
> > + * mis-interpreted as a valid number.
> > + */
> > + addr = hextoul(argv[1], &end);
> > + if (end == (argv[1] + strlen(argv[1]))) {
> > + image_load_addr = addr;
> > + filename = env_get("bootfile");
> > + } else {
> > + filename = argv[1];
> > + }
> > + break;
> > + case 3:
> > + image_load_addr = hextoul(argv[1], NULL);
> > + filename = argv[2];
> > + break;
> > + default:
> > + return CMD_RET_USAGE;
> > + }
> > +
> > + uboot_lwip_init();
> > +
> > + eth_init(); /* activate u-boot eth dev */
> > +
> > + ret = lwip_tftp(image_load_addr, filename);
> > + if (ret)
> > + return ret;
> > +
> > + return ulwip_loop();
> > +}
> > +#endif /* CONFIG_CMD_TFTPBOOT */
> > +
> > +#if defined(CONFIG_CMD_DHCP)
> > +extern int ulwip_dhcp(void);
> > +
> > +int do_lwip_dhcp(void)
> > +{
> > + int ret;
> > + char *filename;
> > +
> > + uboot_lwip_init();
> > +
> > + ret = ulwip_dhcp();
> > +
> > + net_set_timeout_handler(2000UL, ulwip_timeout_handler);
> > +
> > + ulwip_loop();
> > + if (IS_ENABLED(CONFIG_CMD_TFTPBOOT)) {
> > + ulwip_clear_tmo();
> > +
> > + filename = env_get("bootfile");
> > + if (!filename) {
> > + printf("no bootfile\n");
> > + return CMD_RET_FAILURE;
> > + }
> > +
> > + eth_init(); /* activate u-boot eth dev */
> > + net_set_timeout_handler(20000UL, ulwip_timeout_handler);
> > + lwip_tftp(image_load_addr, filename);
> > +
> > + ret = ulwip_loop();
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int _do_lwip_dhcp(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + return do_lwip_dhcp();
> > +}
> > +#endif /* CONFIG_CMD_DHCP */
> > +
> > +static struct cmd_tbl cmds[] = {
> > + U_BOOT_CMD_MKENT(info, 1, 0, do_lwip_info, "Info and stats", ""),
> > + U_BOOT_CMD_MKENT(init, 1, 0, do_lwip_init,
> > + "initialize lwip stack", ""),
> > +#if defined(CONFIG_CMD_LWIP_PING)
> > + U_BOOT_CMD_MKENT(ping, 2, 0, do_lwip_ping,
> > + "send ICMP ECHO_REQUEST to network host",
> > + "pingAddress"),
> > +#endif
> > +#if defined(CONFIG_CMD_WGET)
> > + U_BOOT_CMD_MKENT(wget, 2, 0, do_lwip_wget, "", ""),
> > +#endif
> > +#if defined(CONFIG_CMD_TFTPBOOT)
> > + U_BOOT_CMD_MKENT(tftp, 3, 0, do_lwip_tftp,
> > + "boot image via network using TFTP protocol\n",
> > + "[loadAddress] [[hostIPaddr:]bootfilename]"),
> > +#endif
> > +#if defined(CONFIG_CMD_DHCP)
> > + U_BOOT_CMD_MKENT(dhcp, 1, 0, _do_lwip_dhcp,
> > + "boot image via network using DHCP/TFTP protocol",
> > + ""),
> > +#endif
> > +};
> > +
> > +static int do_ops(struct cmd_tbl *cmdtp, int flag, int argc,
> > + char *const argv[])
> > +{
> > + struct cmd_tbl *cp;
> > +
> > + cp = find_cmd_tbl(argv[1], cmds, ARRAY_SIZE(cmds));
> > +
> > + argc--;
> > + argv++;
> > +
> > + if (cp == NULL || argc > cp->maxargs)
> > + return CMD_RET_USAGE;
> > + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
> > + return CMD_RET_SUCCESS;
> > +
> > + return cp->cmd(cmdtp, flag, argc, argv);
> > +}
> > +
> > +U_BOOT_CMD(
> > + lwip, 4, 1, do_ops,
> > + "LWIP sub system",
> > + "info - display info\n"
> > + "init - init LWIP\n"
> > + "ping addr - pingAddress\n"
> > + "wget http://IPadress/url/\n"
> > + "tftp [loadAddress] [[hostIPaddr:]bootfilename]\n"
> > + "dhcp - boot image via network using DHCP/TFTP protocol\n"
> > + );
> > +
> > +/* Old command kept for compatibility. Same as 'mmc info' */
> > +U_BOOT_CMD(
> > + lwipinfo, 1, 0, do_lwip_info,
> > + "display LWIP info",
> > + "- display LWIP stack info"
> > +);
> > diff --git a/lib/lwip/lwipopts.h b/lib/lwip/lwipopts.h
> > new file mode 100644
> > index 0000000000..b943d7b9be
> > --- /dev/null
> > +++ b/lib/lwip/lwipopts.h
> > @@ -0,0 +1,203 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#ifndef LWIP_LWIPOPTS_H
> > +#define LWIP_LWIPOPTS_H
> > +
> > +#include "lwipopts.h"
> > +
> > +#if defined(CONFIG_LWIP_LIB_DEBUG)
> > +#define LWIP_DEBUG 1
> > +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
> > +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
> > +#define ETHARP_DEBUG LWIP_DBG_OFF
> > +#define NETIF_DEBUG LWIP_DBG_OFF
> > +#define PBUF_DEBUG LWIP_DBG_OFF
> > +#define API_LIB_DEBUG LWIP_DBG_OFF
> > +#define API_MSG_DEBUG LWIP_DBG_OFF
> > +#define SOCKETS_DEBUG LWIP_DBG_OFF
> > +#define ICMP_DEBUG LWIP_DBG_OFF
> > +#define IGMP_DEBUG LWIP_DBG_OFF
> > +#define INET_DEBUG LWIP_DBG_OFF
> > +#define IP_DEBUG LWIP_DBG_OFF
> > +#define IP_REASS_DEBUG LWIP_DBG_OFF
> > +#define RAW_DEBUG LWIP_DBG_OFF
> > +#define MEM_DEBUG LWIP_DBG_OFF
> > +#define MEMP_DEBUG LWIP_DBG_OFF
> > +#define SYS_DEBUG LWIP_DBG_OFF
> > +#define TIMERS_DEBUG LWIP_DBG_OFF
> > +#define TCP_DEBUG LWIP_DBG_OFF
> > +#define TCP_INPUT_DEBUG LWIP_DBG_OFF
> > +#define TCP_FR_DEBUG LWIP_DBG_OFF
> > +#define TCP_RTO_DEBUG LWIP_DBG_OFF
> > +#define TCP_CWND_DEBUG LWIP_DBG_OFF
> > +#define TCP_WND_DEBUG LWIP_DBG_OFF
> > +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
> > +#define TCP_RST_DEBUG LWIP_DBG_OFF
> > +#define TCP_QLEN_DEBUG LWIP_DBG_OFF
> > +#define UDP_DEBUG LWIP_DBG_OFF
> > +#define TCPIP_DEBUG LWIP_DBG_OFF
> > +#define SLIP_DEBUG LWIP_DBG_OFF
> > +#define DHCP_DEBUG LWIP_DBG_ON
> > +#define AUTOIP_DEBUG LWIP_DBG_ON
> > +#define DNS_DEBUG LWIP_DBG_OFF
> > +#define IP6_DEBUG LWIP_DBG_OFF
> > +#define DHCP6_DEBUG LWIP_DBG_OFF
> > +#else
> > +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
> > +#define LWIP_DBG_TYPES_ON LWIP_DBG_OFF
> > +#define ETHARP_DEBUG LWIP_DBG_OFF
> > +#define NETIF_DEBUG LWIP_DBG_OFF
> > +#define PBUF_DEBUG LWIP_DBG_OFF
> > +#define API_LIB_DEBUG LWIP_DBG_OFF
> > +#define API_MSG_DEBUG LWIP_DBG_OFF
> > +#define SOCKETS_DEBUG LWIP_DBG_OFF
> > +#define ICMP_DEBUG LWIP_DBG_OFF
> > +#define IGMP_DEBUG LWIP_DBG_OFF
> > +#define INET_DEBUG LWIP_DBG_OFF
> > +#define IP_DEBUG LWIP_DBG_OFF
> > +#define IP_REASS_DEBUG LWIP_DBG_OFF
> > +#define RAW_DEBUG LWIP_DBG_OFF
> > +#define MEM_DEBUG LWIP_DBG_OFF
> > +#define MEMP_DEBUG LWIP_DBG_OFF
> > +#define SYS_DEBUG LWIP_DBG_OFF
> > +#define TIMERS_DEBUG LWIP_DBG_OFF
> > +#define TCP_DEBUG LWIP_DBG_OFF
> > +#define TCP_INPUT_DEBUG LWIP_DBG_OFF
> > +#define TCP_FR_DEBUG LWIP_DBG_OFF
> > +#define TCP_RTO_DEBUG LWIP_DBG_OFF
> > +#define TCP_CWND_DEBUG LWIP_DBG_OFF
> > +#define TCP_WND_DEBUG LWIP_DBG_OFF
> > +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
> > +#define TCP_RST_DEBUG LWIP_DBG_OFF
> > +#define TCP_QLEN_DEBUG LWIP_DBG_OFF
> > +#define UDP_DEBUG LWIP_DBG_OFF
> > +#define TCPIP_DEBUG LWIP_DBG_OFF
> > +#define SLIP_DEBUG LWIP_DBG_OFF
> > +#define DHCP_DEBUG LWIP_DBG_OFF
> > +#define AUTOIP_DEBUG LWIP_DBG_OFF
> > +#define DNS_DEBUG LWIP_DBG_OFF
> > +#define IP6_DEBUG LWIP_DBG_OFF
> > +#define DHCP6_DEBUG LWIP_DBG_OFF
> > +#endif
> > +#define LWIP_TESTMODE 0
> > +
> > +#if defined(CONFIG_LWIP_LIB_NOASSERT)
> > +#define LWIP_NOASSERT 1
> > +#define LWIP_ASSERT(message, assertion)
> > +#endif
> > +
> > +#include "lwip/debug.h"
> > +
> > +#define SYS_LIGHTWEIGHT_PROT 0
> > +#define NO_SYS 0
> > +
> > +#define MEM_ALIGNMENT 1
> > +#define MEM_SIZE CONFIG_LWIP_LIB_MEM_SIZE
> > +
> > +#define MEMP_NUM_PBUF 4
> > +#define MEMP_NUM_RAW_PCB 2
> > +#define MEMP_NUM_UDP_PCB 4
> > +#define MEMP_NUM_TCP_PCB 2
> > +#define MEMP_NUM_TCP_PCB_LISTEN 2
> > +#define MEMP_NUM_TCP_SEG 16
> > +#define MEMP_NUM_REASSDATA 1
> > +#define MEMP_NUM_ARP_QUEUE 2
> > +#define MEMP_NUM_SYS_TIMEOUT 4
> > +#define MEMP_NUM_NETBUF 2
> > +#define MEMP_NUM_NETCONN 32
> > +#define MEMP_NUM_TCPIP_MSG_API 8
> > +#define MEMP_NUM_TCPIP_MSG_INPKT 8
> > +#define PBUF_POOL_SIZE 8
> > +
> > +#define LWIP_ARP 1
> > +
> > +#define IP_FORWARD 0
> > +#define IP_OPTIONS_ALLOWED 1
> > +#define IP_REASSEMBLY 1
> > +#define IP_FRAG 1
> > +#define IP_REASS_MAXAGE 3
> > +#define IP_REASS_MAX_PBUFS 4
> > +#define IP_FRAG_USES_STATIC_BUF 0
> > +
> > +#define IP_DEFAULT_TTL 255
> > +
> > +#define LWIP_ICMP 1
> > +
> > +#define LWIP_RAW 1
> > +
> > +#if defined(CONFIG_LWIP_LIB_DHCP)
> > +#define LWIP_DHCP 1
> > +#define LWIP_DHCP_BOOTP_FILE 1
> > +#else
> > +#define LWIP_DHCP 0
> > +#endif
> > +#define LWIP_DHCP_DOES_ACD_CHECK 0
> > +
> > +#define LWIP_AUTOIP 0
> > +
> > +#define LWIP_SNMP 0
> > +
> > +#define LWIP_IGMP 0
> > +
> > +#if defined(CONFIG_LWIP_LIB_DNS)
> > +#define LWIP_DNS 1
> > +#else
> > +#define LWIP_DNS 0
> > +#endif
> > +
> > +#if defined(CONFIG_LWIP_LIB_TCP)
> > +#define LWIP_UDP 1
> > +#else
> > +#define LWIP_UDP 0
> > +#endif
> > +
> > +#if defined(CONFIG_LWIP_LIB_TCP)
> > +#define LWIP_TCP 1
> > +#else
> > +#define LWIP_TCP 0
> > +#endif
> > +
> > +#define LWIP_LISTEN_BACKLOG 0
> > +
> > +#define PBUF_LINK_HLEN CONFIG_LWIP_LIB_PBUF_LINK_HLEN
> > +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS +
> 40 + PBUF_LINK_HLEN)
> > +
> > +#define LWIP_HAVE_LOOPIF 0
> > +
> > +#if defined(CONFIG_LWIP_LIB_NETCONN)
> > +#define LWIP_NETCONN 1
> > +#else
> > +#define LWIP_NETCONN 0
> > +#define LWIP_DISABLE_MEMP_SANITY_CHECKS 1
> > +#endif
> > +
> > +#if defined(CONFIG_LWIP_LIB_SOCKET)
> > +#define LWIP_SOCKET 1
> > +
> > +#define SO_REUSE 1
> > +#else
> > +#define LWIP_SOCKET 0
> > +#define SO_REUSE 0
> > +#endif
> > +
> > +#define LWIP_STATS 0
> > +
> > +#define PPP_SUPPORT 0
> > +
> > +#define LWIP_TCPIP_CORE_LOCKING 0
> > +
> > +#if defined(CONFIG_LWIP_LIB_LOOPBACK)
> > +#define LWIP_NETIF_LOOPBACK 1
> > +#else
> > +#define LWIP_NETIF_LOOPBACK 0
> > +#endif
> > +/* use malloc instead of pool */
> > +#define MEMP_MEM_MALLOC 1
> > +#define MEMP_MEM_INIT 1
> > +#define MEM_LIBC_MALLOC 1
> > +
> > +#endif /* LWIP_LWIPOPTS_H */
> > diff --git a/lib/lwip/port/if.c b/lib/lwip/port/if.c
> > new file mode 100644
> > index 0000000000..37c02a451f
> > --- /dev/null
> > +++ b/lib/lwip/port/if.c
> > @@ -0,0 +1,260 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +extern int eth_init(void); /* net.h */
> > +extern void string_to_enetaddr(const char *addr, uint8_t *enetaddr); /*
> net.h */
> > +extern struct in_addr net_ip;
> > +extern u8 net_ethaddr[6];
> > +
> > +#include "lwip/debug.h"
> > +#include "lwip/arch.h"
> > +#include "netif/etharp.h"
> > +#include "lwip/stats.h"
> > +#include "lwip/def.h"
> > +#include "lwip/mem.h"
> > +#include "lwip/pbuf.h"
> > +#include "lwip/sys.h"
> > +#include "lwip/netif.h"
> > +
> > +#include "lwip/ip.h"
> > +
> > +#define IFNAME0 'e'
> > +#define IFNAME1 '0'
> > +
> > +static struct pbuf *low_level_input(struct netif *netif);
> > +static int uboot_net_use_lwip;
> > +
> > +int ulwip_enabled(void)
> > +{
> > + return uboot_net_use_lwip;
> > +}
> > +
> > +/* 1 - in loop
> > + * 0 - no loop
> > + */
> > +static int loop_lwip;
> > +
> > +/* ret 1 - in loop
> > + * 0 - no loop
> > + */
> > +int ulwip_in_loop(void)
> > +{
> > + return loop_lwip;
> > +}
> > +
> > +void ulwip_loop_set(int loop)
> > +{
> > + loop_lwip = loop;
> > +}
> > +
> > +static int ulwip_app_err;
> > +
> > +void ulwip_exit(int err)
> > +{
> > + ulwip_app_err = err;
> > + ulwip_loop_set(0);
> > +}
> > +
> > +int ulwip_app_get_err(void)
> > +{
> > + return ulwip_app_err;
> > +}
> > +
> > +struct uboot_lwip_if {
> > +};
> > +
> > +#if defined(CONFIG_CMD_DHCP)
> > +struct netif uboot_netif;
> > +#else
> > +static struct netif uboot_netif;
> > +#endif
>
> I am not sure I understand why this exists. If you want to change some
> some members of the struct from the dhcp code, why dont you create a
> function that resides here?
>
>
ok. changed to use a helper function to get netif pointer.
> > +
> > +#define LWIP_PORT_INIT_NETMASK(addr) IP4_ADDR((addr), 255, 255, 255, 0)
> > +
> > +extern uchar *net_rx_packet;
> > +extern int net_rx_packet_len;
> > +
> > +int uboot_lwip_poll(void)
> > +{
> > + struct pbuf *p;
> > + int err;
> > +
> > + p = low_level_input(&uboot_netif);
> > + if (!p) {
> > + printf("error p = low_level_input = NULL\n");
> > + return 0;
> > + }
> > +
> > + err = ethernet_input(p, &uboot_netif);
> > + if (err)
> > + printf("ip4_input err %d\n", err);
> > +
> > + return 0;
> > +}
> > +
> > +static struct pbuf *low_level_input(struct netif *netif)
> > +{
> > + struct pbuf *p, *q;
> > + u16_t len = net_rx_packet_len;
> > + uchar *data = net_rx_packet;
> > +
> > +#if ETH_PAD_SIZE
> > + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
> > +#endif
> > +
> > + /* We allocate a pbuf chain of pbufs from the pool. */
> > + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
> > + if (p) {
> > +#if ETH_PAD_SIZE
> > + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding
> word */
> > +#endif
> > + /* We iterate over the pbuf chain until we have read the
> entire
> > + * packet into the pbuf.
> > + */
> > + for (q = p; q != NULL; q = q->next) {
> > + /* Read enough bytes to fill this pbuf in the
> chain. The
> > + * available data in the pbuf is given by the
> q->len
> > + * variable.
> > + * This does not necessarily have to be a memcpy,
> you can also preallocate
> > + * pbufs for a DMA-enabled MAC and after receiving
> truncate it to the
> > + * actually received size. In this case, ensure
> the tot_len member of the
> > + * pbuf is the sum of the chained pbuf len members.
> > + */
> > + MEMCPY(q->payload, data, q->len);
> > + data += q->len;
> > + }
> > + //acknowledge that packet has been read();
> > +
> > +#if ETH_PAD_SIZE
> > + pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding
> word */
> > +#endif
> > + LINK_STATS_INC(link.recv);
> > + } else {
> > + //drop packet();
> > + LINK_STATS_INC(link.memerr);
> > + LINK_STATS_INC(link.drop);
> > + }
> > +
> > + return p;
> > +}
> > +
> > +static int ethernetif_input(struct pbuf *p, struct netif *netif)
> > +{
> > + struct ethernetif *ethernetif;
> > +
> > + ethernetif = netif->state;
> > +
> > + /* move received packet into a new pbuf */
> > + p = low_level_input(netif);
> > +
> > + /* if no packet could be read, silently ignore this */
> > + if (p) {
> > + /* pass all packets to ethernet_input, which decides what
> packets it supports */
> > + if (netif->input(p, netif) != ERR_OK) {
> > + LWIP_DEBUGF(NETIF_DEBUG, ("%s: IP input error\n",
> __func__));
> > + pbuf_free(p);
> > + p = NULL;
> > + }
> > + }
> > + return 0;
> > +}
> > +
> > +static err_t low_level_output(struct netif *netif, struct pbuf *p)
> > +{
> > + int err;
> > +
> > + err = eth_send(p->payload, p->len);
> > + if (err != 0) {
> > + printf("eth_send error %d\n", err);
> > + return ERR_ABRT;
> > + }
> > + return ERR_OK;
> > +}
> > +
> > +err_t uboot_lwip_if_init(struct netif *netif)
> > +{
> > + struct uboot_lwip_if *uif = (struct uboot_lwip_if
> *)malloc(sizeof(struct uboot_lwip_if));
> > +
> > + if (!uif) {
> > + printf("uboot_lwip_if: out of memory\n");
> > + return ERR_MEM;
> > + }
> > + netif->state = uif;
> > +
> > + netif->name[0] = IFNAME0;
> > + netif->name[1] = IFNAME1;
> > +
> > + netif->hwaddr_len = ETHARP_HWADDR_LEN;
> > + string_to_enetaddr(env_get("ethaddr"), netif->hwaddr);
> > +#if defined(CONFIG_LWIP_LIB_DEBUG)
> > + printf(" MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
> > + netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2],
> > + netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]);
> > +#endif
> > +
> > +#if LWIP_IPV4
> > + netif->output = etharp_output;
> > +#endif /* LWIP_IPV4 */
> > +#if LWIP_IPV6
> > + netif->output_ip6 = ethip6_output;
> > +#endif /* LWIP_IPV6 */
> > + netif->linkoutput = low_level_output;
> > + netif->mtu = 1500;
> > + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
> NETIF_FLAG_LINK_UP;
> > +
> > + eth_init(); /* activate u-boot eth dev */
> > +
> > + if (IS_ENABLED(CONFIG_LWIP_LIB_DEBUG)) {
> > + printf("Initialized LWIP stack\n");
> > + }
> > +
> > + return ERR_OK;
> > +}
> > +
> > +int uboot_lwip_init(void)
> > +{
> > + ip4_addr_t ipaddr, netmask, gw;
> > +
> > + if (uboot_net_use_lwip)
> > + return CMD_RET_SUCCESS;
> > +
> > + ip4_addr_set_zero(&gw);
> > + ip4_addr_set_zero(&ipaddr);
> > + ip4_addr_set_zero(&netmask);
> > +
> > + ipaddr_aton(env_get("ipaddr"), &ipaddr);
> > + ipaddr_aton(env_get("ipaddr"), &netmask);
> > +
> > + LWIP_PORT_INIT_NETMASK(&netmask);
> > + if (IS_ENABLED(CONFIG_LWIP_LIB_DEBUG)) {
> > + printf("Starting lwIP, IP: %s\n", ip4addr_ntoa(&ipaddr));
> > + printf(" GW: %s\n", ip4addr_ntoa(&gw));
> > + printf(" mask: %s\n", ip4addr_ntoa(&netmask));
> > + }
> > +
> > + if (!netif_add(&uboot_netif, &ipaddr, &netmask, &gw,
> > + &uboot_netif, uboot_lwip_if_init, ethernetif_input))
> > + printf("err: netif_add failed!\n");
> > +
> > + netif_set_up(&uboot_netif);
> > + netif_set_link_up(&uboot_netif);
> > +#if LWIP_IPV6
> > + netif_create_ip6_linklocal_address(&uboot_netif, 1);
> > + printf(" IPv6: %s\n",
> ip6addr_ntoa(netif_ip6_addr(uboot_netif, 0)));
> > +#endif /* LWIP_IPV6 */
> > +
> > + uboot_net_use_lwip = 1;
> > +
> > + return CMD_RET_SUCCESS;
> > +}
> > +
> > +/* placeholder, not used now */
> > +void uboot_lwip_destroy(void)
> > +{
> > + uboot_net_use_lwip = 0;
> > +}
> > diff --git a/lib/lwip/port/include/arch/cc.h
> b/lib/lwip/port/include/arch/cc.h
> > new file mode 100644
> > index 0000000000..db30d7614e
> > --- /dev/null
> > +++ b/lib/lwip/port/include/arch/cc.h
> > @@ -0,0 +1,46 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#ifndef LWIP_ARCH_CC_H
> > +#define LWIP_ARCH_CC_H
> > +
> > +#include <linux/types.h>
> > +#include <linux/kernel.h>
> > +
> > +#define LWIP_ERRNO_INCLUDE <errno.h>
> > +
> > +#define LWIP_ERRNO_STDINCLUDE 1
> > +#define LWIP_NO_UNISTD_H 1
> > +#define LWIP_TIMEVAL_PRIVATE 1
> > +
> > +extern unsigned int lwip_port_rand(void);
> > +#define LWIP_RAND() (lwip_port_rand())
> > +
> > +/* different handling for unit test, normally not needed */
> > +#ifdef LWIP_NOASSERT_ON_ERROR
> > +#define LWIP_ERROR(message, expression, handler) do { if
> (!(expression)) { \
> > + handler; }} while (0)
> > +#endif
> > +
> > +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
> > +
> > +#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at
> line %d in %s\n", \
> > + x, __LINE__, __FILE__); } while (0)
> > +
> > +static inline int atoi(const char *str)
> > +{
> > + int r = 0;
> > + int i;
> > +
> > + for (i = 0; str[i] != '\0'; ++i)
> > + r = r * 10 + str[i] - '0';
> > +
> > + return r;
> > +}
> > +
> > +#define LWIP_ERR_T int
> > +
> > +#endif /* LWIP_ARCH_CC_H */
> > diff --git a/lib/lwip/port/include/arch/sys_arch.h
> b/lib/lwip/port/include/arch/sys_arch.h
> > new file mode 100644
> > index 0000000000..8d95146275
> > --- /dev/null
> > +++ b/lib/lwip/port/include/arch/sys_arch.h
> > @@ -0,0 +1,59 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#ifndef LWIP_ARCH_SYS_ARCH_H
> > +#define LWIP_ARCH_SYS_ARCH_H
> > +
> > +#include "lwip/opt.h"
> > +#include "lwip/arch.h"
> > +#include "lwip/err.h"
> > +
> > +#define ERR_NEED_SCHED 123
> > +
> > +void sys_arch_msleep(u32_t delay_ms);
> > +#define sys_msleep(ms) sys_arch_msleep(ms)
> > +
> > +#if SYS_LIGHTWEIGHT_PROT
> > +typedef u32_t sys_prot_t;
> > +#endif /* SYS_LIGHTWEIGHT_PROT */
> > +
> > +#include <errno.h>
> > +
> > +#define SYS_MBOX_NULL NULL
> > +#define SYS_SEM_NULL NULL
> > +
> > +typedef u32_t sys_prot_t;
> > +
> > +struct sys_sem;
> > +typedef struct sys_sem *sys_sem_t;
> > +#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL))
> > +#define sys_sem_set_invalid(sem) do { if ((sem) != NULL) { *(sem) =
> NULL; }} while (0)
> > +
> > +/* let sys.h use binary semaphores for mutexes */
> > +#define LWIP_COMPAT_MUTEX 1
> > +#define LWIP_COMPAT_MUTEX_ALLOWED 1
> > +
> > +struct sys_mbox;
> > +typedef struct sys_mbox *sys_mbox_t;
> > +#define sys_mbox_valid(mbox) (((mbox) != NULL) && (*(mbox) != NULL))
> > +#define sys_mbox_set_invalid(mbox) do { if ((mbox) != NULL) { *(mbox) =
> NULL; }} while (0)
> > +
> > +struct sys_thread;
> > +typedef struct sys_thread *sys_thread_t;
> > +
> > +static inline u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
> > +{
> > + return 0;
> > +};
> > +
> > +static inline err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
> > +{
> > + return 0;
> > +};
> > +
> > +#define sys_sem_signal(s)
> > +
> > +#endif /* LWIP_ARCH_SYS_ARCH_H */
> > diff --git a/lib/lwip/port/include/limits.h
> b/lib/lwip/port/include/limits.h
> > new file mode 100644
> > index 0000000000..e69de29bb2
> > diff --git a/lib/lwip/port/sys-arch.c b/lib/lwip/port/sys-arch.c
> > new file mode 100644
> > index 0000000000..609eeccf8c
> > --- /dev/null
> > +++ b/lib/lwip/port/sys-arch.c
> > @@ -0,0 +1,20 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. <maxim.uvarov at linaro.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <rand.h>
> > +#include "lwip/opt.h"
> > +
> > +u32_t sys_now(void)
> > +{
> > + return get_timer(0);
> > +}
> > +
> > +u32_t lwip_port_rand(void)
> > +{
> > + return (u32_t)rand();
> > +}
> > +
> > diff --git a/lib/lwip/ulwip.h b/lib/lwip/ulwip.h
> > new file mode 100644
> > index 0000000000..11ca52aa1f
> > --- /dev/null
> > +++ b/lib/lwip/ulwip.h
> > @@ -0,0 +1,9 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +int ulwip_enabled(void);
> > +int ulwip_in_loop(void);
> > +int ulwip_loop_set(int loop);
> > +int ulwip_exit(int err);
> > +int uboot_lwip_poll(void);
> > +int ulwip_app_get_err(void);
> > +void ulwip_set_tmo(int (*tmo)(void));
> > diff --git a/net/Kconfig b/net/Kconfig
> > index a1ec3f8542..2c5d8b8aca 100644
> > --- a/net/Kconfig
> > +++ b/net/Kconfig
> > @@ -5,6 +5,7 @@
> > menuconfig NET
> > bool "Networking support"
> > default y
> > + select LWIP_LIB
> >
> > if NET
> >
> > diff --git a/net/net.c b/net/net.c
> > index 57da9bda85..3d9a2e798a 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -121,6 +121,7 @@
> > #endif
> > #include <net/tcp.h>
> > #include <net/wget.h>
> > +#include "../lib/lwip/ulwip.h"
> >
> > /** BOOTP EXTENTIONS **/
> >
> > @@ -438,7 +439,11 @@ int net_loop(enum proto_t protocol)
> > #endif
> >
> > bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
> > +#if defined(CONFIG_LWIP_LIB)
> > + if (!ulwip_enabled() || !ulwip_in_loop())
> > +#endif
> > net_init();
> > +
> > if (eth_is_on_demand_init()) {
> > eth_halt();
> > eth_set_current();
> > @@ -619,6 +624,18 @@ restart:
> > */
> > eth_rx();
> >
> > +#if defined(CONFIG_LWIP_LIB)
> > + if (ulwip_enabled()) {
> > + net_set_state(NETLOOP_CONTINUE);
> > + if (!ulwip_in_loop()) {
> > + if (ulwip_app_get_err())
> > + net_set_state(NETLOOP_FAIL);
> > + else
> > + net_set_state(NETLOOP_SUCCESS);
> > + goto done;
> > + }
> > + }
> > +#endif
> > /*
> > * Abort if ctrl-c was pressed.
> > */
> > @@ -1177,6 +1194,13 @@ void net_process_received_packet(uchar
> *in_packet, int len)
> > if (len < ETHER_HDR_SIZE)
> > return;
> >
> > +#if defined(CONFIG_LWIP_LIB)
> > + if (ulwip_enabled()) {
> > + uboot_lwip_poll();
> > + return;
> > + }
> > +#endif
> > +
> > #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
> > if (push_packet) {
> > (*push_packet)(in_packet, len);
> > --
> > 2.30.2
> >
>
> Thanks
> /Ilias
>
Agree that the patch is really huge. And it's even complex to navigate over
the comments. I will split it into smaller changs.
What I also worry about is IPv6 support which theoretically exists and is
supported by lwip, but I did not test it. Because of
original commands have IPv5 it will be good to not break working code.
BR,
Maxim.
More information about the U-Boot
mailing list