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

📄 ixethaccend.c

📁 ixp425 bsp for vxworks
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        return(ERROR);    }		          /*     * If you need clusters to store received packets into then get them     * here ahead of time.     */    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,                                               IX_ETHACC_RX_MBUF_MIN_SIZE, 					       FALSE))        == NULL)        return(ERROR);    /* The number of cblk/mblk pairs allocated for NPE */    pDrvCtrl->rxBufsAlloc = IXETHACC_MBLKS;    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);#ifdef IXP_DRV_DEBUG    /* allow log messages to print */    taskDelay(240);#endif IXP_DRV_DEBUG    return OK;}/********************************************************************************* Return buffers to the Intel Ethernet Engine */LOCAL __inline__ STATUS ixEthAccEndReplenish(END_DEVICE *pDrvCtrl,   /* interrupting device */M_BLK *pMblk){    if (ixOsServFastMutexTryLock(&(pDrvCtrl->fastReplMutex)) == IX_SUCCESS)    {	if (ixEthAccPortRxFreeReplenish(pDrvCtrl->unit, pMblk)	    == IX_ETH_ACC_SUCCESS)	{	    pDrvCtrl->rxBufsReplenish++; /* The number of mblk sent to NPE */	    ixOsServFastMutexUnlock(&(pDrvCtrl->fastReplMutex));	    IXP_DRV_LOG (IXP_DRV_DEBUG_RX, 		     "ixEthAccEndRepl: replenished mbuf %8.8x\n",		     (UINT32)pMblk, 2, 3, 4, 5, 6);	}	else	{#ifdef IXP_DRV_DEBUG_MBUFS	    pDrvCtrl->errs++;#endif	    ixOsServFastMutexUnlock(&(pDrvCtrl->fastReplMutex));	    /* Free buffer back to its pool */	    netMblkClChainFree (pMblk);	    IXP_DRV_LOG(IXP_DRV_DEBUG_RX,"Error:replenish Port[%d]\n",			pDrvCtrl->unit,2,3,4,5,6);	    return ERROR; /* unable to replenish */	}    }    else    {	/* replenish is already running at this time 	 * Free buffer back to its pool	 */	netMblkClChainFree (pMblk);    }    return OK;}/********************************************************************************* Return buffers from the fast pool to the Intel Ethernet Engine */LOCAL void ixEthAccEndReplenishFast(END_DEVICE *pDrvCtrl   /* interrupting device */){    M_BLK_ID pMblk;    int oldLevel;    UINT32 rxBufsActive;    /* drain all buffers from the fast path pool */    while (pDrvCtrl->replRd < pDrvCtrl->replWr)    {	pMblk = pDrvCtrl->replBufList[pDrvCtrl->replRd++ & RECBUF_MASK];        IXP_DRV_LOG (IXP_DRV_DEBUG_RX, 		     "ixEthAccEndRepl fast: received mbuf %8.8x\n",		     (UINT32)pMblk, 2, 3, 4, 5, 6);	/* check the mblk is ready for replenish */        oldLevel = intLock ();  /* protect the mbuf structure */	if(pMblk->pClBlk->clRefCnt != 1 || pMblk->m_next != NULL)        {	    /* this mblk may be shared by other components, 	     * or is chained to an other mbuf, so release	     * it to the pool.	     */	    intUnlock (oldLevel);	    netMblkClChainFree (pMblk);	    continue;	}        intUnlock (oldLevel);        rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;        if (rxBufsActive >= pDrvCtrl->rxBufsAlloc)	{            netMblkClChainFree (pMblk);	    continue;	}        	/* increment stats about fast replenish */#ifdef IXP_DRV_DEBUG_MBUFS	pDrvCtrl->tnetFastReplenish++;#endif#ifdef IXE_CACHED_RX_BUFFERS_ENABLE        /*	 * Mblk header is invalidated in ethAcc component.         * We need only invalidate up to the contents of the use         * of this buffer.         */        DO_EVENT(IXE_EVT_RCV_REPLENISH_LOOP_CACHEOPS);        IXP425_END_CACHE_INVALIDATE(pMblk->m_data, pMblk->m_len);#endif	/* Force Quad align for Ip packet headers */	pMblk->m_data = ALIGN_MDATA(pMblk->pClBlk->clNode.pClBuf);	pMblk->m_len = IX_ETHACC_RX_MBUF_MIN_SIZE;	pMblk->mBlkPktHdr.len = IX_ETHACC_RX_MBUF_MIN_SIZE;        pMblk->m_nextpkt = NULL;#ifdef IXP_DRV_DEBUG_MBUFS	elogHook(pMblk, 2, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif	if (ixEthAccEndReplenish(pDrvCtrl, pMblk) != OK)	{	    IXP_DRV_LOG(IXP_DRV_DEBUG_ERROR,"Error:replenish Port[%d]\n",			pDrvCtrl->unit,2,3,4,5,6);	}        DO_EVENT(IXE_EVT_RCV_REPLENISH_LOOP_BOTTOM);    }}/********************************************************************************* Return buffers from the slow vxWorks pool to the Intel Ethernet Engine */LOCAL void ixEthAccEndReplenishSlow(END_DEVICE *pDrvCtrl   /* interrupting device */){    M_BLK_ID pMblk;    UINT32 rxBufsActive;    /* replenish from buffers from fast replenish queue */    ixEthAccEndReplenishFast(pDrvCtrl);    /* replenish from buffers from vxWorks pool */    rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;    while (rxBufsActive < pDrvCtrl->rxBufsAlloc)    {        if ((pMblk = netTupleGet(pDrvCtrl->end.pNetPool,				 IX_ETHACC_RX_MBUF_MIN_SIZE + ALIGN_MLEN,				 M_DONTWAIT,				 MT_HEADER,				 FALSE ))            == NULL)        {#ifdef IXP_DRV_DEBUG_MBUFS	    pDrvCtrl->tupleGetFail++;#endif	    /* Clear the error */	    if( errnoGet () == S_netBufLib_NO_POOL_MEMORY )		errnoSet(0);            break;    	}	IXP_DRV_LOG (IXP_DRV_DEBUG_RX, 		     "ixEthAccEndRepl slow: replenish mbuf %8.8x\n",		     (UINT32)pMblk, 2, 3, 4, 5, 6);#ifdef IXE_CACHED_RX_BUFFERS_ENABLE        DO_EVENT(IXE_EVT_RCV_REPLENISH_LOOP_CACHEOPS);        IXP425_END_CACHE_INVALIDATE(pMblk->m_data, IX_ETHACC_RX_MBUF_MIN_SIZE + ALIGN_MLEN);#endif        /* Force Quad align for Ip packet on cache line boundary */        pMblk->m_data = ALIGN_MDATA(pMblk->m_data);        pMblk->m_len = IX_ETHACC_RX_MBUF_MIN_SIZE;	pMblk->mBlkPktHdr.len = IX_ETHACC_RX_MBUF_MIN_SIZE;        pMblk->m_next = NULL;        pMblk->m_nextpkt = NULL;#ifdef IXP_DRV_DEBUG_MBUFS	elogHook(pMblk, 1, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif	if (ixEthAccEndReplenish(pDrvCtrl, pMblk) != OK)	{	    IXP_DRV_LOG(IXP_DRV_DEBUG_ERROR,"Error:replenish Port[%d]\n",			pDrvCtrl->unit,2,3,4,5,6);	    return;	}	rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;        DO_EVENT(IXE_EVT_RCV_REPLENISH_LOOP_BOTTOM);    }}/********************************************************************************* ixEthAccEndStart - 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 ixEthAccEndStart(END_OBJ * pDrv  /* device ID */){    IxEthAccStatus result;    END_DEVICE *pDrvCtrl = (END_DEVICE *)pDrv;    /*     * Register Tx Done Callback     */    IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Registering IxEthAcc Callbacks Port[%d]\n",		pDrvCtrl->unit,2,3,4,5,6);    result = ixEthAccPortTxDoneCallbackRegister( pDrvCtrl->unit,                                                 ixEthAccEndTxDoneCallback,                                                 (UINT32) pDrvCtrl);    if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Tx Callbacks Port[%d]\n",		    pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    /*     * Now register Rx Done Callback     */    result = ixEthAccPortRxCallbackRegister( pDrvCtrl->unit,                                             ixEthAccEndRxCallback,                                             (UINT32) pDrvCtrl);        if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Rx Callbacks Port[%d]\n",		    pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    /* reset the counters */#ifdef IXP_DRV_DEBUG_MBUFS    pDrvCtrl->tnetReceived = 0;        /* packets processed to ipastack */    pDrvCtrl->tnetDrop = 0;            /* packets dropped by tnet task */    pDrvCtrl->tnetJobAddFail = 0;          /* netjobadd invoke */    pDrvCtrl->tnetFastReplenish = 0;   /* successful fast replenish */    pDrvCtrl->tupleGetFail = 0;        /* nettupleGet failures */    pDrvCtrl->tupleTxAlloc = 0;        /* mbufs allocated for TX */    pDrvCtrl->errs = 0;                 /* error counter */#endif IXP_DRV_DEBUG_MBUFS    IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Replenish IxEthAcc Port[%d]\n",		pDrvCtrl->unit,2,3,4,5,6);    /* replenish */    ixEthAccEndReplenishSlow(pDrvCtrl);    IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Enable IxEthAcc Port[%d]\n",		pDrvCtrl->unit,2,3,4,5,6);    /* enable hw and starts the rx traffic */    result = ixdp425EthLibStart(pDrvCtrl->unit);    if ( result != IX_SUCCESS)        {        IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,                    "Error:Enabling IxEthAcc Port[%d], result=%d\n",                    pDrvCtrl->unit,		    result,3,4,5,6);        return(ERROR);        }    IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Flags set IxEthAcc Port[%d]\n",		pDrvCtrl->unit,2,3,4,5,6);    END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));    return(OK);}/********************************************************************************* ixEthAccEndPacketGet - get next received message** Get next received message.  Returns NULL if none are* ready.** RETURNS: ptr to next packet, or NULL if none ready.*/char* ixEthAccEndPacketGet(END_DEVICE  *pDrvCtrl   /* device structure */){    /* Not supported by this device */    return(char *)NULL;}#ifdef IXETHACCEND_CSR_1_1/**************************************************************************** * vxWorks patch : recover buffers from a pool, which are alder than  * the indicated time-to-live (ttl) value * This will be used to recover fragmented packets which will never * be released because the driver is dropping the rx traffic  */LOCAL void ixEthAccEnd_ip_ttl_mbuf_release(int maxTtl, NET_POOL_ID  poolId){    extern int ipfragttl;    extern struct ipq ipq;    struct ipq *fp;    int s;    s = splnet();    fp = ipq.next;    if (fp) {	while (fp != &ipq) {	    fp = fp->next;	    /* release entries which are older than the ttl	     * and which first mbuf belongs to the mbuf pool passed 	     * as a parameter, and which are already waiting for	     * reassembly (because chaning already started). 	     * Other entries (which don't need reassembly) are not affected	     */	    if (fp->prev->ipq_ttl > ipfragttl 		|| fp->prev->ipq_ttl + maxTtl < IP_FRAG_TTL_DFLT) {		if (fp->prev->pMbufPkt->m_nextpkt != NULL		    && fp->prev->pMbufPkt->pClBlk->pNetPool == poolId) {		    ip_freef(fp->prev);		}	    }	}    }    splx(s);}/**************************************************************************** * update the stack time-to-live (ttl) value, depending * on the actual load: if many mbufs are already used, more mbufs should not * stay for a while inside the vxWorks stack. */#define IP_FRAG_TTL_MIN 4LOCAL void ixEthAccEnd_ip_ttl_update(END_DEVICE *pDrvCtrl){    /* degrade the ttl value depending on the current number      * of available mbufs      * the result value will be in the following range     *  IP_FRAG_TTL_MIN <= ipFragTtl <= IP_FRAG_TTL_DFLT     */    UINT32 rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;    pDrvCtrl->ipFragTtl = IP_FRAG_TTL_MIN + 	((IP_FRAG_TTL_DFLT-IP_FRAG_TTL_MIN) * rxBufsActive)	/ pDrvCtrl->rxBufsAlloc;    {	/* update the global frag ttl value with the worst-case	* interface value. There is a side effect : 	* it affect all interfaces.	*/	extern int ipfragttl;	END_DEVICE *pOtherDrvCtrl = ixEthAccpDrvCtrl[1 - pDrvCtrl->unit];	if (pOtherDrvCtrl && pOtherDrvCtrl->ipFragTtl <= pDrvCtrl->ipFragTtl)	{	    ipfragttl = pOtherDrvCtrl->ipFragTtl;	}	else	{	    ipfragttl = pDrvCtrl->ipFragTtl;	}    }}#endif/********************************************************************************* ixEthAccEndHandleRcvInt - 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 ixEthAccEndHandleRcvInt(END_DEVICE *pDrvCtrl   /* interrupting device */){    M_BLK_ID pMblk;    UINT32 rxBufsActive;    pDrvCtrl->netJobAddOut++;    DO_EVENT(IXE_EVT_RCV_HANDLE_ENTRY);    while (1)    {        DO_EVENT(IXE_EVT_RCV_RECEIVE_LOOP_TOP);	if (pDrvCtrl->recRd == pDrvCtrl->recWr)	{	    /* queue empty */	    break;	}	DO_EVENT(IXE_EVT_RCV_HANDLE_ENTRY);

⌨️ 快捷键说明

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