⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enetlib.c

📁 Ibmstb02500 miniboot 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
      }      /*-----------------------------------------------------------------------+      | Frame data starts at byte 16 (2 for aligment 12 for addresses 2 for      | frame type).      +-----------------------------------------------------------------------*/      if (rc>0) {         (void)memcpy(p, &inframe[read_bufnum].data[16], rc);         inframe[read_bufnum].inframe_len=0;         read_bufnum=(read_bufnum+ 1)% NUMRECV_BUFF;         (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, 0x00, 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, 0x00, PAGE0);   (void)write_cr(RD1);   for (i=0; i<frame_len; i++) {      (void)write_port(frame[i]);   }   /*--------------------------------------------------------------------------+   | Issue transmit command.   +--------------------------------------------------------------------------*/   (void)write_nic(TPSR, 0x00, 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;   /*--------------------------------------------------------------------------+   | 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* 256)>>8, PAGE0);   (void)write_cr(RD0);   recv_status=read_port();   next_packet=read_port();   count=read_port();   count|=read_port()<<8;   /*--------------------------------------------------------------------------+   | 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.\n");      (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* 256)>>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 + -