📄 network.c
字号:
} /*********************************************************************** * Function: uti596DynamicInterruptHandler * * Description: * This is the interrupt handler for the uti596 board * * Algorithm: * ***********************************************************************/ /* static */ rtems_isr uti596DynamicInterruptHandler(rtems_vector_number irq) { rtems_status_code sc;#ifdef DEBUG_ISR printk("I");#endif UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:on ISR entry"); if ( !(i8259s_cache & 0x20 )) { printk("****Error: network ISR running, no IRR!\n"); printk("****Error: i8259s_cache = 0x%x\n",i8259s_cache ); printk_time(); } scbStatus = uti596_softc.scb.status & 0xf000; if ( scbStatus ){ /* acknowledge interrupts */ /* printk("***INFO: ACK %x\n", scbStatus);*/ uti596_softc.scb.command = scbStatus; outport_word(CHAN_ATTN, 0); if( uti596_softc.resetDone ) { /* stack is attached */ UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:ACK"); } 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_time(); 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_time(); printk("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus); uti596_softc.nic_reset = 1; return; } if ( scbStatus & SCB_CUS_SUSPENDED ) { printk_time(); printk("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus); uti596_softc.nic_reset = 1; return; } if ( scbStatus & RU_SUSPENDED ) { printk_time(); printk("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus); uti596_softc.nic_reset = 1; return; } if ( scbStatus & SCB_STAT_RNR ) { printk_time(); printk("\n*****WARNING: RNR %x\n",scbStatus); printk("*****INFO: RFD cmd: %x status:%x\n", uti596_softc.pBeginRFA -> cmd, uti596_softc.pBeginRFA -> stat); } /* * Receive Unit Control */ if ( scbStatus & SCB_STAT_FR ) { /* a frame has been received */ uti596_softc.rxInterrupts++; #ifdef DBG_FR printk("\nISR:FR\n");#endif if ( uti596_softc.pBeginRFA == I596_NULL || !( uti596_softc.pBeginRFA -> stat & STAT_C)){ dump_scb(); uti596_softc.nic_reset = 1; } else while ( uti596_softc.pBeginRFA != I596_NULL && ( uti596_softc.pBeginRFA -> stat & STAT_C)) { #ifdef DBG_ISR printk("ISR: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("Count < 0 !!!: count == %d, beginRFA = %p\n", uti596_softc.countRFD, uti596_softc.pBeginRFA); uti596_softc.stats.rx_packets++; pIsrRfd = uti596_softc.pBeginRFA -> next; /* the append destroys the link */ uti596append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA ); /* * if we have just received the a frame int he 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("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_RAW_ISR else printk("Rx Wake: %#x\n",uti596_softc.rxDaemonTid);#endif uti596_softc.pBeginRFA = pIsrRfd; } /* end while */ 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 scb_stat_fr */ /* * Check For Command Complete */ if ( scbStatus & SCB_STAT_CX ){#ifdef DBG_ISR printk("ISR:CU\n");#endif pIsrCmd = uti596_softc.pCmdHead; /* * For ALL completed commands */ if ( pIsrCmd != I596_NULL && pIsrCmd->status & STAT_C ){ #ifdef DBG_RAW_ISR printk("ISR:pIsrCmd != NULL\n");#endif /* * Adjust the command block list */ uti596_softc.pCmdHead = 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: /* printk("****INFO:Configure OK\n"); */ uti596_softc.cmdOk = 1; break; case CmdDump: #ifdef DBG_ISR printk("dump!\n");#endif uti596_softc.cmdOk = 1; break; case CmdDiagnose: #ifdef DBG_ISR printk("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("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_RAW_ISR else printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);#endif } } /* End case Cmd_Tx */ 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 %ld.\n", status & 0x07ff); */ } } break; default: /* * This should never be reached */ printk("CX but NO known command\n"); } /* end switch */ pIsrCmd = uti596_softc.pCmdHead; /* next command */ if ( pIsrCmd != I596_NULL ) printk("****WARNING: more commands in list, but no start to NIC\n"); } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C */ else { if ( pIsrCmd != I596_NULL ) { /* The command MAY be NULL from a RESET */ /* Reset the ethernet card, and wake the transmitter (if necessary) */ printk_time(); printk("****INFO: Request board reset ( tx )\n"); uti596_softc.nic_reset = 1; if ( uti596_softc.txDaemonTid){ /* Ensure that a 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_RAW_ISR else printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);#endif } } } } /* end if command complete */ /* if the receiver has stopped, * check if this is a No Resources scenario, * Try to add more RFD's ( no RBDs are used ) */ if ( uti596_softc.started ) { if ( scbStatus & SCB_STAT_RNR ){#ifdef DBG_ISR printk("INFO:RNR: status %#x \n", uti596_softc.scb.status );#endif /* * THE RECEIVER IS OFF! */ if ( uti596_softc.pLastUnkRFD != I596_NULL ){ /* We have an unknown RFD, it is not inbound*/ if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) /* in use */ uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD; /* update end */ else { /* * It is NOT in use, and since RNR, we know EL bit of pEndRFA was read! * So, unlink it from the RFA and move it to the saved queue. * But pBegin can equal LastUnk! */ if ( uti596_softc.pEndRFA != I596_NULL ){ /* check added feb24. */#ifdef DEBUG_RFA if (uti596_softc.pEndRFA -> next != uti596_softc.pLastUnkRFD){ printk("***ERROR:UNK: %p not end->next: %p, end: %p\n", uti596_softc.pLastUnkRFD,uti596_softc.pEndRFA -> next,uti596_softc.pEndRFA); printk("***INFO:countRFD now %d\n", uti596_softc.countRFD); printk("\n\n"); }#endif uti596_softc.pEndRFA -> next = I596_NULL; /* added feb 16 */ } uti596append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD ); uti596_softc.savedCount++; uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD; uti596_softc.countRFD--; /* It was not in the RFA */ /* * The Begin pointer CAN advance this far. We must resynch the CPU side * with the chip. */ if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {#ifdef DEBUG_RFA if ( uti596_softc.countRFD != 0 ) { printk("****INFO:About to set begin to NULL, with count == %d\n", uti596_softc.countRFD ); printk("\n\n"); }#endif uti596_softc.pBeginRFA = I596_NULL; UTI_596_ASSERT(uti596_softc.countRFD == 0,"****ERROR:Count must be zero here!\n"); } } uti596_softc.pLastUnkRFD = I596_NULL; } /* end if exists UnkRFD */ /* * Append the saved queue to the RFA. * Any further RFD's being supplied will be added to * this new list. */ if ( uti596_softc.pSavedRfdQueue != I596_NULL ) { /* entries to add */ if ( uti596_softc.pBeginRFA == I596_NULL ) { /* add at beginning to list */#ifdef DEBUG_RFA if(uti596_softc.countRFD != 0) { printk("****ERROR:Begin pointer is NULL, but count == %d\n",uti596_softc.countRFD); }#endif uti596_softc.pBeginRFA = uti596_softc.pSavedRfdQueue; uti596_softc.pEndRFA = uti596_softc.pEndSavedQueue; uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */ } else { #ifdef DEBUG_RFA if ( uti596_softc.countRFD <= 0) { printk("****ERROR:Begin pointer is not NULL, but count == %d\n",uti596_softc.countRFD); }#endif UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n"); UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n"); uti596_softc.pEndRFA->next = uti596_softc.pSavedRfdQueue; uti596_softc.pEndRFA->cmd &= ~CMD_EOL; /* clear the end of list */ uti596_softc.pEndRFA = uti596_softc.pEndSavedQueue; uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */#ifdef DEBUG_ISR printk("count: %d, saved: %d \n", uti596_softc.countRFD , uti596_softc.savedCount);#endif } /* printk("Isr: countRFD = %d\n",uti596_softc.countRFD); */ uti596_softc.countRFD += uti596_softc.savedCount; /* printk("Isr: after countRFD = %d\n",uti596_softc.countRFD); */ uti596_softc.savedCount = 0; } #ifdef DBG_596_RFD printk("The list starts here %p\n",uti596_softc.pBeginRFA );#endif if ( uti596_softc.countRFD > 1) { /****REMOVED FEB 18. && !( uti596_softc.pBeginRFA -> stat & (STAT_C | STAT_B ))) { *****/ printk_time(); printk("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat); printk("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd); uti596_softc.pBeginRFA -> stat = 0; UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n"); uti596_softc.scb.pRfd = uti596_softc.pBeginRFA; /* start RX here */ printk("****INFO: ISR Starting receiver\n"); uti596_softc.scb.command = RX_START; /* should this also be CU start? */ outport_word(CHAN_ATTN, 0); } /*****REMOVED FEB 18. else { printk("****WARNING: Receiver NOT Started -- countRFD = %d\n", uti596_softc.countRFD); printk("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n", uti596_softc.scb.command, uti596_softc.scb.status, uti596_softc.countRFD); printk("\nRFA: \n"); for ( pISR_Rfd = uti596_softc.pBeginRFA; pISR_Rfd != I596_NULL; pISR_Rfd = pISR_Rfd->next) printk("Frame @ %x, status: %x, cmd: %x\n", pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd); printk("\nInbound: \n"); for ( pISR_Rfd = uti596_softc.pInboundFrameQueue; pISR_Rfd != I596_NULL; pISR_Rfd = pISR_Rfd->next) printk("Frame @ %x, status: %x, cmd: %x\n", pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd); printk("\nSaved: \n"); for ( pISR_Rfd = uti596_softc.pSavedRfdQueue; pISR_Rfd != I596_NULL; pISR_Rfd = pISR_Rfd->next) printk("Frame @ %x, status: %x, cmd: %x\n", pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd); printk("\nUnknown: %p\n",uti596_softc.pLastUnkRFD); } *****/ } /* end stat_rnr */ } /* end if receiver started */ /* UTI_596_ASSERT(uti596_softc.scb.status == scbStatus, "****WARNING:scbStatus change!\n"); */ #ifdef DBG_ISR printk("X\n");#endif count_rx=0; /* * Do this last, to ensure that th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -