📄 ixethaccend.c
字号:
, (int)IX_OSAL_MBUF_MLEN(pIxpBuf) , 5, 6); if (ixEthAccPortRxFreeReplenish(pDrvCtrl->unit, pIxpBuf) == IX_ETH_ACC_SUCCESS) { pDrvCtrl->rxBufsReplenish++; /* The number of mblk sent to NPE */ ixOsalFastMutexUnlock(&(pDrvCtrl->fastReplMutex)); IXP_DRV_LOG (IXP_DRV_DEBUG_RX_HANDLING, "ixEthAccEndRepl: replenished mbuf 0x%08x\n", (UINT32)pIxpBuf, 2, 3, 4, 5, 6); } else {#ifdef IXP_DRV_DEBUG_MBUFS pDrvCtrl->errs++;#endif ixOsalFastMutexUnlock(&(pDrvCtrl->fastReplMutex)); /* Free buffer back to its pool */ netMblkClChainFree ((M_BLK_ID)pIxpBuf); IXP_DRV_LOG(IXP_DRV_DEBUG_RX_HANDLING,"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 ((M_BLK_ID)pIxpBuf); } return OK;}/******************************************************************************** Return buffers from the fast pool to the Intel Ethernet Engine */LOCAL void ixEthAccEndReplenishFast ( END_DEVICE *pDrvCtrl /* interrupting device */ ){ IX_OSAL_MBUF *pIxpBuf; M_BLK *pMblk; int oldLevel; UINT32 rxBufsActive; /* drain all buffers from the fast path pool */ while (pDrvCtrl->replRd != pDrvCtrl->replWr) { pIxpBuf = pDrvCtrl->replBufList[pDrvCtrl->replRd++ & RECBUF_MASK]; pMblk = (M_BLK *)pIxpBuf; IXP_DRV_LOG (IXP_DRV_DEBUG_RX_HANDLING, "ixEthAccEndRepl fast: received mbuf 0x%08x\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, pIxpBuf) != 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 *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_HANDLING, "ixEthAccEndRepl slow: replenish mbuf 0x%08x\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, (IX_OSAL_MBUF *)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;#ifdef INCLUDE_IXETHDB if(ixEthDBPortEnable(pDrvCtrl->unit) != IX_ETH_ACC_SUCCESS) { IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD, "Error:ixEthDBPortEnabled failed for port %d\n", pDrvCtrl->unit,2,3,4,5,6); return ERROR; } result = ixEthDBFilteringPortMaximumFrameSizeSet(pDrvCtrl->unit, END_BUFSIZ); if ( result != IX_ETH_DB_SUCCESS) { IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD, "Error:Setting IxEthDB max frame size " "of %d for port %d\n", END_BUFSIZ, pDrvCtrl->unit,3,4,5,6); return(ERROR); } result = ixEthDBPortAgingEnable(pDrvCtrl->unit); if ( result != IX_ETH_DB_SUCCESS) { IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD, "Error:Cannot enable IxEthDB port aging for port %d\n", pDrvCtrl->unit,2,3,4,5,6); return(ERROR); }#endif /* * 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( (IxEthAccPortId) pDrvCtrl->unit, (IxEthAccPortRxCallback) 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_FRAG_RECOVERY/**************************************************************************** * vxWorks patch : recover buffers from a pool, which are older 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -