mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-28 14:54:05 +00:00
Initial commit of C16x/ST10 arch files and CS8900a Ethernet driver.
This commit is contained in:
parent
0ed4fd6741
commit
1d341bae31
@ -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:
|
||||
|
||||
|
13
src/arch/c16x/FILES
Normal file
13
src/arch/c16x/FILES
Normal file
@ -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>
|
20
src/arch/c16x/include/arch/cc.h
Normal file
20
src/arch/c16x/include/arch/cc.h
Normal file
@ -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__ */
|
6
src/arch/c16x/include/arch/cpu.h
Normal file
6
src/arch/c16x/include/arch/cpu.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __CPU_H__
|
||||
#define __CPU_H__
|
||||
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
|
||||
#endif /* __CPU_H__ */
|
43
src/arch/c16x/include/arch/lib.h
Normal file
43
src/arch/c16x/include/arch/lib.h
Normal file
@ -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__ */
|
41
src/arch/c16x/include/arch/perf.h
Normal file
41
src/arch/c16x/include/arch/perf.h
Normal file
@ -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__ */
|
15
src/arch/c16x/include/arch/sys_arch.h
Normal file
15
src/arch/c16x/include/arch/sys_arch.h
Normal file
@ -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__ */
|
79
src/arch/c16x/include/netif/cs8900if.h
Normal file
79
src/arch/c16x/include/netif/cs8900if.h
Normal file
@ -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__ */
|
96
src/arch/c16x/lib.c
Normal file
96
src/arch/c16x/lib.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
846
src/arch/c16x/netif/cs8900if.c
Normal file
846
src/arch/c16x/netif/cs8900if.c
Normal file
@ -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
|
42
src/arch/c16x/perf.c
Normal file
42
src/arch/c16x/perf.c
Normal file
@ -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
|
||||
}
|
137
src/arch/c16x/sys_arch.c
Normal file
137
src/arch/c16x/sys_arch.c
Normal file
@ -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)
|
||||
{
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
Loading…
x
Reference in New Issue
Block a user