📄 fei82557end.c
字号:
SYS_INT_ENABLE (pDrvCtrl); /* run diagnostics */ if (fei82557Diag (pDrvCtrl) == ERROR) return (ERROR); /* setup address */ if (fei82557IASetup (pDrvCtrl) == ERROR) return (ERROR); if (END_FLAGS_ISSET (IFF_MULTICAST)) FEI_FLAG_SET (FEI_MCAST); /* configure chip */ if (fei82557Config (pDrvCtrl) == ERROR) return (ERROR); /* set some flags to default values */ pDrvCtrl->rxHandle = FALSE; pDrvCtrl->txHandle = FALSE; pDrvCtrl->txStall = FALSE; /* get the current free RFD */ RFD_GET (pRFD); /* initiailize RFD ring */ do { /* set state and command for this RFD */ RFD_WORD_WR (pRFD, RFD_STAT_OFFSET, (UINT32) 0); RFD_WORD_WR (pRFD, RFD_COMM_OFFSET, (UINT32) 0); /* bump to the next RFD */ RFD_NEXT_RD (pRFD, tempVar); pRFD = (RFD_ID) tempVar; } while (pRFD != pDrvCtrl->pRFD); /* mark the last RFD for the chip to became idle */ RFD_LONG_RD (pRFD, RFD_PREV_OFFSET, tempVar); RFD_WORD_WR (tempVar, RFD_COMM_OFFSET, (UINT32) RFD_C_EL); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); /* put CU into suspended state */ if (fei82557NOP (pDrvCtrl) == ERROR) return (ERROR); /* mark the interface as up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* startup the receiver */ if (fei82557SCBCommand (pDrvCtrl, SCB_C_RUSTART, TRUE, pRFD) == ERROR) return (ERROR); DRV_LOG (DRV_DEBUG_START, ("Starting end... Done\n"), 1, 2, 3, 4, 5, 6); return (OK); }/******************************************************************************** fei82557Send - send an Ethernet packet** This routine() takes a M_BLK_ID and sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer.** muxSend() calls this routine each time it wants to send a packet.** RETURNS: N/A*/LOCAL STATUS fei82557Send ( DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ M_BLK * pMblk /* pointer to the mBlk/cluster pair */ ) { volatile CFD_ID pCFD; volatile CFD_ID pPrevCFD; int len = 0; volatile UINT16 command; volatile UINT16 status; char * pEnetHdr; volatile UINT16 scbStatus; DRV_LOG (DRV_DEBUG_TX, ("fei82557Send...\n"), 1, 2, 3, 4, 5, 6); /* check device mode */ if (FEI_FLAG_ISSET (FEI_POLLING)) { return (ERROR); } /* check for CFDs availability */ /* get the current free CFD */ FREE_CFD_GET (pCFD); /* Make cache consistent with memory */ FEI_CACHE_INVALIDATE (pCFD, 4); /* read the CFD status word */ CFD_WORD_RD (pCFD, CFD_STAT_OFFSET, status); if (!(FD_FLAG_ISSET (status, (CFD_S_COMPLETE | CFD_S_OK)))) { DRV_LOG (DRV_DEBUG_TX, ("fei82557Send...NO CFDS \n"), 1, 2, 3, 4, 5, 6); /* set to stall condition */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); pDrvCtrl->txStall = TRUE; END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); } /* interlock with fei82557CFDFree */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); pEnetHdr = (char *) (CFD_PKT_ADDR (pCFD)); len = netMblkToBufCopy (pMblk, (char *) pEnetHdr, NULL); netMblkClChainFree (pMblk); len = max (ETHERSMALL, len); /* set up the current CFD */ CFD_WORD_WR (pCFD, CFD_COUNT_OFFSET, ((len & 0x3fff) | TCB_CNT_EOF)); CFD_WORD_WR (pCFD, CFD_COMM_OFFSET, (CFD_C_XMIT | CFD_C_SUSP)); CFD_WORD_WR (pCFD, CFD_STAT_OFFSET, 0); /* set the thresh value */ CFD_BYTE_WR (pCFD, CFD_THRESH_OFFSET, pDrvCtrl->board.tcbTxThresh); /* no TBDs used */ CFD_BYTE_WR (pCFD, CFD_NUM_OFFSET, 0); /* this is a transmit command */ CFD_BYTE_WR (pCFD, CFD_ACTION_OFFSET, CFD_TX); /* tie to the previous CFD */ CFD_LONG_RD (pCFD, CFD_PREV_OFFSET, pPrevCFD); CFD_WORD_RD (pPrevCFD, CFD_COMM_OFFSET, command); CFD_WORD_WR (pPrevCFD, CFD_COMM_OFFSET, (command & (~CFD_C_SUSP))); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); /* advance the current free CFD pointer */ fei82557FDUpdate (pDrvCtrl, CFD_FREE); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); /* kick the CU if needed */ /* read CSR status word */ CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); if ((scbStatus & SCB_S_CUMASK) == SCB_S_CUSUSP) { if (fei82557SCBCommand (pDrvCtrl, SCB_C_CURESUME, FALSE,(UINT32) 0) == ERROR) { DRV_LOG (DRV_DEBUG_TX, ("Could not send packet\n"), 1, 2, 3, 4, 5, 6); return (ERROR); } else { /* in the old driver ther was a second attempt * at transimitting the packet, but is it sensible? */ } } /* interlock with fei82557CFDFree */ END_TX_SEM_GIVE (&pDrvCtrl->endObj); DRV_LOG (DRV_DEBUG_TX, ("fei82557Send...Done\n"), 1, 2, 3, 4, 5, 6); return (OK); }/******************************************************************************** fei82557Int - entry point for handling interrupts from the 82557** The interrupting events are acknowledged to the device, so that the device* will de-assert its interrupt signal. The amount of work done here is kept* to a minimum; the bulk of the work is deferred to the netTask.** RETURNS: N/A*/LOCAL void fei82557Int ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { UINT16 event; UINT16 scbStatus; UINT16 scbCommand; /* read and save CSR status word */ CSR_WORD_RD (CSR_STAT_OFFSET, event); if ((event & SCB_S_STATMASK) == 0) { /* This device was not the cause of the shared int */ return; } /* clear chip level interrupt pending, use byte access */ CSR_BYTE_WR (CSR_ACK_OFFSET, ((event & SCB_S_STATMASK) >> 8)); /* board level interrupt acknowledge */ SYS_INT_ACK (pDrvCtrl); /* read CSR status word again */ CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); DRV_LOG (DRV_DEBUG_INT, ("fei82557Int: event 0x%x, scbStatus 0x%x\n"), event, scbStatus, 0, 0, 0, 0); /* read CSR command word */ CSR_WORD_RD (CSR_COMM_OFFSET, scbCommand); /* handle transmit interrupts */ if ((event & SCB_S_CNA) && (!((UINT8) (scbCommand >> 8) & SCB_C_M)) && (!(pDrvCtrl->txHandle))) { I82557_INT_DISABLE; pDrvCtrl->txHandle = TRUE; (void) netJobAdd ((FUNCPTR) fei82557CFDFree, (int) pDrvCtrl, 0, 0, 0, 0); } /* handle receive interrupts only if fei82557Receive is not running */ if ((event & SCB_S_FR) && !((UINT8) (scbCommand >> 8) & SCB_C_M) && !(pDrvCtrl->rxHandle)) { I82557_INT_DISABLE; pDrvCtrl->rxHandle = TRUE; (void) netJobAdd ((FUNCPTR) fei82557HandleRecvInt, (int) pDrvCtrl, 0, 0, 0, 0); } }/******************************************************************************** fei82557HandleRecvInt - service task-level interrupts for receive frames** This routine is run in netTask's context. The ISR scheduled* this routine so that it could handle receive packets at task level.** RETURNS: N/A*/LOCAL void fei82557HandleRecvInt ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { volatile RFD_ID pRFD; volatile UINT16 status = 0; volatile UINT16 scbStatus; volatile UINT16 scbCommand; int ix; DRV_LOG (DRV_DEBUG_RX, ("fei82557HandleRecvInt: \n"), 0, 0, 0, 0, 0, 0); /* while RFDs to be processed */ FOREVER { /* check for RFDs availability */ /* get the first used RFD */ RFD_GET (pRFD); /* Make cache consistent with memory */ FEI_CACHE_INVALIDATE (pRFD, RFD_SIZE); /* read the RFD status word */ RFD_WORD_RD (pRFD, RFD_STAT_OFFSET, status); if (!(FD_FLAG_ISSET (status, RFD_S_COMPLETE))) { /* interlock with fei82557Int */ pDrvCtrl->rxHandle = FALSE; break; } /* read and save CSR status word */ CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); /* clear chip level interrupt pending, use byte access */ CSR_BYTE_WR (CSR_ACK_OFFSET, ((scbStatus & (SCB_S_FR | SCB_S_RNR)) >> 8)); fei82557Receive (pDrvCtrl, pRFD); } /* interlock with fei82557Int */ pDrvCtrl->rxHandle = FALSE; /* Flush the write pipe */ CACHE_PIPE_FLUSH (); /* kick receiver (if needed) */ CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); if ((scbStatus & SCB_S_RUMASK) != SCB_S_RURDY) { DRV_LOG (DRV_DEBUG_RX, ("HandleRecvInt: ********* RU NOT READY\n"), 0, 0, 0, 0, 0, 0); /* get the first used RFD */ RFD_GET (pRFD); if (fei82557SCBCommand (pDrvCtrl, SCB_C_RUSTART, TRUE, pRFD) == ERROR) { DRV_LOG (DRV_DEBUG_RX, ("fei82557HandleRecvInt: command %d failed\n"), SCB_C_RUSTART, 0, 0, 0, 0, 0); } else { /* read CSR command word */ CSR_WORD_RD (CSR_COMM_OFFSET, scbCommand); DRV_LOG (DRV_DEBUG_RX, ("fei82557HandleRecvInt: CSR command word 0x%x\n"), (int) scbCommand, 0, 0, 0, 0, 0); /* wait for RUSTART accept */ for (ix = (FEI_INIT_TMO * fei82557ClkRate); --ix;) { /* read CSR command word */ CSR_WORD_RD (CSR_COMM_OFFSET, scbCommand); if (!(scbCommand & SCB_C_RUMASK)) { DRV_LOG (DRV_DEBUG_RX, ("fei82557HandleRecvInt: RUSTART accepted\n"), 0, 0, 0, 0, 0, 0); break; } taskDelay (1); } if (!ix) { DRV_LOG (DRV_DEBUG_RX, ("fei82557HandleRecvInt: RUSTART FAILED#######\n"), 0, 0, 0, 0, 0, 0); } } } /* re-enable receiver interrupts */ I82557_INT_ENABLE; DRV_LOG (DRV_DEBUG_RX, ("fei82557HandleRecvInt... Done, \n"), 0, 0, 0, 0, 0, 0); }/******************************************************************************** fei82557Receive - pass a received frame to the next layer up** RETURNS: N/A*/LOCAL void fei82557Receive ( DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ RFD_ID pRFD /* pointer to a RFD */ ) { volatile RFD_ID pNewRFD; M_BLK_ID pMblk = NULL; CL_BLK_ID pClBlk = NULL; volatile UINT16 status; volatile UINT16 count; /* pass the packet up only if reception was Ok */ RFD_WORD_RD (pRFD, RFD_STAT_OFFSET, status); if (!(FD_FLAG_ISSET (status, RFD_S_OK))) { goto fei82557RecvError; } if ((pMblk = netMblkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -