This commit adds initial picotcp support: * build stuff (Kbuild fixes and fake stdint.h); * "pico_adapter" code for connecting barebox ethernet interfaces to picotcp; * picotcp start initialization and necessary poller. Signed-off-by: Antony Pavlov <antonynpavlov@xxxxxxxxx> Signed-off-by: Daniele Lacamera <daniele.lacamera@xxxxxxx> --- Makefile | 1 + commands/Kconfig | 4 +++ include/net.h | 37 ++++++++++++++++++++++- include/pico_defines.h | 0 include/stdint.h | 1 + net/Kconfig | 16 ++++++++++ net/Makefile | 3 ++ net/eth.c | 71 +++++++++++++++++++++++++++++++++++++++++++ net/net.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++- net/picotcp.c | 20 +++++++++++++ 10 files changed, 232 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5a7fd5f..972b5db 100644 --- a/Makefile +++ b/Makefile @@ -292,6 +292,7 @@ export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_ve # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := -Iinclude -I$(srctree)/dts/include \ + -I$(srctree)/net/picotcp/include -I$(srctree)/net/picotcp/modules \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ -I$(srctree)/arch/$(ARCH)/include \ -I$(objtree)/arch/$(ARCH)/include \ diff --git a/commands/Kconfig b/commands/Kconfig index 5571902..77193cb 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -1184,6 +1184,7 @@ menu "Network" config CMD_DHCP bool select NET_DHCP + depends on NET_LEGACY prompt "dhcp" help DHCP client to obtain IP or boot params @@ -1210,6 +1211,7 @@ config CMD_HOST config NET_CMD_IFUP bool prompt "ifup" + depends on NET_LEGACY help Bring up network interfaces based on config files. @@ -1237,6 +1239,7 @@ config CMD_MIITOOL config CMD_PING tristate + depends on NET_LEGACY prompt "ping" help Send ICMP echo requests. @@ -1245,6 +1248,7 @@ config CMD_PING config CMD_TFTP depends on FS_TFTP + depends on NET_LEGACY tristate prompt "tftp" help diff --git a/include/net.h b/include/net.h index ed63d3c..5f2d470 100644 --- a/include/net.h +++ b/include/net.h @@ -24,6 +24,10 @@ #include <linux/string.h> /* memcpy */ #include <asm/byteorder.h> /* for nton* / ntoh* stuff */ +#include <pico_stack.h> +#include <pico_socket.h> +#include <pico_ipv4.h> + /* How often do we retry to send packages */ #define PKT_NUM_RETRIES 4 @@ -44,6 +48,7 @@ struct eth_device { int (*get_ethaddr) (struct eth_device*, u8 adr[6]); int (*set_ethaddr) (struct eth_device*, const unsigned char *adr); + struct pico_device *picodev; struct eth_device *next; void *priv; @@ -433,6 +438,8 @@ struct net_connection { void *handler; int proto; void *priv; + struct pico_socket *sock; + uint16_t remote_port; }; static inline char *net_alloc_packet(void) @@ -450,10 +457,28 @@ void net_unregister(struct net_connection *con); static inline int net_udp_bind(struct net_connection *con, uint16_t sport) { + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + union pico_address local_address; + uint16_t localport; + + /* FIXME: use local_address == PICO_IPV4_INADDR_ANY */ + memset(&local_address, 0, sizeof(union pico_address)); + + localport = ntohs(sport); + + /* FIXME: check pico_socket_bind() return value */ + pico_socket_bind(con->sock, &local_address, &localport); + + return 0; + } + con->udp->uh_sport = ntohs(sport); return 0; } +#define UDP_PAYLOAD_SIZE (PKTSIZE - sizeof(struct ethernet) - sizeof(struct iphdr) - \ + sizeof(struct udphdr)) + static inline void *net_udp_get_payload(struct net_connection *con) { return con->packet + sizeof(struct ethernet) + sizeof(struct iphdr) + @@ -475,6 +500,10 @@ static inline uint16_t getudppeerport(struct net_connection *con) { struct udphdr *udp = net_eth_to_udphdr(con->rpacket); + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + return con->remote_port; + } + return udp->uh_sport; } @@ -482,7 +511,13 @@ static inline uint16_t getudppeerport(struct net_connection *con) static inline void setudppeerport(struct net_connection *con, uint16_t dport) { - con->udp->uh_dport = dport; + if (IS_ENABLED(CONFIG_NET_LEGACY)) { + con->udp->uh_dport = dport; + } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + /* FIXME */ +// pico_socket_connect(npriv->con->sock, &remote_address, dport); + con->sock->remote_port = dport; + } } #endif /* __NET_H__ */ diff --git a/include/pico_defines.h b/include/pico_defines.h new file mode 100644 index 0000000..e69de29 diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..029276e --- /dev/null +++ b/include/stdint.h @@ -0,0 +1 @@ +/* fake stdint.h for picotcp */ diff --git a/net/Kconfig b/net/Kconfig index a890492..f8f660c 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -3,6 +3,18 @@ menuconfig NET if NET +choice + prompt "network stack implementation" + +config NET_LEGACY + bool "legacy U-Boot network stack" + +config NET_PICOTCP + bool "picotcp network stack" + select POLLER + +endchoice + config NET_NFS bool prompt "nfs support" @@ -20,10 +32,14 @@ config NET_RESOLV config NET_IFUP default y + depends on NET_LEGACY bool config NET_DHCP bool + depends on NET_LEGACY prompt "dhcp support" +source "net/picotcp/Kconfig" + endif diff --git a/net/Makefile b/net/Makefile index 8d564e7..7a4597d 100644 --- a/net/Makefile +++ b/net/Makefile @@ -7,3 +7,6 @@ obj-$(CONFIG_CMD_PING) += ping.o obj-$(CONFIG_NET_RESOLV)+= dns.o obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o obj-$(CONFIG_NET_IFUP) += ifup.o + +obj-$(CONFIG_NET_PICOTCP) += picotcp/ +obj-$(CONFIG_NET_PICOTCP) += picotcp.o diff --git a/net/eth.c b/net/eth.c index a090961..34358f6 100644 --- a/net/eth.c +++ b/net/eth.c @@ -328,6 +328,73 @@ static int eth_register_of_fixup(void) late_initcall(eth_register_of_fixup); #endif +#ifdef CONFIG_NET_PICO_SUPPORT_ETH + +#include <pico_stack.h> +#include <pico_ipv4.h> + +struct pico_device_barebox_eth { + struct pico_device dev; + struct eth_device *edev; +}; + +static int pico_adapter_send(struct pico_device *dev, void *buf, int len) +{ + struct pico_device_barebox_eth *t = (struct pico_device_barebox_eth *)dev; + struct eth_device *edev = t->edev; + + pr_debug("pico_adapter_send barebox eth (len=%d)\n", len); + edev->send(edev, buf, len); + + return len; +} + +static int pico_adapter_poll(struct pico_device *dev, int loop_score) +{ + struct pico_device_barebox_eth *t = (struct pico_device_barebox_eth *)dev; + struct eth_device *edev = t->edev; + + /* pico_stack_recv(dev, buf, len) will be called from net_receive */ + + edev->recv(edev); + + return loop_score; +} + +static void pico_adapter_destroy(struct pico_device *dev) +{ + printf("pico_adapter_destroy barebox eth\n"); +} + +static void pico_adapter_init(struct eth_device *edev) +{ + /* FIXME: get macaddr for edev */ + static unsigned char macaddr0[6] = { 0, 0, 0, 0xa, 0xb, 0xc }; + + struct pico_device_barebox_eth *pif = PICO_ZALLOC(sizeof(struct pico_device_barebox_eth)); + + struct pico_device *picodev; + + char *name = strdup(edev->dev.name); + + picodev = &pif->dev; + if (0 != pico_device_init(picodev, name, macaddr0)) { + pr_info("pico_adapter_init failed.\n"); + pico_adapter_destroy(picodev); + return; + } + + picodev->send = pico_adapter_send; + picodev->poll = pico_adapter_poll; + picodev->destroy = pico_adapter_destroy; + + pif->edev = edev; + edev->picodev = picodev; + + pr_info("Device %s created.\n", picodev->name); +} +#endif /* CONFIG_NET_PICO_SUPPORT_ETH */ + int eth_register(struct eth_device *edev) { struct device_d *dev = &edev->dev; @@ -388,6 +455,10 @@ int eth_register(struct eth_device *edev) if (!eth_current) eth_current = edev; +#ifdef CONFIG_NET_PICO_SUPPORT_ETH + pico_adapter_init(edev); +#endif + return 0; } diff --git a/net/net.c b/net/net.c index 23a9173..f4481f8 100644 --- a/net/net.c +++ b/net/net.c @@ -194,9 +194,15 @@ static int arp_request(IPaddr_t dest, unsigned char *ether) return 0; } +#include <pico_stack.h> + void net_poll(void) { - eth_rx(); + if (IS_ENABLED(CONFIG_NET_LEGACY)) { + eth_rx(); + } else if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + pico_stack_tick(); + } } static uint16_t net_udp_new_localport(void) @@ -262,6 +268,17 @@ static struct net_connection *net_new(IPaddr_t dest, void *handler, struct net_connection *con; int ret; + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + con = xzalloc(sizeof(*con)); + con->handler = handler; + con->packet = net_alloc_packet(); + memset(con->packet, 0, PKTSIZE); + + list_add_tail(&con->list, &connection_list); + + return con; + } + if (!edev) return ERR_PTR(-ENETDOWN); @@ -316,6 +333,27 @@ out: return ERR_PTR(ret); } +#include <pico_socket.h> +#include <pico_ipv4.h> + +static void picotcp_udp_cb(uint16_t ev, struct pico_socket *sock) +{ + struct net_connection *con = sock->priv; + udp_rx_handler_f *handler = con->handler; + int len; + union pico_address ep; + char *pkt = con->packet; + + if (ev == PICO_SOCK_EV_ERR) { + printf(">>>>>> PICO_SOCK_EV_ERR (%d)\n", pico_err); + return; + } + + len = pico_socket_recvfrom(sock, pkt, UDP_PAYLOAD_SIZE, &ep, &con->remote_port); + + handler(con, pkt, len); +} + struct net_connection *net_udp_new(IPaddr_t dest, uint16_t dport, udp_rx_handler_f *handler, void *ctx) { @@ -324,6 +362,26 @@ struct net_connection *net_udp_new(IPaddr_t dest, uint16_t dport, if (IS_ERR(con)) return con; + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + union pico_address remote_address; + + remote_address.ip4.addr = dest; + + con->sock = pico_socket_open(PICO_PROTO_IPV4, + PICO_PROTO_UDP, picotcp_udp_cb); + + if (!con->sock) + return ERR_PTR(-ENOBUFS); + + /* FIXME: check return value */ + pico_socket_connect(con->sock, &remote_address, htons(dport)); + + con->sock->priv = con; + con->priv = ctx; + + return con; + } + con->proto = IPPROTO_UDP; con->udp->uh_dport = htons(dport); con->udp->uh_sport = htons(net_udp_new_localport()); @@ -348,6 +406,10 @@ struct net_connection *net_icmp_new(IPaddr_t dest, rx_handler_f *handler, void net_unregister(struct net_connection *con) { + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + pico_socket_close(con->sock); + } + list_del(&con->list); free(con->packet); free(con); @@ -365,6 +427,13 @@ static int net_ip_send(struct net_connection *con, int len) int net_udp_send(struct net_connection *con, char *payload, int len) { + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + /* FIXME: pico_socket_send() ret code is ignored */ + pico_socket_send(con->sock, payload, len); + + return 0; + } + con->udp->uh_ulen = htons(len + 8); con->udp->uh_sum = 0; @@ -544,12 +613,22 @@ bad: return 0; } +#include <pico_stack.h> + int net_receive(struct eth_device *edev, unsigned char *pkt, int len) { struct ethernet *et = (struct ethernet *)pkt; int et_protlen = ntohs(et->et_protlen); int ret; + if (IS_ENABLED(CONFIG_NET_PICOTCP)) { + pico_stack_recv(edev->picodev, pkt, len); + + led_trigger_network(LED_TRIGGER_NET_RX); + + return 0; + } + led_trigger_network(LED_TRIGGER_NET_RX); if (len < ETHER_HDR_SIZE) { diff --git a/net/picotcp.c b/net/picotcp.c new file mode 100644 index 0000000..ee16a68 --- /dev/null +++ b/net/picotcp.c @@ -0,0 +1,20 @@ +#include <init.h> +#include <poller.h> +#include <pico_stack.h> + +static struct poller_struct picotcp_poller; + +static void picotcp_poller_cb(struct poller_struct *poller) +{ + pico_stack_tick(); +} + +static int picotcp_net_init(void) +{ + pico_stack_init(); + + picotcp_poller.func = picotcp_poller_cb; + + return poller_register(&picotcp_poller); +} +postcore_initcall(picotcp_net_init); -- 2.1.4 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox