Browse Source

re-implemented ethernetif and power-on flow of lwip1.4, note: ethnet driver and init invokings also need to be modified.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1652 bbd45198-f89e-11dd-88c7-29a3b14d5316
mbbill@gmail.com 13 years ago
parent
commit
b2726da244

+ 0 - 1
components/net/lwip-1.4.0/SConscript

@@ -11,7 +11,6 @@ src/api/netifapi.c
 src/api/sockets.c
 src/api/tcpip.c
 src/arch/sys_arch.c
-src/arch/sys_arch_init.c
 src/core/def.c
 src/core/dhcp.c
 src/core/dns.c

+ 0 - 35
components/net/lwip-1.4.0/src/arch/include/arch/bpstruct.h

@@ -1,35 +0,0 @@
-/*
- * 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>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack(1)
-#endif

+ 1 - 1
components/net/lwip-1.4.0/src/arch/include/arch/cc.h

@@ -90,7 +90,7 @@ typedef rt_uint32_t	mem_ptr_t;
 
 void sys_arch_assert(const char* file, int line);
 #define LWIP_PLATFORM_DIAG(x)	do {rt_kprintf x;} while(0)
-#define LWIP_PLATFORM_ASSERT(x) { rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__); }
+#define LWIP_PLATFORM_ASSERT(x) do {rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__);}while(0)
 
 
 #include "string.h"

+ 0 - 42
components/net/lwip-1.4.0/src/arch/include/arch/cpu.h

@@ -1,42 +0,0 @@
-/*
- * 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: cpu.h,v 1.1.1.1 2004/12/16 14:17:14 bear Exp $
- */
-#ifndef __ARCH_CPU_H__
-#define __ARCH_CPU_H__
-
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif /* BYTE_ORDER */
-
-#endif /* __ARCH_CPU_H__ */

+ 0 - 35
components/net/lwip-1.4.0/src/arch/include/arch/epstruct.h

@@ -1,35 +0,0 @@
-/*
- * 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>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack()
-#endif

+ 0 - 44
components/net/lwip-1.4.0/src/arch/include/arch/init.h

@@ -1,44 +0,0 @@
-/*
- * 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: init.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
- */
-#ifndef __ARCH_INIT_H__
-#define __ARCH_INIT_H__
-
-#define TCPIP_INIT_DONE(arg) sys_sem_signal(*(sys_sem_t *)arg)
-
-#endif /* __ARCH_INIT_H__ */
-
-
-
-

+ 0 - 41
components/net/lwip-1.4.0/src/arch/include/arch/lib.h

@@ -1,41 +0,0 @@
-/*
- * 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.1.1 2004/12/16 14:17:14 bear Exp $
- */
-#ifndef __ARCH_LIB_H__
-#define __ARCH_LIB_H__
-
-#define bcopy(s, d, l) rt_memcpy(s, d, l)
-#define bzero(d, n) rt_memset(d, 0, n)
-
-#endif /* __ARCH_LIB_H__ */

+ 4 - 1
components/net/lwip-1.4.0/src/arch/include/arch/sys_arch.h

@@ -35,11 +35,14 @@
 #ifndef __ARCH_SYS_ARCH_H__
 #define __ARCH_SYS_ARCH_H__
 
-#include "arch/cpu.h"
 #include "arch/cc.h"
 
 #include <rtthread.h>
 
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
 #define SYS_MBOX_NULL RT_NULL
 #define SYS_SEM_NULL  RT_NULL
 

+ 0 - 6
components/net/lwip-1.4.0/src/arch/include/arch/sys_arch_init.h

@@ -1,6 +0,0 @@
-#ifndef __LWIP_SYS_INIT_H__
-#define __LWIP_SYS_INIT_H__
-
-void lwip_sys_init();
-
-#endif

+ 0 - 68
components/net/lwip-1.4.0/src/arch/sys_arch_init.c

