summaryrefslogtreecommitdiff
path: root/cpu/ixp/npe/IxEthDBAPISupport.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/ixp/npe/IxEthDBAPISupport.c')
-rw-r--r--cpu/ixp/npe/IxEthDBAPISupport.c678
1 files changed, 678 insertions, 0 deletions
diff --git a/cpu/ixp/npe/IxEthDBAPISupport.c b/cpu/ixp/npe/IxEthDBAPISupport.c
new file mode 100644
index 00000000000..25633a3d56e
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBAPISupport.c
@@ -0,0 +1,678 @@
+/**
+ * @file IxEthDBAPISupport.c
+ *
+ * @brief Public API support functions
+ *
+ * @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 <IxEthDB.h>
+#include <IxNpeMh.h>
+#include <IxFeatureCtrl.h>
+
+#include "IxEthDB_p.h"
+#include "IxEthDBMessages_p.h"
+#include "IxEthDB_p.h"
+#include "IxEthDBLog_p.h"
+
+#ifdef IX_UNIT_TEST
+
+int dbAccessCounter = 0;
+int overflowEvent = 0;
+
+#endif
+
+/*
+ * External declaration
+ */
+extern HashTable dbHashtable;
+
+/*
+ * Internal declaration
+ */
+IX_ETH_DB_PUBLIC
+PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
+
+IX_ETH_DB_PRIVATE
+struct
+{
+ BOOL saved;
+ IxEthDBPriorityTable priorityTable;
+ IxEthDBVlanSet vlanMembership;
+ IxEthDBVlanSet transmitTaggingInfo;
+ IxEthDBFrameFilter frameFilter;
+ IxEthDBTaggingAction taggingAction;
+ IxEthDBFirewallMode firewallMode;
+ BOOL stpBlocked;
+ BOOL srcAddressFilterEnabled;
+ UINT32 maxRxFrameSize;
+ UINT32 maxTxFrameSize;
+} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS];
+
+#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518)
+
+/**
+ * @brief initializes a port
+ *
+ * @param portID ID of the port to be initialized
+ *
+ * Note that redundant initializations are silently
+ * dealt with and do not constitute an error
+ *
+ * This function is fully documented in the main
+ * header file, IxEthDB.h
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBPortInit(IxEthDBPortId portID)
+{
+ PortInfo *portInfo;
+
+ if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
+ {
+ return;
+ }
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS)
+ {
+ WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID);
+
+ return;
+ }
+
+ if (portInfo->initialized)
+ {
+ /* redundant */
+ return;
+ }
+
+ /* initialize core fields */
+ portInfo->portID = portID;
+ SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID);
+
+ /* default values */
+ portInfo->agingEnabled = FALSE;
+ portInfo->enabled = FALSE;
+ portInfo->macAddressUploaded = FALSE;
+ portInfo->maxRxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
+ portInfo->maxTxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
+
+ /* default update control values */
+ portInfo->updateMethod.searchTree = NULL;
+ portInfo->updateMethod.searchTreePendingWrite = FALSE;
+ portInfo->updateMethod.treeInitialized = FALSE;
+ portInfo->updateMethod.updateEnabled = FALSE;
+ portInfo->updateMethod.userControlled = FALSE;
+
+ /* default WiFi parameters */
+ memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid));
+ portInfo->frameControlDurationID = 0;
+
+ /* Ethernet NPE-specific initializations */
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ /* update handler */
+ portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler;
+ }
+
+ /* initialize state save */
+ ixEthDBPortState[portID].saved = FALSE;
+
+ portInfo->initialized = TRUE;
+}
+
+/**
+ * @brief enables a port
+ *
+ * @param portID ID of the port to enable
+ *
+ * This function is fully documented in the main
+ * header file, IxEthDB.h
+ *
+ * @return IX_ETH_DB_SUCCESS if enabling was
+ * accomplished, or a meaningful error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
+{
+ IxEthDBPortMap triggerPorts;
+ PortInfo *portInfo;
+
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (portInfo->enabled)
+ {
+ /* redundant */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ SET_DEPENDENCY_MAP(triggerPorts, portID);
+
+ /* mark as enabled */
+ portInfo->enabled = TRUE;
+
+ /* Operation stops here when Ethernet Learning is not enabled */
+ if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
+ ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ {
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
+ {
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);
+
+ /* must use UnicastAddressSet() before enabling an NPE port */
+ return IX_ETH_DB_MAC_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);
+
+ if (!portInfo->updateMethod.userControlled
+ && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
+ {
+ portInfo->updateMethod.updateEnabled = TRUE;
+ }
+
+ /* if this is first time initialization then we already have
+ write access to the tree and can AccessRelease directly */
+ if (!portInfo->updateMethod.treeInitialized)
+ {
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);
+
+ /* create an initial tree and release access into it */
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+
+ /* mark tree as being initialized */
+ portInfo->updateMethod.treeInitialized = TRUE;
+ }
+ }
+
+ if (ixEthDBPortState[portID].saved)
+ {
+ /* previous configuration data stored, restore state */
+ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+ {
+ ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
+ ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
+ }
+
+#if 0 /* test-only */
+ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+ {
+ ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
+ ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);
+
+ ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
+ ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);
+
+ ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
+ }
+#endif
+
+ if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+ {
+ ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
+ }
+
+ ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
+ ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);
+
+ /* discard previous save */
+ ixEthDBPortState[portID].saved = FALSE;
+ }
+
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief disables a port
+ *
+ * @param portID ID of the port to disable
+ *
+ * This function is fully documented in the
+ * main header file, IxEthDB.h
+ *
+ * @return IX_ETH_DB_SUCCESS if disabling was
+ * successful or an appropriate error message
+ * otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
+{
+ HashIterator iterator;
+ IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
+ BOOL result;
+ PortInfo *portInfo;
+ IxEthDBFeature learningEnabled;
+#if 0 /* test-only */
+ IxEthDBPriorityTable classZeroTable;
+#endif
+
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (!portInfo->enabled)
+ {
+ /* redundant */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ /* save filtering state */
+ ixEthDBPortState[portID].firewallMode = portInfo->firewallMode;
+ ixEthDBPortState[portID].frameFilter = portInfo->frameFilter;
+ ixEthDBPortState[portID].taggingAction = portInfo->taggingAction;
+ ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked;
+ ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
+ ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize;
+ ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize;
+
+ memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
+ memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
+ memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));
+
+ ixEthDBPortState[portID].saved = TRUE;
+
+ /* now turn off all EthDB filtering features on the port */
+
+#if 0 /* test-only */
+ /* VLAN & QoS */
+ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+ {
+ ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
+ ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, FALSE);
+ ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+ ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);
+
+ memset(classZeroTable, 0, sizeof (classZeroTable));
+ ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
+ }
+#endif
+
+ /* STP */
+ if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+ {
+ ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, FALSE);
+ }
+
+ /* Firewall */
+ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+ {
+ ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+ ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
+ ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, FALSE);
+ }
+
+ /* Frame size filter */
+ ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);
+
+ /* WiFi */
+ if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+ {
+ ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
+ }
+
+ /* save and disable the learning feature bit */
+ learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
+ portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
+ }
+ else
+ {
+ /* save the learning feature bit */
+ learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
+ }
+
+ SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+ ixEthDBUpdateLock();
+
+ /* wipe out current entries for this port */
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+ /* check if the port match. If so, remove the entry */
+ if (descriptor->portID == portID
+ && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ && !descriptor->recordData.filteringData.staticEntry)
+ {
+ /* delete entry */
+ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+
+ /* add port to the set of update trigger ports */
+ JOIN_PORT_TO_MAP(triggerPorts, portID);
+ }
+ else
+ {
+ /* move to the next record */
+ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+ }
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if (portInfo->updateMethod.searchTree != NULL)
+ {
+ ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
+ portInfo->updateMethod.searchTree = NULL;
+ }
+
+ ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
+ }
+
+ /* mark as disabled */
+ portInfo->enabled = FALSE;
+
+ /* disable updates unless the user has specifically altered the default behavior */
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if (!portInfo->updateMethod.userControlled)
+ {
+ portInfo->updateMethod.updateEnabled = FALSE;
+ }
+
+ /* make sure we re-initialize the NPE learning tree when the port is re-enabled */
+ portInfo->updateMethod.treeInitialized = FALSE;
+ }
+
+ ixEthDBUpdateUnlock();
+
+ /* restore learning feature bit */
+ portInfo->featureStatus |= learningEnabled;
+
+ /* if we've removed any records or lost any events make sure to force an update */
+ IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);
+
+ if (!result)
+ {
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sends the updated maximum Tx/Rx frame lengths to the NPE
+ *
+ * @param portID ID of the port to update
+ *
+ * @return IX_ETH_DB_SUCCESS if the update completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID)
+{
+ IxNpeMhMessage message;
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+ IX_STATUS result;
+
+ FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief sets the port maximum Rx frame size
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumRxFrameSize maximum Rx frame size
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+ (maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+ }
+ else
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* update internal structure */
+ ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize;
+
+ /* update the maximum frame size in the NPE */
+ return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the port maximum Tx frame size
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumTxFrameSize maximum Tx frame size
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+ (maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+ }
+ else
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* update internal structure */
+ ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize;
+
+ /* update the maximum frame size in the NPE */
+ return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the port maximum Tx and Rx frame sizes
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumFrameSize maximum Tx and Rx frame sizes
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * Note that both the maximum Tx and Rx frame size are set
+ * to the same value. This function is kept for compatibility
+ * reasons.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+ (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+ }
+ else
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* update internal structure */
+ ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
+ ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
+
+ /* update the maximum frame size in the NPE */
+ return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the MAC address of an NPE port
+ *
+ * @param portID port ID to set the MAC address on
+ * @param macAddr pointer to the 6-byte MAC address
+ *
+ * This function is called by the EthAcc
+ * ixEthAccUnicastMacAddressSet() and should not be
+ * manually invoked unless required by special circumstances.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation succeeded
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ IxNpeMhMessage message;
+ IxOsalMutex *ackPortAddressLock;
+ IX_STATUS result;
+
+ /* use this macro instead CHECK_PORT
+ as the port doesn't need to be enabled */
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock;
+
+ /* Operation stops here when Ethernet Learning is not enabled */
+ if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
+ ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ {
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ /* exit if the port is not an Ethernet NPE */
+ if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
+ {
+ return IX_ETH_DB_INVALID_PORT;
+ }
+
+ /* populate message */
+ FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
+
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
+
+ /* send a SetPortAddress message */
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ if (result == IX_SUCCESS)
+ {
+ ixEthDBPortInfo[portID].macAddressUploaded = TRUE;
+ }
+
+ return result;
+}