From patchwork Thu Jun 29 12:34:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 697689 Delivered-To: patch@linaro.org Received: by 2002:adf:e885:0:0:0:0:0 with SMTP id d5csp4866219wrm; Thu, 29 Jun 2023 05:39:46 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7DtMRUVceTnT4hyGd3BnklZqIOR58w3Pe8BjH6IY0VLw7rU46z+eAq68Jw1GinEFPEdqsS X-Received: by 2002:a2e:8613:0:b0:2b6:b4fa:2f8f with SMTP id a19-20020a2e8613000000b002b6b4fa2f8fmr4975378lji.50.1688042385914; Thu, 29 Jun 2023 05:39:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688042385; cv=none; d=google.com; s=arc-20160816; b=u8EGGU282Dc5TzmiUMYm/QCbSMB/YjwrUfznxnRMTwm4nFCvXtxDvN5QbvN+iWoXgy rDHL75vilvvKpEKl5uVoF03G6UNt1taG554buVk7utWTkg/dl5aCCm2DzMEipDEaGH+B bw2vRJ4Gi/5L35CceHMfzjSEOmsegC33NXNYlHaxZuo1SE1qfJhE1pWZPoY3RzarzxJd IM2wgYoDICSm5x1wmYnvI3IXEvRHHiryfAZ0p4LXUUK5Zx40q1+zrcRHqrClclqtXbRl yv0mTxzl6byaqIKFtuGNqWmS3OMdeLRaQMwOKOFfNWOdpHQ+BGBRCcxTPEhr7/khRQu+ 6P7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature; bh=8KSMKzLHFo3bFtjtnVoiAzbvADJWL2Q2ENTIt9VRhwQ=; fh=378OOY3Qcv/6SzHacyD4RkrbXzlmlfqp4CO9kQxJxOk=; b=q9DM/g1UB7y8I7F9N75+neOVNf5T0uRMrhc36aU/zC2vgHmpBmmgHiAgsnnxJMgABB gYz9fnTabXt3VaQvNTpAP/ivVYchM42dXMgNB67h22es9eIXzT1Eh8/0OOQHVo/Ucs5a /o+skWjxlteGmuPiEpnTWQbaaqEizghPLyKL7ARwk5pexZRNpuPW297keUkia1waG1Ct /dtYua9FhpJ75YubkKZglkhhnJ9NNIFGv2Vh2w6nYo4BQKZYHhLvTngmKBui61b+hWPb SxfiPOHHJ8TTVUOugHdzBMrHph1KhhsJVyPl8dV522XvSi5aTbWd75SuAHlPVfM/MYA0 F0UQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=p7ujdSS8; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id p13-20020a2ea40d000000b002b6cb5572besi250652ljn.398.2023.06.29.05.39.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 05:39:45 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=p7ujdSS8; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2204386712; Thu, 29 Jun 2023 14:39:21 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="p7ujdSS8"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F3A82866B7; Thu, 29 Jun 2023 14:38:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 74937866F0 for ; Thu, 29 Jun 2023 14:36:43 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lj1-x229.google.com with SMTP id 38308e7fff4ca-2b5e7dba43cso9210861fa.1 for ; Thu, 29 Jun 2023 05:36:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688042200; x=1690634200; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=8KSMKzLHFo3bFtjtnVoiAzbvADJWL2Q2ENTIt9VRhwQ=; b=p7ujdSS8sDghA4w7hxavcYmq2ksVurjO78LyBlnGhlzysLtwul1JkD81X2Xv4ZR/7L JWrKQf3kYtPrmOlvSr4nA5vupjnTBHYMpmKhbLZ70aY1qTM2txfwrBAZXutDa3sI+9Bw rjCglGQIiqYfkPtZMPRTCaVYckbWNpGTKoAE12YvLfxB9msFZPwmFoXYQKD1Jvv+fbWu dnO/xgqa6ngNuOqHxZLqxB+fPCY9aeDMYVsVPxLaVdO5DzB98E4O17P+hEkQwo5DSnH1 zqaC0cFe/klKgzk4TNtklnHpUbqM9RRNc710kLCcdYL+uzWRNUmwdOGnDBNEtz5sf51m OCww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688042200; x=1690634200; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8KSMKzLHFo3bFtjtnVoiAzbvADJWL2Q2ENTIt9VRhwQ=; b=No5lGBNV0+W9aK5AFEH9sD7Y0miemiO/CMeWqR+pnHf/H7GrtXcBNJmgy4QG/B+ZdH zlt/qgxq3eraTa99nvNDsnnft9cuYfTrrP2ZSpbdV/MsCd/WUYc78XVpzny0hkfnj6Iu nTwM/cCbKtEAwtjiyPhsR+si/hZLYpsjk67Fozio7HvvzCDmoeuIJQCHP0M5A8fDRNzL rrNWi9e1OTTYWEfIsFC+L16KCFDclDNqdqNYwvmhBxJuKArG6Dny4Ur3pkPyJohRKLue AULgMNSiBylzfDfD8Nw08w/oppBP+W3kBdSN+iOeQLWY90PYJ/0do/vUI09tks/2ynyF a1Hw== X-Gm-Message-State: AC+VfDwooEotwegG94DKkTuBx3T4m+3s6gmokCk+NjBLjuw1ARin+rME pxGadu3M66aB64XssWBaE9lgmTMlEOUBhETpOQNVsg== X-Received: by 2002:a05:6512:3045:b0:4fb:89cd:9616 with SMTP id b5-20020a056512304500b004fb89cd9616mr5571039lfb.0.1688042200082; Thu, 29 Jun 2023 05:36:40 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id p3-20020ac246c3000000b004f59c182f7bsm2295742lfo.249.2023.06.29.05.36.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 05:36:39 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv2 1/3] net/lwip: add lwip-external submodule Date: Thu, 29 Jun 2023 18:34:28 +0600 Message-Id: <20230629123430.3679-1-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This commit adds the lwip library as a git submodule. I think there has to be advantages to compile lwip inside U-boot, i.e. use the same compiler and flags as the main code. One of them is LTO and the other is to enable additional debug options for network protocol during development. Also we can copy lwip library code inside U-boot, but for now I don't want to send all lwip code to the mailing list. So it's git submodule. Signed-off-by: Maxim Uvarov --- .gitmodules | 3 +++ lib/lwip/lwip-external | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 lib/lwip/lwip-external diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..afc709af10 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/lwip/lwip-external"] + path = lib/lwip/lwip-external + url = https://git.savannah.nongnu.org/git/lwip.git diff --git a/lib/lwip/lwip-external b/lib/lwip/lwip-external new file mode 160000 index 0000000000..3fe8d2fc43 --- /dev/null +++ b/lib/lwip/lwip-external @@ -0,0 +1 @@ +Subproject commit 3fe8d2fc43a9b69f7ed28c63d44a7744f9c0def9 From patchwork Thu Jun 29 12:34:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 697690 Delivered-To: patch@linaro.org Received: by 2002:adf:e885:0:0:0:0:0 with SMTP id d5csp4867030wrm; Thu, 29 Jun 2023 05:41:35 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5pfskRIUmEC8hJptpNxmtzcOSWWQgzWsgoDj2FN1rfiZzfGHZ03lylMWj3WXSwoTrtzIOf X-Received: by 2002:a05:6512:2824:b0:4fb:7888:7e6d with SMTP id cf36-20020a056512282400b004fb78887e6dmr9082016lfb.46.1688042495727; Thu, 29 Jun 2023 05:41:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688042495; cv=none; d=google.com; s=arc-20160816; b=p947KzabVocjstLmDEBiANcC7kzrQm3GfxXzMfTEwPQacV3GpvI6yfdNUDzV2qU+Ju tKmKWr7bihNy0hhGObJkKr86fMR2Hp7Hk83ecNRC96KbReU8bmSE06ZgMC3VWLFhFd1Y yWDS8SLl0FmQgbA9O6Jt7zvbQw4boqP1tvtTc8NQRGIOKbHhiCNCae6+F8B3n67L6mtK UaSfSRc0oSUr7IL43XtoHcxbfz9Vsy351d1NZ6Bj91XFxz0ICebSaDbnpP6IZT5hNKxa h4/n9BMlkFzHOrELfeVXmA1otednRwm2MeptTVqTXPI43225GoyetcoKAQqpP4nnqC1/ 3gMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=zR/mAiHa/g2ftLqabFFjszrLQ75T0+a4qDU/lDizxas=; fh=378OOY3Qcv/6SzHacyD4RkrbXzlmlfqp4CO9kQxJxOk=; b=lrrFuitXs2uTayiem0vfHFwAQ2aLB5BkcfJB+J0pQJ2aAeVmIGtPEcpVpqXizQzDdn BPF0AjMKPu0UmP45WjjfozBA9pUi8kL7+W5V3CuhaQX0635nI58uWK0wwE1RjF+ZRTd8 m3lNMHCu1FkLI86KArfPbqVY4LYtfZDMmPWqdaz7rb/LI76brWpKBtMLp3v1XqNtXwB5 glRquofWgrKRDwGa0N7MYIfvbrRwRnOlEzkfrfNxytGYD+t7Tddv9SB/fNML/IlMqQHI Jb6iaccmYMxnmiglvsCNK47zkPU6SMKZ3L8jyYmi7P2jFysvUSNiBXMT5voT3AE8uvpf +AyQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NDp4REYn; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id y23-20020ac24477000000b004f8643d7fc7si1187038lfl.60.2023.06.29.05.41.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 05:41:35 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NDp4REYn; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B8383866B5; Thu, 29 Jun 2023 14:41:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="NDp4REYn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 01853866DD; Thu, 29 Jun 2023 14:38:31 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NUMERIC_HTTP_ADDR,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x133.google.com (mail-lf1-x133.google.com [IPv6:2a00:1450:4864:20::133]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CCC51866F1 for ; Thu, 29 Jun 2023 14:36:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x133.google.com with SMTP id 2adb3069b0e04-4f865f0e16cso973208e87.3 for ; Thu, 29 Jun 2023 05:36:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688042204; x=1690634204; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zR/mAiHa/g2ftLqabFFjszrLQ75T0+a4qDU/lDizxas=; b=NDp4REYn9GD0niCchSHROxtGLK01G/BkoP3loFnaulK2PDhAtwHFitQ28Uqw/d35q4 jvVRP6SBVAi33vDpdO1kzbMxcjuT1FCAH543vOFD0iHRDG7sAo5O6g+v9eJTxZ1M9kNL Lsqm8Acj63JMrmrNgoaO9hiHpYUxMYEdpLUslzd4nFdG86GgtIVeyss2FG2ltTCgDHif 0lU9aV1tr9b4IQT/ZGqyQX1pOgDZXHII9xLhE3r6sZOSGUb26C03/kuhSD9TmU1Gno5R /6piBwCwkTnHUdQm/vJVyfx4P4tM3ChqM0rOxgBB/JzOsDRnEWCK/DXEk334BA/ByKA2 H/Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688042204; x=1690634204; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zR/mAiHa/g2ftLqabFFjszrLQ75T0+a4qDU/lDizxas=; b=cJNDSX+4PHbDDv9Y59ArHPSQNw7OvCCcQRGeAxWT8obNFuNBe2qU1NndT3L1uJbsS0 2sg8YkR0QQG3JVPKLD+J9ybWt+f1/OPEdXrDaO3rH5c1BosXXFyrdgMzNEafs4dy8PnN R6tL4hVWLPQkCEFV6BtjZYRcuCdKiEP8fEZMfuOknZ5g4kxrZi6O7dt8f1Oj7OdPr5C/ jIanlmhwA+yOjj2pgxEu/y6tkR38VwkHeFD8J9YAbqASzO/qWxYNihERMLilpmr1hzvv ygKzyDHbx+DE8Qx5G+LO5NqbqhTpHNBdHjMT1SExWbYsMUwaQn4Wu4LXtg+zt16tNn2B AStQ== X-Gm-Message-State: AC+VfDyfz5yg6TxagaoO1jlpUhzzzyRpLR4hH7+ookDW46xA4nq0InjB sGuXzAYBQV0Gex/282L3NXN3mBEf3SgkW4bNaqnOsg== X-Received: by 2002:a05:6512:39d0:b0:4f9:6581:8b4c with SMTP id k16-20020a05651239d000b004f965818b4cmr15713756lfu.44.1688042203680; Thu, 29 Jun 2023 05:36:43 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id p3-20020ac246c3000000b004f59c182f7bsm2295742lfo.249.2023.06.29.05.36.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 05:36:43 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv2 2/3] net/lwip: add README.lwip Date: Thu, 29 Jun 2023 18:34:29 +0600 Message-Id: <20230629123430.3679-2-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230629123430.3679-1-maxim.uvarov@linaro.org> References: <20230629123430.3679-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Just add inital README.lwip doc. Signed-off-by: Maxim Uvarov --- doc/README.lwip | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 doc/README.lwip diff --git a/doc/README.lwip b/doc/README.lwip new file mode 100644 index 0000000000..16f41049ab --- /dev/null +++ b/doc/README.lwip @@ -0,0 +1,90 @@ + RFC LWIP IP stack intergation for U-boot + ---------------------------------------- + +Reliable and bug free IP stack is usually an issue when you are trying to write it +from scratch. It looks like not, but when addinging new features it will be chelledging. +This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source +TCP/IP stack designed for embedded systems for U-boot. That will allow using already +written network applications for microcontrollers. + +LwIP  license: +lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. + +Main features include: +- Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE +- DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) +- APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API +- Extended features: IP forwarding over multiple network interfaces, TCP congestion control, RTT estimation and fast recovery/fast retransmit +- Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, mDNS responder, MQTT client, TFTP server + +U-boot implementation details: + +1. In general we can build lwIP as .a library and link it against u-boot or compile it in +the U-boot tree in the same way as other U-boot files. There are few reasons why I selected +the second variant: iwIP is very customizable with defines for features, memory size, types of +allocation, some internal types and platform specific code. And it was more easy to enable/disable + debug which is also done with defines, and is needed periodically. + +2. lwIP has 2 APIs - raw mode and sequential (as lwIP names it, or socket API as we name it in Linux). + This RFC implements only raw API as the proof of work. + +Raw IP means that the call back function for RX path is registered and will be called when packet +data passes the IP stack and is ready for the application. + +This RFC has an unmodified working ping example from lwip sources which registeres this callback. +  ping_pcb = raw_new(IP_PROTO_ICMP); +  raw_recv(ping_pcb, ping_recv, NULL); <- ping_recv is app callback. +  raw_bind(ping_pcb, IP_ADDR_ANY) + +Socket API also gives nice advantages due it will be easy to port linux socket applications to u-boot. +I.e. lwIP sockets compatible with the linux ones. But that will require RX thread running in the background. +So that means we need some kind of scheduler, locking and threading support or find some other solution. + +3.  Input and output + +RX packet path is injected to U-boot eth_rx() polling loop and TX patch is in eth_send() accordingly. +So we do not touch any drivers code and just eat packets when they are ready. + +4. Testing + +Unmodified ping example can be used. I did ping from qemu/u-boot tap device on the host: + +=> lwip init +=> lwip ping 192.168.1.2 +ping: recv 3 ms +tcpdump on the host: +5:09:10.925951 ARP, Request who-has 192.168.1.200 tell 192.168.1.200, length 28 15:09:12.114643 IP6 fe80::38e2:41ff:fec3:8bda > ip6-allrouters: ICMP6, router solicitation, length 16 15:09:20.370725 ARP, Request who-has 192.168.1.2 tell 192.168.1.200, length 28 15:09:20.370740 ARP, Reply 192.168.1.2 is-at 3a:e2:41:c3:8b:da (oui Unknown), length 28 15:09:20.372789 IP 192.168.1.200 > 192.168.1.2: ICMP echo request, id 44975, seq 1, length 40 15:09:20.372810 IP 192.168.1.2 > 192.168.1.200: ICMP echo reply, id 44975, seq 1, length 40 15:09:25.426636 ARP, Request who-has 192.168.1.200 tell 192.168.1.2, length 28 15:09:25.426870 ARP, Reply 192.168.1.200 is-at f6:11:01:02:03:04 (oui Unknown), length 28 + + +5. Wget example + +Http server has 192.168.1.2 IP address. (I did not port DNS resolving yet, +but it's also exist in lwip.) So example just downloads some file with http +protocol: + +Net: eth0: virtio-net#30 +Hit any key to stop autoboot: 0 +=> lwip init +Starting lwIP, local interface IP is 192.168.1.200 +Initialized LWIP stack +=> lwip wget http://192.168.1.2/ +downloading http://192.168.1.2/ to addr 0x40200000 +downloaded chunk size 294, to addr 0x40200000 +downloaded chunk size 318, to addr 0x40200126 +=> md 0x40200000 0x40 +40200000: 4f44213c 50595443 74682045 0a3e6c6d . +40200010: 6d74683c 3c0a3e6c 64616568 743c0a3e ..Welcome to +40200030: 6e69676e 2f3c2178 6c746974 3c0a3e65 nginx!.< +40200040: 6c797473 200a3e65 62202020 2079646f style>. body +40200050: 20200a7b 20202020 69772020 3a687464 {. width: +40200060: 65353320 200a3b6d 20202020 6d202020 35em;. m +40200070: 69677261 30203a6e 74756120 200a3b6f argin: 0 auto;. +40200080: 20202020 66202020 2d746e6f 696d6166 font-fami +40200090: 203a796c 6f686154 202c616d 64726556 ly: Tahoma, Verd +402000a0: 2c616e61 69724120 202c6c61 736e6173 ana, Arial, sans +402000b0: 7265732d 0a3b6669 20202020 2f3c0a7d -serif;. }...< +402000d0: 79646f62 683c0a3e 65573e31 6d6f636c body>.

Welcom +402000e0: 6f742065 69676e20 3c21786e 3e31682f e to nginx!

+402000f0: 3e703c0a 79206649 7320756f 74206565 .

If you see t From patchwork Thu Jun 29 12:34:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 697691 Delivered-To: patch@linaro.org Received: by 2002:adf:e885:0:0:0:0:0 with SMTP id d5csp4867602wrm; Thu, 29 Jun 2023 05:42:49 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7Ktf+6ZHOuM46nVL4LO87H3tRaqAeqpXNFq3s6nj7LtSeCEGssHuUTy7U5RQEBoFpdSDL7 X-Received: by 2002:a19:6909:0:b0:4f8:7513:8cb0 with SMTP id e9-20020a196909000000b004f875138cb0mr17045395lfc.2.1688042568682; Thu, 29 Jun 2023 05:42:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688042568; cv=none; d=google.com; s=arc-20160816; b=LLVCyJxRGOh7VBx/ZXygjKZ2PlF5s5lzEzlclaFI9J71GJKzH4FpXiseYVGhVI3yri lDoU1iFZNNSpdT2lZHqyJKcxj+i/k5ekPyreKWzP8holWDRVYdb9n8ZQgRm83gBYBUyl ng9inYbu5J9lGvs6NUJEsSfRcc0NnwAf3cUc1579zYqkySiNsn5AaiF95j4PKZ52W1WY M4pfnWqT5pOP5ee+XFhNInX+bxDQmyoFo/pKWqpeKapAdlDVwwybJ/iF/jIrT62GBIXU LbEmtakQB5Goa5mGcTz7pgs7oLF8L3hDnWcRUJBLPO9z97dgQ9bCCxnTBGNBwq34SlH6 1ilg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=DvvtAOAyJv7XaHJidgkQHvAZ7ftHDl8whyyzM2DnsDk=; fh=378OOY3Qcv/6SzHacyD4RkrbXzlmlfqp4CO9kQxJxOk=; b=eKEZGHqW2K1xHOH4CVcKSFIz1XBlcQuamuHeCBB6UUjh3xek/SgmXNmLIxvLGDdIjq QHNJL3+tUn5KRST/+SGzULM0zk5GMmI6m6DB5BWfiaBmHKSgtNQzuBfidoLohN0OVZYe KtO2VmMaB71TkmI5gnQHUCDANwYClUGuTR6V0Oot+mvYNFzNKyFRZA46ljixElpWktsW 4LMJ5F5TsqdfMXBxFooKOhPbz7JYoB1/WZXCJDAlPmH8jDxRORlGkvkocXv+OrOiUYzd iuFJetW6Nz04oZHynmI7leoND/jeF0mPGzvB5f/5mgoIji97QdxUjLL6QFvtxlQJNo/m 8S0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="C/VLcxNu"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id l3-20020ac25543000000b004f00067a98fsi3740299lfk.340.2023.06.29.05.42.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 05:42:48 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="C/VLcxNu"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 66F6A866C1; Thu, 29 Jun 2023 14:42:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="C/VLcxNu"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7888C86638; Thu, 29 Jun 2023 14:40:22 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [IPv6:2a00:1450:4864:20::135]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 17873866F6 for ; Thu, 29 Jun 2023 14:36:49 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=maxim.uvarov@linaro.org Received: by mail-lf1-x135.google.com with SMTP id 2adb3069b0e04-4fb7b2e3dacso1002849e87.0 for ; Thu, 29 Jun 2023 05:36:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1688042207; x=1690634207; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DvvtAOAyJv7XaHJidgkQHvAZ7ftHDl8whyyzM2DnsDk=; b=C/VLcxNuzt7Na5ATPncQgy7SfBUl63/vS7PV9vhzojGYlo155qTuk+WVUoY+TNJPrg HaVkhEr3iGEXZ+Z+8hm5vULaIIwRlzME6a7txX1xOgzwabMGUliAtXe2uEdxudJriCKW vklR/Dge6t37pKmcDhzvdNP9t2fmkoftQPGMb0c18jx11WuCHtqNFDQGdWyyyC+STJ9w GRKsL/7vXG1XHtiP83g7SPxTsp8rKgCyHZ76gu4vx5BLRJsgfIxN0dPVAmjDb0vgQL/F hTiOaopT/vI31mgnlAee/fLxJeyB8/1pQKEjO2BiIYzD/1mH237+mT2oUtsSeVjQMuhn 2zbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688042207; x=1690634207; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DvvtAOAyJv7XaHJidgkQHvAZ7ftHDl8whyyzM2DnsDk=; b=HUerJhoKoEZQJWwOB9Dn5RjY4Qx/h2vMB2vD7yyR5RYwhd/A7mEoJhvXm0B/vY/zv0 7atOuGJpgUeym0lJJyKGgJbmrbPquWP3rMyuDrdjW5l7e59pc5Qj7hQEEhJ9/DUrv5iu GUAdJUL6Q+ARE7LUoP33YtLnt3Xtn1TPWqKV5l7LnLNrrsSvLLFRGujOwAJQUiN73ofU nLmTIR7eCgz4yh8LzyqPpmQwJT+Yng286rQwZA1w9g6irAnwMjGTkBkAlhOFSEgqqTnN wgwbD7dxLbtgaE0Z7xtws9eK9US6Aisi32eSudVaoK5Yot0e/TIdey35+nDIXq0iQZjR cYpA== X-Gm-Message-State: AC+VfDzJUnZIKcbmfEfoFqTZ6FxRUZFPNF0PCTRovTJZmb7LUqkqN0/x CTEqRi6CAUT8kcqP7/D50SK5iQFpnz5/d1aCCEvoxg== X-Received: by 2002:ac2:5b46:0:b0:4f6:3677:54e with SMTP id i6-20020ac25b46000000b004f63677054emr21073610lfp.36.1688042206780; Thu, 29 Jun 2023 05:36:46 -0700 (PDT) Received: from localhost.localdomain ([45.82.14.220]) by smtp.gmail.com with ESMTPSA id p3-20020ac246c3000000b004f59c182f7bsm2295742lfo.249.2023.06.29.05.36.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Jun 2023 05:36:46 -0700 (PDT) From: Maxim Uvarov To: u-boot@lists.denx.de Cc: pbrobinson@redhat.com, ilias.apalodimas@linaro.org, joe.hershberger@ni.com, rfried.dev@gmail.com, trini@konsulko.com, goldsimon@gmx.de, lwip-devel@nongnu.org, Maxim Uvarov Subject: [PATCHv2 3/3] net/lwip: add lwip library for the network stack Date: Thu, 29 Jun 2023 18:34:30 +0600 Message-Id: <20230629123430.3679-3-maxim.uvarov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230629123430.3679-1-maxim.uvarov@linaro.org> References: <20230629123430.3679-1-maxim.uvarov@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This commit adds lwip library for the U-boot network stack. Supported commands: ping, tftp, dhcp and wget. Signed-off-by: Maxim Uvarov --- .gitignore | 9 + cmd/net.c | 38 +++- include/net.h | 2 +- lib/Kconfig | 2 + lib/Makefile | 2 + lib/lwip/Kconfig | 108 ++++++++++ lib/lwip/Makefile | 98 +++++++++ lib/lwip/apps/dhcp/lwip-dhcp.c | 52 +++++ lib/lwip/apps/http/lwip-wget.c | 71 +++++++ 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 | 121 +++++++++++ lib/lwip/cmd-lwip.c | 276 ++++++++++++++++++++++++++ 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/eth-uclass.c | 4 +- net/net.c | 25 +++ 23 files changed, 1496 insertions(+), 5 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/cmd/net.c b/cmd/net.c index 0e9f200ca9..5b3dfd6c7e 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -36,6 +36,10 @@ U_BOOT_CMD( #endif #ifdef CONFIG_CMD_TFTPBOOT +#if defined(CONFIG_CMD_LWIP_REPLACE_TFTP) +int do_lwip_tftp(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); +#endif int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int ret; @@ -56,7 +60,12 @@ U_BOOT_CMD( ); #else U_BOOT_CMD( - tftpboot, 3, 1, do_tftpb, + tftpboot, 3, 1, +#if defined(CONFIG_CMD_LWIP_REPLACE_TFTP) + do_lwip_tftp, +#else + do_tftpb, +#endif "load file via network using TFTP protocol", "[loadAddress] [[hostIPaddr:]bootfilename]" ); @@ -112,7 +121,11 @@ U_BOOT_CMD( static int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { +#if defined(CONFIG_CMD_LWIP_REPLACE_DHCP) + return do_lwip_dhcp(); +#else return netboot_common(DHCP, cmdtp, argc, argv); +#endif } U_BOOT_CMD( @@ -137,13 +150,22 @@ U_BOOT_CMD( #endif #if defined(CONFIG_CMD_WGET) +#if defined(CONFIG_CMD_LWIP_REPLACE_WGET) +int do_lwip_wget(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +#endif static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { return netboot_common(WGET, cmdtp, argc, argv); } U_BOOT_CMD( - wget, 3, 1, do_wget, + wget, 3, 1, +#if defined(CONFIG_CMD_LWIP_REPLACE_WGET) + do_lwip_wget, +#else + do_wget, +#endif "boot image via network using HTTP protocol", "[loadAddress] [[hostIPaddr:]path and image name]" ); @@ -376,6 +398,10 @@ static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, } #if defined(CONFIG_CMD_PING) +#if defined(CONFIG_CMD_LWIP_REPLACE_PING) +extern int do_lwip_ping(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); +#else static int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -395,9 +421,15 @@ static int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } +#endif U_BOOT_CMD( - ping, 2, 1, do_ping, + ping, 2, 1, +#if defined(CONFIG_CMD_LWIP_REPLACE_PING) + do_lwip_ping, +#else + do_ping, +#endif "send ICMP ECHO_REQUEST to network host", "pingAddress" ); diff --git a/include/net.h b/include/net.h index 1a99009959..8622983597 100644 --- a/include/net.h +++ b/include/net.h @@ -561,7 +561,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..80d540ba54 --- /dev/null +++ b/lib/lwip/Kconfig @@ -0,0 +1,108 @@ +menu "LWIP" +config LWIP_LIB + bool "Support LWIP library" + help + Selecting this option will enable the shared 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 + 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" + default n + help + Increases size on 1k. +config LWIP_LIB_SOCKET + bool "socket API" + default n +config LWIP_LIB_NETCONN + bool "netconn API" + default n +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 + +config CMD_LWIP + bool "lwip cmd" + default y + depends on LWIP_LIB + help + lwip networking command. + +config CMD_LWIP_PING + bool "ping" + default y + depends on CMD_LWIP + help + lwip ping command. + +config CMD_LWIP_REPLACE_PING + bool "replace original ping command" + default n + +config CMD_LWIP_WGET + bool "wget" + default y + depends on CMD_LWIP + help + lwip wget command. + +config CMD_LWIP_REPLACE_WGET + bool "replace original wget command" + default n + +config CMD_LWIP_TFTP + bool "tftp" + default y + depends on CMD_LWIP + help + lwip tftp command. + +config CMD_LWIP_REPLACE_TFTP + bool "replace original tftp command" + default n + +config CMD_LWIP_DHCP + bool "dhcp" + default y + depends on CMD_LWIP + depends on LWIP_LIB_DHCP + help + lwip dhcp command. + +config CMD_LWIP_REPLACE_DHCP + bool "replace original dhcp command" + default n +endmenu diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile new file mode 100644 index 0000000000..6f68eb04ed --- /dev/null +++ b/lib/lwip/Makefile @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro Ltd. + +LWIPDIR=lwip-external/src + +ccflags-y += -I$(CURDIR)/lib/lwip/port/include +ccflags-y += -I$(CURDIR)/lib/lwip/lwip-external/src/include -I$(CURDIR)/lib/lwip + +obj-$(CONFIG_LWIP_LIB) += $(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_LWIP_LIB) += $(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_LWIP_LIB) += $(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_LWIP_LIB) += $(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_LWIP_LIB) += $(LWIPDIR)/netif/ethernet.o + +obj-$(CONFIG_LWIP_LIB) += port/if.o +obj-$(CONFIG_LWIP_LIB) += port/sys-arch.o + +obj-$(CONFIG_CMD_LWIP) += cmd-lwip.o + +.PHONY: $(obj)/apps/ping/ping.c +$(obj)/apps/ping/ping.o: $(obj)/apps/ping/ping.c +$(obj)/apps/ping/ping.c: + cp ./lib/lwip/lwip-external/contrib/apps/ping/ping.c $(obj)/apps/ping/ping.c + +obj-$(CONFIG_CMD_LWIP) += apps/ping/ping.o +obj-$(CONFIG_CMD_LWIP) += 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 ./lib/lwip/lwip-external/src/apps/http/http_client.c $(obj)/apps/http/http_client.c + cp ./lib/lwip/lwip-external/src/include/lwip/apps/http_client.h $(obj)/apps/http/http_client.h + +obj-$(CONFIG_CMD_LWIP_WGET) += apps/http/http_client.o +obj-$(CONFIG_CMD_LWIP_WGET) += apps/http/lwip-wget.o + +$(obj)/apps/tftp/tftp.o: $(obj)/apps/tftp/tftp.c +.PHONY: $(obj)/apps/tftp/tftp.c +$(obj)/apps/tftp/tftp.c: + cp ./lib/lwip/lwip-external/src/apps/tftp/tftp.c $(obj)/apps/tftp/tftp.c + cp ./lib/lwip/lwip-external/src/include/lwip/apps/tftp_client.h $(obj)/apps/tftp/tftp_client.h + cp ./lib/lwip/lwip-external/src/include/lwip/apps/tftp_common.h $(obj)/apps/tftp/tftp_common.h + cp ./lib/lwip/lwip-external/contrib/examples/tftp/tftp_example.h $(obj)/apps/tftp/tftp_example.h + +obj-$(CONFIG_CMD_LWIP_TFTP) += apps/tftp/tftp.o +obj-$(CONFIG_CMD_LWIP_TFTP) += apps/tftp/lwip-tftp.o + +obj-$(CONFIG_CMD_LWIP_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. + */ + +#include +#include +#include + +#include +#include + +#include "../../../lwip/ulwip.h" + +static struct dhcp dhcp; +static bool dhcp_is_set; +extern struct netif uboot_netif; + +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; +} + +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..07aabd15f3 --- /dev/null +++ b/lib/lwip/apps/http/lwip-wget.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include + +#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); + 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)); + 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; + } + 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. + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "ping.h" + +#include "../../../lwip/ulwip.h" + +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. + */ + +#ifndef LWIP_PING_H +#define LWIP_PING_H + +#include + +/** + * 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..c38e83c8ee --- /dev/null +++ b/lib/lwip/apps/tftp/lwip-tftp.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +#include + +#include "lwip/apps/tftp_client.h" +#include "lwip/apps/tftp_server.h" +#include "tftp_example.h" + +#include + +#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); + 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); + + 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..d7cdc4e411 --- /dev/null +++ b/lib/lwip/cmd-lwip.c @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Maxim Uvarov, maxim.uvarov@linaro.org + */ + +#include +#include +#include +#include +#include +#include +#include + +#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_LWIP_REPLACE_PING) +static +#endif +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(); +} + +extern int lwip_wget(ulong addr, char *url); + +#if !defined(CONFIG_CMD_LWIP_REPLACE_WGET) +static +#endif +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(); +} + +#if defined(CONFIG_CMD_LWIP_TFTP) +extern int lwip_tftp(ulong addr, char *filename); +#if !defined(CONFIG_CMD_LWIP_REPLACE_TFTP) +static +#endif +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 + +#if defined(CONFIG_CMD_LWIP_DHCP) +extern int ulwip_dhcp(void); + +#if !defined(CONFIG_CMD_LWIP_REPLACE_DHCP) +static +#endif +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_LWIP_TFTP)) { + 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 + +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_LWIP_WGET) + U_BOOT_CMD_MKENT(wget, 2, 0, do_lwip_wget, "", ""), +#endif +#if defined(CONFIG_CMD_LWIP_TFTP) + 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_LWIP_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. + */ + +#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..15d44054be --- /dev/null +++ b/lib/lwip/port/if.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * (C) Copyright 2023 Linaro Ltd. + */ + +#include +#include +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_LWIP_DHCP) +struct netif uboot_netif; +#else +static struct netif uboot_netif; +#endif + +#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. + */ + +#ifndef LWIP_ARCH_CC_H +#define LWIP_ARCH_CC_H + +#include +#include + +#define LWIP_ERRNO_INCLUDE + +#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. + */ + +#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 + +#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. + */ + +#include +#include +#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/eth-uclass.c b/net/eth-uclass.c index f41da4b37b..6031ad805d 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -367,8 +367,10 @@ int eth_send(void *packet, int length) if (!current) return -ENODEV; - if (!eth_is_active(current)) + if (!eth_is_active(current)) { + printf("%s() !eth_is_active\n", __func__); return -EINVAL; + } ret = eth_get_ops(current)->send(current, packet, length); if (ret < 0) { diff --git a/net/net.c b/net/net.c index 57da9bda85..aa9dd85a99 100644 --- a/net/net.c +++ b/net/net.c @@ -121,6 +121,7 @@ #endif #include #include +#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,10 +624,23 @@ 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. */ if (ctrlc()) { + printf("-->enter ctrlc\n"); /* cancel any ARP that may not have completed */ net_arp_wait_packet_ip.s_addr = 0; @@ -1177,6 +1195,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);