/** * @brief initializes the event processor * * Initializes the event processor queue and processing thread. * Called from ixEthDBInit() DB-subcomponent master init function. * * @warning do not call directly * * @retval IX_ETH_DB_SUCCESS initialization was successful * @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure) * * @internal */ IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void) { if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS) { return IX_ETH_DB_FAIL; } if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS) { return IX_ETH_DB_FAIL; } if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) { /* start processor loop thread */ if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS) { return IX_ETH_DB_FAIL; } } /* Initialize the event processor pausing state */ ixEthDBEventProcessorPausing = FALSE; return IX_ETH_DB_SUCCESS; }
/* ------------------------------------------- * Initialise the tx subcomponent */ IX_STATUS ixAtmdAccTxCfgIfInit (void) { IX_STATUS returnStatus = IX_SUCCESS; /* reset statistics counters */ ixAtmdAccTxCfgIfStatsReset (); /* initialise tx data structures */ if((ixAtmdAccTxCfgInitDone == FALSE) && (ixAtmdAccTxCfgInfoInit () == IX_SUCCESS) && (ixOsalMutexInit (&txControlLock) == IX_SUCCESS)) { /* register port state interface to port management */ ixAtmdAccPortStateHandlersRegister( ixAtmdAccTxPortSetupNotify, ixAtmdAccTxPortStateChange, ixAtmdAccTxPortIsEnabledCheck, ixAtmdAccTxPortIsDisabledCheck); /* initialisae a security flag */ ixAtmdAccTxCfgInitDone = TRUE; } else { returnStatus = IX_FAIL; } /* end of if-else(powerOf2) */ return returnStatus; }
/******************************************************************** * ixEthAccMiiInit */ IxEthAccStatus ixEthAccMiiInit() { if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS) { return IX_ETH_ACC_FAIL; } /* Use one MAC coprocessor for MII since any MAC can access all PHYs. * Check which NPE MAC coprocessor is available starting with NPEB. * If NPEB is unavailable, check NPEC, then NPEA. * If none of the three work, return failure. */ miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETH_MAC_B0_MAP_SIZE); if (miiBaseAddressVirt == 0) { ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, "EthAcc: Could not map MII I/O mapped memory\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } REG_WRITE(miiBaseAddressVirt, IX_ETH_ACC_MAC_CORE_CNTRL, IX_ETH_ACC_CORE_MDC_EN); return IX_ETH_ACC_SUCCESS; }
/* * Function definitions. */ void ixQMgrQCfgInit (void) { int loopIndex; for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) { /* info for code inlining */ ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder; /* info for code inlining */ ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder; ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder; ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder; } /* Initialise the AqmIf component */ ixQMgrAqmIfInit (); /* Reset all queues to have queue name = NULL, entry size = 0 and * isConfigured = false */ for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) { strcpy (cfgQueueInfo[loopIndex].qName, ""); cfgQueueInfo[loopIndex].qSizeInWords = 0; cfgQueueInfo[loopIndex].qEntrySizeInWords = 0; cfgQueueInfo[loopIndex].isConfigured = FALSE; /* Statistics */ stats.qStats[loopIndex].isConfigured = FALSE; stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName; } /* Statistics */ stats.wmSetCnt = 0; ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress); ixOsalMutexInit(&ixQMgrQCfgMutex); cfgInitialized = TRUE; }
/* * Function definition: ixEthAccCodeletDBMaintenanceStart() * * Start the EDB Maintenance task */ IX_STATUS ixEthAccCodeletDBMaintenanceStart(void) { IxOsalThread maintenanceThread; IxOsalThreadAttr threadAttr; threadAttr.name = "Codelet EDB Maintenance"; threadAttr.stackSize = 32 * 1024; /* 32kbytes */ threadAttr.priority = IX_ETHACC_CODELET_DB_PRIORITY; if (!ixEthAccCodeletDBMaintenanceInitialized) { /* this should be initialized once */ ixOsalMutexInit (&ixEthAccCodeletDBMaintenanceTaskRunning); ixEthAccCodeletDBMaintenanceInitialized = TRUE; ixEthAccCodeletDBMaintenanceTaskStopTrigger = TRUE; } if (ixEthAccCodeletDBMaintenanceTaskStopTrigger) { /* Polled mode based on a task running a loop */ if (ixOsalThreadCreate(&maintenanceThread, &threadAttr, (IxOsalVoidFnVoidPtr) ixEthAccCodeletDBMaintenanceTask, NULL) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDBMaintenanceTaskRunning); printf("DBLearning: Error spawning DB maintenance task\n"); return (IX_FAIL); } /* Start the thread */ if (ixOsalThreadStart(&maintenanceThread) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDBMaintenanceTaskRunning); printf("DBLearning: Error failed to start the maintenance thread\n"); return IX_FAIL; } } return (IX_SUCCESS); }
IxEthAccStatus ixEthAccMiiInit() { if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS) { return IX_ETH_ACC_FAIL; } /* Use NPE-B MAC coprocessor for MII since IXP42X and IXP46X product line * only has this MAC coprocessor to communicate with PHY through * MDIO interface. */ if( (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == ixFeatureCtrlDeviceRead ()) || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X == ixFeatureCtrlDeviceRead ()) ) { miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_ETH_ACC_MAC_0_MAP_SIZE); } if( IX_FEATURE_CTRL_DEVICE_TYPE_IXP43X == ixFeatureCtrlDeviceRead () ) { /* Use NPE-C MAC coprocessor for MII since IXP43X product line * only has this MAC coprocessor to communicate with PHY through * MDIO interface. */ miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE, IX_ETH_ACC_MAC_1_MAP_SIZE); } if (miiBaseAddressVirt == 0) { ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, "EthAcc: Could not map MII I/O mapped memory\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } REG_WRITE(miiBaseAddressVirt, IX_ETH_ACC_MAC_CORE_CNTRL, IX_ETH_ACC_CORE_MDC_EN); return IX_ETH_ACC_SUCCESS; }
/* --------------------------------------------------------- * Module Initialisation */ IX_STATUS ixAtmdAccUtilInit (void) { IX_STATUS returnStatus = IX_FAIL; if (initDone == FALSE) { returnStatus = ixOsalMutexInit (&utilLock); if (returnStatus != IX_SUCCESS) { returnStatus = IX_FAIL; } else { initDone = TRUE; } /* end of if-else(returnStatus) */ } /* end of if(initDone) */ return returnStatus; }
/******************************************************************** * ixEthAccMiiInit */ IxEthAccStatus ixEthAccMiiInit() { if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS) { return IX_ETH_ACC_FAIL; } miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE); if (miiBaseAddressVirt == 0) { ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, "EthAcc: Could not map MII I/O mapped memory\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } return IX_ETH_ACC_SUCCESS; }
/* ---------------------------------------------------- * Initialisation */ IX_STATUS ixAtmdAccDescMgmtInit (void) { IX_STATUS returnStatus = IX_FAIL; IxAtmdAccNpeDescriptor* npeDescriptorPtr = NULL; void *physicalAddress; unsigned int descSize = 0; unsigned char *descPtr = NULL; unsigned char *descPtrAlign = NULL; if (!initDone) { returnStatus = ixOsalMutexInit (&descMgmtLock); if (returnStatus != IX_SUCCESS) { returnStatus = IX_FAIL; } else { ixAtmdAccDescMgmtStatsReset (); /* compute the size of each element and ensure descriptors are 64-byte aligned */ /* NPE_ADDR_ALIGN is multiple of IX_OSAL_CACHE_LINE_SIZE which is 64 */ descSize = (((sizeof (IxAtmdAccNpeDescriptor)) + (NPE_ADDR_ALIGN - 1)) / NPE_ADDR_ALIGN) * NPE_ADDR_ALIGN; /* allocate a big buffer containing all elements */ descPtr = IX_OSAL_CACHE_DMA_MALLOC((IX_ATMDACC_MAX_NPE_DESCRIPTORS * descSize) + (NPE_ADDR_ALIGN - 1)); descPtr += (NPE_ADDR_ALIGN - 1); descPointer = descPtr; /* mask descriptor pointer with 0xffffffc0 to ensure lower 6 bits are 0*/ descPtrAlign = (unsigned char *)(((UINT32)descPtr) & NPE_DESCRIPTOR_MASK); IxAtmdDmaDescPointer = descPtrAlign; if (descPtrAlign == NULL) { returnStatus = IX_FAIL; } else { for (npeDescCount = 0; (npeDescCount < IX_ATMDACC_MAX_NPE_DESCRIPTORS); npeDescCount++) { /* allocate a NPE descriptor from the big buffer */ npeDescriptorPtr = (IxAtmdAccNpeDescriptor *)descPtrAlign; descPtrAlign += descSize; /* initialise the array of descriptors */ npeDescriptorArray[npeDescCount] = npeDescriptorPtr; physicalAddress = npeDescriptorPtr; IX_ATMDACC_CONVERT_TO_PHYSICAL_ADDRESS (physicalAddress); npeDescriptorPtr->atmd.physicalAddress = (unsigned int)physicalAddress; #ifndef NDEBUG npeDescriptorPtr->atmd.signature = IX_ATMDACC_DESCRIPTOR_SIGNATURE; #endif } /* end of for(npeDescCount) */ if (returnStatus == IX_SUCCESS) { initDone = TRUE; } } } /* end of if-else(returnStatus) */ } /* end of if(initDone) */ return returnStatus; }
/** * @brief scans the capabilities of the loaded NPE images * * This function MUST be called by the ixEthDBInit() function. * No EthDB features (including learning and filtering) are enabled * before this function is called. * * @return none * * @internal */ IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void) { IxNpeDlImageId imageId, npeAImageId; IxEthDBPortId portIndex; PortInfo *portInfo; IxEthDBPriorityTable defaultPriorityTable; IX_STATUS result; UINT32 queueIndex; UINT32 queueStructureIndex; UINT32 trafficClassDefinitionIndex; /* read version of NPE A - required to set the AQM queues for B and C */ npeAImageId.functionalityId = 0; ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId); for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { IxNpeMhMessage msg; portInfo = &ixEthDBPortInfo[portIndex]; /* check and bypass if NPE B or C is fused out */ if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue; /* all ports are capable of LEARNING by default */ portInfo->featureCapability |= IX_ETH_DB_LEARNING; portInfo->featureStatus |= IX_ETH_DB_LEARNING; if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) { if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS) { WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex); } else { /* initialize and empty NPE response mutex */ ixOsalMutexInit(&portInfo->npeAckLock); ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER); /* check NPE response to GetStatus */ msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24; msg.data[1] = 0; IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result); if (result != IX_SUCCESS) { WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n"); continue; } if (imageId.functionalityId == 0x00 || imageId.functionalityId == 0x03 || imageId.functionalityId == 0x04 || imageId.functionalityId == 0x80) { portInfo->featureCapability |= IX_ETH_DB_FILTERING; portInfo->featureCapability |= IX_ETH_DB_FIREWALL; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; } else if (imageId.functionalityId == 0x01 || imageId.functionalityId == 0x81) { portInfo->featureCapability |= IX_ETH_DB_FILTERING; portInfo->featureCapability |= IX_ETH_DB_FIREWALL; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; } else if (imageId.functionalityId == 0x02 || imageId.functionalityId == 0x82) { portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION; portInfo->featureCapability |= IX_ETH_DB_FIREWALL; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; } /* reset AQM queues */ memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments)); /* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */ IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h"); /* find the traffic class definition index compatible with the current NPE A functionality ID */ for (trafficClassDefinitionIndex = 0 ; trafficClassDefinitionIndex < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]); trafficClassDefinitionIndex++) { if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId) { /* found it */ break; } } /* select the default case if we went over the array boundary */ if (trafficClassDefinitionIndex == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0])) { trafficClassDefinitionIndex = 0; /* the first record is the default case */ } /* select queue assignment structure based on the traffic class configuration index */ queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX]; /* only traffic class 0 is active at initialization time */ portInfo->ixEthDBTrafficClassCount = 1; /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */ portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS; portInfo->featureStatus |= IX_ETH_DB_FIREWALL; portInfo->enabled = TRUE; #define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ /* set VLAN initial configuration (permissive) */ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */ { /* QoS capable */ portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX]; /* set AQM queues */ for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) { portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex]; } /* set default PVID (0) and default traffic class 0 */ ixEthDBPortVlanTagSet(portIndex, 0); /* enable reception of all frames */ ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES); /* clear full VLAN membership */ ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); /* clear TTI table - no VLAN tagged frames will be transmitted */ ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE); /* set membership on 0, otherwise no Tx or Rx is working */ ixEthDBPortVlanMembershipAdd(portIndex, 0); } else /* QoS not available in this image */ #endif /* test-only */ { /* initialize traffic class availability (only class 0 is available) */ portInfo->ixEthDBTrafficClassAvailable = 1; /* point all AQM queues to traffic class 0 */ for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) { portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][0]; } } #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ /* download priority mapping table and Rx queue configuration */ memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable); #endif /* by default we turn off invalid source MAC address filtering */ ixEthDBFirewallInvalidAddressFilterEnable(portIndex, FALSE); /* disable port, VLAN, Firewall feature bits */ portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS; portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL; portInfo->enabled = FALSE; /* enable filtering by default if present */ if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0) { portInfo->featureStatus |= IX_ETH_DB_FILTERING; } } } } }
/** * @brief scans the capabilities of the loaded NPE images * * This function MUST be called by the ixEthDBInit() function. * No EthDB features (including learning and filtering) are enabled * before this function is called. * * @return none * * @internal */ IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void) { UINT8 functionalityId, npeAFunctionalityId; IxEthDBPortId portIndex; PortInfo *portInfo; IxEthDBPriorityTable defaultPriorityTable; IX_STATUS result; UINT32 queueIndex; UINT32 queueStructureIndex; UINT32 trafficClassDefinitionIndex, totalTrafficClass; totalTrafficClass = sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]); /* ensure there's at least 2 traffic class records in the definition table, otherwise we have no default cases, hence no queues */ IX_ENSURE(totalTrafficClass >= 2, "DB: no traffic class definitions found, check IxEthDBQoS.h"); /* read version of NPE A - required to set the AQM queues for B and C */ npeAFunctionalityId = 0; if(IX_FAIL == ixNpeDlLoadedImageFunctionalityGet(IX_NPEDL_NPEID_NPEA, &npeAFunctionalityId)) { /* IX_FAIL is returned when there is no image loaded in NPEA. Then we can use all 8 queues */ trafficClassDefinitionIndex = 1; /* the second record is the default if no image loaded */ } else { /* find the traffic class definition index compatible with the current NPE A functionality ID */ for (trafficClassDefinitionIndex = 0 ; trafficClassDefinitionIndex < totalTrafficClass ; trafficClassDefinitionIndex++) { if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAFunctionalityId) { /* found it */ break; } } /* select the default case if we went over the array boundary */ if (trafficClassDefinitionIndex == totalTrafficClass) { trafficClassDefinitionIndex = 0; /* the first record is the default case */ } } /* To decide port definition for NPE A - IX_ETH_NPE or IX_ETH_GENERIC IX_ETH_NPE will be set for NPE A when the functionality id is ranged from 0x80 to 0x8F and ethernet + hss co-exists images range from 0x90 to 0x9F. For the rest of functionality Ids, the port type will be set to IX_ETH_GENERIC. */ if ((npeAFunctionalityId & 0xF0) != 0x80 && (npeAFunctionalityId & 0xF0) != 0x90) { /* NPEA is not Ethernet capable. Override default port definition */ ixEthDBPortDefinitions[IX_NPEA_PORT].type = IX_ETH_GENERIC; } /* select queue assignment structure based on the traffic class configuration index */ queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX]; for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { IxNpeMhMessage msg; portInfo = &ixEthDBPortInfo[portIndex]; /* check and bypass if NPE A, B or C is fused out */ if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue; /* all ports are capable of LEARNING by default */ portInfo->featureCapability = IX_ETH_DB_LEARNING; portInfo->featureStatus = IX_ETH_DB_LEARNING; if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) { if (IX_SUCCESS != ixNpeDlLoadedImageFunctionalityGet(IX_ETHNPE_PHYSICAL_ID_TO_NODE(portIndex), &functionalityId)) { WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex); } else { /* initialize and empty NPE response mutex */ ixOsalMutexInit(&portInfo->npeAckLock); ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER); /* check NPE response to GetStatus */ msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24; msg.data[1] = 0; IX_ETHDB_SEND_NPE_MSG(IX_ETHNPE_PHYSICAL_ID_TO_NODE(portIndex), msg, result); if (result != IX_SUCCESS) { WARNING_LOG("DB: (FeatureScan) warning, %d port could not send message to the NPE\n", portIndex); continue; } if (functionalityId == 0x00 || functionalityId == 0x03 || functionalityId == 0x04 || functionalityId == 0x80) { portInfo->featureCapability |= IX_ETH_DB_FILTERING; portInfo->featureCapability |= IX_ETH_DB_FIREWALL; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; } else if (functionalityId == 0x01 || functionalityId == 0x81 || functionalityId == 0x0B || functionalityId == 0x8B || functionalityId == 0x90) { portInfo->featureCapability |= IX_ETH_DB_FILTERING; portInfo->featureCapability |= IX_ETH_DB_FIREWALL; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; } else if (functionalityId == 0x02 || functionalityId == 0x82 || functionalityId == 0x0D || functionalityId == 0x8D || functionalityId == 0x91) { portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION; portInfo->featureCapability |= IX_ETH_DB_FIREWALL; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; } else if (functionalityId == 0x0C || functionalityId == 0x8C) { portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION; portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; } /* check if image supports mask based firewall */ if (functionalityId == 0x0B || functionalityId == 0x8B || functionalityId == 0x0D || functionalityId == 0x8D || functionalityId == 0x90 || functionalityId == 0x91) { /* this feature is always on and is based on the NPE */ portInfo->featureStatus |= IX_ETH_DB_ADDRESS_MASKING; portInfo->featureCapability |= IX_ETH_DB_ADDRESS_MASKING; } /* reset AQM queues */ ixOsalMemSet(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments)); /* only traffic class 0 is active at initialization time */ portInfo->ixEthDBTrafficClassCount = 1; /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */ portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS; portInfo->featureStatus |= IX_ETH_DB_FIREWALL; portInfo->enabled = TRUE; /* set VLAN initial configuration (permissive) */ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */ { /* QoS capable */ portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX]; /* set AQM queues */ for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) { portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex]; } /* set default PVID (0) and default traffic class 0 */ ixEthDBPortVlanTagSet(portIndex, 0); /* enable reception of all frames */ ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES); /* clear full VLAN membership */ ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); /* clear TTI table - no VLAN tagged frames will be transmitted */ ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE); /* set membership on 0, otherwise no Tx or Rx is working */ ixEthDBPortVlanMembershipAdd(portIndex, 0); } else /* QoS not available in this image */ { /* initialize traffic class availability (only class 0 is available) */ portInfo->ixEthDBTrafficClassAvailable = 1; /* point all AQM queues to traffic class 0 */ for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) { portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][0]; } } /* download priority mapping table and Rx queue configuration */ ixOsalMemSet (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable); /* by default we turn on invalid source MAC address filtering */ ixEthDBFirewallInvalidAddressFilterEnable(portIndex, TRUE); /* Notify VLAN tagging is disabled */ if (ixEthDBIngressVlanTaggingEnabledSet(portIndex, IX_ETH_DB_DISABLE_VLAN) != IX_SUCCESS) { WARNING_LOG("DB: (FeatureScan) warning, %d port could not disable VLAN \n", portIndex); continue; } /* disable port, VLAN, Firewall feature bits */ portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS; portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL; portInfo->enabled = FALSE; /* enable filtering by default if present */ if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0) { portInfo->featureStatus |= IX_ETH_DB_FILTERING; } } } } }
/* * Function definition: ixEthAccCodeletInit() * * See header file for documentation. */ IX_STATUS ixEthAccCodeletInit(IxEthAccCodeletOperation operationType, IxEthAccPortId inPort, IxEthAccPortId outPort) { IxEthAccPortId portId; IxOsalThread statsPollThread; IxOsalThreadAttr threadAttr; threadAttr.name = "Codelet Stats"; threadAttr.stackSize = 32 * 1024; /* 32kbytes */ threadAttr.priority = 128; #ifdef __ixp46X /* Set the expansion bus fuse register to enable MUX for NPEA MII */ { UINT32 expbusCtrlReg; expbusCtrlReg = ixFeatureCtrlRead (); expbusCtrlReg |= ((unsigned long)1<<8); ixFeatureCtrlWrite (expbusCtrlReg); } #endif /* check the component is already initialized */ if(ixEthAccCodeletInitialised) { printf("CodeletMain: Ethernet codelet already initialised\n"); return(IX_SUCCESS); } #ifdef __vxworks /* When the ixe drivers are running, the codelets * cannot run. */ for (portId = 0; portId < IX_ETHACC_CODELET_MAX_PORT; portId++) { if (endFindByName ("ixe", portId) != NULL) { printf("CodeletMain: FAIL: Driver ixe%d detected\n",portId); return IX_FAIL; } } #endif /* Initialize NPE IMAGE ID here again to prevent confusion in multiple * ixEthAccCodeletMain() calls with different operationType. */ ETH_NPEA_IMAGEID = IX_NPEDL_NPEIMAGE_NPEA_ETH_MACFILTERLEARN_HSSCHAN_COEXIST; ETH_NPEB_IMAGEID = IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB; ETH_NPEC_IMAGEID = IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB; /* Create mutexes for thread control */ ixEthAccCodeletStatsPollTaskStop = TRUE; ixOsalMutexInit (&ixEthAccCodeletStatsPollTaskRunning); /* Initialise MBUF pool */ if(ixEthAccCodeletMemPoolInit() != IX_SUCCESS) { printf("CodeletMain: Error initialising mBuf pool\n"); return (IX_FAIL); } /* Check Silicon stepping */ printf("Checking Silicon stepping...\n"); if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) { if ((ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == IX_FEATURE_CTRL_SILICON_TYPE_B0) { /* * If it is B0 Silicon, we only enable port when its corresponding * Eth Coprocessor is available. */ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == IX_FEATURE_CTRL_COMPONENT_ENABLED) { ixEthAccCodeletHardwareExists[IX_ETH_PORT_1] = TRUE; } if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == IX_FEATURE_CTRL_COMPONENT_ENABLED) { ixEthAccCodeletHardwareExists[IX_ETH_PORT_2] = TRUE; } } else if ((ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == IX_FEATURE_CTRL_SILICON_TYPE_A0) { /* * If it is A0 Silicon, we enable both as both Eth Coprocessors * are available. */ ixEthAccCodeletHardwareExists[IX_ETH_PORT_1] = TRUE; ixEthAccCodeletHardwareExists[IX_ETH_PORT_2] = TRUE; } else { printf("CodeletMain: Error. Operation for other silicon stepping is undefined!.\n"); return (IX_FAIL); } } else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) { ixEthAccCodeletHardwareExists[IX_ETH_PORT_1] = TRUE; ixEthAccCodeletHardwareExists[IX_ETH_PORT_2] = TRUE; #ifdef __ixp46X ixEthAccCodeletHardwareExists[IX_ETH_PORT_3] = TRUE; #endif } /*********************************************************************** * * System initialisation done. Now initialise Access components. * ***********************************************************************/ /* Initialise Queue Manager */ printf("Initialising Queue Manager...\n"); if (ixQMgrInit() != IX_SUCCESS) { printf("CodeletMain: Error initialising queue manager!\n"); return (IX_FAIL); } /* Start the Queue Manager dispatcher */ if(ixEthAccCodeletDispatcherStart(IX_ETH_CODELET_QMGR_DISPATCH_MODE) != IX_SUCCESS) { printf("CodeletMain: Error starting queue manager dispatch loop!\n"); return (IX_FAIL); } /* Initialise NPE Message handler */ printf("\nStarting NPE message handler...\n"); if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) { printf("CodeletMain: Error initialising NPE Message handler!\n"); return (IX_FAIL); } /* Initialise NPEs firmware */ printf ("Initialising NPEs...\n"); if (ixEthAccCodeletHardwareExists[IX_ETH_PORT_1]) { if ((operationType == IX_ETHACC_CODELET_BRIDGE_WIFI) && (inPort == IX_ETH_PORT_1)) { printf("CodeletMain: the 802.3 <=> 802.11 header conversion image is loaded on NPE B\n"); ETH_NPEB_IMAGEID = IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB; } if (IX_SUCCESS != ixNpeDlNpeInitAndStart(ETH_NPEB_IMAGEID)) { printf ("CodeletMain: Error initialising and starting NPE B!\n"); return (IX_FAIL); } } if (ixEthAccCodeletHardwareExists[IX_ETH_PORT_2]) { if ((operationType == IX_ETHACC_CODELET_BRIDGE_WIFI) && (inPort == IX_ETH_PORT_2)) { printf("CodeletMain: the 802.3 <=> 802.11 header conversion image is loaded on NPE C\n"); ETH_NPEC_IMAGEID = IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB; } if (IX_SUCCESS != ixNpeDlNpeInitAndStart(ETH_NPEC_IMAGEID)) { printf ("CodeletMain: Error initialising and starting NPE C!\n"); return (IX_FAIL); } } #ifdef __ixp46X if (ixEthAccCodeletHardwareExists[IX_ETH_PORT_3]) { if ((operationType == IX_ETHACC_CODELET_BRIDGE_WIFI) && (inPort == IX_ETH_PORT_3)) { printf("CodeletMain: the 802.3 <=> 802.11 header conversion image is loaded on NPE A\n"); ETH_NPEA_IMAGEID = IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB; } if (IX_SUCCESS != ixNpeDlNpeInitAndStart(ETH_NPEA_IMAGEID)) { printf ("CodeletMain: Error initialising and starting NPE A!\n"); return (IX_FAIL); } } #endif printf ("Initialising Access Layers\n"); /* Enable QoS on ethDB. This has to be done before ethAcc initialisation */ if (operationType == IX_ETHACC_CODELET_BRIDGE_QOS) { printf("Enabling QoS\n"); if (IX_ETH_DB_SUCCESS != ixEthDBInit()) { printf ("CodeletMain: Error initialising EthDB\n"); return (IX_FAIL); } (void)ixEthDBPortInit(inPort); if (IX_ETH_DB_SUCCESS != ixEthDBFeatureEnable(inPort, IX_ETH_DB_VLAN_QOS, TRUE)) { printf("CodeletMain: Error enabling QoS on port %d\n",inPort); return (IX_FAIL); } } /* initialise ethAcc : QoS, if needed is already configured */ if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) { printf("CodeletMain: Error initialising Ethernet access driver!\n"); return (IX_FAIL); } /*********************************************************************** * * Access components initialisation done. Now initialize the ports * ***********************************************************************/ /* Configure all available ports */ for (portId = 0; portId < IX_ETHACC_CODELET_MAX_PORT; portId++) { if (ixEthAccCodeletHardwareExists[portId]) { if(ixEthAccCodeletPortInit(portId) != IX_ETH_ACC_SUCCESS) { printf("CodeletMain: Error setup port %u\n", portId); return (IX_FAIL); } } } /* Find and initialise all available PHYs */ printf ("Discover and reset the PHYs...\n"); if(ixEthAccCodeletPhyInit() != IX_SUCCESS) { printf("CodeletMain: Error initialising Ethernet phy(s)!\n"); return (IX_FAIL); } /*********************************************************************** * * PortInitialization done. Now start the codelet features * ***********************************************************************/ /* starts ethDB maintenance running from a different task */ if (ixEthAccCodeletDBMaintenanceStart() != IX_SUCCESS) { printf("CodeletMain: Error spawning DB maintenance task\n"); return (IX_FAIL); } /* Starts the traffic display (in a different task) this is initially * set to FALSE in order to allow the traffic stats to start only * once traffic is started to be received */ ixEthAccCodeletTrafficPollEnabled = FALSE; if (ixOsalThreadCreate(&statsPollThread, &threadAttr, (IxOsalVoidFnVoidPtr) ixEthAccCodeletStatsPollTask, NULL) != IX_SUCCESS) { printf("CodeletMain: Error spawning stats task\n"); return (IX_FAIL); } /* Start the thread */ if (ixOsalThreadStart(&statsPollThread) != IX_SUCCESS) { printf("CodeletMain: Error failed to start the stats thread\n"); return IX_FAIL; } ixEthAccCodeletInitialised = TRUE; return (IX_SUCCESS); }
IX_STATUS ixEthAccCodeletDispatcherStart(BOOL useInterrupt) { IxOsalThread qDispatchThread; IxOsalThreadAttr threadAttr; threadAttr.name = "Codelet Q Dispatcher"; threadAttr.stackSize = 32 * 1024; /* 32kbytes */ threadAttr.priority = IX_ETHACC_CODELET_QMR_PRIORITY; if (!ixEthAccCodeletDispatcherInitialized) { /* this should be initialized once */ ixQMgrDispatcherLoopGet(&ixEthAccCodeletDispatcherFunc); ixOsalMutexInit (&ixEthAccCodeletDispatcherPollRunning); ixEthAccCodeletDispatcherPollStopTrigger = TRUE; ixEthAccCodeletDispatcherInitialized = TRUE; } if(useInterrupt) /* Interrupt mode */ { /* * Hook the QM QLOW dispatcher to the interrupt controller. */ if (ixOsalIrqBind(IX_ETH_CODELET_QMGR_IRQ, (IxOsalVoidFnVoidPtr)(ixEthAccCodeletDispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Failed to bind to QM1 interrupt\n"); return (IX_FAIL); } } else { if (ixEthAccCodeletDispatcherPollStopTrigger) { /* Polled mode based on a task running a loop */ if (ixOsalThreadCreate(&qDispatchThread, &threadAttr, (IxOsalVoidFnVoidPtr) ixEthAccCodeletDispatcherPoll, NULL) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Error spawning Q Dispatcher task\n"); return (IX_FAIL); } /* Start the thread */ if (ixOsalThreadStart(&qDispatchThread) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Error failed to start the Q Dispatcher thread\n"); return IX_FAIL; } } } return (IX_SUCCESS); }
PUBLIC IxEthAccStatus ixEthAccInit() { #ifdef CONFIG_IXP425_COMPONENT_ETHDB /* * Initialize Control plane */ if (ixEthDBInit() != IX_ETH_ACC_SUCCESS) { IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } #endif if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) { ixEthAccNewSrcMask = (~0); /* want all the bits */ } else { ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */ } /* * Initialize Data plane */ if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS ) { IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS ) { IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } /* * Initialize MII */ if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS ) { IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } /* * Initialize MAC I/O memory */ if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS) { IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } /* * Initialize control plane interface lock */ if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS) { IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } /* initialiasation is complete */ ixEthAccServiceInit = TRUE; return IX_ETH_ACC_SUCCESS; }