📄 ethernet.c
字号:
unsigned char bnry,curr;
char j;
page(0);
//bnry=reg03; //bnry page have read 读页指针
bnry=nic_read(NIC_PG0_BNRY);
//Uart_Printf("\n in query_8019() fuction bnry== %x\n",bnry);
page(1);
curr=nic_read(NIC_PG0_ISR); //curr writepoint 8019写页指针
//Uart_Printf("\n in query_8019() fuction curr== %x\n",curr);
page(0);
if (curr==0)return;
bnry++;
// Uart_Printf("\n in query_8019() fuction bnry+1== %x\n",bnry);
if (bnry>0x7f) bnry=0x4c;
if (bnry != curr)
{
event_word |= EVENT_ETH_ARRIVED;
// event_word=0x1ff;
// Uart_Printf("\n in query_8019() in event_word== %x\n",event_word);
}
// Uart_Printf("\n in query_8019() out event_word== %x\n",event_word);
nic_write(NIC_PG0_RBCR1, 0x00);
nic_write(NIC_PG0_RBCR0, 0x00);
nic_write(NIC_CR,NIC_CR_STA | NIC_CR_RD2);
//reg0b=0x00; reg0a=0x00; reg00=0x22;//complete dma page 0
}
//------------------------------------------------------------------------
// This functions checks 8019 status then sends an ethernet
// frame to it by calling an assembler function.
//------------------------------------------------------------------------
void send_frame(unsigned char * outbuf, unsigned short len)/*发送一个数据包的命令,长度最小为60字节,最大1514字节*/
{
unsigned char i;
unsigned short ii;
page(0);
if(len<60)len=60;
nic_write(0x00,0x22);
txd_buffer_select=!txd_buffer_select;
// Uart_Printf("\n txd_buffer_select== %x\n",txd_buffer_select);
if (txd_buffer_select)
nic_write(NIC_PG0_RSAR1, 0x40);
// reg09=0x40 ; //txdwrite highaddress
else
nic_write(NIC_PG0_RSAR1, 0x46);
// reg09=0x46 ; //txdwrite highaddress
nic_write(NIC_PG0_RSAR0, 0x00);
//reg08=0x00; //read page address low
nic_write(NIC_PG0_RBCR1, ((len >> 8) & 0xff));
// reg0b=len>>8; //read count high
nic_write(NIC_PG0_RBCR0, ((len) & 0xff));
// reg0a=len&0xff; //read count low;
nic_write(NIC_CR, 0x12);
// reg00=0x12; //write dma, page0
for (ii=0;ii<len;ii++)
{
nic_write(NIC_IOPORT, *(outbuf+ii));
// Uart_Printf("\n in ii= outuf== %d %x\n",ii,*(outbuf+ii));
// reg10=*(outbuf+ii);
}
/* 以下3句为中止dma的操作,可以不要 */
//reg0b=0x00; //read count high 中止DMA操作
nic_write(NIC_PG0_TBCR1, 0x00);
nic_write(NIC_PG0_TBCR0, 0x00);
// reg0a=0x00; //read count low;
nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
// reg00=0x22; //complete dma page 0
for(i=0;i<16;i++) //最多重发16次
{
for(ii=0;ii<1000;ii++) //检查txp为是否为低
{
if((nic_read(NIC_CR) & 0x04)==0)break;
//if ((reg00&0x04)==0) break;
}
if ((nic_read(NIC_PG0_TSR)&0x01)!=0)break;
//if ((reg04&0x01)!=0) break; //表示发送成功
nic_write(NIC_CR, 0x3e);
// reg00=0x3e;
}
nic_write(NIC_PG0_ISR,0xff);
//reg07=0xff;
if(txd_buffer_select)
nic_write(NIC_PG0_TPSR,0x40);
//reg04=0x40; //txd packet start;
else
nic_write(NIC_PG0_TPSR,0x46);
//reg04=0x46; //txd packet start;
nic_write(NIC_PG0_TBCR1,((len >> 8) & 0xff));
// reg06=len>>8; //high byte counter
nic_write(NIC_PG0_TBCR0, ((len) & 0xff));
//reg05=len&0xff; //low byte counter
nic_write(NIC_PG0_ISR,0xff);
//reg07=0xff;
nic_write(NIC_CR, 0x3e);
// reg00=0x3e; //to sendpacket;
free(outbuf);
//printf("ETH:send frame.\n");
}
//------------------------------------------------------------------------
// This function gets an incoming Ethernet frame from the 8019.
// There may be more than 1 waiting but just allocate memory for
// one and read one in. Use the 8019 to queue incoming packets.
//------------------------------------------------------------------------
unsigned char * rcve_frame(void)
{
unsigned char bnry,curr,next_page;
unsigned short len, ii;
unsigned char temp;
unsigned char * buf;
page(0);
bnry=nic_read(NIC_PG0_BNRY);
//Uart_Printf("\n in rcve_frame fuction NIC_NIC_PG0_BNRY== %x\n",bnry);
// bnry=reg03; //bnry page have read
page(1);
curr=nic_read(NIC_PG1_CURR);
//Uart_Printf("\n in rcve_frame fuction NIC_GPO_CURR== %x\n",curr);
//curr=reg07; //curr writepoint 8019
page(0);
if ((curr==0)) return NULL;
next_page=bnry;
//Uart_Printf("\n in rcve_frame Nfuction next_page== %x\n",next_page);
bnry++;
// Uart_Printf("\n in rcve_frame bnry+1 %x\n",bnry);
if (bnry>0x7f) bnry=0x4c;
if (bnry!=curr)
{
page(0);
nic_write(NIC_PG0_RSAR1,bnry);
//Uart_Printf("\n in rcve_frame NIC_PR0_RSAR1== %x\n",bnry);
//reg09=bnry; //read page address high
nic_write(NIC_PG0_RSAR0,0x00);
//reg08=0x00; //read page address low
nic_write(NIC_PG0_RBCR1,0x00);
//reg0b=0x00; //read count high
nic_write(NIC_PG0_RBCR0,0x04);
//reg0a=4; //read count low;
nic_write(NIC_CR, 0x0a);
//reg00=0x0a; //read dma
temp=nic_read(NIC_IOPORT);
// Uart_Printf("\n in one next temp== %x\n",temp);
temp=nic_read(NIC_IOPORT);
// Uart_Printf("\n in two next temp== %x\n",temp);
//temp = reg10; temp = reg10;
next_page = temp-1; //next page start-1
// Uart_Printf("\n in one next next_page-1= %x\n",next_page);
len=nic_read(NIC_IOPORT);
// Uart_Printf("\n in two len low address== %x\n",len);
temp=nic_read(NIC_IOPORT);
// Uart_Printf("\n in two len higa address== %x\n",temp);
// len = reg10; temp = reg10;
len += temp<<8;
// Uart_Printf("\n in inter len address== %x\n",len);
nic_write(NIC_PG0_RBCR1, 0x00);
nic_write(NIC_PG0_RBCR0, 0x00);
nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
// reg0b=0x00; reg0a=0x00; reg00=0x22;//complete dma page 0
// Allocate enough memory to hold the incoming frame
buf = (unsigned char *)malloc(len);
if (buf == NULL)
{
// out of RAM
// Tell 8019 to skip the frame
page(1);
curr=nic_read(NIC_PG1_CURR);
//curr=reg07; //page1
page(0);
bnry = curr -1;
if (bnry < 0x4c) bnry =0x7f;
nic_write(NIC_PG0_BNRY,bnry);
// reg03=bnry; //write to bnry
nic_write(NIC_PG0_ISR,0xff);
// reg07=0xff;
return NULL;
}
// This flag keeps track of allocated rcve memory
rcve_buf_allocated = TRUE;
// Call the assembler function to get the incoming frame
nic_write(NIC_PG0_RSAR1, bnry);
//reg09=bnry; //read page address high
nic_write(NIC_PG0_RSAR0, 0x04);
//reg08=4; //read page address low
nic_write(NIC_PG0_RBCR1, ((len >> 8) & 0xff));
nic_write(NIC_PG0_RBCR0, ((len) & 0xff));
//reg0b=len>>8; //read count high
//reg0a=len&0xff; //read count low;
nic_write(NIC_CR, 0x0a);
//reg00=0x0a; //read dma
buf=net_in_data;
// len=len-4;
for(ii=0;ii<len;ii++)
{
//buf[ii]=reg10;
buf[ii]=nic_read(NIC_IOPORT);
// Uart_Printf("\n %x ",buf[ii]);
// Uart_Printf("\n buf[ii]====== %x ",buf[ii]);
// Uart_Printf("\n ii====== %x\n ",ii);
}
nic_write(NIC_PG0_RBCR1, 0x00);
nic_write(NIC_PG0_RBCR0, 0x00);
nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
//reg0b=0x00; reg0a=0x00; reg00=0x22; //dma complete page0
// Return pointer to start of buffer
bnry=next_page;
if (bnry<0x4c) bnry=0x7f;
nic_write(NIC_PG0_BNRY,bnry);
//reg03=bnry; //write to bnry
nic_write(NIC_PG0_ISR,0xff);
// reg07=0xff;
return (buf);
// printf("ETH:read frame.\n");
}
return NULL;
}
void eth_send(unsigned char * outbuf, unsigned char * hwaddr, unsigned short ptype, unsigned short len)
{
struct ETH_HEADER * eth;
eth = (struct ETH_HEADER *)outbuf;
// Add 14 byte Ethernet header
memcpy(eth->dest_hwaddr, hwaddr, 6);
memcpy(eth->source_hwaddr, my_hwaddr, 6);
eth->frame_type = ntohs(ptype);
// We just added 14 bytes to length
// EtherOutput(outbuf, len+14);
send_frame(outbuf, len + 14);
// send_frame(outbuf,len+33);
}
//------------------------------------------------------------------------
// This is the handler for incoming Ethernet frames
// This is designed to handle standard Ethernet (RFC 893) frames
// See "TCP/IP Illustrated, Volume 1" Sect 2.2
//------------------------------------------------------------------------
void eth_rcve(unsigned char * inbuf)
{
struct ETH_HEADER * eth;
eth = (struct ETH_HEADER *)inbuf;
emtp=ntohs(eth->frame_type);
// Uart_Printf("\n in eth_rvce emtp== %x\n",emtp);
// Uart_Printf("\n in eth_rvce H==%x\n",(emtp>>8)&0xff);
// Uart_Printf("\n in eth_rvce L==%x\n",emtp&0xff);
// Reject frames in IEEE 802 format where Eth type field
// is used for length. Todo: Make it handle this format
if (emtp < 1520)
{
// Uart_Printf("\n is error data L==\n");
return;
}
// Figure out what type of frame it is from Eth header
// Call appropriate handler and supply address of buffer
switch (emtp)
{
case ARP_PACKET:
Uart_Printf("\n is ARP_PACKET ARRIVER \n");
arp_rcve(inbuf);
break;
case IP_PACKET:
// Uart_Printf("\n is IP_PACKET ARRIVER \n");
ip_rcve(inbuf);
break;
default:
// if (debug) printf("Error: Unknown pkt rcvd\n");
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -