/**
 * @file IxEthDBVlan.c
 *
 * @brief Implementation of the VLAN 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 "IxEthDB.h"
#include "IxEthDB_p.h"

/* forward prototypes */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex);
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);

/* contants used by various functions as "action" parameter */
#define ADD_VLAN    (0x1)
#define REMOVE_VLAN (0x2)

/**
 * @brief adds or removes a VLAN from a VLAN set
 *
 * @param vlanID VLAN ID to add or remove
 * @param table VLAN set to add into or remove from
 * @param action ADD_VLAN or REMOVE_VLAN
 * 
 * @internal
 */
IX_ETH_DB_PRIVATE
void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action)
{
    UINT32 setOffset;
    
    /* add/remove VID to membership table */
    setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */

    if (action == ADD_VLAN)
    {
        table[setOffset] |= 1 << VLAN_SET_MASK(vlanID);
    }
    else if (action == REMOVE_VLAN)
    {
        table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID));
    }
}

/**
 * @brief updates a set of 8 VLANs in an NPE
 *
 * @param portID ID of the port
 * @param setOffset offset of the 8 VLANs
 *
 * This function updates the VLAN membership table
 * and Transmit Tagging Info table for 8 consecutive
 * VLAN IDs indexed by setOffset.
 *
 * For example, a setOffset of 0 indexes VLAN IDs 0
 * through 7, 1 indexes VLAN IDs 8 through 9 etc.
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed
 * successfully or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset)
{
    PortInfo *portInfo = &ixEthDBPortInfo[portID];
    IxNpeMhMessage message;
    IX_STATUS result;
        
    FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
        2 * setOffset, 
        portInfo->vlanMembership[setOffset], 
        portInfo->transmitTaggingInfo[setOffset]);
    
    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
    
    return result;
}

/**
 * @brief updates a VLAN range in an NPE
 *
 * @param portID ID of the port
 *
 * This function is similar to @ref ixEthDBVlanTableEntryUpdate
 * except that it can update more than one VLAN set (up to
 * the entire VLAN membership and TTI tables if the offset is 0
 * and length is sizeof (IxEthDBVlanSet) (512 bytes).
 *
 * Updating the NPE via this method is slower as it requires
 * a memory copy from SDRAM, hence it is recommended that the
 * ixEthDBVlanTableEntryUpdate function is used where possible.
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed
 * successfully or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID)
{
    PortInfo *portInfo    = &ixEthDBPortInfo[portID];
    UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone;
    IxNpeMhMessage message;
    UINT32 setIndex;
    IX_STATUS result;

    /* copy membership info and transmit tagging into into exchange area */
    for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++)
    {
        /* membership and TTI data are interleaved */
        vlanUpdateZone[setIndex * 2]     = portInfo->vlanMembership[setIndex];
        vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex];
    }

    IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE);
    
    /* build NPE message */
    FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, 
        IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone));

    /* send message */    
    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);

    return result;
}

/**
 * @brief adds or removes a VLAN from a port's VLAN membership table
 * or Transmit Tagging Information table
 *
 * @param portID ID of the port
 * @param vlanID VLAN ID to add or remove
 * @param table to add or remove from
 * @param action ADD_VLAN or REMOVE_VLAN
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed
 * successfully or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action)
{
    /* change VLAN in local membership table */
    ixEthDBLocalVlanMembershipChange(vlanID, table, action);
    
    /* send updated entry to NPE */
    return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID));
}

/**
 * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID)
 *
 * @param portID ID of the port
 * @param vlanTag port VLAN tag (802.1Q tag)
 * 
 * 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 ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag)
{
    IxNpeMhMessage message;
    IX_STATUS result;
    
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
 
    IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
        
    /* add VLAN ID to local membership table */
    ixEthDBPortVlanMembershipChange(portID, 
        vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, 
        ixEthDBPortInfo[portID].vlanMembership, 
        ADD_VLAN);
        
    /* set tag in portInfo */
    ixEthDBPortInfo[portID].vlanTag = vlanTag;
    
    /* build VLAN_SetDefaultRxVID message */
    FILL_SETDEFAULTRXVID_MSG(message, 
        IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
        IX_IEEE802_1Q_VLAN_TPID, 
        vlanTag);
    
    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
    
    return result;
}

/**
 * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID)
 *
 * @param portID ID of the port
 * @param vlanTag address to write the port VLAN tag (802.1Q tag) 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 ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(vlanTag);
    
    *vlanTag = ixEthDBPortInfo[portID].vlanTag;
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a 
 * database filtering record
 *
 * @param portID ID of the port
 * @param vlanTag VLAN tag (802.1Q tag)
 * 
 * Important: filtering records are automatically converted to 
 * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag.
 *
 * 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 ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag)
{
    HashNode *searchResult;
    MacDescriptor *descriptor;
    
    IX_ETH_DB_CHECK_REFERENCE(macAddr);
    
    IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
    
    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
    
    if (searchResult == NULL)
    {
        return IX_ETH_DB_NO_SUCH_ADDR;
    }
    
    descriptor = (MacDescriptor *) searchResult->data;
    
    /* set record type to VLAN if not already set */
    descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD;
    
    /* add vlan tag */
    descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag;
    
    /* transaction completed */
    ixEthDBReleaseHashNode(searchResult);
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a 
 * database VLAN filtering record
 *
 * @param portID ID of the port
 * @param vlanTag address to write the VLAN tag (802.1Q tag) 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 ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag)
{
    HashNode *searchResult;
    MacDescriptor *descriptor;
    
    IX_ETH_DB_CHECK_REFERENCE(macAddr);
    
    IX_ETH_DB_CHECK_REFERENCE(vlanTag);
    
    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD);
    
    if (searchResult == NULL)
    {
        return IX_ETH_DB_NO_SUCH_ADDR;
    }
    
    descriptor = (MacDescriptor *) searchResult->data;
        
    /* get vlan tag */
    *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag;
    
    /* transaction completed */
    ixEthDBReleaseHashNode(searchResult);
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief adds a VLAN to a port's VLAN membership table
 *
 * @param portID ID of the port
 * @param vlanID VLAN ID to add
 * 
 * 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 ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_VLAN_ID(vlanID);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);

    return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
}

/**
 * @brief removes a VLAN from a port's VLAN membership table
 *
 * @param portID ID of the port
 * @param vlanID VLAN ID to remove
 *
 * 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 ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);

    IX_ETH_DB_CHECK_VLAN_ID(vlanID);

    /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */
    vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK;
    
    /* check we're not asked to remove the default port VID */
    if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag))
    {
        return IX_ETH_DB_NO_PERMISSION;
    }
    
    return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
}

/**
 * @brief adds or removes a VLAN range from a port's 
 * VLAN membership table or TTI table
 *
 * @param portID ID of the port
 * @param vlanIDMin start of the VLAN range
 * @param vlanIDMax end of the VLAN range
 * @param table VLAN set to add or remove from
 * @param action ADD_VLAN or REMOVE_VLAN
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action)
{
    UINT32 setOffsetMin, setOffsetMax;
    
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin);
    
    IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax);
    
    /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */
    vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK;
    vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK;
    
    /* is this a range? */
    if (vlanIDMax < vlanIDMin)
    {
        return IX_ETH_DB_INVALID_VLAN;
    }
    
    /* check that we're not specifically asked to remove the default port VID */
    if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin)
    {
        return IX_ETH_DB_NO_PERMISSION;
    }
    
    /* compute set offsets */
    setOffsetMin = VLAN_SET_OFFSET(vlanIDMin);
    setOffsetMax = VLAN_SET_OFFSET(vlanIDMax);

    /* change VLAN range */
    for (; vlanIDMin <= vlanIDMax ; vlanIDMin++)
    {
        /* change vlan in local membership table */
        ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action);
    }

    /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */
    if (setOffsetMin == setOffsetMax)
    {
        /* send updated entry to NPE */
        return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin);
    }
    else
    {
        /* update a zone of the membership/transmit tag info table */
        return ixEthDBVlanTableRangeUpdate(portID);
    }
}

/**
 * @brief adds a VLAN range to a port's VLAN membership table
 *
 * @param portID ID of the port
 * @param vlanIDMin start of the VLAN range
 * @param vlanIDMax end of the VLAN range
 * 
 * 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 ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
}

/**
 * @brief removes a VLAN range from a port's VLAN membership table
 *
 * @param portID ID of the port
 * @param vlanIDMin start of the VLAN range
 * @param vlanIDMax end of the VLAN range
 *
 * 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 ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
{
    IX_ETH_DB_CHECK_PORT(portID);

    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
}

/**
 * @brief sets a port's VLAN membership table or TTI table and
 * updates the NPE VLAN configuration
 *
 * @param portID ID of the port
 * @param portVlanTable port VLAN table to set
 * @param vlanSet new set contents
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(vlanSet);

    memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet));
    
    return ixEthDBVlanTableRangeUpdate(portID);
}

/**
 * @brief retireves a port's VLAN membership table or TTI table
 *
 * @param portID ID of the port
 * @param portVlanTable port VLAN table to retrieve
 * @param vlanSet address to 
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(vlanSet);
    
    memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet));
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief sets a port's VLAN membership table
 *
 * @param portID ID of the port
 * @param vlanSet new VLAN membership table
 *
 * 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 ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
{
    IxEthDBVlanId vlanID;

    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_REFERENCE(vlanSet);

    /* set the bit corresponding to the PVID just in case */
    vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
    vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
    
    return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
}

/**
 * @brief retrieves a port's VLAN membership table
 *
 * @param portID ID of the port
 * @param vlanSet location to store the port's VLAN membership table
 *
 * 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 ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
}

/**
 * @brief enables or disables Egress tagging for one VLAN ID
 *
 * @param portID ID of the port
 * @param vlanID VLAN ID to enable or disable Egress tagging on
 * @param enabled TRUE to enable and FALSE to disable tagging
 *
 * 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 ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_VLAN_ID(vlanID);

    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);

    return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
}

/**
 * @brief retrieves the Egress tagging status for one VLAN ID
 *
 * @param portID ID of the port
 * @param vlanID VLAN ID to retrieve the tagging status for
 * @param enabled location to store the tagging status
 * (TRUE - tagging enabled, FALSE - tagging disabled)
 *
 * 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 ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(enabled);

    IX_ETH_DB_CHECK_VLAN_ID(vlanID);
    
    *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0);
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief enables or disables Egress VLAN tagging for a VLAN range
 *
 * @param portID ID of the port
 * @param vlanIDMin start of VLAN range
 * @param vlanIDMax end of VLAN range
 * @param enabled TRUE to enable or FALSE to disable VLAN tagging
 *
 * 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 ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
}

/**
 * @brief sets the Egress VLAN tagging table (the Transmit Tagging
 * Information table)
 *
 * @param portID ID of the port
 * @param vlanSet new TTI table
 *
 * 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 ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
{
    IxEthDBVlanId vlanID;

    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);

    IX_ETH_DB_CHECK_REFERENCE(vlanSet);

    /* set the PVID bit just in case */
    vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
    vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
    
    return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
}

/**
 * @brief retrieves the Egress VLAN tagging table (the Transmit 
 * Tagging Information table)
 *
 * @param portID ID of the port
 * @param vlanSet location to store the port's TTI table
 *
 * 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 ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
}

/**
 * @brief sends the NPE the updated frame filter and default
 * Ingress tagging
 *
 * @param portID ID of the port
 * 
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID)
{
    PortInfo *portInfo = &ixEthDBPortInfo[portID];
    IxNpeMhMessage message;
    IX_STATUS result;

    FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction);
    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);

    return result;
}

/**
 * @brief sets the default Ingress tagging behavior
 *
 * @param portID ID of the port
 * @param taggingAction default tagging behavior
 *
 * 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 ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction)
{
    PortInfo *portInfo;
    
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    portInfo = &ixEthDBPortInfo[portID];
    
    if (taggingAction == IX_ETH_DB_PASS_THROUGH)
    {
        portInfo->npeTaggingAction = 0x00;
    }
    else if (taggingAction == IX_ETH_DB_ADD_TAG)
    {
        portInfo->npeTaggingAction = 0x02;
    }
    else if (taggingAction == IX_ETH_DB_REMOVE_TAG)
    {
        portInfo->npeTaggingAction = 0x01;
    }
    else
    {
        return IX_ETH_DB_INVALID_ARG;
    }
    
    portInfo->taggingAction = taggingAction;
    
    return ixEthDBIngressVlanModeUpdate(portID);
}

/**
 * @brief retrieves the default Ingress tagging behavior of a port
 *
 * @param portID ID of the port
 * @param taggingAction location to save the default tagging behavior
 * 
 * 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 ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);

    IX_ETH_DB_CHECK_REFERENCE(taggingAction);
    
    *taggingAction = ixEthDBPortInfo[portID].taggingAction;
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief sets the Ingress acceptable frame type filter
 *
 * @param portID ID of the port
 * @param frameFilter acceptable frame type filter
 * 
 * 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 ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter)
{
    PortInfo *portInfo;
    IxEthDBStatus result = IX_ETH_DB_SUCCESS;
        
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    /* check parameter range 
       the ORed value of the valid values is 0x7
       a value having extra bits is invalid */
    if ((frameFilter | 0x7) != 0x7 || frameFilter == 0)
    {
        return IX_ETH_DB_INVALID_ARG;
    }
    
    portInfo = &ixEthDBPortInfo[portID];
    
    portInfo->frameFilter    = frameFilter;
    portInfo->npeFrameFilter = 0; /* allow all by default */
    
    /* if accepting priority tagged but not all VLAN tagged
       set the membership table to contain only VLAN ID 0 
       hence remove vlans 1-4094 and add VLAN ID 0 */
    if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0)
        && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0))
    {
        result = ixEthDBPortVlanMembershipRangeChange(portID, 
            1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN);

        if (result == IX_ETH_DB_SUCCESS)
        {
            ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN);
            result = ixEthDBVlanTableRangeUpdate(portID);
        }
    }
    
    /* untagged only? */
    if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES)
    {
        portInfo->npeFrameFilter = 0x01;
    }
    
    /* tagged only? */
    if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0)
    {
        portInfo->npeFrameFilter = 0x02;
    }

    if (result == IX_ETH_DB_SUCCESS)
    {
        result = ixEthDBIngressVlanModeUpdate(portID);
    }

    return result;
}

