📄 network.c
字号:
#ifdef DBG_WAIT printk(("uti596_setScpAndScb: Succeeded\n" )) #endif return 0; } case UTI596_WAIT_FOR_STAT_C: do { if( *sc->pCurrent_command_status & STAT_C ) break; else rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks); } while (start_ticks <= end_ticks); if (start_ticks > end_ticks ) { #ifdef DBG_WAIT printk(("uti596_initMem: timed out - STAT_C not obtained\n" )) #endif return -1; } else { #ifdef DBG_WAIT printk(("uti596_initMem: STAT_C obtained OK\n" )) #endif return 0; } } return -1;} /* * uti596_issueCA * * Issue a Channel Attention command. Possibly wait for the * command to start or complete. * * Input parameters: * sc - pointer to the uti596_softc * wait_type - UTI596_NO_WAIT * UTI596_WAIT_BEGIN * UTI596_WAIT_COMPLETION * * Output parameters: NONE * * Return value: * 0 if successful, -1 otherwise. */static int uti596_issueCA( uti596_softc_ *sc, unsigned8 waitType){ /* Issue Channel Attention */ i82596->chan_attn = 0x00000000; return (uti596_wait ( sc, waitType ));}/* * uti596_addCmd * * Add a uti596_cmd onto the end of the CBL command chain, * or to the start if the chain is empty. * * Input parameters: * pCmd - a pointer to the command to be added. * * Output parameters: NONE * * Return value: NONE */static void uti596_addCmd( i596_cmd *pCmd){ ISR_Level level; #ifdef DBG_ADD_CMD printk(("uti596_addCmd: Adding command 0x%x\n", pCmd -> command )) #endif /* Mark command as last in list, to return an interrupt */ pCmd->command |= (CMD_EOL | CMD_INTR ); pCmd->status = 0; pCmd->next = I596_NULL; _ISR_Disable(level); if (uti596_softc.pCmdHead == I596_NULL) { uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd; uti596_softc.scb.cmd_pointer = word_swap ((unsigned long)pCmd); uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); uti596_softc.scb.command = CUC_START; uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT ); _ISR_Enable(level); } else { uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd); uti596_softc.pCmdTail = pCmd; _ISR_Enable(level); } #ifdef DBG_ADD_CMD printk(("uti596_addCmd: Scb status & command 0x%x 0x%x\n", uti596_softc.scb.status, uti596_softc.scb.command )) #endif}/* * uti596_addPolledCmd * * Add a single uti596_cmd to the end of the command block list * for processing, send a CU_START and wait for its acceptance * * Input parameters: * sc - a pointer to the uti596_softc struct * * Output parameters: NONE * * Return value: NONE */void uti596_addPolledCmd( i596_cmd *pCmd){ #ifdef DBG_ADD_CMD printk(("uti596_addPolledCmd: Adding command 0x%x\n", pCmd -> command )) #endif pCmd->status = 0; pCmd->command |= CMD_EOL ; /* only command in list*/ pCmd->next = I596_NULL; uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd; uti596_softc.scb.cmd_pointer = word_swap((unsigned long)pCmd); uti596_softc.scb.command = CUC_START; uti596_issueCA ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL; uti596_softc.scb.cmd_pointer = (unsigned long) I596_NULL; #ifdef DBG_ADD_CMD printk(("uti596_addPolledCmd: Scb status & command 0x%x 0x%x\n", uti596_softc.scb.status, uti596_softc.scb.command )) #endif}/* * uti596_CU_dump * * Dump the LANC 82596 registers * The outcome is the same as the portDump() but executed * via the CU instead of via a PORT access. * * Input parameters: * drp - a pointer to a i596_dump_result structure. * * Output parameters: NONE * * Return value: NONE */static void uti596_CU_dump ( i596_dump_result * drp){ i596_dump dumpCmd; dumpCmd.cmd.command = CmdDump; dumpCmd.cmd.next = I596_NULL; dumpCmd.pData = (char *) drp; uti596_softc.cmdOk = 0; uti596_addCmd ( (i596_cmd *) &dumpCmd );}/* * uti596_dump_scb * * Dump the system control block * This function expands to nothing when using interrupt driven I/O * * Input parameters: NONE * * Output parameters: NONE * * Return value: NONE */static void uti596_dump_scb ( void ){ printk(("status 0x%x\n",uti596_softc.scb.status)) printk(("command 0x%x\n",uti596_softc.scb.command)) printk(("cmd 0x%x\n",(int)uti596_softc.scb.pCmd)) printk(("rfd 0x%x\n",(int)uti596_softc.scb.pRfd)) printk(("crc_err 0x%x\n",uti596_softc.scb.crc_err)) printk(("align_err 0x%x\n",uti596_softc.scb.align_err)) printk(("resource_err 0x%x\n",uti596_softc.scb.resource_err )) printk(("over_err 0x%x\n",uti596_softc.scb.over_err)) printk(("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err)) printk(("short_err 0x%x\n",uti596_softc.scb.short_err)) printk(("t_on 0x%x\n",uti596_softc.scb.t_on)) printk(("t_off 0x%x\n",uti596_softc.scb.t_off))}/* * uti596_setScpAndScb * * Issue the first channel attention after reset and wait for the busy * field to clear in the iscp. * * Input parameters: * sc - pointer to the global uti596_softc * * Output parameters: NONE * * Return value: * 0 if successful, -1 otherwise. */static int uti596_setScpAndScb( uti596_softc_ * sc){ /* set the busy flag in the iscp */ sc->iscp.busy = 1; /* the command block list (CBL) is empty */ sc->scb.command = 0; sc->scb.cmd_pointer = (unsigned long) I596_NULL; /* all 1's */ sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */ uti596_writePortFunction( sc->pScp, UTI596_SCP_PORT_FUNCTION ); /* Issue CA: pass the scb address to the 596 */ return ( uti596_issueCA ( sc, UTI596_WAIT_FOR_INITIALIZATION ) );}/* * uti596_diagnose * * Send a diagnose command to the CU * * Input parameters: NONE * * Output parameters: NONE * * Return value: * 0 if successful, -1 otherwise */static int uti596_diagnose( void ){ i596_cmd diagnose; diagnose.command = CmdDiagnose; diagnose.status = 0; uti596_softc.pCurrent_command_status = (unsigned short *)&diagnose.status; uti596_addPolledCmd(&diagnose); return (uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_STAT_C )); #ifdef DBG_INIT printk(("Status diagnostic: 0xa000 is a success ... 0x%2.2x\n", diagnose.status)) #endif}/* * uti596_configure * * Send the CU a configure command with the desired * configuration structure * * Input parameters: * sc - a pointer to the uti596_softc struct * * Output parameters: NONE * * Return value: * 0 if successful, -1 otherwise */static int uti596_configure ( uti596_softc_ * sc){ sc->set_conf.cmd.command = CmdConfigure; memcpy ( (void *)sc->set_conf.data, uti596initSetup, 14); uti596_addPolledCmd( (i596_cmd *) &sc->set_conf); /* Poll for successful command completion */ sc->pCurrent_command_status = (unsigned short *)&(sc->set_conf.cmd.status); return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) );}/* * uti596_IAsetup * * Send the CU an Individual Address setup command with * the ethernet hardware address * * Input parameters: * sc - a pointer to the uti596_softc struct * * Output parameters: NONE * * Return value: * 0 if successful, -1 otherwise */static int uti596_IAsetup ( uti596_softc_ * sc){ int i; 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; uti596_addPolledCmd((i596_cmd *)&sc->set_add); /* Poll for successful command completion */ sc->pCurrent_command_status = (unsigned short *)&(sc->set_add.cmd.status); return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) );}/* * uti596_initTBD * * Initialize transmit buffer descriptors * dynamically allocate mem for the number of tbd's required * * Input parameters: * sc - a pointer to the uti596_softc struct * * Output parameters: NONE * * Return value: * 0 if successful, -1 otherwise */static int uti596_initTBD ( uti596_softc_ * sc ){ int i; i596_tbd *pTbd, *pPrev; /* Set up a transmit command with a tbd ready */ sc->pLastUnkRFD = I596_NULL; sc->pTxCmd = (i596_tx *) calloc (1,sizeof (struct i596_tx) ); sc->pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) ); if ((sc->pTxCmd == NULL) || (sc->pTbd == NULL)) { return -1; } sc->pTxCmd->pTbd = (i596_tbd *) word_swap ((unsigned long) sc->pTbd); sc->pTxCmd->cmd.command = CMD_FLEX|CmdTx; sc->pTxCmd->pad = 0; sc->pTxCmd->count = 0; /* all bytes are in list of TBD's */ pPrev = pTbd = sc->pTbd; /* Allocate a linked list of tbd's each with it's 'next' field written * with upper and lower words swapped (for big endian), and mark the end. */ for ( i=0; i<sc->txBdCount; i++) { if ( (pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) )) == NULL ) { return -1; } pPrev->next = (i596_tbd *) word_swap ((unsigned long) pTbd); pPrev = pTbd; } pTbd->next = I596_NULL; return 0;}/* * uti596_initRFA * * Initialize the Receive Frame Area * dynamically allocate mem for the number of rfd's required * * Input parameters: * sc - a pointer to the uti596_softc struct * * Output parameters: NONE * * Return value: * # of buffer descriptors successfully allocated */static int uti596_initRFA( int num ){ i596_rfd *pRfd; int i = 0; #ifdef DBG_INIT printk(("uti596_initRFA: begins\n Requested frame descriptors ... %d.\n", num)) #endif /* * Create the first RFD in the RFA */ pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd)); if ( !pRfd ) { printk(("Can't allocate first buffer.\n")) return 0; } else { uti596_softc.countRFD = 1; uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd; } /* Create remaining RFDs */ for (i = 1; i < num; i++) { pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd) ); if ( pRfd != NULL ) { uti596_softc.countRFD++; /* update count */ uti596_softc.pEndRFA->next = (i596_rfd *) word_swap ((unsigned long) pRfd); /* write the link */ uti596_softc.pEndRFA = pRfd; /* move the end */ } else { printk(("Can't allocate all buffers: only %d allocated\n", i)) break; } } /* end for */ uti596_softc.pEndRFA->next = I596_NULL; UTI_596_ASSERT(uti596_softc.countRFD == RX_BUF_COUNT,"INIT:WRONG RFD COUNT\n" ) #ifdef DBG_INIT printk (("uti596_initRFA: Head of RFA is buffer %p \n\ uti596_initRFA: End of RFA is buffer %p \n", uti596_softc.pBeginRFA, uti596_softc.pEndRFA )) #endif /* Walk and initialize the RFD's */ for ( pRfd = uti596_softc.pBeginRFA; pRfd != I596_NULL; pRfd = (i596_rfd *) word_swap ((unsigned long)pRfd->next) ) { pRfd->cmd = 0x0000; pRfd->stat = 0x0000; pRfd->pRbd = I596_NULL; pRfd->count = 0; /* number of bytes in buffer: usually less than size */ pRfd->size = 1532; /* was 1532; buffer size ( All RBD ) */ } /* end for */ /* mark the last RFD as the last one in the RDL */ uti596_softc.pEndRFA -> cmd = CMD_EOL; uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* initially empty */ uti596_softc.savedCount = 0; uti596_softc.nop.cmd.command = CmdNOp; /* initialize the nop command */ return (i); /* the number of allocated buffers */}/* * uti596_initMem * * Initialize the 82596 memory structures for Tx and Rx * dynamically allocate mem for the number of tbd's required * * Input parameters: * sc - a pointer to the uti596_softc struct * * Output parameters: NONE * * Return value: NONE */void uti596_initMem( uti596_softc_ * sc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -