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

📄 dp8381~1.c

📁 网卡83815的vxworks下基于PCI总线的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (tok == NULL)	return ERROR;    pDrvCtrl->dmaBufSize = strtoul (tok, NULL, NULL);    /* Transmit descriptor count. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->txDescCount =  strtoul (tok, NULL, NULL);    if (pDrvCtrl->txDescCount == 0)        pDrvCtrl->txDescCount = DP_TX_DESC_COUNT_DEFAULT;    /* Receive descriptor count. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->rxDescCount = strtoul (tok, NULL, NULL);    if (pDrvCtrl->rxDescCount == 0)        pDrvCtrl->rxDescCount = DP_RX_DESC_COUNT_DEFAULT;    /* Cluster count and mBlk count. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->clCount =  strtoul (tok, NULL, NULL);        if (pDrvCtrl->clCount == 0)        pDrvCtrl->clCount = (pDrvCtrl->rxDescCount + pDrvCtrl->txDescCount +                             DP_CL_EXTRA_DEFAULT);		    else if (pDrvCtrl->clCount <             (pDrvCtrl->rxDescCount + pDrvCtrl->txDescCount + DP_CL_EXTRA_MIN))        pDrvCtrl->clCount = (pDrvCtrl->rxDescCount + pDrvCtrl->txDescCount +                             DP_CL_EXTRA_MIN);		    pDrvCtrl->mBlkCount = pDrvCtrl->clCount * 2;        DRV_LOG (DRV_DEBUG_LOAD, "unit=%d, pDmaBuf=0x%x, dmaBufSize=%d, "             "txDescCount=%d, rxDescCount=%d, clCount=%d\n",             pDrvCtrl->unit, (UINT32)pDrvCtrl->pDmaBuf, pDrvCtrl->dmaBufSize,             pDrvCtrl->txDescCount, pDrvCtrl->rxDescCount, pDrvCtrl->clCount);    return OK;    }/********************************************************************************* dp83815MemInit - initialize queues and netpool for the device** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815MemInit    (    END_DEVICE * pDrvCtrl	/* device to be initialized */    )    {    M_CL_CONFIG		mclBlkConfig;    CL_DESC		clDescTbl[1];    char*	pMemBuf;    UINT32	txQMemSize;     UINT32	rxQMemSize;    UINT32 	totalSize;        /* Allocate memory for the net pool */        if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not allocate net pool memory\n",                 1, 2, 3, 4, 5, 6);        goto dpMemInitFail;        }          /* Allocate memory for mBlks and clBlks */        mclBlkConfig.mBlkNum  = pDrvCtrl->mBlkCount;    mclBlkConfig.clBlkNum = pDrvCtrl->clCount;    mclBlkConfig.memSize  = ((mclBlkConfig.mBlkNum  * MBLK_SIZE) +                             (mclBlkConfig.clBlkNum * CLBLK_SIZE));    mclBlkConfig.memArea  = pDrvCtrl->pMclMem =         memalign (sizeof (long), mclBlkConfig.memSize);        if (mclBlkConfig.memArea == NULL)        {         DRV_LOG (DRV_DEBUG_LOAD, "Could not allocate mclBlk memory\n",                  1, 2, 3, 4, 5, 6);        goto dpMemInitFail;        }                /* Allocate memory for clusters, Tx and Rx Queues */    /* Get the total memory size needed */    clDescTbl[0].clSize  = DP_BUF_SIZE;    clDescTbl[0].clNum   = pDrvCtrl->clCount;    clDescTbl[0].memSize = ((pDrvCtrl->clCount *                             (DP_BUF_SIZE + ( 2 * sizeof (long)))) +                            sizeof(int));    txQMemSize = DP_QUEUE_ELE_SIZE * pDrvCtrl->txDescCount;    rxQMemSize = DP_QUEUE_ELE_SIZE * pDrvCtrl->rxDescCount;    totalSize = clDescTbl[0].memSize + txQMemSize + rxQMemSize + DP_ALIGN;    /* If user has specified DevMem, validate; else allocate memory */        if ((pDrvCtrl->pDmaBuf != NULL) && (pDrvCtrl->pDmaBuf != (char*)NONE))        {        if (pDrvCtrl->dmaBufSize < totalSize)            {            DRV_LOG (DRV_DEBUG_LOAD, "Dp: not enough memory provided, "                     "need %ul got %d\n",                     totalSize,pDrvCtrl->dmaBufSize, 3, 4, 5, 6);            goto dpMemInitFail;            }                /* assume pool is cache coherent, copy null structure */                pDrvCtrl->cacheFuncs = cacheNullFuncs;        }    else        {         /* 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 ("dp: device requires cache coherent memory\n");             return (ERROR);             }                 pDrvCtrl->pDmaBuf = (char*) cacheDmaMalloc (totalSize);/*hanzhf*/                if (pDrvCtrl->pDmaBuf == NULL)            goto dpMemInitFail;        /* copy the DMA structure */        pDrvCtrl->cacheFuncs = cacheDmaFuncs;/*hanzhf*/        pDrvCtrl->flags |= DP83815_BUF_LOCAL;        DRV_LOG (DRV_DEBUG_LOAD, "DevMem allocated, pDmaBuf=0x%x\n",                 (UINT32)pDrvCtrl->pDmaBuf, 2, 3, 4, 5, 6);        }    /* Clear and align memory */        memset (pDrvCtrl->pDmaBuf, 0, totalSize);    pMemBuf = (char*)(((UINT32)pDrvCtrl->pDmaBuf + DP_ALIGN) & ~(DP_ALIGN - 1));        /* Initialize the memory pool. */     clDescTbl[0].memArea = pMemBuf;    if (netPoolInit (pDrvCtrl->end.pNetPool, &mclBlkConfig, clDescTbl, 1, NULL)        == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Failed to intialize memory pool\n",                 1, 2, 3, 4, 5, 6);        goto dpMemInitFail;        }#ifdef DRV_DEBUG    dp83815Pool = pDrvCtrl->end.pNetPool;#endif            /* Create Tx and Rx queues */    pMemBuf += clDescTbl[0].memSize;    if (dp83815QueueCreate (pDrvCtrl, &pDrvCtrl->txQueue, pMemBuf,                            pDrvCtrl->txDescCount,                              DP_QUEUE_TYPE_TX) != OK)        {        printf ("Eth%d: Failed to create tx queue\n", pDrvCtrl->unit);        goto dpMemInitFail;        }        pMemBuf += txQMemSize;       if (dp83815QueueCreate (pDrvCtrl, &pDrvCtrl->rxQueue, pMemBuf,                            pDrvCtrl->rxDescCount,                              DP_QUEUE_TYPE_RX) != OK)        {        printf ("Eth%d: Failed to create rx queue\n", pDrvCtrl->unit);        goto dpMemInitFail;        }        DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);    return OK;    dpMemInitFail:    	{        /* free memory allocated for mBlk-clBlks */        if (mclBlkConfig.memArea != NULL)        /* free memory allocated for clusters and Tx/Rx Queues */                if ((pDrvCtrl->flags & DP83815_BUF_LOCAL) &&            (pDrvCtrl->pDmaBuf != NULL))            cacheDmaFree (pDrvCtrl->pDmaBuf);                    /* free memory allocated for net pool */        if (pDrvCtrl->end.pNetPool != NULL)            free (pDrvCtrl->end.pNetPool);                DRV_LOG (DRV_DEBUG_LOAD, "Memory Init failed..\n", 1, 2, 3, 4, 5, 6);                 return ERROR;        }    }/******************************************************************************** dp83815Start - 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 dp83815Start    (    VOID * pObj		/* device ID */    )    {    END_DEVICE *pDrvCtrl = pObj;	/* device to be started */    UINT32 iobase = pDrvCtrl->baseAddr; /* base address of device */    STATUS result;	    /* Install interrupt vector */    SYS_INT_CONNECT (pDrvCtrl, dp83815Int, (int)pDrvCtrl, &result);    if (result == ERROR)        {       	return ERROR;        }	    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    /* Turn on device interrupts */    DP_REG32_WRITE (DP_IMR,DP_IMR_RXOK  );    DP_REG32_WRITE (DP_IER, DP_IER_IE);    /* Enable Tx/Rx */    DP_REG32_WRITE (DP_CR, DP_CR_TXE | DP_CR_RXE);        /* Enable the interrupt */    SYS_INT_ENABLE (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* dp83815Int - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void dp83815Int    (    END_DEVICE  *pDrvCtrl	/* interrupting device */    )    {    UINT32  iobase = pDrvCtrl->baseAddr;    UINT32  regIsr;        regIsr = DP_REG32_READ (DP_ISR);        DRV_LOG (DRV_DEBUG_INT, "dp%d: intStatus=0x%x ",             pDrvCtrl->unit, regIsr, 3, 4, 5, 6);    if (regIsr & DP_ISR_RXOK)        {        DRV_LOG (DRV_DEBUG_INT, "RX_INT ",                 pDrvCtrl->unit, 2, 3, 4, 5, 6);        if ((pDrvCtrl->flags & DP83815_RCV) == NULL)            {            pDrvCtrl->flags |= DP83815_RCV;            netJobAdd ((FUNCPTR)dp83815Recv, (int)pDrvCtrl, 0,0,0,0);            }        }    DRV_LOG (DRV_DEBUG_INT, "\n", 1, 2, 3, 4, 5, 6);    }/********************************************************************************* dp83815Recv - process the next incoming packet** Handle one incoming packet.  The packet is checked for errors and sent* to the upper layer.** RETURNS: OK on success or ERROR.*/LOCAL STATUS dp83815Recv    (    END_DEVICE *pDrvCtrl	/* device structure */    )    {    UINT32	cmdsts;    int         len;    VIRT_ADDR   rxDesc;    M_BLK_ID 	pNewMblk;    M_BLK_ID 	pRxMblk;    UINT	iobase = pDrvCtrl->baseAddr;        /* Process all received packets */    for (rxDesc = dp83815RxDescGet (pDrvCtrl);         (rxDesc != NULL);         rxDesc = dp83815RxDescGet (pDrvCtrl))        {        DRV_LOG (DRV_DEBUG_RX, "Rx: rxDesc=0x%x, CMDSTS = 0x%x\n",                 (UINT32)rxDesc, DP_DESC_CMDSTS_XLATE_GET(rxDesc), 3, 4, 5, 6);        /* Increment the packet count */            END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);        cmdsts = DP_DESC_CMDSTS_XLATE_GET (rxDesc);        /* Send the packet to the stack if no errors */        if ((cmdsts & DP_DESC_CMDSTS_RX_ERRORS) == 0)            {            len = (cmdsts & DP_DESC_CMDSTS_SIZE) - ETH_CRC_LEN;            /* Allocate a new replacement mblock tuple (mblk-clblk-cluster) */                pNewMblk = netTupleGet (pDrvCtrl->end.pNetPool, DP_BUF_SIZE,                                    M_DONTWAIT, MT_DATA, FALSE);            pRxMblk = (M_BLK_ID) DP_DESC_MBLKPTR_GET (rxDesc);            END_CACHE_INVALIDATE (pRxMblk->mBlkHdr.mData, len);                        if (pNewMblk)                {                /* Replace the data buffer in the rxDesc */                DP_DESC_BUFPTR_XLATE_SET (rxDesc, (pNewMblk->mBlkHdr.mData+4));/*hanzhf*/                DP_DESC_MBLKPTR_SET (rxDesc, pNewMblk);                /* Update the received Mblk */                pRxMblk->mBlkHdr.mData+=2;/*hanzhf*/                pRxMblk->mBlkHdr.mLen    = len;                pRxMblk->mBlkHdr.mFlags |= M_PKTHDR;                pRxMblk->mBlkPktHdr.len  = len;							    /* Make the data coherent and sent to the stack */                                DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n",                         1, 2, 3, 4, 5, 6);				dp83815memAlign((char*)(pRxMblk->mBlkHdr.mData+4), len);/*hanzhf*/#ifdef DRV_DEBUG                if (dp83815Debug & DRV_DEBUG_RX)                    dumpPkt (pRxMblk->mBlkHdr.mData, len);#endif                END_RCV_RTN_CALL(&pDrvCtrl->end, pRxMblk);                }            else                {                /* Increment the dropped packet count -- no resources */                                END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);                }            }        else            {            /* Increment error statistics */            END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); /* bad packet */            }        /* Cleanup the descriptor and make available for reception */                DP_DESC_CMDSTS_XLATE_SET (rxDesc, DP_BUF_SIZE);        END_CACHE_FLUSH (rxDesc, DP_DESC_SIZE);        DP_REG32_SET (DP_CR, DP_CR_RXE);                }    pDrvCtrl->flags &= ~(DP83815_RCV);    return OK;    }/********************************************************************************* dp83815Send - the driver send routine** This routine takes a M_BLK_ID and sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.   ** RETURNS: OK or ERROR.*/LOCAL STATUS dp83815Send    (    VOID * 	pObj,	/* device ptr */    M_BLK_ID    pMblk	/* data to send */    )    {    END_DEVICE * pDrvCtrl = pObj;	/* device ptr */    VIRT_ADDR	txDesc;    UINT32	cmdsts,temp;/* hanzhf*/    UINT32	iobase = pDrvCtrl->baseAddr;    M_BLK_ID	pTxMblk;    int		len;#if 0    BOOL	doCopy = (pMblk->mBlkHdr.mNext) ? TRUE: FALSE;#else    BOOL	doCopy = 1;#endif    if (pDrvCtrl->flags & DP83815_POLLING)        {        netMblkClChainFree (pMblk);

⌨️ 快捷键说明

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