@@ -1,68 +0,0 @@
-#include <rtthread.h>
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-#endif
-
-#include "lwip/debug.h"
-#include "lwip/mem.h"
-#include "lwip/sys.h"
-#include "lwip/stats.h"
-#include "lwip/tcpip.h"
-#include "lwip/ip_addr.h"
-#include "lwip/dhcp.h"
-
-#include "netif/ethernetif.h"
-#include "netif/etharp.h"
-
-/*
- * lwip system initial entry
- */
-void lwip_sys_init()
-{
-	struct ip_addr ipaddr, netmask, gw;
-
-#if LWIP_DHCP
-	rt_uint32_t mscnt = 0;
-
-	IP4_ADDR(&gw, 0,0,0,0);
-	IP4_ADDR(&ipaddr, 0,0,0,0);
-	IP4_ADDR(&netmask, 0,0,0,0);
-#else
-	IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3);
-	IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3);
-	IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3);
-#endif
-
-  	tcpip_init(RT_NULL, RT_NULL);
-
-	netif_set_addr(netif_default, &ipaddr, &netmask, &gw);
-	netif_set_up(netif_default);
-
-#if LWIP_DHCP
-	/* use DHCP client */
-	dhcp_start(netif_default);
-
-    while (netif_default->ip_addr.addr == 0)
-	{
-        rt_thread_delay(DHCP_FINE_TIMER_MSECS * RT_TICK_PER_SECOND / 1000);
-
-        dhcp_fine_tmr();
-        mscnt += DHCP_FINE_TIMER_MSECS;
-        if (mscnt >= DHCP_COARSE_TIMER_SECS*1000)
-        {
-            dhcp_coarse_tmr();
-            mscnt = 0;
-        }
-    }
-	
-	rt_kprintf("Acquired IP address from DHCP server:");
-	rt_kprintf("%d.%d.%d.%d\n", netif_default->ip_addr.addr & 0xff,
-		(netif_default->ip_addr.addr>>8) & 0xff,
-		(netif_default->ip_addr.addr>>16) & 0xff, 
-		(netif_default->ip_addr.addr>>24) & 0xff);
-#endif
-
-#if defined(RT_USING_FINSH) && (LWIP_STATS_DISPLAY)
-    finsh_syscall_append("lwip_info", (syscall_func)stats_display);
-#endif
-}

+ 3 - 6
components/net/lwip-1.4.0/src/include/netif/ethernetif.h

@@ -7,24 +7,21 @@
 #define NIOCTL_GADDR		0x01
 #define ETHERNET_MTU		1500
 
+
 struct eth_device
 {
 	/* inherit from rt_device */
 	struct rt_device parent;
 
-	struct eth_addr *ethaddr;
 	struct netif *netif;
-	struct rt_semaphore tx_ack;
 
 	/* eth device interface */
 	struct pbuf* (*eth_rx)(rt_device_t dev);
+
 	rt_err_t (*eth_tx)(rt_device_t dev, struct pbuf* p);
 };
 
-rt_err_t eth_device_ready(struct eth_device* dev);
-
-rt_err_t eth_device_init(struct eth_device* dev, const char* name);
+rt_err_t eth_rx_ready(struct eth_device *dev);
 
-rt_err_t eth_system_device_init(void);
 
 #endif /* __NETIF_ETHERNETIF_H__ */

+ 137 - 193
components/net/lwip-1.4.0/src/netif/ethernetif.c

@@ -46,8 +46,8 @@
 
 #include <rtthread.h>
 
-#include "lwip/debug.h"
 #include "lwip/opt.h"
+#include "lwip/debug.h"
 #include "lwip/def.h"
 #include "lwip/mem.h"
 #include "lwip/pbuf.h"
@@ -59,190 +59,30 @@
 #include "netif/etharp.h"
 #include "netif/ethernetif.h"
 
-/* eth rx/tx thread */
-static struct rt_mailbox eth_rx_thread_mb;
-static struct rt_thread eth_rx_thread;
+/* configurations */
 #ifndef RT_LWIP_ETHTHREAD_PRIORITY
-#define RT_ETHERNETIF_THREAD_PREORITY	0x90
-static char eth_rx_thread_mb_pool[48 * 4];
-static char eth_rx_thread_stack[1024];
-#else
-#define RT_ETHERNETIF_THREAD_PREORITY	RT_LWIP_ETHTHREAD_PRIORITY
-static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
-static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
+#define RT_LWIP_ETHTHREAD_PRIORITY 0x90
 #endif
 
