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

📄 ln7990end.c

📁 7990驱动编程
💻 C
📖 第 1 页 / 共 5 页
字号:
            break;        }    /*                        Turkey Carving     *                        --------------     *     *                          LOW MEMORY     *     *             |-------------------------------------|     *             |       The initialization block      |     *             |         (sizeof (ln_ib))            |     *             |-------------------------------------|     *             |         The Rx descriptors          |     *             | ((1 << lnRsize) + 1)*sizeof (ln_rmd)|     *             |-------------------------------------|     *             |         The Tx descriptors          |     *             | ((1 << lnTsize) + 1)*sizeof (ln_tmd)|     *             |-------------------------------------|     */    /* align */    pDrvCtrl->pShMem = (char *) ( ( (int)pDrvCtrl->pShMem + 3) & ~3);    /* Save some things */    pDrvCtrl->memBase  = (char *)((ULONG)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); /* HELP: deal with memWidth */    /* 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. */    pDrvCtrl->pTring = (ln_tmd *) (int)(pDrvCtrl->pShMem + IB_SIZ +			((1 << lnRsize) + 1) * RMD_SIZ);    pDrvCtrl->tringSize = 1 << lnTsize;    pDrvCtrl->tringLen  = lnTsize;    pDrvCtrl->tmdIndex	= 0;    pDrvCtrl->tmdIndexC	= 0;    /* Set up the structures to allow us to free data after sending it. */        for (ix = 0; ix < pDrvCtrl->rringSize; ix++)        {        pDrvCtrl->freeRtn[ix] = NULL;        pDrvCtrl->freeData[ix].arg1 = NULL;        pDrvCtrl->freeData[ix].arg2 = NULL;        }    /*     * Allocate receive buffers from our own private pool.     */    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    lnMclConfig.mBlkNum = pDrvCtrl->rringSize * 2;    lnClDescTbl[0].clNum = pDrvCtrl->rringSize *2;    lnMclConfig.clBlkNum = lnClDescTbl[0].clNum;    lnMclConfig.memSize = (lnMclConfig.mBlkNum * (MSIZE + sizeof (long))) +                          (lnMclConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));    if ((lnMclConfig.memArea = (char *) memalign (sizeof(long),                                                  lnMclConfig.memSize))        == NULL)        return (ERROR);        lnClDescTbl[0].clNum = pDrvCtrl->rringSize *2;        lnClDescTbl[0].memSize = (lnClDescTbl[0].clNum * (LN_BUFSIZ + 8))        + sizeof(int);    if ((int) pDrvCtrl->memAdrs != NONE) /* Do we hand over our own memory? */        {        lnClDescTbl[0].memArea =                 (char *)(pDrvCtrl->pTring + (((1 << lnTsize) + 1) * TMD_SIZ));        }    else        {        lnClDescTbl[0].memArea =            (char *) cacheDmaMalloc (lnClDescTbl[0].memSize);        if ((int)lnClDescTbl[0].memArea == NULL)            {            DRV_LOG(DRV_DEBUG_LOAD,                    "system memory unavailable\n", 1, 2, 3, 4, 5, 6);            return (ERROR);            }        }        if (netPoolInit(pDrvCtrl->end.pNetPool, &lnMclConfig,                    &lnClDescTbl[0], lnClDescTblNumEnt, NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return (ERROR);        }#ifdef DRV_DEBUG    ln7990NetPool = *pDrvCtrl->end.pNetPool;#endif    /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = clPoolIdGet(pDrvCtrl->end.pNetPool,                                      LN_BUFSIZ, FALSE);    pRmd = pDrvCtrl->pRring;    for (ix = 0; ix < pDrvCtrl->rringSize; ix++, pRmd++)        {        if ((pTempBuf = (char *)netClusterGet(pDrvCtrl->end.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;    }/********************************************************************************* ln7990Start - 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 ln7990Start    (    LN7990END_DEVICE *pDrvCtrl    )    {    STATUS result;    pDrvCtrl->txCleaning = FALSE;    pDrvCtrl->txBlocked = FALSE;    SYS_INT_CONNECT (pDrvCtrl, ln7990Int, (int)pDrvCtrl, &result);    if (result == ERROR)	return ERROR;    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    SYS_INT_ENABLE (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* ln7990HandleError - 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 ln7990HandleError    (    LN7990END_DEVICE  *pDrvCtrl    )    {    u_short stat;    pDrvCtrl->errorHandling = FALSE;    stat = pDrvCtrl->errorStat;    pDrvCtrl->errorStat &= ~stat;        if (stat & lncsr_MERR)	{	pDrvCtrl->lastError.errCode = END_ERR_RESET;	pDrvCtrl->lastError.pMesg = "Memory error.";	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);	}    if (stat & lncsr_BABL)	{	pDrvCtrl->lastError.errCode = END_ERR_WARN;	pDrvCtrl->lastError.pMesg = "Babbling";	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);	}    if (stat & lncsr_MISS)	{	pDrvCtrl->lastError.errCode = END_ERR_WARN;	pDrvCtrl->lastError.pMesg = "Missing";	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);	}        return;    }    /********************************************************************************* ln7990Int - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void ln7990Int    (    LN7990END_DEVICE  *pDrvCtrl    )    {    u_short        stat;    ln_rmd         *pRmd;   /* Read the device status register */    stat = ln7990Csr0Read (pDrvCtrl);    DRV_LOG (DRV_DEBUG_INT, "i=0x%x:\n", stat, 2, 3, 4, 5, 6);    /* If false interrupt, return. */    if (!(stat & lncsr_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.     */    ln7990CsrWrite (pDrvCtrl, 0, ((stat &	    (lncsr_BABL|lncsr_CERR|lncsr_MISS|lncsr_MERR|	     lncsr_RINT|lncsr_TINT|lncsr_IDON)) | lncsr_INEA));    /* Check for errors */    if (stat & (lncsr_BABL | lncsr_MISS | lncsr_MERR))        {        ++pDrvCtrl->csr0Errs;	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	if (stat & lncsr_BABL)	    {	    pDrvCtrl->errorStat |= lncsr_BABL;	    if (!pDrvCtrl->errorHandling)		{		if (netJobAdd ((FUNCPTR) ln7990HandleError, (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 & lncsr_MISS)	    {	    pDrvCtrl->errorStat |= lncsr_MISS;	    if (!pDrvCtrl->errorHandling)		{		if (netJobAdd ((FUNCPTR) ln7990HandleError, (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 & lncsr_MERR)        /* memory error */            {	    pDrvCtrl->errorStat |= lncsr_MERR;	    if (!pDrvCtrl->errorHandling)		{		if (netJobAdd ((FUNCPTR) ln7990HandleError, (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->end, (IFF_UP | IFF_RUNNING));	    /* Only reset device if Restart will occur */	    if (netJobAdd ((FUNCPTR) ln7990Restart			   , (int) pDrvCtrl, 2, 3, 4, 5) == OK)		{		ln7990Reset (pDrvCtrl);		}	    return;	    }        }    /* Have netTask handle any input packets */    pRmd =  pDrvCtrl->pRring + pDrvCtrl->rmdIndex;    LN_CACHE_INVALIDATE (pRmd, RMD_SIZ);    if (((stat & lncsr_RINT) && (stat & lncsr_RXON)) ||	LN_RMD_OWNED (pRmd) == 0)        {        DRV_LOG (DRV_DEBUG_INT, "r ", 1, 2, 3, 4, 5, 6);        if (!(pDrvCtrl->flags & LS_RCV_HANDLING_FLAG))            {            if (netJobAdd ((FUNCPTR)ln7990HandleRecvInt, (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 & lncsr_TINT))	{        return;	}    DRV_LOG (DRV_DEBUG_INT, "t ", 1, 2, 3, 4, 5, 6);        if (!pDrvCtrl->txCleaning)        {        pDrvCtrl->txCleaning = TRUE;        netJobAdd ((FUNCPTR)ln7990ScrubTRing, (int) pDrvCtrl, 0, 0, 0, 0);        }    if (pDrvCtrl->txBlocked)	/* cause a restart */        {        netJobAdd ((FUNCPTR)muxTxRestart, (int) &pDrvCtrl->end, 0, 0, 0, 0);        pDrvCtrl->txBlocked = FALSE;        }    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    }/********************************************************************************* ln7990HandleRecvInt - 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.** RETURNS: N/A.*/LOCAL void ln7990HandleRecvInt    (    LN7990END_DEVICE *pDrvCtrl    )    {    ln_rmd *pRmd;    do        {        pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;        while ((pRmd = ln7990FullRMDGet (pDrvCtrl)) != NULL)            ln7990Recv (pDrvCtrl, pRmd);        /*         * There is a RACE right here.  The ISR could add a receive packet         * and check the boolean below, and decide to exit.  Thus the         * packet could be dropped if we don't double check before we         * return.         */        pDrvCtrl->flags &= ~LS_RCV_HANDLING_FLAG;        }    while (ln7990FullRMDGet (pDrvCtrl) != NULL);    /* this double check solves the RACE */    }/********************************************************************************* ln7990FullRMDGet - get next received message RMD** Get next recevied message descriptor.  Returns NULL if none are* ready.** RETURNS: ptr to next Rx desc to process, or NULL if none ready.*/LOCAL ln_rmd *ln7990FullRMDGet    (    LN7990END_DEVICE  *pDrvCtrl    )    {    ln_rmd   *pRmd;    pRmd = pDrvCtrl->pRring + pDrvCtrl->rmdIndex;  /* form ptr to Rx desc */    LN_CACHE_INVALIDATE (pRmd, RMD_SIZ);    if (LN_RMD_OWNED (pRmd) == 0)        return (pRmd);    else        return ((ln_rmd *) NULL);    }/********************************************************************************* ln7990Recv - process the next incoming packet** Handle one incoming packet.  The packet is checked for errors.** RETURNS: N/A.

⌨️ 快捷键说明

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