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

📄 ln97xend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Add it all up */    sz = (((1 << lnRsize) + 1) * RMD_SIZ) +         (((1 << lnTsize) + 1) * TMD_SIZ) + IB_SIZ + 0x10;    /***** Establish a region of shared memory *****/    /* OK. We now know how much shared memory we need.  If the caller     * provides a specific memory region, we check to see if the provided     * region is large enough for our needs.  If the caller did not     * provide a specific region, then we attempt to allocate the memory     * from the system, using the cache aware allocation system call.     */    switch ((int) pDrvCtrl->memAdrs)	{	default :       /* caller provided memory */	    if (pDrvCtrl->memSize < sz)     /* not enough space */		{		DRV_LOG (DRV_DEBUG_LOAD, "ln97x: not enough memory provided\n"			 "ln97x: need %ul got %d\n",			 sz, pDrvCtrl->memSize, 3, 4, 5, 6);		return (ERROR);                }	    /* set the beginning of pool */	    pDrvCtrl->pShMem = pDrvCtrl->memAdrs;	    /* assume pool is cache coherent, copy null structure */	    pDrvCtrl->cacheFuncs = cacheNullFuncs;	    DRV_LOG (DRV_DEBUG_LOAD, "Memory checks out\n", 1, 2, 3, 4, 5, 6);	    break;        case NONE :     /* get our own memory */	    /* Because the structures that are shared between the device	     * and the driver may share cache lines, the possibility exists	     * that the driver could flush a cache line for a structure and	     * wipe out an asynchronous change by the device to a neighboring	     * structure. Therefore, this driver cannot operate with memory	     * that is not write coherent.  We check for the availability of	     * such memory here, and abort if the system did not give us what	     * we need.	     */	    if (!CACHE_DMA_IS_WRITE_COHERENT ())		{		printf ( "ln97x: device requires cache coherent memory\n" );		return (ERROR);		}	    pDrvCtrl->pShMem = (char *) cacheDmaMalloc (sz);	    if (pDrvCtrl->pShMem == NULL)		{		printf ( "ln97x: system memory unavailable\n" );		return (ERROR);		}	    /* copy the DMA structure */	    pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        }    /*                        Turkey Carving     *                        --------------     *     *                          LOW MEMORY     *     *             |-------------------------------------|     *             |       The initialization block      |     *             |         (sizeof (LN_IB))            |     *             |-------------------------------------|     *             |         The Rx descriptors          |     *             | (1 << lnRsize) * sizeof (LN_RMD)    |     *             |-------------------------------------|     *             |         The Tx descriptors          |     *             | (1 << lnTsize) * sizeof (LN_TMD)    |     *             |-------------------------------------|     */    /* Save some things */    pDrvCtrl->memBase  = (char *)((UINT32)pDrvCtrl->pShMem & 0xff000000);    if ((int) pDrvCtrl->memAdrs == NONE)        pDrvCtrl->flags |= LS_MEM_ALLOC_FLAG;    /* first let's clear memory */    bzero ( (char *) pDrvCtrl->pShMem, (int) sz );    /* setup Rx memory pointers */    pDrvCtrl->pRring    = (LN_RMD *) ((int)pDrvCtrl->pShMem + IB_SIZ);    pDrvCtrl->rringLen  = lnRsize;    pDrvCtrl->rringSize = 1 << lnRsize;    pDrvCtrl->rmdIndex  = 0;    /* setup Tx memory pointers. */    /* Note: +2 is to round up to alignment. */    pDrvCtrl->pTring = (LN_TMD *) (int)(pDrvCtrl->pShMem + IB_SIZ +                        ((1 << lnRsize) + 1) * RMD_SIZ + 0xf);    pDrvCtrl->pTring = (LN_TMD *) (((int)pDrvCtrl->pTring + 0xf) & ~0xf);    pDrvCtrl->tringSize = 1 << lnTsize;    pDrvCtrl->tringLen  = lnTsize;    pDrvCtrl->tmdIndex  = 0;    pDrvCtrl->tmdIndexC = 0;    /* allocate pool structure for mblks, clBlk, and clusters */    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)	return (ERROR);#ifdef DRV_DEBUG    pLan97xNetPool = pDrvCtrl->endObj.pNetPool;#endif        pDrvCtrl->clDesc.clNum    = pDrvCtrl->rringSize * 2;    pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum;    pDrvCtrl->mClCfg.mBlkNum  = pDrvCtrl->mClCfg.clBlkNum * 2;    /* total memory size for mBlks and clBlks */        pDrvCtrl->mClCfg.memSize =        (pDrvCtrl->mClCfg.mBlkNum  *  (MSIZE + sizeof (long))) +        (pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long)));    /* total memory for mBlks and clBlks */    if ((pDrvCtrl->mClCfg.memArea =         (char *) memalign (sizeof(long), pDrvCtrl->mClCfg.memSize)) == NULL)        return (ERROR);    /* total memory size for all clusters */    pDrvCtrl->clDesc.clSize  = LN_BUFSIZ;    pDrvCtrl->clDesc.memSize =        (pDrvCtrl->clDesc.clNum * (pDrvCtrl->clDesc.clSize + 8)) + sizeof(int);    /* Do we hand over our own memory? */    if (pDrvCtrl->memAdrs != (char *)NONE)        {        pDrvCtrl->clDesc.memArea =            (char *)(pDrvCtrl->pTring + pDrvCtrl->tringSize);        }    else        {        pDrvCtrl->clDesc.memArea = cacheDmaMalloc (pDrvCtrl->clDesc.memSize);                    if (pDrvCtrl->clDesc.memArea == NULL)            {            DRV_LOG(DRV_DEBUG_LOAD,                    "system memory unavailable\n", 1, 2, 3, 4, 5, 6);            return (ERROR);            }        }    /* initialize the device net pool */        if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->mClCfg,                     &pDrvCtrl->clDesc, 1, NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return (ERROR);        }        /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,                                       LN_BUFSIZ, FALSE);    /* Longword align rmd ring */    pDrvCtrl->pRring = (LN_RMD *) (((int)pDrvCtrl->pRring + 0xf) & ~0xf);    pDrvCtrl->pRring = (LN_RMD *) (((int)pDrvCtrl->pRring + 0xf) & ~0xf);    pRmd = pDrvCtrl->pRring;    DRV_LOG (DRV_DEBUG_LOAD, "Using %d RX buffers from 0x%X\n",             pDrvCtrl->rringSize, (int)pRmd, 3, 4, 5, 6);    for (ix = 0; ix < pDrvCtrl->rringSize; ix++, pRmd++)        {        if ((pTempBuf = (char *)netClusterGet (pDrvCtrl->endObj.pNetPool,                                               pDrvCtrl->pClPoolId)) == NULL)            {            DRV_LOG (DRV_DEBUG_LOAD, "Could not get a buffer\n",                     1, 2, 3, 4, 5, 6);            return (ERROR);            }        pTempBuf += pDrvCtrl->offset;        LN_RMD_BUF_TO_ADDR (pRmd, pTemp, pTempBuf);        }    return OK;    }/********************************************************************************* ln97xStart - 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 ln97xStart    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    STATUS 		result;    pDrvCtrl->txCleaning = FALSE;    pDrvCtrl->txBlocked  = FALSE;    SYS_INT_CONNECT (pDrvCtrl, ln97xInt, (int)pDrvCtrl, &result);    if (result == ERROR)        return ERROR;    /* mark the interface as up */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    SYS_INT_ENABLE ();    DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* ln97xHandleError - handle controller interrupt errors** This routine is called to process controller errors at a task level that * were detecected in interrupt context.** RETURNS: N/A.*/LOCAL void ln97xHandleError    (    LN_97X_DRV_CTRL  *pDrvCtrl    )    {    u_short stat;    pDrvCtrl->errorHandling = FALSE;    stat = pDrvCtrl->errorStat;    pDrvCtrl->errorStat &= ~stat;        if (stat & CSR0_MERR)        {        pDrvCtrl->lastError.errCode = END_ERR_RESET;        pDrvCtrl->lastError.pMesg = "Memory error.";        muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);        }    if (stat & CSR0_BABL)        {        pDrvCtrl->lastError.errCode = END_ERR_WARN;        pDrvCtrl->lastError.pMesg = "Babbling";        muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);        }    if (stat & CSR0_MISS)        {        pDrvCtrl->lastError.errCode = END_ERR_WARN;        pDrvCtrl->lastError.pMesg = "Missing";        muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);        }        return;    }/********************************************************************************* ln97xInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void ln97xInt    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    UINT32	   	stat;    /* Read the device status register */    stat = ln97xCsrRead (pDrvCtrl, 0);    DRV_LOG (DRV_DEBUG_INT, "i=0x%x:\n", stat, 2, 3, 4, 5, 6);    /* If false interrupt, return. */    if (! (stat & CSR0_INTR))        {        DRV_LOG (DRV_DEBUG_INT, "False interrupt.\n", 1, 2, 3, 4, 5, 6);        return;        }    /*     * enable interrupts, clear receive and/or transmit interrupts, and clear     * any errors that may be set.     * Writing back what was read clears all interrupts     */    ln97xCsrWrite (pDrvCtrl, 0, stat);    /* Check for errors */    if (stat & (CSR0_BABL | CSR0_MISS | CSR0_MERR))	{        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        if (stat & CSR0_BABL)            {            pDrvCtrl->errorStat |= CSR0_BABL;            if (!pDrvCtrl->errorHandling)                {                if (netJobAdd ((FUNCPTR) ln97xHandleError, (int) pDrvCtrl                               , 2, 3, 4, 5) == OK)                    {                    pDrvCtrl->errorHandling = TRUE;                    }                }            DRV_LOG (DRV_DEBUG_INT, "Babbling\n", 1, 2, 3, 4, 5, 6);            }        if (stat & CSR0_MISS)            {            pDrvCtrl->errorStat |= CSR0_MISS;            if (!pDrvCtrl->errorHandling)                {                if (netJobAdd ((FUNCPTR) ln97xHandleError, (int) pDrvCtrl                               , 2, 3, 4, 5) == OK)                    {                    pDrvCtrl->errorHandling = TRUE;                    }                }            DRV_LOG (DRV_DEBUG_INT, "Missing\n", 1, 2, 3, 4, 5, 6);            }        /* restart chip on fatal error */        if (stat & CSR0_MERR)        /* memory error */	    {            pDrvCtrl->errorStat |= CSR0_MERR;            if (!pDrvCtrl->errorHandling)                {                if (netJobAdd ((FUNCPTR) ln97xHandleError, (int) pDrvCtrl                               , 2, 3, 4, 5) == OK)                    {                    pDrvCtrl->errorHandling = TRUE;                    }                }            DRV_LOG (DRV_DEBUG_INT, "Memory error, restarting.\n",                     1, 2, 3, 4, 5, 6);            END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));	    /* Only reset device if Restart will occur */	    if (netJobAdd ((FUNCPTR) ln97xRestart, (int) pDrvCtrl                           , 2, 3, 4, 5) == OK)		{		ln97xReset (pDrvCtrl);		}            return;	    }	}    /* Have netTask handle any input packets */    if ((stat & CSR0_RINT) && (stat & CSR0_RXON) &&        !(pDrvCtrl->flags & LS_RCV_HANDLING_FLAG)       )	{        if (netJobAdd ((FUNCPTR)ln97xHandleRecvInt, (int)pDrvCtrl                       , 0,0,0,0) == OK)            {            pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;            }	}    /*     * Did LANCE update any of the TMD's?     * If not then don't bother continuing with transmitter stuff     */    if ((stat & CSR0_TINT) && (!pDrvCtrl->txCleaning))        {        pDrvCtrl->txCleaning = TRUE;        netJobAdd ((FUNCPTR)ln97xTRingScrub, (int) pDrvCtrl, 0, 0, 0, 0);        }    if (pDrvCtrl->txBlocked)    /* cause a restart */        {        pDrvCtrl->txBlocked = FALSE;        netJobAdd ((FUNCPTR)muxTxRestart, (int) &pDrvCtrl->endObj, 0, 0, 0, 0);        }    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    return;    }/********************************************************************************* ln97xHandleRecvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.*/LOCAL void ln97xHandleRecvInt    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */

⌨️ 快捷键说明

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