-struct eth_tx_msg
-{
-	struct netif 	*netif;
-	struct pbuf 	*buf;
-};
-static struct rt_mailbox eth_tx_thread_mb;
-static struct rt_thread eth_tx_thread;
-#ifndef RT_LWIP_ETHTHREAD_PRIORITY
-static char eth_tx_thread_mb_pool[32 * 4];
-static char eth_tx_thread_stack[512];
-#else
-static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
-static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
+#ifndef RT_LWIP_ETHTHREAD_MBOX_SIZE
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE 48
 #endif
 
-/* ================================================================================== */
-
-static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
-{
-	struct eth_tx_msg msg;
-	struct eth_device* enetif;
-
-	RT_DEBUG_NOT_IN_INTERRUPT;
-
-	enetif = (struct eth_device*)netif->state;
-
-	/* send a message to eth tx thread */
-	msg.netif = netif;
-	msg.buf   = p;
-	if (rt_mb_send(&eth_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK)
-	{
-		/* waiting for ack */
-		rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER);
-	}
-
-	return ERR_OK;
-}
-
-
-/* Since "ethernetif_init" is called back from netif_add() and we are
-   unable to get the pointer to the dev which owns this netif, this
-   global var is used to solve this problem. */
-static struct eth_device* eth_dev;
-/* the interface provided to LwIP */
-static err_t ethernetif_init(struct netif *netif)
-{
-
-	RT_DEBUG_NOT_IN_INTERRUPT;
-
-	if( (eth_dev == RT_NULL) || (eth_dev->netif != netif) )
-		return ERR_MEM;
-
-	/* set name */
-	netif->name[0] = eth_dev->parent.parent.name[0];
-	netif->name[1] = eth_dev->parent.parent.name[1];
-
-	/* set hw address to 6 */
-	netif->hwaddr_len	= 6;
-	/* maximum transfer unit */
-	netif->mtu			= ETHERNET_MTU;
-
-	/* NOTE: the NETIF_FLAG_UP and NETIF_FLAG_LINK_UP flag is not set here.
-	They should be set by netif_set_up() and netif_set_link_up() automatically */
-	netif->flags		= NETIF_FLAG_BROADCAST |
-						NETIF_FLAG_ETHARP;
-#ifdef LWIP_IGMP
-	netif->flags |= NETIF_FLAG_IGMP;
+#ifndef RT_LWIP_ETHTHREAD_STACKSIZE
+#define RT_LWIP_ETHTHREAD_STACKSIZE 1024
 #endif
 
-#ifdef LWIP_DHCP
-	netif->flags |= NETIF_FLAG_DHCP;
-#endif
 
-	/* get hardware address */
-	rt_device_control(&(eth_dev->parent), NIOCTL_GADDR, netif->hwaddr);
-
-	/* set output */
-	netif->output		= etharp_output;
-	netif->linkoutput	= ethernetif_linkoutput;
-	
-	return ERR_OK;
-}
-
-
-/* ethernetif APIs */
-/* WARNING: because netif_set_up() is not re-entrance ( it will pending on sem/mbox )
- * you MUST NOT call it before scheduler starts.
- */
-rt_err_t eth_device_init(struct eth_device* dev, const char* name)
-{
-	struct netif* pnetif;
-
-	RT_DEBUG_NOT_IN_INTERRUPT;
-
-	/* allocate memory */
-	pnetif = (struct netif*) rt_malloc (sizeof(struct netif));
-	if (pnetif == RT_NULL)
-	{
-		rt_kprintf("malloc netif failed\n");
-		return -RT_ERROR;
-	}
-	rt_memset(pnetif, 0, sizeof(struct netif));
-
-
-	/* set netif */
-	dev->netif = pnetif;
-	/* register to rt-thread device manager */
-	rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
-	dev->parent.type = RT_Device_Class_NetIf;
-	rt_sem_init(&(dev->tx_ack), name, 0, RT_IPC_FLAG_FIFO);
-
-
-	/* add netif to lwip */
-	/* NOTE: eth_init will be called back by netif_add, we should put some initialization
-	         code to eth_init(). See include/lwip/netif.h line 97 */
-	eth_dev = dev;
-	if (netif_add(pnetif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
-		ethernetif_init, tcpip_input) == RT_NULL)
-	{
-		/* failed, unregister device and free netif */
-		rt_device_unregister(&(dev->parent));
-		rt_free(pnetif);
-		eth_dev = RT_NULL;
-		return -RT_ERROR;
-	}
-	eth_dev = RT_NULL;
-
-	netif_set_default(pnetif);
-
-	/* We bring up the netif here cause we still don't have a call back function
-	which indicates the ethernet interface status from the ethernet driver. */
-	netif_set_up(pnetif);
-	netif_set_link_up(pnetif);
-
-	return RT_EOK;
-}
-
-
-/* ================================================================================== */
-/* NOTE: Previous functions are interface for lwip, and below are for rt-thread */
-void eth_tx_thread_entry(void* parameter)
-{
-	struct eth_tx_msg* msg;
-
-	while (1)
-	{
-		if (rt_mb_recv(&eth_tx_thread_mb, (rt_uint32_t*)&msg, RT_WAITING_FOREVER) == RT_EOK)
- 		{
-			struct eth_device* enetif;
-
-			RT_ASSERT(msg->netif != RT_NULL);
-			RT_ASSERT(msg->buf   != RT_NULL);
+/* eth rx thread */
+static struct rt_mailbox eth_rx_thread_mb;
+static struct rt_thread eth_rx_thread;
 
-			enetif = (struct eth_device*)msg->netif->state;
-			if (enetif != RT_NULL)
-			{
-				/* call driver's interface */
-				if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK)
-				{
-					rt_kprintf("transmit eth packet failed\n");
-				}
-			}
+static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
 
-			/* send ack */
-			rt_sem_release(&(enetif->tx_ack));
-		}
-	}
-}
 
 /* ethernet buffer */
