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

📄 ixatmcodeletswloopback.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 2 页
字号:
	    {		/* Balance is 16 UBR VCs */		atmServiceCat = IX_ATM_UBR;                IX_ATMCODELET_LOG("Setting up UBR: ");	    }	}	else	{	    IX_ATMCODELET_LOG("Setting up UBR: ");	}	/* Use a different port per channel, depending on the maximum	 * number of ports configured	 */	retval = ixAtmUtilsAtmVcRegisterConnect(ixAtmSwLb_port,						 ixAtmSwLb_vpi,						 ixAtmSwLb_vci,						 aalType,						 atmServiceCat,						 IX_ATM_RX_A,						 ixAtmSwLbRxCallback,						 IX_ATMCODELET_RX_FREE_Q_LOW_THRESHOLD,						 ixAtmSwLbTxDoneCallback,						 ixAtmSwLbRxFreeLowReplenish,						 ixAtmSwLb_channelIdx,						 &ixAtmSwLbRxVcInfoTable[ixAtmSwLb_channelIdx].connId,						 &ixAtmSwLbTxVcInfoTable[ixAtmSwLb_channelIdx].connId);		if (retval != IX_SUCCESS)	{	    IX_ATMCODELET_LOG("Sw loopback VC setup failed for port %2u vpi %3u vci %5u\n", 			      ixAtmSwLb_port, ixAtmSwLb_vpi, ixAtmSwLb_vci);	    return IX_FAIL;	}	else	{	    IX_ATMCODELET_LOG("Sw loopback VC configured for port %2u vpi %3u vci %5u\n", 			      ixAtmSwLb_port, ixAtmSwLb_vpi, ixAtmSwLb_vci);	}	/* Wrap the port back to 0 when numPortss used already */	ixAtmSwLb_port++;	if (ixAtmSwLb_port >= (IxAtmLogicalPort)numPorts)        {	    ixAtmSwLb_port = 0;        }	/* use the next vci */	ixAtmSwLb_vci++;    }    return IX_SUCCESS;}/* * Replenish buffers to the RxFree queue. Buffers are taken from * the software queue. */voidixAtmSwLbRxFreeLowReplenish (IxAtmdAccUserId userId){    IX_OSAL_MBUF *mBuf;    IX_STATUS retval;    IxAtmConnId connId;    UINT32 numFreeEntries;    UINT32 cnt;    connId = ixAtmSwLbRxVcInfoTable[userId].connId;    /* Get the number of free entries in the RX Free queue */    retval = ixAtmdAccRxVcFreeEntriesQuery (connId, &numFreeEntries);    if (retval != IX_SUCCESS)    {	IX_ATMCODELET_LOG("Failed to query depth of Rx Free Q for connection %u\n",			  connId);	return;    }    /* Replenish Rx buffers  */    for (cnt=0; cnt<numFreeEntries; cnt++)    {	if (ixAtmQueueEmptyQuery (&loopbackSwq))	{	    ixAtmSwLbChannelRxSwqUndl++;	    ixAtmUtilsMbufGet(IX_ATMCODELET_MBUF_SIZE, &mBuf);	    if (mBuf == NULL)	    {		IX_ATMCODELET_LOG("Failed to get rx free mbuffers\n");		return;	    }	}	else	{	    mBuf = ixAtmMBufQueueGet (&loopbackSwq);	}	/* 	 * Set the number of bytes of data in this MBUF to the number of	 * payloads that will fit evenly into IX_ATMCODELET_MBUF_SIZE.	 */	IX_OSAL_MBUF_MLEN(mBuf) = 	    (IX_ATMCODELET_MBUF_SIZE / ixAtmSwLbRxVcInfoTable[userId].bytesPerCell) *	    ixAtmSwLbRxVcInfoTable[userId].bytesPerCell;        ixAtmSwLbRxInvalidate(mBuf);	/* Send free buffers to NPE */	retval = ixAtmdAccRxVcFreeReplenish (connId, mBuf);	if (retval != IX_SUCCESS)	{	    /* Free the allocated buffer */	    ixAtmUtilsMbufFree(mBuf);	    IX_ATMCODELET_LOG("Failed to pass Rx free buffers to Atmd \n");	    return;	}	/* Update stats */	ixAtmSwLbStats->rxFreeBuffers++;    }}/* --------------------------------------------------------------   Return the stats.   -------------------------------------------------------------- */voidixAtmSwLbStatsGet (IxAtmCodeletStats *stats){    *stats = *ixAtmSwLbStats;}/* --------------------------------------------------------------   Reset counters.   -------------------------------------------------------------- */PRIVATE voidixAtmSwLbStatsReset (void){    if (NULL != ixAtmSwLbStats)    {	ixAtmSwLbStats->txPdus = 0;	ixAtmSwLbStats->txBytes = 0;	ixAtmSwLbStats->rxPdus = 0;	ixAtmSwLbStats->rxBytes = 0;	ixAtmSwLbStats->txDonePdus = 0;	ixAtmSwLbStats->rxFreeBuffers = 0;	ixAtmSwLbStats->txPdusSubmitFail = 0;	ixAtmSwLbStats->txPdusSubmitBusy = 0;	ixAtmSwLbStats->rxPdusInvalid = 0;    }}/* --------------------------------------------------------------   The calback is called when the TxDone queue reaches a   specified level. The mubf passed to this function is recycled   by placing it on the the softwre queue.   -------------------------------------------------------------- */PRIVATE voidixAtmSwLbTxDoneCallback (IxAtmdAccUserId userId,			 IX_OSAL_MBUF *mbufPtr){    ixAtmSwLbStats->txDonePdus++;    if (ixAtmQueueFullQuery (&loopbackSwq))    {	ixAtmSwLbChannelRxSwqOvfl++;	ixAtmUtilsMbufFree(mbufPtr);    }    else    {	ixAtmChainQueuePut (&loopbackSwq,			    mbufPtr);    }}/* --------------------------------------------------------------   The callback is called when an Atm Packet has been recieved. If   the PDU is invalid or it is a buffer returned during a   dissconnect by IxAtmdAcc then return the buffer to the vxWorks   pool. Otherwise transmit the PDU; this is where the loopback   occurs. 1 PDU is transmitted for every rxToTxRatio PDUs   received.   -------------------------------------------------------------- */PRIVATE voidixAtmSwLbRxCallback (IxAtmLogicalPort port,		     IxAtmdAccUserId userId,		     IxAtmdAccPduStatus pduStatus,		     IxAtmdAccClpStatus clp,		     IX_OSAL_MBUF *mbufPtr){    IX_STATUS retval = IX_FAIL;    static UINT32 rxCount = 0;    UINT32 sizeInCells;    UINT32 rxBytes = 0;    if (mbufPtr == NULL)    {	IX_ATMCODELET_LOG ("rxCallback called with NULL mbufPtr\n");	return;    }    rxBytes = IX_OSAL_MBUF_PKT_LEN(mbufPtr);    /* Size of the data transmitted in CELLS */    sizeInCells = rxBytes/ixAtmSwLbRxVcInfoTable[userId].bytesPerCell;    if (pduStatus == IX_ATMDACC_MBUF_RETURN)    {	/* Return this buffer to the pool */	ixAtmUtilsMbufFree (mbufPtr);	return;    }        if ((pduStatus != IX_ATMDACC_AAL0_VALID) && (pduStatus != IX_ATMDACC_AAL5_VALID))    {		ixAtmSwLbStats->rxPdusInvalid++;	/* Return buffer to the pool */        ixAtmUtilsMbufFree(mbufPtr);	return;    }    /* Update stats */    ixAtmSwLbStats->rxPdus++;    ixAtmSwLbStats->rxBytes += rxBytes;	    /* Only send 1 PDU for every rxToTxRatio PDUs received */    if (rxCount++ == 0)    {	/* Tx the Rx data, including the trailer */	retval = ixAtmdAccTxVcPduSubmit (ixAtmSwLbTxVcInfoTable[userId].connId,					 mbufPtr,					 IX_ATMCODELET_DEFAULT_CLP,					 sizeInCells );	if (retval != IX_SUCCESS)	{	    ixAtmSwLbStats->txPdusSubmitFail++;	    ixAtmUtilsMbufFree (mbufPtr);	}    }    else    {	/* Do not process this Pdu. Free the buffer */        ixAtmUtilsMbufFree (mbufPtr);	    }    if (rxCount == swLbRxToTxRatio)    {	rxCount = 0;    }    if (retval == IX_SUCCESS)    {	/* Update status */	ixAtmSwLbStats->txPdus++;	ixAtmSwLbStats->txBytes += rxBytes;    }    return;}/* ---------------------------------------------------*/PRIVATE voidixAtmSwLbRxInvalidate(IX_OSAL_MBUF * mbufPtr){    while (mbufPtr != NULL)    {      IX_OSAL_CACHE_INVALIDATE(IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr));      mbufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr);    }    return;}/* --------------------------------------------------------------   Software queue manipulation functions.   -------------------------------------------------------------- */PRIVATE BOOL ixAtmQueueFullQuery (IxAtmCodeletSwLbSwMbufQ *s){    return (s->head - s->tail == s->size);}PRIVATE BOOL ixAtmQueueEmptyQuery (IxAtmCodeletSwLbSwMbufQ *s){    return (s->head == s->tail);}PRIVATE IX_OSAL_MBUF * ixAtmMBufQueueGet (IxAtmCodeletSwLbSwMbufQ *s){    IX_OSAL_ASSERT (s->head != s->tail);    return (s->array[s->tail++ & s->mask]);}PRIVATE void ixAtmSwLbMBufQueuePut (IxAtmCodeletSwLbSwMbufQ *s, IX_OSAL_MBUF *buf){    IX_OSAL_ASSERT (s->head - s->tail != s->size);    s->array[s->head++ & s->mask] = buf;}PRIVATE void ixAtmChainQueuePut (IxAtmCodeletSwLbSwMbufQ *s,		    IX_OSAL_MBUF *mbufPtr){    IX_OSAL_MBUF *buf;    do    {	if (ixAtmQueueFullQuery(s))	{	    ixAtmUtilsMbufFree(mbufPtr);	    break;	}	else	{	    buf = mbufPtr;	    mbufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr);	    IX_OSAL_ASSERT(IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(buf) == 0);	    ixAtmSwLbMBufQueuePut (s, buf);	}    }    while (mbufPtr);}         

⌨️ 快捷键说明

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