]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
Initial commit of C16x/ST10 arch files and CS8900a Ethernet driver.
authorlikewise <likewise>
Fri, 29 Nov 2002 10:59:34 +0000 (10:59 +0000)
committerlikewise <likewise>
Fri, 29 Nov 2002 10:59:34 +0000 (10:59 +0000)
12 files changed:
src/arch/FILES
src/arch/c16x/FILES [new file with mode: 0644]
src/arch/c16x/include/arch/cc.h [new file with mode: 0644]
src/arch/c16x/include/arch/cpu.h [new file with mode: 0644]
src/arch/c16x/include/arch/lib.h [new file with mode: 0644]
src/arch/c16x/include/arch/perf.h [new file with mode: 0644]
src/arch/c16x/include/arch/sys_arch.h [new file with mode: 0644]
src/arch/c16x/include/netif/cs8900if.h [new file with mode: 0644]
src/arch/c16x/lib.c [new file with mode: 0644]
src/arch/c16x/netif/cs8900if.c [new file with mode: 0644]
src/arch/c16x/perf.c [new file with mode: 0644]
src/arch/c16x/sys_arch.c [new file with mode: 0644]

index c6eeda8916b2ac7ffd5b3fb29c4a39362c3bee78..c7fb417613ef0dfacd4c4d7a07b2d41441fad6d9 100644 (file)
@@ -1,5 +1,11 @@
 6502/      - Architectural files for the 6502 CPU.
 
+c16x/      - Architectural files for the C16x/ST10 uC.
+             Supports lwIP Raw API only.
+             CS8900a Ethernet driver for 16-bit mode.
+
+msvc6/     - Architectural files for Microsoft Visual C++ 6.0.
+
 rtxc/      - Architectural files for the RTXC operating system.
 
 unix/      - Architectural files for testing on unix-like systems