-void eth_rx_thread_entry(void* parameter)
+static void eth_rx_thread_entry(void* parameter)
 {
 	struct eth_device* device;
 
@@ -269,21 +109,32 @@ void eth_rx_thread_entry(void* parameter)
 				else break;
 			}
 		}
+		else
+		{
+			LWIP_ASSERT("Should not happen!\n",0);
+		}
 	}
 }
 
-rt_err_t eth_device_ready(struct eth_device* dev)
+
+
+static err_t enetif_linkoutput(struct netif *pnetif, struct pbuf *p)
 {
-	/* post message to ethernet thread */
-	return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+	struct eth_device *dev;
+
+	dev = (struct eth_device *)(pnetif->state);
+	return dev->eth_tx(&(dev->parent), p);
 }
 
-rt_err_t eth_system_device_init()
+
+static err_t enetif_init(struct netif *pnetif)
 {
 	rt_err_t result = RT_EOK;
+	struct eth_device *dev;
+	rt_uint32_t level;
 
-	/* init rx thread */
-	/* init mailbox and create ethernet thread */
+	/* init rx thread.
+	 * init mailbox and create ethernet thread */
 	result = rt_mb_init(&eth_rx_thread_mb, "erxmb",
 		&eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4,
 		RT_IPC_FLAG_FIFO);
@@ -291,30 +142,122 @@ rt_err_t eth_system_device_init()
 
 	result = rt_thread_init(&eth_rx_thread, "erx", eth_rx_thread_entry, RT_NULL,
 		&eth_rx_thread_stack[0], sizeof(eth_rx_thread_stack),
-		RT_ETHERNETIF_THREAD_PREORITY, 16);
+		RT_LWIP_ETHTHREAD_PRIORITY, 16);
 	RT_ASSERT(result == RT_EOK);
 
 	result = rt_thread_startup(&eth_rx_thread);
 	RT_ASSERT(result == RT_EOK);
 
-	/* init tx thread */
-	/* init mailbox and create ethernet thread */
-	result = rt_mb_init(&eth_tx_thread_mb, "etxmb",
-		&eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4,
-		RT_IPC_FLAG_FIFO);
-	RT_ASSERT(result == RT_EOK);
 
