📄 ethernetif.i
字号:
struct stats_proto {
u16_t xmit;
u16_t rexmit;
u16_t recv;
u16_t drop;
u16_t chkerr;
u16_t lenerr;
u16_t memerr;
u16_t rterr;
u16_t proterr;
u16_t opterr;
u16_t err;
};
struct stats_mem {
mem_size_t avail;
mem_size_t used;
mem_size_t max;
mem_size_t err;
};
struct stats_pbuf {
u16_t avail;
u16_t used;
u16_t max;
u16_t err;
u16_t alloc_locked;
u16_t refresh_locked;
};
struct stats_syselem {
u16_t used;
u16_t max;
u16_t err;
};
struct stats_sys {
struct stats_syselem sem;
struct stats_syselem mbox;
};
# 115 "..\\unip\\include\\lwip\\stats.h"
struct stats_ {
struct stats_proto icmp;
struct stats_proto tcp;
struct stats_pbuf pbuf;
struct stats_mem mem;
struct stats_mem memp[MEMP_MAX];
};
extern struct stats_ lwip_stats ;
void stats_init(void);
# 65 "..\\unip\\include\\lwipopts.h" 2
# 1 "..\\unip\\include\\netif\\etharp.h" 1
struct eth_addr {
u16_t addr[3];
} __attribute__((packed)) ;
struct eth_hdr {
struct eth_addr dest __attribute__((packed)) ;
struct eth_addr src __attribute__((packed)) ;
u16_t type __attribute__((packed)) ;
} __attribute__((packed)) ;
struct etharp_hdr {
struct eth_hdr ethhdr __attribute__((packed)) ;
u16_t hwtype __attribute__((packed)) ;
u16_t proto __attribute__((packed)) ;
u16_t _hwlen_protolen __attribute__((packed)) ;
u16_t opcode __attribute__((packed)) ;
struct eth_addr shwaddr __attribute__((packed)) ;
struct ip_addr sipaddr __attribute__((packed)) ;
struct eth_addr dhwaddr __attribute__((packed)) ;
struct ip_addr dipaddr __attribute__((packed)) ;
} __attribute__((packed)) ;
struct ethip_hdr {
struct eth_hdr eth __attribute__((packed)) ;
struct ip_hdr ip __attribute__((packed)) ;
};
enum etharp_state {
ETHARP_STATE_EMPTY,
ETHARP_STATE_PENDING,
ETHARP_STATE_STABLE
};
struct etharp_entry {
struct ip_addr ipaddr;
struct eth_addr ethaddr;
enum etharp_state state;
struct pbuf *p;
u8_t ctime;
};
void etharp_init(void);
void etharp_tmr(void);
struct pbuf *etharp_ip_input(struct netif *netif, struct pbuf *p);
struct pbuf *etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
struct pbuf *p);
struct pbuf *etharp_output(struct netif *netif, struct ip_addr *ipaddr,
struct pbuf *q);
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
struct eth_addr * etharp_lookup(struct ip_addr *ipaddr);
extern struct etharp_entry arp_table [] ;
extern u16_t arp_num ;
# 68 "..\\unip\\include\\lwipopts.h" 2
# 1 "..\\unip\\include\\unsp\\include\\ethernet.h" 1
err_t ethernetif_init(struct netif *netif);
void etharp_timer(void *arg);
# 73 "..\\unip\\include\\lwipopts.h" 2
# 21 "..\\code\\include\\config.h" 2
# 42 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c" 2
# 1 "..\\unip\\include\\unsp\\spce061\\Dm9000.h" 1
# 43 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c" 2
# 1 "..\\unip\\include\\unsp\\spce061\\hardware.h" 1
# 44 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c" 2
enum DM9K_PHY_mode {
DM9K_10MHD = 0,
DM9K_100MHD = 1,
DM9K_10MFD = 4,
DM9K_100MFD = 5,
DM9K_AUTO = 8,
DM9K_DISCONN = 9
};
extern void delay(u16_t);
u16_t inb(int port)
{
int iData,i;
* ((volatile u16_t *)(0x7005 )) =0x4070;
* ((volatile u16_t *)(0x7002 )) =0x0000;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x0020|port;
* ((volatile u16_t *)(0x7002 )) =0x0000;
iData=* ((volatile u16_t *)(0x7000 )) ;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x4070|port;
* ((volatile u16_t *)(0x7002 )) =0xffff;
return(iData & 0x00ff);
}
void outb(int data,int port)
{
int i;
* ((volatile u16_t *)(0x7002 )) =0xffff;
* ((volatile u16_t *)(0x7000 )) =data;
* ((volatile u16_t *)(0x7005 )) =0x4070|port;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x0010|port;
* ((volatile u16_t *)(0x7005 )) =0x4070;
}
u16_t inw(int port)
{
int iData,i;
* ((volatile u16_t *)(0x7005 )) =0x4070;
* ((volatile u16_t *)(0x7002 )) =0x0000;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x0020|port;
iData=* ((volatile u16_t *)(0x7000 )) ;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x4070|port;
* ((volatile u16_t *)(0x7002 )) =0xffff;
return(iData);
}
void outw(int data,int port)
{
int i;
* ((volatile u16_t *)(0x7002 )) =0xffff;
* ((volatile u16_t *)(0x7000 )) =data;
* ((volatile u16_t *)(0x7005 )) =0x4070|port;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x0010|port;
* ((volatile u16_t *)(0x7005 )) =0x0070|port;
* ((volatile u16_t *)(0x7005 )) =0x4070|port;
}
void r_pack(unsigned int len,unsigned int *payload)
{
unsigned int i,j=0;
* ((volatile u16_t *)(0x7005 )) =0x4074;
* ((volatile u16_t *)(0x7002 )) =0x0000;
for(j=0;j<len;j++)
{
* ((volatile u16_t *)(0x7005 )) =0x0024;
*(payload++)=* ((volatile u16_t *)(0x7000 )) ;
* ((volatile u16_t *)(0x7005 )) =0x0034;
}
* ((volatile u16_t *)(0x7002 )) =0xffff;
}
void drop(unsigned int len)
{
unsigned int i,j=0;
* ((volatile u16_t *)(0x7005 )) =0x4070;
* ((volatile u16_t *)(0x7002 )) =0x0000;
for(j=0;j<len;j++)
{
* ((volatile u16_t *)(0x7005 )) =0x0024;
* ((volatile u16_t *)(0x7005 )) =0x0034;
}
* ((volatile u16_t *)(0x7002 )) =0xffff;
}
void s_pack(unsigned int len,unsigned int *payload)
{
unsigned int i,j=0;
* ((volatile u16_t *)(0x7005 )) =0x4070;
* ((volatile u16_t *)(0x7002 )) =0xffff;
for(j=0;j<len;j++)
{
* ((volatile u16_t *)(0x7000 )) =*(payload++);
* ((volatile u16_t *)(0x7005 )) =0x4074;
* ((volatile u16_t *)(0x7005 )) =0x0014;
* ((volatile u16_t *)(0x7005 )) =0x4074;
}
}
void delay(u16_t delay_time);
static const struct eth_addr ethbroadcast = {{0xffff,0xffff,0xffff}};
static void ethernetif_input(struct netif *netif);
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,struct ip_addr *ipaddr);
typedef struct EtherDev{
u16_t base_addr;
struct eth_addr dev_addr;
u8_t op_mode;
u8_t io_mode;
u16_t link_mode;
u16_t reset_rx_status;
u16_t rx_packets;
u16_t tx_packets;
} Dm9000_t;
static struct EtherDev * dmfe_dev = ((void *)0) ;
int dmfe_probe(struct EtherDev *);
static int dmfe_stop(struct EtherDev *);
static void dmfe_init_DM9K(struct EtherDev *);
volatile static u8_t ior(int);
static void iow(int, u8_t);
volatile static u16_t phy_read( int);
static void phy_write(int, u16_t);
static u16_t read_srom_word(int);
struct EtherDev *init_etherdev(struct EtherDev *dev, u16_t opt)
{
dev = mem_malloc(sizeof (struct EtherDev));
memset(dev,0,sizeof (struct EtherDev));
return(dev);
}
int dmfe_probe(struct EtherDev *dev)
{
u32_t id_val;
u16_t iobase = 0x000 ;
u16_t i, DM9K_found = 0 ,oft;
;
outb(0x28 , iobase);
id_val = inb(iobase + 4);
outb(0x29 , iobase);
id_val |= inb(iobase + 4) << 8;
outb(0x2A , iobase);
id_val |= (u32_t)inb(iobase + 4) << 16;
outb(0x2B , iobase);
id_val |= (u32_t)inb(iobase + 4) << 24;
if (id_val == 0x90000A46 ) {
;
DM9K_found = 1 ;
dev = init_etherdev(dev, 0);
dmfe_dev = dev;
dev->base_addr = iobase;
dev->dev_addr.addr[0]=0x6000;
dev->dev_addr.addr[1]=0x006e;
dev->dev_addr.addr[2]=0x0090;
for (i = 0, oft = 0x10; i < 6; i++, oft++)
iow(oft, getbyte( dev->dev_addr .addr, i ) );
}
return DM9K_found ? 0:-1;
}
void low_level_init(struct netif *netif)
{
struct EtherDev * dev = netif->state;
dmfe_init_DM9K(dev);
}
static void set_PHY_mode(u16_t op_mode)
{
u16_t phy_reg4 = 0x01e1, phy_reg0=0x1000;
switch(op_mode) {
case DM9K_10MHD: phy_reg4 = 0x21;
phy_reg0 = 0x0000;
break;
case DM9K_10MFD: phy_reg4 = 0x41;
phy_reg0 = 0x1100;
break;
case DM9K_100MHD: phy_reg4 = 0x81;
phy_reg0 = 0x2000;
break;
case DM9K_100MFD: phy_reg4 = 0x101;
phy_reg0 =0x3100;
break;
}
phy_write(4, phy_reg4);
phy_write(0, phy_reg0);
iow( 0x1e, 0x01);
iow( 0x1f, 0x00);
}
err_t
low_level_output(struct netif *netif, struct pbuf *skb)
{
struct EtherDev *dev = netif->state;
u16_t * data_ptr;
int i, tmplen;
struct pbuf *q;
ior(0x05);
outb(0xf8, (0x0 ) );
if (dev->io_mode == 0 ) {
for(q = skb ; q != ((void *)0) ; q = q->next) {
if ((q->len % 2) && (q->next != ((void *)0) ))
{
;
while(1);
}
data_ptr = q->payload;
tmplen = (q->len + 1) / 2;
s_pack(tmplen, data_ptr);
}
dev->tx_packets++;
iow( 0xfc, skb->tot_len & 0xff);
iow( 0xfd, (skb->tot_len >> 8) & 0xff);
iow( 0x02, 0x01);
while (!( ior( 0x01) & (4 | 8)));
return 0 ;
}
}
static void dmfe_init_DM9K(struct EtherDev *dev)
{
iow( 0, 3);
delay(100);
iow( 0, 0);
iow( 0, 3);
delay(100);
iow( 0, 0);
dev->io_mode = ior( 0xfe) >> 6;
;
delay(200);
dev->op_mode = DM9K_10MFD;
set_PHY_mode(dev->op_mode);
delay(500);
if (!(ior(0x01 ) &1<<6))
dev->link_mode = DM9K_DISCONN;
else dev->link_mode = dev->op_mode;
iow( 0x00, 0x00 );
iow( 0x02, 0);
iow( 0x08, 0x3f);
iow( 0x09, 0x38 );
iow( 0x0a, 0x00 );
iow( 0x2f, 0);
iow( 0x01, 0x2c);
iow( 0xfe, 0x0f);
iow( 0x05, 0x30 | 1);
iow( 0xff, 0x83 );
}
static int dmfe_stop(struct EtherDev *dev)
{
;
phy_write( 0x00, 0x8000);
delay(200);
iow( 0x1f, 0x01);
iow( 0xff, 0x80);
iow( 0x05, 0x00);
delay(200);
return 0;
}
struct pbuf *
low_level_input(struct netif *netif)
{
struct EtherDev *dev = netif->state;
struct pbuf *skb = ((void *)0) ;
u16_t rxbyte, *rdptr;
u16_t i, RxStatus, RxLen, GoodPacket, tmplen;
ior(0xf0);
rxbyte = inb((0x0 + 4) );
if (rxbyte == 0x01 ) {
GoodPacket = 1 ;
outb(0xf2, (0x0 ) );
if (dev->io_mode == 0 ) {
RxStatus = inw((0x0 + 4) );
RxLen = inw((0x0 + 4) );
}
if (RxLen < 0x40) {
GoodPacket = 0 ;
}
if (RxLen > 1536 ) {
;
}
if (RxStatus & 0xbf00) {
GoodPacket = 0 ;
if (RxStatus & 0x100)
;
if (RxStatus & 0x200)
;
if (RxStatus & 0x8000)
;
}
if ( GoodPacket && ((skb = pbuf_alloc(PBUF_LINK,RxLen, PBUF_POOL)) != ((void *)0) ) ) {
rdptr = skb->payload;
if (dev->io_mode == 0 ) {
tmplen = (RxLen + 1) / 2;
r_pack(tmplen, rdptr);
}
dev->rx_packets++;
return(skb);
} else {
if (skb!= ((void *)0) ) pbuf_free(skb);
tmplen = (RxLen + 1) / 2;
drop(tmplen);
return(((void *)0) );
}
}
return (((void *)0) );
}
# 605 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c"
volatile static u8_t ior(int reg)
{
outb(reg, (0x0 ) );
return inb((0x0 + 4) );
}
static void iow(int reg, u8_t value)
{
outb(reg, (0x0 ) );
outb(value, (0x0 + 4) );
}
volatile static u16_t phy_read(int reg)
{
iow(0xc, 0x40 | reg);
iow(0xb, 0xc);
delay(100);
while((ior(0x0B ) & 0x01) == 0x01);
iow( 0xb, 0x0);
return ( ior(0xe) << 8 ) | ior(0xd);
}
static void phy_write(int reg, u16_t value)
{
iow(0xc, 0x40 | reg);
iow(0xd, (value & 0xff));
iow(0xe, ( (value >> 8) & 0xff));
iow(0xb, 0xa);
delay(200);
while((ior(0x0B ) & 0x01) == 0x01);
iow(0xb, 0x0);
}
static err_t
ethernetif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
struct EtherDev *dev;
struct pbuf *q;
struct eth_hdr *ethhdr;
struct eth_addr *dest;
struct ip_addr *queryaddr;
err_t err;
u8_t i;
;
dev = netif->state;
if (pbuf_header(p, 14) != 0) {
q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM);
if (q == ((void *)0) ) {
return -1 ;
}
pbuf_chain(q, p);
p = q;
}
queryaddr = ipaddr;
if ((( ipaddr ) == ((void *)0) || ( ipaddr )->addr == 0) ||
((((( ipaddr )->addr) & ~(( &(netif->netmask) )->addr)) == (0xffffffff & ~(( &(netif->netmask) )->addr))) || (( ipaddr )->addr == 0xffffffff) || (( ipaddr )->addr == 0x00000000)) ) {
dest = (struct eth_addr *)ðbroadcast;
} else if (((( ipaddr )->addr & ntohl(0xf0000000)) == ntohl(0xe0000000)) ) {
} else {
if (((( ipaddr )->addr & ( &(netif->netmask) )->addr) == (( &(netif->ip_addr) )->addr & ( &(netif->netmask) )->addr)) ) {
queryaddr = ipaddr;
} else {
queryaddr = &(netif->gw);
}
dest = etharp_lookup(queryaddr);
}
if (dest == ((void *)0) ) {
err = etharp_query(netif, queryaddr, p);
return err;
}
ethhdr = p->payload;
for(i = 0; i < 3; i++) {
ethhdr->dest.addr[i] = dest->addr[i];
ethhdr->src.addr[i] = dev->dev_addr.addr[i];
}
ethhdr->type = htons(0x0800 );
return low_level_output(netif, p);
}
static void
ethernetif_input(struct netif *netif)
{
struct EtherDev *dev;
struct eth_hdr *ethhdr;
struct pbuf *p;
dev = netif->state;
p = low_level_input(netif);
if (p != ((void *)0) ) {
ethhdr = p->payload;
switch (htons(ethhdr->type)) {
case 0x0800 :
etharp_ip_input(netif, p);
pbuf_header(p, -14);
netif->input(p, netif);
break;
case 0x0806 :
p = etharp_arp_input(netif, &(dev->dev_addr), p);
if (p != ((void *)0) ) {
low_level_output(netif, p);
pbuf_free(p);
}
break;
default:
pbuf_free(p);
break;
}
}
}
void
etharp_timer(void *arg)
{
struct EtherDev *dev = arg;
if (!(ior(0x01 ) & 1<<6))
dev->link_mode = DM9K_DISCONN;
else dev->link_mode = dev->op_mode;
etharp_tmr();
;
}
err_t
ethernetif_init(struct netif *netif)
{
int i;
if (dmfe_probe(dmfe_dev)!=0)
{
;
return -11 ;
};
netif->state = dmfe_dev;
netif->name[0] = 'e' ;
netif->name[1] = 't' ;
netif->hwaddr_len = 3;
netif->output = ethernetif_output;
netif->linkoutput = low_level_output;
for (i = 0; i < netif->hwaddr_len; ++i) {
netif->hwaddr[i] = dmfe_dev->dev_addr.addr[i];
}
low_level_init(netif);
etharp_init();
return 0 ;
;
}
u8_t CheckNetPack(struct EtherDev *dev)
{
u16_t temp;
ior(0xF0 );
switch(ior(0xF0 ))
{
case 0x00 :
{
return(0);
}
case 0x01 : return(1);
default :
temp = ior(0xF4) + ior(0xF5)*256;
;
dev->reset_rx_status++;
dmfe_stop(dev);
delay(200);
dmfe_init_DM9K(dev);
return(0);
}
}
void Ethernet_poll(struct netif *netif)
{
if (((struct EtherDev *)(netif->state))->link_mode == DM9K_DISCONN)
{
;
return;
}
if(CheckNetPack((struct EtherDev *)(netif->state)))
ethernetif_input(netif);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -