📄 ixethaal5app.c
字号:
printf("Invalid Atm VC specified - must be in range 0 to IX_EAA_NUM_ATM_VCS (i.e. %d)\n", IX_EAA_NUM_ATM_VCS); return; } atmSrcMacAddrDBase[vc].macAddress[0] = mac1; atmSrcMacAddrDBase[vc].macAddress[1] = mac2; atmSrcMacAddrDBase[vc].macAddress[2] = mac3; atmSrcMacAddrDBase[vc].macAddress[3] = mac4; atmSrcMacAddrDBase[vc].macAddress[4] = mac5; atmSrcMacAddrDBase[vc].macAddress[5] = mac6; printf("\nVC %d with MAC Address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", vc, mac1, mac2, mac3, mac4, mac5, mac6);}void ixEAAShowMAC(void){ int vc; for (vc = 0 ; vc< IX_EAA_NUM_ATM_VCS ; vc++) { printf("\nVC %d with MAC Address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", vc, atmSrcMacAddrDBase[vc].macAddress[0], atmSrcMacAddrDBase[vc].macAddress[1], atmSrcMacAddrDBase[vc].macAddress[2], atmSrcMacAddrDBase[vc].macAddress[3], atmSrcMacAddrDBase[vc].macAddress[4], atmSrcMacAddrDBase[vc].macAddress[5]); } return;}/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*//* * ixEAABufferInit function initialize the beginning of mbuf data with * a poolId (used to replenish the mbuf to its correct VC channel * or ethernet port, and the RFC 1483 header placeholder. */ void ixEAABufferInit(IX_OSAL_MBUF *mbufPtr, UINT32 poolId){ unsigned char *payloadPtr; /* initialize first 4 bytes of mData to poolId and increment mData pointer (so poolId will be hidden for AtmdAcc and ixEthAcc components */ IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr); payloadPtr = (unsigned char *)IX_OSAL_MBUF_MDATA(mbufPtr); IX_OSAL_WRITE_BE_SHARED_LONG(((UINT32*)IX_OSAL_MBUF_MDATA(mbufPtr)),poolId); IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_MBUF_USER_SPACE; /* initialize last 2 bytes to RFC1483 header related to VC based multiplexing of Ethernet/802.3 PDUs. */ IX_OSAL_MBUF_MDATA(mbufPtr) -= IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; IX_OSAL_WRITE_BE_SHARED_SHORT(IX_OSAL_MBUF_MDATA(mbufPtr),IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER); IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; /* note that mData is moved by 8 words from original start */ /* flush the 8 words of user space */ IX_OSAL_CACHE_FLUSH((UINT32)payloadPtr, IX_EAA_MBUF_USER_SPACE); IX_OSAL_CACHE_FLUSH((UINT32)IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr));}/*>>>>>>>>>>> ATMDACC CALLBACK AND BUFFER PROCESSING FUNCTIONS <<<<<<<<<<<<<<*//* * ixEAAAtmBufferRecycle function returns mbuf pointed by mbufPtr back to * AtmdAcc component free buffer receive 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 VC associated with vcId */ void ixEAAAtmBufferRecycle( IxAtmConnId vcId, IX_OSAL_MBUF * mbufPtr ){ if( IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) == NULL) { IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr); /* invalidate the part of cache possibly used (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_MDATA(mbufPtr) -= IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; IX_OSAL_MBUF_MLEN(mbufPtr) = IX_EAA_DEFAULT_MBUF_DATA_SIZE; /* Return buffer to AtmdAcc Rx component */ if (ixAtmdAccRxVcFreeReplenish (vcId, mbufPtr) != IX_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "Failed to pass Rx free buffer to AtmdAcc\n", 0, 0, 0, 0, 0, 0); /* If buffer replenishing fails, it means AtmdAcc 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 */ IX_OSAL_ASSERT(FALSE); } } else { IX_OSAL_MBUF* mbufCurPtr = mbufPtr; /* if buffer is chained, then update statistics, unchain it and replenish */ if( IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) ) IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumAtmRxChainedBuffers++;); /* Unchain, reset and replenish buffers */ while( mbufCurPtr ) { mbufPtr = mbufCurPtr; /* Obtain next buffer from the chain */ mbufCurPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufCurPtr); /* Reset current buffer */ IX_OSAL_MBUF_POOL_MDATA_RESET(mbufPtr); IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_MBUF_USER_SPACE; IX_OSAL_MBUF_MDATA(mbufPtr) -= IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; 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 AtmdAcc Rx component */ IX_OSAL_CACHE_INVALIDATE((UINT32) IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr)); if (ixAtmdAccRxVcFreeReplenish (vcId, mbufPtr) != IX_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "Failed to pass Rx free buffer to AtmdAcc\n", 0, 0, 0, 0, 0, 0); /* If buffer replenishing fails, it means AtmdAcc 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 */ IX_OSAL_ASSERT(FALSE); } } }}/* ---------------------------------------------------*/#ifdef IXEAA_DEBUGstatic voidmbufDump (char *s, IX_OSAL_MBUF * mbufPtr){ printf (">> %s >>", s); while (mbufPtr) { unsigned char *ptChar = (unsigned char *)IX_OSAL_MBUF_MDATA(mbufPtr); unsigned int len = IX_OSAL_MBUF_MLEN(mbufPtr); unsigned int cpt = 0; printf ("\nMbuf length %u : ", len); while (len--) { if ((cpt++ % 16) == 0) { printf("\n%8.8x : ", cpt - 1); } printf ("%2.2x ", (int) *ptChar++); } printf ("\n"); mbufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr); } /* end of while(mbufPtr) */ printf (">>>>>\n");}#endif#ifdef _DIAB_TOOL__asm volatile void _pduPrefetch (volatile UINT8* pdu) {% reg pdu; pld [pdu];}#endif /* #ifdef _DIAB_TOOL *//* ATM Rx callback - called by AtmdAcc when new rx buffers are available for particular connection */void ixEAAAtmRxCallback(IxAtmLogicalPort port, IxAtmdAccUserId userId, IxAtmdAccPduStatus status, IxAtmdAccClpStatus clp, IX_OSAL_MBUF * mbufPtr){ int len; UINT8* pdu; IxEthAccPortId ethPortId = 0; int ethLength; /* 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)); */#ifndef __wince /* preload the last cache line (AAL5 trailer) */ pdu = IX_OSAL_MBUF_MDATA(mbufPtr); pdu += ((IX_OSAL_MBUF_MLEN(mbufPtr) - IX_EAA_AAL5_LENGTH_POS_FROM_END_OF_TRAILER) & ~31);#ifdef _DIAB_TOOL _pduPrefetch(pdu);#else __asm__ ("pld [%0]\n": : "r" (pdu)); #endif /* #ifdef _DIAB_TOOL */#endif pdu = IX_OSAL_MBUF_MDATA(mbufPtr); len = IX_OSAL_MBUF_PKT_LEN(mbufPtr); ixEAANumAtmRxPackets++;#ifdef IXEAA_DEBUG mbufDump("Atm RX", mbufPtr);#endif /* Verify that pdu is valid and also that buffer is not chained */ if( status != IX_ATMDACC_AAL5_VALID || IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) != NULL) { /* Status IX_ATMDACC_MBUF_RETURN is passed to Rx callback when AtmdAcc is shutting down VC. In such a case AtmdAcc is returning all client buffers through Rx callback. This application doesn't handle VC connections dynamically (opening/closing VCs at runtime). It means that we can ignore buffers in this situation as they no longer will be used. */ IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumAtmRxDropBuffers++;); if( status == IX_ATMDACC_MBUF_RETURN ) { return; } ixEAAAtmBufferRecycle( atmVcRxId[ userId ], mbufPtr ); return; } if (IX_OSAL_READ_BE_SHARED_SHORT((UINT16*) pdu) == IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER ) { routedProtocol = FALSE; /* Because this packet will be sent through Ethernet, therefore RFC1483 header must be removed from the start of pdu. This will be done by incrementing mData pointer by 2 */ IX_OSAL_MBUF_MDATA(mbufPtr) += IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; pdu += IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; /* compare the frame dst/src with the last one received */ if (!memcmp(atmMacAddrLookup[ userId ], pdu, 2 * IX_IEEE803_MAC_ADDRESS_SIZE )) { /* same source, same destination */ ethPortId = atmPortIdLookup[ userId ]; } else { /* Obtain destination MAC address and check if it is recognized by Ethernet driver (if one of Ethernet ports ever received packet from that address */ if( ixEthDBFilteringDatabaseSearch((void*)ðPortId, (IxEthDBMacAddr*) pdu) != IX_ETH_ACC_SUCCESS ) { /* IMPORTANT!!! Flooding is not normally supported, what means that back to back configuration (IXP4XX <-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 Eth side was not found. In such a case packet is dropped and mbuffer recycled: ixEAAAtmBufferRecycle( atmVcRxId[ userId ], mbufPtr ); Instead of dropping packet it could be forwarded to port Eth1. In such case flooding would be supported on Eth1. To implement that solution code below should be commented (together with 'return;' instruction 15 lines below) and one line should be added: ethPortId = IX_ETH_PORT_1;. So to be precise this if(){...} statement will look like: if( ixEthDBFilteringDatabaseSearch( ðPortId, (IxEthDBMacAddr*) pdu) != IX_ETH_ACC_SUCCESS ) { ethPortId = IX_ETH_PORT_1; } This will enable flooding on port Eth1 only. To enable it on another port, ethPortId must be assigned corresponding value. */ IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumAtmRxMACDroppedBuffers++;); /* if destination MAC address is not recognized by eth. driver, then packet will be discarded and buffer recycled */ ixEAAAtmBufferRecycle( atmVcRxId[ userId ], mbufPtr ); return; } /* Obtain source MAC and add it to the 'Atm' MAC database Database holds only one Mac address per Vc, so we need to copy source Mac address to the Mac data base array at location pointed by Vc number (userId). Source Mac address follows destinations Mac address in the pdu */ memcpy( &atmSrcMacAddrDBase[ userId ], (pdu + IX_IEEE803_MAC_ADDRESS_SIZE), IX_IEEE803_MAC_ADDRESS_SIZE ); /* update the internal lookup */ atmPortIdLookup[ userId ] = ethPortId; memcpy( atmMacAddrLookup[ userId ], pdu, 2 * IX_IEEE803_MAC_ADDRESS_SIZE ); } /* position pdu pointer on the length field in AAL5 CPCS-PDU trailer (starts 6 bytes from the end of the PDU). Pdu was already incremented by IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE, so we need to take it into account here as well */ pdu += (len - IX_EAA_AAL5_LENGTH_POS_FROM_END_OF_TRAILER) - IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; /* obtained eth frame length = PDU length - RFC1483 header size. the PDU length is stored in two bytes, therefore we cast pdu to UINT16 */ ethLength = IX_OSAL_READ_BE_SHARED_SHORT( (UINT16*) (pdu) ) - IX_EAA_RFC1483_VCMUX_BRIDGED_HEADER_SIZE; } else if (IX_OSAL_READ_BE_SHARED_SHORT((UINT16*) pdu) == IX_EAA_RFC1483_VCMUX_ROUTED_IP_HEADER ) { routedProtocol = TRUE; /* position pdu pointer on the length field in AAL5 CPCS-PDU trailer (starts 6 bytes from the end of the PDU). */ pdu += len - IX_EAA_AAL5_LENGTH_POS_FROM_END_OF_TRAILER; /* obtained eth frame length = PDU length - RFC1483 header size. the PDU length is stored in two bytes, therefore we cast pdu to UINT16 */ ethLength = IX_OSAL_READ_BE_SHARED_SHORT((UINT16*)pdu); /* tx to eth port 1 */ ethPortId = IX_ETH_PORT_1; /* prepend the MAC addresses and length (802.3 header) */ IX_OSAL_MBUF_MDATA(mbufPtr) -= IX_EAA_RFC1483_VCMUX_ROUTED_HEADER_SIZE; pdu = IX_OSAL_MBUF_MDATA(mbufPtr); memcpy(pdu, ðSrcMacAddrDBase[ethPortId], IX_IEEE803_MAC_ADDRESS_SIZE); pdu += IX_IEEE803_MAC_ADDRESS_SIZE; memcpy(pdu, &macAddr1, IX_IEEE803_MAC_ADDRESS_SIZE); pdu += IX_IEEE803_MAC_ADDRESS_SIZE; IX_OSAL_WRITE_BE_SHARED_SHORT((UINT16*)pdu,0x800); ethLength += IX_EAA_RFC1483_VCMUX_ROUTED_HEADER_SIZE; } else { /* drop the packet - this may occur for ICMP-like PDUs or bad-formed packets */ ixEAAAtmBufferRecycle( atmVcRxId[ userId ], mbufPtr ); return; } /* check that the ethernet frame length is valid */ if( ethLength < IX_EAA_MIN_ETH_FRAME_SIZE || ethLength > IX_EAA_MAX_ETH_FRAME_SIZE ) { IX_ETHAAL5APP_CODELET_DEBUG_DO(ixEAANumAtmRxDropBuffers++;); ixEAAAtmBufferRecycle( atmVcRxId[ userId ], mbufPtr ); return; } /* make mbuffers data length equal to Ethernet frame length and send it to appropriate Ethernet port */ IX_OSAL_MBUF_MLEN(mbufPtr) = ethLength; IX_OSAL_MBUF_PKT_LEN(mbufPtr) = ethLength; IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(mbufPtr) = NULL; #ifdef IXEAA_DEBUG mbufDump("Tx Eth", mbufPtr);#endif IX_OSAL_CACHE_FLUSH((UINT32)IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr)); /* submit buffer to Ethernet port */ if( ixEthAccPortTxFrameSubmit( ethPortId, mbufPtr, IX_ETH_ACC_TX_PRIORITY_4 ) != IX_ETH_ACC_SUCCESS )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -