📄 fei82557end.c
字号:
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 to the next RFD */ RFD_NEXT_WR (pRFD, ((int)pRFD + RFD_DESC_SIZE)); pRbdTag->next = pRbdTag->index + 1; /* Set the RBD's next pointer to the next RBD */ RBD_NEXT_WR (pRBD, ((int)pRBD + RBD_SIZE)); RBD_WORD_WR (pRBD, RBD_CFG_OFFSET, CLUSTER_SIZE); break; case LAST_RFD: /* last */ /* Set the RFD's RBD pointer to 0xffffffff */ RFD_RBD_WR (pRFD, RBD_NULL_ADDR); /* Set last RFD's next pointer to the first RFD */ RFD_NEXT_WR (pRFD, (UINT32)pDrvCtrl->pRfdBase); pRbdTag->next = 0; /* Set last RBD's next pointer to the first RBD */ RBD_NEXT_WR (pRBD, (UINT32)pDrvCtrl->pRbdBase); RBD_WORD_WR (pRBD, RBD_CFG_OFFSET, (CLUSTER_SIZE | RBD_C_EL)); pDrvCtrl->eLRbdTag = pRbdTag; break; default : /* Set the RFD's RBD pointer to 0xffffffff */ RFD_RBD_WR (pRFD, RBD_NULL_ADDR); /* Set the RFD's next pointer to the next RFD */ RFD_NEXT_WR (pRFD, ((int)pRFD + RFD_DESC_SIZE)); pRbdTag->next = pRbdTag->index + 1; /* Set the RBD's next pointer to the next RBD */ RBD_NEXT_WR (pRBD, ((int)pRBD + RBD_SIZE)); RBD_WORD_WR (pRBD, RBD_CFG_OFFSET, CLUSTER_SIZE); } /* clear the status field */ RFD_WORD_WR (pRFD, RFD_STAT_OFFSET, (UINT16) 0); /* Set the actual count field to zero */ RFD_WORD_WR (pRFD, RFD_COUNT_OFFSET, 0); /* * Set the size field to zero s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -