diff options
Diffstat (limited to 'drivers/net/npe/IxEthDBAPISupport.c')
| -rw-r--r-- | drivers/net/npe/IxEthDBAPISupport.c | 675 | 
1 files changed, 675 insertions, 0 deletions
| diff --git a/drivers/net/npe/IxEthDBAPISupport.c b/drivers/net/npe/IxEthDBAPISupport.c new file mode 100644 index 000000000..36bc200a3 --- /dev/null +++ b/drivers/net/npe/IxEthDBAPISupport.c @@ -0,0 +1,675 @@ +/** + * @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; +    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; +    } + +    /* 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; +} |