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

📄 ibmemacend.c

📁 WINDRIVER SBC405 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
     * MAL this EMAC is attached to.     */    tok = strtok_r (NULL, ":", ppHolder);    if (tok == NULL)        return ERROR;    pDrvCtrl->pMalData = (MAL_DATA *)strtoul (tok, NULL, 16);    /*     * Fourteenth parameter is the OPB bus speed in MHz.     */    tok = strtok_r (NULL, ":", ppHolder);    if (tok == NULL)        return ERROR;    pDrvCtrl->opbSpeedMhz = atoi (tok);    return OK;    }/********************************************************************************* ibmEmacMemInit - initialize memory required for the driver** Using data in the control structure (some of which came from the* initialization string), setup and initialize the memory regions as needed.** RETURNS: OK or ERROR.*/LOCAL STATUS ibmEmacMemInit    (    EMAC_DRV_CTRL * pDrvCtrl    )    {    UINT32      tempSize;    int         i, j;    MAL_BD *    pTempDesc;    char *      pTempBuf;    /*     * If a memory region was specified in the initialization string, determine     * if it is large enough to hold the minimum number of buffers (clusters).     * It is assumed that this memory is not cached.  Descriptor memory has     * already been allocated by malLib.     */    if ((int)pDrvCtrl->memInputAdrs != NONE)        {        pDrvCtrl->memAdrs = pDrvCtrl->memInputAdrs;        pDrvCtrl->memSize = pDrvCtrl->memInputSize;        /* If not properly aligned, align it */        while ((int)pDrvCtrl->memAdrs & (pDrvCtrl->cacheLineSize - 1))            {            pDrvCtrl->memAdrs++;            pDrvCtrl->memSize--;            }        /* initialize the space */        bzero((char *)pDrvCtrl->memAdrs, pDrvCtrl->memSize);        if (pDrvCtrl->memSize > EMAC_MIN_MEM_SIZE)            {            /*             * Determine the number of buffers this region can hold, and             * determine the numbers of descriptors needed for both TX and             * RX.             */            tempSize = pDrvCtrl->memSize;            if (tempSize > EMAC_MAX_MEM_SIZE)                tempSize = EMAC_MAX_MEM_SIZE;            /*             * Give half of the descriptors to the RX channel, the rest to the             * TX channel(s).             */            tempSize = tempSize / EMAC_BSC_MEM_SIZE;            pDrvCtrl->numRxD = tempSize / 2;            if (pDrvCtrl->inputFlags & EMAC_INPUT_TX_2_CHANNEL)                {                pDrvCtrl->txInfo[0].numTxD = (tempSize - pDrvCtrl->numRxD) / 2;                pDrvCtrl->txInfo[1].numTxD = pDrvCtrl->txInfo[0].numTxD;                }            else                {                pDrvCtrl->txInfo[0].numTxD = tempSize - pDrvCtrl->numRxD;                }            /* Assume the memory is cache safe, copy null structure */            pDrvCtrl->cacheFuncs = cacheNullFuncs;            }        else            {            printf("MemSize specified in the ibmEmacEnd load string is not\n");            printf("large enough.  It must be at least %d bytes.\n",                                                        EMAC_MIN_MEM_SIZE);            }        }    /*     * If a memory region was not specified in the load string, allocate one     * (default size).  Buffer memory does NOT have to be cache safe (i.e.     * uncached)  If buffer memory is cached, this driver will manage cache     * coherency.     */    if ((int)pDrvCtrl->memInputAdrs == NONE)        {        /*         * Allocate the default sized chunk of memory to hold buffers.         * The inputFlags parameter that was passed into the load string         * indicates whether the buffers should be allocated from cached         * or cache safe memory.         * Add the size of a cache line because it may have to be         * adjusted for proper cache line alignment.         */        pDrvCtrl->memSizeMalloc = EMAC_DFT_MEM_SIZE + pDrvCtrl->cacheLineSize;        if (pDrvCtrl->inputFlags & EMAC_INPUT_UNCACHED_BUF)            {            /* Allocate cache safe (uncached) memory for buffers */            pDrvCtrl->memAdrsMalloc = cacheDmaMalloc(pDrvCtrl->memSizeMalloc);            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            }        else            {            /*             * Allocate cached memory for buffers             * Specify the flush and invalidate functions needed to maintain             * data cache coherency.             */            pDrvCtrl->memAdrsMalloc = malloc(pDrvCtrl->memSizeMalloc);            pDrvCtrl->cacheFuncs.flushRtn = cacheFlush;            pDrvCtrl->cacheFuncs.invalidateRtn = cacheInvalidate;            }        if (pDrvCtrl->memAdrsMalloc == NULL)            {            printf("Could not allocate memory for ibmEmacEnd\n");            return(ERROR);            }        /* Initialize region to zeros */        bzero((char *)pDrvCtrl->memAdrsMalloc, pDrvCtrl->memSizeMalloc);        /* Adjust the alignment. Put on a cache line boundary */        pDrvCtrl->memAdrs = pDrvCtrl->memAdrsMalloc;        pDrvCtrl->memSize = pDrvCtrl->memSizeMalloc;        while ((int)pDrvCtrl->memAdrs & (pDrvCtrl->cacheLineSize - 1))            {            pDrvCtrl->memAdrs++;	    pDrvCtrl->memSize--;            }        DRV_LOG (DRV_DEBUG_INFO, "Buffer space = 0x%x size = 0x%x\n",                                        pDrvCtrl->memAdrs,                                        pDrvCtrl->memSize, 3, 4, 5, 6);        pDrvCtrl->numRxD = EMAC_RXD_DFT;        /*         * Depending on how many TX channels are being used, TX channel 0 gets         * all of the allotted TX descriptors, or half.  TX channel 1 gets what         * is left.         */        pDrvCtrl->txInfo[0].numTxD = EMAC_TXD_DFT / pDrvCtrl->numTxChannels;        pDrvCtrl->txInfo[1].numTxD = EMAC_TXD_DFT - pDrvCtrl->txInfo[0].numTxD;        }    /* Get the address of the TX descriptor tables */    malChannelDescTblPtrGet(pDrvCtrl->pMalData, MAL_TX_TYPE,                            pDrvCtrl->txChn0MalChannel,                            &pDrvCtrl->txInfo[0].pTxDesc);    DRV_LOG (DRV_DEBUG_INFO, "TX 0 Desc Ring 0x%x\n",                                    pDrvCtrl->txInfo[0].pTxDesc, 2, 3, 4, 5, 6);    malChannelDescTblPtrGet(pDrvCtrl->pMalData, MAL_TX_TYPE,                            pDrvCtrl->txChn1MalChannel,                            &pDrvCtrl->txInfo[1].pTxDesc);    DRV_LOG (DRV_DEBUG_INFO, "TX 1 Desc Ring 0x%x\n",                                    pDrvCtrl->txInfo[1].pTxDesc, 2, 3, 4, 5, 6);    /*     * Initialize the arrays that will be used by SendCleanup to free clusters     * or mBlks after a packet has been transmitted.     */    for (i = 0; i < pDrvCtrl->numTxChannels; i++)        {        for (j = 0; j < pDrvCtrl->txInfo[i].numTxD; j++)            {            pDrvCtrl->txInfo[i].txFree[j].typeFree = EMAC_TX_FREE_NONE;            pDrvCtrl->txInfo[i].txFree[j].pFree = NULL;            }        }    /*     * Allocate memory for a net pool structure, and initialize it.     * There will be one cluster for each descriptor, one cluster block     * for each cluster, and two mBlks for each cluster block.     */    pDrvCtrl->end.pNetPool = malloc(sizeof(NET_POOL));    if (pDrvCtrl->end.pNetPool == NULL)        return (ERROR);    pDrvCtrl->clDesc.clNum    = (pDrvCtrl->numRxD * EMAC_RXD_LOAN_X)                                + pDrvCtrl->txInfo[0].numTxD                                + pDrvCtrl->txInfo[1].numTxD;    pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum;    pDrvCtrl->mClCfg.mBlkNum  = pDrvCtrl->mClCfg.clBlkNum * 2;    /* Determine the memory required to hold all mBlks and clBlks */    pDrvCtrl->mClCfg.memSize =                    (pDrvCtrl->mClCfg.mBlkNum * (M_BLK_SZ + sizeof (long))) +                    (pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long)));    /* Allocate memory to hold the mBlk and clBlk structures*/    pDrvCtrl->mClCfg.memArea = memalign(sizeof(long), pDrvCtrl->mClCfg.memSize);    if (pDrvCtrl->mClCfg.memArea == NULL)        return (ERROR);    DRV_LOG (DRV_DEBUG_INFO, "mBlk clBlk storage = 0x%x size = 0x%x\n",                                                   pDrvCtrl->mClCfg.memArea,                                                   pDrvCtrl->mClCfg.memSize,                                                   3, 4, 5, 6);    /*     * Finally determine the memory required to hold all of the clusters.     * The size of a cluster MUST be an even multiple of the cache line size.     * Memory for the clusters was allocated above.     */    pDrvCtrl->clDesc.clSize  = EMAC_BUF_SIZE;    pDrvCtrl->clDesc.memSize = pDrvCtrl->clDesc.clNum *                               (pDrvCtrl->clDesc.clSize + sizeof(long));    pDrvCtrl->clDesc.memArea = (char *)pDrvCtrl->memAdrs;    /* Initialize the net pool */    if (netPoolInit (pDrvCtrl->end.pNetPool, &pDrvCtrl->mClCfg,                     &pDrvCtrl->clDesc, 1, NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_ERROR, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return (ERROR);        }    /* Get and save the net cluster pool id */    pDrvCtrl->pClPoolId = clPoolIdGet(pDrvCtrl->end.pNetPool,                                               EMAC_BUF_SIZE, FALSE);    /*     * Get the address of the RX channel descriptor table.     * Go ahead and get a cluster from the pool for each of the RX descriptors.     * Assign each of the clusters to one of the RX descriptors.     * This is done to make the driver almost ready to receive packets.     */    malChannelDescTblPtrGet(pDrvCtrl->pMalData, MAL_RX_TYPE,                            pDrvCtrl->rxChn0MalChannel,                            &pDrvCtrl->pRxDesc);    DRV_LOG (DRV_DEBUG_INFO, "RX Desc Ring 0x%x\n",                                        pDrvCtrl->pRxDesc, 2, 3, 4, 5, 6);    pTempDesc = pDrvCtrl->pRxDesc;    for (i = 0; i < pDrvCtrl->numRxD; i++)        {        pTempBuf = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);        if (pTempBuf == NULL)            {            DRV_LOG (DRV_DEBUG_LOAD, "Get RX cluster from pool failed\n",                     1, 2, 3, 4, 5, 6);            return (ERROR);            }        /* Put the cluster address in the buffer addr field of the descriptor */        pTempDesc[i].bufferAdrs = pTempBuf;        }    return OK;    }/********************************************************************************* ibmEmacStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR*/LOCAL STATUS ibmEmacStart    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    int     rc;    DRV_LOG (DRV_DEBUG_START, "ibmEmacStart \n", 1, 2, 3, 4, 5, 6);    pDrvCtrl->localFlags &= ~EMAC_TX_CLEAN_RUNNING;    pDrvCtrl->localFlags &= ~EMAC_TX_BLOCKED;    /*     * Connect, clear status, then enable the Ethernet interrupt.     * This interrupt is primarily for error conditions.     * MAL handles interrupts for TX/RX end-of-buffer, and descriptor errors.     */    EMAC_INT_CONNECT (pDrvCtrl, ibmEmacInt, pDrvCtrl, &rc);    EMAC_REG_WRITE(pDrvCtrl, EMAC_ISR, 0xFFFFFFFF);    EMAC_INT_ENABLE (pDrvCtrl);    /* Allow MAL EOB and Descriptor error interrupts */    malChannelIntMaskSet(pDrvCtrl->pMalData, MAL_TX_TYPE,                         pDrvCtrl->txChn0MalChannel,                         MAL_EOB_INT_EN | MAL_DE_INT_EN | MAL_SERR_INT_EN);    if (pDrvCtrl->inputFlags & EMAC_INPUT_TX_2_CHANNEL)        malChannelIntMaskSet(pDrvCtrl->pMalData, MAL_TX_TYPE,                             pDrvCtrl->txChn1MalChannel,                             MAL_EOB_INT_EN | MAL_DE_INT_EN | MAL_SERR_INT_EN);    malChannelIntMaskSet(pDrvCtrl->pMalData, MAL_RX_TYPE,                         pDrvCtrl->rxChn0MalChannel,                         MAL_EOB_INT_EN | MAL_DE_INT_EN | MAL_SERR_INT_EN);    DRV_LOG (DRV_DEBUG_START, "TX and RX channels active.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* ibmEmacInt - handle EMAC controller interrupt** This routine is called at interrupt level in response to an interrupt from* the EMAC controller.  The interrupt occurs because of TX or RX error* conditions.**/LOCAL void ibmEmacInt    (    EMAC_DRV_CTRL *   pDrvCtrl    )    {    UINT isrReg;    UINT isrClear;    /* Read the EMAC interrupt status register */    EMAC_REG_READ(pDrvCtrl, EMAC_ISR, isrReg);    pDrvCtrl->errorEmac = isrReg;    DRV_LOG (DRV_DEBUG_ENET_INT, "EMAC Ethernet int 0x%x\n",                                                       isrReg, 2, 3, 4, 5, 6);    /*     * Check to see if there was a TX error.  If there was, the Dead bit     * will be set. Clear the status bits for the TX error, and clear the     * dead bit.  Keep count of these errors in the main device structure.     *     * Note that non-zero values of EMAC_ISR_TX_INTS are used primarily     * for debugging.  When EMAC_ISR_TX_INTS is zero, some compilers     * may warn about an always-false conditional expression.     */    if (isrReg & EMAC_ISR_TX_INTS)        {        pDrvCtrl->intErrorTX++;        if (pDrvCtrl->inputFlags & EMAC_INPUT_TX_2_CHANNEL)            isrClear = EMAC_ISR_TX_INTS | EMAC_ISR_DB0 | EMAC_ISR_DB1;

⌨️ 快捷键说明

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