📄 motfccend.c
字号:
)
{
UINT32 bdMemSize,rbdMemSize,tbdMemSize;
UINT16 clNum; /* a buffer number holder */
/* cluster blocks configuration */
M_CL_CONFIG mclBlkConfig = {0, 0, NULL, 0};
/* cluster blocks config table */
CL_DESC clDescTbl [] = { {MOT_FCC_MAX_CL_LEN, 0, NULL, 0} };
/* number of different clusters sizes in pool -- only 1 */
int clDescTblNumEnt = 1;
/* initialize the netPool */
if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL)
{
return ERROR;
}
/*
* Establish the memory area that we will share with the device. This
* area may be thought of as being divided into two parts: one is the
* buffer descriptors (BD) and the second one is for the data buffers.
* Since they have different requirements as far as cache are concerned,
* they may be addressed separately.
* We'll deal with the BDs area first. If the caller has provided
* an area, then we assume it is non-cacheable and will not require
* the use of the special cache routines. If the caller has not provided
* an area, then we must obtain it from the system, using the cache
* savvy allocation routine.
*/
switch ((int) pDrvCtrl->pBdBase)
{
case NONE : /* we must obtain it */
/* this driver can't handle write incoherent caches */
if (!CACHE_DMA_IS_WRITE_COHERENT ())
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
"motFccInitMem: shared memory not cache coherent\n",
0,0,0,0,0,0);
return ERROR;
}
rbdMemSize = MOT_FCC_RBD_SZ * pDrvCtrl->rbdNum;
tbdMemSize = MOT_FCC_TBD_SZ * pDrvCtrl->tbdNum;
bdMemSize = rbdMemSize + tbdMemSize + MOT_FCC_BD_ALIGN;
pDrvCtrl->pBdBase = cacheDmaMalloc(bdMemSize);
if (pDrvCtrl->pBdBase == NULL)
{
/* no memory available */
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
"motFccInitMem: could not obtain memory\n",
0,0,0,0,0,0);
return ERROR;
}
pDrvCtrl->bdSize = bdMemSize;
MOT_FCC_FLAG_SET (MOT_FCC_OWN_BD_MEM);
pDrvCtrl->bdCacheFuncs = cacheDmaFuncs;
break;
default : /* the user provided an area */
if (!pDrvCtrl->bdSize)
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
"motFccInitMem: not enough memory\n",0,0,0,0,0,0);
return ERROR;
}
/*
* check whether user provided a number for Rx and Tx BDs
* fill in the blanks if we can.
* check whether enough memory was provided, etc.
*/
if (MOT_FCC_FLAG_ISSET (MOT_FCC_INV_TBD_NUM) &&
MOT_FCC_FLAG_ISSET (MOT_FCC_INV_RBD_NUM))
{
pDrvCtrl->tbdNum = pDrvCtrl->bdSize /
(MOT_FCC_TBD_SZ + MOT_FCC_RBD_SZ);
pDrvCtrl->rbdNum = pDrvCtrl->tbdNum;
}
else if (MOT_FCC_FLAG_ISSET (MOT_FCC_INV_TBD_NUM))
{
rbdMemSize = MOT_FCC_RBD_SZ * pDrvCtrl->rbdNum;
pDrvCtrl->tbdNum = (pDrvCtrl->bdSize - rbdMemSize) /
MOT_FCC_TBD_SZ;
}
else if (MOT_FCC_FLAG_ISSET (MOT_FCC_INV_RBD_NUM))
{
tbdMemSize = MOT_FCC_TBD_SZ * pDrvCtrl->tbdNum;
pDrvCtrl->rbdNum = (pDrvCtrl->bdSize - tbdMemSize) /
MOT_FCC_RBD_SZ;
}
else
{
rbdMemSize = MOT_FCC_RBD_SZ * pDrvCtrl->rbdNum;
tbdMemSize = MOT_FCC_TBD_SZ * pDrvCtrl->tbdNum;
bdMemSize = rbdMemSize + tbdMemSize + MOT_FCC_BD_ALIGN;
if (pDrvCtrl->bdSize < bdMemSize)
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
"motFccInitMem: not enough memory\n",
0,0,0,0,0,0);
return ERROR;
}
}
if ((pDrvCtrl->tbdNum < MOT_FCC_TBD_MIN) ||
(pDrvCtrl->rbdNum < MOT_FCC_RBD_MIN))
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
"motFccInitMem: not enough BDs\n",0,0,0,0,0,0);
return ERROR;
}
MOT_FCC_FLAG_CLEAR (MOT_FCC_OWN_BD_MEM);
pDrvCtrl->bdCacheFuncs = cacheNullFuncs;
break;
}
/* zero the shared memory */
memset (pDrvCtrl->pBdBase, 0, (int) pDrvCtrl->bdSize);
/* align the shared memory */
pDrvCtrl->pBdBase = (char *) ROUND_UP((UINT32)pDrvCtrl->pBdBase,
MOT_FCC_BD_ALIGN);
/*
* number of clusters, including loaning buffers, a min number
* of transmit clusters for copy-mode transmit, and one transmit
* cluster for polling operation.
*/
clNum = pDrvCtrl->rbdNum + MOT_FCC_BD_LOAN_NUM + MOT_FCC_TX_POLL_NUM +
MOT_FCC_TX_CL_NUM;
/* pool of mblks */
if (mclBlkConfig.mBlkNum == 0)
{
mclBlkConfig.mBlkNum = clNum * pDrvCtrl->mblkMult;
}
/* pool of clusters, including loaning buffers */
if (clDescTbl[0].clNum == 0)
{
clDescTbl[0].clNum = clNum * pDrvCtrl->clMult;
clDescTbl[0].clSize = MOT_FCC_MAX_CL_LEN;
}
/* there's a cluster overhead and an alignment issue */
clDescTbl[0].memSize = clDescTbl[0].clNum *
(clDescTbl[0].clSize + CL_OVERHEAD) +
CL_ALIGNMENT - 1;
/*
* Now we'll deal with the data buffers. If the caller has provided
* an area, then we assume it is non-cacheable and will not require
* the use of the special cache routines. If the caller has not provided
* an area, then we must obtain it from the system, but we will not be
* using the cache savvy allocation routine, since we will flushing or
* invalidate the data cache itself as appropriate. This speeds up
* driver operation, as the network stack will be able to process data
* in a cacheable area.
*/
switch ((int) pDrvCtrl->pBufBase)
{
case NONE : /* we must obtain it */
clDescTbl[0].memArea = (char *) memalign(CL_ALIGNMENT,
clDescTbl[0].memSize);
if (clDescTbl[0].memArea == NULL)
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
("motFccInitMem: could not obtain memory\n"),
0,0,0,0,0,0);
return ERROR;
}
/* store the pointer to the clBlock area and its size */
pDrvCtrl->pBufBase = clDescTbl[0].memArea;
pDrvCtrl->bufSize = clDescTbl[0].memSize;
MOT_FCC_FLAG_SET (MOT_FCC_OWN_BUF_MEM);
/* cache functions descriptor for data buffers */
motFccBufCacheFuncs.flushRtn = cacheArchFlush;
motFccBufCacheFuncs.invalidateRtn = cacheArchInvalidate;
motFccBufCacheFuncs.virtToPhysRtn = NULL;
motFccBufCacheFuncs.physToVirtRtn = NULL;
pDrvCtrl->bufCacheFuncs = motFccBufCacheFuncs;
break;
default : /* the user provided an area */
if (pDrvCtrl->bufSize == 0)
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
("motFccInitMem: not enough memory\n"),0,0,0,0,0,0);
return ERROR;
}
/*
* check the user provided enough memory with reference
* to the given number of receive/transmit frames, if any.
*/
if (pDrvCtrl->bufSize < clDescTbl[0].memSize)
{
MOT_FCC_LOG (MOT_FCC_DBG_LOAD,
("motFccInitMem: not enough memory\n"),0,0,0,0,0,0);
return ERROR;
}
/* Set memArea to the buffer base */
clDescTbl[0].memArea = pDrvCtrl->pBufBase;
MOT_FCC_FLAG_CLEAR (MOT_FCC_OWN_BUF_MEM);
pDrvCtrl->bufCacheFuncs = cacheNullFuncs;
break;
}
/* zero and align the shared memory */
memset (pDrvCtrl->pBufBase, 0, (int) pDrvCtrl->bufSize);
pDrvCtrl->pBufBase = (char *) ROUND_UP((UINT32)pDrvCtrl->pBufBase,
CL_ALIGNMENT);
/* pool of cluster blocks */
if (mclBlkConfig.clBlkNum == 0)
{
mclBlkConfig.clBlkNum = clDescTbl[0].clNum;
}
/* get memory for mblks */
if (mclBlkConfig.memArea == NULL)
{
/* memory size adjusted to hold the netPool pointer at the head */
mclBlkConfig.memSize = ((mclBlkConfig.mBlkNum *
(M_BLK_SZ + MBLK_ALIGNMENT)) +
(mclBlkConfig.clBlkNum *
(CL_BLK_SZ + CL_ALIGNMENT)));
mclBlkConfig.memArea = (char *) memalign (MBLK_ALIGNMENT,
mclBlkConfig.memSize);
if (mclBlkConfig.memArea == NULL)
{
return ERROR;
}
else
{
memset (mclBlkConfig.memArea, 0, (int)mclBlkConfig.memSize);
}
/* store the pointer to the mBlock area */
pDrvCtrl->pMBlkArea = mclBlkConfig.memArea;
pDrvCtrl->mBlkSize = mclBlkConfig.memSize;
}
/* init the mem pool */
if (netPoolInit (pDrvCtrl->endObj.pNetPool,
&mclBlkConfig, &clDescTbl[0], clDescTblNumEnt,
NULL) == ERROR)
{
return ERROR;
}
if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,
MOT_FCC_MAX_CL_LEN, FALSE)) == NULL)
{
return ERROR;
}
/* wait for 25% available before restart MUX */
pDrvCtrl->unStallThresh = (pDrvCtrl->tbdNum >> 2);
MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccInitMem...done\n"),
0, 0, 0, 0, 0, 0);
return OK;
}
/**************************************************************************
*
* motFccStart - start the device
*
* This routine starts the FCC device and brings it up to an operational
* state. The driver must have already been loaded with the motFccEndLoad()
* routine.
*
* INTERNAL
* The speed field in the phyInfo structure is only set after the call
* to the physical layer init routine. On the other hand, the mib2
* interface is initialized in the motFccEndLoad() routine, and the default
* value of 10Mbit assumed there is not always correct. We need to
* correct it here.
*
* RETURNS: OK, or ERROR if the device could not be started.
*
*/
LOCAL STATUS motFccStart
(
DRV_CTRL *pDrvCtrl
)
{
int retVal; /* convenient holder for return value */
char bucket[4]; /* holder for vxMemProbe */
MOT_FCC_LOG (MOT_FCC_DBG_START, "motFccStart...\n", 1, 2, 3, 4, 5, 6);
/* must have been loaded */
if (!pDrvCtrl->loaded)
return ERROR;
if (vxMemProbe ((char *) (pDrvCtrl->fccIramAddr),
VX_READ, 4, &bucket[0]) != OK)
{
MOT_FCC_LOG (MOT_FCC_DBG_START, "motFccStart: need MMU mapping for address 0x%x\n",
(UINT32) pDrvCtrl->fccIramAddr, 2, 3, 4, 5, 6);
return ERROR;
}
if (motFccTbdInit(pDrvCtrl) == ERROR || motFccRbdInit(pDrvCtrl) == ERROR)
return ERROR;
/* set some flags to default values */
pDrvCtrl->txStall = FALSE;
pDrvCtrl->tbdIndex = 0;
pDrvCtrl->usedTbdIndex = 0;
pDrvCtrl->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -