/******************************************************************************
 *
 *  <:copyright-BRCM:2016:DUAL/GPL:standard
 *  
 *     Copyright (c) 2016 Broadcom
 *     All Rights Reserved
 *  
 *  Unless you and Broadcom execute a separate written software license
 *  agreement governing use of this software, this software is licensed
 *  to you under the terms of the GNU General Public License version 2
 *  (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
 *  with the following added to such license:
 *  
 *     As a special exception, the copyright holders of this software give
 *     you permission to link this software with independent modules, and
 *     to copy and distribute the resulting executable under terms of your
 *     choice, provided that you also meet, for each linked independent
 *     module, the terms and conditions of the license of that module.
 *     An independent module is a module which is not derived from this
 *     software.  The special exception does not apply to any modifications
 *     of the software.
 *  
 *  Not withstanding the above, under no circumstances may you combine
 *  this software in any way with any other Broadcom software provided
 *  under a license other than the GPL, without Broadcom's express prior
 *  written consent.
 *  
 *  :>
 *
 *****************************************************************************/
 
 /**
 * @file bal_dpp_vswitch.c
 * @brief BAL Switch util helper functions that handle vswitch service requests
 * @addtogroup sw_util
 */

/*@{*/
#include <bal_common.h>
#include <bcm_dev_log.h>
#include <bal_msg.h>
#include <bal_utils_msg.h>
#include "bcmos_errno.h"

#ifndef TEST_SW_UTIL_LOOPBACK
#include <bcm/types.h>
#include <sal/core/libc.h>
#ifndef sal_memset
#define sal_memset memset
#endif
#include <bcm/port.h>
#include <bcm/vlan.h>
#include <bcm/error.h>
#include <bcm/vswitch.h>

#include "bal_switch_flow.h"
#include "bal_dpp_vswitch.h"
#include "bal_switch_util.h"

/* A local link list to keep trak of virtual switch service */
TAILQ_HEAD(bal_sw_vsi_list_head, bal_sw_vsi_service) g_swutil_vsi_list;

/**
 * @brief The vsi list init function prepare a link list to keep track of 
 *        vsi service in the switch util
 *
 * @return error code
 */
bcmos_errno bal_sw_util_vsi_list_init(void)
{
    static uint32_t g_vsi_inited = 0;
    if(g_vsi_inited == 0)
    {
        TAILQ_INIT(&g_swutil_vsi_list);
        g_vsi_inited = 1;
    }
    return BCM_ERR_OK;
}

/**
 * @brief The vsi list search function by LIF tag
 *
 * @param p_lif_tag a pointer to the packet tag that need to match the entry in the list
 * @param p_svc_indx  a pointer to store the created service tag index within the vsi 
 
 * @return pointer to an element in the list, NULL if failed
 */
static bal_sw_vsi_service *bal_sw_util_dpp_vsi_service_get_by_tag(bal_sw_lif_pkt_tag *p_lif_tag, uint32_t *p_svc_indx)
{
    bal_sw_vsi_service *p_entry, *p_temp;
    int lif_match = 0, svc_idx;
    
    if(p_svc_indx == NULL)
    { 
        BCM_LOG(ERROR, log_id_sw_util, "call VSI service get tag with invalid parameter\n");
        return NULL;
    }
    
    /* clear the storage area */
    *p_svc_indx = 0;
    
    TAILQ_FOREACH_SAFE(p_entry, &g_swutil_vsi_list, next_service, p_temp)
    {  
        for(svc_idx = 0; svc_idx < p_entry->num_tag; svc_idx++)
        {            
            if( p_entry->pkt_tag[svc_idx].type == p_lif_tag->type)
            {
                switch (p_lif_tag->type)
                {
                case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                    if( p_lif_tag->o_vid == p_entry->pkt_tag[svc_idx].o_vid)
                    {
                        lif_match = 1;
                    }   
                    break;
                case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
                    if( p_lif_tag->o_vid == p_entry->pkt_tag[svc_idx].o_vid && p_lif_tag->i_vid == p_entry->pkt_tag[svc_idx].i_vid)
                    {
                        lif_match = 1;
                    }   
                    break;
                case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
                    lif_match = 1;
                    break;
                default:
                    BCM_LOG(ERROR, log_id_sw_util, "Unsupported packet type %d in LIF info\n", p_lif_tag->type);
                    return NULL;            
                }
                if(lif_match)
                {
                    if(p_svc_indx)
                    {
                        *p_svc_indx = svc_idx;
                    }
                    return p_entry;
                }
            }
        }
    }

    /* if reach the end of the list, TAILQ_FOREACH_SAFE set the p_entry to NULL */
    return NULL;
   
}

/*
 * @brief The vsi list insert function
 *
 * @param entry  the vsi element to be added in the link list
 * @return error code
*/
static bal_sw_vsi_service *bal_sw_util_vsi_list_insert(bal_sw_vsi_service  *p_entry)
{
    bal_sw_vsi_service *p_new_entry;

    p_new_entry = bcmos_calloc(sizeof(bal_sw_vsi_service));
    if(NULL == p_new_entry)
    {
        BCM_LOG(ERROR, log_id_sw_util, "VSI list insert out of memory\n");
        return NULL;
    }
    *p_new_entry = *p_entry;
    TAILQ_INSERT_TAIL(&g_swutil_vsi_list, p_new_entry, next_service);
    return p_new_entry;
}

/*
 * @brief The vsi list remove function
 *
 * @param p_entry Pointer to the vsi element in the link list result from the search functions
 * @return error code
*/
static bcmos_errno bal_sw_util_vsi_list_remove(bal_sw_vsi_service *p_entry)
{
    TAILQ_REMOVE(&g_swutil_vsi_list, p_entry, next_service);
    bcmos_free(p_entry);
    return BCM_ERR_OK;
}

/**
 * @brief The vsi create function create a virtual switch service that contains ingress LIF 
 *        and virtual switch. This service can later be connected to multiple egress LIF of multiple FLOWs.  
 *        The function use the source port and vid information in the bcmbal_flow_cfg as input
 *        The pointer of the created vsi will be returned
 *        Since a vsi can provide multiple srevices, the index to the created service tag is return here
 *  
 * @param unit        switch device id 
 * @param p_flow      a pointer to the flow definition which the created service will be based on
 * @param p_svc_indx  a pointer to store the created service tag index within the vsi  
 * 
 * @return pointer to the vsi service list entry, NULL if operation failed
 */

