📄 enetlib.c
字号:
(void)ppcMtmsr(msr); return(rc); } (void)ppcMtmsr(msr); (void)ppcMftb(&tb_end); if (tbmilisec_dif(&tb_end, &tb_start)>9000) { return(-1); } }}/*-----------------------------------------------------------------------------+| Write_port.+-----------------------------------------------------------------------------*/static void write_port(unsigned char value){// while(1) {// if (in8(NIC_DMA)&ACC_MASK) { (void)out8(NIC_PORT, value);// break;// }// } return;}/*-----------------------------------------------------------------------------+| Read_port.+-----------------------------------------------------------------------------*/static unsigned char read_port(){ unsigned char cr;// while(1) {// if (in8(NIC_DMA)&ACC_MASK) { cr=in8(NIC_PORT);// break;// }// } return(cr);}/*-----------------------------------------------------------------------------+| Enet_send_macframe.+-----------------------------------------------------------------------------*/int enet_send_macframe(char *frame, int frame_len){ struct enet_frame *ef_ptr=(struct enet_frame *)frame; unsigned long i; unsigned char enet_reg; tb_t tb_start; tb_t tb_end; /*--------------------------------------------------------------------------+ | Copy in our address into the frame. +--------------------------------------------------------------------------*/ (void)memcpy(ef_ptr->source_addr, hwd_addr, ENET_ADDR_LENGTH); /*--------------------------------------------------------------------------+ | If frame is too long or too short, modify length. +--------------------------------------------------------------------------*/ if (frame_len>ENET_MAX_MTU) { frame_len=ENET_MAX_MTU; } else if (frame_len<ENET_MINPACKET) { frame_len=ENET_MINPACKET; } /*--------------------------------------------------------------------------+ | Data sheet page 1-107 specifies this arcane procedute to do a remote | write (first you have to do remote read). +--------------------------------------------------------------------------*/ (void)write_nic(RBCR0, 0x10, PAGE0); (void)write_nic(RBCR1, 0x00, PAGE0); (void)write_nic(RSAR0, 0x00, PAGE0); (void)write_nic(RSAR1, (TR_STARTP*PACKET_SIZE)>>8, PAGE0); (void)write_cr(RD0); /*--------------------------------------------------------------------------+ | Set up DMA to transfer packet to the controller chip. Do not inline | write port, compiler will optimize it in such a way that machine check | will result the first time this is run. +--------------------------------------------------------------------------*/ (void)write_nic(RBCR0, frame_len&0x000000FF, PAGE0); (void)write_nic(RBCR1, (frame_len&0x0000FF00)>>8, PAGE0); (void)write_nic(RSAR0, 0x00, PAGE0); (void)write_nic(RSAR1, (TR_STARTP*PACKET_SIZE)>>8, PAGE0); (void)write_cr(RD1); for (i=0; i<frame_len; i++) { (void)write_port(frame[i]); } /*--------------------------------------------------------------------------+ | Issue transmit command. +--------------------------------------------------------------------------*/ (void)write_nic(TPSR, TR_STARTP, PAGE0); (void)write_nic(TBCR0, frame_len&0x000000FF, PAGE0); (void)write_nic(TBCR1, (frame_len&0x0000FF00)>>8, PAGE0); (void)write_nic(ISR, PTX|TXE, PAGE0); (void)write_cr(TXP); (void)ppcMftb(&tb_start); while(1) { enet_reg=read_nic(ISR, PAGE0); if ((enet_reg&PTX)!=0x0) { (void)write_nic(ISR, PTX, PAGE0); return(0); } else if ((enet_reg&TXE)!=0x0) { (void)write_nic(ISR, TXE, PAGE0); return(-1); } (void)ppcMftb(&tb_end); if (tbmilisec_dif(&tb_end, &tb_start)>3000) { return(-1); } }}/*-----------------------------------------------------------------------------+| Enet_rcv_packet.+-----------------------------------------------------------------------------*/static int enet_rcv_packet(char *inframe, int max){ unsigned char recv_status; unsigned char next_packet; unsigned char bp; unsigned long count; unsigned long dma_count; unsigned long addr; unsigned long residual; unsigned long j;#if 0 { int i, st, next, cnt, curr; s1printf("\n\nDUMP: curr = %02x\n", curr=read_nic(CURR, PAGE1)); if(curr < PSTART_VALUE) // some unknown error { rtl8019_dump(); }/* for(i=PSTART_VALUE; i<PSTOP_VALUE; i++) { (void)write_nic(RBCR0, 0x04, PAGE0); (void)write_nic(RBCR1, 0x00, PAGE0); (void)write_nic(RSAR0, 0x00, PAGE0); (void)write_nic(RSAR1, (i* PACKET_SIZE)>>8, PAGE0); (void)write_cr(RD0); st=read_port(); next=read_port(); cnt=read_port(); cnt|=read_port()<<8; s1printf("RCV: pg %02x = st %02x, next %02x, count = %d\n", i, st, next, count); }*/ }#endif /*--------------------------------------------------------------------------+ | Receive first 4 bytes giving us the receive packet statistics. +--------------------------------------------------------------------------*/ (void)write_nic(RBCR0, 0x04, PAGE0); (void)write_nic(RBCR1, 0x00, PAGE0); (void)write_nic(RSAR0, 0x00, PAGE0); (void)write_nic(RSAR1, (next_packet_ptr* PACKET_SIZE)>>8, PAGE0); (void)write_cr(RD0); recv_status=read_port(); next_packet=read_port(); count=read_port(); count|=read_port()<<8;// s1printf("RCV: pg %02x = st %02x, next %02x, count = %d (%04x)\n", next_packet_ptr, recv_status, next_packet, count, count); /*--------------------------------------------------------------------------+ | We already got 4 bytes. Set up addr where the next packet resides. Check | count if too big. +--------------------------------------------------------------------------*/ count-=4; if (count>max) { (void)s1printf("ENET: CE %d.\n", count); (void)enetInit(ip_addr, NULL, NULL); return(0); } addr=(next_packet_ptr* 256)+ 4; if ((recv_status&PRXS)==0x0) { /*-----------------------------------------------------------------------+ | We should never get bad packets. +-----------------------------------------------------------------------*/ (void)s1printf("ENET: SE.\n"); (void)enetInit(ip_addr, NULL, NULL); return(0); } /*--------------------------------------------------------------------------+ | Pull packet out of memory. If we do not hit the end boundry handle it | in one transfer. Packet is received starting at byte 3 so that the ip | packet will be word aligned and we do not have to do memmove later. +--------------------------------------------------------------------------*/ if ((addr+ count)<(PSTOP_VALUE* PACKET_SIZE)) { /*-----------------------------------------------------------------------+ | Set up DMA address and count. +-----------------------------------------------------------------------*/ (void)write_nic(RBCR0, count&0x000000FF, PAGE0); (void)write_nic(RBCR1, (count&0x0000FF00)>>8, PAGE0); (void)write_nic(RSAR0, addr&0x000000FF, PAGE0); (void)write_nic(RSAR1, (addr&0x0000FF00)>>8, PAGE0); (void)write_cr(RD0); for (j=2; j<count+ 2; j++) { inframe[j]=read_port(); } } else { /*-----------------------------------------------------------------------+ | Pull out all the bytes to the end boundry then do another transfer to | get the rest of the packet. +-----------------------------------------------------------------------*/ residual=(addr+ count)- (PSTOP_VALUE* PACKET_SIZE); dma_count=count- residual; /*-----------------------------------------------------------------------+ | Set up DMA address, and count. +-----------------------------------------------------------------------*/ (void)write_nic(RBCR0, dma_count&0x000000FF, PAGE0); (void)write_nic(RBCR1, (dma_count&0x0000FF00)>>8, PAGE0); (void)write_nic(RSAR0, addr&0x000000FF, PAGE0); (void)write_nic(RSAR1, (addr&0x0000FF00)>>8, PAGE0); (void)write_cr(RD0); inframe[210+2+14+20+8]=0x00; for (j=2; j<(dma_count+ 2); j++) { inframe[j]=read_port(); } /*-----------------------------------------------------------------------+ | Set up DMA address and count (start transfer at start page). +-----------------------------------------------------------------------*/ (void)write_nic(RBCR0, residual&0x000000FF, PAGE0); (void)write_nic(RBCR1, (residual&0x0000FF00)>>8, PAGE0); (void)write_nic(RSAR0, 0x00, PAGE0); (void)write_nic(RSAR1, (PSTART_VALUE* PACKET_SIZE)>>8, PAGE0); (void)write_cr(RD0); for (j=(dma_count+ 2); j<(dma_count+ residual+ 2); j++) { inframe[j]=read_port(); } } /*--------------------------------------------------------------------------+ | Advance boundry pointer using algorighm on page 1-56 AT/LANTIC data sheet. | If "next_packet" is outside bouns signal error. +--------------------------------------------------------------------------*/ if ((next_packet>PSTOP_VALUE) || (next_packet<PSTART_VALUE)) { (void)s1printf("ENET: NE.\n"); (void)enetInit(ip_addr, NULL, NULL); return(0); } next_packet_ptr=next_packet; bp=next_packet_ptr- 1; if (bp<PSTART_VALUE) { bp=PSTOP_VALUE- 1; } (void)write_nic(BNRY, bp, PAGE0); /*--------------------------------------------------------------------------+ | Return number of bytes read. +--------------------------------------------------------------------------*/ return(count);}/*-----------------------------------------------------------------------------+| Enet_register.+-----------------------------------------------------------------------------*/int enet_register(void (*recv_function)(char *frame, unsigned long frame_len), unsigned long ip_addr){ osopen_enet.recv_function=recv_function; osopen_enet.ip_addr=ip_addr; return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -