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

📄 ixethaal5app.c

📁 intel IXP400系列cpu(2.3版)的库文件
💻 C
📖 第 1 页 / 共 5 页
字号:
    {#ifdef IXEAA_DEBUG        printf("AtmdAcc - cell was not sent\n");#endif        /* Recycle buffer if Ethernet port didn't accept it */        ixEAAAtmBufferRecycle( atmVcRxId[ userId ], mbufPtr );    }    else    {        ixEAANumAtmRxEthFramesForwarded++;    }}/* ATM Tx done callback - called by AtmdAcc when new tx buffer was sent and is no   longer used by atmdAcc */void ixEAAAtmTxDoneCallback(IxAtmdAccUserId userId, IX_OSAL_MBUF * mbufPtr){    UINT32  bufDestination;    /* Obtain interface and port id from the start of the buffer data  */    IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr);    bufDestination = IX_OSAL_READ_BE_SHARED_LONG( (UINT32*) IX_OSAL_MBUF_MDATA(mbufPtr) );    /* Verify it belongs to Ethernet */    if( (bufDestination & IX_EAA_MARK_MASK) != IX_EAA_ETH_MARK )    {        ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 		  "!!!Wrong buffer mark - expected to belong"                               "to Ethernet interface (buffer is lost)\n",                    0, 0, 0, 0, 0, 0);        IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumAtmRxDropBuffers++;);        return;    }    /* Extract port id from the least significant byte of first word of mbuf        data */    bufDestination &= IX_EAA_ETH_PORT_MASK;    /* Verify port is in valid range */    if( bufDestination >= IX_EAA_NUM_ETH_PORTS )    {        ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 		  "!!!Buffer belongs to invalid Ethernet port (buffer is lost)\n",                    0, 0, 0, 0, 0, 0);        IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumAtmRxDropBuffers++;);        return;    }    ixEAAEthBufferRecycle( bufDestination, mbufPtr );}/* We provide free buffers only, from 'ixEAAEthTxDoneCallback' or from    ixEAAAtmRxCallback (as a result of error condition). Basically only buffers   that were previously returned to rx handler are given to AtmdAcc component   after processing. We don't have additional pool of buffers */void ixEAAAtmRxVcFreeLowCallback(IxAtmdAccUserId userId){}/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*//*>>>>>>>>>>>>>> ETH CALLBACK AND BUFFER PROCESSING FUNCTIONS <<<<<<<<<<<<<<<<*//* * ixEAAEthBufferRecycle function returns mbuf pointed by mbufPtr back to ixEthAcc * component free rx buffer queue. Buffer is unchained (and any following * buffers in the chain). Length fields and data pointers are reset to the  * original state. Then buffer is replenished to the ethernet port associated  * with portId. Normally this function is called from ixEAAAtmTxDoneCallback * to replenish ethernet buffer after forwarding it to ATM port. It can be * called from ixEAAEthRxCallback as a result of error condition (if for  * example bufer contains chain of buffers, which application doesn't support. */void ixEAAEthBufferRecycle( IxEthAccPortId portId, IX_OSAL_MBUF * mbufPtr ){    if( IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) == NULL )    {	IX_STATUS status;	IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr);        /* invalidate only the possibly modified part (including aal5 trailer) */        IX_OSAL_CACHE_INVALIDATE(	    (UINT32) IX_OSAL_MBUF_MDATA(mbufPtr), 	    IX_OSAL_MBUF_MLEN(mbufPtr) + IX_EAA_MBUF_USER_SPACE + 48);                IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_MBUF_USER_SPACE;        IX_OSAL_MBUF_MLEN(mbufPtr) = IX_EAA_DEFAULT_MBUF_DATA_SIZE;         /* Return buffer to ixEthAcc Rx component */        status = ixEthAccPortRxFreeReplenish( portId, mbufPtr);        if (status != IX_SUCCESS)        {            ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 		      "Failed to pass Rx free buffer to ixEthAcc\n",                        0, 0, 0, 0, 0, 0);            /* If buffer replenishing fails, it means ixEthAcc component can not               accept more free buffers (internal free receive queue is full).               This should never happened, because this application replenish               only buffers that were passed to Rx callback. Therefore we assert               in such situation */            if (IX_ETH_ACC_PORT_UNINITIALIZED==status) 	    {              /* This happens when attempts to replenish to queue that its associated Eth NPE                 is not enabled. If this happens, we return mbuf back to pool */	      IX_OSAL_MBUF_POOL_PUT(mbufPtr);            }         }    }    else    {	IX_OSAL_MBUF* mbufNextPtr;	IX_STATUS status;		/* if buffer is chained, then update statistics, unchain it and replenish */	if( IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) != NULL )	{	    IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumEthRxChainedBuffers++;);	}		/* Unchain, reset and replenish buffers */	while( mbufPtr )	{	    /* Obtain next buffer from the chain */	    mbufNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr);	    /* Reset current buffer - data is changed by Atm rx callback function	       to remove RFC1483 header and now it must be set to original value */	    IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr);	    IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_MBUF_USER_SPACE;	    	    IX_OSAL_MBUF_MLEN(mbufPtr) = IX_EAA_DEFAULT_MBUF_DATA_SIZE;	    IX_OSAL_MBUF_PKT_LEN(mbufPtr) = IX_EAA_DEFAULT_MBUF_DATA_SIZE;	    /* unchain current buffer */	    IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) = NULL;	    IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(mbufPtr) = NULL;	    /* Return buffer to ixEthAcc Rx component */	    IX_OSAL_CACHE_INVALIDATE((UINT32) IX_OSAL_MBUF_MDATA(mbufPtr), 	                             IX_OSAL_MBUF_MLEN(mbufPtr));	    	    status = ixEthAccPortRxFreeReplenish( portId, mbufPtr);	    if (status != IX_SUCCESS)	    {		ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 			  "Failed to pass Rx free buffer to ixEthAcc\n",			    0, 0, 0, 0, 0, 0);		/* If buffer replenishing fails, it means ixEthAcc component can not		   accept more free buffers (internal free receive queue is full).		   This should never happened, because this application replenish		   only buffers that were passed to Rx callback. Therefore we assert		   in such situation */		if (IX_ETH_ACC_PORT_UNINITIALIZED==status) 		{		    /* This happens when attempts to replenish to queue that its associated Eth NPE		       is not enabled. If this happens, we return mbuf back to pool */		    IX_OSAL_MBUF_POOL_PUT(mbufPtr);		} 	    }	    /* take the next buffer from the chain and repeat all steps as for	       current one */	    mbufPtr = mbufNextPtr;	}    }}/* Eth Rx callback - called by ixEthAcc when new rx buffers are available for    particular port (callbackTag is different for each Eth port) */void ixEAAEthRxCallback(UINT32 callbackTag, IX_OSAL_MBUF *mbufPtr, IxEthAccPortId portId){    UINT8*           pdu;    int             ethLength;    int             numCells;    int             atmPortCnt;    int             atmVcCnt = 0;    IxAtmdAccUserId connVcId;    UINT16         *pduLengthField;    /* There is no need to invalidate the mbuf payload : invalidate     * is already done before replenish and there is no cache line     * in MMU for this mbuf     * IX_OSAL_CACHE_INVALIDATE((UINT32) IX_OSAL_MBUF_MDATA(mbufPtr),      *                              IX_OSAL_MBUF_MLEN(mbufPtr));     */#ifdef IXEAA_DEBUG      mbufDump("Eth RX", mbufPtr);#endif    ixEAANumEthRxFrames++;    pdu = IX_OSAL_MBUF_MDATA(mbufPtr);    /* Verify that pdu length is valid, which has to be greater than minimum        Ethernet frame size. Verify also that buffer is not chained */    if( IX_OSAL_MBUF_PKT_LEN(mbufPtr) < IX_EAA_MIN_ETH_FRAME_SIZE ||         IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) != NULL )    {        if( IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) != NULL )                ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 			  "WARNING: Received Ethernet frame"                                       "stored in chained buffers\n",                            0, 0, 0, 0, 0, 0);        else            ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 		      "WARNING: Received Ethernet frame"                                       "has length less than 64 bytes\n",                            0, 0, 0, 0, 0, 0);        /* Frames less than 64 bytes in size and chained ones are not supported */        ixEAAEthBufferRecycle( callbackTag, mbufPtr );        return;    }    /* The packet will be sent to the atm port 0 */    if (routedProtocol)    {       atmPortCnt = 0;    }    else    {    /* Check if destination MAC address is present in the 'Atm'        Mac database (if one of VC connections received recently packet        from that address). The array with source Mac addresses        received from Utopia needs to be searched for the occurrence. 'pdu' points       to the start of buffer, which contains dest. mac address. Start from       port 0 and increment port until Mac is found or all ports scanned */	atmVcCnt = 0;	while (atmVcCnt < IX_EAA_NUM_ATM_VCS &&	       memcmp( pdu, &atmSrcMacAddrDBase[ atmVcCnt ], 		       IX_IEEE803_MAC_ADDRESS_SIZE ))	{	    atmVcCnt++; 	}	    }    /* if atmPortCnt is less than number of enable ports, then we found right        port, otherwise Mac address is unknown and packet will be discarded */    if( atmVcCnt == IX_EAA_NUM_ATM_VCS )    {        /* IMPORTANT!!! Flooding is not normally supported, what means that           back to back configuration (IX4XX <-ADSL-> IXP4XX) will not transfer           any data. However simplified flooding can be easily implemented.           Code below is executed only if dest. MAC address on the ATM side           was not found. In such a case packet is dropped and mbuffer           recycled: ixEAAEthBufferRecycle( callbackTag, mbufPtr );           Instead of dropping packet it could be forwarded to Phy 1 of Utopia           interface, thus flooding would be supported on Phy 1. To implement           that solution code below should be commented (together with 'return;'           instruction 9 lines below) and one line should be added:           atmPortCnt = 1;. So to be precise this if(){...} statement will look            like:           if( atmPortCnt == atmNumPortsEnabled )           {               atmPortCnt = 1;           }           This will enable flooding on Phy 1 of Utopia port only. To enable it           on another Phy, atmPortCnt must be assigned corresponding value.        */#ifdef IXEAA_DEBUG        printf("Unknown Mac...");#endif        IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumEthRxMACDroppedBuffers++;);        /* if destination MAC address is not recognized by eth. driver, then           packet will be discarded and buffer recycled */        ixEAAEthBufferRecycle( callbackTag, mbufPtr );        return;    }    /* Obtain VC id using port returned from MAC data base. */    connVcId = atmVcTxId[ atmVcCnt ];    if (routedProtocol)    {       /* store the last source mac address */       memcpy(&ethSrcMacAddrDBase[callbackTag],            pdu + IX_IEEE803_MAC_ADDRESS_SIZE,           IX_IEEE803_MAC_ADDRESS_SIZE);       ethLength = IX_OSAL_MBUF_MLEN(mbufPtr);  /* obtain eth data length */       /* Calculate length of Ethernet frame with VcMux header. FCS will not be        included in encapsulated frame, therefore length of frame must be        decremented by 4. header is removed. */       ethLength -= IX_EAA_ETH_FCS_SIZE;        IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_RFC1483_VCMUX_ROUTED_HEADER_SIZE;       ethLength -= IX_EAA_RFC1483_VCMUX_ROUTED_HEADER_SIZE;     }    else    {	/* Append trailer and padding so the total length of pdu	   fits exactly into ATM cells and trailer is right justified	   in the last cell by adding pad field (0-47 bytes). */	ethLength = IX_OSAL_MBUF_MLEN(mbufPtr);  /* obtain eth data length */	/* Calculate length of Ethernet frame with VcMux header. FCS will not be 	   included in encapsulated frame, therefore length of frame must be 	   decremented by 4. RFC1483 header is added (2 bytes). */	ethLength -= IX_EAA_ETH_FCS_SIZE; 	ethLength += IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE;	/* Because this packet will be sent through ATM, therefore RFC1483	   header must be appended at the start of pdu. This will be done by	   decrementing mData pointer by 2 - header is already placed before 	   start of buffer */	IX_OSAL_MBUF_MDATA(mbufPtr) -= IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE;     }        /* Calculate total number of cells in packet (in two steps) */    /* Atm packet will also contain Aal5 CPCS-PDU trailer (8 bytes in total) */    pdu = IX_OSAL_MBUF_MDATA(mbufPtr);    numCells = (ethLength + 47) / 48 + extraAtmCellNeeded[ethLength % 48];    /* Since Aal5 CPCS-PDU trailer must be justified at the end of the cell, the       total length of the packet must be modulus of 48. Calculate number of cells */    IX_OSAL_MBUF_MLEN(mbufPtr) = numCells * 48;    IX_OSAL_MBUF_PKT_LEN(mbufPtr) = IX_OSAL_MBUF_MLEN(mbufPtr);    /* fill length field in AAL5 CPCS-PDU trailer and leave CRC field untouched       (will be filled by NPE). This code assumes processor is working in       big endian mode */    pduLengthField = (UINT16*) (pdu + 				IX_OSAL_MBUF_MLEN(mbufPtr) - 				IX_EAA_AAL5_LENGTH_POS_FROM_END_OF_TRAILER);    IX_OSAL_WRITE_BE_SHARED_SHORT(pduLengthField,(UINT16) ethLength);    /* fill trailer padding */    ixOsalMemSet(pdu + ethLength, 0x0, ((UINT8 *)pduLengthField - pdu) - ethLength);#ifdef IXEAA_DEBUG    mbufDump("Tx Atm", mbufPtr);#endif    /* submit buffer to VC */    IX_OSAL_CACHE_FLUSH((UINT32)IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr));    if( ixAtmdAccTxVcPduSubmit( connVcId, mbufPtr, 0, numCells ) !=         IX_SUCCESS )    {#ifdef IXEAA_DEBUG        printf("AtmdAcc - cell was not sent\n");#endif        /* Recycle buffer if Atm port didn't accept it */        ixEAAEthBufferRecycle( callbackTag, mbufPtr );    }    else    {        ixEAANumEthRxEthFramesForwarded++;    }}/* Eth Tx done callback - called by ixEthAcc when new tx buffer was sent and is    no longer used by ixEthAcc */void ixEAAEthTxDoneCallback(UINT32 callbackTag, IX_OSAL_MBUF *mbufPtr){    UINT32  bufDestination;    if (IX_OSAL_MBUF_NET_POOL(mbufPtr) == mBufAtmPool[0])    {       /* prioritize traffic on port 0 , recognize the pool id */	bufDestination = 0;    }    else    {	/* Obtain interface and port id from the start of the buffer data  */	IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr);	bufDestination = IX_OSAL_READ_BE_SHARED_LONG( (UINT32*) IX_OSAL_MBUF_MDATA(mbufPtr));		/* Verify it belongs to Ethernet */	if( (bufDestination & IX_EAA_MARK_MASK) != IX_EAA_ATM_MARK )	{	    ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 		      "!!!Wrong buffer mark - expected to belong to"			"Atm interface (buffer is lost)\n",			0, 0, 0, 0, 0, 0);	    IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumEthRxDropBuffers++;);	    return;	}	/* Extract port id from the least significant byte of first word of mbuf 	   data */	bufDestination &= IX_EAA_ATM_VC_MASK;	/* Verify port is in valid range */	if( bufDestination >= IX_EAA_NUM_ATM_VCS )	{	    ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, 		      "!!!Buffer belongs to invalid Atm port"			"(buffer is lost)\n",			0, 0, 0, 0, 0, 0);	    IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumEthRxDropBuffers++;);	    return;	}    }    

⌨️ 快捷键说明

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