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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 5 页
字号:
  void *arg){  uti596_softc_ *sc = (uti596_softc_ *)arg;  struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;  struct mbuf *m;  rtems_event_set events;  for (;;) {   /*    * Wait for packet from stack    */    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,                                RTEMS_EVENT_ANY | RTEMS_WAIT,                                RTEMS_NO_TIMEOUT, &events);   /*    * Send packets till queue is empty.    * Ensure that irq is on before sending.    */    for (;;) {     /* Get the next mbuf chain to transmit. */      IF_DEQUEUE(&ifp->if_snd, m);      if (!m)        break;      send_packet (ifp, m); /* blocks */    }    ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive  */  }}/*********************************************************************** *  Function:   uti596_rxDaemon * *  Description: Receiver task * *  Algorithm: Extract the packet from an RFD, and place into an *             mbuf chain.  Place the mbuf chain in the network task *             queue. Assumes that the frame check sequence is removed *             by the 82596. * ***********************************************************************//* static */ void uti596_rxDaemon(  void *arg){  uti596_softc_ *sc = (uti596_softc_ *)arg;  struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;  struct mbuf *m;  i596_rfd *pRfd;  ISR_Level level;  int tid;  rtems_event_set events;  struct ether_header *eh;  int frames = 0;	#ifdef DBG_RX  printk(("uti596_rxDaemon: begin\n"))  printk(("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd))	#endif  rtems_task_ident (0, 0, &tid);  for(;;) {    /*     * Wait for packet.     */	#ifdef DBG_RX     printk(("uti596_rxDaemon: Receiver sleeps\n"))	#endif     rtems_bsdnet_event_receive (INTERRUPT_EVENT,                                 RTEMS_WAIT|RTEMS_EVENT_ANY,                                 RTEMS_NO_TIMEOUT,                                 &events);		 #ifdef DBG_RX     printk(("uti596_rxDaemon: Receiver wakes\n"))		 #endif     /*      * While received frames are available. Note that the frame may be      * a fragment, so it is NOT a complete packet.      */     pRfd = uti596_dequeue( (i596_rfd **)&sc->pInboundFrameQueue);     while ( pRfd &&             pRfd != I596_NULL &&             pRfd -> stat & STAT_C )     {       if ( pRfd->stat & STAT_OK) {    				/* a good frame */         int pkt_len = pRfd->count & 0x3fff;	/* the actual # of bytes received */				 #ifdef DBG_RX         printk(("uti596_rxDaemon: Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len))				 #endif         frames++;         /*          * Allocate an mbuf to give to the stack          * The format of the data portion of the RFD is:          * <ethernet header, payload>.          * The FRAME CHECK SEQUENCE / CRC is stripped by the uti596.          * This is to be optimized later.... should not have to memcopy!          */         MGETHDR(m, M_WAIT, MT_DATA);         MCLGET(m, M_WAIT);         m->m_pkthdr.rcvif = ifp;         /* move everything into an mbuf */         memcpy(m->m_data, (const char *)pRfd->data, pkt_len);         m->m_len = m->m_pkthdr.len = pkt_len - sizeof(struct ether_header) - 4;         /* move the header to an mbuf */         eh = mtod (m, struct ether_header *);         m->m_data += sizeof(struct ether_header);				 #ifdef DBG_PACKETS				 {				 	 int i;         	 printk(("uti596_rxDaemon: mbuf contains:\n"))         	 print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header)));         	 for ( i = 0; i<20; i++) { 		     	   printk(("."))	       	 }         }				 #endif       	 ether_input (ifp, eh, m);       } /* end if STAT_OK */       else {         /*          * A bad frame is present: Note that this could be the last RFD!          */				 #ifdef DBG_RX         printk(("uti596_rxDaemon: Bad frame\n"))				 #endif         /*          * FIX ME: use the statistics from the SCB          */         sc->stats.rx_errors++;         if ((sc->scb.pRfd->stat) & 0x0001)           sc->stats.collisions++;         if ((sc->scb.pRfd->stat) & 0x0080)           sc->stats.rx_length_errors++;         if ((sc->scb.pRfd->stat) & 0x0100)           sc->stats.rx_over_errors++;         if ((sc->scb.pRfd->stat) & 0x0200)           sc->stats.rx_fifo_errors++;         if ((sc->scb.pRfd->stat) & 0x0400)           sc->stats.rx_frame_errors++;         if ((sc->scb.pRfd->stat) & 0x0800)           sc->stats.rx_crc_errors++;         if ((sc->scb.pRfd->stat) & 0x1000)           sc->stats.rx_length_errors++;       }       UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n")       _ISR_Disable(level);       uti596_supplyFD ( pRfd );   /* Return RFD to RFA. */       _ISR_Enable(level);       pRfd = uti596_dequeue( (i596_rfd **)&sc->pInboundFrameQueue); /* grab next frame */     } /* end while */  } /* end for() */	#ifdef DBG_RX  printk (("uti596_rxDaemon: frames ... %d\n", frames))	#endif}/*********************************************************************** *  Function:   void uti596_resetDaemon * *  Description: ***********************************************************************/void uti596_resetDaemon(  void *arg){  uti596_softc_ *sc = (uti596_softc_ *)arg;  rtems_event_set events;  rtems_time_of_day tm_struct;  /* struct ifnet *ifp = &sc->arpcom.ac_if; */  for (;;) {   /* Wait for reset event from ISR */    rtems_bsdnet_event_receive (NIC_RESET_EVENT,                                RTEMS_EVENT_ANY | RTEMS_WAIT,                                RTEMS_NO_TIMEOUT, &events);    rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);    printk(("reset daemon: Resetting NIC @ %d:%d:%d \n",           tm_struct.hour, tm_struct.minute, tm_struct.second))    sc->stats.nic_reset_count++;    /* Reinitialize the LANC */    rtems_bsdnet_semaphore_obtain ();    uti596_reset();    rtems_bsdnet_semaphore_release ();  }}/*********************************************************************** *  Function:   uti596_DynamicInterruptHandler * *  Description: *             This is the interrupt handler for the uti596 board * ***********************************************************************//* static */ rtems_isr uti596_DynamicInterruptHandler(  rtems_vector_number irq){	#ifdef DBG_ISR  printk(("uti596_DynamicInterruptHandler: begins"))	#endif uti596_wait (&uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT); scbStatus = uti596_softc.scb.status & 0xf000; if ( scbStatus ) {   /* acknowledge interrupts */      /* Write to the ICLR bit in the PCCchip2 control registers to clear    * the INT status bit. Clearing INT here *before* sending the CA signal    * to the 82596 should ensure that interrupts won't be lost.    */    pccchip2->LANC_int_ctl |=0x08;    pccchip2->LANC_berr_ctl |=0x08;       /* printk(("***INFO: ACK %x\n", scbStatus))*/       /* Send the CA signal to acknowledge interrupt */    uti596_softc.scb.command = scbStatus;    uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );    if( uti596_softc.resetDone ) {      /* stack is attached */      uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );    }    else {      printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus))      return;    }  }  else {    printk(("\n***ERROR: Spurious interrupt. Resetting...\n"))    uti596_softc.nic_reset = 1;  }  if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ) {    printk(("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus))    uti596_softc.nic_reset = 1;    return;  }  if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {    printk(("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus))    uti596_softc.nic_reset = 1;    return;  }  if ( scbStatus & SCB_CUS_SUSPENDED ) {    printk(("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus))    uti596_softc.nic_reset = 1;    return;  }  if ( scbStatus & RU_SUSPENDED  ) {    printk(("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus))    uti596_softc.nic_reset = 1;    return;  }  if ( scbStatus & SCB_STAT_RNR ) {    printk(("\n*****WARNING: RNR %x\n",scbStatus))    if (uti596_softc.pBeginRFA != I596_NULL) {        printk(("*****INFO: RFD cmd: %x status:%x\n", uti596_softc.pBeginRFA->cmd,                                        uti596_softc.pBeginRFA->stat))    }    else {        printk(("*****WARNING: RNR condition with NULL BeginRFA\n"))    }            } /*  * Receive Unit Control  *   a frame is received  */  if ( scbStatus & SCB_STAT_FR ) {    uti596_softc.rxInterrupts++;  		#ifdef DBG_ISR    printk(("uti596_DynamicInterruptHandler: Frame received\n"))		#endif    if ( uti596_softc.pBeginRFA == I596_NULL ||       !( uti596_softc.pBeginRFA -> stat & STAT_C)) {      uti596_dump_scb();      uti596_softc.nic_reset = 1;    }    else {      while ( uti596_softc.pBeginRFA != I596_NULL &&           ( uti596_softc.pBeginRFA -> stat & STAT_C)) {				#ifdef DBG_ISR        printk(("uti596_DynamicInterruptHandler: pBeginRFA != NULL\n"))				#endif        count_rx ++;        if ( count_rx > 1) {          printk(("****WARNING: Received 2 frames on 1 interrupt \n"))                                }       /* Give Received Frame to the ULCS */        uti596_softc.countRFD--;        if ( uti596_softc.countRFD < 0 ) {          printk(("ISR: Count < 0 !!! count == %d, beginRFA = %p\n",                 uti596_softc.countRFD, uti596_softc.pBeginRFA))                                }        uti596_softc.stats.rx_packets++;        /* the rfd next link is stored with upper and lower words swapped so read it that way */        pIsrRfd = (i596_rfd *) word_swap ((unsigned long)uti596_softc.pBeginRFA->next);        /* the append destroys the link */        uti596_append( (i596_rfd **)&uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );       /*        * if we have just received the a frame in the last unknown RFD,        * then it is certain that the RFA is empty.        */        if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {          UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n")          uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;        }				#ifdef DBG_ISR        printk(("uti596_DynamicInterruptHandler: Wake %#x\n",uti596_softc.rxDaemonTid))				#endif        sc = rtems_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);        if ( sc != RTEMS_SUCCESSFUL ) {          rtems_panic("Can't notify rxDaemon: %s\n",                    rtems_status_text (sc));        }				#ifdef DBG_ISR        else {          printk(("uti596_DynamicInterruptHandler: Rx Wake: %#x\n",uti596_softc.rxDaemonTid))        }				#endif        uti596_softc.pBeginRFA = pIsrRfd;      } /* end while */    } /* end if */    if ( uti596_softc.pBeginRFA == I596_NULL ) {      /* adjust the pEndRFA to reflect an empty list */      if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 ) {        printk(("Last Unk is NULL, BeginRFA is null, and count == %d\n",               uti596_softc.countRFD))                        }      uti596_softc.pEndRFA = I596_NULL;      if ( uti596_softc.countRFD != 0 ) {        printk(("****ERROR:Count is %d, but begin ptr is NULL\n",               uti596_softc.countRFD ))      }    }  } /* end if ( scbStatus & SCB_STAT_FR ) */ /*  * Command Unit Control  *   a command is completed  */  if ( scbStatus & SCB_STAT_CX ) {		#ifdef DBG_ISR    printk(("uti596_DynamicInterruptHandler: CU\n"))		#endif    pIsrCmd = uti596_softc.pCmdHead;   /* For ALL completed commands */   if ( pIsrCmd !=  I596_NULL && pIsrCmd->status & STAT_C  ) {			 #ifdef DBG_ISR       printk(("uti596_DynamicInterruptHandler: pIsrCmd != NULL\n"))			 #endif      /* Adjust the command block list */      uti596_softc.pCmdHead = (i596_cmd *) word_swap ((unsigned long)pIsrCmd->next);     /*      * If there are MORE commands to process,      * the serialization in the raw routine has failed.      * ( Perhaps AddCmd is bad? )      */      UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL, "****ERROR: command serialization failed\n")                          /* What if the command did not complete OK? */      switch ( pIsrCmd->command & 0x7) {        case CmdConfigure:          uti596_softc.cmdOk = 1;          break;        case CmdDump:					#ifdef DBG_ISR          printk(("uti596_DynamicInterruptHandler: dump!\n"))					#endif          uti596_softc.cmdOk = 1;          break;        case CmdDiagnose:					#ifdef DBG_ISR          printk(("uti596_DynamicInterruptHandler: diagnose!\n"))					#endif          uti596_softc.cmdOk = 1;          break;        case CmdSASetup:          /* printk(("****INFO:Set address interrupt\n")) */          if ( pIsrCmd -> status & STAT_OK ) {            uti596_softc.cmdOk = 1;          }          else {            printk(("****ERROR:SET ADD FAILED\n"))                                        }          break;        case CmdTx:          UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n")					#ifdef DBG_ISR          printk(("uti596_DynamicInterruptHandler: wake TX:0x%x\n",uti596_softc.txDaemonTid))					#endif          if ( uti596_softc.txDaemonTid ) {            /* Ensure that the transmitter is present */            sc = rtems_event_send (uti596_softc.txDaemonTid,                                 INTERRUPT_EVENT);            if ( sc != RTEMS_SUCCESSFUL ) {              printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",                     uti596_softc.txDaemonTid, rtems_status_text (sc) ))            }						#ifdef DBG_ISR            else {              printk(("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid))            }						#endif          }          break;        case CmdMulticastList:          printk(("***ERROR:Multicast?!\n"))          pIsrCmd->next = I596_NULL;          break;        case CmdTDR: {                  unsigned long status = *( (unsigned long *)pIsrCmd)+1;                  printk(("****ERROR:TDR?!\n"))                  if (status & STAT_C) {                    /* mark the TDR command successful */                    uti596_softc.cmdOk = 1;                  }                  else {                    if (status & 0x4000) {                      printk(("****WARNING:Transceiver problem.\n"))                    }                    if (status & 0x2000) {                      printk(("****WARNING:Termination problem.\n"))                    }                    if (status & 0x1000) {                      printk(("****WARNING:Short circuit.\n"))                      /* printk(("****INFO:Time %

⌨️ 快捷键说明

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