📄 ixethaccdataplane.c
字号:
/* Check the user is not changing the callback type * when the port is enabled. */ if (ixEthAccMacState[portId].portDisableState == ACTIVE) { for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) { if ((ixEthAccMacState[port].portDisableState == ACTIVE) && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE)) { /* one of the active ports has a different rx callback type. * Changing the callback type when the port is enabled * is not safe */ return (IX_ETH_ACC_INVALID_ARG); } } } /* update the callback pointer : this is done before * registering the new qmgr callback */ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn; ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag; /* update the qmgr callback for rx queues */ if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback) != IX_ETH_ACC_SUCCESS) { /* unexpected qmgr error */ IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \ "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0); RX_INC(portId,rxUnexpectedError); return (IX_ETH_ACC_INVALID_ARG); } ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE; return (IX_ETH_ACC_SUCCESS);}IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag){ IxEthAccPortId port; if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) { return (IX_ETH_ACC_FAIL); } if (!IX_ETH_ACC_IS_PORT_VALID(portId)) { return (IX_ETH_ACC_INVALID_PORT); } if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) { IX_ETH_ACC_WARNING_LOG("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); return IX_ETH_ACC_SUCCESS ; } if (!IX_ETH_IS_PORT_INITIALIZED(portId)) { return (IX_ETH_ACC_PORT_UNINITIALIZED); } /* Check for null function pointer here. */ if (rxCallbackFn == NULL) { return (IX_ETH_ACC_INVALID_ARG); } /* Check the user is not changing the callback type * when the port is enabled. */ if (ixEthAccMacState[portId].portDisableState == ACTIVE) { for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) { if ((ixEthAccMacState[port].portDisableState == ACTIVE) && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE)) { /* one of the active ports has a different rx callback type. * Changing the callback type when the port is enabled * is not safe */ return (IX_ETH_ACC_INVALID_ARG); } } } /* update the callback pointer : this is done before * registering the new qmgr callback */ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn; ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag; /* update the qmgr callback for rx queues */ if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback) != IX_ETH_ACC_SUCCESS) { /* unexpected qmgr error */ RX_INC(portId,rxUnexpectedError); IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \ "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0); return (IX_ETH_ACC_INVALID_ARG); } ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE; return (IX_ETH_ACC_SUCCESS);}IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId, IX_OSAL_MBUF *buffer, IxEthAccTxPriority priority){ IX_STATUS qStatus = IX_SUCCESS; UINT32 qBuffer; IxEthAccTxPriority highestPriority; IxQMgrQStatus txQStatus;#ifndef NDEBUG if (buffer == NULL) { return (IX_ETH_ACC_FAIL); } if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) { return (IX_ETH_ACC_FAIL); } if (!IX_ETH_ACC_IS_PORT_VALID(portId)) { return (IX_ETH_ACC_INVALID_PORT); } if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) { IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n", (INT32)portId,0,0,0,0,0); return IX_ETH_ACC_PORT_UNINITIALIZED ; } if (!IX_ETH_IS_PORT_INITIALIZED(portId)) { return (IX_ETH_ACC_PORT_UNINITIALIZED); } if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7) { return (IX_ETH_ACC_INVALID_ARG); }#endif /* * Need to Flush the MBUF and its contents (data) as it may be * read from the NPE. Convert virtual addresses to physical addresses also. */ qBuffer = ixEthAccMbufTxQPrepare(buffer); /* * If no fifo priority set on Xscale ... */ if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == FIFO_NO_PRIORITY) { /* * Add The Tx Buffer to the H/W Tx Q if possible * (the priority is passed to the NPE, because * the NPE is able to reorder the frames * before transmission to the underlying hardware) */ qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, IX_ETH_ACC_TX_DEFAULT_PRIORITY); if (qStatus == IX_SUCCESS) { TX_STATS_INC(portId,txQOK); /* * "best case" scenario : Buffer added to h/w Q. */ return (IX_SUCCESS); } else if (qStatus == IX_QMGR_Q_OVERFLOW) { /* * We were unable to write the buffer to the * appropriate H/W Q, Save it in the sw Q. * (use the default priority queue regardless of * input parameter) */ priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY; } else { /* unexpected qmgr error */ TX_INC(portId,txUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n", (UINT32)qStatus, 0, 0, 0, 0, 0); return (IX_ETH_ACC_FAIL); } } else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == FIFO_PRIORITY) { /* * For priority transmission, put the frame directly on the H/W queue * if the H/W queue is empty, otherwise, put it in a S/W Q */ ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus); if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0) { /*The tx queue is empty, check whether there are buffers on the s/w queues*/ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) !=IX_ETH_ACC_FAIL) { /*there are buffers on the s/w queues, submit them*/ ixEthAccTxFromSwQ(portId, highestPriority); /* the queue was empty, 1 buffer is already supplied * but is likely to be immediately transmitted and the * hw queue is likely to be empty again, so submit * more from the sw queues */ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) !=IX_ETH_ACC_FAIL) { ixEthAccTxFromSwQ(portId, highestPriority); /* * and force the buffer supplied to be placed * on a priority queue */ qStatus = IX_QMGR_Q_OVERFLOW; } else { /*there are no buffers in the s/w queues, submit directly*/ qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); } } else { /*there are no buffers in the s/w queues, submit directly*/ qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); } } else { qStatus = IX_QMGR_Q_OVERFLOW; } } else { TX_INC(portId,txUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n", 0, 0, 0, 0, 0, 0); return (IX_ETH_ACC_FAIL); } if(qStatus == IX_SUCCESS ) { TX_STATS_INC(portId,txQOK); return IX_ETH_ACC_SUCCESS; } else if(qStatus == IX_QMGR_Q_OVERFLOW) { TX_STATS_INC(portId,txQDelayed); /* * We were unable to write the buffer to the * appropriate H/W Q, Save it in a s/w Q. */ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( ixEthAccPortData[portId]. ixEthAccTxData.txQ[priority], buffer); qStatus = ixQMgrNotificationEnable( IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); if (qStatus != IX_SUCCESS) { if (qStatus == IX_QMGR_WARNING) { /* notification is enabled for a queue * which is already empty (the condition is already met) * and there will be no more queue event to drain the sw queue */ TX_STATS_INC(portId,txLateNotificationEnabled); /* pull a buffer from the sw queue */ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) !=IX_ETH_ACC_FAIL) { /*there are buffers on the s/w queues, submit from them*/ ixEthAccTxFromSwQ(portId, highestPriority); } } else { TX_INC(portId,txUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", qStatus, 0, 0, 0, 0, 0); } } } else { TX_INC(portId,txUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", qStatus, 0, 0, 0, 0, 0); return (IX_ETH_ACC_FAIL); } return (IX_ETH_ACC_SUCCESS);}/** * * @brief replenish: convert a chain of mbufs to the format * expected by the NPE * */IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId, IX_OSAL_MBUF *buffer){ IX_STATUS qStatus = IX_SUCCESS; UINT32 qBuffer; /* * Check buffer is valid. */#ifndef NDEBUG /* check parameter value */ if (buffer == 0) { return (IX_ETH_ACC_FAIL); } if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) { return (IX_ETH_ACC_FAIL); } if (!IX_ETH_ACC_IS_PORT_VALID(portId)) { return (IX_ETH_ACC_INVALID_PORT); } /* check initialisation is done */ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) { IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0); return IX_ETH_ACC_PORT_UNINITIALIZED ; } if (!IX_ETH_IS_PORT_INITIALIZED(portId)) { return (IX_ETH_ACC_PORT_UNINITIALIZED); } /* check boundaries and constraints */ if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) { return (IX_ETH_ACC_FAIL); }#endif qBuffer = ixEthAccMbufRxQPrepare(buffer); /* * Add The Rx Buffer to the H/W Free buffer Q if possible */ qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer); if (qStatus == IX_SUCCESS) { RX_STATS_INC(portId,rxFreeRepOK); /* * Buffer added to h/w Q. */ return (IX_SUCCESS); } else if (qStatus == IX_QMGR_Q_OVERFLOW) { RX_STATS_INC(portId,rxFreeRepDelayed); /* * We were unable to write the buffer to the approprate H/W Q, * Save it in a s/w Q. */ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, buffer); qStatus = ixQMgrNotificationEnable( IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId)); if (qStatus != IX_SUCCESS) { if (qStatus == IX_QMGR_WARNING) { /* notification is enabled for a queue * which is already empty (the condition is already met) * and there will be no more queue event to drain the sw queue * move an entry from the sw queue to the hw queue */ RX_STATS_INC(portId,rxFreeLateNotificationEnabled); ixEthAccRxFreeFromSwQ(portId); } else { RX_INC(portId,rxUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthAccRxPortFreeReplenish:Error: %u\n", qStatus, 0, 0, 0, 0, 0); } } } else { RX_INC(portId,rxUnexpectedError); IX_ETH_ACC_FATAL_LOG( "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n", (UINT32)qStatus, 0, 0, 0, 0, 0); return(IX_ETH_ACC_FAIL); } return (IX_ETH_ACC_SUCCESS);}IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched){ if (!IX_ETH_ACC_IS_PORT_VALID(portId)) { return (IX_ETH_ACC_INVALID_PORT); } if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) { IX_ETH_ACC_WARNING_LOG("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0); return IX_ETH_ACC_SUCCESS ; } if (!IX_ETH_IS_PORT_INITIALIZED(portId)) { return (IX_ETH_ACC_PORT_UNINITIALIZED); } if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) { return (IX_ETH_ACC_INVALID_ARG); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -