/*****************************************************************************
 *                            Intel Proprietary
 *
 * Copyright (c) 1998-2002 By Intel Corporation.  All rights reserved.  
 * No part of this program or publication may be reproduced, transmitted,
 * transcribed, stored in a retrieval system, or translated into any language
 * or computer language in any form or by any means, electronic, mechanical,
 * magnetic, optical, chemical, manual, or otherwise, without the prior
 * written permission of:
 *                        Intel Corporation
 *                        2200 Mission College Blvd.
 *                        Santa Clara, CA  95052-8119
 *****************************************************************************/

/**
 *****************************************************************************
 * @ingroup LlcSnapEncap
 *
 * File:  ix_cc_llc_snap_encap_library.c
 *
 * @description
 *      This file defines the library API used by the LLC Snap
 *      Encapsulation Core Component.
 *
 *****************************************************************************/

/*****************************************************************************
 *
 * Contents:
 *        Definitions of following exported data:
 *
 *        Definitions of following exported functions:
 *            ix_cc_llc_snap_encap_add_next_hop
 *            ix_cc_llc_snap_encap_delete_next_hop
 *
 *        Definitions of following local data:
 *
 *        Definitions of following local functions:
 *
 *****************************************************************************/


/*
 * User defined include files
 */
#include "ix_cc_llc_snap_encap.h"
#include "ix_cc_llc_snap_encap_private.h"


/**
 ****************************************************************************
 * @ingroup LlcSnapEncap
 * Add a new Next Hop entry to the table
 * @description
 *    This library function actually fills the entry in the Next Hop table.
 *    Table index is the nextHop function argument. The CC checks if the
 *    desired entry is empty; if it is - the entry is filled with received
 *    data; if it is not - proper error code is returned.
 *
 * @param nextHop - IN: Next Hop ID
 * @param vpi - IN: outgoing VPI for the packet
 * @param vci - IN: outgoing VCI for the packet
 * @param vcq - IN: VCQ number for the packet
 * @param dSap - IN: LLC header: DSAP field
 * @param sSap - IN: LLC header: SSAP field
 * @param ctrl - IN: LLC header: Ctrl field
 * @param oui - IN: SNAP header: Organizationally Unique Identifier (OUI) field
 * @param pid - IN: SNAP header: Protocol Identifier (PID) field   
 *
 * @retval IX_SUCCESS - entry successfully added
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM - invalid input
 *                                                          parameter(s)
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_DUPLICATED - entry already exists
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED - Core Component not
 *                                                      initialized yet
 *
 *****************************************************************************/
ix_error
ix_cc_llc_snap_encap_add_next_hop(ix_uint16 nextHop,
                                  ix_uint8 encapType,
                                  ix_uint16 vpi,
                                  ix_uint16 vci,
                                  ix_uint16 vcq,
                                  ix_uint8 dSap,
                                  ix_uint8 sSap,
                                  ix_uint8 ctrl,
                                  ix_uint32 oui,
                                  ix_uint16 pid)
{
    llc_snap_encap_next_hop_entry_t* pNextHopTable;
    
    /* check if the CC is initialized yet */
    if ((pLlcSnapEncapContext == NULL) ||
        (pLlcSnapEncapContext->initialized != TRUE))
    {
        /* Core Component not initialized */
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED,
        ("LLC Snap Encap Add Next Hop: CC not initialized yet"));
    }

    /* check parameters' consistency */
    if (nextHop > llcSnapEncapRegistryData.numberOfNextHopEntries)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM,
        ("LLC Snap Encap Add Next Hop: nextHop value invalid"));
    }

    if ((encapType != ENCAP_LLC) && (encapType != ENCAP_VCMUX))
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM,
        ("LLC Snap Encap Add Next Hop: encapType value invalid"));
    }

    /* get the Next Hop table from context */
    pNextHopTable = (llc_snap_encap_next_hop_entry_t*) \
        (pLlcSnapEncapContext->pNextHopTableSramBase);

    if (pNextHopTable == NULL)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED,
        ("LLC Snap Encap Add Next Hop: Next Hop table is NULL"));
    }

    /* check if the entry is occupied - we assume VCI cannot be equal to 0 */
    if (pNextHopTable[nextHop].vci != 0)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_DUPLICATED,
        ("LLC Snap Encap Add Next Hop: Entry already exists"));
    }

    /* entry clear, fill it with received data */
    pNextHopTable[nextHop].vpi = vpi;
    pNextHopTable[nextHop].vci = vci;
    pNextHopTable[nextHop].vcq = vcq;

    if (encapType == ENCAP_LLC)
    {
        pNextHopTable[nextHop].encap_header.llc_snap.dSap = dSap;
        pNextHopTable[nextHop].encap_header.llc_snap.sSap = sSap;
        pNextHopTable[nextHop].encap_header.llc_snap.ctrl = ctrl;
        pNextHopTable[nextHop].encap_header.llc_snap.oui  = oui;
        pNextHopTable[nextHop].encap_header.llc_snap.pid  = pid;
    }
    else /* VCMUX */
    {
        pNextHopTable[nextHop].encap_header.vcmux.lw0 = VCMUX_FILL;
        pNextHopTable[nextHop].encap_header.vcmux.lw1 = VCMUX_FILL;
    }
        
    return IX_SUCCESS;
    
} /* ix_cc_llc_snap_encap_add_next_hop */


/**
 ****************************************************************************
 * @ingroup LlcSnapEncap
 * Delete an entry in the Next Hop table
 * @description
 *    This library function actually deletes the entry in the Next Hop table.
 *    Table index is the nextHop function argument. The CC checks if the
 *    desired entry exists; if it does - the entry is cleared (thus removed);
 *    if it does not - proper error code is returned.
 *
 * @param nextHop - IN: Next Hop ID
 *
 * @retval IX_SUCCESS - message was successfully built and sent 
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM - invalid input
 *                                                          parameter
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_FOUND - such entry does not exist 
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED - Core Component not
 *                                                      initialized yet
 *
 *****************************************************************************/
ix_error
ix_cc_llc_snap_encap_delete_next_hop(ix_uint16 nextHop)
{
    llc_snap_encap_next_hop_entry_t* pNextHopTable;
    
    /* check if the CC is initialized yet */
    if ((pLlcSnapEncapContext == NULL) ||
        (pLlcSnapEncapContext->initialized != TRUE))
    {
        /* Core Component not initialized */
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED,
        ("LLC Snap Encap Delete Next Hop: CC not initialized yet"));
    }

    /* check parameters' consistency */
    if (nextHop > llcSnapEncapRegistryData.numberOfNextHopEntries)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM,
        ("LLC Snap Encap Delete Next Hop: nextHop value invalid"));
    }

    /* get the Next Hop table from context */
    pNextHopTable = (llc_snap_encap_next_hop_entry_t*) \
        (pLlcSnapEncapContext->pNextHopTableSramBase);

    if (pNextHopTable == NULL)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED,
        ("LLC Snap Encap Delete Next Hop: Next Hop table is NULL"));
    }

    /* check if the entry is occupied - we assume VCI cannot be equal to 0 */
    if (pNextHopTable[nextHop].vci == 0)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_FOUND,
        ("LLC Snap Encap Delete Next Hop: Entry does not exist"));
    }

    /* entry found - remove it */
    ix_ossl_memset(&pNextHopTable[nextHop],
                   0,
                   sizeof(llc_snap_encap_next_hop_entry_t));
    
    return IX_SUCCESS;
    
} /* ix_cc_llc_snap_encap_delete_next_hop */