bal_sw_vsi_service *bal_sw_util_dpp_vsi_service_create(int unit, bcmbal_flow_cfg *p_flow, uint32_t *p_svc_indx)
{
    int rv;
    bal_sw_lif_pkt_tag svc_pkt_tag = {0};
    bal_sw_vsi_service *p_vsi_service, vsi_svc_elm;
    bcm_vlan_t vsi;
    int multicast_id, flags;
    
    /* p_flow can be NULL when create vswitch for multicast group, service tag will be added when multicast flow is created */
    if (p_flow == NULL) 
    {
        BCM_LOG(INFO, log_id_sw_util, "create vsi service with no service tag \n");
        p_vsi_service = NULL;
    }
    else
    {
        /* find out if the vsi service already exist */
        svc_pkt_tag.type = p_flow->data.classifier.pkt_tag_type;
        svc_pkt_tag.o_vid = p_flow->data.classifier.o_vid;
        svc_pkt_tag.i_vid = p_flow->data.classifier.i_vid;
        p_vsi_service = bal_sw_util_dpp_vsi_service_get_by_tag(&svc_pkt_tag, p_svc_indx);
    }
    
    /* if no service, create one */
    if(p_vsi_service == NULL)
    {
        /* initialize link list vsi element */
        memset(&vsi_svc_elm, 0, sizeof (bal_sw_vsi_service));
        /* if flow (service tag) is specified, fill in the basic info, since it is new, add it to the first tag */
        if(p_flow)
        {
            vsi_svc_elm.pkt_tag[0] = svc_pkt_tag;
            vsi_svc_elm.num_tag = 1;
        }
        
        rv = bcm_vswitch_create(unit, &vsi);
        if (rv != BCM_E_NONE)
        {
            BCM_LOG(ERROR, log_id_sw_util, "bcm_vswitch_create failed %d \n", rv);
            return NULL;            
        }
        else
        {
            BCM_LOG(INFO, log_id_sw_util, " vswitch 0x%x created\n", vsi);
        }
        vsi_svc_elm.vswitch = vsi;
        /* create two multicast groups (a.k.a. flooding group), one for upstream and one for downstream
           clean up first, it is OK there is nothing to destroy */

        /* Create the multicast group used for upstream flooding
         * (PON-->NNI). For the upstream mcast group, the QAX hardware
         * requires the ID to be set to a value equal to the VSI ID
         * created above.
         */
        multicast_id = vsi + BAL_DPP_US_FLOOD_OFFSET;
        rv = bcm_multicast_group_is_free(unit, multicast_id);
        if (rv == BCM_E_EXISTS)
        {
            rv = bcm_multicast_destroy(unit, multicast_id);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "US: bcm_multicast_destroy 0x%x failed %d \n", multicast_id, rv);
                bcm_vswitch_destroy(unit, vsi);
                return NULL;                
            }
        }
        /* flags = ingress replication + fixed id + L2 multicast */
        flags = BCM_MULTICAST_INGRESS_GROUP | BCM_MULTICAST_WITH_ID | BCM_MULTICAST_TYPE_L2;
        rv = bcm_multicast_create(unit, flags, &multicast_id);
        if (rv != BCM_E_NONE)
        {
           BCM_LOG(ERROR, log_id_sw_util, "US: in bcm_multicast_create 0x%x w ingress failed %d \n", multicast_id, rv);
           bcm_vswitch_destroy(unit, vsi);
           return NULL;           
        }
        else
        {
            BCM_LOG(INFO, log_id_sw_util, "US: vswitch flood group 0x%x created\n", multicast_id);
        }
        vsi_svc_elm.us_flood_grp_id = multicast_id;

        /* downstream flooding group */
        multicast_id = vsi + BAL_DPP_DS_FLOOD_OFFSET;
        rv = bcm_multicast_group_is_free(unit, multicast_id);
        if (rv == BCM_E_EXISTS)
        {
            rv = bcm_multicast_destroy(unit, multicast_id);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "DS: bcm_multicast_destroy 0x%x failed %d \n", multicast_id, rv);
                bcm_multicast_destroy(unit, vsi_svc_elm.us_flood_grp_id);
                bcm_vswitch_destroy(unit, vsi);
                return NULL;                
            }
        }
        flags = BCM_MULTICAST_INGRESS_GROUP | BCM_MULTICAST_WITH_ID | BCM_MULTICAST_TYPE_L2;
        rv = bcm_multicast_create(unit, flags, &multicast_id);
        if (rv != BCM_E_NONE)
        {
           BCM_LOG(ERROR, log_id_sw_util, "DS: in bcm_multicast_create 0x%x w ingress 2 failed %d \n", multicast_id, rv);
           bcm_multicast_destroy(unit, vsi_svc_elm.us_flood_grp_id);
           bcm_vswitch_destroy(unit, vsi);
           return NULL;           
        }
        else
        {
            BCM_LOG(INFO, log_id_sw_util, "DS: vswitch flood group 0x%x created\n", multicast_id);
        }
        vsi_svc_elm.ds_flood_grp_id = multicast_id;
                
        /* add vsi service to the vsi list */
        p_vsi_service = bal_sw_util_vsi_list_insert(&vsi_svc_elm);
        if (p_vsi_service == NULL)
        {
            BCM_LOG(ERROR, log_id_sw_util, "VSI: fail to insert new vsi to the service list\n");
            bcm_multicast_destroy(unit, vsi_svc_elm.us_flood_grp_id);
            bcm_multicast_destroy(unit, vsi_svc_elm.ds_flood_grp_id);
            bcm_vswitch_destroy(unit, vsi_svc_elm.vswitch);   
            return NULL; 
        }
         p_vsi_service->use_count = 1;
    } 
    else
    {
        p_vsi_service->use_count++;
    }         

    return p_vsi_service;
}

