Re: [PATCHv6 09/14] net/lwip: implement lwIP port to U-Boot

2023-08-18 Thread Simon Goldschmidt
Hi all,

could you please remove the lwip-devel list from CC? I am interested in these 
mails, but the more you dive into U-Boot specific things here, the less people 
on our lwip list will be interested in this topic.

Thanks,
Simon


Am 18. August 2023 14:53:43 MESZ schrieb Maxim Uvarov :
>On Wed, 16 Aug 2023 at 15:01, Ilias Apalodimas 
>wrote:
>
>> On Mon, Aug 14, 2023 at 07:32:48PM +0600, Maxim Uvarov wrote:
>> > Implement network lwIP interface connected to the U-boot.
>> > Keep original file structure widely used fro lwIP ports.
>> > (i.e. port/if.c port/sys-arch.c).
>>
>> What the patch does is obvious.  Try to describe *why* we need this
>>
>> >
>> > Signed-off-by: Maxim Uvarov 
>> > ---
>> >  net/eth-uclass.c  |   8 +
>> >  net/lwip/port/if.c| 260 ++
>> >  net/lwip/port/include/arch/cc.h   |  39 
>> >  net/lwip/port/include/arch/sys_arch.h |  56 ++
>> >  net/lwip/port/include/limits.h|   0
>> >  net/lwip/port/sys-arch.c  |  20 ++
>> >  6 files changed, 383 insertions(+)
>> >  create mode 100644 net/lwip/port/if.c
>> >  create mode 100644 net/lwip/port/include/arch/cc.h
>> >  create mode 100644 net/lwip/port/include/arch/sys_arch.h
>> >  create mode 100644 net/lwip/port/include/limits.h
>> >  create mode 100644 net/lwip/port/sys-arch.c
>> >
>> > diff --git a/net/eth-uclass.c b/net/eth-uclass.c
>> > index c393600fab..6625f6d8a5 100644
>> > --- a/net/eth-uclass.c
>> > +++ b/net/eth-uclass.c
>> > @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
>> >  struct eth_device_priv {
>> >   enum eth_state_t state;
>> >   bool running;
>> > + ulwip ulwip;
>> >  };
>> >
>> >  /**
>> > @@ -347,6 +348,13 @@ int eth_init(void)
>> >   return ret;
>> >  }
>> >
>> > +struct ulwip *eth_lwip_priv(struct udevice *current)
>> > +{
>> > + struct eth_device_priv *priv = dev_get_uclass_priv(current);
>> > +
>> > + return &priv->ulwip;
>> > +}
>> > +
>> >  void eth_halt(void)
>> >  {
>> >   struct udevice *current;
>> > diff --git a/net/lwip/port/if.c b/net/lwip/port/if.c
>> > new file mode 100644
>> > index 00..625a9c10bf
>> > --- /dev/null
>> > +++ b/net/lwip/port/if.c
>> > @@ -0,0 +1,260 @@
>> > +// SPDX-License-Identifier: GPL-2.0
>> > +
>> > +/*
>> > + * (C) Copyright 2023 Linaro Ltd. 
>> > + */
>> > +
>> > +#include 
>> > +#include 
>> > +#include 
>> > +#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/ethip6.h"
>> > +
>> > +#include "lwip/ip.h"
>> > +
>> > +#define IFNAME0 'e'
>> > +#define IFNAME1 '0'
>>
>> Why is this needed and how was 'e0' chosen?
>> Dont we have a device name in the udevice struct?
>>
>>
>If we assume that we have lwip netif on top of an active U-Boot eth device,
>then it can be any name.
>
>  /** descriptive abbreviation */
>
>  char name[2];
>
>./net/lwip/lwip-external/contrib/examples/ethernetif/ethernetif.c:#define
>IFNAME0 'e'
>./net/lwip/lwip-external/contrib/examples/ethernetif/ethernetif.c:#define
>IFNAME1 'n'
>./net/lwip/lwip-external/contrib/ports/unix/port/netif/tapif.c:#define
>IFNAME0 't'
>./net/lwip/lwip-external/contrib/ports/unix/port/netif/tapif.c:#define
>IFNAME1 'p'
>./net/lwip/lwip-external/contrib/ports/unix/port/netif/vdeif.c:#define
>IFNAME0 'v'
>./net/lwip/lwip-external/contrib/ports/unix/port/netif/vdeif.c:#define
>IFNAME1 'd'
>./net/lwip/lwip-external/contrib/ports/win32/pcapif.c:#define IFNAME0
>'e'
>./net/lwip/lwip-external/contrib/ports/win32/pcapif.c:#define IFNAME1
>'0'
>./net/lwip/lwip-external/src/netif/bridgeif.c:#define IFNAME0 'b'
>./net/lwip/lwip-external/src/netif/bridgeif.c:#define IFNAME1 'r'
>./net/lwip/port/if.c:#define IFNAME0 'u'
>./net/lwip/port/if.c:#define IFNAME1 '0'
>
>
>
>> > +
>> > +static struct pbuf *low_level_input(struct netif *netif);
>> > +
>> > +int ulwip_enabled(void)
>> > +{
>> > + struct ulwip *ulwip;
>> > +
>> > + ulwip = eth_lwip_priv(eth_get_dev());
>>
>> eth_get_dev() can return NULL.  There are various locations of this call
>> that needs fixing
>>
>
>
>ok.
>
>
>>
>> > + return ulwip->init_done;
>> > +}
>> > +
>> > +
>> > +struct ulwip_if {
>> > +};
>>
>> Why the forward declaration?
>>
>> > +
>> > +#define LWIP_PORT_INIT_NETMASK(addr)  IP4_ADDR((addr), 255, 255, 255, 0)
>>
>> Why are we limiting the netmask to a class C network?
>>
>>
>that can be completely removed.
>
>
>> > +
>> > +void ulwip_poll(void)
>> > +{
>> > + struct pbuf *p;
>> > + int err;
>> > + struct netif *netif = netif_get_by_index(1);
>>
>> First of all netif can be NULL. Apart from that always requesting index 1
>> feels wrong.  We should do something similar to eth_get_dev() and get the
>> *active* device correlation to an index
>>
>>
>I expect that it will 

Re: [PATCHv6 09/14] net/lwip: implement lwIP port to U-Boot

2023-08-18 Thread Maxim Uvarov
On Wed, 16 Aug 2023 at 15:01, Ilias Apalodimas 
wrote:

> On Mon, Aug 14, 2023 at 07:32:48PM +0600, Maxim Uvarov wrote:
> > Implement network lwIP interface connected to the U-boot.
> > Keep original file structure widely used fro lwIP ports.
> > (i.e. port/if.c port/sys-arch.c).
>
> What the patch does is obvious.  Try to describe *why* we need this
>
> >
> > Signed-off-by: Maxim Uvarov 
> > ---
> >  net/eth-uclass.c  |   8 +
> >  net/lwip/port/if.c| 260 ++
> >  net/lwip/port/include/arch/cc.h   |  39 
> >  net/lwip/port/include/arch/sys_arch.h |  56 ++
> >  net/lwip/port/include/limits.h|   0
> >  net/lwip/port/sys-arch.c  |  20 ++
> >  6 files changed, 383 insertions(+)
> >  create mode 100644 net/lwip/port/if.c
> >  create mode 100644 net/lwip/port/include/arch/cc.h
> >  create mode 100644 net/lwip/port/include/arch/sys_arch.h
> >  create mode 100644 net/lwip/port/include/limits.h
> >  create mode 100644 net/lwip/port/sys-arch.c
> >
> > diff --git a/net/eth-uclass.c b/net/eth-uclass.c
> > index c393600fab..6625f6d8a5 100644
> > --- a/net/eth-uclass.c
> > +++ b/net/eth-uclass.c
> > @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
> >  struct eth_device_priv {
> >   enum eth_state_t state;
> >   bool running;
> > + ulwip ulwip;
> >  };
> >
> >  /**
> > @@ -347,6 +348,13 @@ int eth_init(void)
> >   return ret;
> >  }
> >
> > +struct ulwip *eth_lwip_priv(struct udevice *current)
> > +{
> > + struct eth_device_priv *priv = dev_get_uclass_priv(current);
> > +
> > + return &priv->ulwip;
> > +}
> > +
> >  void eth_halt(void)
> >  {
> >   struct udevice *current;
> > diff --git a/net/lwip/port/if.c b/net/lwip/port/if.c
> > new file mode 100644
> > index 00..625a9c10bf
> > --- /dev/null
> > +++ b/net/lwip/port/if.c
> > @@ -0,0 +1,260 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * (C) Copyright 2023 Linaro Ltd. 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#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/ethip6.h"
> > +
> > +#include "lwip/ip.h"
> > +
> > +#define IFNAME0 'e'
> > +#define IFNAME1 '0'
>
> Why is this needed and how was 'e0' chosen?
> Dont we have a device name in the udevice struct?
>
>
If we assume that we have lwip netif on top of an active U-Boot eth device,
then it can be any name.

  /** descriptive abbreviation */

  char name[2];

./net/lwip/lwip-external/contrib/examples/ethernetif/ethernetif.c:#define
IFNAME0 'e'
./net/lwip/lwip-external/contrib/examples/ethernetif/ethernetif.c:#define
IFNAME1 'n'
./net/lwip/lwip-external/contrib/ports/unix/port/netif/tapif.c:#define
IFNAME0 't'
./net/lwip/lwip-external/contrib/ports/unix/port/netif/tapif.c:#define
IFNAME1 'p'
./net/lwip/lwip-external/contrib/ports/unix/port/netif/vdeif.c:#define
IFNAME0 'v'
./net/lwip/lwip-external/contrib/ports/unix/port/netif/vdeif.c:#define
IFNAME1 'd'
./net/lwip/lwip-external/contrib/ports/win32/pcapif.c:#define IFNAME0
'e'
./net/lwip/lwip-external/contrib/ports/win32/pcapif.c:#define IFNAME1
'0'
./net/lwip/lwip-external/src/netif/bridgeif.c:#define IFNAME0 'b'
./net/lwip/lwip-external/src/netif/bridgeif.c:#define IFNAME1 'r'
./net/lwip/port/if.c:#define IFNAME0 'u'
./net/lwip/port/if.c:#define IFNAME1 '0'



> > +
> > +static struct pbuf *low_level_input(struct netif *netif);
> > +
> > +int ulwip_enabled(void)
> > +{
> > + struct ulwip *ulwip;
> > +
> > + ulwip = eth_lwip_priv(eth_get_dev());
>
> eth_get_dev() can return NULL.  There are various locations of this call
> that needs fixing
>


ok.


>
> > + return ulwip->init_done;
> > +}
> > +
> > +
> > +struct ulwip_if {
> > +};
>
> Why the forward declaration?
>
> > +
> > +#define LWIP_PORT_INIT_NETMASK(addr)  IP4_ADDR((addr), 255, 255, 255, 0)
>
> Why are we limiting the netmask to a class C network?
>
>
that can be completely removed.


> > +
> > +void ulwip_poll(void)
> > +{
> > + struct pbuf *p;
> > + int err;
> > + struct netif *netif = netif_get_by_index(1);
>
> First of all netif can be NULL. Apart from that always requesting index 1
> feels wrong.  We should do something similar to eth_get_dev() and get the
> *active* device correlation to an index
>
>
I expect that it will be 1 lwip netif for all eth defs. And only active eth
dev works with lwip.
This can be reconsidered but might be not a part of the initial patch set.


> > +
> > + p = low_level_input(netif);
> > + if (!p) {
> > + log_err("error p = low_level_input = NULL\n");
>
> This looks like a debug message.
> 'Network interface undefined' or something else, which is more readable.
>
> > + return;
> > + }
> > +
> > + /* ethern

Re: [PATCHv6 09/14] net/lwip: implement lwIP port to U-Boot

2023-08-16 Thread Ilias Apalodimas
On Mon, Aug 14, 2023 at 07:32:48PM +0600, Maxim Uvarov wrote:
> Implement network lwIP interface connected to the U-boot.
> Keep original file structure widely used fro lwIP ports.
> (i.e. port/if.c port/sys-arch.c).

What the patch does is obvious.  Try to describe *why* we need this 

> 
> Signed-off-by: Maxim Uvarov 
> ---
>  net/eth-uclass.c  |   8 +
>  net/lwip/port/if.c| 260 ++
>  net/lwip/port/include/arch/cc.h   |  39 
>  net/lwip/port/include/arch/sys_arch.h |  56 ++
>  net/lwip/port/include/limits.h|   0
>  net/lwip/port/sys-arch.c  |  20 ++
>  6 files changed, 383 insertions(+)
>  create mode 100644 net/lwip/port/if.c
>  create mode 100644 net/lwip/port/include/arch/cc.h
>  create mode 100644 net/lwip/port/include/arch/sys_arch.h
>  create mode 100644 net/lwip/port/include/limits.h
>  create mode 100644 net/lwip/port/sys-arch.c
> 
> diff --git a/net/eth-uclass.c b/net/eth-uclass.c
> index c393600fab..6625f6d8a5 100644
> --- a/net/eth-uclass.c
> +++ b/net/eth-uclass.c
> @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
>  struct eth_device_priv {
>   enum eth_state_t state;
>   bool running;
> + ulwip ulwip;
>  };
>  
>  /**
> @@ -347,6 +348,13 @@ int eth_init(void)
>   return ret;
>  }
>  
> +struct ulwip *eth_lwip_priv(struct udevice *current)
> +{
> + struct eth_device_priv *priv = dev_get_uclass_priv(current);
> +
> + return &priv->ulwip;
> +}
> +
>  void eth_halt(void)
>  {
>   struct udevice *current;
> diff --git a/net/lwip/port/if.c b/net/lwip/port/if.c
> new file mode 100644
> index 00..625a9c10bf
> --- /dev/null
> +++ b/net/lwip/port/if.c
> @@ -0,0 +1,260 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * (C) Copyright 2023 Linaro Ltd. 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#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/ethip6.h"
> +
> +#include "lwip/ip.h"
> +
> +#define IFNAME0 'e'
> +#define IFNAME1 '0'

Why is this needed and how was 'e0' chosen?
Dont we have a device name in the udevice struct?

> +
> +static struct pbuf *low_level_input(struct netif *netif);
> +
> +int ulwip_enabled(void)
> +{
> + struct ulwip *ulwip;
> +
> + ulwip = eth_lwip_priv(eth_get_dev());

eth_get_dev() can return NULL.  There are various locations of this call
that needs fixing

> + return ulwip->init_done;
> +}
> +
> +
> +struct ulwip_if {
> +};

Why the forward declaration?

> +
> +#define LWIP_PORT_INIT_NETMASK(addr)  IP4_ADDR((addr), 255, 255, 255, 0)

Why are we limiting the netmask to a class C network?

> +
> +void ulwip_poll(void)
> +{
> + struct pbuf *p;
> + int err;
> + struct netif *netif = netif_get_by_index(1);

First of all netif can be NULL. Apart from that always requesting index 1
feels wrong.  We should do something similar to eth_get_dev() and get the
*active* device correlation to an index

> +
> + p = low_level_input(netif);
> + if (!p) {
> + log_err("error p = low_level_input = NULL\n");

This looks like a debug message.
'Network interface undefined' or something else, which is more readable. 

> + return;
> + }
> +
> + /* ethernet_input always returns ERR_OK */
> + err = ethernet_input(p, netif);
> + if (err)
> + log_err("ip4_input err %d\n", err);
> +
> + return;
> +}
> +
> +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;
> +
> + /* We allocate a pbuf chain of pbufs from the pool. */
> + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
> + if (p) {

if (!p) and reverse the logic 

> + /* 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();
> +
> + LINK_STATS_INC(link.recv);
> + } else {
> +

[PATCHv6 09/14] net/lwip: implement lwIP port to U-Boot

2023-08-14 Thread Maxim Uvarov
Implement network lwIP interface connected to the U-boot.
Keep original file structure widely used fro lwIP ports.
(i.e. port/if.c port/sys-arch.c).

Signed-off-by: Maxim Uvarov 
---
 net/eth-uclass.c  |   8 +
 net/lwip/port/if.c| 260 ++
 net/lwip/port/include/arch/cc.h   |  39 
 net/lwip/port/include/arch/sys_arch.h |  56 ++
 net/lwip/port/include/limits.h|   0
 net/lwip/port/sys-arch.c  |  20 ++
 6 files changed, 383 insertions(+)
 create mode 100644 net/lwip/port/if.c
 create mode 100644 net/lwip/port/include/arch/cc.h
 create mode 100644 net/lwip/port/include/arch/sys_arch.h
 create mode 100644 net/lwip/port/include/limits.h
 create mode 100644 net/lwip/port/sys-arch.c

diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index c393600fab..6625f6d8a5 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
 struct eth_device_priv {
enum eth_state_t state;
bool running;
+   ulwip ulwip;
 };
 
 /**
@@ -347,6 +348,13 @@ int eth_init(void)
return ret;
 }
 
+struct ulwip *eth_lwip_priv(struct udevice *current)
+{
+   struct eth_device_priv *priv = dev_get_uclass_priv(current);
+
+   return &priv->ulwip;
+}
+
 void eth_halt(void)
 {
struct udevice *current;
diff --git a/net/lwip/port/if.c b/net/lwip/port/if.c
new file mode 100644
index 00..625a9c10bf
--- /dev/null
+++ b/net/lwip/port/if.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * (C) Copyright 2023 Linaro Ltd. 
+ */
+
+#include 
+#include 
+#include 
+#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/ethip6.h"
+
+#include "lwip/ip.h"
+
+#define IFNAME0 'e'
+#define IFNAME1 '0'
+
+static struct pbuf *low_level_input(struct netif *netif);
+
+int ulwip_enabled(void)
+{
+   struct ulwip *ulwip;
+
+   ulwip = eth_lwip_priv(eth_get_dev());
+   return ulwip->init_done;
+}
+
+int ulwip_in_loop(void)
+{
+   struct ulwip *ulwip;
+
+   ulwip = eth_lwip_priv(eth_get_dev());
+   return ulwip->loop;
+}
+
+void ulwip_loop_set(int loop)
+{
+   struct ulwip *ulwip;
+
+   ulwip = eth_lwip_priv(eth_get_dev());
+   ulwip->loop = loop;
+}
+
+void ulwip_exit(int err)
+{
+   struct ulwip *ulwip;
+
+   ulwip = eth_lwip_priv(eth_get_dev());
+   ulwip->loop = 0;
+   ulwip->err = err;
+}
+
+int ulwip_app_get_err(void)
+{
+   struct ulwip *ulwip;
+
+   ulwip = eth_lwip_priv(eth_get_dev());
+   return ulwip->err;
+}
+
+struct ulwip_if {
+};
+
+#define LWIP_PORT_INIT_NETMASK(addr)  IP4_ADDR((addr), 255, 255, 255, 0)
+
+void ulwip_poll(void)
+{
+   struct pbuf *p;
+   int err;
+   struct netif *netif = netif_get_by_index(1);
+
+   p = low_level_input(netif);
+   if (!p) {
+   log_err("error p = low_level_input = NULL\n");
+   return;
+   }
+
+   /* ethernet_input always returns ERR_OK */
+   err = ethernet_input(p, netif);
+   if (err)
+   log_err("ip4_input err %d\n", err);
+
+   return;
+}
+
+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;
+
+   /* We allocate a pbuf chain of pbufs from the pool. */
+   p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+   if (p) {
+   /* 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();
+
+   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 */
+