📄 ixethaccdataplane.c
字号:
#ifndef NDEBUG if (mbufPtr == NULL) { ixEthAccDataStats.unexpectedError++; IX_ETH_ACC_FATAL_LOG( "ixEthRxMultiBufferPriorityPoll: Null Mbuf Ptr\n", 0, 0, 0, 0, 0, 0); return qEntriesProcessed; }#endif /* convert the next entry * (the conversion function takes care about null pointers which * are used to mark the end of the loop) */ nextQEntry = *(++qEntryPtr); nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); /* * Get Port ID from message. */ portId = IX_ETHNPE_NODE_AND_PORT_TO_PHYSICAL_ID(IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(qEntry),IX_ETHNPE_QM_Q_PID_VAL(qEntry)); /* process frame, check the return code and skip the remaining of * the loop if the frame is to be filtered out */ if (ixEthRxFrameProcess(portId, mbufPtr)) { /* store a mbuf pointer in an array */ *rxMbufPtr[portId]++ = mbufPtr; /* * increment priority stats */ RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); qEntriesProcessed++; } } } /* check if any of the the arrays contains any entry */ for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) { if (rxMbufPtr[portId] != rxMbufPortArray[portId]) { /* add a last NULL pointer at the end of the * array of mbuf pointers */ *rxMbufPtr[portId] = NULL; /* * increment callback count stats */ RX_STATS_INC(portId,rxFrameClientCallback); /* * Call user level callback with an array of * buffers (NULL terminated) */ ixEthAccPortData[portId].ixEthAccRxData. rxMultiBufferCallbackFn( ixEthAccPortData[portId].ixEthAccRxData. rxMultiBufferCallbackTag, rxMbufPortArray[portId]); /* reset the buffer pointer to the beginning of * the array */ rxMbufPtr[portId] = rxMbufPortArray[portId]; } } return qEntriesProcessed;}/** * @fn ixEthRxFrameQMCallback * * @brief receive callback for Frame receive Q from NPE * * Frames are passed one-at-a-time to the user * * @param @ref IxQMgrCallback * * @return none * * @internal * * Design note : while processing the entry X, entry X+1 is preloaded * into memory to reduce the number of stall cycles * */void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId){ IX_OSAL_MBUF *mbufPtr; IX_OSAL_MBUF *nextMbufPtr; UINT32 qEntry; UINT32 nextQEntry; UINT32 *qEntryPtr; UINT32 portId; UINT32 destPortId; UINT32 rxQReadStatus; /* * Design note : entries are read in a buffer, This buffer contains * an extra zeroed entry so the loop will * always terminate on a null entry, whatever the result of Burst read is. */ UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK + 1]; /* * Indication of the number of times the callback is used. */ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); do { /* * Indication of the number of times the queue is drained */ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); /* ensure the last entry of the array contains a zeroed value */ qEntryPtr = rxQEntry; qEntryPtr[IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK] = 0; rxQReadStatus = ixQMgrQBurstRead(qId, IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK, qEntryPtr);#ifndef NDEBUG if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) && (rxQReadStatus != IX_SUCCESS)) { ixEthAccDataStats.unexpectedError++; /*major error*/ IX_ETH_ACC_FATAL_LOG( "ixEthRxFrameQMCallback:Error: %u\n", (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); return; }#endif /* convert and preload the next entry * (the conversion function takes care about null pointers which * are used to mark the end of the loop) */ nextQEntry = *qEntryPtr; nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); while(nextQEntry != 0) { /* get the next entry */ qEntry = nextQEntry; mbufPtr = nextMbufPtr;#ifndef NDEBUG if (mbufPtr == NULL) { ixEthAccDataStats.unexpectedError++; IX_ETH_ACC_FATAL_LOG( "ixEthRxFrameQMCallback: Null Mbuf Ptr\n", 0, 0, 0, 0, 0, 0); return; }#endif /* convert the next entry * (the conversion function takes care about null pointers which * are used to mark the end of the loop) */ nextQEntry = *(++qEntryPtr); nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); /* * Get Port ID from message. */ portId = IX_ETHNPE_NODE_AND_PORT_TO_PHYSICAL_ID(IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(qEntry),IX_ETHNPE_QM_Q_PID_VAL(qEntry)); /* process frame, check the return code and skip the remaining of * the loop if the frame is to be filtered out */ if (ixEthRxFrameProcess(portId, mbufPtr)) { /* destination portId for this packet */ destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr); if (destPortId != IX_ETH_DB_UNKNOWN_PORT) { destPortId = IX_ETHNPE_LOGICAL_ID_TO_PHYSICAL_ID(destPortId); } /* * increment callback count stats */ RX_STATS_INC(portId,rxFrameClientCallback); /* * Call user level callback. */ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn( ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag, mbufPtr, destPortId); } } } while (rxQReadStatus == IX_SUCCESS);}/** * @fn ixEthRxMultiBufferQMCallback * * @brief receive callback for Frame receive Q from NPE * * Frames are passed as an array to the user * * @param @ref IxQMgrCallback * * @return none * * @internal * * Design note : while processing the entry X, entry X+1 is preloaded * into memory to reduce the number of stall cycles * */void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId){ IX_OSAL_MBUF *mbufPtr; IX_OSAL_MBUF *nextMbufPtr; UINT32 qEntry; UINT32 nextQEntry; UINT32 *qEntryPtr; UINT32 portId; UINT32 rxQReadStatus; /* * Design note : entries are read in a static buffer, This buffer contains * an extra zeroed entry so the loop will * always terminate on a null entry, whatever the result of Burst read is. */ static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK + 1]; static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK + 1]; IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS]; for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) { rxMbufPtr[portId] = rxMbufPortArray[portId]; } /* * Indication of the number of times the callback is used. */ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); do { /* * Indication of the number of times the queue is drained */ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); /* ensure the last entry of the array contains a zeroed value */ qEntryPtr = rxQEntry; qEntryPtr[IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK] = 0; rxQReadStatus = ixQMgrQBurstRead(qId, IX_ETH_ACC_MAX_RX_MBUF_CONSUME_PER_CALLBACK, qEntryPtr);#ifndef NDEBUG if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) && (rxQReadStatus != IX_SUCCESS)) { ixEthAccDataStats.unexpectedError++; /*major error*/ IX_ETH_ACC_FATAL_LOG( "ixEthRxFrameMultiBufferQMCallback:Error: %u\n", (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); return; }#endif /* convert and preload the next entry * (the conversion function takes care about null pointers which * are used to mark the end of the loop) */ nextQEntry = *qEntryPtr; nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); while(nextQEntry != 0) { /* get the next entry */ qEntry = nextQEntry; mbufPtr = nextMbufPtr;#ifndef NDEBUG if (mbufPtr == NULL) { ixEthAccDataStats.unexpectedError++; IX_ETH_ACC_FATAL_LOG( "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n", 0, 0, 0, 0, 0, 0); return; }#endif /* convert the next entry * (the conversion function takes care about null pointers which * are used to mark the end of the loop) */ nextQEntry = *(++qEntryPtr); nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); /* * Get Port ID from message. */ portId = IX_ETHNPE_NODE_AND_PORT_TO_PHYSICAL_ID(IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(qEntry),IX_ETHNPE_QM_Q_PID_VAL(qEntry)); /* skip the remaining of the loop if the frame is * to be filtered out */ if (ixEthRxFrameProcess(portId, mbufPtr)) { /* store a mbuf pointer in an array */ *rxMbufPtr[portId]++ = mbufPtr; /* * increment priority stats */ RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); } } /* check if any of the the arrays contains any entry */ for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) { if (rxMbufPtr[portId] != rxMbufPortArray[portId]) { /* add a last NULL pointer at the end of the * array of mbuf pointers */ *rxMbufPtr[portId] = NULL; /* * increment callback count stats */ RX_STATS_INC(portId,rxFrameClientCallback); /* * Call user level callback with an array of * buffers (NULL terminated) */ ixEthAccPortData[portId].ixEthAccRxData. rxMultiBufferCallbackFn( ixEthAccPortData[portId].ixEthAccRxData. rxMultiBufferCallbackTag, rxMbufPortArray[portId]); /* reset the buffer pointer to the beginning of * the array */ rxMbufPtr[portId] = rxMbufPortArray[portId]; } } } while (rxQReadStatus == IX_SUCCESS);}/** * @brief rxFree low event handler * */void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId){ IxEthAccPortId portId = (IxEthAccPortId) callbackId; int lockVal; UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD; IX_STATUS qStatus = IX_SUCCESS; /* * We have reached a low threshold on one of the Rx Free Qs */ /*note that due to the fact that we are working off an Empty threshold, this callback need only write a single entry to the Rx Free queue in order to re-arm the notification */ RX_STATS_INC(portId,rxFreeLowCallback); /* * Get buffers from approprite S/W Rx freeBufferList Q. */ #ifndef NDEBUG if (!IX_ETH_ACC_IS_PORT_VALID(portId)) { ixEthAccDataStats.unexpectedError++; IX_ETH_ACC_FATAL_LOG( "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n", portId, 0, 0, 0, 0, 0); return; }#endif IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. ixEthAccRxData.freeBufferList)) { /* * Turn off Q callback notification for Q in Question. */ qStatus = ixQMgrNotificationDisable( IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); if (qStatus != IX_SUCCESS) { RX_INC(portId,rxUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n", qStatus, 0, 0, 0, 0, 0); return; } } else { IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); /* * Load the H/W Q with buffers from the s/w Q. */ do { /* * Consume Q entries. - Note Q contains Physical addresss, * and have already been flushed to memory, * And endianess converted if required. */ if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS) { /* * No more entries in s/w Q. * Turn off Q callback indication */ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. ixEthAccRxData.freeBufferList)) { qStatus = ixQMgrNotificationDisable( IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); } IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); break; } } while (--maxQWritesToPerf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -