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

📄 fei82557end.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    DRV_CTRL *  pDrvCtrl       /* pointer to DRV_CTRL structure */
    )
    {
    CFD_ID		pCFD;	   	/* pointer to CFDs */
    RFD_ID		pRFD;	   	/* pointer to RFDs */
    RFD_TAG *   	pRfdTag;
    RBD_ID		pRBD;	   	/* pointer to RFDs */
    RBD_TAG *   	pRbdTag;
    UINT32		clSize;	   	/* size of allocation for clusters */
    UINT32		clusterSize;   	/* size of allocation for clusters */
    UINT32		memSize;   	/* size of allocation passed by BSP */
    UINT32		nSubtract = 1; 	/* number of RFDs to subtract */
    UINT32		rfdSize;   	/* size of allocation for RFDs */
    UINT32		rbdSize;   	/* size of allocation for RBDs */
    UINT32		cfdSize;   	/* size of allocation for CFDs */
    int			ix;		/* index counter */
    BOOL		firstCFD = TRUE;/* the first CFD? */
    int                 firstOrLast;
     

    M_CL_CONFIG	 fei82557MclBlkConfig =
    {
	/*
	 *  mBlkNum  	clBlkNum     	memArea     memSize
	 *  -----------  	----		-------     -------
	 */
	    0,		0, 		NULL, 	    0
    };

    CL_DESC	 fei82557ClDescTbl [] =
    {
	/*
	 *  clusterSize  		num    	memArea     memSize
	 *  -----------  		----	-------     -------
	 */

	{CLUSTER_SIZE,			0,  	NULL,       0}    

    };

    int fei82557ClDescTblNumEnt = (NELEMENTS (fei82557ClDescTbl));

    /* initialize the netPool */

    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL)
	return (ERROR);

   /* this driver can't handle write incoherent caches */

    if (!CACHE_DMA_IS_WRITE_COHERENT ()) 
	{
	DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: shared 
			          memory not cache coherent\n"),
			          1, 2, 3, 4, 5, 6);
	return (ERROR);
	}

    switch ((int) pDrvCtrl->pClusterBase)
	{
	case NONE :			     /* we must obtain it */

            clSize = (pDrvCtrl->nClusters * CLUSTER_SIZE);

            /* Add one to rfdSize, rbdSize, & cfdSize to accomodate alignment */
            rfdSize = ((pDrvCtrl->nRFDs + 1) * RFD_DESC_SIZE);
            rbdSize = ((pDrvCtrl->nRBDs + 1) * RBD_SIZE);
            cfdSize = ((pDrvCtrl->nCFDs + 1) * CFD_SIZE);

            /* Align on 32 byte boundries */
            if ((pDrvCtrl->pRfdBase = cacheDmaMalloc (rfdSize + rbdSize + 
                                                      cfdSize)) == NULL)
                {
                return (ERROR);
                }

            memset (pDrvCtrl->pRfdBase, 0, (rfdSize + rbdSize + cfdSize));

            pDrvCtrl->pRfdBase = (char *)ROUND_UP((UINT32) pDrvCtrl->pRfdBase, 
                                                  32);

            pDrvCtrl->rfdTags = (RFD_TAG *)pDrvCtrl->pRfdBase;
            pDrvCtrl->pRFD = (RFD_ID)pDrvCtrl->pRfdBase;

            pDrvCtrl->pRbdBase = (char *)((int)pDrvCtrl->pRfdBase + rfdSize);
            pDrvCtrl->rbdTags = (RBD_TAG *)pDrvCtrl->pRbdBase;

            pDrvCtrl->pCfdBase = (char *)((int)pDrvCtrl->pRbdBase + rbdSize);

            pDrvCtrl->pClusterBase = memalign (_CACHE_ALIGN_SIZE, clSize); 

	    if (pDrvCtrl->pClusterBase == NULL)      /* no memory available */
		{
		DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: could not 
					    obtain memory\n"),
					    1, 2, 3, 4, 5, 6);
		return (ERROR);
		}
            /* zero the shared memory */
            memset(pDrvCtrl->pClusterBase,0,clSize);

	    pDrvCtrl->clMemSize = clSize;

	    FEI_FLAG_SET (FEI_OWN_MEM);

	    pDrvCtrl->cacheDmaFuncs = cacheDmaFuncs;
            pDrvCtrl->cacheFuncs = cacheUserFuncs;

            pDrvCtrl->pSendRtn = (FUNCPTR)fei82557GatherSend; 

	    break;

	default :			       /* the user provided an area */

	    if (pDrvCtrl->clMemSize == 0) 
		{
		DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: not enough 
					   memory\n"),
					   1, 2, 3, 4, 5, 6);
		return (ERROR);
		}

	    /* 
	     * check the user provided enough memory with reference
	     * to the given number of receive/transmit frames, if any.
	     */

           while ((pDrvCtrl->nRBDs * RBD_SIZE) > (nSubtract * CLUSTER_SIZE))
               {
               nSubtract++;
               }
            rfdSize = ((pDrvCtrl->nRFDs + 1) * RFD_DESC_SIZE);
            rbdSize = ((pDrvCtrl->nRBDs + 1) * RBD_SIZE);
            cfdSize = (pDrvCtrl->nCFDs * (CFD_SIZE + CLUSTER_SIZE)); 
            clusterSize = (((pDrvCtrl->nRFDs + 1) * 2) * CLUSTER_SIZE); 

            memSize = rfdSize + rbdSize + cfdSize + clusterSize;

            if (pDrvCtrl->clMemSize < memSize) 
	        {
	        DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: not enough 
	                                  memory\n"), 1, 2, 3, 4, 5, 6);
	        return (ERROR);
	        }

            /* zero the shared memory */
            memset(pDrvCtrl->pClusterBase,0,pDrvCtrl->clMemSize);

            memSize = pDrvCtrl->clMemSize - (rfdSize + rbdSize + cfdSize);

            pDrvCtrl->nClusters = ((memSize / CLUSTER_SIZE) - nSubtract); 

            pDrvCtrl->pRfdBase = pDrvCtrl->pClusterBase;
            pDrvCtrl->rfdTags = (RFD_TAG *)pDrvCtrl->pRfdBase; 
            pDrvCtrl->pRFD = (RFD_ID)pDrvCtrl->pRfdBase;

            pDrvCtrl->pRbdBase = (char *)((int)pDrvCtrl->pRfdBase + rfdSize);
            pDrvCtrl->rbdTags = (RBD_TAG *)pDrvCtrl->pRbdBase; 

            pDrvCtrl->pClusterBase = (char *)((int)pDrvCtrl->pRbdBase + 
                                                   rbdSize);

            pDrvCtrl->pCfdBase = (char *)((int)pDrvCtrl->pClusterBase + 
                                (pDrvCtrl->nClusters * CLUSTER_SIZE));  

	    FEI_FLAG_CLEAR (FEI_OWN_MEM);
	    pDrvCtrl->cacheDmaFuncs = cacheNullFuncs; 
            pDrvCtrl->cacheFuncs = cacheDmaFuncs;

            pDrvCtrl->pSendRtn = (FUNCPTR)fei82557CopySend; 

	    break;
	}

    /* pool of mblks */

    if (fei82557MclBlkConfig.mBlkNum == 0)
	fei82557MclBlkConfig.mBlkNum = pDrvCtrl->nClusters * 10;

    /* pool of clusters */

    if (fei82557ClDescTbl[0].clNum == 0)
	{
	fei82557ClDescTbl[0].clNum = pDrvCtrl->nClusters;
	fei82557ClDescTbl[0].clSize = CLUSTER_SIZE;
	}

    fei82557ClDescTbl[0].memSize = pDrvCtrl->clMemSize;  
    fei82557ClDescTbl[0].memArea = pDrvCtrl->pClusterBase;

    DRV_LOG (DRV_DEBUG_LOAD, ("fei82557EndLoad: pClusterBase %p nClusters %d 
                              cluster size %x\n"),
                              (int)pDrvCtrl->pClusterBase,pDrvCtrl->nClusters,
                              CLUSTER_SIZE,0,0,0); 

    /* pool of cluster blocks */

    if (fei82557MclBlkConfig.clBlkNum == 0)
	fei82557MclBlkConfig.clBlkNum = (fei82557ClDescTbl[0].clNum * 2);

    /* get memory for mblks */

    if (fei82557MclBlkConfig.memArea == NULL)
	{
	/* memory size adjusted to hold the netPool pointer at the head */

        fei82557MclBlkConfig.memSize = (((fei82557MclBlkConfig.mBlkNum + 1) *
                                       MBLK_SIZE)  +
                                       ((fei82557MclBlkConfig.clBlkNum + 1) *
                                       CLBLK_SIZE));

	if ((fei82557MclBlkConfig.memArea = 
                                 (char *) (memalign (_CACHE_ALIGN_SIZE, 
                                           fei82557MclBlkConfig.memSize)) +
                                          (MBLK_SIZE - sizeof(long)))
	    == NULL)
	    return (ERROR);

	/* store the pointer to the cluster block area */
	pDrvCtrl->pMclBlkMemArea = fei82557MclBlkConfig.memArea;
	}

    /* init the mem pool */

    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &fei82557MclBlkConfig, 
		     &fei82557ClDescTbl[0], fei82557ClDescTblNumEnt, 
                     _pEndNetPoolFuncTbl) == ERROR)
	return (ERROR);

    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,
					       CLUSTER_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->pCfdBase;

    /* 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);
        CFD_LONG_WR (pCFD, CFD_MBLK_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;


    /* Initialize the RFDs and RBDs */

    for (ix = 0; ix < pDrvCtrl->nRFDs; ix++)
        {
        pRFD = (RFD_ID)((int)pDrvCtrl->pRfdBase + (ix * RFD_DESC_SIZE));
        pRBD = (RBD_ID)((int)pDrvCtrl->pRbdBase + (ix * RBD_SIZE));

        pRbdTag = (RBD_TAG *)pRBD;
        pRbdTag->pRBD = pRBD;                     
        pRbdTag->pRFD = pRFD;
        pRbdTag->index = ix;

       if ((pRbdTag->pMblk = netTupleGet(pDrvCtrl->endObj.pNetPool,CLUSTER_SIZE,
                                         M_DONTWAIT, MT_DATA,0)) == NULL)
            {
            return (ERROR);
            }

        pRbdTag->pMblk->mBlkHdr.mData = 
                                 (char *)((int)pRbdTag->pMblk->mBlkHdr.mData +
                                          pDrvCtrl->offset);

        RBD_BUF_WR (pRBD, (UINT32)pRbdTag->pMblk->mBlkHdr.mData);

        pRfdTag = (RFD_TAG *)pRFD;
        pRfdTag->index = ix;
        pRfdTag->nextIndex = (ix + 1) % pDrvCtrl->nRFDs;
        pRfdTag->status = 0;
        pRfdTag->pRFD = pRFD;

        if (ix == 0)
            firstOrLast = FIRST_RFD;
        else if (ix == pDrvCtrl->nRFDs - 1)
            firstOrLast = LAST_RFD;
        else
            firstOrLast = MID_RFD;

        switch (firstOrLast)
            {
            case FIRST_RFD: /* first */

                /* Set first RFD's RBD address pointer to first RBD */
                RFD_RBD_WR (pRFD, (UINT32)pDrvCtrl->pRbdBase);

                /* Set the RFD's next pointer

⌨️ 快捷键说明

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