-	result = rt_thread_init(&eth_tx_thread, "etx", eth_tx_thread_entry, RT_NULL,
-		&eth_tx_thread_stack[0], sizeof(eth_tx_thread_stack),
-		RT_ETHERNETIF_THREAD_PREORITY, 16);
-	RT_ASSERT(result == RT_EOK);
+	dev = (struct eth_device *)(pnetif->state);
 
-	result = rt_thread_startup(&eth_tx_thread);
-	RT_ASSERT(result == RT_EOK);
+	pnetif->name[0] = dev->parent.parent.name[0];
+	pnetif->name[1] = dev->parent.parent.name[1];
+
+	pnetif->hwaddr_len	= 6;
+	pnetif->mtu			= ETHERNET_MTU;
+	pnetif->flags		= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+
+#ifdef LWIP_IGMP
+	pnetif->flags |= NETIF_FLAG_IGMP;
+#endif
+
+#ifdef LWIP_DHCP
+	pnetif->flags |= NETIF_FLAG_DHCP;
+#endif
+
+	/* get hardware address */
+	rt_device_control(&(dev->parent), NIOCTL_GADDR, pnetif->hwaddr);
+
+	/* set output */
+	pnetif->output		= etharp_output;
+	pnetif->linkoutput	= enetif_linkoutput;
+
+	/* finally, we connect netif and device together.
+	 * We initialized eth_device first, but ethernetif is still not ready.
+	 * Although we checked if dev->netif is null but we still must avoid
+	 * concurrency problem here.*/
+	level = rt_hw_interrupt_disable();
+	dev->netif = pnetif;
+	rt_hw_interrupt_enable(level);
 
-	return result;
+	return ERR_OK;
+}
+
+rt_err_t eth_rx_ready(struct eth_device* dev)
+{
+	if (dev->netif)
+		/* post message to ethernet thread */
+		return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+	else
+		return ERR_OK; /* netif is not initialized yet, just return. */
 }
 
+/* Functions below shouldn't be here because they are application or usage related.
+ * I just give an example of a right power-on procedure here. */
+static struct netif ethernetif;
+extern struct eth_device * get_eth_dev(void);
+
+/* This function is called-back in tcpip thread, so we don't need to use msg api
+ * to call those netif_xxx functions. But if we use these anywhere else, we must
+ * use msg api to avoid concurrent problem.
+ */
+static void tcpip_init_done_callback(void *arg)
+{
+	ip_addr_t ipaddr, netmask, gw;
+
+	LWIP_ASSERT("invalid arg.\n",arg);
+
+#if LWIP_DHCP
+	IP4_ADDR(&gw, 0,0,0,0);
+	IP4_ADDR(&ipaddr, 0,0,0,0);
+	IP4_ADDR(&netmask, 0,0,0,0);
+#else
+	IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3);
+	IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3);
+	IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3);
+#endif
+
+	netif_add(&ethernetif, &ipaddr, &netmask, &gw, 
+		get_eth_dev(), enetif_init, tcpip_input);
+
+	netif_set_default(&ethernetif);
+
+#if LWIP_DHCP
+	dhcp_start(&ethernetif);
+#else
+	netif_set_up(&ethernetif);
+#endif
+
+	netif_set_link_up(&ethernetif);
+	
+	sys_sem_signal((sys_sem_t*)(&arg));
+}
+
+
+/* Make sure the 'dev' has already been initialized before calling this function.
+ * This function will initialize the lwip tcpip stack as well as the ethernetif.
+ * It will assign the dev->netif and netif->state field to make a connection between
+ * eth driver and ethnetif.
+ */
+void lwip_enetif_init(void)
+{
+	sys_sem_t init_done_sem;
+
+	if(sys_sem_new(&init_done_sem, 0) != ERR_OK)
+	{
+    	LWIP_ASSERT("Failed to create semaphore", 0);
+		return;
+	}
+	tcpip_init(tcpip_init_done_callback,(void *)init_done_sem);
+
+	sys_sem_wait(&init_done_sem);
+	rt_kprintf("TCP/IP initialized.\n");
+
+	sys_sem_free(&init_done_sem);
+}
+
+#if 0
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 #include "ipv4/lwip/inet.h"
@@ -377,3 +320,4 @@ void list_if()
 }
 FINSH_FUNCTION_EXPORT(list_if, list network interface information);
 #endif
+#endif