/**
 * @brief The vsi destroy function free up Hardare resource of a virtual switch. 
 *        It also remove the vsi fromt the service list
 *
 * @param unit        switch device id 
 * @param p_vsi_svc   a pointer to the vsi service
 * 
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_vsi_service_destroy(int unit, bal_sw_vsi_service *p_vsi_svc)
{
    int rv;
    
     /* input validation */
    if (p_vsi_svc == NULL) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "destroy vsi service with invalid parameters \n");
        return BCM_ERR_PARM;
    }
    
    /* only clean up when no more users */
    if(p_vsi_svc->use_count > 1)
    {
        p_vsi_svc->use_count--;
        return BCM_ERR_OK;   
    }
    
    /* free up HW resource, continue even if any failed */
    rv = bcm_multicast_destroy(unit, p_vsi_svc->us_flood_grp_id);
    if (rv != BCM_E_NONE)
    {
        BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy US 0x%x failed %d \n", p_vsi_svc->us_flood_grp_id, rv);
    }
    rv = bcm_multicast_destroy(unit, p_vsi_svc->ds_flood_grp_id);
    if (rv != BCM_E_NONE)
    {
        BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy DS 0x%x failed %d \n", p_vsi_svc->ds_flood_grp_id, rv);
    }
    rv = bcm_vswitch_destroy(unit, p_vsi_svc->vswitch);
    if (rv != BCM_E_NONE)
    {
        BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy vswitch 0x%x failed %d \n", p_vsi_svc->vswitch, rv);
    }    
    
    /* remove from the service list */
    rv = bal_sw_util_vsi_list_remove(p_vsi_svc);
    if (rv != BCM_E_NONE)
    {
        BCM_LOG(WARNING, log_id_sw_util, "bcm_multicast_destroy VSI entry failed %d \n", rv);
    }
    
    return BCM_ERR_OK;
}


/**
 * @brief The vsi port_find function search a port from the port list of a vsi service entry. 
 *
 * @param p_vsi_svc   a pointer to the vsi service
 * @param svc_tag_indx an index to the service within the vsi that a port need to be searched
 * @param port        the ingress port that needs to be located
 * @param idx         pointer to a storage where the array index of the found port will be return
 * 
 * @return           error code
 */

static bcmos_errno bal_sw_util_dpp_vsi_service_port_find(bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t port, uint32_t *idx)
{
    int i;
    
    /* input validation */
    if (p_vsi_svc == NULL) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "vsi service port find function with invalid parameters \n");
        return BCM_ERR_PARM;
    }
    /* loop through the list */
    for( i=0; i<p_vsi_svc->pkt_tag[svc_tag_indx].num_port; i++)
    {
        if(p_vsi_svc->pkt_tag[svc_tag_indx].port[i].port == port)
        {
            break;
        }
    }
    if (i == p_vsi_svc->pkt_tag[svc_tag_indx].num_port)
    {
        return BCM_ERR_NOENT;
    }
    *idx = i;
    return BCM_ERR_OK;
}

/**
 * @brief The vsi port_find function search a gport from the port list of a vsi service entry. 
 *
 * @param p_vsi_svc   a pointer to the vsi service
 * @param svc_tag_indx an index to the service within the vsi that a gport need to be searched
 * @param gport       the ingress gport that needs to be located
 * @param idx         pointer to a storage where the array index of the found port will be return
 * 
 * @return           error code
 */

static bcmos_errno bal_sw_util_dpp_vsi_service_gport_find(bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t gport, uint32_t *idx)
{
    int i;
    
    /* input validation */
    if (p_vsi_svc == NULL) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "vsi service port find function with invalid parameters \n");
        return BCM_ERR_PARM;
    }
    /* loop through the list */
    for( i=0; i<p_vsi_svc->pkt_tag[svc_tag_indx].num_port; i++)
    {
        if(p_vsi_svc->pkt_tag[svc_tag_indx].port[i].gport == gport)
        {
            break;
        }
    }
    if (i == p_vsi_svc->pkt_tag[svc_tag_indx].num_port)
    {
        return BCM_ERR_NOENT;
    }
    *idx = i;
    return BCM_ERR_OK;
}

/**
 * @brief The vsi port_add function add an ingress port to the vsi service.
          If the port is already in the vsi, just increase the counter
          If the port is not in the vsi, create a gport and add it to the US flooding group.
          This allows the US SPEAK_FIRST packets to be forwarded to the network.   
 *
 * @param unit        switch device id 
 * @param p_vsi_svc   a pointer to the vsi service
 * @param svc_tag_indx an index to the service within the vsi that a port need to be added
 * @param port        the ingress port that needs to be added to the vsi service
 * @param p_gport     a valid pointer where the created/existing gport will be returned.
 *                    NULL, if caller don't care the gport  
 * 
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_vsi_service_port_add(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t port, int32_t *p_gport)
{
    bcm_vlan_port_t vp;
    uint32_t idx;
    int ind, rv;
    int32_t gport;
    bcmos_errno ret;
    int port_encap_id;

    /* input validation */
    if (p_vsi_svc == NULL) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "vsi service port add function with invalid parameters \n");
        return BCM_ERR_PARM;
    }
    /* check if the port already in the vsi */
    ret = bal_sw_util_dpp_vsi_service_port_find(p_vsi_svc, svc_tag_indx, port, &idx);
    /* if port already in the vsi, just increase the counter */
    if(ret == BCM_ERR_OK)
    {
        if(p_gport)
        {
            *p_gport = p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].gport;
        }
        (p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].use_count)++;
        return BCM_ERR_OK;
    }
    
    /* create the LIF */
    bcm_vlan_port_t_init(&vp);
    vp.port = port;
    /* configure frame match according to the service packet tags */
    switch(p_vsi_svc->pkt_tag[svc_tag_indx].type)
    {
        case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
            vp.criteria = BCM_VLAN_PORT_MATCH_PORT;
        break;
        case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
            vp.criteria = BCM_VLAN_PORT_MATCH_PORT_VLAN;
            vp.match_vlan = p_vsi_svc->pkt_tag[svc_tag_indx].o_vid;
        break;
        case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
            vp.criteria = BCM_VLAN_PORT_MATCH_PORT_VLAN_STACKED;
            vp.match_vlan = p_vsi_svc->pkt_tag[svc_tag_indx].o_vid;
            vp.match_inner_vlan = p_vsi_svc->pkt_tag[svc_tag_indx].i_vid;
        break;
        default:
            /* should not reach here */
            BCM_LOG(ERROR, log_id_sw_util, "VSI: Unsupported packet type %d \n",p_vsi_svc->pkt_tag[svc_tag_indx].type );
            return BCM_ERR_INTERNAL;
        break;
    }
    
    vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */      
    vp.flags = BCM_VLAN_PORT_OUTER_VLAN_PRESERVE  | BCM_VLAN_PORT_INNER_VLAN_PRESERVE;

    rv = bcm_vlan_port_create(unit, &vp);
    if (rv != BCM_E_NONE)
    {
         BCM_LOG(ERROR, log_id_sw_util, "VSI: bcm_vlan_port_create port %d, failed %d\n", port, rv);
         return BCM_ERR_INTERNAL;
    }

    gport = vp.vlan_port_id;

    // add gport to vswitch
    rv = bcm_vswitch_port_add(unit, p_vsi_svc->vswitch, gport);
    if (rv != BCM_E_NONE)
    {
         BCM_LOG(ERROR, log_id_sw_util, "VSI, bcm_vswitch_port_add for port %d failed %d\n", port, rv);
         bcm_vlan_port_destroy(unit, gport);         
         return BCM_ERR_INTERNAL;        
    }
    else
    {
        BCM_LOG(INFO, log_id_sw_util, "VSI: bcm_vswitch_port_add for port %d, gport 0x%x\n", port, gport);
    }
    /* if caller requre for the gport info, return the gport */
    if(p_gport)
    {
        *p_gport = gport;
    }
    /* record the gport into the vsi */
    ind = p_vsi_svc->pkt_tag[svc_tag_indx].num_port;
    if (ind == MAX_NET_PORT)
    {
        BCM_LOG(ERROR, log_id_sw_util, "VSI, reach max port allow\n");
        bcm_vswitch_port_delete(unit, p_vsi_svc->vswitch, gport);
        bcm_vlan_port_destroy(unit, gport);         
        return BCM_ERR_NORES;          
    }
    p_vsi_svc->pkt_tag[svc_tag_indx].port[ind].port = port;
    p_vsi_svc->pkt_tag[svc_tag_indx].port[ind].gport = gport;
    p_vsi_svc->pkt_tag[svc_tag_indx].port[ind].use_count = 1;
    p_vsi_svc->pkt_tag[svc_tag_indx].num_port = ++ind;

    ret = BCM_ERR_OK;
    do
    {
        // update flooding group with phy_port/gport as ingress port
        rv = bcm_multicast_vlan_encap_get(unit, p_vsi_svc->us_flood_grp_id, port, gport, &port_encap_id);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_vlan_encap_get for port failed %d\n", rv);
             ret = BCM_ERR_NOENT;
             break;             
        }
        /* be a member of the upstream flooding group */
        rv = bcm_multicast_ingress_add(unit, p_vsi_svc->us_flood_grp_id, port, port_encap_id);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_ingress_add for port failed %d\n", rv);     
             ret = BCM_ERR_NOENT;
             break;
        }
        
        /* now set the type of packets that goes to the downstream flooding group */
        /* forward unknown unicast */        
        rv = bcm_port_control_set(unit, gport, bcmPortControlFloodUnknownUcastGroup, BAL_DPP_DS_FLOOD_OFFSET);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set ucast for nni failed %d\n", rv);
             ret = BCM_ERR_INTERNAL;
             break;
        }
        /* drop unknown multicast */
        rv = bcm_port_control_set(unit, gport, bcmPortControlFloodUnknownMcastGroup, BCM_GPORT_BLACK_HOLE);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set mcast for nni failed %d\n", rv);
             ret = BCM_ERR_INTERNAL;
             break;
        }
        
        /* forward broadcast */
        rv = bcm_port_control_set(unit, gport, bcmPortControlFloodBroadcastGroup, BAL_DPP_DS_FLOOD_OFFSET);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set bcast for nni failed %d\n", rv);
             ret = BCM_ERR_INTERNAL;
             break;
        }
    }while(0);
    
    return ret;
}

