summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/ixp/npe/IxEthDBFeatures.c')
-rw-r--r--arch/arm/cpu/ixp/npe/IxEthDBFeatures.c662
1 files changed, 662 insertions, 0 deletions
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c b/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c
new file mode 100644
index 0000000..7a58d26
--- /dev/null
+++ b/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c
@@ -0,0 +1,662 @@
+/**
+ * @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;
+}