@@ -9,7 +15,6 @@ v2pro/     - Architectural files for the Xilinx Virtex-II PRO device with
              embedded PowerPC 405 Processor.  Supports lwIP Raw API only.
              (requires V2PDK - http://www.xilinx.com/ise/vii_pro/kit.htm)
 
-msvc6/     - Architectural files for Microsoft Visual C++ 6.0
 
 Each subdirectory (may) also include:
 
diff --git a/src/arch/c16x/FILES b/src/arch/c16x/FILES
new file mode 100644 (file)
index 0000000..6de2a62
--- /dev/null
@@ -0,0 +1,13 @@
+This directory contains architecture and compiler specific stuff for porting lwIP
+to the C16x and ST10 microcontrollers. The compiler specifics are for Tasking EDE
+v7.5r2.
+
+The sequential API has not been ported; it's function are empties. If someone is
+interested in adding a sequential API, please contact the author (see below).
+
+Besides this, a Cirrus (formerly Crystal Semiconductors) CS8900a Ethernet driver
+is included, which assumes a 16-bit data bus configuration. When porting this
+driver, note that the CS8900a does not support interrupts in 8-bit mode.
+
+Leon Woestenberg
+<leon.woestenberg@axon.tv>
diff --git a/src/arch/c16x/include/arch/cc.h b/src/arch/c16x/include/arch/cc.h
new file mode 100644 (file)
index 0000000..b4a9275
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __CC_H__
+#define __CC_H__
+
+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;
+
+// LW: Supported in at least >=v7.5 r2, but lwIP worked without the "_packed" attribute already
+#define PACK_STRUCT_BEGIN _packed
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+
+
+#endif /* __CC_H__ */
diff --git a/src/arch/c16x/include/arch/cpu.h b/src/arch/c16x/include/arch/cpu.h
new file mode 100644 (file)
index 0000000..627f5f3
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __CPU_H__
+#define __CPU_H__
+
+#define BYTE_ORDER LITTLE_ENDIAN
+
+#endif /* __CPU_H__ */
diff --git a/src/arch/c16x/include/arch/lib.h b/src/arch/c16x/include/arch/lib.h
new file mode 100644 (file)
index 0000000..1d400b0
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lib.h,v 1.1 2002/11/29 11:03:34 likewise Exp $
+ */
+#ifndef __LIB_H__
+#define __LIB_H__
+
+//int strlen(const char *str);
+//int strncmp(const char *str1, const char *str2, int len);
+void bcopy(const void *src, void *dest, int len);
+void bzero(void *data, int n);
+
+#endif /* __LIB_H__ */
diff --git a/src/arch/c16x/include/arch/perf.h b/src/arch/c16x/include/arch/perf.h
new file mode 100644 (file)
index 0000000..211c1e4
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: perf.h,v 1.1 2002/11/29 11:03:34 likewise Exp $
+ */
+#ifndef __PERF_H__
+#define __PERF_H__
+
+#define PERF_START    /* null definition */
+#define PERF_STOP(x)  /* null definition */
+
+#endif /* __PERF_H__ */
diff --git a/src/arch/c16x/include/arch/sys_arch.h b/src/arch/c16x/include/arch/sys_arch.h
new file mode 100644 (file)
index 0000000..dae2a55
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __SYS_ARCH_H__
+#define __SYS_ARCH_H__
+
+#define SEMA int
+#define QUEUE int
+#define TASK int
+
+#define SYS_MBOX_NULL (QUEUE)0
+#define SYS_SEM_NULL  (SEMA)0
+
+typedef SEMA sys_sem_t;
+typedef QUEUE sys_mbox_t;
+typedef TASK sys_thread_t;
+
+#endif /* __SYS_ARCH_H__ */
diff --git a/src/arch/c16x/include/netif/cs8900if.h b/src/arch/c16x/include/netif/cs8900if.h
new file mode 100644 (file)
index 0000000..15aa90b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Leon Woestenberg <leon.woestenberg@axon.tv>
+ *
+ * This is a device driver for the Crystal Semiconductor CS8900
+ * chip in combination with the lwIP stack.
+ *
+ * This is work under development. Please coordinate changes
+ * and requests with Leon Woestenberg <leon.woestenberg@axon.tv>
+ *
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code under any conditions they seem fit.
+ *
+ */
+#ifndef __NETIF_CS8900IF_H__
+#define __NETIF_CS8900IF_H__
+
+#include "lwip/netif.h"
+
+/* interface statistics gathering
+ * such as collisions, dropped packets, missed packets
+ * 0 = no statistics, minimal memory requirements, no overhead 
+ * 1 = statistics on, but some have large granularity (0x200), very low overhead
+ * 2 = statistics on, updated on every call to cs8900_service(), low overhead
+ */
+#define CS8900_STATS 2
+
+struct cs8900if
+{
+  //struct eth_addr *ethaddr;
+  u8_t needs_service;
+  u8_t use_polling;
+#if (CS8900_STATS > 0)
+  u32_t interrupts; // #interrupt requests of cs8900
+  u32_t missed; // #packets on medium that could not enter cs8900a chip due to buffer shortage
+  u32_t dropped; // #packets dropped after they have been received in chip buffer
+  u32_t collisions; // #collisions on medium when transmitting packets 
+  u32_t sentpackets; // #number of sent packets
+  u32_t sentbytes; // #number of sent bytes
+#endif
+  /* Add whatever per-interface state that is needed here. */
+};
+
+void cs8900if_init(struct netif *);
+void cs8900if_service(struct netif *);
+void cs8900if_input(struct netif *netif);
+err_t cs8900if_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);
+
+void cs8900_send_debug(unsigned char *p, unsigned int len);
+
+#endif /* __NETIF_CS8900IF_H__ */
diff --git a/src/arch/c16x/lib.c b/src/arch/c16x/lib.c
new file mode 100644 (file)
index 0000000..e10278c
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lib.c,v 1.1 2002/11/29 11:03:34 likewise Exp $
+ */
+
+/* These are generic implementations of various library functions used
+ * throughout the lwIP code. When porting, those should be optimized
+ * for the particular processor architecture, preferably coded in
+ * assembler.
+ */
+
+#include "lwip/arch.h"
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+/*-----------------------------------------------------------------------------------*/
+u16_t
+htons(u16_t n)
+{
+  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
+}
+/*-----------------------------------------------------------------------------------*/
+u16_t
+ntohs(u16_t n)
+{
+  return htons(n);
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+htonl(u32_t n)
+{
+  return ((n & 0xff) << 24) |
+    ((n & 0xff00) << 8) |
+    ((n & 0xff0000) >> 8) |
+    ((n & 0xff000000) >> 24);
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+ntohl(u32_t n)
+{
+  return htonl(n);
+}
+/*-----------------------------------------------------------------------------------*/
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+void
+bcopy(const void *src, void *dst, unsigned int size)
+{
+  char *csrc, *cdst;
+  int i;
+
+  csrc = (char *)src;
+  cdst = dst;
+  
+  for(i = 0; i < size; i++) {
+    cdst[i] = csrc[i];
+  }    
+}
+/*-----------------------------------------------------------------------------------*/
+void
+bzero(void *s, int n)
+{
+  for(n--; n > 0; n--) {
+    ((char *)s)[n] = 0;
+  }
+}
+/*-----------------------------------------------------------------------------------*/
diff --git a/src/arch/c16x/netif/cs8900if.c b/src/arch/c16x/netif/cs8900if.c
new file mode 100644 (file)
index 0000000..f5e4233
--- /dev/null
@@ -0,0 +1,846 @@
+/** @file
+/*
+ * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Leon Woestenberg <leon.woestenberg@axon.tv>
+ *
+ * This is a device driver for the Crystal Semiconductor CS8900
+ * chip in combination with the lwIP stack.
+ *
+ * This is work under development. Please coordinate changes
+ * and requests with Leon Woestenberg <leon.woestenberg@axon.tv>
+ *
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code under any conditions they seem fit.
+ *
+ * A quick function roadmap:
+ *
+ * cs8900_*() are low level, cs8900 hardware specific functions.
+ * These are declared static in the device driver source and
+ * SHOULD NOT need to be called from outside this source.
+ *
+ * cs8900if_*() are the lwIP network interface functions.
+ * 
+ * cs8900_interrupt() is an early interrupt service routine (ISR).
+ * It merely sets a flag to indicate the cs8900 needs servicing.
+ * (This function MAY be tied to an interrupt vector, IF present).
+ *
+ * cs8900_service() is the actual interrupt event service routine.
+ * It must be called whenever the cs8900 needs servicing. It MAY
+ * be polled safely (so, you do NOT NEED interrupt support.)
+ *
+ * cs8900_init() sets up the cs8900, using its register set. When
+ * using the driver on your particular hardware platform, make sure
+ * the register setups match.
+ * Function is called from cs8900if_init().
+ *
+ * cs8900_input() transfers a received packet from the chip.
+ * Function is called from cs8900if_input().
+ *
+ * cs8900_output() transfers a packet to the chip for transmission.
+ * Function is called from cs8900if_output().
+ *
+ * cs8900if_init() initializes the lwIP network interface, and
+ * calls cs8900_init() to initialize the hardware.
+ * Function is called from lwIP.
+ * 
+ * cs8900if_service() is the service routine, which must be called
+ * upon the need for service, or on a regular basis, in order to
+ * service the Ethernet chip.
+ *
+ * cs8900if_input() calls cs8900_input() to get a received packet
+ * and then forwards the packet to protocol(s) handler(s).
+ * Function is called from cs8900_service().
+ *
+ * cs8900if_output() resolves the hardware address, then
+ * calls cs8900_output() to transfer the packet.
+ * Function is called from lwIP.
+ *
+ * Future development:
+ * 
+ * Split the generic Ethernet functionality (a lot of the
+ * cs8900if_*() functions) and the actual cs8900a dependencies.
+ *
+ * Enhance the interrupt handler to service the Ethernet
+ * chip (to decrease latency); support early packet
+ * inspection (during reception) to early drop unwanted
+ * packets, minimize chip buffer use and maximize throughput.
+ *
+ * Statistics gathering, currently under development.
+ * SNMP support, currently under development.
+ *
+ */
+
+#include "lwip/debug.h"
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "netif/etharp.h"
+
+#if 0
+// include some debugging help
+#  define DBG_LEVEL 1
+#  include "leds.h"
+#  include "display.h"
+//#  include "page.h"
+#  define LED_NEED_SERVICE LED_FP1
+#else
+// no debugging
+#  define leds_on()
+#  define leds_off()
+#endif
+
+#include "cs8900if.h"
+#if LWIP_SNMP > 0
+#  include "snmp.h"
+#endif
+
+// Define those to better describe your network interface
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+static const struct eth_addr ethbroadcast = {{0xffU,0xffU,0xffU,0xffU,0xffU,0xffU}};
+
+// Forward declarations
+static err_t cs8900_output(struct netif *netif, struct pbuf *p);
+static struct pbuf *cs8900_input(struct netif *netif);
+static void cs8900_service(struct netif *netif);
+static u32_t cs8900_chksum(void *dataptr, int len);
+
+// Define these to match your hardware setup
+#define MEM_BASE 0x00E000
+#define IO_BASE 0x800
+#define INT_NR 0x00
+
+#define RXTXREG  *((volatile u16_t *)(MEM_BASE + IO_BASE))
+#define TXCMD    *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x04))
+#define TXLENGTH *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x06))
+#define ISQ      *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x08))
+#define PACKETPP *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x0A))
+#define PPDATA   *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x0C))
+
+// CS8900 PacketPage register offsets 
+#define  CS_PP_EISA        0x0000          // EISA Registration number of CS8900
+#define  CS_PP_PRODID      0x0002          // Product ID Number
+#define  CS_PP_IOBASE      0x0020          // I/O Base Address
+#define  CS_PP_INTNUM      0x0022          // Interrupt number (0,1,2, or 3)
+#define  CS_PP_RXCFG       0x0102          // Receiver Configuration
+#define  CS_PP_RXCTL       0x0104          // Receiver Control
+#define  CS_PP_TXCFG       0x0106          // Transmit Configuration
+#define  CS_PP_BUFCFG      0x010A          // Buffer Configuration
+#define  CS_PP_LINECTL     0x0112          // Line Control Register offset
+#define  CS_PP_SELFCTL     0x0114          // Self Control
+#define  CS_PP_BUSCTL      0x0116          // Bus Control
+#define  CS_PP_TESTCTL     0x0118          // Test Control
+#define  CS_PP_ISQ         0x0120          // Interrupt status queue
+#define  CS_PP_RXEVENT     0x0124          // Receiver Event
+#define  CS_PP_TX_EVENT    0x0128          // Transmitter Event
+#define  CS_PP_BUF_EVENT   0x012C          // Buffer Event
+#define  CS_PP_RXMISS      0x0130          // Receiver Miss Counter
+#define  CS_PP_TXCOL       0x0132          // Transmit Collision Counter
+#define  CS_PP_LINESTATUS  0x0134          // Line Status
+#define  CS_PP_SELFTEST    0x0136          // Self Status
+#define  CS_PP_BUSSTATUS   0x0138          // Bus Status
+#define  CS_PP_TXCMD       0x0144          // Transmit Command Request
+#define  CS_PP_TXLEN       0x0146          // Transmit Length
+#define  CS_PP_IA1         0x0158          // Individual Address (IA)
+#define  CS_PP_IA2         0x015A          // Individual Address (IA)
+#define  CS_PP_IA3         0x015C          // Individual Address (IA)
+
+#define  CS_PP_RXSTATUS    0x0400          // Receive Status
+#define  CS_PP_RXLEN       0x0402          // Receive Length
+#define  CS_PP_RXFRAME     0x0404          // Receive Frame Location
+#define  CS_PP_TXFRAME     0x0A00          // Transmit Frame Location
+
+
+// removed interrupt from library
+#if 0
+// hardware interrupt vector handler 
+_interrupt(0x18) void cs8900_interrupt(void)
+{
+  struct cs8900if *cs8900if = cs8900if_netif->state;
+  // network interface is configured?
+  if (cs8900if != NULL)
+  {
+    // chip needs service
+    cs8900if->needs_service = 1;
+#if (CS8900_STATS > 0)
+    cs8900if->interrupts++;
+#endif
+  }
+#ifdef LED_NEED_SERVICE
+  leds_on(LED_NEED_SERVICE);
+#endif
+}
+#endif
+
+// cs8900_init()
+//
+// initializes the CS8900A chip
+//
+static void cs8900_init(struct netif *netif)
+{
+#ifdef LED_NEED_SERVICE
+  leds_off(LED_NEED_SERVICE);
+#endif
+
+  // set RESET bit
+  PACKETPP = CS_PP_SELFCTL;
+  PPDATA = 0x0055U;
+
+  // { the RESET bit will be cleared by the cs8900a
+  //   as a result of the reset }
+  // RESET bit cleared?
+  while((PPDATA & 0x0040U) != 0); // TODO: add timeout
+
+  // { after full initialization of the cs8900a
+  //   the INITD bit will be set }
+
+  PACKETPP = CS_PP_SELFTEST;
+  // INITD bit still clear?
+  while ((PPDATA & 0x0080U) == 0); // TODO: add timeout
+  // { INITD bit is set }
+
+  // SIBUSY bit still set?
+  while ((PPDATA & 0x0100U) == 0x0100); // TODO: add timeout
+  // { SIBUSY bit clear }
+
+#if 1
+  { 
+  u16_t dummy;
+  // datasheet section 3.3.3 
+  dummy = *(u16_t *)(MEM_BASE + IO_BASE + 0x0D);
+  // Dummy read, put chip in 16-bit mode
+  dummy = *(u16_t *)(MEM_BASE + IO_BASE + 0x0D);
+  }
+#endif
+
+  // Set MAC address
+  PACKETPP = CS_PP_IA1;
+  PPDATA = (u16_t)(netif->hwaddr[0]) | (u16_t)(netif->hwaddr[1] << 8U);
+  PACKETPP = CS_PP_IA2;
+  PPDATA = (u16_t)(netif->hwaddr[2]) | (u16_t)(netif->hwaddr[3] << 8U);
+  PACKETPP = CS_PP_IA3;
+  PPDATA = (u16_t)(netif->hwaddr[4]) | (u16_t)(netif->hwaddr[5] << 8U);
+
+  // accept valid unicast or broadcast frames
+  PACKETPP = CS_PP_RXCTL;
+  PPDATA = (0x0005U | 0x0800U/*broadcast*/ | 0x0400U/*individual*/ | 0x0100U/*RxOK*/);
+  // enable receive interrupt
+  PACKETPP = CS_PP_RXCFG;
+  PPDATA = (0x0003U | 0x0100U/*RXIRQ*/);
+
+  // disable transmit interrupt (is default)
+  PACKETPP = CS_PP_TXCFG;
+  PPDATA = (0x0007U | 0);
+
+  // use interrupt number 0
+  PACKETPP = CS_PP_INTNUM;
+  PPDATA = (0x0000U);
+
+  // generate interrupt event on:
+  // - the RxMISS counter reaches 0x200, or
+  // - a received frame is lost
+  PACKETPP = CS_PP_BUFCFG;
+  PPDATA = (0x000bU |
+#if (CS8900_STATS > 0) // interrupt before counter overflow 
+  (0x2000U/*MissOvfloiE*/ | 0x1000U/*TxColOvfloiE*/) |
+#endif
+#if (CS8900_STATS > 1) // interrupt on counter increment
+  (0x0400U/*RxMissiE*/) |
+#endif
+  0x0000);
+
+  // enable interrupt generation
+  PACKETPP = CS_PP_BUSCTL;
+  PPDATA = (0x0017U | 0x8000U/*EnableIRQ*/);
+
+  // enable:
+  // - receiver
+  // - transmitter
+  PACKETPP = CS_PP_LINECTL;
+  PPDATA = (0x0013U | 0x0080U/*SerTxOn*/ | 0x0040U/*SerRxOn*/);
+}
+
+static err_t cs8900_output(struct netif *netif, struct pbuf *p)
+{
+       int tries = 0;
+
+  // exit if link has failed
+  PACKETPP = CS_PP_LINESTATUS;
+  if ((PPDATA & 0x0080U/*LinkOK*/) == 0) return ERR_CONN; // no Ethernet link
+
+  /* issue 'transmit' command to CS8900 */
+  TXCMD = 0x00C9U;
+  /* send length (in bytes) of packet to send */
+  TXLENGTH = p->tot_len;
+
+  PACKETPP = CS_PP_BUSSTATUS;
+  // not ready for transmission and still within 100 retries?
+  while(((PPDATA & 0x0100U/*Rdy4TxNOW*/) == 0) && (tries++ < 100))
+  {
+    // throw away the last committed received frame
+    PACKETPP = CS_PP_RXCFG;
+    PPDATA = (0x0003U | 0x0040U/*Skip_1*/ | 0x0100U/*RxOKiE*/);
+    PACKETPP = CS_PP_BUSSTATUS;
+    /* cs8900if->dropped++; // CHECK: we do not know if we actually will drop a frame here */ 
+  }
+  // ready to transmit?
+  if((PPDATA & 0x0100U/*Rdy4TxNOW*/) != 0)
+  {
+    // q traverses through linked list of pbuf's
+    struct pbuf *q;
+    for(q = p; q != NULL; q = q->next)
+    {
+      u16_t i;
+      u16_t *ptr = (u16_t *)q->payload;
+      // Send the data from the pbuf to the interface, one pbuf at a
+      // time. The size of the data in each pbuf is kept in the ->len
+      // variable.
+      for(i = 0; i < q->len; i += 2)
+      {
+        RXTXREG = *ptr++;
+      }
+#if (CS8900_STATS > 0)
+      ((struct cs8900if *)netif->state)->sentbytes += q->len;
+#endif
+#if LWIP_SNMP > 0
+    snmp_add_ifoutoctets(p->tot_len);
+#endif
+#if (CS8900_STATS > 0)
+    ((struct cs8900if *)netif->state)->sentpackets++;
+#endif
+    }
+  }
+  else
+  {
+    // { not ready to transmit!? }
+#if LWIP_SNMP > 0
+    snmp_inc_ifoutdiscards();
+#endif
+  }
+  return ERR_OK;
+}
+
+/**
+ * Move a received packet from the cs8900 into a new pbuf.
+ *
+ * Must be called after reading an ISQ event containing the
+ * "Receiver Event" register, before reading new ISQ events.
+ *
+ * This function copies a frame from the CS8900A.
+ * It is designed failsafe:
+ * - It does not assume a frame is actually present.
+ * - It checks for non-zero length
+ * - It does not overflow the frame buffer
+ */
+static struct pbuf *cs8900_input(struct netif *netif)
+{
+  struct pbuf *p = NULL, *q = NULL;
+  u16_t len = 0;
+  u16_t event_type;
+  u16_t i;
+  u16_t *ptr = NULL;
+
+  // read RxStatus
+  event_type = RXTXREG;
+
+  // correctly received frame, either broadcast or individual address?
+  // TODO: maybe defer these conditions to cs8900_input()
+  if ((event_type & 0x0100U/*RxOK*/) && (event_type & 0x0c00U/*Broadcast | Individual*/))
+  {
+#if LWIP_SNMP > 0
+    // update number of received MAC-unicast and non-MAC-unicast packets
+    if (event_type & 0x0400U/*Individual*/)
+    {
+      snmp_inc_ifinucastpkts();
+    }
+    else
+    {
+      snmp_inc_ifinnucastpkts();
+    }
+#endif
+    event_type = 0; 
+    // read RxLength
+    len = RXTXREG;
+    DEBUGF(NETIF_DEBUG, ("cs8900_input: packet len %u\n", len));
+#if LWIP_SNMP > 0    
+    snmp_add_ifinoctets(len);
+#endif
+    // positive length?
+    if (len > 0)
+    {
+      // allocate a pbuf chain with total length 'len' 
+      p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL);
+      if (p != 0)
+      {
+        for (q = p; q != 0; q = q->next)
+             {
+          DEBUGF(NETIF_DEBUG, ("cs8900_input: pbuf @%p len %u\n", q, q->len));
+               ptr = q->payload;
+          // TODO: CHECK: what if q->len is odd? we don't use the last byte?
+               for (i = 0; i < (q->len + 1) / 2; i++)
+         {
+                 *ptr = RXTXREG;
+                 ptr++;
+         }
+       }
+      }
+      // could not allocate a pbuf
+      else
+      {
+        // skip received frame
+        // TODO: maybe do not skip the frame at this point in time?
+        PACKETPP = CS_PP_RXCFG;
+        PPDATA = (0x0003U | 0x0100U/*RxOKiE*/ | 0x0040U/*Skip_1*/);
+#if (CS8900_STATS > 0)
+        ((struct cs8900if *)netif->state)->dropped++;
+#endif
+#if LWIP_SNMP > 0    
+        snmp_inc_ifindiscards();
+#endif
+        len = 0;
+      }
+    }
+    // length was zero
+    else
+    {
+    }
+  }
+  return p;
+}
+
+
+/**
+ * To be called when the cs8900a needs service. Does
+ * not assume the cs8900a needs service. Does test the
+ * cs8900a whether it needs service. 
+ *
+ * As such, may be used robustly called as a deferred
+ * (or "late") interrupt handler, or may be called in
+ * a loop to implement polling, or both.
+ *
+ * Use cs8900if_service() from your application instead
+ * of this function. 
+ */
+static void cs8900_service(struct netif *netif)
+{
+  // amount of ISQ's to handle (> 0) in one cs8900_service() call
+  unsigned char events2service = 1;
+  // NOTES:
+  // static, so only initialized to zero at program start.
+  // irq_status will always hold the last ISQ event register that
+  // still needs service. As such, we may leave this function if
+  // we encounter an event we cannot service yet, and return later
+  // to try to service it.
+  static u16_t irq_status = 0x0000U;
+
+  // The "cs8900_needs_service" flag indicates whether any events
+  // still need to be serviced.
+  // clear flag here. 
+  // a receive interrupt can, *concurrently with this function*,
+  // set this flag on new ISQ event occurences.
+  // we will re-evaluate the correct setting of this flag at
+  // function exit (below).
+  ((struct cs8900if *)netif->state)->needs_service = 0;
+#ifdef LED_NEED_SERVICE
+  leds_off(LED_NEED_SERVICE);
+#endif
+  // no unhandled irq_status left?
+  if (irq_status == 0x0000U)
+  {
+    // read ISQ register
+    irq_status = ISQ;
+  }
+  // ISQ interrupt event, and allowed to service in this loop?
+  while ((irq_status != 0x0000U) && (events2service-- > 0))
+  {
+    // investigate event
+    if ((irq_status & 0x003fU) == 0x0004U/*Receiver Event*/)
+    {
+      // correctly received frame, either broadcast or individual address
+      // TODO: think where these checks should appear: here or in cs8900_input()
+      if ((irq_status & 0x0100U/*RxOK*/) && (irq_status & 0x0c00U/*Broadcast | Individual*/))
+      {
+        // read the frame from the cs8900a
+        cs8900if_input(netif);
+      }
+      else
+      {
+        // skip this frame
+        PACKETPP = CS_PP_RXCFG;
+        PPDATA |= 0x0040U/*Skip_1*/;
+#if (CS8900_STATS > 0)
+        ((struct cs8900if *)netif->state)->dropped++;
+#endif
+      }
+    }
+#if (CS8900_STATS > 0)
+    else if ((irq_status & 0x003fU) == 0x0010U/*RxMISS Event*/)
+    {
+         ((struct cs8900if *)netif->state)->missed += (irq_status >> 6);
+       }
+    else if ((irq_status & 0x003fU) == 0x0012U/*TxCOL Event*/)
+    {
+         ((struct cs8900if *)netif->state)->collisions += (irq_status >> 6);
+       }
+#endif
+    // read ISQ register
+    irq_status = ISQ;
+  }
+
+  // we did not deplete the ISQ?
+  if (irq_status != 0x0000U)
+  {
+    // the cs8900a still needs service
+    ((struct cs8900if *)netif->state)->needs_service = 1;
+#ifdef LED_NEED_SERVICE
+    leds_on(LED_NEED_SERVICE);
+#endif
+  }
+#if (CS8900_STATS > 1)
+  // read RxMiss Counter (zeroes itself upon read)
+  PACKETPP = CS_PP_RXMISS;
+  ((struct cs8900if *)netif->state)->missed += (PPDATA >> 6);
+  // read RxCol Counter (zeroes itself upon read)
+  PACKETPP = CS_PP_TXCOL;
+  ((struct cs8900if *)netif->state)->collisions += (PPDATA >> 6);
+#endif
+}
+
+/**
+ * Service the CS8900.
+ *
+ * Can be called in a polling manner, or only after the CS8900 has raised
+ * an interrupt request.
+ *
+ * @param netif The lwIP network interface data structure belonging to this device.
+ *
+ */
+void cs8900if_service(struct netif *netif)
+{
+  // is there a reason to call the service routine?
+  if ((((struct cs8900if *)netif->state)->needs_service) ||
+      (((struct cs8900if *)netif->state)->use_polling))
+  {
+    cs8900_service(netif);
+  }
+}
+
+/**
+ * Writing an IP packet (to be transmitted) to the CS8900.
+ *
+ * Before writing a frame to the CS8900, the ARP module is asked to resolve the
+ * Ethernet MAC address. The ARP module might undertake actions to resolve the
+ * address first, and queue this packet for later transmission.
+ *
+ * @param netif The lwIP network interface data structure belonging to this device.
+ * @param p pbuf to be transmitted (or the first pbuf of a chained list of pbufs).
+ * @param ipaddr destination IP address.
+ *
+ * @internal It uses the function cs8900_input() that should handle the actual
+ * reception of bytes from the network interface.
+ *
+ */
+err_t cs8900if_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
+{
+  struct cs8900if *cs8900if = netif->state;
+  p = etharp_output(netif, ipaddr, p);
+  /* network hardware address obtained? */
+  if (p != NULL)
+  {
+         /* send out the packet */
+    cs8900_output(netif, p);
+         /* ARP cleanup */
+    etharp_output_sent(p);
+    p = NULL;
+  }
+  // { p == NULL }
+       else
+       {
+         /* we cannot tell if the packet was sent, the packet could have been queued */
+    /* on an ARP entry that was already pending. */
+       }
+  return ERR_OK;
+}
+/**
+ * Read a received packet from the CS8900.
+ *
+ * This function should be called when a packet is received by the CS8900
+ * and is fully available to read. It moves the received packet to a pbuf
+ * which is forwarded to the IP network layer or ARP module. It transmits
+ * a resulting ARP reply or queued packet.
+ *
+ * @param netif The lwIP network interface to read from.
+ *
+ * @internal Uses cs8900_input() to move the packet from the CS8900 to a
+ * newly allocated pbuf.
+ *
+ */
+void cs8900if_input(struct netif *netif)
+{
+  struct cs8900if *cs8900if = netif->state;
+  struct eth_hdr *ethhdr = NULL;
+  struct pbuf *p = NULL, *q = NULL;
+
+  /* move received packet into a new pbuf */
+  p = cs8900_input(netif);
+  /* no packet could be read */
+  if (p == NULL) {
+    /* silently ignore this */
+    return;
+  }
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = p->payload;
+  
+  q = NULL;
+  switch(htons(ethhdr->type)) {
+  /* IP packet? */
+  case ETHTYPE_IP:
+    /* update ARP table, obtain first queued packet */
+    q = etharp_ip_input(netif, p);
+    /* skip Ethernet header */
+    pbuf_header(p, -14);
+    /* pass to network layer */
+    netif->input(p, netif);
+    break;
+  /* ARP packet? */
+  case ETHTYPE_ARP:
+    /* pass p to ARP module, get ARP reply or ARP queued packet */
+    q = etharp_arp_input(netif, (struct eth_addr *)&netif->hwaddr, p);
+    break;
+  /* unsupported Ethernet packet type */
+  default:
+    /* free pbuf */
+    pbuf_free(p);
+    p = NULL;
+    break;
+  }
+  /* send out the ARP reply or ARP queued packet */
+  if (q != NULL) {
+    /* q pbuf has been succesfully sent? */
+    if (cs8900_output(netif, q) == ERR_OK)
+    {
+      pbuf_free(q);
+      q = NULL;
+    }
+    else
+    {
+      /* TODO: re-queue packet in the ARP cache here (?) */
+      pbuf_free(q);
+      q = NULL;
+    }
+  }
+}
+/**
+ * Initialize the CS8900 Ethernet MAC/PHY device driver.
+ *
+ * @param netif The lwIP network interface data structure belonging to this device.
+ *
+ */
+void cs8900if_init(struct netif *netif)
+{
+  struct cs8900if *cs8900if;
+
+  cs8900if = mem_malloc(sizeof(struct cs8900if));
+       if(cs8900if == NULL) return;
+
+  // initialize lwip network interface
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  netif->output = cs8900if_output;
+  netif->linkoutput = cs8900_output;
+
+  // initialize cs8900 specific interface structure
+  netif->state = cs8900if;
+
+  // initially assume no ISQ event
+  cs8900if->needs_service = 0;
+  // set to 1 if polling method is used
+  cs8900if->use_polling = 0;
+
+#if (CS8900_STATS > 0)
+  // number of interrupt service routine calls
+  cs8900if->interrupts = 0;
+  cs8900if->missed = 0;
+  cs8900if->dropped = 0;
+  cs8900if->sentpackets = 0;
+  cs8900if->sentbytes = 0;
+#endif
+
+  // intialize the cs8900a chip
+  cs8900_init(netif);
+}
+
+#if 1 
+/**
+ * Dump an array of bytes inside a UDP message's data field.
+ *
+ * It is a self-contained function, independent of higher protocol layers or other
+ * functions, so it allows you to debug these higher layers, such as lwIP.
+ *
+ * @param p pointer to an array of bytes, at least with length 'len'
+ * @param len number of bytes available at the address pointed to by 'p'
+ */
+void cs8900_send_debug(unsigned char *p, unsigned int len)
+{
+       int tries = 0, i;
+
+  // network interface state
+  extern struct netif *ethif;
+
+  // exit if link has failed
+  PACKETPP = CS_PP_LINESTATUS;
+  if ((PPDATA & 0x0080U/*LinkOK*/) == 0) return; // TODO: find a correct error code
+
+  // transmit command
+  TXCMD = 0x00C9U;
+       // send at least 60 bytes
+  TXLENGTH = (14 + 20 + 8 + len < 60) ? 60 : (14 + 20 + 8 + len);
+
+  PACKETPP = CS_PP_BUSSTATUS;
+  // not ready for transmission and still within 100 retries?
+  while (((PPDATA & 0x0100U/*Rdy4TxNOW*/) == 0) && (tries++ < 100))
+  {
+    // throw away the last committed received frame
+    PACKETPP = CS_PP_RXCFG;
+    PPDATA = (0x0003U | 0x0040U/*Skip_1*/ | 0x0100U/*RxOKiE*/);
+    PACKETPP = CS_PP_BUSSTATUS;
+    /* cs8900if->dropped++; CHECK: we do not know if we actually will drop a frame here, do we? */ 
+  }
+  // ready to transmit?
+  if((PPDATA & 0x0100U/*Rdy4TxNOW*/) != 0)
+  { 
+    u16_t data, checksum = 0;
+    u32_t udp_checksum = 0;
+                     
+    // destination Ethernet address
+    RXTXREG = 0xa000U; 
+    RXTXREG = 0xc524U; 
+    RXTXREG = 0x6d72U; 
+    // source Ethernet address
+    RXTXREG = htons(((u16_t)ethif->hwaddr[0] << 8U) | (u16_t)ethif->hwaddr[1]); 
+    RXTXREG = htons(((u16_t)ethif->hwaddr[2] << 8U) | (u16_t)ethif->hwaddr[3]); 
+    RXTXREG = htons(((u16_t)ethif->hwaddr[4] << 8U) | (u16_t)ethif->hwaddr[5]);
+    // frame type
+    RXTXREG = htons(0x0800);
+    // TOS, version
+    RXTXREG = htons(data = ((0x40 | 0x05) << 8) | 0x00); 
+    checksum += data;
+    // length
+    RXTXREG = htons(data = 20 + 8 + len); 
+    checksum += data;
+    // identifier
+    RXTXREG = htons(data = 0); 
+    checksum += data;
+    // fragment offset
+    RXTXREG = htons(data = 0); 
+    checksum += data;
+    // TTL, UDP protocol
+    RXTXREG = htons(data = (255U << 8) | 17U); 
+    checksum += data;
+
+    checksum += (htonl(ethif->ip_addr.addr) & 0xffff0000U) >> 16;
+    checksum += (htonl(ethif->ip_addr.addr) & 0x0000ffffU);
+    checksum += 0xc0a8U;
+    checksum += 0x0001U;
+    checksum += 6; // LW: kludge/hack: checksum calculation seems to be wrong somehow
+    // LW: this seems (?) to fix it
+    // checksum
+    RXTXREG = htons(~checksum); 
+
+    // source IP
+    RXTXREG = htons((htonl(ethif->ip_addr.addr) & 0xffff0000U) >> 16); 
+    // source IP           
+    RXTXREG = htons( htonl(ethif->ip_addr.addr) & 0x0000ffffU); 
+    // destination IP
+    RXTXREG = htons(0xc0a8U); 
+    // destination IP
+    RXTXREG = htons(0x0001U); 
+    // source port 3000
+    RXTXREG = htons(3000U); 
+    // destination port 3000
+    RXTXREG = htons(3000U); 
+    // UDP length
+    RXTXREG = htons(len); 
+    // UDP checksum (not present)
+
+    udp_checksum =  (htonl(ethif->ip_addr.addr) & 0xffff0000U) >> 16;
+    udp_checksum += (htonl(ethif->ip_addr.addr) & 0x0000ffffU);
+    udp_checksum += 0xc0a8U;
+    udp_checksum += 0x0001U;
+    udp_checksum += 0x0011U;
+    udp_checksum += (8 + len);
+    udp_checksum += 3000;
+    udp_checksum += 3000;
+    udp_checksum += (8 + len);
+    udp_checksum += cs8900_chksum(p, len);
+    while(udp_checksum >> 16) {
+      udp_checksum = (udp_checksum & 0xffffUL) + (udp_checksum >> 16);
+    }    
+
+    RXTXREG = htons(~(udp_checksum & 0xffff));
+         // UDP data
+    for (i = 0; i < len; i += 2)
+    {
+      RXTXREG = htons((p[i] << 8) | p[i + 1]);
+    } 
+         // pad to 60 bytes
+         while (i < 60)
+         {
+      RXTXREG = 0;
+           i += 2;
+         }
+  }
+}
+
+static u32_t cs8900_chksum(void *dataptr, int len)
+{
+  u32_t acc = 0;
+  u16_t *ptr = (u16_t *)dataptr;
+    
+  for(acc = 0; len > 1; len -= 2) {
+    acc += *ptr;
+    ptr++;
+  }
+  /* add up any odd byte */
+  if(len == 1) {
+    acc += htons((u16_t)((*(u8_t *)ptr) & 0xffU) << 8);
+  }
+  return acc;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/arch/c16x/perf.c b/src/arch/c16x/perf.c
new file mode 100644 (file)
index 0000000..d03e79d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: perf.c,v 1.1 2002/11/29 11:03:34 likewise Exp $
+ */
+
+#include "arch/perf.h"
+
+void
+perf_init(char *fname)
+{
+  if (fname); // LEON: prevent warning
+}
diff --git a/src/arch/c16x/sys_arch.c b/src/arch/c16x/sys_arch.c
new file mode 100644 (file)
index 0000000..bad0b06
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: sys_arch.c,v 1.1 2002/11/29 11:03:34 likewise Exp $
+ */
+
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+
+//#include "timers.h"
+
+static struct sys_timeouts timeouts;
+
+/*-----------------------------------------------------------------------------------*/
+sys_mbox_t
+sys_mbox_new(void)
+{
+  return SYS_MBOX_NULL;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_free(sys_mbox_t mbox)
+{
+  if (mbox); // LEON: prevent warning
+  return;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_post(sys_mbox_t mbox, void *data)
+{
+  if (mbox); // LEON: prevent warning
+  if (data); // LEON: prevent warning
+  return;
+}
+
+u16_t
+sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout)
+{
+  if (mbox); // LEON: prevent warning
+  if (msg); // LEON: prevent warning
+  if (timeout); // LEON: prevent warning
+  return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+sys_sem_t
+sys_sem_new(u8_t count)
+{
+  if (count);
+  return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+u16_t
+sys_arch_sem_wait(sys_sem_t sem, u16_t timeout)
+{
+  if (sem);
+  return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_sem_signal(sys_sem_t sem)
+{
+  if (sem);
+  return;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_sem_free(sys_sem_t sem)
+{
+  if (sem);
+  return;
+}
+
+void
+sys_init(void)
+{
+  timeouts.next = NULL;
+  return;
+}
+
+struct sys_timeouts *
+sys_arch_timeouts(void)
+{
+  return &timeouts;
+}
+
+u8_t                   
+sys_timeout_u32_t(u32_t msecs, sys_timeout_handler h, void *data) // LEON: arg 1 was unsigned int
+{
+  return 0;
+  // WAS: return timer_obtain(msecs, h, data);
+  // RE-ENABLE IF DHCP_TIMER_CALLBACKS
+#if DHCP_TIMER_CALLBACKS
+#error DHCP_TIMER_CALLBACKS not supported!
+#endif
+}
+
+void
+sys_thread_new(void (* function)(void *arg), void *arg)
+{
+  if (arg); // LW
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_main(void)
+{
+}
+/*-----------------------------------------------------------------------------------*/