From 91cd79a8a3e9c414b8eace41f08e729bb676c1f5 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 17 Apr 2015 14:51:30 +0800 Subject: [PATCH] soc/runtime: add lwip (thanks Florent) --- .gitmodules | 3 + soc/runtime/liblwip/Makefile | 56 +++++++ soc/runtime/liblwip/arch/cc.h | 60 ++++++++ soc/runtime/liblwip/arch/perf.h | 11 ++ soc/runtime/liblwip/arch/sys_arch.h | 20 +++ soc/runtime/liblwip/lwipopts.h | 213 ++++++++++++++++++++++++++ soc/runtime/liblwip/netif/liteethif.c | 137 +++++++++++++++++ soc/runtime/liblwip/netif/liteethif.h | 17 ++ soc/runtime/lwip | 1 + 9 files changed, 518 insertions(+) create mode 100644 .gitmodules create mode 100644 soc/runtime/liblwip/Makefile create mode 100644 soc/runtime/liblwip/arch/cc.h create mode 100644 soc/runtime/liblwip/arch/perf.h create mode 100644 soc/runtime/liblwip/arch/sys_arch.h create mode 100644 soc/runtime/liblwip/lwipopts.h create mode 100644 soc/runtime/liblwip/netif/liteethif.c create mode 100644 soc/runtime/liblwip/netif/liteethif.h create mode 160000 soc/runtime/lwip diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..1d2170527 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "soc/runtime/lwip"] + path = soc/runtime/lwip + url = git://git.savannah.nongnu.org/lwip.git diff --git a/soc/runtime/liblwip/Makefile b/soc/runtime/liblwip/Makefile new file mode 100644 index 000000000..9d52a37c4 --- /dev/null +++ b/soc/runtime/liblwip/Makefile @@ -0,0 +1,56 @@ +include $(MSCDIR)/software/common.mak + +LWIPDIR=../lwip/src + +CFLAGS += $(CPPFLAGS) -I. \ + -I$(LWIPDIR)/include \ + -I$(LWIPDIR)/include/ipv4 + +# COREFILES, CORE4FILES: The minimum set of files needed for lwIP. +COREOBJS=$(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/tcp.o \ + $(LWIPDIR)/core/tcp_in.o \ + $(LWIPDIR)/core/tcp_out.o \ + $(LWIPDIR)/core/udp.o \ + $(LWIPDIR)/core/dhcp.o \ + $(LWIPDIR)/core/inet_chksum.o \ + $(LWIPDIR)/core/timers.o \ + $(LWIPDIR)/core/init.o + +CORE4OBJS=$(LWIPDIR)/core/ipv4/icmp.o \ + $(LWIPDIR)/core/ipv4/ip4.o \ + $(LWIPDIR)/core/ipv4/ip4_addr.o \ + $(LWIPDIR)/core/ipv4/ip_frag.o + +# NETIFOBJS: Files implementing various generic network interface functions. +NETIFOBJS=$(LWIPDIR)/netif/etharp.o \ + netif/liteethif.o + +# NETIFOBJS: All the above. +LWIPOBJS=$(COREOBJS) $(CORE4OBJS) $(NETIFOBJS) +OBJS_LIB+=$(LWIPOBJS) + +LWIPLIB=liblwip.a + +all: $(LWIPLIB) + +.PHONY: all compile clean + +%.o: %.c + $(compile-dep) + +%.o: %.S + $(assemble) + +clean: + rm -f $(LWIPOBJS) $(LWIPOBJS:.o=.d) $(LWIPLIB) + +liblwip.a: $(LWIPOBJS) + $(AR) clr liblwip.a $(LWIPOBJS) + $(RANLIB) liblwip.a diff --git a/soc/runtime/liblwip/arch/cc.h b/soc/runtime/liblwip/arch/cc.h new file mode 100644 index 000000000..e1c4c42ab --- /dev/null +++ b/soc/runtime/liblwip/arch/cc.h @@ -0,0 +1,60 @@ +// This file is Copyright (c) 2015 Florent Kermarrec +// LiteETH lwIP port for ARTIQ +// License: BSD + +#ifndef __ARCH_CC_H__ +#define __ARCH_CC_H__ + +/* Include some files for defining library routines */ +#include +#include +#include + +#define BYTE_ORDER BIG_ENDIAN + +/* Define generic types */ +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned long u32_t; +typedef signed long s32_t; + +typedef u32_t mem_ptr_t; + +/* Define (sn)printf formatters for these types */ +#define U8_F "c" +#define S8_F "c" +#define X8_F "x" +#define U16_F "u" +#define S16_F "d" +#define X16_F "x" +#define U32_F "u" +#define S32_F "d" +#define X32_F "x" + +/* Compiler hints for packing structures */ +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_STRUCT __attribute__((packed)) +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_END + +/* prototypes for printf() and abort() */ +#include +#include +#include "console.h" +#define pp_printf printf + +/* Definitions for ASSERT/DIAG */ +#ifdef LWIP_NOASSERT +#define LWIP_PLATFORM_ASSERT(x) +#else +#define LWIP_PLATFORM_ASSERT(x) do {pp_printf("Assertion \"%s\" failed at line %d in %s\n", \ + x, __LINE__, __FILE__); } while(0) +#endif + +#ifdef LWIP_DEBUG +#define LWIP_PLATFORM_DIAG(x) do {pp_printf x;} while(0) +#endif + +#endif /* __ARCH_CC_H__ */ diff --git a/soc/runtime/liblwip/arch/perf.h b/soc/runtime/liblwip/arch/perf.h new file mode 100644 index 000000000..37e52e4db --- /dev/null +++ b/soc/runtime/liblwip/arch/perf.h @@ -0,0 +1,11 @@ +// This file is Copyright (c) 2015 Florent Kermarrec +// LiteETH lwIP port for ARTIQ +// License: BSD + +#ifndef __ARCH_PERF_H__ +#define __ARCH_PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __ARCH_PERF_H__ */ diff --git a/soc/runtime/liblwip/arch/sys_arch.h b/soc/runtime/liblwip/arch/sys_arch.h new file mode 100644 index 000000000..a9e2503e2 --- /dev/null +++ b/soc/runtime/liblwip/arch/sys_arch.h @@ -0,0 +1,20 @@ +// This file is Copyright (c) 2015 Florent Kermarrec +// LiteETH lwIP port for ARTIQ +// License: BSD + +#ifndef __ARCH_SYS_ARCH_H__ +#define __ARCH_SYS_ARCH_H__ + +#define SYS_MBOX_NULL NULL +#define SYS_SEM_NULL NULL + +typedef void * sys_prot_t; + +typedef void * sys_sem_t; + +typedef void * sys_mbox_t; + +typedef void * sys_thread_t; + +#endif /* __ARCH_SYS_ARCH_H__ */ + diff --git a/soc/runtime/liblwip/lwipopts.h b/soc/runtime/liblwip/lwipopts.h new file mode 100644 index 000000000..3a23b80cd --- /dev/null +++ b/soc/runtime/liblwip/lwipopts.h @@ -0,0 +1,213 @@ +// This file is Copyright (c) 2015 Florent Kermarrec +// LiteETH lwIP port for ARTIQ +// License: BSD + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +//#define LWIP_DEBUG +#include + +/*----------------------------General options ------------------------------ */ +#define NO_SYS 1 +#define LWIP_NETCONN 0 +#define LWIP_SOCKET 0 +#define LWIP_IPV6 0 + + /* ------------------------ Memory options -------------------------------- */ +/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which + lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 + byte alignment -> define MEM_ALIGNMENT to 2. */ +#define MEM_ALIGNMENT 4 /* MUST BE 4 */ + +/* 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. */ +#define MEM_SIZE 16000 + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + sends a lot of data out of ROM (or other static memory), this + should be set high. */ +#define MEMP_NUM_PBUF 20 +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + per active UDP "connection". */ +#define MEMP_NUM_UDP_PCB 4 +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + connections. */ +#define MEMP_NUM_TCP_PCB 10 +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + connections. */ +#define MEMP_NUM_TCP_PCB_LISTEN 8 +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + segments. */ +#define MEMP_NUM_TCP_SEG 8 +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + timeouts. */ +#define MEMP_NUM_SYS_TIMEOUT 3 + +/* The following four are used only with the sequential API and can be + set to 0 if the application only will use the raw API. */ +/* MEMP_NUM_NETBUF: the number of struct netbufs. */ +//#define MEMP_NUM_NETBUF 4 +/* MEMP_NUM_NETCONN: the number of struct netconns. */ +//#define MEMP_NUM_NETCONN 4 + +/* These two control is reclaimer functions should be compiled + in. Should always be turned on (1). */ +#define MEM_RECLAIM 1 +#define MEMP_RECLAIM 1 + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#define PBUF_POOL_SIZE 4 + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +#define PBUF_POOL_BUFSIZE 1024 + +/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a + link level header. */ +#define PBUF_LINK_HLEN 16 + +/* ------------------------ TCP options ----------------------------------- */ +#define LWIP_TCP 1 +#define TCP_TTL 255 + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory. */ +#define TCP_QUEUE_OOSEQ 1 + +/* TCP Maximum segment size. */ +#define TCP_MSS 256 + +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF 512 + +/* TCP sender buffer space (pbufs). This must be at least = 2 * + TCP_SND_BUF/TCP_MSS for things to work. */ +#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS + +/* TCP receive window. */ +#define TCP_WND 256 + +/* Maximum number of retransmissions of data segments. */ +#define TCP_MAXRTX 12 + +/* Maximum number of retransmissions of SYN segments. */ +#define TCP_SYNMAXRTX 4 + +/* ------------------------ ARP options ----------------------------------- */ +#define LWIP_ARP 1 +#define ARP_TABLE_SIZE 10 +#define ARP_QUEUEING 1 + +/* ------------------------ IP options ------------------------------------ */ +/* Define IP_FORWARD to 1 if you wish to have the ability to forward + IP packets across network interfaces. If you are going to run lwIP + on a device with only one network interface, define this to 0. */ +#define IP_FORWARD 0 + +/* If defined to 1, IP options are allowed (but not parsed). If + defined to 0, all packets with IP options are dropped. */ +#define IP_OPTIONS 0 /* set it to 1 to allow IP options in hdr */ +#define IP_REASSEMBLY 0 /* set it to 1 to enable tcp/ip reassembly */ +#define IP_FRAG 0 /* Outgoing fragmentation of IP packets occurs + * when the packet-size exceeds the path maximum + * packet-size (path MTU). To avoid fragmentation, + * don't allow application OR lwIP to generate packets larger + * than anticipated path maximum transmission unit. + * + * For TCP, setting TCP_MSS to much less than anticipated + * path MTU avoids frag/defrag. For UDP it depends on app + * and path MTU. For ping (ICMP), with large payload, + * frag/reass is required. Some network stacks have + * path MTU discovery capability but not sure if LwIP + * supports it + */ +#define LWIP_RAW 1 /* set it to 1 to enable raw support */ + +/* ------------------------ ICMP options ---------------------------------- */ +#define ICMP_TTL 255 + +/* ------------------------ DHCP options ---------------------------------- */ +/* Define LWIP_DHCP to 1 if you want DHCP configuration of + interfaces. DHCP is not implemented in lwIP 0.5.1, however, so + turning this on does currently not work. */ +#define LWIP_DHCP 0 + +/* 1 if you want to do an ARP check on the offered address + (recommended). */ +//#define DHCP_DOES_ARP_CHECK 1 + +/* ------------------------ UDP options ----------------------------------- */ +#define LWIP_UDP 1 /* set it to 1 to enable UDP */ +#define UDP_TTL 255 /* time to live for udp */ +#define CHECKSUM_GEN_UDP 0 /* don't generate UDP chksum, if UDP enabled*/ +#define CHECKSUM_CHECK_UDP 0 /* check chksum in rx UDP pkts if enabled */ + +#define LWIP_STATS 0 +#define LWIP_COMPAT_SOCKETS 0 + +/* Override the default dynamic memory alloc functions (malloc copy)*/ +//#include "memmgr.h" + +//#define mem_init() +//#define mem_free memmgr_free +//#define mem_malloc memmgr_alloc +//#define mem_calloc(c, n) memmgr_alloc((c) * (n)) +//#define mem_realloc(p, sz) (p) + +#ifdef LWIP_DEBUG +/* + * for a list of options for the flags, please refer to + * lwip/src/include/lwip/debug.h + ******************NOTE******************************** + * + * TO TURN OFF A SPECIFIC DEBUG SOURCE, SET THE VALUE TO + * DBG_OFF + * + * DO NOT MODIFY DBG_TYPES_ON OR DBG_MIN_LEVEL UNLESS YOU + * ARE AWARE WHAT YOU'RE DOING!! + * + */ +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#define DBG_TYPES_ON LWIP_DBG_TRACE + +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#define ETHARP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define NETIF_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define PBUF_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define API_LIB_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define API_MSG_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define SOCKETS_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define ICMP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define INET_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define IP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define IP_REASS_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define RAW_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define MEM_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define MEMP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define SYS_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_INPUT_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_FR_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_RTO_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_CWND_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_WND_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_OUTPUT_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_RST_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCP_QLEN_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define UDP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TCPIP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define PPP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define SLIP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define DHCP_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE +#define TIMERS_DEBUG LWIP_DBG_ON|LWIP_DBG_TRACE + +/* APPLICATION DEBUGGING */ +/* #define HTTPD_DEBUG (1) */ +#endif + + +/* Perform DHCP */ +/*#define LWIP_DHCP (1)*/ + +#endif /* __LWIPOPTS_H__ */ diff --git a/soc/runtime/liblwip/netif/liteethif.c b/soc/runtime/liblwip/netif/liteethif.c new file mode 100644 index 000000000..96969d7cc --- /dev/null +++ b/soc/runtime/liblwip/netif/liteethif.c @@ -0,0 +1,137 @@ +// This file is Copyright (c) 2015 Florent Kermarrec +// LiteETH lwIP port for ARTIQ +// License: BSD + +#include +#include + +#include +#include "netif/liteethif.h" + +#include +#include +#include + +typedef union { + unsigned char raw[1514]; +} ethernet_buffer; + +static unsigned int rxslot; +static unsigned int rxlen; +static ethernet_buffer *rxbuffer; +static ethernet_buffer *rxbuffer0; +static ethernet_buffer *rxbuffer1; +static unsigned int txslot; +static unsigned int txlen; +static ethernet_buffer *txbuffer; +static ethernet_buffer *txbuffer0; +static ethernet_buffer *txbuffer1; + +#define IFNAME0 'e' +#define IFNAME1 't' + +static void liteeth_low_level_init(struct netif *netif) +{ + int i; + + netif->hwaddr_len = 6; + for(i=0;ihwaddr_len;i++) + netif->hwaddr[i] = macadr[i]; + netif->mtu = 1514; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + + ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER); + ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); + + rxbuffer0 = (ethernet_buffer *)ETHMAC_RX0_BASE; + rxbuffer1 = (ethernet_buffer *)ETHMAC_RX1_BASE; + txbuffer0 = (ethernet_buffer *)ETHMAC_TX0_BASE; + txbuffer1 = (ethernet_buffer *)ETHMAC_TX1_BASE; + + rxslot = 0; + txslot = 0; + + rxbuffer = rxbuffer0; + txbuffer = txbuffer0; + + return; +} + +static err_t liteeth_low_level_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q; + + txlen = 0; + for(q = p; q != NULL; q = q->next) { + memcpy(txbuffer->raw, q->payload, q->len); + txbuffer += q->len; + txlen += q->len; + } + + ethmac_sram_reader_slot_write(txslot); + ethmac_sram_reader_length_write(txlen); + while(!(ethmac_sram_reader_ready_read())); + ethmac_sram_reader_start_write(1); + + txslot = (txslot+1)%2; + if (txslot) + txbuffer = txbuffer1; + else + txbuffer = txbuffer0; + + return ERR_OK; +} + +static struct pbuf * liteeth_low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + + rxslot = ethmac_sram_writer_slot_read(); + rxlen = ethmac_sram_writer_length_read(); + if (rxslot) + rxbuffer = rxbuffer1; + else + rxbuffer = rxbuffer0; + + p = pbuf_alloc(PBUF_RAW, rxlen, PBUF_POOL); + if (p != NULL) { + for(q = p; q != NULL; q = q->next) { + memcpy(q->payload, rxbuffer->raw, q->len); + rxbuffer += q->len; + } + } + + return p; +} + +void liteeth_input(struct netif *netif) +{ + struct pbuf *p; + p = liteeth_low_level_input(netif); + if (p != NULL) { + netif->input(p, netif); + } +} + +err_t liteeth_init(struct netif *netif) +{ + struct liteethif *liteethif; + + liteethif = mem_malloc(sizeof(struct liteethif)); + if (liteethif == NULL) + return ERR_MEM; + netif->state = liteethif; + + netif->hwaddr_len = 6; + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + netif->output = etharp_output; + netif->linkoutput = liteeth_low_level_output; + netif->mtu = 1514; + + liteethif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + + liteeth_low_level_init(netif); + + return ERR_OK; +} diff --git a/soc/runtime/liblwip/netif/liteethif.h b/soc/runtime/liblwip/netif/liteethif.h new file mode 100644 index 000000000..fcd2e1d1b --- /dev/null +++ b/soc/runtime/liblwip/netif/liteethif.h @@ -0,0 +1,17 @@ +// This file is Copyright (c) 2015 Florent Kermarrec +// LiteETH lwIP port for ARTIQ +// License: BSD + +#ifndef __LITEETHIF_H__ +#define __LITEETHIF_H__ + +extern unsigned char macadr[]; + +struct liteethif { + struct eth_addr *ethaddr; +}; + +void liteeth_input(struct netif *netif); +err_t liteeth_init(struct netif *netif); + +#endif /* __LITEETH_IF_H__ */ diff --git a/soc/runtime/lwip b/soc/runtime/lwip new file mode 160000 index 000000000..caf9fc568 --- /dev/null +++ b/soc/runtime/lwip @@ -0,0 +1 @@ +Subproject commit caf9fc568715b82587ed9698658fdcd40c6c0a9d