/*
* Copyright (c) 2001-2004 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>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "netif/etharp.h"
#include "HYT_api.h"//add by smallbox at 07.03.27
//#include "MAC/inc/libemac.h"//add by smallbox at 07.03.27
//#include "LD_Eth.h"//add by smallbox at 07.09.30
#include "dm9000x.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'h'
#define IFNAME1 'e'
//add by heyunhunn at 07.03.27
#define MTU 1500
//end add
struct ethernetif {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
/* Forward declarations. */
static void ethernetif_input(struct netif *netif);
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
/*
*******************************************************************************
* low_level_init
*
*Description: 对网卡进行初始化设置
*
*Arguments : netif指向netif结构的指针,该结构储存着网卡的一些基本信息
*
*
*Returns : 无
*
*Note : MAC地址需要与RTL8019的MAC地址保持一致
*
* V1.0 by smallbox at 2007.04.03
* V1.1 Modify by smallbox at 2007.10.08 for Mac addr
*
*******************************************************************************
*/
static void low_level_init(struct netif *netif)
{
struct ethernetif *ethernetif;
ethernetif = netif->state;
netif->hwaddr_len = NETIF_MAX_HWADDR_LEN;
//设置MAC地址
netif->hwaddr[0] = MAC_ADDR_0;
netif->hwaddr[1] = MAC_ADDR_1;
netif->hwaddr[2] = MAC_ADDR_2;
netif->hwaddr[3] = MAC_ADDR_3;
netif->hwaddr[4] = MAC_ADDR_4;
netif->hwaddr[5] = MAC_ADDR_5;
netif->mtu = MTU;
netif->flags = NETIF_FLAG_BROADCAST;
HYT_DM9000X_init();
}
/*
*******************************************************************************
* low_level_output
*
*Description: TCP/IP协议包的发送
*
*Arguments : netif 指向netif结构的指针
* *p 指向的发送的数据包
*
*Returns : 无
*
*Note : 返回指向pbuf结构的指针
*
* V1.0 by smallbox at 2007.04.04
*
*******************************************************************************
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
struct ethernetif *ethernetif;
struct pbuf *q;
ethernetif= netif->state;
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE);
#endif
for(q = p; q != NULL; q = q->next) {
HYT_DM9000X_SendPacket(q->payload,q->len);
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE);
#endif
#if LINK_STATS
lwip_stats.link.xmit++;
#endif /* LINK_STATS */
return ERR_OK;
}
/*
*******************************************************************************
* low_level_input
*
*Description: 完成实际的信息包接收
*
*Arguments : netif指向netif结构的指针
*
*
*Returns : 无
*
*Note : 返回指向pbuf结构的指针
*
* V1.0 by smallbox at 2007.04.04
* V1.1 Modify by smallbox at 2007.10.16
* 优化了改函数,速度上得到一定的改善
*
*******************************************************************************
*/
static struct pbuf * low_level_input(struct netif *netif)
{
struct ethernetif *ethernetif;
struct pbuf *p = NULL, *q;
u16_t len;
int flag;
unsigned int i;
unsigned char buffer[4096];
unsigned char *des;
unsigned char *data;
data = buffer;
ethernetif = netif->state;
flag = HYT_DM9000X_RevPacket(data,&len);
#if 0
if(flag == 1) {
des = data;
LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
for(i=0; i<len; i++) {
LWIP_DEBUGF(RTL8019_DEBUG, ("0x%02X ",*des++));
}
LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
LWIP_DEBUGF(RTL8019_DEBUG, ("the receive data length is %d\r\n",len));
LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
}
#endif
if(flag == 1) {
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE;
#endif
//p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
//Modify by smallbox at 07.10.16
if(p == NULL) {
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
}
if (p != NULL) {
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE);
#endif
for(q = p; q != NULL; q = q->next) {
memcpy(q->payload,(unsigned char *)data, q->len);
data += q->len;
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE);
#endif
#if LINK_STATS
lwip_stats.link.recv++;
#endif
} else {
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif
}
}
return p;
}
/*
* ethernetif_output():
*
* 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 actual transmission of the packet.
*
*/
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
/* resolve hardware address, then send (or queue) packet */
return etharp_output(netif, ipaddr, p);
}
/*
*******************************************************************************
* LD_Ethernet_Rev
*
*Description: 创建以太网RTL8019接收任务
*
*Arguments : netif 网卡的基本信息[此时为NULL]
*
*
*Returns : 无
*
*Note : 该任务采用查询方式接收
*
* V1.0 by smallbox at 2007.10.09
*
*******************************************************************************
*/
void LD_Ethernet_Rev(void)
{
int prio;
prio = sys_thread_new(ethernetif_input,(struct netif *)netif_default, 7);
LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
LWIP_DEBUGF(RTL8019_DEBUG, ("Current ethernetif_input Priority is %d\r\n",prio));
LWIP_DEBUGF(RTL8019_DEBUG, ("\r\n"));
}
/*
*******************************************************************************
* ethernetif_input
*
*Description: 以太网卡信息包接收任务,
* 它通过调用low_level_input()函数来完成实际的信息包接收
*
*Arguments : netif 网卡的基本信息[此时为NULL]
*
*
*Returns : 无
*
*Note :
*
* V1.0 by smallbox at 2007.04.02
*
*******************************************************************************
*/
void ethernetif_input(struct netif *netif)
{
struct ethernetif *ethernetif;
struct eth_hdr *ethhdr;
struct pbuf *p;
while(1)
{
ethernetif = netif->state;
do{
p = low_level_input(netif);
if (p == NULL)
OSTimeDlyHMSM(0,0,0,100);
}while(p == NULL);
#if LINK_STATS
lwip_stats.link.recv++;
#endif
ethhdr = p->payload;
switch (htons(ethhdr->type)) {
case ETHTYPE_IP:
#if 1
etharp_ip_input(netif, p); //更新ARP表
#endif
//跳过以太网头部字段
pbuf_header(p, -sizeof(struct eth_hdr));
//传递到网络层
netif->input(p, netif);
break;
case ETHTYPE_ARP:
//将netif传递到ARP模块
p = etharp_arp_input(netif, ethernetif->ethaddr, p);
if(p != NULL) {
low_level_output(netif, p);
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
}
static void arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
/*
*******************************************************************************
* ethernetif_init
*
*Description: 通过调用low_level_init()函数完成网卡初始设置工作。
* 该函数应该在操作系统启动后设置LwIP时调用,这个系统
* 就是在SetupLwIP_Ethernet()函数中通过调用netif_add()
* 函数调用该函数完成网卡初始设置工作。
*
*Arguments : netif指向netif结构的指针,该结构储存着网卡的一些基本信息
*
*
*Returns : 如果无法申请下内存则返回ERR_MEM,成功则返回ERR_OK
*
*Note :
*
* V1.0 by smallbox at 2007.04.03
*
*******************************************************************************
*/
err_t ethernetif_init(struct netif *netif)
{
struct ethernetif *ethernetif;
ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\r\n"));
return ERR_MEM;
}
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = ethernetif_output;
netif->linkoutput = low_level_output;
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
}
/*$PAGE$*/
作者:小盒子
时间:2012.04.24
地点:大连