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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 5 页
字号:
  outport_word(CHAN_ATTN,0);    while (sc->iscp.stat)    if (--boguscnt == 0)      {	printf("initialize_hardware: timed out with status %4.4lx\n", 	       sc->iscp.stat );	break;      }    /* clear the command word */  sc->scb.command = 0;        /*   * Set up interrupts ( NEW irq style )   */  sc->irqInfo.name = UTI_596_IRQ;  sc->irqInfo.hdl  = ( void * ) uti596DynamicInterruptHandler;  sc->irqInfo.on   = uti596_maskOn;  sc->irqInfo.off  = uti596_maskOff;  sc->irqInfo.isOn = uti596_isOn;    status_code = BSP_install_rtems_irq_handler (&sc->irqInfo);  if (!status_code)    rtems_panic ("Can't attach uti596 interrupt handler for irq %d\n",		  sc->irqInfo.name);  /* Initialize the 82596 memory ( Transmit buffers ) */  uti596_initMem(sc);  #ifdef DBG_INIT  printf("After attach, status of board = 0x%x\n", sc->scb.status );#endif  outport_word(0x380, 0xf); /* reset the LED's */}voiduti596_reset_hardware(struct uti596_softc *sc){  int boguscnt = 1000;  rtems_status_code status_code;  struct i596_cmd *pCmd;   printf("uti596_reset_hardware\n");  pCmd = sc->pCmdHead;  /* This is a tx command for sure (99.99999%)  */    /* reset the board  */  outport_word( PORT_ADDR, 0 );  outport_word( PORT_ADDR, 0 );  if ( sc->pScp == NULL ) {    printf("Calloc scp\n");    uti596_softc.pScp = (struct i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);  }#ifdef DBG_RESET  printf("reset_hardware:Scp address %p\n", sc->pScp);#endif  sc->pScp = (struct i596_scp *)    ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);  #ifdef DBG_RESET  printf("reset_hardware:change scp address to : %p\n",sc->pScp);#endif    /* change the scp address */#ifdef DBG_RESET  printf("Change the SCP address\n");#endif    /*   * Set the DMA mode to enable the 82596 to become a bus-master   */  outport_byte(DMA_MASK_REG,DMA_DISABLE);      /* disable_dma */  outport_byte(DMA_MODE_REG,DMA_MODE_CASCADE); /* set dma mode */  outport_byte(DMA_MASK_REG,DMA_ENABLE);       /* enable dma */  /* reset the board  */  outport_word( PORT_ADDR, 0 );  outport_word( PORT_ADDR, 0 );    /*  outport_word(PORT_ADDR, ((((int)uti596_softc.pScp) &  0xffff) | 2 ));  outport_word(PORT_ADDR, (( (int)uti596_softc.pScp) >> 16 ) & 0xffff ); */   outport_word(PORT_ADDR, ((((int)sc->pScp) &  0xffff) | 2 ));  outport_word(PORT_ADDR, (( (int)sc->pScp) >> 16 ) & 0xffff );    /* This is linear mode, LOCK function is disabled  */    sc->pScp->sysbus = 0x00540000;  sc->pScp->iscp   = &sc->iscp;  sc->iscp.scb     = &sc->scb;  sc->iscp.stat    = 0x0001;    sc->pCmdHead     = sc->scb.pCmd = I596_NULL;  /*   * Wake the transmitter if needed.    */  if ( uti596_softc.txDaemonTid && pCmd != I596_NULL ){      printf("****RESET: wakes transmitter!\n");    status_code = rtems_event_send (uti596_softc.txDaemonTid, 			   INTERRUPT_EVENT);        if ( status_code != RTEMS_SUCCESSFUL )      printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",	     uti596_softc.txDaemonTid, rtems_status_text (status_code) );  }  #ifdef DBG_596  printf("reset_hardware: starting i82596.\n");#endif    /* Pass the scb address to the 596 */  outport_word(CHAN_ATTN,0);    while (sc->iscp.stat)    if (--boguscnt == 0)      {	printf("reset_hardware: timed out with status %4.4lx\n", 	       sc->iscp.stat );	break;      }    /* clear the command word */  sc->scb.command = 0;        #ifdef DBG_RESET  printf("After reset_hardware, status of board = 0x%x\n", sc->scb.status );#endif  outport_word(0x380, 0xf); /* reset the LED's */}/*********************************************************************** *  Function:   uti596_initMem * *  Description: *             creates the necessary descriptors for the *             uti596 board, hooks the interrupt, and starts the board. *             Assumes that interrupts are hooked. * *  Algorithm: * ***********************************************************************/ voiduti596_initMem(struct uti596_softc * sc){    int i,count;    struct i596_tbd *pTbd;    sc->resetDone = 0; /* ??? */    /*     * Set up receive frame area (RFA)      */    i = uti596_initRFA( sc->rxBdCount );    if ( i < sc->rxBdCount  )       printf("init_rfd: only able to allocate %d receive frame descriptors\n", i);        sc->scb.pRfd =  sc->pBeginRFA; #ifdef DBG_INIT    printf(" IRQ %d.\n", sc->irqInfo.name);#endif            /*     * Diagnose the health of the board     */    uti596Diagnose(1);    /*     * set up the i596 config command     */#ifdef DBG_INIT    printf("Configuring\n");#endif    sc->set_conf.cmd.command = CmdConfigure;    memcpy (sc->set_conf.data, uti596initSetup, 14);    uti596addPolledCmd( (struct i596_cmd *) &sc->set_conf);    /****    * POLL    ****/    count = 2000;    while( !( sc->set_conf.cmd.status & STAT_C ) && --count )      printf(".");    if ( count )      printf("Configure OK, count = %d\n",count);    else      printf("***Configure failed\n");    /*******/    /*      * Create the IA setup command     */#ifdef DBG_INIT    printf("Setting Address\n");#endif    sc->set_add.cmd.command = CmdSASetup;    for ( i=0; i<6; i++)      sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];    sc->cmdOk = 0;    uti596addPolledCmd((struct i596_cmd *)&sc->set_add);        /*******/        count = 2000;    while( !(sc->set_add.cmd.status & STAT_C ) && --count)      printf(".");        if ( count )      printf ("Set Address OK, count= %d\n",count);    else      printf("Set Address Failed\n");    /*******/#ifdef DBG_INIT    printf( "After initialization, status and command: 0x%x, 0x%x\n", 	    sc->scb.status, sc->scb.status);      #endif    /* initialize transmit buffer descriptors*/    sc->pLastUnkRFD = I596_NULL;    sc->pTxCmd         = (struct tx_cmd *) calloc (1,sizeof (struct tx_cmd) );    sc->pTbd           = (struct i596_tbd *) calloc (1,sizeof (struct i596_tbd) );    sc->pTxCmd -> pTbd = sc->pTbd;    sc->pTxCmd->cmd.command  = CMD_FLEX|CmdTx;    sc->pTxCmd->pad          = 0;    sc->pTxCmd->size         = 0; /* all bytes are in list of TBD's */                             pTbd = sc->pTbd;    for ( i=0; i<sc->txBdCount; i++)      pTbd = pTbd -> next = (struct i596_tbd *) calloc (1,sizeof (struct i596_tbd) );          pTbd -> next = I596_NULL;    memset ( &sc->zeroes, 0, 64);   #ifdef DBG_596    printf( "After receiver start, status and command: 0x%x, 0x%x\n", 	    sc->scb.status, sc->scb.status);#endif    printf("uti596_initMem allows ISR's\n");    sc->resetDone = 1; /* now need ISR  */}/*********************************************************************** *  Function:   uti596dump * *  Description: Dump 596 registers * *  Algorithm:  ***********************************************************************//* static */ intuti596dump(char * pDumpArea){  struct i596_dump dumpCmd;  int boguscnt = 25000000; /* over a second! */#ifdef DBG_596  printf("uti596dump:\n");#endif  dumpCmd.cmd.command = CmdDump;  dumpCmd.cmd.next    = I596_NULL;  dumpCmd.pData       = pDumpArea;  uti596_softc.cmdOk = 0;  uti596addCmd        ( (struct i596_cmd *)&dumpCmd);  while (1)    if ( --boguscnt == 0){      printf("Dump command was not processed within spin loop delay\n");      return 0;    }    else {      if ( uti596_softc.cmdOk )	return 1; /* successful completion */    }        }/*********************************************************************** *  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 */ voiduti596_rxDaemon(void *arg){  struct uti596_softc *sc = (struct uti596_softc *)arg;  struct ifnet *ifp = &sc->arpcom.ac_if;  struct mbuf *m;  struct i596_rfd *pRfd;  ISR_Level level;  int tid;  rtems_event_set events;  struct ether_header *eh;    int frames = 0;  #ifdef DBG_596  printf ("uti596_rxDaemon\n");  printf("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd);#endif      rtems_task_ident (0, 0, &tid);#ifdef DBG_596  printf("RX tid = 0x%x\n", tid);#endif        for(;;) {      /*       * Wait for packet.       */#ifdef DBG_596      printf("Receiver sleeps\n");#endif      rtems_bsdnet_event_receive (INTERRUPT_EVENT,				  RTEMS_WAIT|RTEMS_EVENT_ANY,				  RTEMS_NO_TIMEOUT,				  &events);      #ifdef DBG_596      printf("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 = uti596dequeue( &sc->pInboundFrameQueue);      while ( pRfd && 	      pRfd != I596_NULL &&	      pRfd -> stat & STAT_C )	{#ifdef DEBUG_INIT	  printf("\nReceived packet:\n");	  print_eth( pRfd->data);#endif	  if ( pRfd->stat & STAT_OK){	    /*	 a good frame. Allocate an mbuf to take it from the queue */	    int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */#ifdef DBG_596	    printf("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, 		   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_596	      printf("m->m_ext: %p pRfd -> data: %p\n",		     m->m_ext,  pRfd -> data);#endif#ifdef DEBUG_INIT_2	    printf("mbuf contains:\n");	    print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header)));	    for ( i = 0; i<20; i++)	      printf(".");#endif#ifdef DBG_VERSION	  BREAKPOINT();#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_596	    printf("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");#ifdef DBG_SUPPLY_FD 	  printf("Supply FD Starting\n");#endif	  _ISR_Disable(level);	  uti596supplyFD ( pRfd );   /* Return RFD to RFA. CAN WE REALLY?*/	  _ISR_Enable(level);#ifdef DBG_SUPPLY_FD 	  printf("Supply FD Complete\n");#endif#ifdef DBG_VERSION	  BREAKPOINT();#endif	  pRfd = uti596dequeue( &sc->pInboundFrameQueue); /* grab next frame */	  	} /* end while */    } /* end for(;;)*/    #ifdef DBG_596    printf ("frames %d\n", frames);#endif    } /***********************************************************************  *  Function:   uti596clearListStatus  *  *  Description:  *             Clear the stat fields for all rfd's  *  Algorithm:   *  ***********************************************************************/

⌨️ 快捷键说明

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