📄 fei82559end.c
字号:
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) goto fei82557RecvError; if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL) goto fei82557RecvError; if ((pNewRFD = (RFD_ID) netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId)) == NULL) goto fei82557RecvError; /* is the RFD to be given back?? */ if (netClBlkJoin (pClBlk, (char *) pRFD, RFD_SIZE, NULL, 0, 0, 0) == NULL) goto fei82557RecvError; if (netMblkClJoin (pMblk, pClBlk) == NULL) goto fei82557RecvError;#ifdef INCLUDE_MIBII_RFC2233#else END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);#endif /* INCLUDE_MIBII_RFC2233 */ /* get the actual received bytes number */ RFD_WORD_RD (pRFD, RFD_COUNT_OFFSET, count); pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mData = (char *) (RFD_PKT_ADDR (pRFD)); pMblk->mBlkHdr.mLen = count & ~0xc000; pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen; /* put the new RFD on the RFD queue */ fei82557RFDReturn(pDrvCtrl, pNewRFD);#ifdef INCLUDE_MIBII_RFC2233 if (pDrvCtrl->endObj.pMib2Tbl != NULL) { pDrvCtrl->endObj.pMib2Tbl->m2PktCountRtn(pDrvCtrl->endObj.pMib2Tbl, M2_PACKET_IN, pMblk->mBlkHdr.mData, pMblk->mBlkHdr.mLen); }#endif /* INCLUDE_MIBII_RFC2233 */ END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk); DRV_LOG (DRV_DEBUG_RX, ("fei82557Receive... Done, \n"), 0, 0, 0, 0, 0, 0); return;fei82557RecvError: if (pMblk != NULL) netMblkFree (pDrvCtrl->endObj.pNetPool, pMblk); if (pClBlk != NULL) netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk); if (pNewRFD != NULL) netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *) pNewRFD); #ifdef INCLUDE_MIBII_RFC2233 if (pDrvCtrl->endObj.pMib2Tbl != NULL) { pDrvCtrl->endObj.pMib2Tbl->m2CtrUpdateRtn(pDrvCtrl->endObj.pMib2Tbl, M2_ctrId_ifInErrors, 1); }#else END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);#endif /* INCLUDE_MIBII_RFC2233 */ /* put the errored RFD on the RFD queue */ fei82557RFDReturn(pDrvCtrl, pRFD); }/**************************************************************************** fei82557RFDReturn - put a Receive Frame on the Receive Queue** This routine puts a Receive Frame on the Receive Queue.** RETURNS: N/A**/LOCAL void fei82557RFDReturn ( DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ RFD_ID pNewRFD /* pointer to a RFD */ ) { volatile UINT32 tempVar; volatile RFD_ID pRFD; volatile UINT16 command; /* get the last used RFD */ RFD_GET (pRFD); /* link it to the RFD chain */ /* link the new RFD to the next one */ RFD_NEXT_RD (pRFD, (UINT32) tempVar); RFD_LONG_WR (tempVar, RFD_PREV_OFFSET, (UINT32) pNewRFD); RFD_NEXT_WR (pNewRFD, tempVar); /* link the new RFD to the previous one */ RFD_LONG_RD (pRFD, RFD_PREV_OFFSET, tempVar); RFD_NEXT_WR (tempVar, pNewRFD); RFD_LONG_WR (pNewRFD, RFD_PREV_OFFSET, tempVar); /* init the new RFD, mirrors fei82557Start */ /* set state and command for this RFD */ RFD_WORD_WR (pNewRFD, RFD_STAT_OFFSET, (UINT32) 0); RFD_WORD_WR (pNewRFD, RFD_COMM_OFFSET, (UINT32) RFD_C_EL); /* no RBDs used */ RFD_RBD_WR (pNewRFD, (UINT32) RBD_NOT_USED); /* set the actual count field to zero */ RFD_WORD_WR (pNewRFD, RFD_COUNT_OFFSET, 0); /* set the size field for Ethernet packets */ RFD_WORD_WR (pNewRFD, RFD_SIZE_OFFSET, (UINT32) (ETHERMTU + EH_SIZE)); /* chain the previous RFD */ RFD_LONG_RD (pNewRFD, RFD_PREV_OFFSET, tempVar); RFD_WORD_RD (tempVar, RFD_COMM_OFFSET, command); RFD_WORD_WR (tempVar, RFD_COMM_OFFSET, (command & (~RFD_C_EL))); /* bump to the next free RFD */ fei82557FDUpdate (pDrvCtrl, RFD_FREE); }/**************************************************************************** fei82557CFDFree - free all used command frames** This routine frees all used command frames and notifies upper protocols* that new resources are available.** RETURNS: N/A**/LOCAL void fei82557CFDFree ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { volatile CFD_ID pUsedCFD = NULL; volatile UINT16 status; volatile UINT16 scbStatus; UINT8 action; if (!(FEI_FLAG_ISSET (FEI_POLLING))) { I82557_INT_ENABLE; /* interlock with fei82557Send */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* read CSR status word */ CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); /* if CU is active, do not go on */ if ((scbStatus & SCB_S_CUMASK) != SCB_S_CUSUSP) { END_TX_SEM_GIVE (&pDrvCtrl->endObj); pDrvCtrl->txHandle = FALSE; return; } } /* process all the used CFDs until we find either: * a. a non-complete frame; * b. a frame with the SUSPEND bit set */ FOREVER { static BOOL first = TRUE; USED_CFD_GET (pUsedCFD); /* Make cache consistent with memory */ FEI_CACHE_INVALIDATE (pUsedCFD, 4); /* read the CFD status word */ CFD_WORD_RD (pUsedCFD, CFD_STAT_OFFSET, status); /* if it's not ready, don't touch it! */ if (!(FD_FLAG_ISSET (status, (CFD_S_COMPLETE | CFD_S_OK)))) { break; } /* put CFD back to a TxCB - mirrors fei82557InitMem() */ /* no TBDs used */ CFD_TBD_WR (pUsedCFD, (UINT32) TBD_NOT_USED); CFD_BYTE_WR (pUsedCFD, CFD_NUM_OFFSET, 0); /* set the thresh value */ CFD_BYTE_WR (pUsedCFD, CFD_THRESH_OFFSET, pDrvCtrl->board.tcbTxThresh); /* correct statistic only in case of non-action command */ CFD_BYTE_RD (pUsedCFD, CFD_ACTION_OFFSET, action); if ((action == CFD_TX) && !(FD_FLAG_ISSET (status, (CFD_S_COMPLETE | CFD_S_OK)))) { if (!(FEI_FLAG_ISSET (FEI_POLLING))) { DRV_LOG (DRV_DEBUG_INT, ("fei82557CFDFree: Errored Frame \n"), 0, 0, 0, 0, 0, 0); }#ifdef INCLUDE_MIBII_RFC2233 if (pDrvCtrl->endObj.pMib2Tbl != NULL) { pDrvCtrl->endObj.pMib2Tbl->m2CtrUpdateRtn(pDrvCtrl->endObj.pMib2Tbl, M2_ctrId_ifOutErrors,1); }#else END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1);#endif /* INCLUDE_MIBII_RFC2233 */ /* make the errored CFD available */ CFD_WORD_WR (pUsedCFD, CFD_STAT_OFFSET, (CFD_S_OK | CFD_S_COMPLETE)); } if (!(FEI_FLAG_ISSET (FEI_POLLING))) { if (first) { /* soon notify upper protocols CFDs are available */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -