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

📄 enetlib.c

📁 Ibmstb02500 miniboot 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
   | pointer to page start.   +--------------------------------------------------------------------------*/   (void)write_nic(PAR0, hwd_addr[0], PAGE1);   (void)write_nic(PAR1, hwd_addr[1], PAGE1);   (void)write_nic(PAR2, hwd_addr[2], PAGE1);   (void)write_nic(PAR3, hwd_addr[3], PAGE1);   (void)write_nic(PAR4, hwd_addr[4], PAGE1);   (void)write_nic(PAR5, hwd_addr[5], PAGE1);   (void)write_nic(MAR0, 0x00, PAGE1);   (void)write_nic(MAR1, 0x00, PAGE1);   (void)write_nic(MAR2, 0x00, PAGE1);   (void)write_nic(MAR3, 0x00, PAGE1);   (void)write_nic(MAR4, 0x00, PAGE1);   (void)write_nic(MAR5, 0x00, PAGE1);   (void)write_nic(CURR, PSTART_VALUE+ 1, PAGE1);   /*--------------------------------------------------------------------------+   | Start controller and take it out of loopback.   +--------------------------------------------------------------------------*/   (void)write_cr(STA|RD2);   (void)write_nic(TCR, LBM0, PAGE0);      /*--------------------------------------------------------------------------+   | Enable and configure the pocessor interrupts in level 1.   | Copy the IP address.   +--------------------------------------------------------------------------*/   temp = ppcMfuiccr();   ppcMtuiccr(temp & (~(0x80000000>>ENET_INT)));   temp = ppcMfuictr();   ppcMtuictr(temp & (~(0x80000000>>ENET_INT)));   temp = ppcMfuicpr();   ppcMtuicpr(temp & (0x7fffffff>>ENET_INT));   ppcMtuicsr(0x80000000>>ENET_INT);   temp = ppcMfuicer();   ppcMtuicer(temp | (0x80000000>>ENET_INT));   ip_addr=srcaddr;   (void)ppcMtmsr(msr);   return(0);}/*-----------------------------------------------------------------------------+| EnetInt.+-----------------------------------------------------------------------------*/int enetInt(){   struct ip            *ip_ptr;   struct enet_frame    *ef_ptr;   struct arp_frame     *af_p;   unsigned long        data_len;   unsigned char        isr;   while (1) {      isr=read_nic(ISR, PAGE0);      if ((isr&(PRX|OVW))==0x0) {         break;      }      if ((isr&PRX)!=0x0) {#if 0      	 // YYD, check for CURR mistake         isr=read_nic(CURR, PAGE1);         if(isr < PSTART_VALUE)   // how can this be wrong         {         	s1printf("CURR wrong %02x\n", isr);                (void)write_nic(ISR, PRX, PAGE0);         	break;         }#endif         if (inframe[flih_bufnum].inframe_len!=0) {            (void)s1printf("ENET: hold frame collision, inbound frame.\n");            inframe[flih_bufnum].inframe_len=0;         }         data_len=enet_rcv_packet(inframe[flih_bufnum].data, ENET_MAX_MTU);         if (data_len==0x0) {            continue;         }         /*--------------------------------------------------------------------+         | Clear interrupt only if there is no more packets in ring buffer.         +--------------------------------------------------------------------*/         isr=read_nic(CURR, PAGE1);         if (next_packet_ptr==isr) {            (void)write_nic(ISR, PRX, PAGE0);            ppcSync();            ppcMtuicsr(0x80000000>>ENET_INT); /* clear at uicc too */         }         ef_ptr=(struct enet_frame *)&inframe[flih_bufnum].data[2];         switch(ef_ptr->type) {            /*-----------------------------------------------------------------+            | Forward packet to OS Open if destined for that IP address.            +-----------------------------------------------------------------*/            case ENET_ARPTYPE:               af_p=(struct arp_frame *)ef_ptr->enet_data;               if ((osopen_enet.ip_addr!=0x0) && (memcmp(af_p->ar_tpa,                   &osopen_enet.ip_addr, af_p->ar_pln)==0)) {                  _callxlc((int)(*osopen_enet.recv_function),(char *)ef_ptr, data_len);               } else {                  if (af_p->ar_op==ARP_REQUEST) {                     /*--------------------------------------------------------+                     | If ARP_REQUEST is looking for us then send response.                     +--------------------------------------------------------*/                     if (memcmp(af_p->ar_tpa, ip_addr, af_p->ar_pln)==0) {                        (void)enetarp_input(af_p);                        /*-----------------------------------------------------+                        | Formulate reply, using same buffer.                        +-----------------------------------------------------*/                        (void)memcpy(af_p->ar_tha, af_p->ar_sha, af_p->ar_hln);                        (void)memcpy(af_p->ar_tpa, af_p->ar_spa, af_p->ar_pln);                        (void)memcpy(af_p->ar_sha, hwd_addr, af_p->ar_hln);                        (void)memcpy(af_p->ar_spa, ip_addr, af_p->ar_pln);                        af_p->ar_op=ARP_REPLY;                        (void)memcpy(ef_ptr->dest_addr, af_p->ar_tha,                        ENET_ADDR_LENGTH);                        if (enet_send_macframe((char *)ef_ptr, data_len)) {                           (void)s1printf("ENET: send frame error.\n");                        }                     }                  } else if (af_p->ar_op==ARP_REPLY) {                     (void)enetarp_input(af_p);                     /*--------------------------------------------------------+                     | Real arp processing here, try retransmission if a packet                     | is in the holding pen.                     +--------------------------------------------------------*/                     ef_ptr=(struct enet_frame *)outframe;                     ip_ptr=(struct ip *)ef_ptr->enet_data;                     if ((outframe_len!=0) && (memcmp(&ip_ptr->ip_dst,                         af_p->ar_spa, sizeof(ip_ptr->ip_dst))==0)) {                        (void)memcpy(ef_ptr->dest_addr, af_p->ar_sha,                        ENET_ADDR_LENGTH);                        if (enet_send_macframe((char *)outframe, outframe_len)) {                           (void)s1printf("ENET: send frame error.\n");                        } else {                           outframe_len=0;                        }                     }                  }               }               break;            /*-----------------------------------------------------------------+            | Some kind of IP packet.            +-----------------------------------------------------------------*/            case ENET_IPTYPE:               ip_ptr=(struct ip *)ef_ptr->enet_data;               if ((osopen_enet.ip_addr!=0x0) && (memcmp(&ip_ptr->ip_dst.s_addr,                   &osopen_enet.ip_addr, sizeof(ip_ptr->ip_dst.s_addr))==0)) {                  _callxlc((int)(*osopen_enet.recv_function), (char *)ef_ptr, data_len);               } else if (memcmp(&ip_ptr->ip_dst.s_addr, ip_addr,                            sizeof(ip_ptr->ip_dst.s_addr))==0 ||                         ( (*ip_addr == 0) && (memcmp(ef_ptr->dest_addr, hwd_addr,  // YYD                          ENET_ADDR_LENGTH)==0)  )) {                               // enable to get packet when ip is not set                  if ((route_packet((char *)ip_ptr, data_len,                                (int *)&ef_ptr->dest_addr)==0) &&                    (memcmp(ef_ptr->dest_addr,brd_addr, ENET_ADDR_LENGTH)!=0)) {                      inframe[flih_bufnum].inframe_len=data_len;                      flih_bufnum=(flih_bufnum+ 1)% NUMRECV_BUFF;                  }               }               break;            /*-----------------------------------------------------------------+            | Not IP or ARP discard it.            +-----------------------------------------------------------------*/            default:               break;         }      } else if ((isr&OVW)!=0x0) {         /*--------------------------------------------------------------------+         | All the packets are removed from the buffer, so reinitialize         | controller.         +--------------------------------------------------------------------*/         (void)s1printf("ENET: Receive Buffer Overflow.\n");                  (void)enetInit(ip_addr, NULL, NULL);      }   }   /* clear interrupt bit in universal interrupt controller */   ppcMtuicsr(0x80000000>>ENET_INT);   return(0);}/*-----------------------------------------------------------------------------+| EnetSend.+-----------------------------------------------------------------------------*/int enetSend(char *p,    int len, int *parmp){   struct enet_frame    *e_frame=(struct enet_frame *)outframe;   struct arp_frame     *a_frame;   unsigned char        *datap=e_frame->enet_data;   unsigned long        msr;   struct ip            *ip_ptr=(struct ip *)p;   unsigned long        target_address=ip_ptr->ip_dst.s_addr;   unsigned long        fake_length;   unsigned char        outbarp[ENET_MINPACKET];   /*--------------------------------------------------------------------------+   | Disable interrupts.   +--------------------------------------------------------------------------*/   msr=ppcAndMsr(~ppcMsrEE);   if (outframe_len!=0) {      (void)s1printf("ENET: hold frame collision, outbound frame.\n");      outframe_len=0;   }   e_frame->type=ENET_IPTYPE;   /*--------------------------------------------------------------------------+   | Destination is a broadcast address.   +--------------------------------------------------------------------------*/   if (target_address==0xFFFFFFFF) {      (void)memset(e_frame->dest_addr, 0xFF, ENET_ADDR_LENGTH);   } else {      if (enetarp_resolve(target_address, (char *)e_frame->dest_addr)==0) {         /*--------------------------------------------------------------------+         | Build arp packet and send it instead of data packet.         +--------------------------------------------------------------------*/         e_frame=(struct enet_frame *)outbarp;         (void)memset(e_frame->dest_addr, 0xFF, ENET_ADDR_LENGTH);         e_frame->type=ENET_ARPTYPE;         a_frame=(struct arp_frame *)e_frame->enet_data;         (void)memset(a_frame, 0x00, sizeof(struct arp_frame));         a_frame->ar_hrd=1;         a_frame->ar_pro=0x800;         a_frame->ar_hln=6;         a_frame->ar_pln=4;         (void)memcpy(a_frame->ar_tpa, &target_address, a_frame->ar_pln);         (void)memcpy(a_frame->ar_sha, hwd_addr, a_frame->ar_hln);         (void)memcpy(a_frame->ar_spa, ip_addr, a_frame->ar_pln);         a_frame->ar_op=ARP_REQUEST;         /*--------------------------------------------------------------------+         | Stack current frame in holding pen (-2 for XLC sizeof).         +--------------------------------------------------------------------*/         outframe_len=len+ sizeof(struct enet_frame)- 2;         (void)memcpy(datap, p, len);         if (enet_send_macframe((char *)outbarp, sizeof(outbarp))) {            (void)s1printf("ENET: send frame error.\n");         }         (void)ppcMtmsr(msr);         return(-1);      }   }   (void)memcpy(datap, p, len);   fake_length=len+ sizeof(struct enet_frame)- 2;   if (fake_length<ENET_MINPACKET) {      fake_length=ENET_MINPACKET;   }   if (enet_send_macframe((char *)outframe, fake_length)) {      (void)s1printf("ENET: send frame error.\n");      (void)ppcMtmsr(msr);      return(-1);   }   (void)ppcMtmsr(msr);   return(len+ sizeof(struct enet_frame)- 2);}/*-----------------------------------------------------------------------------+| EnetRecv.+-----------------------------------------------------------------------------*/int enetRecv(char *p, int len, int *parmp){   int                  rc;   tb_t                 tb_start;   tb_t                 tb_end;   unsigned long        msr;   (void)ppcMftb(&tb_start);   while (1) {      msr=ppcAndMsr(~ppcMsrEE);      /*-----------------------------------------------------------------------+      | Frame length is reduced by 14 (6 for dest addr, 6 for source addr, and      | 2 for frame type fields) since we only want to copy the data portion      | of the packet.      +-----------------------------------------------------------------------*/      if (inframe[read_bufnum].inframe_len<len) {         rc=inframe[read_bufnum].inframe_len - 14;      } else {         rc=len - 14;      }      /*-----------------------------------------------------------------------+      | 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -