📄 m5200fecend.c
字号:
pDrvCtrl->RevD = 1; if (!pDrvCtrl->tbdNum || pDrvCtrl->tbdNum <= 2) { MOT_FEC_FLAG_SET (MOT_FEC_INV_TBD_NUM); pDrvCtrl->tbdNum = MOT_FEC_TBD_DEF_NUM; } if (!pDrvCtrl->rbdNum || pDrvCtrl->rbdNum <= 2) { MOT_FEC_FLAG_SET (MOT_FEC_INV_RBD_NUM); pDrvCtrl->rbdNum = MOT_FEC_RBD_DEF_NUM; } MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecEndParse: unit=%d MBARAddr=0x%x ilevel=0x%x bufBase=0x%x bufSize=0x%x \n"), pDrvCtrl->unit, (int) pDrvCtrl->MBARAddr, (int) pDrvCtrl->ilevel, pDrvCtrl->pBufBase, pDrvCtrl->bufSize, 0); MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecEndParse: fifoTxBase=0x%x fifoRxBase=0x%x tbdNum=%d rbdNum=%d flags=0x%x\n"), pDrvCtrl->fifoTxBase, pDrvCtrl->fifoRxBase, pDrvCtrl->tbdNum, pDrvCtrl->rbdNum, pDrvCtrl->userFlags, 0); MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecEndParse: phyAddr=0x%x isoPhyAddr=0x%x phyDefMode=0x%x \n"), pDrvCtrl->phyInfo->phyAddr, pDrvCtrl->phyInfo->isoPhyAddr, pDrvCtrl->phyInfo->phyDefMode, 0, 0, 0); return (OK); }/******************************************************************************** motFecInitMem - initialize memory** This routine initializes all the memory needed by the driver whose control* structure is passed in <pDrvCtrl>.** RETURNS: OK or ERROR*/LOCAL STATUS motFecInitMem ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { UINT32 bdSize; /* temporary size holder */ UINT32 clSize; /* temporary size holder */ UINT16 clNum; /* a buffer number holder */ M_CL_CONFIG mclBlkConfig = {0, 0, NULL, 0}; /* cluster blocks configuration */ CL_DESC clDescTbl [] = { {MOT_FEC_MAX_CL_LEN, 0, NULL, 0} }; /* cluster blocks config table */ int clDescTblNumEnt = (NELEMENTS (clDescTbl)); /* number of different clusters */ /* initialize the netPool */ if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL) return (ERROR); /* * we include here room for both TBDs and RBDs, * and the alignment factor. */ bdSize = MOT_FEC_BD_MEM (pDrvCtrl); pDrvCtrl->bufSize = bdSize; MOT_FEC_FLAG_SET (MOT_FEC_OWN_MEM); pDrvCtrl->bdCacheFuncs = cacheDmaFuncs; /* cache functions descriptor for data buffers */ motFecBufCacheFuncs.flushRtn = motFecBufFlushRtn; motFecBufCacheFuncs.invalidateRtn = motFecBufInvRtn; motFecBufCacheFuncs.virtToPhysRtn = NULL; motFecBufCacheFuncs.physToVirtRtn = NULL; pDrvCtrl->bufCacheFuncs = motFecBufCacheFuncs; /* * 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_FEC_BD_LOAN_NUM + 1 + MOT_FEC_TX_CL_NUM; clSize = (MOT_FEC_TX_MEM (pDrvCtrl) + MOT_FEC_RX_MEM (pDrvCtrl) + (CL_OVERHEAD * clNum) + MOT_FEC_BD_ALIGN); /* pool of mblks */ if (mclBlkConfig.mBlkNum == 0) mclBlkConfig.mBlkNum = clNum * 2; /* pool of clusters, including loaning buffers */ if (clDescTbl[0].clNum == 0) { clDescTbl[0].clNum = clNum; clDescTbl[0].clSize = MOT_FEC_MAX_CL_LEN; } /* there's a cluster overhead and an alignment issue */ clDescTbl[0].memSize = (clDescTbl[0].clNum * (clDescTbl[0].clSize + CL_OVERHEAD)); clDescTbl[0].memArea = (char *) (memalign (CL_ALIGNMENT, clSize)); if (clDescTbl[0].memArea == NULL) { return (ERROR); } /* store the pointer to the clBlock area */ pDrvCtrl->pClBlkArea = clDescTbl[0].memArea; pDrvCtrl->clBlkSize = clDescTbl[0].memSize; /* 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_FEC_MAX_CL_LEN, FALSE)) == NULL) { return (ERROR); } MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecInitMem... Done\n"), 0, 0, 0, 0, 0, 0); return OK; }/**************************************************************************** motFecStart - start the device** This routine starts the FEC device and brings it up to an operational* state. The driver must have already been loaded with the m5200FecEndLoad()* routine.** RETURNS: OK, or ERROR if the device could not be initialized.** 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 m5200FecEndLoad() routine, and the default* value of 10Mbit assumed there is not always correct. We need to* correct it here.**/LOCAL STATUS motFecStart ( DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */ ) { int retVal; /* convenient holder for return value */ char bucket[4]; MOT_FEC_LOG (MOT_FEC_DBG_START, ("Starting end...\n"), 1, 2, 3, 4, 5, 6); /* must have been loaded */ if (!pDrvCtrl->loaded) return (ERROR); if (vxMemProbe ((char *) (pDrvCtrl->MBARAddr + MOT_FEC_CSR_OFF), VX_READ, 4, &bucket[0]) != OK) { MOT_FEC_LOG (MOT_FEC_DBG_START, (": need MMU mapping for address 0x%x\n"), (UINT32) pDrvCtrl->MBARAddr, 2, 3, 4, 5, 6); return (ERROR); } if (motFecTbdInit (pDrvCtrl) == ERROR) return (ERROR); if (motFecRbdInit (pDrvCtrl) == ERROR) return (ERROR); /* reset the chip */ if (motFecReset (pDrvCtrl) != OK) return (ERROR); /* set some flags to default values */ pDrvCtrl->txStall = FALSE; pDrvCtrl->tbdIndex = 0; pDrvCtrl->usedTbdIndex = 0; pDrvCtrl->cleanTbdNum = pDrvCtrl->tbdNum; pDrvCtrl->rbdIndex = 0; /* connect the interrupt handler */ SYS_FEC_INT_CONNECT (pDrvCtrl, motFecInt, (int) pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); intConnect (IV_SDMA_TASK2, sdmaFecTransInt, (int) pDrvCtrl); intConnect (IV_SDMA_TASK3, sdmaFecRecInt, (int) pDrvCtrl); /* enable system interrupt: set relevant bit in SIMASK */ SYS_FEC_INT_ENABLE (pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* configure some chip's registers */ if (motFecPrePhyConfig (pDrvCtrl) == ERROR) return (ERROR); /* initialize some fields in the PHY info structure */ if (motFecPhyPreInit (pDrvCtrl) != OK) { MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("Failed to pre-initialize the PHY\n"), 0, 0, 0, 0, 0, 0); return (ERROR); } /* ^ phyFlags = 0x3d1 * MOT_FEC_PHY_PRE_INIT | MOT_FEC_PHY_AUTO | MOT_FEC_PHY_100 | MOT_FEC_PHY_10 | MOT_FEC_PHY_FD | MOT_FEC_PHY_HD */ #if 0 /* 无用的代码 */ if (motFecMiiWrite (pDrvCtrl, 0, MII_CTRL_REG, MII_CR_AUTO_EN | MII_CR_FDX) != OK) return (ERROR); #endif /* initialize the Physical medium layer */ if (_func_motFecPhyInit == NULL) return (ERROR); /* 调用motFecPhyInit */ if (((* _func_motFecPhyInit) (pDrvCtrl)) != OK) { MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("Failed to initialize the PHY\n"), 0, 0, 0, 0, 0, 0); return (ERROR); } /* configure other chip's registers */ if (motFecPostPhyConfig (pDrvCtrl) == ERROR) return (ERROR); /* * Set priority of different initiators */ * BESTCOMM_IPR0 = 0x07000006; * BESTCOMM_IPR4 = 0x05000000; /* correct the speed for the mib2 stuff */ pDrvCtrl->endObj.mib2Tbl.ifSpeed = pDrvCtrl->phyInfo->phySpeed; if (END_FLAGS_ISSET (IFF_MULTICAST)) MOT_FEC_FLAG_SET (MOT_FEC_MCAST); /* * Clear SmartDMA task interrupt pending bits. */ TaskIntClear( rxTaskId ); /* mark the interface as up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("pDrvCtrl: tbdBase= 0x%x rbdBase= 0x%x \n "), pDrvCtrl->tbdBase, pDrvCtrl->rbdBase, 3, 4, 5, 6); /* enable the Ethernet Controller */ MOT_FEC_ETH_ENABLE; /* * Enable the SmartDMA receive task. */ TaskStart( rxTaskId, 1, rxTaskId, 1 ); TaskStart( txTaskId, 1, txTaskId, 1 ); /* startup the receiver */ MOT_FEC_RX_ACTIVATE; MOT_FEC_TX_ACTIVATE; /* Flush the write pipe */ MOT_FEC_LOG (MOT_FEC_DBG_START, ("Starting end... Done\n"), 1, 2, 3, 4, 5, 6); return (OK); }/**************************************************************************** motFecStop - stop the 'motfec' 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, motFecStart() must be called.** RETURNS: OK, always.*/LOCAL STATUS motFecStop ( DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */ ) { int retVal; /* convenient holder for return value */ UINT32 status = 0; MOT_FEC_LOG (MOT_FEC_DBG_LOAD, ("motFecStop...\n"), 1, 2, 3, 4, 5, 6); /* mark the interface as down */ END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* issue a graceful transmit command */ MOT_FEC_CSR_RD (MOT_FEC_TX_CTRL_OFF, status); MOT_FEC_CSR_WR (MOT_FEC_TX_CTRL_OFF, status | MOT_FEC_TX_CTRL_GRA); /* wait for the related interrupt */ MOT_FEC_GRA_SEM_TAKE; /* mask chip interrupts */ MOT_FEC_INT_DISABLE; /* disable system interrupt: reset relevant bit in SIMASK */ SYS_FEC_INT_DISABLE (pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* disconnect the interrupt handler */ SYS_FEC_INT_DISCONNECT (pDrvCtrl, motFecInt, (int)pDrvCtrl, retVal); if (retVal == ERROR) return (ERROR); /* * Disable the SmartDMA transmit and receive tasks. */ TaskStop( rxTaskId ); TaskStop( txTaskId ); /* * Disable transmit / receive interrupts */ intDisable(INUM_SDMA_TASK2); intDisable(INUM_SDMA_TASK3); /* disable the Ethernet Controller */ MOT_FEC_ETH_DISABLE; if (motFecBdFree (pDrvCtrl) != OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -