📄 m8260fccend.c
字号:
*/
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;
}
/* 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;
}
pDrvCtrl->unStallThresh = (pDrvCtrl->tbdNum >> 2); /* wait for 25% available before restart MUX */
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 inthe 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, "Starting end...\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, ": 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->cleanTbdNum = pDrvCtrl->tbdNum;
pDrvCtrl->rbdIndex = 0;
/* acknowledge system interrupt */
SYS_FCC_INT_ACK (pDrvCtrl, retVal);
if (retVal == ERROR)
return ERROR;
/* connect the interrupt handler */
SYS_FCC_INT_CONNECT (pDrvCtrl, motFccInt, (int) pDrvCtrl, retVal);
if (retVal == ERROR)
return ERROR;
/* enable system interrupt: set relevant bit in SIMNR_L */
SYS_FCC_INT_ENABLE (pDrvCtrl, retVal);
if (retVal == ERROR)
return ERROR;
/* call the BSP to do any other initialization (MII interface) */
SYS_FCC_ENET_ENABLE;
/* initialize some fields in the PHY info structure */
if (motFccPhyPreInit (pDrvCtrl) != OK) {
MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("Failed to pre-initialize the PHY\n"), 0, 0, 0, 0, 0, 0);
return ERROR;
}
/* initialize the Physical medium layer */
if (_func_motFccPhyInit == NULL)
return ERROR;
if (((* _func_motFccPhyInit) (pDrvCtrl->phyInfo)) != OK) {
MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("Failed to initialize the PHY\n"), 0, 0, 0, 0, 0, 0);
return ERROR;
}
/* initialize the chip */
if (motFccInit (pDrvCtrl) == ERROR)
return ERROR;
/* correct the speed for the mib2 stuff */
pDrvCtrl->endObj.mib2Tbl.ifSpeed = pDrvCtrl->phyInfo->phySpeed;
/* startup the transmitter */
pDrvCtrl->fccReg->fcc_gmr |= M8260_GFMR_ENT;
/* mark the interface as up */
END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
/* startup the receiver */
MOT_FCC_RX_ACTIVATE;
/* Flush the write pipe */
CACHE_PIPE_FLUSH ();
MOT_FCC_LOG (MOT_FCC_DBG_START, ("Starting end... Done\n"), 1, 2, 3, 4, 5, 6);
return OK;
}
/**************************************************************************
*
* motFccStop - stop the 'motfcc' interface
*
* This routine marks the interface as inactive, disables interrupts and
* the Ethernet Controller. As a result, reception is stopped immediately,
* and transmission is stopped after a bad CRC is appended to any frame
* currently being transmitted. The reception/transmission control logic
* (FIFO pointers, buffer descriptors, etc.) is reset. To bring the
* interface back up, motFccStart() must be called.
*
* RETURNS: OK, always.
*/
LOCAL STATUS motFccStop(DRV_CTRL *pDrvCtrl)
{
int retVal; /* convenient holder for return value */
UINT8 command = 0; /* command to issue to the CP */
MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccStop...\n"), 1, 2, 3, 4, 5, 6);
/* mark the interface as down */
END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
/* issue a graceful stop transmit command to the CP */
command = M8260_CPCR_TX_GRSTOP;
if (motFccCpcrCommand (pDrvCtrl, command) == ERROR)
return ERROR;
/* wait for the related interrupt */
MOT_FCC_GRA_SEM_TAKE;
/* mask chip interrupts */
MOT_FCC_INT_DISABLE;
/* disable system interrupt: reset relevant bit in SIMNR_L */
SYS_FCC_INT_DISABLE (pDrvCtrl, retVal);
if (retVal == ERROR)
return ERROR;
/* disconnect the interrupt handler */
SYS_FCC_INT_DISCONNECT (pDrvCtrl, motFccInt, (int)pDrvCtrl, retVal);
if (retVal == ERROR)
return ERROR;
/* call the BSP to disable the MII interface */
SYS_FCC_ENET_DISABLE;
/* free buffer descriptors */
if (motFccBdFree (pDrvCtrl) != OK)
return ERROR;
MOT_FCC_LOG (MOT_FCC_DBG_LOAD, ("motFccStop... Done \n"), 1, 2, 3, 4, 5, 6);
return OK;
}
/*******************************************************************************
*
* motFccSendDummyFrame - send a dummy ethernet packet out for ARP
*
* This routine is run in netTask's context.
*
* RETURNS: N/A
*/
LOCAL void motFccSendDummyFrame(DRV_CTRL *pDrvCtrl)
{
int intLevel; /* current intr level */
int len; /* length of data to be sent */
char *pBuf; /* pointer to data to be sent */
FCC_BD *pTbd; /* pointer to the current ready TBD */
FCC_TBD_LIST *pTbdList; /* pointer to the TBD list*/
END_TX_SEM_TAKE(&pDrvCtrl->endObj, WAIT_FOREVER);
pTbd = &pDrvCtrl->tbdBase[pDrvCtrl->tbdIndex];
pTbdList = &pDrvCtrl->pTbdList[pDrvCtrl->tbdIndex];
pBuf = pDrvCtrl->pTxPollBuf;
memset(pBuf,0xff,6);
bcopy((char *)MOT_FCC_ADDR_GET(&pDrvCtrl->endObj),pBuf+6,6);
len = 100;
MOT_FCC_CACHE_FLUSH(pBuf,len); /* flush the cache, if necessary */
pTbd->bdLen = len;
pTbd->bdAddr = (unsigned long)pBuf;
pTbdList->pBuf = NULL; /* not a Cluster pointer */
pTbdList->info = 0; /* so we know NOT to free in ISR */
intLevel = intLock();
pDrvCtrl->cleanTbdNum -= 1; /* keep accurate count of clean BDs */
if (pDrvCtrl->tbdIndex == (pDrvCtrl->tbdNum - 1)){
pTbd->word1 =
( M8260_FETH_TBD_R
| M8260_FETH_TBD_L
| M8260_FETH_TBD_TC
| M8260_FETH_TBD_I
| M8260_FETH_TBD_W
| M8260_FETH_TBD_PAD
);
}else{
pTbd->word1 =
( M8260_FETH_TBD_R
| M8260_FETH_TBD_L
| M8260_FETH_TBD_TC
| M8260_FETH_TBD_I
| M8260_FETH_TBD_PAD
);
}
/* move on to the next element */
pDrvCtrl->tbdIndex = (pDrvCtrl->tbdIndex + 1) % pDrvCtrl->tbdNum;
intUnlock (intLevel);
END_TX_SEM_GIVE(&pDrvCtrl->endObj);
}
/*******************************************************************************
*
* motFccHandleLSCJob - task-level link status event processor
*
* This routine is run in netTask's context.
*
* RETURNS: N/A
*/
LOCAL void motFccHandleLSCJob(DRV_CTRL *pDrvCtrl)
{
int intLevel; /* current intr level */
UINT16 miiStat;
int retVal,duplex;
UINT32 fccIramAddr,fpsmrVal;
fccIramAddr = pDrvCtrl->fccIramAddr;
MOT_FCC_LOG (MOT_FCC_DBG_ANY, "motFccHandleLSCJob: \n", 0, 0, 0, 0, 0, 0);
++pDrvCtrl->Stats->numLSCHandlerEntries;
/* read MII status register once to unlatch link status bit */
retVal = motFccMiiRead(pDrvCtrl,pDrvCtrl->phyInfo->phyAddr,1,&miiStat);
/* read again to know it's current value */
retVal = motFccMiiRead(pDrvCtrl,pDrvCtrl->phyInfo->phyAddr,1,&miiStat);
if(miiStat & 4){ /* if link is now up */
if(_func_motFccPhyDuplex){
/* get duplex mode from BSP */
retVal = (* _func_motFccPhyDuplex)(pDrvCtrl->phyInfo,&duplex);
if(retVal == OK){
intLevel = int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -