⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fei82557end.c

📁 这是ARM在Vxworks的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		{		pDrvCtrl->nCFDs = 				((FEI_SAFE_MEM (pDrvCtrl) - 				 (2 * FEI_RFD_MEM (pDrvCtrl))) /				 (CFD_SIZE));		}	    else if (FEI_FLAG_ISSET (FEI_INV_NRFD))		{		pDrvCtrl->nRFDs = 				((FEI_SAFE_MEM (pDrvCtrl) - 				 FEI_CFD_MEM (pDrvCtrl)) /				 (2 * CL_RFD_SIZE));		}	    else		{		if (pDrvCtrl->memSize < size) 		    {		    DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: not enough  memory\n"),					      1, 2, 3, 4, 5, 6);		    return (ERROR);		    }		}	    if ((pDrvCtrl->nCFDs <= 2) || (pDrvCtrl->nRFDs <= 2))		{		DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: not enough memory\n"),					  1, 2, 3, 4, 5, 6);		return (ERROR);		}	    FEI_FLAG_CLEAR (FEI_OWN_MEM);	    pDrvCtrl->cacheFuncs = cacheNullFuncs;	    break;	}    /* zero the shared memory */    memset (pDrvCtrl->pMemBase, 0, (int) pDrvCtrl->memSize);    /* pool of mblks */    if (fei82557MclBlkConfig.mBlkNum == 0)        fei82557MclBlkConfig.mBlkNum = ((pDrvCtrl->nRFDs) *                                        FEI_RFD_LOAN_MULTIPLIER + 1 ) * 5;    /* pool of clusters, including loaning buffers */    if (fei82557ClDescTbl[0].clNum == 0)	{	fei82557ClDescTbl[0].clNum = ((pDrvCtrl->nRFDs) * \                                       (FEI_RFD_LOAN_MULTIPLIER + 1));	fei82557ClDescTbl[0].clSize = RFD_SIZE;	}    fei82557ClDescTbl[0].memSize = (fei82557ClDescTbl[0].clNum * 				  (fei82557ClDescTbl[0].clSize + CL_OVERHEAD));    fei82557ClDescTbl[0].memArea = pDrvCtrl->pMemBase + 				  (pDrvCtrl->nCFDs * CFD_SIZE);    /* align the shared memory */    fei82557ClDescTbl[0].memArea = (char *) 				   (((u_long) fei82557ClDescTbl[0].memArea + 0x3)				   & ~0x3);    /* pool of cluster blocks */    if (fei82557MclBlkConfig.clBlkNum == 0)	fei82557MclBlkConfig.clBlkNum = fei82557ClDescTbl[0].clNum;    /* get memory for mblks */    if (fei82557MclBlkConfig.memArea == NULL)	{	/* memory size adjusted to hold the netPool pointer at the head */	fei82557MclBlkConfig.memSize = ((fei82557MclBlkConfig.mBlkNum *				       (M_BLK_SZ + sizeof(long)))  +				       (fei82557MclBlkConfig.clBlkNum * 					CL_BLK_SZ + sizeof(long)));	if ((fei82557MclBlkConfig.memArea = (char *) memalign					    (4, fei82557MclBlkConfig.memSize))	    == NULL)	    return (ERROR);	/* store the pointer to the cluster area */	pDrvCtrl->pMemArea = fei82557MclBlkConfig.memArea;	}    /* init the mem pool */    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &fei82557MclBlkConfig, 		     &fei82557ClDescTbl[0], fei82557ClDescTblNumEnt, NULL) 		     == ERROR)	return (ERROR);    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,					       RFD_SIZE, FALSE)) == NULL)	return (ERROR);    /* carve up the shared-memory region */    /*     * N.B.     * We are setting up the CFD ring as a ring of TxCBs, tied off with a     * CFD_C_SUSP as frames are copied into the data buffers.  The     * susp/resume model is used because the links to the next CFDs do     * not change -- it is a fixed ring.  Also note that if a CFD is needed     * for anything else (e.g., DIAG, NOP, DUMP, CONFIG, or IASETUP comands),     * then the commands will use the current CFD in the ring.  After the     * command is complete, it will be set back to a TxCB by fei82557Action().     */    /* First ready CFD pointer */    pCFD = pDrvCtrl->pFreeCFD = (CFD_ID) pDrvCtrl->pMemBase;    /* initialize the CFD ring */    for (ix = 0; ix < pDrvCtrl->nCFDs; ix++)	{	CFD_WORD_WR (pCFD, CFD_STAT_OFFSET,		     (CFD_S_COMPLETE | CFD_S_OK));	/* tie the current CFD to the next one */	CFD_NEXT_WR (pCFD, ((UINT32) pCFD + CFD_SIZE));	CFD_LONG_WR (pCFD, CFD_SW_NEXT_OFFSET, ((UINT32) pCFD + CFD_SIZE));	if (!firstCFD)	    {	    /* Previous CFD pointer */	    CFD_LONG_WR (pCFD, CFD_PREV_OFFSET,			 ((UINT32) pCFD - CFD_SIZE));	    }	else	    {	    /* remember this CFD */	    pDrvCtrl->pFreeCFD = pCFD;	    /* tie the first CFD to the last one */	    CFD_LONG_WR (pCFD, CFD_PREV_OFFSET,			 ((UINT32) pCFD + (CFD_SIZE * (pDrvCtrl->nCFDs - 1))));	    firstCFD = FALSE;	    }	/* no TBDs used */	CFD_TBD_WR (pCFD, (UINT32) TBD_NOT_USED);	CFD_BYTE_WR (pCFD, CFD_NUM_OFFSET, 0);	/* set the thresh value */	CFD_BYTE_WR (pCFD, CFD_THRESH_OFFSET, 		     pDrvCtrl->board.tcbTxThresh);	/* bump to the next CFD */	pCFD = (CFD_ID) ((UINT32) pCFD + CFD_SIZE);	}    pCFD = (CFD_ID) ((UINT32) pCFD - CFD_SIZE);    /* tie the last CFD to the first one */    CFD_NEXT_WR (pCFD, ((UINT32) pDrvCtrl->pFreeCFD));    CFD_LONG_WR (pCFD, CFD_SW_NEXT_OFFSET, ((UINT32) pDrvCtrl->pFreeCFD));    /* set the used CFDs ring to the free one */    pDrvCtrl->pUsedCFD = pDrvCtrl->pFreeCFD;    /*     * N.B.     * Use RFD_C_EL to tie the end of the RBD ring, and not RFD_C_SUSP     * This is because we want the option of inserting a new RFD into     * the ring on the fly (i.e., via an SCB_RUSTART command).  Why would     * we do this?  Buffer loaning....  A suspend/resume reception model     * will not allow us to do this, so we must use an idle/start model.     */    /* initialize the RFD ring, some of the fields will be done      * in fei82557Start      */    for (ix = 0; ix < pDrvCtrl->nRFDs; ix++)	{	volatile RFD_ID    pRFDOld;	if ((pRFD = (RFD_ID) netClusterGet (pDrvCtrl->endObj.pNetPool,					   pDrvCtrl->pClPoolId)) == NULL)	    return (ERROR);	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 (pRFDOld, RFD_SW_NEXT_OFFSET, (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);    RFD_LONG_WR (pRFD, RFD_SW_NEXT_OFFSET, (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(SCB_C_M);    /* 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_LONG_RD (pRFD, RFD_SW_NEXT_OFFSET, 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))))	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -