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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 5 页
字号:
{  int i;  #ifdef DBG_INIT  printk(("uti596_initMem: begins\n"))  #endif  sc->resetDone = 0;  /*   * Set up receive frame area (RFA)   */  i = uti596_initRFA( sc->rxBdCount );  if ( i < sc->rxBdCount ) {    printk(("init_rfd: only able to allocate %d receive frame descriptors\n", i))  }                  /*   * Write the SCB with a pointer to the receive frame area   * and keep a pointer for our use.   */  sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA);  sc->scb.pRfd =  sc->pBeginRFA;  /*   * Diagnose the health of the board   */  uti596_diagnose();  /*   * Configure the 82596   */  uti596_configure( sc );  /*   * Set up the Individual (hardware) Address   */  uti596_IAsetup ( sc );	/*	 * Initialize the transmit buffer descriptors	 */  uti596_initTBD( sc );  /* Padding used to fill short tx frames */  memset ( &sc->zeroes, 0, 64);  /* now need ISR  */  sc->resetDone = 1;}/* *  uti596_initialize * *  Reset the 82596 and initialize it with a new SCP. *   *  Input parameters: *    sc - pointer to the uti596_softc * *  Output parameters: NONE * *  Return value: NONE */void uti596_initialize(  uti596_softc_ *sc){  /* Reset the device. Stops it from doing whatever it might be doing.  */  uti596_portReset();  /* Get a new System Configuration Pointer */  uti596_scp_alloc( sc );  /* write the SYSBUS: interrupt pin active high, LOCK disabled,   * internal triggering, linear mode   */  sc->pScp->sysbus = 0x54;    /* provide the iscp to the scp, keep a pointer for our use */  sc->pScp->iscp_pointer = word_swap((unsigned long)&sc->iscp);  sc->pScp->iscp = &sc->iscp;  /* provide the scb to the iscp, keep a pointer for our use */  sc->iscp.scb_pointer = word_swap((unsigned long)&sc->scb);  sc->iscp.scb = &sc->scb;  #ifdef DBG_INIT  printk(("uti596_initialize: Starting i82596.\n"))  #endif  /* Set up the 82596 */  uti596_setScpAndScb( sc );    /* clear the scb command word */  sc->scb.command = 0;}/* *  uti596_initialize_hardware * *  Reset the 82596 and initialize it with a new SCP. Enable bus snooping. *  Install the interrupt handlers. *   *  Input parameters: *    sc - pointer to the uti596_softc * *  Output parameters: NONE * *  Return value: NONE */void uti596_initialize_hardware(  uti596_softc_ *sc){  rtems_isr_entry dummy;  printk(("uti596_initialize_hardware: begins\n"))  /* Get the PCCChip2 to assert bus snooping signals on behalf of the i82596 */  pccchip2->LANC_berr_ctl	= 0x40;  uti596_initialize( sc );    /*   * Configure interrupt control in PCCchip2   */  pccchip2->LANC_error		= 0xff;		/* clear status register */  pccchip2->LANC_int_ctl	= 0x5d;		/* lvl 5, enabled, edge-sensitive rising */  pccchip2->LANC_berr_ctl	= 0x5d;		/* bus error: lvl 5, enabled, snoop control  								 									 * will supply dirty data and leave dirty data  								 									 * on read access and sink any data on write  								 									 */  /*    * Install the interrupt handler   * calls rtems_interrupt_catch   */    dummy = (rtems_isr_entry) set_vector( uti596_DynamicInterruptHandler, 0x57, 1 );  /* Initialize the 82596 memory */  uti596_initMem(sc);  #ifdef DBG_INIT  printk(("uti596_initialize_hardware: After attach, status of board = 0x%x\n", sc->scb.status ))  #endif}/* *  uti596_reset_hardware * *  Reset the 82596 and initialize it with an SCP. *   *  Input parameters: *    sc - pointer to the uti596_softc * *  Output parameters: NONE * *  Return value: NONE */void uti596_reset_hardware(  uti596_softc_ *sc){  rtems_status_code status_code;  i596_cmd *pCmd;  pCmd = sc->pCmdHead;  /* This is a tx command for sure (99.99999%)  */  /* the command block list (CBL) is empty */  sc->scb.cmd_pointer = (unsigned long) I596_NULL;	/* all 1's */  sc->pCmdHead = sc->scb.pCmd = I596_NULL;			    /* all 1's */  #ifdef DBG_RESET  printk(("uti596_reset_hardware\n"))  #endif  uti596_initialize( sc );    /*   * Wake the transmitter if needed.   */  if ( sc->txDaemonTid && pCmd != I596_NULL ) {    printk(("****RESET: wakes transmitter!\n"))    status_code = rtems_event_send (sc->txDaemonTid,                           INTERRUPT_EVENT);    if ( status_code != RTEMS_SUCCESSFUL ) {      printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",             sc->txDaemonTid, rtems_status_text (status_code) ))    }  }  #ifdef DBG_RESET  printk(("uti596_reset_hardware: After reset_hardware, status of board = 0x%x\n", sc->scb.status ))  #endif}/* *  uti596_clearListStatus *  *  Clear the stat fields for all RFDs *  *  Input parameters: *  	pRfd - a pointer to the head of the RFA * *  Output parameters: NONE  * *  Return value: NONE */void uti596_clearListStatus(  i596_rfd *pRfd){  while ( pRfd != I596_NULL ) {    pRfd -> stat = 0;    pRfd = (i596_rfd *) word_swap((unsigned long)pRfd-> next);  }}/* *  uti596_reset *  *  Reset the 82596 and reconfigure *  *  Input parameters: NONE * *  Output parameters: NONE  * *  Return value: NONE */void uti596_reset( void ){  uti596_softc_ *sc = &uti596_softc;	#ifdef DBG_RESET  printk(("uti596_reset: begin\n"))	#endif	/* Wait for the CU to be available, then	 * reset the ethernet hardware. Must re-config. 	 */  sc->resetDone = 0;	uti596_wait ( sc, UTI596_WAIT_FOR_CU_ACCEPT );  uti596_reset_hardware ( &uti596_softc ); 	#ifdef DBG_RESET  uti596_diagnose();	#endif  /*   * Configure the 82596   */  uti596_configure( sc );  /*   * Set up the Individual (hardware) Address   */  uti596_IAsetup ( sc );  sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL;  /* restore the RFA */  if ( sc->pLastUnkRFD != I596_NULL ) {    sc-> pEndRFA =  sc->pLastUnkRFD; /* The end position can be updated */    sc-> pLastUnkRFD = I596_NULL;  }  sc->pEndRFA->next = sc->pSavedRfdQueue;  if ( sc->pSavedRfdQueue != I596_NULL ) {    sc->pEndRFA = sc->pEndSavedQueue;    sc->pSavedRfdQueue = sc->pEndSavedQueue = I596_NULL;    sc -> countRFD = sc->rxBdCount ;  }  /* Re-address the head of the RFA in the SCB */  sc->scb.pRfd =  sc->pBeginRFA;   sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA);	/* Clear the status of all RFDs */  uti596_clearListStatus( sc->pBeginRFA );  printk(("uti596_reset: Starting NIC\n"))  /* Start the receiver */  sc->scb.command = RX_START;  sc->started = 1;               /* assume that the start is accepted */  sc->resetDone = 1;  uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT );    UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n")	#ifdef DBG_RESET  printk(("uti596_reset: completed\n"))	#endif}/* *  uti596_dequeue *  *  Remove an RFD from the received fram queue *  *  Input parameters: *  	ppQ - a pointer to a i596_rfd pointer * *  Output parameters: NONE  * *  Return value: *  	pRfd - a pointer to the dequeued RFD */i596_rfd * uti596_dequeue(  i596_rfd ** ppQ){  ISR_Level level;  i596_rfd * pRfd;    _ISR_Disable(level);  /* invalid address, or empty queue or emptied queue */  if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {    _ISR_Enable(level);     return I596_NULL;  }  	/* 	 * Point to the dequeued buffer, then	 * adjust the queue pointer and detach the buffer	 */  pRfd = *ppQ;        *ppQ = (i596_rfd *) word_swap ((unsigned long) pRfd->next);  pRfd->next = I596_NULL;  /* unlink the rfd being returned */  _ISR_Enable(level);  return pRfd;}/* *  uti596_append *  *  Remove an RFD buffer from the RFA and tack it on to *  	the received frame queue for processing. *  *  Input parameters: *  	 ppQ - a pointer to the queue pointer *  	pRfd - a pointer to the buffer to be returned * *  Output parameters: NONE  * *  Return value: NONE */ void uti596_append(  i596_rfd ** ppQ,  i596_rfd * pRfd){  i596_rfd *p;  if ( pRfd != NULL && pRfd != I596_NULL) {    pRfd -> next = I596_NULL;    pRfd -> cmd |= CMD_EOL;    /* set EL bit */    if ( *ppQ == NULL || *ppQ == I596_NULL ) {      /* empty list */      *ppQ = pRfd;    }    else {      /* walk to the end of the list */      for ( p=*ppQ;            p->next != I596_NULL;            p=(i596_rfd *) word_swap ((unsigned long)p->next) );      /* append the rfd */      p->cmd &= ~CMD_EOL;  /* Clear EL bit at end */      p->next = (i596_rfd *) word_swap ((unsigned long)pRfd);    }  }  else {    printk(("Illegal attempt to append: %p\n", pRfd))  }}/* *  uti596_supplyFD *  *  Return a buffer (RFD) to the receive frame area (RFA). *  Call with interrupts disabled. *  *  Input parameters: *  	pRfd - a pointer to the buffer to be returned * *  Output parameters: NONE  * *  Return value: NONE */void uti596_supplyFD (  i596_rfd * pRfd){ i596_rfd *pLastRfd; UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD!\n")  pRfd -> cmd  = CMD_EOL; pRfd -> pRbd = I596_NULL; pRfd -> next = I596_NULL; pRfd -> stat = 0x0000;      /* clear STAT_C and STAT_B bits */ /*  * Check if the list is empty:  */ if ( uti596_softc.pBeginRFA == I596_NULL ) { 	 /* Start a list with one entry */   uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;   UTI_596_ASSERT(uti596_softc.countRFD == 0, "Null begin, but non-zero count\n")   if ( uti596_softc.pLastUnkRFD != I596_NULL ) {     printk(("LastUnkRFD is NOT NULL!!\n"))   }   uti596_softc.countRFD = 1;   return; }  /*  * Check if the last RFD is used/read by the 596.  */ pLastRfd = uti596_softc.pEndRFA; /* C = complete, B = busy (prefetched) */ if ( pLastRfd != I596_NULL && ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) {    /*    * Not yet too late to add it    */   pLastRfd -> next = (i596_rfd *) word_swap ((unsigned long)pRfd);   pLastRfd -> cmd &= ~CMD_EOL;  /* RESET_EL : reset EL bit to 0  */   uti596_softc.countRFD++;  /* Lets assume we add it successfully                                If not, the RFD may be used, and may                                decrement countRFD < 0 !! */   /*    * Check if the last RFD was used while appending.    */   if ( pLastRfd -> stat & ( STAT_C | STAT_B ) ) { /* completed or was prefetched */     /*      * Either the EL bit of the last rfd has been read by the 82596,      * and it will stop after reception,( true when RESET_EL not reached ) or      * the EL bit was NOT read by the 82596 and it will use the linked      * RFD for the next reception. ( true when RESET_EL was reached )      * So, it is unknown whether or not the linked rfd will be used.      * Therefore, the end of list CANNOT be updated.      */     UTI_596_ASSERT ( uti596_softc.pLastUnkRFD == I596_NULL, "Too many Unk RFD's\n" )     uti596_softc.pLastUnkRFD = pRfd;     return;   }   else {     /*      * The RFD being added was not touched by the 82596      */     if (uti596_softc.pLastUnkRFD != I596_NULL ) {       uti596_append((i596_rfd **)&uti596_softc.pSavedRfdQueue, pRfd); /* Only here! saved Q */       uti596_softc.pEndSavedQueue = pRfd;       uti596_softc.savedCount++;       uti596_softc.countRFD--;     }     else {            uti596_softc.pEndRFA = pRfd;   /* the RFA has been extended */              if ( ( uti596_softc.scb.status & SCB_STAT_RNR ||              uti596_softc.scb.status & RU_NO_RESOURCES ) &&              uti596_softc.countRFD > 1 ) {                       /* Ensure that beginRFA is not EOL */

⌨️ 快捷键说明

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