/**
 * @brief retrieves the acceptable frame type filter for a port
 *
 * @param portID ID of the port
 * @param frameFilter location to store the frame filter
 *
 * 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 ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(frameFilter);
    
    *frameFilter = ixEthDBPortInfo[portID].frameFilter;
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief sends an NPE the updated configuration related
 * to one QoS priority (associated traffic class and AQM mapping)
 *
 * @param portID ID of the port
 * @param classIndex QoS priority (traffic class index)
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 * or an appropriate error message otherwise
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex)
{
    IxNpeMhMessage message;
    IX_STATUS result;

    UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex];
    UINT32 aqmQueue     = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass];
    
    FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue);
    
    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
    
    return result;
}

/**
 * @brief sets the priority mapping table
 *
 * @param portID ID of the port
 * @param priorityTable new priority mapping table
 *
 * 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 ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
{
    UINT32 classIndex;
    
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(priorityTable);
           
    for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
    {
        /* check range */
        if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
        {
            return IX_ETH_DB_INVALID_PRIORITY;
        }
    }
    
    /* set new traffic classes */
    for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
    {
        ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex];
        
        if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS)
        {
            return IX_ETH_DB_FAIL;
        }
    }
    
    return IX_ETH_DB_SUCCESS;
 }

/**
 * @brief retrieves a port's priority mapping table
 *
 * @param portID ID of the port
 * @param priorityTable location to store the priority table
 *
 * 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 ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(priorityTable);
    
    memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable));
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief sets one QoS priority => traffic class mapping
 *
 * @param portID ID of the port
 * @param userPriority QoS (user) priority
 * @param trafficClass associated traffic class
 *
 * 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 ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);

    /* check ranges for userPriority and trafficClass */
    if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
    {
        return IX_ETH_DB_INVALID_PRIORITY;
    }
    
    ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass;
    
    return ixEthDBUpdateTrafficClass(portID, userPriority);
}

/**
 * @brief retrieves one QoS priority => traffic class mapping
 *
 * @param portID ID of the port
 * @param userPriority QoS (user) priority
 * @param trafficClass location to store the associated traffic class
 * 
 * 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 ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass)
{
    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
    
    IX_ETH_DB_CHECK_REFERENCE(trafficClass);
    
    /* check userPriority range */
    if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT)
    {
        return IX_ETH_DB_INVALID_PRIORITY;
    }
    
    *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority];
    
    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief enables or disables the source port extraction
 * from the VLAN TPID field
 *
 * @param portID ID of the port
 * @param enable TRUE to enable or FALSE to disable
 *
 * 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 ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable)
{
    IxNpeMhMessage message;
    IX_STATUS result;

    IX_ETH_DB_CHECK_PORT(portID);
    
    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
    
    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);

    FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable);

    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
    
    return result;
}