/**
 * @brief The vsi port_rem function remove an ingress port to the vsi service.
 *
 * @param unit        switch device id 
 * @param p_vsi_svc   a pointer to the vsi service
 * @param svc_tag_indx an index to the service within the vsi that a port need to be removed
 * @param gport       the ingress gport that needs to be removed from the vsi service
 *
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_vsi_service_port_rem(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx, uint32_t gport)
{
    uint32_t idx;;
    int port_encap_id, rv, i;
    bcmos_errno ret = BCM_ERR_OK;
    int port;
    /* input validation */
    if (p_vsi_svc == NULL) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "vsi service port rem function with invalid parameters \n");
        return BCM_ERR_PARM;
    }
    /* check if the port in the vsi */
    ret = bal_sw_util_dpp_vsi_service_gport_find(p_vsi_svc, svc_tag_indx, gport, &idx);
    if(ret != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, log_id_sw_util, "Error, vsi service port find for gport %d failed\n", gport);
        return ret;
    }
    /* only remove from the array when no flow reference it */
    if(p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].use_count > 1)
    { 
        (p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].use_count)--;
        return BCM_ERR_OK;
    }
   
    port = p_vsi_svc->pkt_tag[svc_tag_indx].port[idx].port;
    
    /* compact the port list */
    for(i=idx; i<p_vsi_svc->pkt_tag[svc_tag_indx].num_port-1; i++)
    {
        p_vsi_svc->pkt_tag[svc_tag_indx].port[i] = p_vsi_svc->pkt_tag[svc_tag_indx].port[i+1];
    }
    memset(&p_vsi_svc->pkt_tag[svc_tag_indx].port[i], 0, sizeof (bal_sw_lif_port));
    
    (p_vsi_svc->pkt_tag[svc_tag_indx].num_port)--; 
    
    ret = BCM_ERR_OK;
    do
    {
        /* find the encap_id */
        rv = bcm_multicast_vlan_encap_get(unit, p_vsi_svc->us_flood_grp_id, port, gport, &port_encap_id);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_vlan_encap_get for port %d failed %d\n", port, rv);
             ret = BCM_ERR_NOENT;
             break;             
        }
        /* remove from the upstream flooding group */
        rv = bcm_multicast_ingress_delete(unit, p_vsi_svc->us_flood_grp_id, port, port_encap_id);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_ingress_delete for port %d failed %d\n", port, rv);     
             ret = BCM_ERR_NOENT;
             break;
        }
        rv = bcm_vswitch_port_delete(unit, p_vsi_svc->vswitch, gport);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vswitch_port_delete for port %d failed %d\n", port, rv);
             ret = BCM_ERR_NOENT;
             break;             
        }
        rv = bcm_vlan_port_destroy(unit, gport);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(WARNING, log_id_sw_util, "Error, bcm_vlan_port_destroy for port %d failed %d\n", port, rv);
             /* Likely a bug in the 6.5.4 release, igore for now
             ret = BCM_ERR_NOENT;
             break;  
             */             
        }    
    }while(0);
    return  ret;
}

