📄 ixethacccommon.c
字号:
rxQueues[rxQueue+1].trafficClass) &&(rxQueues[rxQueue].npeId < rxQueues[rxQueue+1].npeId))) { /* swap adjacent elements */ int npeCount = rxQueues[rxQueue].npeCount; UINT32 npeId = rxQueues[rxQueue].npeId; IxQMgrQId qId = rxQueues[rxQueue].qId; IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass; rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount; rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId; rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId; rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass; rxQueues[rxQueue+1].npeCount = npeCount; rxQueues[rxQueue+1].npeId = npeId; rxQueues[rxQueue+1].qId = qId; rxQueues[rxQueue+1].trafficClass = trafficClass; completelySorted = FALSE; } } } while (!completelySorted); return (IX_ETH_ACC_SUCCESS);}/** * @fn ixEthAccQMgrQueuesConfig(void) * * @brief Setup all the queues and register all callbacks required * by this component to the QMgr * * Rx queues configuration is driven by QoS setup. * Many Rx queues may be required when QoS is enabled (this depends * on IxEthDB setup and the images being downloaded). The configuration * of the rxQueues is done in many steps as follows: * * @li select all Rx queues as configured by ethDB for all ports * @li sort the queues by traffic class * @li build the priority dependency for all queues * @li fill the configuration for all rx queues * @li configure all statically configured queues * @li configure all dynamically configured queues * * @param none * * @return IxEthAccStatus * * @internal */IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccQMgrQueuesConfig(IxEthAccPortId portId){ IxEthAccQregInfo qInfoDes; IxEthAccQregInfo rxFreeQInfoDes; IxEthAccQregInfo txQInfoDes; UINT32 rxQueue = 0; /* Rx queue list stored globally */ IxEthAccRxQueue *rxQueues = ixEthAccRxQueues; IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; IxEthNpeNodeId ixNpeId = IX_ETHNPE_PHYSICAL_ID_TO_NODE(portId); /* Configure the TxDone Queue * Note that the TxDone queue is shared by all ports * ixEthAccQMgrQueueSetup makes sure it is not configured again */ memcpy(&qInfoDes, &ixEthAccQmgrTxDoneTemplate, sizeof(qInfoDes)); /* setup the TxDone Queue watermark level from the static table */ qInfoDes.AlmostFullThreshold = ixEthAccQueueNFWatermarkTable[ixEthAccDataInfo.npeCount]; ret = ixEthAccQMgrQueueSetup(&qInfoDes); if(ret) return (ret); /* Configure the TX and RxFree Queues for this port */ memcpy(&rxFreeQInfoDes, &ixEthAccQmgrRxFreeTemplate, sizeof(rxFreeQInfoDes)); ixEthAccPortData[portId].ixEthAccRxData.rxFreeQueueSource \ = rxFreeQInfoDes.qConditionSource; rxFreeQInfoDes.callbackTag = portId; memcpy(&txQInfoDes, &ixEthAccQmgrTxTemplate, sizeof(txQInfoDes)); ixEthAccPortData[portId].ixEthAccTxData.txQueueSource \ = txQInfoDes.qConditionSource; txQInfoDes.callbackTag = portId; ixEthAccPortData[portId].ixEthAccRxData.rxFreeQueue \ = rxFreeQInfoDes.qId \ = ixEthAccNpeStaticQueueConfigs[ixNpeId][IX_ETHACC_RXFREE_QUEUE_ASSIGNMENT_INDEX]; ixEthAccPortData[portId].ixEthAccTxData.txQueue \ = txQInfoDes.qId \ = ixEthAccNpeStaticQueueConfigs[ixNpeId][IX_ETHACC_TX_QUEUE_ASSIGNMENT_INDEX]; ret = ixEthAccQMgrQueueSetup(&rxFreeQInfoDes); if(ret) return (ret); ret = ixEthAccQMgrQueueSetup(&txQInfoDes); if(ret) return (ret); /* Get RX queue list */ ret = ixEthAccGetRxQueueList(portId, rxQueues); if(ret) return (ret); /* get RX queue template for the queues */ memcpy(&qInfoDes, &ixEthAccQmgrRxTemplate, sizeof(qInfoDes)); /* go through all the queues configuring with proper parameters: * - queue ID (from rxQueues list) * - queue size (larger size for higher priority queues) * - Almost full watermark (based on npe count for queue) */ for (rxQueue = 0; (rxQueues[rxQueue].npeCount != 0) && (ret == IX_ETH_ACC_SUCCESS); rxQueue++) { /* copy the local priority qId into dataplane struct and add to bitmask */ ixEthAccDataInfo.rxQueues[rxQueue] = rxQueues[rxQueue].qId; ixEthAccDataInfo.rxQueuesIntMask |= (1 << (rxQueues[rxQueue].qId)); /* setup the Rx Queue ID */ qInfoDes.qId = rxQueues[rxQueue].qId; /* setup the Rx Queue size from static table */ qInfoDes.qSize = ixEthAccRxQueueSizeTable[rxQueue]; /* setup the Rx Queue watermark level from the static table */ qInfoDes.AlmostFullThreshold = ixEthAccQueueNFWatermarkTable[rxQueues[rxQueue].npeCount]; /* Set the callback tag in Rx queue storage * Used for callback registration */ rxQueues[rxQueue].callbackTag = qInfoDes.callbackTag; /* configure this queue */ ret = ixEthAccQMgrQueueSetup(&qInfoDes); } /* set invalid last entry in dataplane struct */ ixEthAccDataInfo.rxQueues[rxQueue] = IX_QMGR_MAX_NUM_QUEUES; /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */ ixEthDBFeaturePropertySet(portId, IX_ETH_DB_VLAN_QOS, IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE, NULL /* ignored */); return (ret); }/* @ixEthUnconfigQueues * * @params none * * @fn - unconfigures the queues configured in ixEthAccInit * * @return IxEthAccStatus */IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccQueuesUnconfig (void){ IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; IxEthAccQregInfo qInfoDes; IxEthAccPortId portId; UINT32 rxQueue = 0; /* Rx queue list stored globally */ IxEthAccRxQueue *rxQueues = ixEthAccRxQueues; /* Get RX queue list */ ret = ixEthAccGetRxQueueList(0, rxQueues); if(ret) return (ret); /* un configure the Rx queues */ for (rxQueue = 0; (rxQueues[rxQueue].npeCount != 0) && (ret == IX_ETH_ACC_SUCCESS); rxQueue++) { memset(&qInfoDes, 0, sizeof(IxEthAccQregInfo)); qInfoDes.qId = rxQueues[rxQueue].qId; ret = ixEthAccQMgrQueueUnsetup (&qInfoDes); } /* clear the rxQueues data structure */ memset(rxQueues, 0, sizeof(ixEthAccRxQueues)); /* un configure the TxDone queue */ ret = ixEthAccQMgrQueueUnsetup(&ixEthAccQmgrTxDoneTemplate); /* un configure the RxFree and Tx queues */ for (portId = 0; portId < IX_ETH_ACC_NUM_PORTS; ++portId) { ixQMgrNotificationDisable(ixEthAccPortData[portId].ixEthAccTxData.txQueue); ixQMgrNotificationDisable(ixEthAccPortData[portId].ixEthAccRxData.rxFreeQueue); } return ret;}/** * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries) * * @brief Add and return the total number of entries in all Rx queues * * @param UINT32 rxQueueEntries[in] number of entries in all queues * * @return void * * @note Rx queues configuration is driven by Qos Setup. There is a * variable number of rx queues which are set at initialisation. * * @internal */IX_ETH_ACC_PUBLICvoid ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries){ UINT32 rxQueueLevel; IxEthAccRxQueue *rxQueuePtr; *numRxQueueEntries = 0; /* iterate thru rx queues */ for (rxQueuePtr = ixEthAccRxQueues; rxQueuePtr->npeCount != 0; ++rxQueuePtr) { /* retrieve the rx queue level */ rxQueueLevel = 0; ixQMgrQNumEntriesGet(rxQueuePtr->qId, &rxQueueLevel); (*numRxQueueEntries) += rxQueueLevel; }}/** * @fn ixEthAccQMgrRxNotificationEnable(void) * * @brief Enable AQM notification for all rx queues. * * @return IxEthAccStatus * */IX_ETH_ACC_PUBLICvoid ixEthAccQMgrRxNotificationEnable(){ UINT32 intEnableReg; intEnableReg = IX_OSAL_READ_LONG(ixEthAccQMIntEnableBaseAddress); IX_OSAL_WRITE_LONG(ixEthAccQMIntEnableBaseAddress, (intEnableReg | ixEthAccDataInfo.rxQueuesIntMask)); }/** * @fn ixEthAccQMgrRxNotificationDisable(void) * * @brief Disable AQM notification for all rx queues. * * @return IxEthAccStatus * */IX_ETH_ACC_PUBLICvoid ixEthAccQMgrRxNotificationDisable(){ UINT32 intEnableReg; intEnableReg = IX_OSAL_READ_LONG(ixEthAccQMIntEnableBaseAddress); IX_OSAL_WRITE_LONG(ixEthAccQMIntEnableBaseAddress, (intEnableReg & ~(ixEthAccDataInfo.rxQueuesIntMask))); IX_OSAL_WRITE_LONG(ixEthAccQMIntStatusBaseAddress, ixEthAccDataInfo.rxQueuesIntMask); }/** * @fn ixEthAccQMgrRxCallbacksRegister * * @brief Change the callback registered to all rx queues. * * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register * @param IxQMgrCallbackId ixQMgrCallbackTag[in] callback tag to register * * @return IxEthAccStatus * * @note The user may decide to use different Rx mechanisms * (e.g. receive many frames at the same time , or receive * one frame at a time, depending on the overall application * performances). A different QMgr callback is registered. This * way, there is no excessive pointer checks in the datapath. * * @internal */IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback, IxQMgrCallbackId ixQMgrCallbackTag){ IxEthAccRxQueue *rxQueuePtr; IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; IxQMgrCallbackId callbackTag = ixQMgrCallbackTag; /* parameter check */ if (NULL == ixQMgrCallback) { ret = IX_ETH_ACC_FAIL; } /* iterate thru rx queues */ for (rxQueuePtr = ixEthAccRxQueues; (rxQueuePtr->npeCount != 0) && (ret == IX_ETH_ACC_SUCCESS); ++rxQueuePtr) { /* if no tag given, use stored tag */ if(ixQMgrCallbackTag == 0) callbackTag = rxQueuePtr->callbackTag; /* register the rx callback for all queues */ ret = ixQMgrNotificationCallbackSet(rxQueuePtr->qId, ixQMgrCallback, callbackTag); } return(ret);}/** * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) * * @brief Check the hardware and microcode exists for this port * * @param IxEthAccPortId portId[in] port * * @return IxEthAccStatus * * @note The following conditions must all be true to pass: * - The port's associated NPE exists * - An ethernet NPE image is loaded * - For ports 1-3 on NPEB, the correct 4port image is loaded * and the (1-3 ports) are enabled in hardware * - The Ethernet coprocessor exists for the port * * @internal */IX_ETH_ACC_PUBLICIxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId physicalId){ UINT8 functionalityId; IxEthNpeNodeId npeId = IX_ETHNPE_PHYSICAL_ID_TO_NODE(physicalId); IxEthNpePortId portId = IX_ETHNPE_PHYSICAL_ID_TO_PORT(physicalId); if (IX_SUCCESS != ixNpeDlLoadedImageFunctionalityGet(npeId, &functionalityId)) { return IX_ETH_ACC_FAIL; } else { /* If not IXP42X A0 stepping, proceed to check for existence of NPEs and ethernet coprocessors */ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) { switch(npeId) { case IX_NPEDL_NPEID_NPEA: if ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == IX_FEATURE_CTRL_COMPONENT_DISABLED) || ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == IX_FEATURE_CTRL_COMPONENT_DISABLED) || (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == IX_FEATURE_CTRL_COMPONENT_DISABLED))) { return IX_ETH_ACC_FAIL; } break; case IX_NPEDL_NPEID_NPEB: if ( (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) == IX_FEATURE_CTRL_COMPONENT_DISABLED) ) { return IX_ETH_ACC_FAIL; } if (portId == 0) { if( ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == IX_FEATURE_CTRL_COMPONENT_DISABLED) { return IX_ETH_ACC_FAIL; } } else /* ports 1-3 */ { if( ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB_ETH) == IX_FEATURE_CTRL_COMPONENT_DISABLED) { return IX_ETH_ACC_FAIL; } } break; case IX_NPEDL_NPEID_NPEC: if ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) == IX_FEATURE_CTRL_COMPONENT_DISABLED) || ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == IX_FEATURE_CTRL_COMPONENT_DISABLED) || (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == IX_FEATURE_CTRL_COMPONENT_DISABLED))) { return IX_ETH_ACC_FAIL; } break; default: /* invalid NPE */ return IX_ETH_ACC_FAIL; } } return IX_ETH_ACC_SUCCESS; }}/** * @fn ixEthAccStatsShow(void) * * @brief Displays all EthAcc stats * * @return void * */void ixEthAccStatsShow(IxEthAccPortId portId){ ixEthAccMdioShow(); printf("\nPort %u\nUnicast MAC : ", portId); ixEthAccPortUnicastAddressShow(portId); ixEthAccPortMulticastAddressShow(portId); printf("\n"); ixEthAccDataPlaneShow();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -