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

📄 ln97xend.c

📁 VMware上运行vxWorks的BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
	    if (!CACHE_DMA_IS_WRITE_COHERENT ())		{		printf ( "ln97x: device requires cache coherent memory\n" );		return (ERROR);		}	    pDrvCtrl->pShMem = (char *) cacheDmaMalloc (sz);	    if ((int)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;    /* 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 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 ((int)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;    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);    }/********************************************************************************* 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->lastError.errCode = END_ERR_WARN;            pDrvCtrl->lastError.pMesg = "Babbling";            netJobAdd ((FUNCPTR) muxError, (int) &pDrvCtrl->endObj,                       (int) &pDrvCtrl->lastError,                       0, 0, 0);            DRV_LOG (DRV_DEBUG_INT, "Babbling\n", 1, 2, 3, 4, 5, 6);            }        if (stat & CSR0_MISS)            {            pDrvCtrl->lastError.errCode = END_ERR_WARN;            pDrvCtrl->lastError.pMesg = "Missing";            netJobAdd ((FUNCPTR) muxError, (int) &pDrvCtrl->endObj,                       (int) &pDrvCtrl->lastError,                       0, 0, 0);            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->lastError.errCode = END_ERR_RESET;            pDrvCtrl->lastError.pMesg = "Memory error.";            netJobAdd ((FUNCPTR)muxError, (int) &pDrvCtrl->endObj,                       (int)&pDrvCtrl->lastError,                       0, 0, 0);            DRV_LOG (DRV_DEBUG_INT, "Memory error, restarting.\n",                     1, 2, 3, 4, 5, 6);            END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));            ln97xRestart (pDrvCtrl);            return;	    }	}    /* Have netTask handle any input packets */    if ((stat & CSR0_RINT) && (stat & CSR0_RXON))	{        if (!(pDrvCtrl->flags & LS_RCV_HANDLING_FLAG))	    {            pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;            (void) netJobAdd ((FUNCPTR)ln97xHandleRecvInt, (int)pDrvCtrl,                              0,0,0,0);	    }	}    /*     * Did LANCE update any of the TMD's?     * If not then don't bother continuing with transmitter stuff     */    if (!(stat & CSR0_TINT))        return;    DRV_LOG (DRV_DEBUG_INT, "t ", 1, 2, 3, 4, 5, 6);    if (!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 */    )    {    LN_RMD * 		pRmd = (LN_RMD *)NULL;    do        {        pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;        while ((pRmd = ln97xFullRMDGet (pDrvCtrl)) != (LN_RMD *)NULL) 	    {	    LN_CACHE_INVALIDATE (pRmd, RMD_SIZ);            ln97xRecv (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 (ln97xFullRMDGet (pDrvCtrl) != NULL);    /* this double check solves the RACE */    }/********************************************************************************* ln97xFullRMDGet - get next received message RMD** Returns ptr to next Rx desc to process, or NULL if none ready.*/LOCAL LN_RMD * ln97xFullRMDGet    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    LN_RMD *		pRmd;    pRmd = pDrvCtrl->pRring + pDrvCtrl->rmdIndex;  /* form ptr to Rx desc */    /* If receive buffer has been released to us, return it */    if ((PCI_SWAP (pRmd->rBufRmd1) & RMD1_OWN) == 0)        return (pRmd);    else        return ((LN_RMD *) NULL);    }/********************************************************************************* ln97xRecv - process the next incoming packet** RETURNS: OK/ERROR*/LOCAL STATUS ln97xRecv    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    LN_RMD *		pRmd    )    {    int         	len;    M_BLK_ID    	pMblk;    char *       	pCluster;    char *       	pNewCluster;    char *       	pTemp;    CL_BLK_ID   	pClBlk;    UINT32		rmd1Tmp;    /* Packet must be checked for errors, Read rmd1 once only */    rmd1Tmp = PCI_SWAP (pRmd->rBufRmd1);    DRV_LOG (DRV_DEBUG_TX, "Recv : rmd1 = %X index = %d\n", rmd1Tmp,             pDrvCtrl->rmdIndex, 3, 4, 5, 6);    /* If error flag OR if packet is not completely in one buffer */    if  ((rmd1Tmp & RMD1_ERR) ||          (rmd1Tmp & (RMD1_STP | RMD1_ENP)) != (RMD1_STP | RMD1_ENP))	{        DRV_LOG (DRV_DEBUG_RX, "RMD error!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;                          /* skip to clean up */	}    /* If we cannot get a buffer to loan then bail out. */    pNewCluster = netClusterGet (pDrvCtrl->endObj.pNetPool,                                 pDrvCtrl->pClPoolId);    if (pNewCluster == NULL)        {        DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)        {        netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);        DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.

⌨️ 快捷键说明

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