coldfire port.patch #872 from David Haas
This commit is contained in:
parent
1cb0c2930a
commit
2b84c23ea3
|
@ -14,6 +14,9 @@ unix/ - Architectural files for testing on unix-like systems
|
|||
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)
|
||||
|
||||
coldfire/ - Architectural files for Motorola Coldfire 5272 CPU running
|
||||
under Nucleus OS. Supports DMA and ISRs in ethernet driver.
|
||||
|
||||
|
||||
Each subdirectory (may) also include:
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
### README --- c:/cygwin/home/dhaas/work/cfimage/lwip/arch/coldfire/
|
||||
|
||||
##
|
||||
## Author: dhaas@alum.rpi.edu
|
||||
|
||||
These files are a port of lwip to coldfire (specifically the MCF5272 with
|
||||
on-board FEC) under the Nucleus OS. Nucleus is pretty generic so it should be
|
||||
fairly easy to port this to any other embedded OS. Nucleus memory managment
|
||||
is not used. It is assumed you have a working malloc (which at least
|
||||
long-word aligns memory).
|
||||
|
||||
The compiler used was Diab 4.3b. You will almost certainly need to change
|
||||
cc.h for your compiler.
|
||||
|
||||
IMPORTANT NOTE: If you use the fec driver for a different processor which has
|
||||
a data cache you will need to make sure the buffer descriptors and memory
|
||||
used for pbufs are not in a cachable area. Otherwise the fec driver is
|
||||
guarrenteed to malfunction. The 5272 which this was written for does not
|
||||
support data cache so it did not matter and malloc was used.
|
||||
|
||||
|
||||
I have not released a proj directory, since my system is probably very
|
||||
different than anyone trying to use this code. However my lwipopts file might
|
||||
look a little different, and I reproduce that here:
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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. 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: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
#define NO_SYS 0
|
||||
/*#define LWIP_EVENT_API 0*/
|
||||
|
||||
/* ---------- Memory options ---------- */
|
||||
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
|
||||
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
|
||||
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||
#define MEM_ALIGNMENT 4
|
||||
|
||||
/* MEM_SIZE: the size of the heap memory. If the application will send
|
||||
a lot of data that needs to be copied, this should be set high. */
|
||||
#define MEM_SIZE 65000
|
||||
|
||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||
sends a lot of data out of ROM (or other static memory), this
|
||||
should be set high. */
|
||||
#define MEMP_NUM_PBUF 16
|
||||
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
|
||||
per active UDP "connection". */
|
||||
#define MEMP_NUM_UDP_PCB 4
|
||||
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB 5
|
||||
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 8
|
||||
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
|
||||
segments. */
|
||||
#define MEMP_NUM_TCP_SEG 16
|
||||
|
||||
/* The following four are used only with the sequential API and can be
|
||||
set to 0 if the application only will use the raw API. */
|
||||
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
|
||||
#define MEMP_NUM_NETBUF 6
|
||||
/* MEMP_NUM_NETCONN: the number of struct netconns. */
|
||||
#define MEMP_NUM_NETCONN 10
|
||||
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
|
||||
communication between the TCP/IP stack and the sequential
|
||||
programs. */
|
||||
#define MEMP_NUM_API_MSG 16
|
||||
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
|
||||
for sequential API communication and incoming packets. Used in
|
||||
src/api/tcpip.c. */
|
||||
#define MEMP_NUM_TCPIP_MSG 16
|
||||
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
|
||||
timeouts. */
|
||||
#define MEMP_NUM_SYS_TIMEOUT 3
|
||||
|
||||
/* These two control is reclaimer functions should be compiled
|
||||
in. Should always be turned on (1). */
|
||||
#define MEM_RECLAIM 1
|
||||
#define MEMP_RECLAIM 1
|
||||
|
||||
/* ---------- Pbuf options ---------- */
|
||||
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
|
||||
#define PBUF_POOL_SIZE 128
|
||||
|
||||
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||
#define PBUF_POOL_BUFSIZE 1024
|
||||
|
||||
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
|
||||
link level header. */
|
||||
#define PBUF_LINK_HLEN 16
|
||||
|
||||
/* SYS_ISR_PROT: Define this macro if pbuf functions are called from
|
||||
an ISR and you need extra (and faster) critical region protection. */
|
||||
#define SYS_ISR_PROT 1
|
||||
|
||||
/* ---------- TCP options ---------- */
|
||||
#define LWIP_TCP 1
|
||||
#define TCP_TTL 255
|
||||
|
||||
/* Controls if TCP should queue segments that arrive out of
|
||||
order. Define to 0 if your device is low on memory. */
|
||||
#define TCP_QUEUE_OOSEQ 1
|
||||
|
||||
/* TCP Maximum segment size. */
|
||||
#define TCP_MSS 128
|
||||
|
||||
/* TCP sender buffer space (bytes). */
|
||||
#define TCP_SND_BUF 256
|
||||
|
||||
/* TCP sender buffer space (pbufs). This must be at least = 2 *
|
||||
TCP_SND_BUF/TCP_MSS for things to work. */
|
||||
#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS
|
||||
|
||||
/* TCP receive window. */
|
||||
#define TCP_WND 1024
|
||||
|
||||
/* Maximum number of retransmissions of data segments. */
|
||||
#define TCP_MAXRTX 12
|
||||
|
||||
/* Maximum number of retransmissions of SYN segments. */
|
||||
#define TCP_SYNMAXRTX 4
|
||||
|
||||
/* TCP writable space (bytes). This must be less than or equal
|
||||
to TCP_SND_BUF. It is the amount of space which must be
|
||||
available in the tcp snd_buf for select to return writable */
|
||||
#define TCP_SNDLOWAT TCP_SND_BUF/2
|
||||
|
||||
/* ---------- ARP options ---------- */
|
||||
#define ARP_TABLE_SIZE 10
|
||||
#define ARP_QUEUEING 1
|
||||
/**
|
||||
* - If enabled, cache entries are generated for every kind of ARP traffic or
|
||||
* broadcast IP traffic. This enhances behaviour for sending to a dynamic set
|
||||
* of hosts, for example if acting as a gateway.
|
||||
* - If disabled, cache entries are generated only for IP destination addresses
|
||||
* in use by lwIP or applications. This enhances performance if sending to a small,
|
||||
* reasonably static number of hosts. Typically for embedded devices.
|
||||
*/
|
||||
#define ETHARP_ALWAYS_INSERT 0
|
||||
|
||||
/* ---------- IP options ---------- */
|
||||
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
|
||||
IP packets across network interfaces. If you are going to run lwIP
|
||||
on a device with only one network interface, define this to 0. */
|
||||
#define IP_FORWARD 0
|
||||
|
||||
/* If defined to 1, IP options are allowed (but not parsed). If
|
||||
defined to 0, all packets with IP options are dropped. */
|
||||
#define IP_OPTIONS 1
|
||||
|
||||
/* IP reassembly and segmentation.These are orthogonal even
|
||||
* if they both deal with IP fragments */
|
||||
#define IP_REASSEMBLY 1
|
||||
#define IP_FRAG 1
|
||||
|
||||
/* ---------- ICMP options ---------- */
|
||||
#define ICMP_TTL 255
|
||||
|
||||
|
||||
/* ---------- DHCP options ---------- */
|
||||
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
|
||||
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
|
||||
turning this on does currently not work. */
|
||||
#define LWIP_DHCP 0
|
||||
|
||||
/* 1 if you want to do an ARP check on the offered address
|
||||
(recommended). */
|
||||
#define DHCP_DOES_ARP_CHECK 1
|
||||
|
||||
/* ---------- UDP options ---------- */
|
||||
#define LWIP_UDP 1
|
||||
#define UDP_TTL 255
|
||||
|
||||
|
||||
/* ---------- Statistics options ---------- */
|
||||
#define STATS
|
||||
|
||||
#ifdef STATS
|
||||
#define LINK_STATS
|
||||
#define IP_STATS
|
||||
#define ICMP_STATS
|
||||
#define UDP_STATS
|
||||
#define TCP_STATS
|
||||
#define MEM_STATS
|
||||
#define MEMP_STATS
|
||||
#define PBUF_STATS
|
||||
#define SYS_STATS
|
||||
#endif /* STATS */
|
||||
|
||||
|
||||
#define LWIP_COMPAT_SOCKETS
|
||||
#endif /* __LWIPOPTS_H__ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, 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: cc.h,v 1.1 2003/01/18 18:47:22 jani Exp $
|
||||
*/
|
||||
#ifndef __CC_H__
|
||||
#define __CC_H__
|
||||
|
||||
#include <types.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;
|
||||
|
||||
#define PACK_STRUCT_BEGIN #pragma pack(1,1,0)
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define ALIGN_STRUCT_8_BEGIN #pragma pack(1,8,0)
|
||||
#define ALIGN_STRUCT_END #pragma pack()
|
||||
#define PACK_STRUCT_END #pragma pack()
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
|
||||
|
||||
#define _SYS_TYPES_FD_SET
|
||||
#define NBBY 8 /* number of bits in a byte */
|
||||
|
||||
#ifndef FD_SETSIZE
|
||||
#define FD_SETSIZE 64
|
||||
#endif /* FD_SETSIZE */
|
||||
|
||||
typedef long fd_mask;
|
||||
#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
|
||||
#ifndef howmany
|
||||
#define howmany(x,y) (((x)+((y)-1))/(y))
|
||||
#endif /* howmany */
|
||||
|
||||
typedef struct _types_fd_set {
|
||||
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
|
||||
} _types_fd_set;
|
||||
|
||||
#define fd_set _types_fd_set
|
||||
|
||||
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
|
||||
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
|
||||
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
|
||||
#define FD_ZERO(p) do { \
|
||||
size_t __i; \
|
||||
char *__tmp = (char *)p; \
|
||||
for (__i = 0; __i < sizeof (*(p)); ++__i) \
|
||||
*__tmp++ = 0; \
|
||||
} while (0)
|
||||
|
||||
#endif /* __CC_H__ */
|
|
@ -0,0 +1,43 @@
|
|||
/* @(#)cpu.h
|
||||
* Copyright (c) 2001-2003, 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: David Haas <dhaas@alum.rpi.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CPU_H
|
||||
#define _CPU_H 1
|
||||
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#define IMM_ADDRESS (0x10000000)
|
||||
#define FEC_LEVEL 4
|
||||
|
||||
#endif /* _CPU_H */
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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: David Haas <dhaas@alum.rpi.edu>
|
||||
*
|
||||
* $Id:
|
||||
*/
|
||||
#ifndef __ERRNO_H__
|
||||
#define __ERRNO_H__
|
||||
|
||||
/* This can be used to test whether errno is implemented */
|
||||
#define ERRNO
|
||||
|
||||
#define errno (*sys_arch_errno())
|
||||
|
||||
|
||||
/* Error numbers */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EWOULDBLOCK 40 /* We would have blocked if this was'nt non-blocking i/o */
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, 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 2003/01/18 18:47:22 jani Exp $
|
||||
*/
|
||||
#ifndef __LIB_H__
|
||||
#define __LIB_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#endif /* __LIB_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 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. 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: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __PERF_H__
|
||||
#define __PERF_H__
|
||||
|
||||
#define PERF_START /* null definition */
|
||||
#define PERF_STOP(x) /* null definition */
|
||||
|
||||
#endif /* __PERF_H__ */
|
|
@ -0,0 +1,69 @@
|
|||
/* @(#)sys_arch.h
|
||||
* Copyright (c) 2001-2003 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. 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: David Haas
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ARCH_H
|
||||
#define _SYS_ARCH_H 1
|
||||
|
||||
#include <nucleus.h>
|
||||
#include <stdlib.h>
|
||||
#include "netif/etharp.h"
|
||||
|
||||
#define SYS_MBOX_NULL NULL
|
||||
#define SYS_SEM_NULL NULL
|
||||
|
||||
/* sockets needs this definition. include time.h if this is a unix system */
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
};
|
||||
|
||||
typedef NU_SEMAPHORE * sys_sem_t;
|
||||
typedef NU_QUEUE * sys_mbox_t;
|
||||
typedef NU_TASK * sys_thread_t;
|
||||
|
||||
/* Functions specific to Coldfire/Nucleus */
|
||||
void
|
||||
sys_setvect(u32_t vector, void (*isr_function)(void), void (*dis_funct)(void));
|
||||
u32_t
|
||||
sys_disable_interrupts(void);
|
||||
void
|
||||
sys_restore_interrupts(u32_t old_level);
|
||||
void
|
||||
sys_get_eth_addr(struct eth_addr *eth_addr);
|
||||
int *
|
||||
sys_arch_errno(void);
|
||||
|
||||
|
||||
#include "arch/errno.h"
|
||||
|
||||
#endif /* _SYS_ARCH_H */
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* @(#)5272fec.h
|
||||
* Copyright (c) 2001-2003 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. 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.
|
||||
*
|
||||
* Purpose: MCF5272 fec ethernet driver
|
||||
*
|
||||
* Author: David Haas
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _5272FEC_H
|
||||
#define _5272FEC_H 1
|
||||
|
||||
|
||||
void
|
||||
mcf5272fecif_init(struct netif *netif);
|
||||
|
||||
|
||||
#endif /* _5272FEC_H */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 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. 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: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __NETIF_TCPDUMP_H__
|
||||
#define __NETIF_TCPDUMP_H__
|
||||
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
void tcpdump(struct pbuf *p);
|
||||
|
||||
#endif /* __NETIF_TCPDUMP_H__ */
|
|
@ -0,0 +1,787 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003, 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: David Haas dhaas@alum.rpi.edu
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is an ethernet driver for the internal fec in the Coldfire MCF5272.
|
||||
The driver has been written to use ISRs for Receive Frame and Transmit Frame
|
||||
Complete.
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
#include "arch/mcf5272.h"
|
||||
|
||||
/* Sizing the descriptor rings will depend upon how many pbufs you have available
|
||||
* and how big they are. Also on how many frames you might want to input before dropping
|
||||
* frames. Generally it is a good idea to buffer one tcp window. This means that
|
||||
* you won't get a tcp retransmit and your tcp transmissions will be reasonably fast.
|
||||
*/
|
||||
#define NUM_RXBDS 64 // Number of receive descriptor rings
|
||||
#define NUM_TXBDS 32 // Number of transmit descriptor rings
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 'e'
|
||||
#define IFNAME1 't'
|
||||
|
||||
/* Define interface MTU size. We set this to 1518, since this is the max
|
||||
Size of an ethernet frame without VLAN support. */
|
||||
#define MTU_FEC 1518
|
||||
|
||||
PACK_STRUCT_BEGIN
|
||||
struct rxbd
|
||||
{
|
||||
u16_t flags;
|
||||
u16_t data_len;
|
||||
u8_t *p_buf;
|
||||
};
|
||||
PACK_STRUCT_END
|
||||
typedef struct rxbd rxbd_t;
|
||||
|
||||
PACK_STRUCT_BEGIN
|
||||
struct txbd
|
||||
{
|
||||
u16_t flags;
|
||||
u16_t data_len;
|
||||
u8_t *p_buf;
|
||||
};
|
||||
PACK_STRUCT_END
|
||||
typedef struct txbd txbd_t;
|
||||
|
||||
ALIGN_STRUCT_8_BEGIN
|
||||
struct mcf5272if
|
||||
{
|
||||
rxbd_t rxbd_a[NUM_RXBDS]; // Rx descriptor ring. Must be aligned to double-word
|
||||
txbd_t txbd_a[NUM_TXBDS]; // Tx descriptor ring. Must be aligned to double-word
|
||||
struct pbuf *rx_pbuf_a[NUM_RXBDS]; // Array of pbufs corresponding to payloads in rx desc ring.
|
||||
struct pbuf *tx_pbuf_a[NUM_TXBDS]; // Array of pbufs corresponding to payloads in tx desc ring.
|
||||
unsigned int rx_remove; // Index that driver will remove next rx frame from.
|
||||
unsigned int rx_insert; // Index that driver will insert next empty rx buffer.
|
||||
unsigned int tx_insert; // Index that driver will insert next tx frame to.
|
||||
unsigned int tx_remove; // Index that driver will clean up next tx buffer.
|
||||
unsigned int tx_free; // Number of free transmit descriptors.
|
||||
unsigned int rx_buf_len; // number of bytes in a rx buffer (that we can use).
|
||||
MCF5272_IMM *imm; // imm address. All register accesses use this as base.
|
||||
struct eth_addr *ethaddr;
|
||||
struct netif *netif;
|
||||
};
|
||||
ALIGN_STRUCT_END
|
||||
|
||||
typedef struct mcf5272if mcf5272if_t;
|
||||
|
||||
#define INC_RX_BD_INDEX(idx) do { if (++idx >= NUM_RXBDS) idx = 0; } while (0)
|
||||
#define INC_TX_BD_INDEX(idx) do { if (++idx >= NUM_TXBDS) idx = 0; } while (0)
|
||||
#define DEC_TX_BD_INDEX(idx) do { if (idx-- == 0) idx = NUM_TXBDS-1; } while (0)
|
||||
|
||||
static mcf5272if_t *mcf5272if;
|
||||
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||
|
||||
u32_t phy;
|
||||
|
||||
typedef struct mcf5272if mcf5272if_t;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
fill_rx_ring(mcf5272if_t *mcf5272)
|
||||
{
|
||||
struct pbuf *p;
|
||||
struct rxbd *p_rxbd;
|
||||
int i = mcf5272->rx_insert;
|
||||
void *new_payload;
|
||||
u32_t u_p_pay;
|
||||
|
||||
/* Try and fill as many receive buffers as we can */
|
||||
while (mcf5272->rx_pbuf_a[i] == 0)
|
||||
{
|
||||
p = pbuf_alloc(PBUF_RAW, (u16_t) mcf5272->rx_buf_len, PBUF_POOL);
|
||||
if (p == 0)
|
||||
/* No pbufs, so can't refill ring */
|
||||
return;
|
||||
/* Align payload start to be divisible by 16 as required by HW */
|
||||
u_p_pay = (u32_t) p->payload;
|
||||
new_payload = p->payload = (void *) (((u_p_pay + 15) / 16) * 16);
|
||||
|
||||
mcf5272->rx_pbuf_a[i] = p;
|
||||
p_rxbd = &mcf5272->rxbd_a[i];
|
||||
p_rxbd->p_buf = (u8_t *) new_payload;
|
||||
p_rxbd->flags = (p_rxbd->flags & MCF5272_FEC_RX_BD_W) | MCF5272_FEC_RX_BD_E;
|
||||
INC_RX_BD_INDEX(mcf5272->rx_insert);
|
||||
i = mcf5272->rx_insert;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
enable_fec(mcf5272if_t *mcf5272)
|
||||
{
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
int i;
|
||||
|
||||
/* Initialize empty tx descriptor ring */
|
||||
for(i = 0; i < NUM_TXBDS-1; i++)
|
||||
mcf5272->txbd_a[i].flags = 0;
|
||||
/* Set wrap bit for last descriptor */
|
||||
mcf5272->txbd_a[i].flags = MCF5272_FEC_TX_BD_W;
|
||||
/* initialize tx indexes */
|
||||
mcf5272->tx_remove = mcf5272->tx_insert = 0;
|
||||
mcf5272->tx_free = NUM_TXBDS;
|
||||
|
||||
/* Initialize empty rx descriptor ring */
|
||||
for (i = 0; i < NUM_RXBDS-1; i++)
|
||||
mcf5272->rxbd_a[i].flags = 0;
|
||||
/* Set wrap bit for last descriptor */
|
||||
mcf5272->rxbd_a[i].flags = MCF5272_FEC_RX_BD_W;
|
||||
/* Initialize rx indexes */
|
||||
mcf5272->rx_remove = mcf5272->rx_insert = 0;
|
||||
|
||||
/* Fill receive descriptor ring */
|
||||
fill_rx_ring(mcf5272);
|
||||
|
||||
/* Enable FEC */
|
||||
MCF5272_WR_FEC_ECR(imm, (MCF5272_FEC_ECR_ETHER_EN));// | 0x2000000));
|
||||
|
||||
/* Indicate that there have been empty receive buffers produced */
|
||||
MCF5272_WR_FEC_RDAR(imm,1);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
disable_fec(mcf5272if_t *mcf5272)
|
||||
{
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
int i;
|
||||
u32_t value;
|
||||
u32_t old_level;
|
||||
|
||||
/* We need to disable interrupts here, It is important when dealing with shared
|
||||
registers. */
|
||||
old_level = sys_disable_interrupts();
|
||||
|
||||
/* First disable the FEC interrupts. Do it in the appropriate ICR register. */
|
||||
value = MCF5272_RD_SIM_ICR3(imm);
|
||||
MCF5272_WR_SIM_ICR3(imm, (value & ~(MCF5272_SIM_ICR_ERX_IL(7) |
|
||||
MCF5272_SIM_ICR_ETX_IL(7) |
|
||||
MCF5272_SIM_ICR_ENTC_IL(7))));
|
||||
|
||||
/* Now we can restore interrupts. This is because we can assume that
|
||||
* we are single threaded here (only 1 thread will be calling disable_fec
|
||||
* for THIS interface). */
|
||||
sys_restore_interrupts(old_level);
|
||||
|
||||
/* Release all buffers attached to the descriptors. Since the driver
|
||||
* ALWAYS zeros the pbuf array locations and descriptors when buffers are
|
||||
* removed, we know we just have to free any non-zero descriptors */
|
||||
for (i = 0; i < NUM_RXBDS; i++)
|
||||
if (mcf5272->rx_pbuf_a[i])
|
||||
{
|
||||
pbuf_free(mcf5272->rx_pbuf_a[i]);
|
||||
mcf5272->rx_pbuf_a[i] = 0;
|
||||
mcf5272->rxbd_a->p_buf = 0;
|
||||
}
|
||||
for (i = 0; i < NUM_TXBDS; i++)
|
||||
if (mcf5272->tx_pbuf_a[i])
|
||||
{
|
||||
pbuf_free(mcf5272->tx_pbuf_a[i]);
|
||||
mcf5272->tx_pbuf_a[i] = 0;
|
||||
mcf5272->txbd_a->p_buf = 0;
|
||||
}
|
||||
|
||||
/* Reset the FEC - equivalent to a hard reset */
|
||||
MCF5272_WR_FEC_ECR(imm,MCF5272_FEC_ECR_RESET);
|
||||
/* Wait for the reset sequence to complete, it should take about 16 clock cycles */
|
||||
i = 0;
|
||||
while (MCF5272_RD_FEC_ECR(imm) & MCF5272_FEC_ECR_RESET)
|
||||
{
|
||||
if (++i > 100)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Disable all FEC interrupts by clearing the IMR register */
|
||||
MCF5272_WR_FEC_IMR(imm,0);
|
||||
/* Clear any interrupts by setting all bits in the EIR register */
|
||||
MCF5272_WR_FEC_EIR(imm,0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*
|
||||
* Function called by receive LISR to disable fec tx interrupt
|
||||
*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcf5272_dis_tx_int(void)
|
||||
{
|
||||
mcf5272if_t *mcf5272 = mcf5272if;
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
u32_t value;
|
||||
|
||||
value = MCF5272_RD_FEC_IMR(imm);
|
||||
/* Clear rx interrupt bit */
|
||||
MCF5272_WR_FEC_IMR(imm, (value & ~MCF5272_FEC_IMR_TXFEN));
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*
|
||||
*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcf5272fec_tx_cleanup(void)
|
||||
{
|
||||
struct pbuf *p;
|
||||
mcf5272if_t *mcf5272 = mcf5272if;
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
u32_t value;
|
||||
u32_t old_level;
|
||||
unsigned int tx_remove_sof;
|
||||
unsigned int tx_remove_eof;
|
||||
unsigned int i;
|
||||
u16_t flags;
|
||||
|
||||
|
||||
tx_remove_sof = tx_remove_eof = mcf5272->tx_remove;
|
||||
|
||||
/* Loop, looking for completed buffers at eof */
|
||||
while ((((flags = mcf5272->txbd_a[tx_remove_eof].flags) & MCF5272_FEC_TX_BD_R) == 0) &&
|
||||
(mcf5272->tx_pbuf_a[tx_remove_eof] != 0))
|
||||
{
|
||||
/* See if this is last buffer in frame */
|
||||
if ((flags & MCF5272_FEC_TX_BD_L) != 0)
|
||||
{
|
||||
i = tx_remove_eof;
|
||||
/* This frame is complete. Take the frame off backwards */
|
||||
do
|
||||
{
|
||||
p = mcf5272->tx_pbuf_a[i];
|
||||
mcf5272->tx_pbuf_a[i] = 0;
|
||||
mcf5272->txbd_a[i].p_buf = 0;
|
||||
mcf5272->tx_free++;
|
||||
if (i != tx_remove_sof)
|
||||
DEC_TX_BD_INDEX(i);
|
||||
else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
pbuf_free(p); // Will be head of chain
|
||||
/* Look at next descriptor */
|
||||
INC_TX_BD_INDEX(tx_remove_eof);
|
||||
tx_remove_sof = tx_remove_eof;
|
||||
}
|
||||
else
|
||||
INC_TX_BD_INDEX(tx_remove_eof);
|
||||
}
|
||||
mcf5272->tx_remove = tx_remove_eof;
|
||||
|
||||
/* clear interrupt status for tx interrupt */
|
||||
old_level = sys_disable_interrupts();
|
||||
MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_EIR_TXF);
|
||||
value = MCF5272_RD_FEC_IMR(imm);
|
||||
/* Set tx interrupt bit again */
|
||||
MCF5272_WR_FEC_IMR(imm, (value | MCF5272_FEC_IMR_TXFEN));
|
||||
/* Now we can re-enable higher priority interrupts again */
|
||||
sys_restore_interrupts(old_level);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*
|
||||
void low_level_output(mcf5272if_t *mcf5272, struct pbuf *p)
|
||||
|
||||
Output pbuf chain to hardware. It is assumed that there is a complete and correct
|
||||
ethernet frame in p. The only buffering we have in this system is in the
|
||||
hardware descriptor ring. If there is no room on the ring, then drop the frame.
|
||||
*-----------------------------------------------------------------------------------*/
|
||||
static err_t
|
||||
low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q;
|
||||
mcf5272if_t *mcf5272 = netif->state;
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
int num_desc;
|
||||
int num_free;
|
||||
unsigned int tx_insert_sof, tx_insert_eof;
|
||||
unsigned int i;
|
||||
u32_t old_level;
|
||||
|
||||
/* Interrupts are disabled through this whole thing to support multi-threading
|
||||
* transmit calls. Also this function might be called from an ISR. */
|
||||
old_level = sys_disable_interrupts();
|
||||
|
||||
/* Determine number of descriptors needed */
|
||||
num_desc = pbuf_clen(p);
|
||||
if (num_desc > mcf5272->tx_free)
|
||||
{
|
||||
/* Drop the frame, we have no place to put it */
|
||||
pbuf_free(p);
|
||||
#ifdef LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
#endif
|
||||
sys_restore_interrupts(old_level);
|
||||
return ERR_MEM;
|
||||
|
||||
} else {
|
||||
/* Increment use count on pbuf */
|
||||
pbuf_ref(p);
|
||||
|
||||
/* Put buffers on descriptor ring, but don't mark them as ready yet */
|
||||
tx_insert_eof = tx_insert_sof = mcf5272->tx_insert;
|
||||
q = p;
|
||||
do
|
||||
{
|
||||
mcf5272->tx_free--;
|
||||
mcf5272->tx_pbuf_a[tx_insert_eof] = q;
|
||||
mcf5272->txbd_a[tx_insert_eof].p_buf = q->payload;
|
||||
mcf5272->txbd_a[tx_insert_eof].data_len = q->len;
|
||||
q = q->next;
|
||||
if (q)
|
||||
INC_TX_BD_INDEX(tx_insert_eof);
|
||||
} while (q);
|
||||
|
||||
/* Go backwards through descriptor ring setting flags */
|
||||
i = tx_insert_eof;
|
||||
do
|
||||
{
|
||||
mcf5272->txbd_a[i].flags = (u16_t) (MCF5272_FEC_TX_BD_R |
|
||||
(mcf5272->txbd_a[i].flags & MCF5272_FEC_TX_BD_W) |
|
||||
((i == tx_insert_eof) ? (MCF5272_FEC_TX_BD_L | MCF5272_FEC_TX_BD_TC) : 0));
|
||||
if (i != tx_insert_sof)
|
||||
DEC_TX_BD_INDEX(i);
|
||||
else
|
||||
break;
|
||||
} while (1);
|
||||
INC_TX_BD_INDEX(tx_insert_eof);
|
||||
mcf5272->tx_insert = tx_insert_eof;
|
||||
#ifdef LINK_STATS
|
||||
lwip_stats.link.xmit++;
|
||||
#endif
|
||||
/* Indicate that there has been a transmit buffer produced */
|
||||
MCF5272_WR_FEC_TDAR(imm,1);
|
||||
sys_restore_interrupts(old_level);
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* This function is called by the TCP/IP stack when an IP packet
|
||||
* should be sent. It calls the function called low_level_output() to
|
||||
* do the actuall transmission of the packet.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static err_t
|
||||
mcf5272fecif_output(struct netif *netif, struct pbuf *p,
|
||||
struct ip_addr *ipaddr)
|
||||
{
|
||||
p = etharp_output(netif, ipaddr, p);
|
||||
if(p != NULL) {
|
||||
low_level_output(netif, p);
|
||||
}
|
||||
return ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
eth_input(struct pbuf *p, struct netif *netif)
|
||||
{
|
||||
/* Ethernet protocol layer */
|
||||
struct eth_hdr *ethhdr;
|
||||
mcf5272if_t *mcf5272 = netif->state;
|
||||
struct pbuf *q = NULL;
|
||||
|
||||
ethhdr = p->payload;
|
||||
|
||||
switch(htons(ethhdr->type)) {
|
||||
case ETHTYPE_IP:
|
||||
q = etharp_ip_input(netif, p);
|
||||
pbuf_header(p, -14);
|
||||
netif->input(p, netif);
|
||||
break;
|
||||
case ETHTYPE_ARP:
|
||||
q = etharp_arp_input(netif, mcf5272->ethaddr, p);
|
||||
break;
|
||||
default:
|
||||
pbuf_free(p);
|
||||
break;
|
||||
}
|
||||
if(q != NULL) {
|
||||
low_level_output(netif, q);
|
||||
pbuf_free(q);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
arp_timer(void *arg)
|
||||
{
|
||||
etharp_tmr();
|
||||
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*
|
||||
* Function called by receive LISR to disable fec rx interrupt
|
||||
*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcf5272_dis_rx_int(void)
|
||||
{
|
||||
mcf5272if_t *mcf5272 = mcf5272if;
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
u32_t value;
|
||||
|
||||
value = MCF5272_RD_FEC_IMR(imm);
|
||||
/* Clear rx interrupt bit */
|
||||
MCF5272_WR_FEC_IMR(imm, (value & ~MCF5272_FEC_IMR_RXFEN));
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcf5272fec_rx(void)
|
||||
{
|
||||
/* This is the receive ISR. It is written to be a high-level ISR. */
|
||||
u32_t old_level;
|
||||
mcf5272if_t *mcf5272 = mcf5272if;
|
||||
MCF5272_IMM *imm = mcf5272->imm;
|
||||
u32_t value;
|
||||
u16_t flags;
|
||||
unsigned int rx_remove_sof;
|
||||
unsigned int rx_remove_eof;
|
||||
struct pbuf *p;
|
||||
|
||||
|
||||
rx_remove_sof = rx_remove_eof = mcf5272->rx_remove;
|
||||
|
||||
/* Loop, looking for filled buffers at eof */
|
||||
while ((((flags = mcf5272->rxbd_a[rx_remove_eof].flags) & MCF5272_FEC_RX_BD_E) == 0) &&
|
||||
(mcf5272->rx_pbuf_a[rx_remove_eof] != 0))
|
||||
{
|
||||
/* See if this is last buffer in frame */
|
||||
if ((flags & MCF5272_FEC_RX_BD_L) != 0)
|
||||
{
|
||||
/* This frame is ready to go. Start at first descriptor in frame. */
|
||||
p = 0;
|
||||
do
|
||||
{
|
||||
/* Adjust pbuf length if this is last buffer in frame */
|
||||
if (rx_remove_sof == rx_remove_eof)
|
||||
{
|
||||
mcf5272->rx_pbuf_a[rx_remove_sof]->tot_len =
|
||||
mcf5272->rx_pbuf_a[rx_remove_sof]->len = (u16_t)
|
||||
(mcf5272->rxbd_a[rx_remove_sof].data_len - (p ? p->tot_len : 0));
|
||||
}
|
||||
else
|
||||
mcf5272->rx_pbuf_a[rx_remove_sof]->len =
|
||||
mcf5272->rx_pbuf_a[rx_remove_sof]->tot_len = mcf5272->rxbd_a[rx_remove_sof].data_len;
|
||||
|
||||
/* Chain pbuf */
|
||||
if (p == 0)
|
||||
{
|
||||
p = mcf5272->rx_pbuf_a[rx_remove_sof]; // First in chain
|
||||
p->tot_len = p->len; // Important since len might have changed
|
||||
}
|
||||
else
|
||||
pbuf_chain(p, mcf5272->rx_pbuf_a[rx_remove_sof]);
|
||||
/* Clear pointer to mark descriptor as free */
|
||||
mcf5272->rx_pbuf_a[rx_remove_sof] = 0;
|
||||
mcf5272->rxbd_a[rx_remove_sof].p_buf = 0;
|
||||
|
||||
if (rx_remove_sof != rx_remove_eof)
|
||||
INC_RX_BD_INDEX(rx_remove_sof);
|
||||
else
|
||||
break;
|
||||
|
||||
} while (1);
|
||||
INC_RX_BD_INDEX(rx_remove_sof);
|
||||
|
||||
/* Check error status of frame */
|
||||
if (flags & (MCF5272_FEC_RX_BD_LG |
|
||||
MCF5272_FEC_RX_BD_NO |
|
||||
MCF5272_FEC_RX_BD_CR |
|
||||
MCF5272_FEC_RX_BD_OV))
|
||||
{
|
||||
#ifdef LINK_STATS
|
||||
lwip_stats.link.drop++;
|
||||
if (flags & MCF5272_FEC_RX_BD_LG)
|
||||
lwip_stats.link.lenerr++; //Jumbo gram
|
||||
else
|
||||
if (flags & (MCF5272_FEC_RX_BD_NO | MCF5272_FEC_RX_BD_OV))
|
||||
lwip_stats.link.err++;
|
||||
else
|
||||
if (flags & MCF5272_FEC_RX_BD_CR)
|
||||
lwip_stats.link.chkerr++; // CRC errors
|
||||
#endif
|
||||
/* Drop errored frame */
|
||||
pbuf_free(p);
|
||||
} else {
|
||||
/* Good frame. increment stat */
|
||||
#ifdef LINK_STATS
|
||||
lwip_stats.link.recv++;
|
||||
#endif
|
||||
eth_input(p, mcf5272->netif);
|
||||
}
|
||||
}
|
||||
INC_RX_BD_INDEX(rx_remove_eof);
|
||||
}
|
||||
mcf5272->rx_remove = rx_remove_sof;
|
||||
|
||||
/* clear interrupt status for rx interrupt */
|
||||
old_level = sys_disable_interrupts();
|
||||
MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_EIR_RXF);
|
||||
value = MCF5272_RD_FEC_IMR(imm);
|
||||
/* Set rx interrupt bit again */
|
||||
MCF5272_WR_FEC_IMR(imm, (value | MCF5272_FEC_IMR_RXFEN));
|
||||
/* Now we can re-enable higher priority interrupts again */
|
||||
sys_restore_interrupts(old_level);
|
||||
|
||||
/* Fill up empty descriptor rings */
|
||||
fill_rx_ring(mcf5272);
|
||||
/* Tell fec that we have filled up her ring */
|
||||
MCF5272_WR_FEC_RDAR(imm, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
low_level_init(struct netif *netif)
|
||||
{
|
||||
mcf5272if_t *mcf5272;
|
||||
MCF5272_IMM *imm;
|
||||
VOID (*old_lisr)(INT); /* old LISR */
|
||||
u32_t value;
|
||||
u32_t old_level;
|
||||
struct pbuf *p;
|
||||
int i;
|
||||
|
||||
mcf5272 = netif->state;
|
||||
imm = mcf5272->imm;
|
||||
|
||||
/* Initialize our ethernet address */
|
||||
sys_get_eth_addr(mcf5272->ethaddr);
|
||||
|
||||
/* First disable fec */
|
||||
disable_fec(mcf5272);
|
||||
|
||||
/* Plug appropriate low level interrupt vectors */
|
||||
sys_setvect(MCF5272_VECTOR_ERx, mcf5272fec_rx, mcf5272_dis_rx_int);
|
||||
sys_setvect(MCF5272_VECTOR_ETx, mcf5272fec_tx_cleanup, mcf5272_dis_tx_int);
|
||||
//sys_setvect(MCF5272_VECTOR_ENTC, mcf5272fec_ntc);
|
||||
|
||||
/* Set the I_MASK register to enable only rx & tx frame interrupts */
|
||||
MCF5272_WR_FEC_IMR(imm, MCF5272_FEC_IMR_TXFEN | MCF5272_FEC_IMR_RXFEN);
|
||||
|
||||
/* Clear I_EVENT register */
|
||||
MCF5272_WR_FEC_EIR(imm,0xFFFFFFFF);
|
||||
|
||||
/* Set up the appropriate interrupt levels */
|
||||
/* Disable interrupts, since this is a read/modify/write operation */
|
||||
old_level = sys_disable_interrupts();
|
||||
value = MCF5272_RD_SIM_ICR3(imm);
|
||||
MCF5272_WR_SIM_ICR3(imm, value | MCF5272_SIM_ICR_ERX_IL(FEC_LEVEL) |
|
||||
MCF5272_SIM_ICR_ETX_IL(FEC_LEVEL));
|
||||
sys_restore_interrupts(old_level);
|
||||
|
||||
/* Set the source address for the controller */
|
||||
MCF5272_WR_FEC_MALR(imm,0
|
||||
| (mcf5272->ethaddr->addr[0] <<24)
|
||||
| (mcf5272->ethaddr->addr[1] <<16)
|
||||
| (mcf5272->ethaddr->addr[2] <<8)
|
||||
| (mcf5272->ethaddr->addr[3] <<0));
|
||||
MCF5272_WR_FEC_MAUR(imm,0
|
||||
| (mcf5272->ethaddr->addr[4] <<24)
|
||||
| (mcf5272->ethaddr->addr[5] <<16));
|
||||
|
||||
/* Initialize the hash table registers */
|
||||
/* We are not supporting multicast addresses */
|
||||
MCF5272_WR_FEC_HTUR(imm,0);
|
||||
MCF5272_WR_FEC_HTLR(imm,0);
|
||||
|
||||
/* Set Receive Buffer Size. We subtract 16 because the start of the receive
|
||||
* buffer MUST be divisible by 16, so depending on where the payload really
|
||||
* starts in the pbuf, we might be increasing the start point by up to 15 bytes.
|
||||
* See the alignment code in fill_rx_ring() */
|
||||
/* There might be an offset to the payload address and we should subtract
|
||||
* that offset */
|
||||
p = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
|
||||
i = 0;
|
||||
if (p)
|
||||
{
|
||||
struct pbuf *q = p;
|
||||
|
||||
while ((q = q->next) != 0)
|
||||
i += q->len;
|
||||
mcf5272->rx_buf_len = PBUF_POOL_BUFSIZE-16-i;
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
|
||||
MCF5272_WR_FEC_EMRBR(imm, (u16_t) mcf5272->rx_buf_len);
|
||||
|
||||
/* Point to the start of the circular Rx buffer descriptor queue */
|
||||
MCF5272_WR_FEC_ERDSR(imm, ((u32_t) &mcf5272->rxbd_a[0]));
|
||||
|
||||
/* Point to the start of the circular Tx buffer descriptor queue */
|
||||
MCF5272_WR_FEC_ETDSR(imm, ((u32_t) &mcf5272->txbd_a[0]));
|
||||
|
||||
/* Set the tranceiver interface to MII mode */
|
||||
MCF5272_WR_FEC_RCR(imm, 0
|
||||
| MCF5272_FEC_RCR_MII_MODE);
|
||||
/* | MCF5272_FEC_RCR_DRT); */ /* half duplex */
|
||||
|
||||
/* Only operate in half-duplex, no heart beat control */
|
||||
MCF5272_WR_FEC_TCR(imm, 0);
|
||||
|
||||
/* Set the maximum frame length (MTU) */
|
||||
MCF5272_WR_FEC_MFLR(imm, MTU_FEC);
|
||||
|
||||
/* Set MII bus speed */
|
||||
MCF5272_WR_FEC_MSCR(imm, 0x0a);
|
||||
|
||||
/* Enable fec i/o pins */
|
||||
value = MCF5272_RD_GPIO_PBCNT(imm);
|
||||
MCF5272_WR_GPIO_PBCNT(imm, ((value & 0x0000ffff) | 0x55550000));
|
||||
|
||||
/* Clear MII interrupt status */
|
||||
MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_IMR_MIIEN);
|
||||
|
||||
/* /\* Read phy ID *\/ */
|
||||
/* MCF5272_WR_FEC_MMFR(imm, 0x600a0000); */
|
||||
/* while (1) */
|
||||
/* { */
|
||||
/* value = MCF5272_RD_FEC_EIR(imm); */
|
||||
/* if ((value & MCF5272_FEC_IMR_MIIEN) != 0) */
|
||||
/* { */
|
||||
/* MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_IMR_MIIEN); */
|
||||
/* break; */
|
||||
/* } */
|
||||
/* } */
|
||||
/* phy = MCF5272_RD_FEC_MMFR(imm); */
|
||||
|
||||
/* Enable FEC */
|
||||
enable_fec(mcf5272);
|
||||
|
||||
/* THIS IS FOR LEVEL ONE/INTEL PHY ONLY!!! */
|
||||
/* Program Phy LED 3 to tell us transmit status */
|
||||
MCF5272_WR_FEC_MMFR(imm, 0x50520412);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*
|
||||
* etharp timer thread
|
||||
* It's only job is to initialize the timer, create a semaphore and wait on it
|
||||
* forever. We need a special task to handle the arp timer.
|
||||
*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
etharp_timer_thread(void *arg)
|
||||
{
|
||||
sys_sem_t *psem = (sys_sem_t *) arg;
|
||||
sys_sem_t sem;
|
||||
|
||||
/* Create timeout timer */
|
||||
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
|
||||
/* Signal previous task that it can go */
|
||||
sys_sem_signal(*psem);
|
||||
|
||||
sem = sys_sem_new(0);
|
||||
|
||||
while(1)
|
||||
{
|
||||
sys_sem_wait(sem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
etharp_timer_init(void *arg)
|
||||
{
|
||||
sys_thread_new((void *)etharp_timer_thread, arg);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* mcf5272fecif_init(struct netif *netif):
|
||||
*
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* network interface. It calls the function low_level_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* Note that there is only one fec in a 5272!
|
||||
*
|
||||
*/
|
||||
void
|
||||
mcf5272fecif_init(struct netif *netif)
|
||||
{
|
||||
sys_sem_t sem;
|
||||
|
||||
/* Allocate our interface control block */
|
||||
/* IMPORTANT NOTE: This works for 5272, but if you are using a cpu with data cache
|
||||
* then you need to make sure you get this memory from non-cachable memory. */
|
||||
mcf5272if = (mcf5272if_t *) calloc(1, sizeof(mcf5272if_t));
|
||||
if (mcf5272if)
|
||||
{
|
||||
netif->state = mcf5272if;
|
||||
mcf5272if->netif = netif;
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
netif->output = mcf5272fecif_output;
|
||||
netif->linkoutput = low_level_output;
|
||||
netif->mtu = MTU_FEC - 18; // mtu without ethernet header and crc
|
||||
mcf5272if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
|
||||
mcf5272if->imm = mcf5272_get_immp();
|
||||
|
||||
low_level_init(netif);
|
||||
|
||||
etharp_init();
|
||||
sem = sys_sem_new(0);
|
||||
etharp_timer_init(&sem);
|
||||
sys_sem_wait(sem);
|
||||
sys_sem_free(sem);
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
else
|
||||
Give some error message if we are out of memory
|
||||
*/
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 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. 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: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "netif/tcpdump.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/inet.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
tcpdump(struct pbuf *p)
|
||||
{
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 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. 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: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "arch/perf.h"
|
||||
|
||||
void
|
||||
perf_init(char *fname)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,574 @@
|
|||
/* @(#)sys_arch.c
|
||||
* Copyright (c) 2001-2003 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. 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: David Haas <dhaas@alum.rpi.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/debug.h"
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include "nucleus.h"
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct sys_thread {
|
||||
struct sys_thread *next;
|
||||
struct sys_timeouts timeouts;
|
||||
int errno_i;
|
||||
NU_TASK *pthread;
|
||||
void (*function)(void *arg);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
struct sys_hisr
|
||||
{
|
||||
struct sys_hisr *next;
|
||||
NU_HISR *hisr;
|
||||
void (*disablefun) (void);
|
||||
u32_t vector;
|
||||
};
|
||||
|
||||
static int num_sem = 0; // Number of semaphores created
|
||||
static int num_mbox = 0; // Number of mailboxes created
|
||||
static int num_thread = 0; // Number of threads created
|
||||
static int num_hisr = 0; // Number of hisrs created
|
||||
static sys_sem_t thread_sem; // Protect thread structure
|
||||
static struct sys_thread *threads = NULL;
|
||||
static struct sys_hisr *hisrs = NULL;
|
||||
|
||||
#define TICKS_PER_SECOND 10000
|
||||
#define MS_TO_TICKS(MS) (MS * TICKS_PER_SECOND) / 1000
|
||||
#define TICKS_TO_MS(TICKS) (1000 * TICKS) / TICKS_PER_SECOND
|
||||
|
||||
#define SYS_MBOX_SIZE 128 // Number of elements in mbox queue
|
||||
#define SYS_STACK_SIZE 2048 // A minimum Nucleus stack for coldfire
|
||||
#define SYS_HISR_STACK_SIZE 2048 // A minimum Nucleus stack for coldfire
|
||||
/* People often make a mistake on the priority of their communications task.
|
||||
The TCP/IP stack should be at a relatively low priority if it is an endpoint
|
||||
(not a router) on a somewhat underpowered CPU. You are'nt going to keep up
|
||||
with network traffic during a denial of service attack or misconfigured network
|
||||
and you don't want an overburdened network task to cause other important tasks
|
||||
(including your UI) to stop working. Drop packets! It forces flow control and
|
||||
lets the rest of your system run.
|
||||
*/
|
||||
#define SYS_THREAD_PRIORITY 220 // Relatively low priority
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_init(void)
|
||||
{
|
||||
thread_sem = sys_sem_new(1);
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void
|
||||
sys_thread_entry(UNSIGNED argc, VOID *argv)
|
||||
{
|
||||
/* argv is passed as a pointer to our thread structure */
|
||||
struct sys_thread *p_thread = (struct sys_thread *)argv;
|
||||
|
||||
p_thread->function(p_thread->arg);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static struct sys_thread *
|
||||
introduce_thread(NU_TASK *id, void (*function)(void *arg), void *arg)
|
||||
{
|
||||
struct sys_thread *thread;
|
||||
|
||||
thread = (struct sys_thread *) calloc(1,sizeof(struct sys_thread));
|
||||
|
||||
if(thread) {
|
||||
sys_arch_sem_wait(thread_sem, 0); //Wait to obtain the semaphore
|
||||
thread->next = threads;
|
||||
thread->timeouts.next = NULL;
|
||||
thread->pthread = id;
|
||||
thread->function = function;
|
||||
thread->arg = arg;
|
||||
threads = thread;
|
||||
sys_sem_signal(thread_sem); //Release semaphore
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* We use Nucleus task as thread. Create one with a standard size stack at a standard
|
||||
* priority. */
|
||||
void
|
||||
sys_thread_new(void (*function)(void *arg), void *arg)
|
||||
{
|
||||
NU_TASK *p_thread;
|
||||
u8_t *p_stack;
|
||||
STATUS status;
|
||||
char thread_name[8] = " ";
|
||||
struct sys_thread *st;
|
||||
|
||||
p_stack = (u8_t *) malloc(SYS_STACK_SIZE);
|
||||
if (p_stack)
|
||||
{
|
||||
p_thread = (NU_TASK *) calloc(1,sizeof(NU_TASK));
|
||||
if (p_thread)
|
||||
{
|
||||
/* get a new thread structure */
|
||||
st = introduce_thread(p_thread, function, arg);
|
||||
if (st)
|
||||
{
|
||||
num_thread = (num_thread +1) % 100; // Only count to 99
|
||||
sprintf(thread_name, "lwip%02d", num_thread);
|
||||
thread_name[strlen(thread_name)] = ' ';
|
||||
|
||||
status = NU_Create_Task(p_thread,
|
||||
thread_name,
|
||||
sys_thread_entry,
|
||||
0,
|
||||
st,
|
||||
p_stack,
|
||||
SYS_STACK_SIZE,
|
||||
SYS_THREAD_PRIORITY,
|
||||
0, //Disable timeslicing
|
||||
NU_PREEMPT,
|
||||
NU_START);
|
||||
if (status == NU_SUCCESS)
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static struct sys_thread *
|
||||
current_thread(void)
|
||||
{
|
||||
struct sys_thread *st;
|
||||
NU_TASK *pt;
|
||||
|
||||
pt = NU_Current_Task_Pointer();
|
||||
sys_arch_sem_wait(thread_sem, 0);
|
||||
|
||||
for(st = threads; st != NULL; st = st->next)
|
||||
{
|
||||
if(st->pthread == pt)
|
||||
{
|
||||
sys_sem_signal(thread_sem);
|
||||
|
||||
return st;
|
||||
}
|
||||
}
|
||||
|
||||
sys_sem_signal(thread_sem);
|
||||
|
||||
st = introduce_thread(pt, 0, 0);
|
||||
|
||||
if(!st) {
|
||||
abort();
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
struct sys_timeouts *
|
||||
sys_arch_timeouts(void)
|
||||
{
|
||||
struct sys_thread *thread;
|
||||
|
||||
thread = current_thread();
|
||||
return &thread->timeouts;
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
int *
|
||||
sys_arch_errno(void)
|
||||
{
|
||||
struct sys_thread *thread;
|
||||
|
||||
thread = current_thread();
|
||||
return &thread->errno_i;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
sys_sem_t
|
||||
sys_sem_new(u8_t count)
|
||||
{
|
||||
STATUS status;
|
||||
NU_SEMAPHORE *sem;
|
||||
char sem_name[8] = " ";
|
||||
|
||||
#ifdef SYS_STATS
|
||||
lwip_stats.sys.sem.used++;
|
||||
if(lwip_stats.sys.sem.used > lwip_stats.sys.sem.max)
|
||||
{
|
||||
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
|
||||
}
|
||||
#endif /* SYS_STATS */
|
||||
|
||||
/* Get memory for new semaphore */
|
||||
sem = (NU_SEMAPHORE *) calloc(1,sizeof(NU_SEMAPHORE));
|
||||
|
||||
if (sem)
|
||||
{
|
||||
/* Create a unique name for semaphore based on number created */
|
||||
num_sem = (num_sem + 1) % 100; // Only count to 99
|
||||
sprintf(sem_name, "lwip%02d", num_sem);
|
||||
sem_name[strlen(sem_name)] = ' ';
|
||||
|
||||
/* Ask nucleus to create semaphore */
|
||||
NU_Create_Semaphore(sem,
|
||||
sem_name,
|
||||
count,
|
||||
NU_FIFO);
|
||||
}
|
||||
return sem;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_sem_free(sys_sem_t sem)
|
||||
{
|
||||
if (sem != SYS_SEM_NULL)
|
||||
{
|
||||
#ifdef SYS_STATS
|
||||
lwip_stats.sys.sem.used--;
|
||||
#endif /* SYS_STATS */
|
||||
NU_Delete_Semaphore(sem);
|
||||
free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_sem_signal(sys_sem_t sem)
|
||||
{
|
||||
NU_Release_Semaphore(sem);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
u16_t
|
||||
sys_arch_sem_wait(sys_sem_t sem, u16_t timeout)
|
||||
{
|
||||
UNSIGNED timestart, timespent;
|
||||
STATUS status;
|
||||
|
||||
/* Get the current time */
|
||||
timestart = NU_Retrieve_Clock();
|
||||
/* Wait for the semaphore */
|
||||
status = NU_Obtain_Semaphore(sem,
|
||||
timeout ? MS_TO_TICKS(timeout) : NU_SUSPEND);
|
||||
/* This next statement takes wraparound into account. It works. Really! */
|
||||
timespent = TICKS_TO_MS(((s32_t) ((s32_t) NU_Retrieve_Clock() - (s32_t) timestart)));
|
||||
|
||||
if (status == NU_TIMEOUT)
|
||||
return 0;
|
||||
else
|
||||
return timespent ? (u16_t) timespent : 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
sys_mbox_t
|
||||
sys_mbox_new(void)
|
||||
{
|
||||
u32_t *p_queue_mem;
|
||||
NU_QUEUE *p_queue;
|
||||
char queue_name[8] = " ";
|
||||
|
||||
/* Allocate memory for queue */
|
||||
p_queue_mem = (u32_t *) calloc(1,(SYS_MBOX_SIZE * sizeof(u32_t)));
|
||||
if (p_queue_mem)
|
||||
{
|
||||
/* Allocate memory for queue control block */
|
||||
p_queue = (NU_QUEUE *) calloc(1,sizeof(NU_QUEUE));
|
||||
if (p_queue)
|
||||
{
|
||||
/* Create a unique name for mbox based on number created */
|
||||
num_mbox = (num_mbox + 1) % 100;
|
||||
sprintf(queue_name, "lwip%02d", num_mbox);
|
||||
queue_name[strlen(queue_name)] = ' ';
|
||||
|
||||
NU_Create_Queue(p_queue,
|
||||
queue_name,
|
||||
p_queue_mem,
|
||||
SYS_MBOX_SIZE,
|
||||
NU_FIXED_SIZE,
|
||||
1,
|
||||
NU_FIFO);
|
||||
#ifdef SYS_STATS
|
||||
lwip_stats.sys.mbox.used++;
|
||||
if(lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max) {
|
||||
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
|
||||
}
|
||||
#endif /* SYS_STATS */
|
||||
return p_queue;
|
||||
}
|
||||
else
|
||||
free(p_queue_mem);
|
||||
}
|
||||
return SYS_MBOX_NULL;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_mbox_free(sys_mbox_t mbox)
|
||||
{
|
||||
VOID *p_queue_mem;
|
||||
CHAR name[8];
|
||||
UNSIGNED queue_size;
|
||||
UNSIGNED available;
|
||||
UNSIGNED messages;
|
||||
OPTION message_type;
|
||||
UNSIGNED message_size;
|
||||
OPTION suspend_type;
|
||||
UNSIGNED tasks_waiting;
|
||||
NU_TASK *first_task;
|
||||
STATUS status;
|
||||
|
||||
if (mbox != SYS_MBOX_NULL)
|
||||
{
|
||||
/* First we need to get address of queue memory. Ask Nucleus
|
||||
for information about the queue */
|
||||
status = NU_Queue_Information(mbox,
|
||||
name,
|
||||
&p_queue_mem,
|
||||
&queue_size,
|
||||
&available,
|
||||
&messages,
|
||||
&message_type,
|
||||
&message_size,
|
||||
&suspend_type,
|
||||
&tasks_waiting,
|
||||
&first_task);
|
||||
if (status == NU_SUCCESS)
|
||||
free(p_queue_mem);
|
||||
NU_Delete_Queue(mbox);
|
||||
free(mbox);
|
||||
#ifdef SYS_STATS
|
||||
lwip_stats.sys.mbox.used--;
|
||||
#endif /* SYS_STATS */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------
|
||||
This function sends a message to a mailbox. It is unusual in that no error
|
||||
return is made. This is because the caller is responsible for ensuring that
|
||||
the mailbox queue will not fail. The caller does this by limiting the number
|
||||
of msg structures which exist for a given mailbox.
|
||||
---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_mbox_post(sys_mbox_t mbox, void *msg)
|
||||
{
|
||||
UNSIGNED status;
|
||||
|
||||
DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", mbox, msg));
|
||||
status = NU_Send_To_Queue(mbox,
|
||||
&msg,
|
||||
1,
|
||||
NU_NO_SUSPEND);
|
||||
ASSERT("sys_mbox_post: mbx post failed", status == NU_SUCCESS);
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
u16_t
|
||||
sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout)
|
||||
{
|
||||
UNSIGNED timestart, timespent;
|
||||
STATUS status;
|
||||
void *ret_msg;
|
||||
UNSIGNED actual_size;
|
||||
|
||||
/* Get the current time */
|
||||
timestart = NU_Retrieve_Clock();
|
||||
|
||||
/* Wait for message */
|
||||
status = NU_Receive_From_Queue(mbox,
|
||||
&ret_msg,
|
||||
1,
|
||||
&actual_size,
|
||||
timeout ? MS_TO_TICKS(timeout) : NU_SUSPEND);
|
||||
|
||||
if (status == NU_SUCCESS)
|
||||
{
|
||||
if (msg)
|
||||
*msg = ret_msg;
|
||||
DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", mbox, ret_msg));
|
||||
}
|
||||
|
||||
/* This next statement takes wraparound into account. It works. Really! */
|
||||
timespent = TICKS_TO_MS(((s32_t) ((s32_t) NU_Retrieve_Clock() - (s32_t) timestart)));
|
||||
|
||||
if (status == NU_TIMEOUT)
|
||||
return 0;
|
||||
else
|
||||
return timespent ? (u16_t) timespent : 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void
|
||||
sys_arch_lisr(INT vector_number)
|
||||
{
|
||||
struct sys_hisr *p_hisr = hisrs;
|
||||
|
||||
/* Determine which HISR to activate */
|
||||
while (p_hisr != NULL)
|
||||
{
|
||||
if (vector_number == p_hisr->vector)
|
||||
{
|
||||
if (p_hisr->disablefun)
|
||||
(*p_hisr->disablefun)();
|
||||
NU_Activate_HISR(p_hisr->hisr);
|
||||
break;
|
||||
}
|
||||
p_hisr = p_hisr->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_setvect(u32_t vector, void (*isr_function)(void), void (*dis_funct)(void))
|
||||
{
|
||||
/* The passed function is called as a high level ISR on the selected vector.
|
||||
It is assumed that all the functions in this module can be called by the
|
||||
isr_function.
|
||||
*/
|
||||
struct sys_hisr *p_hisr = hisrs;
|
||||
INT old_level;
|
||||
NU_HISR *nucleus_hisr;
|
||||
u8_t *p_stack;
|
||||
STATUS status;
|
||||
char hisr_name[8] = " ";
|
||||
void (*old_lisr)(INT);
|
||||
|
||||
/* In this case a Nucleus HISR is created for the isr_function. This
|
||||
* requires it's own stack. Also get memory for Nucleus HISR. */
|
||||
nucleus_hisr = (NU_HISR *) calloc(1,sizeof(NU_HISR));
|
||||
if (nucleus_hisr)
|
||||
{
|
||||
p_stack = (u8_t *) malloc(SYS_HISR_STACK_SIZE);
|
||||
if (p_stack)
|
||||
{
|
||||
|
||||
/* It is most efficient to disable interrupts for Nucleus for a short
|
||||
time. Chances are we are doing this while interrupts are disabled
|
||||
already during system initialization.
|
||||
*/
|
||||
old_level = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
|
||||
|
||||
/* It is a simplification here that once an HISR is set up for a particular
|
||||
* vector it will never be set up again. This way if the init code is called
|
||||
* more than once it is harmless (no memory leaks)
|
||||
*/
|
||||
while (p_hisr != NULL)
|
||||
{
|
||||
if (vector == p_hisr->vector)
|
||||
{
|
||||
NU_Control_Interrupts(old_level);
|
||||
free(p_stack);
|
||||
free(nucleus_hisr);
|
||||
return;
|
||||
}
|
||||
p_hisr = p_hisr->next;
|
||||
}
|
||||
|
||||
/* Get a sys_hisr structure */
|
||||
p_hisr = (struct sys_hisr *) calloc(1,sizeof(struct sys_hisr));
|
||||
if (p_hisr)
|
||||
{
|
||||
p_hisr->next = hisrs;
|
||||
p_hisr->vector = vector;
|
||||
p_hisr->hisr = nucleus_hisr;
|
||||
p_hisr->disablefun = dis_funct;
|
||||
hisrs = p_hisr;
|
||||
|
||||
NU_Control_Interrupts(old_level);
|
||||
|
||||
num_hisr = (num_hisr + 1) % 100;
|
||||
sprintf(hisr_name, "lwip%02d", num_hisr);
|
||||
hisr_name[strlen(hisr_name)] = ' ';
|
||||
|
||||
/* Ask Nucleus to create the HISR */
|
||||
status = NU_Create_HISR(p_hisr->hisr,
|
||||
hisr_name,
|
||||
isr_function,
|
||||
1, //Priority 0-2
|
||||
p_stack,
|
||||
SYS_HISR_STACK_SIZE);
|
||||
if (status == NU_SUCCESS)
|
||||
{
|
||||
/* Plug vector with system lisr now */
|
||||
NU_Register_LISR(vector, sys_arch_lisr, &old_lisr);
|
||||
return; //Success
|
||||
}
|
||||
}
|
||||
NU_Control_Interrupts(old_level);
|
||||
}
|
||||
}
|
||||
/* Errors should be logged here */
|
||||
abort();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
u32_t
|
||||
sys_disable_interrupts(void)
|
||||
{
|
||||
return NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void
|
||||
sys_restore_interrupts(u32_t old_level)
|
||||
{
|
||||
NU_Control_Interrupts(old_level);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* void sys_get_eth_addr(struct eth_addr *eth_addr)
|
||||
*
|
||||
* Get configured ethernet address from nvram and return it
|
||||
* in a eth_addr structure.
|
||||
*********************************************************************/
|
||||
void
|
||||
sys_get_eth_addr(struct eth_addr *eth_addr)
|
||||
{
|
||||
Cfg_lan *p_lan = config_get_lan_setup();
|
||||
|
||||
eth_addr->addr[0] = (u8_t) ((p_lan->etheraddrhi >> 16) & 0xff);
|
||||
eth_addr->addr[1] = (u8_t) ((p_lan->etheraddrhi >> 8) & 0xff);
|
||||
eth_addr->addr[2] = (u8_t) ((p_lan->etheraddrhi) & 0xff);
|
||||
eth_addr->addr[3] = (u8_t) ((p_lan->etheraddrlo >> 16) & 0xff);
|
||||
eth_addr->addr[4] = (u8_t) ((p_lan->etheraddrlo >> 8) & 0xff);
|
||||
eth_addr->addr[5] = (u8_t) ((p_lan->etheraddrlo) & 0xff);
|
||||
}
|
Loading…
Reference in New Issue