/**
 * @brief The vsi_service_tag_add function add the service tag of a flow to a vsi target service.
 *
 * @param unit           switch device id 
 * @param p_vsi_target   a pointer to the vsi service
 * @param p_flow         a pointer to a flow that define the service tag need to be added
 * @param p_svc_tag_indx a pointer to store the return service tag index that just added
 *
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_vsi_service_tag_add(int unit, bal_sw_vsi_service *p_vsi_target, bcmbal_flow_cfg *p_flow, uint32_t *p_svc_tag_indx)
{
    bal_sw_lif_pkt_tag svc_pkt_tag = {0};
    bal_sw_vsi_service *p_vsi_service;
    
    /* input parameters checking */
    if (p_flow == NULL || p_vsi_target == NULL || p_svc_tag_indx == NULL) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "invalid parameters when adding vsi service tag \n");
        return BCM_ERR_PARM;
    }    
    
    /* find out if the service tag already exist */
    svc_pkt_tag.type = p_flow->data.classifier.pkt_tag_type;
    svc_pkt_tag.o_vid = p_flow->data.classifier.o_vid;
    svc_pkt_tag.i_vid = p_flow->data.classifier.i_vid;
    p_vsi_service = bal_sw_util_dpp_vsi_service_get_by_tag(&svc_pkt_tag, p_svc_tag_indx);
    if (p_vsi_service)
    {
        /* if the service tag already exist in the system, it has to be within the same vsi.
           We don't allow same service tag to be serviced by more than one vsi
         */
        if(p_vsi_service != p_vsi_target)
        {
            return BCM_ERR_INTERNAL;
        }
        else
        {
            return BCM_ERR_OK;
        }                      
    }

    /* now add the tag to the list */       
    p_vsi_target->pkt_tag[p_vsi_target->num_tag] = svc_pkt_tag;
    *p_svc_tag_indx = p_vsi_target->num_tag;
    p_vsi_target->num_tag ++;
    return BCM_ERR_OK;
}

/**
 * @brief The vsi_service_tag_rem function remove the service tag index by svc_tag_indx from a vsi service.
 *
 * @param unit           switch device id 
 * @param p_vsi_svc      a pointer to the vsi service
 * @param svc_tag_indx   a service tag index point to the service tag list that need to be removed
 *
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_vsi_service_tag_rem(int unit, bal_sw_vsi_service *p_vsi_svc, uint32_t svc_tag_indx)
{
    int i;
       /* input parameters checking */
    if (p_vsi_svc == NULL || p_vsi_svc->num_tag <= svc_tag_indx) 
    {
        BCM_LOG(ERROR, log_id_sw_util, "invalid parameters when removing vsi service tag \n");
        return BCM_ERR_PARM;
    } 
    /* compact the tag list */
    for(i=svc_tag_indx; i<p_vsi_svc->num_tag-1; i++)
    {
        p_vsi_svc->pkt_tag[i] = p_vsi_svc->pkt_tag[i+1];
    }
    memset(&p_vsi_svc->pkt_tag[i], 0, sizeof (bal_sw_lif_pkt_tag));
    
    (p_vsi_svc->num_tag)--;  
    return BCM_ERR_OK;    
}

#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */
/*@}*/

 
