📄 fei82557end.c
字号:
if (firstRFD) { /* first ready RFD pointer */ pDrvCtrl->pRFD = pRFD; firstRFD = FALSE; } else { /* tie the previous RFD to the current one */ RFD_NEXT_WR (pRFDOld, (UINT32) pRFD); RFD_LONG_WR (pRFD, RFD_PREV_OFFSET, (UINT32) pRFDOld); } /* no RBDs used */ RFD_RBD_WR (pRFD, (UINT32) RBD_NOT_USED); /* set the actual count field to zero */ RFD_WORD_WR (pRFD, RFD_COUNT_OFFSET, 0); /* set the size field for Ethernet packets */ RFD_WORD_WR (pRFD, RFD_SIZE_OFFSET, (UINT32) (ETHERMTU + EH_SIZE)); /* remember this RFD */ pRFDOld = pRFD; } /* tie the last RFD to the first one */ RFD_NEXT_WR ((UINT32) pRFD, (UINT32) pDrvCtrl->pRFD); /* link the first RFD to the last one */ RFD_LONG_WR (pDrvCtrl->pRFD, RFD_PREV_OFFSET, (UINT32) pRFD); /* Flush the write pipe */ CACHE_PIPE_FLUSH (); DRV_LOG (DRV_DEBUG_LOAD, ("fei82557InitMem... Done\n"), 0, 0, 0, 0, 0, 0); return OK; }/**************************************************************************** fei82557Start - start the device** This routine starts the 82557 device and brings it up to an operational* state. The driver must have already been attached with the fei82557Load()* routine.** RETURNS: OK, or ERROR if the device could not be initialized.*/LOCAL STATUS fei82557Start ( DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */ ) { RFD_ID pRFD; UINT32 tempVar; int retVal; DRV_LOG (DRV_DEBUG_START, ("Starting end...\n"), 1, 2, 3, 4, 5, 6); /* must have been attached */ if (!pDrvCtrl->attached) return (ERROR); /* reset the chip */ if (fei82557Reset (pDrvCtrl) == ERROR) return (ERROR); /* connect the int handler */ SYS_INT_CONNECT (pDrvCtrl, fei82557Int, (int) pDrvCtrl, &retVal); if (retVal == ERROR) return (ERROR); /* acknowledge interrupts */ SYS_INT_ACK (pDrvCtrl); /* enable chip interrupts after fei82557Reset disabled them */ I82557_INT_ENABLE; /* enable system interrupts after fei82557Reset disabled them */ 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)) { netMblkClChainFree (pMblk); /* free the given mBlk chain */ errno = EINVAL; return (ERROR); } /* interlock with fei82557CFDFree */ END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER); /* 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 */ pDrvCtrl->txStall = TRUE; CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); if ((scbStatus & SCB_S_CUMASK) == SCB_S_CUSUSP) { if (fei82557SCBCommand (pDrvCtrl, SCB_C_CUSTART, TRUE, pCFD) == ERROR) { DRV_LOG (DRV_DEBUG_TX,("CU Start failed \n"), 0, 0, 0, 0, 0, 0); } } END_TX_SEM_GIVE (&pDrvCtrl->endObj); return (END_ERR_BLOCK); } 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); END_TX_SEM_GIVE (&pDrvCtrl->endObj); 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; /* 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; } /* Disable interrupts in the device for now */ I82557_INT_DISABLE; /* 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); /* handle transmit interrupts */ if ((event & SCB_S_CNA) && (pDrvCtrl->txHandle == FALSE)) { pDrvCtrl->txHandle = TRUE; netJobAdd ((FUNCPTR) fei82557CFDFree, (int) pDrvCtrl, 0, 0, 0, 0); } /* handle receive interrupts only if fei82557Receive is not running */ if ((event & (SCB_S_FR | SCB_S_RNR)) && (pDrvCtrl->rxHandle == FALSE)) { pDrvCtrl->rxHandle = TRUE; netJobAdd ((FUNCPTR) fei82557HandleRecvInt, (int) pDrvCtrl, 0, 0, 0, 0); } I82557_INT_ENABLE; }/******************************************************************************** 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; UINT16 status = 0; UINT16 scbStatus; 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); DRV_LOG (DRV_DEBUG_RX, "Checking RFD @ %#x status = %#x\n", (int) pRFD, (int) status ,0,0,0,0); if (!(FD_FLAG_ISSET (status, RFD_S_COMPLETE))) { /* No more RFDs, so break out of the inner loop */ break; } fei82557Receive (pDrvCtrl, pRFD); } /* Flush the write pipe */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -