| /** | 
 |  * @file IxEthDBFeatures.c | 
 |  * | 
 |  * @brief Implementation of the EthDB feature control API | 
 |  * | 
 |  * @par | 
 |  * IXP400 SW Release version 2.0 | 
 |  * | 
 |  * -- Copyright Notice -- | 
 |  * | 
 |  * @par | 
 |  * Copyright 2001-2005, Intel Corporation. | 
 |  * All rights reserved. | 
 |  * | 
 |  * @par | 
 |  * Redistribution and use in source and binary forms, with or without | 
 |  * modification, are permitted provided that the following conditions | 
 |  * are met: | 
 |  * 1. Redistributions of source code must retain the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer. | 
 |  * 2. Redistributions in binary form must reproduce the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer in the | 
 |  *    documentation and/or other materials provided with the distribution. | 
 |  * 3. Neither the name of the Intel Corporation nor the names of its contributors | 
 |  *    may be used to endorse or promote products derived from this software | 
 |  *    without specific prior written permission. | 
 |  * | 
 |  * @par | 
 |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' | 
 |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
 |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | 
 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
 |  * SUCH DAMAGE. | 
 |  * | 
 |  * @par | 
 |  * -- End of Copyright Notice -- | 
 |  */ | 
 |  | 
 | #include "IxNpeDl.h" | 
 | #include "IxEthDBQoS.h" | 
 | #include "IxEthDB_p.h" | 
 |  | 
 | /** | 
 |  * @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 returns the capability of a port | 
 |  * | 
 |  * @param portID ID of the port | 
 |  * @param featureSet location to store the port capability in | 
 |  * | 
 |  * This function will save the capability set of the given port | 
 |  * into the given location. Capabilities are bit-ORed, each representing | 
 |  * a bit of the feature set. | 
 |  * | 
 |  * Note that this function is documented in the main component | 
 |  * public header file, IxEthDB.h. | 
 |  * | 
 |  * @return IX_ETH_DB_SUCCESS if the operation completed successfully | 
 |  * or IX_ETH_DB_INVALID_PORT if the given port is invalid | 
 |  */ | 
 | IX_ETH_DB_PUBLIC | 
 | IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) | 
 | { | 
 |     IX_ETH_DB_CHECK_PORT_INITIALIZED(portID); | 
 |  | 
 |     IX_ETH_DB_CHECK_REFERENCE(featureSet); | 
 |  | 
 |     *featureSet = ixEthDBPortInfo[portID].featureCapability; | 
 |  | 
 |     return IX_ETH_DB_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * @brief enables or disables a port capability | 
 |  * | 
 |  * @param portID ID of the port | 
 |  * @param feature feature to enable or disable | 
 |  * @param enabled TRUE to enable the selected feature or FALSE to disable it | 
 |  * | 
 |  * Note that this function is documented in the main component | 
 |  * header file, IxEthDB.h. | 
 |  * | 
 |  * @return IX_ETH_DB_SUCCESS if the operation completed | 
 |  * successfully or an appropriate error message otherwise | 
 |  */ | 
 | IX_ETH_DB_PUBLIC | 
 | IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable) | 
 | { | 
 |     PortInfo *portInfo; | 
 |     IxEthDBPriorityTable defaultPriorityTable; | 
 |     IxEthDBVlanSet vlanSet; | 
 |     IxEthDBStatus status = IX_ETH_DB_SUCCESS; | 
 |     BOOL portEnabled; | 
 |  | 
 |     IX_ETH_DB_CHECK_PORT_INITIALIZED(portID); | 
 |  | 
 |     portInfo    = &ixEthDBPortInfo[portID]; | 
 |     portEnabled = portInfo->enabled; | 
 |  | 
 |     /* check that only one feature is selected */ | 
 |     if (!ixEthDBCheckSingleBitValue(feature)) | 
 |     { | 
 |         return IX_ETH_DB_FEATURE_UNAVAILABLE; | 
 |     } | 
 |  | 
 |     /* port capable of this feature? */ | 
 |     if ((portInfo->featureCapability & feature) == 0) | 
 |     { | 
 |         return IX_ETH_DB_FEATURE_UNAVAILABLE; | 
 |     } | 
 |  | 
 |     /* mutual exclusion between learning and WiFi header conversion */ | 
 |     if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION)) | 
 |             == (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION)) | 
 |     { | 
 |         return IX_ETH_DB_NO_PERMISSION; | 
 |     } | 
 |  | 
 |     /* learning must be enabled before filtering */ | 
 |     if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0)) | 
 |     { | 
 |         return IX_ETH_DB_NO_PERMISSION; | 
 |     } | 
 |  | 
 |     /* filtering must be disabled before learning */ | 
 |     if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0)) | 
 |     { | 
 |         return IX_ETH_DB_NO_PERMISSION; | 
 |     } | 
 |  | 
 |     /* redundant enabling or disabling */ | 
 |     if ((!enable && ((portInfo->featureStatus & feature) == 0)) | 
 |         || (enable && ((portInfo->featureStatus & feature) != 0))) | 
 |     { | 
 |         /* do nothing */ | 
 |         return IX_ETH_DB_SUCCESS; | 
 |     } | 
 |  | 
 |     /* force port enabled */ | 
 |     portInfo->enabled = TRUE; | 
 |  | 
 |     if (enable) | 
 |     { | 
 |         /* turn on enable bit */ | 
 |         portInfo->featureStatus |= feature; | 
 |  | 
 | #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ | 
 |         /* if this is VLAN/QoS set the default priority table */ | 
 |         if (feature == IX_ETH_DB_VLAN_QOS) | 
 |         { | 
 |             /* turn on VLAN/QoS (most permissive mode): | 
 |                 - set default 802.1Q priority mapping table, in accordance to the | 
 |                   availability of traffic classes | 
 |                 - set the acceptable frame filter to accept all | 
 |                 - set the Ingress tagging mode to pass-through | 
 |                 - set full VLAN membership list | 
 |                 - set full TTI table | 
 |                 - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0) | 
 |                 - enable TPID port extraction | 
 |             */ | 
 |  | 
 |             portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable; | 
 |  | 
 |             /* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */ | 
 |             memcpy (defaultPriorityTable, | 
 |                 (const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1], | 
 |                 sizeof (defaultPriorityTable)); | 
 |  | 
 |             /* update priority mapping and AQM queue assignments */ | 
 |             status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable); | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); | 
 |             } | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH); | 
 |             } | 
 |  | 
 |             /* set membership and TTI tables */ | 
 |             memset (vlanSet, 0xFF, sizeof (vlanSet)); | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 /* use the internal function to bypass PVID check */ | 
 |                 status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet); | 
 |             } | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 /* use the internal function to bypass PVID check */ | 
 |                 status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet); | 
 |             } | 
 |  | 
 |             /* reset the PVID */ | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBPortVlanTagSet(portID, 0); | 
 |             } | 
 |  | 
 |             /* enable TPID port extraction */ | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBVlanPortExtractionEnable(portID, TRUE); | 
 |             } | 
 |         } | 
 |         else if (feature == IX_ETH_DB_FIREWALL) | 
 | #endif | 
 |         { | 
 |             /* firewall starts in black-list mode unless otherwise configured before * | 
 |              * note that invalid source MAC address filtering is disabled by default */ | 
 |             if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST | 
 |                 && portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST) | 
 |             { | 
 |                 status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST); | 
 |  | 
 |                 if (status == IX_ETH_DB_SUCCESS) | 
 |                 { | 
 |                     status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE); | 
 |                 } | 
 |             } | 
 |         } | 
 |  | 
 |         if (status != IX_ETH_DB_SUCCESS) | 
 |         { | 
 |             /* checks failed, disable */ | 
 |             portInfo->featureStatus &= ~feature; | 
 |         } | 
 |     } | 
 |     else | 
 |     { | 
 |         /* turn off features */ | 
 |         if (feature == IX_ETH_DB_FIREWALL) | 
 |         { | 
 |             /* turning off the firewall is equivalent to: | 
 |                 - set to black-list mode | 
 |                 - clear all the entries and download the new table | 
 |                 - turn off the invalid source address checking | 
 |             */ | 
 |  | 
 |             status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD); | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST); | 
 |             } | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE); | 
 |             } | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBFirewallTableDownload(portID); | 
 |             } | 
 |         } | 
 |         else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION) | 
 |         { | 
 |             /* turn off header conversion */ | 
 |             status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD); | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBWiFiConversionTableDownload(portID); | 
 |             } | 
 |         } | 
 | #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ | 
 |         else if (feature == IX_ETH_DB_VLAN_QOS) | 
 |         { | 
 |             /* turn off VLAN/QoS: | 
 |                 - set a priority mapping table with one traffic class | 
 |                 - set the acceptable frame filter to accept all | 
 |                 - set the Ingress tagging mode to pass-through | 
 |                 - clear the VLAN membership list | 
 |                 - clear the TTI table | 
 |                 - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0) | 
 |                 - disable TPID port extraction | 
 |             */ | 
 |  | 
 |             /* initialize all => traffic class 0 priority mapping table */ | 
 |             memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); | 
 |             portInfo->ixEthDBTrafficClassCount = 1; | 
 |             status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable); | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); | 
 |             } | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH); | 
 |             } | 
 |  | 
 |             /* clear membership and TTI tables */ | 
 |             memset (vlanSet, 0, sizeof (vlanSet)); | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 /* use the internal function to bypass PVID check */ | 
 |                 status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet); | 
 |             } | 
 |  | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 /* use the internal function to bypass PVID check */ | 
 |                 status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet); | 
 |             } | 
 |  | 
 |             /* reset the PVID */ | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBPortVlanTagSet(portID, 0); | 
 |             } | 
 |  | 
 |             /* disable TPID port extraction */ | 
 |             if (status == IX_ETH_DB_SUCCESS) | 
 |             { | 
 |                 status = ixEthDBVlanPortExtractionEnable(portID, FALSE); | 
 |             } | 
 |         } | 
 | #endif | 
 |  | 
 |         if (status == IX_ETH_DB_SUCCESS) | 
 |         { | 
 |             /* checks passed, disable */ | 
 |             portInfo->featureStatus &= ~feature; | 
 |         } | 
 |     } | 
 |  | 
 |     /* restore port enabled state */ | 
 |     portInfo->enabled = portEnabled; | 
 |  | 
 |     return status; | 
 | } | 
 |  | 
 | /** | 
 |  * @brief returns the status of a feature | 
 |  * | 
 |  * @param portID port ID | 
 |  * @param present location to store a boolean value indicating | 
 |  * if the feature is present (TRUE) or not (FALSE) | 
 |  * @param enabled location to store a booleam value indicating | 
 |  * if the feature is present (TRUE) or not (FALSE) | 
 |  * | 
 |  * Note that this function is documented in the main component | 
 |  * header file, IxEthDB.h. | 
 |  * | 
 |  * @return IX_ETH_DB_SUCCESS if the operation completed | 
 |  * successfully or an appropriate error message otherwise | 
 |  */ | 
 | IX_ETH_DB_PUBLIC | 
 | IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) | 
 | { | 
 |     PortInfo *portInfo; | 
 |  | 
 |     IX_ETH_DB_CHECK_PORT(portID); | 
 |  | 
 |     IX_ETH_DB_CHECK_REFERENCE(present); | 
 |  | 
 |     IX_ETH_DB_CHECK_REFERENCE(enabled); | 
 |  | 
 |     portInfo = &ixEthDBPortInfo[portID]; | 
 |  | 
 |     *present = (portInfo->featureCapability & feature) != 0; | 
 |     *enabled = (portInfo->featureStatus & feature) != 0; | 
 |  | 
 |     return IX_ETH_DB_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * @brief returns the value of an EthDB property | 
 |  * | 
 |  * @param portID ID of the port | 
 |  * @param feature feature owning the property | 
 |  * @param property ID of the property | 
 |  * @param type location to store the property type into | 
 |  * @param value location to store the property value into | 
 |  * | 
 |  * Note that this function is documented in the main component | 
 |  * header file, IxEthDB.h. | 
 |  * | 
 |  * @return IX_ETH_DB_SUCCESS if the operation completed | 
 |  * successfully or an appropriate error message otherwise | 
 |  */ | 
 | IX_ETH_DB_PUBLIC | 
 | IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) | 
 | { | 
 |     IX_ETH_DB_CHECK_PORT_EXISTS(portID); | 
 |  | 
 |     IX_ETH_DB_CHECK_REFERENCE(type); | 
 |  | 
 |     IX_ETH_DB_CHECK_REFERENCE(value); | 
 |  | 
 |     if (feature == IX_ETH_DB_VLAN_QOS) | 
 |     { | 
 |         if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY) | 
 |         { | 
 |             * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; | 
 |             *type              = IX_ETH_DB_INTEGER_PROPERTY; | 
 |  | 
 |             return IX_ETH_DB_SUCCESS; | 
 |         } | 
 |         else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY | 
 |             && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY) | 
 |         { | 
 |             UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; | 
 |  | 
 |             if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) | 
 |             { | 
 |                 return IX_ETH_DB_FAIL; | 
 |             } | 
 |  | 
 |             * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta]; | 
 |             *type              = IX_ETH_DB_INTEGER_PROPERTY; | 
 |  | 
 |             return IX_ETH_DB_SUCCESS; | 
 |         } | 
 |     } | 
 |  | 
 |     return IX_ETH_DB_INVALID_ARG; | 
 | } | 
 |  | 
 | /** | 
 |  * @brief sets the value of an EthDB property | 
 |  * | 
 |  * @param portID ID of the port | 
 |  * @param feature feature owning the property | 
 |  * @param property ID of the property | 
 |  * @param value location containing the property value | 
 |  * | 
 |  * This function implements a private property intended | 
 |  * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE | 
 |  * property (the value is ignored), the availability of traffic classes is | 
 |  * frozen to whatever traffic class structure is currently in use. | 
 |  * This means that if VLAN_QOS has been enabled before EthAcc | 
 |  * initialization then all the defined traffic classes will be available; | 
 |  * otherwise only one traffic class (0) will be available. | 
 |  * | 
 |  * Note that this function is documented in the main component | 
 |  * header file, IxEthDB.h as not accepting any parameters. The | 
 |  * current implementation is only intended for the private use of EthAcc. | 
 |  * | 
 |  * Also note that once this function is called the effect is irreversible, | 
 |  * unless EthDB is complete unloaded and re-initialized. | 
 |  * | 
 |  * @return IX_ETH_DB_INVALID_ARG (no read-write properties are | 
 |  * supported in this release) | 
 |  */ | 
 | IX_ETH_DB_PUBLIC | 
 | IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) | 
 | { | 
 |     IX_ETH_DB_CHECK_PORT_EXISTS(portID); | 
 |  | 
 |     if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE)) | 
 |     { | 
 |         ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; | 
 |  | 
 |         return IX_ETH_DB_SUCCESS; | 
 |     } | 
 |  | 
 |     return IX_ETH_DB_INVALID_ARG; | 
 | } |