/******************************************************************************
 *
 *  <: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_group.c
 * @brief BAL Switch util helper functions that handle group 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/multicast.h>

#include "bal_dpp_group.h"
#include "bal_switch_acc_term.h"
#include "bal_dpp_vswitch.h"



/* A local link list to keep track of group list */
TAILQ_HEAD(bal_sw_group_list_head, bal_sw_group_list) g_swutil_group_list;

/**
 * @brief The group list init function prepare a link list to keep track of 
 *        multicast group in the switch util
 *
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_group_list_init(void)
{
    TAILQ_INIT(&g_swutil_group_list);
    return BCM_ERR_OK;
}

/**
 * @brief The group list finish function release all resources allocated in the list
 *
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_group_list_finish(void)
{
	bal_sw_group_list *current_entry, *p_temp_entry;

    /* Free all the entries in the list */
    TAILQ_FOREACH_SAFE(current_entry,
                       &g_swutil_group_list,
                       next_grp,
                       p_temp_entry)
    {
        /* Remove it from the list */
        TAILQ_REMOVE(&g_swutil_group_list, current_entry, next_grp);

        bcmos_free(current_entry);
    }

    return BCM_ERR_OK;
}

/**
 * @brief The group list search function by BAL group id
 *
 * @param grp_id the group id that need to match the entry in the list
 * @return pointer to an element in the list, NULL if search failed
 */
bal_sw_group_list *bal_sw_util_dpp_group_list_get_by_id(uint32_t grp_id)
{
    bal_sw_group_list *p_entry, *p_temp;
    
    TAILQ_FOREACH_SAFE(p_entry, &g_swutil_group_list, next_grp, p_temp)
    {       
        if( p_entry->bal_grp_id == grp_id)
        {
            break;
        }
    }
    /* if reach the end of the list, TAILQ_FOREACH_SAFE set the p_entry to NULL */
    return p_entry;
   
}

/*
 * @brief The group list insert function
 *
 * @param entry  the group element to be added in the link list
 * @return pointer to the newly inserted group in the list, NULL if operation failed 
*/
static bal_sw_group_list *bal_sw_util_group_list_insert(bal_sw_group_list entry)
{
    bal_sw_group_list *p_new_entry;

    p_new_entry = bcmos_calloc(sizeof(bal_sw_group_list));
    if(NULL == p_new_entry)
    {
        BCM_LOG(ERROR, log_id_sw_util, "GROUP list insert out of memory\n");
        return NULL;
    }
    *p_new_entry = entry;
    TAILQ_INSERT_TAIL(&g_swutil_group_list, p_new_entry, next_grp);
    return p_new_entry;
}

/*
 * @brief The group list remove function
 *
 * @param p_entry Pointer to the group element in the link list result from the search functions
 * @return error code
*/
static bcmos_errno bal_sw_util_group_list_remove(bal_sw_group_list *p_entry)
{
    TAILQ_REMOVE(&g_swutil_group_list, p_entry, next_grp);
    bcmos_free(p_entry);
    return BCM_ERR_OK;
}

/**
 * @brief The group list membership check function by port
 *        Validate if interface/svervice_port is already a member 
 *
 * @param p_grp_port the interface that need to be matched in the list
 * @param p_entry pointer to an entry in the group list
 * @return index to the port member, -1 if not found
 */
static int bal_sw_util_dpp_group_list_membership_check(bal_sw_group_list *p_entry, bal_sw_group_port *p_grp_port)
{
    int i;
    
    if(p_entry == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group membership check with NULL parameter\n");
        return BCMOS_FALSE;
    }
    
    for(i=0; i<p_entry->num_port; i++)
    {
        if(p_entry->port[i].port == p_grp_port->port &&
           p_entry->port[i].svc_port == p_grp_port->svc_port)
        {
            p_grp_port->gport = p_entry->port[i].gport;
            return i;
        }
    }
    return -1;
}

/**
 * @brief The group list membership remove function by port
 *        remove interface/svervice_port from the group membership 
 *
 * @param grp_port the interface that need to be matched in the list
 * @param p_entry pointer to an entry in the group list
 * @return boolen TRUE or FALSE
 */
static bcmos_bool bal_sw_util_dpp_group_list_membership_rem(bal_sw_group_list *p_entry, bal_sw_group_port grp_port)
{
    int i, rv;
    
    if(p_entry == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group membership remove with NULL parameter\n");
        return BCMOS_FALSE;
    }
    
    for(i=0; i<p_entry->num_port; i++)
    {
        if(p_entry->port[i].port == grp_port.port &&
           p_entry->port[i].svc_port == grp_port.svc_port)
        {
            /* destroy the vlan port (i.e., PON LIF) */
            if(p_entry->port[i].gport)
            {
                rv = bcm_vlan_port_destroy(p_entry->device, p_entry->port[i].gport);
                if (rv != BCM_E_NONE)
                {
                    BCM_LOG(WARNING, log_id_sw_util, "Warning, GROUP:bcm_vlan_port_destroy pon %d failed %d\n", p_entry->port[i].gport, rv);  
                    /* Likely a bug in the 6.5.4 release, ignore for now                
                    return BCMOS_FALSE;  
                     */
                }
                p_entry->port[i].gport = 0;
            }
            break;
        }
    }
    
    /* if can't find the port, just return OK */
    if(i != p_entry->num_port)
    {
        /* pack the list */
        bal_sw_group_port null_port={0};       
        for(; i<p_entry->num_port-1; i++)
        {
            p_entry->port[i] = p_entry->port[i+1];
        }
        p_entry->port[i] = null_port;
        p_entry->num_port--;
    }
       
    return BCMOS_TRUE;
}


/**
 * @brief The group create function create a multicast group that contains egress LIF. 
 *        This group can later connects to virtual switch in multiple FLOWs.  
 *        
 *        The pointer of the created group will be returned
 *  
 * @param unit       switch device id 
 * @param p_grp      a pointer to the multicast group definition
 * 
 * @return pointer to the group list entry, NULL if operation failed
 */

bal_sw_group_list *bal_sw_util_dpp_group_create(int unit, bcmbal_group_cfg *p_grp)
{
    bal_sw_group_list *p_grp_list, grp_list_elm;
    int32_t multicast_id;
    uint32_t svc_indx;
    int rv, flags;
    bal_sw_vsi_service *p_vsi_service;
    
    if(p_grp == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group create with NULL parameter\n");
        return NULL;
    }
    /* check group list */
    p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
    if(p_grp_list)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group create with group id %d already existed\n", p_grp->key.group_id);
        return NULL;
    }
    /* alloc an entry in the group list*/
    memset(&grp_list_elm, 0, sizeof(bal_sw_group_list));
    grp_list_elm.device = unit;
    grp_list_elm.bal_grp_id = p_grp->key.group_id;
    p_grp_list = bal_sw_util_group_list_insert(grp_list_elm);
    if(p_grp_list == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group create failed insert to group list\n");
        return NULL;
    }

    /* create a vswitch with empty service, we need vsi to create the MC flooding group for egress */
    p_vsi_service = bal_sw_util_dpp_vsi_service_create(unit, NULL, &svc_indx);
    if(NULL == p_vsi_service)
    {
        BCM_LOG(ERROR, log_id_sw_util, "create vsi service for group failed \n");
        bal_sw_util_group_list_remove(p_grp_list);
        return NULL;        
    }
    
    p_grp_list->p_vsi = p_vsi_service;
    
    multicast_id = p_vsi_service->vswitch + BAL_DPP_MC_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, "MC: bcm_multicast_destroy 0x%x failed %d \n", multicast_id, rv);
            bal_sw_util_group_list_remove(p_grp_list);
            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, "MC: in bcm_multicast_create 0x%x w ingress failed %d \n", multicast_id, rv);
       bal_sw_util_group_list_remove(p_grp_list);
       
       return NULL;           
    }
    else
    {
        BCM_LOG(INFO, log_id_sw_util, "MC: vswitch flood group 0x%x created\n", multicast_id);
    }
    
    /* update the group list info */
    p_grp_list->l2_grp_id = multicast_id;
    return p_grp_list;
}

/**
 * @brief The group add function add members to the multicast group.
 *        In this function, gourp members are PON interfaces  
 *       
 * @param unit       switch device id 
 * @param p_grp      a pointer to the multicast group definition
 * 
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_group_add(int unit, bcmbal_group_cfg *p_grp)
{
    bal_sw_group_list *p_grp_list;
    int i, pon, rv, indx; 
    bcm_gport_t pon_gport;
    bcmos_errno ret;
    int pon_encap_id;
    bcm_vlan_port_t vp;
    uint32_t flood_grp;
    
    if(p_grp == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group add with NULL parameter\n");
        return BCM_ERR_PARM;
    }
    /* check if L2 group has been created */
    p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
    if(!p_grp_list)
    {
        BCM_LOG(INFO, log_id_sw_util, "group add will alloc a L2 MC group, group id %d \n", p_grp->key.group_id);
        p_grp_list = bal_sw_util_dpp_group_create(unit, p_grp);
        if(p_grp_list == NULL)
        {
            BCM_LOG(ERROR, log_id_sw_util, "group add failed create L2 Mc group\n");
            return BCM_ERR_NORES;
        }
    } 

    
    ret = BCM_ERR_OK;
       
    for(i=0; i<p_grp->data.members.len; i++)
    {
        bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
        bal_sw_group_port port_member;
        
        /* find the L2 logical interface number */
        pon = bal_bcm_pon_inf_pbm_get(p_member->intf_id);
        
        /* check if interface is already a member in the group list */
        port_member.port     = pon;
        port_member.svc_port = p_member->svc_port_id;
        if( -1 != bal_sw_util_dpp_group_list_membership_check(p_grp_list, &port_member))
        {
           BCM_LOG(INFO, log_id_sw_util, "pon interface %d with service port %d already a member\n",p_member->intf_id, p_member->svc_port_id);
           continue;
        }
       
        /* check if interface already has an entry in the group list */
        port_member.port     = pon;
        port_member.svc_port = 0;
        indx = bal_sw_util_dpp_group_list_membership_check(p_grp_list, &port_member);
        if( -1 == indx)
        {
            /* make sure there is still room in the group list for new member */
            if(p_grp_list->num_port >= MAX_PON_PORT)
            {
               BCM_LOG(ERROR, log_id_sw_util,
                        "Error, GROUP: Reach maximum number of membership in the group list\n");                  
                ret = BCM_ERR_NORES;
                break;           
            }
        }
        /* if group has a owner, create a LIF for each member */  
        if(p_grp->data.owner != BCMBAL_GROUP_OWNER_NONE)
        {       
           /* Map the tunnel ID to a PON channel OTM port */
            rv = bcm_port_pon_tunnel_map_set(unit,
                                             pon,
                                             p_member->svc_port_id,
                                             pon);
            if (rv != BCM_E_NONE)
            { 
                BCM_LOG(ERROR, log_id_sw_util,
                        "Error, GROUP:bcm_port_pon_tunnel_map_set on pon %d failed %d"
                        " (have you chosen the correct intf_maptable?)\n", pon, rv);
                ret = BCM_ERR_INTERNAL;
                break;
            }
            
            /* Create the pon LIF to be DS only  */
            bcm_vlan_port_t_init(&vp);
            
            /* preserve any incoming packet vlan tags, if vlan actions are required, do it using egress translation */
            vp.flags =  BCM_VLAN_PORT_OUTER_VLAN_PRESERVE  | BCM_VLAN_PORT_INNER_VLAN_PRESERVE;        
            /* It is required to set the FEC flag so that the egress redirection action from the DS classification can 
               select the correct PON LIF to forward the packet */
            vp.flags |= BCM_VLAN_PORT_FORWARD_GROUP; 
            
            vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL;
      
            vp.port = pon;        
            vp.match_tunnel_value = p_member->svc_port_id;
            vp.egress_tunnel_value = p_member->svc_port_id;
      
            vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
           
            /* Create the vlan port (i.e., PON LIF) */
            rv = bcm_vlan_port_create(unit, &vp);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_port_create pon %d failed %d\n", pon, rv);         
                ret = BCM_ERR_INTERNAL;
                break;  
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Info, GROUP:bcm_vlan_port_create pon %d with tunnel %d success\n", pon, p_member->svc_port_id); 
            }
     
            pon_gport = vp.vlan_port_id;
            rv = bcm_port_discard_set(unit, pon_gport, BCM_PORT_DISCARD_INGRESS);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_port_discard_set on pon %d failed %d\n", pon, rv);         
                ret = BCM_ERR_INTERNAL;
                break;  
            }
            /* select the flooding group */
            if(p_grp->data.owner == BCMBAL_GROUP_OWNER_MULTICAST)
            {
                flood_grp = p_grp_list->l2_grp_id;
            }
            else
            {
                flood_grp = (p_grp_list->p_vsi)->ds_flood_grp_id;
            }
            /* join the L2 multicast group */
            rv = bcm_multicast_vlan_encap_get(unit, flood_grp, pon, pon_gport, &pon_encap_id);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_encap_get on pon %d failed %d\n", pon, rv);         
                ret = BCM_ERR_INTERNAL;      
                break;
            }
            rv = bcm_multicast_ingress_add(unit, flood_grp, pon, pon_encap_id);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_multicast_ingress_add on pon %d failed %d\n", pon, rv);         
                ret = BCM_ERR_INTERNAL;          
                break;
            }
            
            BCM_LOG(INFO, log_id_sw_util, "Info, GROUP:pon %d join l2 mc group 0x%x success\n", pon, flood_grp); 
            /* update the group list membership */
            port_member.gport = pon_gport;
        }
        else
        {
            port_member.gport = 0;
        }
        p_grp_list->port[p_grp_list->num_port] = port_member;
        p_grp_list->num_port++;
        
    }
    
   
    return ret;     
}


/**
 * @brief The group remove function remove members from the multicast group.
 *        In this function, group members are PON interfaces  
 *       
 * @param unit       switch device id 
 * @param p_grp      a pointer to the multicast group definition
 * 
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_group_rem(int unit, bcmbal_group_cfg *p_grp)
{
    bal_sw_group_list *p_grp_list;
    int i, pon, rv; 
    bcmos_errno ret;
    int pon_encap_id;
    
    if(p_grp == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group remove with NULL parameter\n");
        return BCM_ERR_PARM;
    }
    /* check if L2 group has been created */
    p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
    if(!p_grp_list)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group remove can not find L2 Mc group %d\n", p_grp->key.group_id);
        return BCM_ERR_INTERNAL;
    } 

    /* remove LIF for each member */  
    ret = BCM_ERR_OK;
    for(i=0; i<p_grp->data.members.len; i++)
    {
        bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
        bal_sw_group_port port_member;
        
        /* find the L2 logical interface number */
        pon = bal_bcm_pon_inf_pbm_get(p_member->intf_id);
        
        /* check if interface is already removed from the group list */
        port_member.port     = pon;
        port_member.svc_port = p_member->svc_port_id;
        if( -1 == bal_sw_util_dpp_group_list_membership_check(p_grp_list, &port_member))
        {
            BCM_LOG(INFO, log_id_sw_util, "pon interface %d with service port %d is not a member\n",p_member->intf_id, p_member->svc_port_id);
            continue;
        }
        
        /* if the member has a LIF assigned, remove it from the switch multicast group */
        if(port_member.gport)
        {
            /* leave the L2 multicast group */        
             rv = bcm_multicast_vlan_encap_get(unit, p_grp_list->l2_grp_id, pon, port_member.gport, &pon_encap_id);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_encap_get on pon %d failed %d\n", pon, rv);         
                ret = BCM_ERR_INTERNAL;      
                break;
            }
            rv = bcm_multicast_ingress_delete(unit, p_grp_list->l2_grp_id, pon, pon_encap_id);
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_multicast_ingress_delete on pon %d failed %d\n", pon, rv);         
                ret = BCM_ERR_INTERNAL;          
                break;
            }
        }
        if( BCMOS_FALSE == bal_sw_util_dpp_group_list_membership_rem(p_grp_list, port_member))
        {
            BCM_LOG(INFO, log_id_sw_util, "pon interface %d with service port %d membership remove failed\n",p_member->intf_id, p_member->svc_port_id);
            ret = BCM_ERR_INTERNAL;
            break;  
        }  
    }
  
    return ret;     
}

/**
 * @brief The group set function replace members from the multicast group.
 *        In this function, group members are PON interfaces  
 *       
 * @param unit       switch device id 
 * @param p_grp      a pointer to the multicast group definition
 * 
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_group_set(int unit, bcmbal_group_cfg *p_grp)
{
    bal_sw_group_list *p_grp_list;
    bcmos_errno ret = BCM_ERR_OK;
    int pon_encap_id;
    
    if(p_grp == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group replace with NULL parameter\n");
        return BCM_ERR_PARM;
    }
    /* check if L2 group has been created */
    p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
    if(!p_grp_list)
    {
        /* mark it OK to create group at the end */
        ret = BCM_ERR_OK;
    } 
    else if(p_grp_list->num_port)
    {
        /* remove all members from the group */
        do
        {
            if( p_grp_list->port[0].gport)
            {
                        /* leave the L2 multicast group */        
                if (BCM_E_NONE != bcm_multicast_vlan_encap_get(unit, p_grp_list->l2_grp_id, p_grp_list->port[0].port, p_grp_list->port[0].gport, &pon_encap_id))
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_vlan_encap_get on pon %d failed\n", p_grp_list->port[0].port);         
                    ret = BCM_ERR_INTERNAL;      
                    break;
                }
                if (BCM_E_NONE != bcm_multicast_ingress_delete(unit, p_grp_list->l2_grp_id, p_grp_list->port[0].port, pon_encap_id))
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, GROUP:bcm_multicast_ingress_delete on pon %d failed\n", p_grp_list->port[0].port);         
                    ret = BCM_ERR_INTERNAL;          
                    break;
                }
            }
            if( BCMOS_FALSE == bal_sw_util_dpp_group_list_membership_rem(p_grp_list, p_grp_list->port[0]))
            {          
                BCM_LOG(ERROR, log_id_sw_util, "group set fail to remove existing member interface %d\n",p_grp_list->port[0].port );
                ret = BCM_ERR_INTERNAL;
                break;                
            }      
        }while(p_grp_list->num_port);
    }
  
    if(ret == BCM_ERR_OK)
    {
        /* create/add the group */
        return bal_sw_util_dpp_group_add(unit, p_grp);
    }
    return ret;     
}

/**
 * @brief The group destroy function free up a multicast group.
 *        The group will be removed from the group list. 
 *        All L2 resources accociated with the group will be free.         
 *  
 * @param unit       switch device id 
 * @param p_grp      a pointer to the multicast group definition
 * 
 * @return error code
 */

bcmos_errno bal_sw_util_dpp_group_destroy(int unit, bcmbal_group_cfg *p_grp)
{
    bal_sw_group_list *p_grp_list;
    int rv;
    bcmos_errno ret;
    
    if(p_grp == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group destroy with NULL parameter\n");
        return BCM_ERR_PARM;
    }
    /* check group list */
    p_grp_list = bal_sw_util_dpp_group_list_get_by_id(p_grp->key.group_id);
    if(!p_grp_list)
    {
        BCM_LOG(INFO, log_id_sw_util, "group destroy with group id %d does not existed\n", p_grp->key.group_id);
        return BCM_ERR_OK;
    }
    /* can't destroy if any flow is still reference it */
    if(p_grp_list->use_count)
    {
        BCM_LOG(WARNING, log_id_sw_util, "group destroy with group id %d is busy\n", p_grp->key.group_id);
        return BCM_ERR_INVALID_OP;
    }
    
    /* Do our best to clean up */
    /* free resources used by all members */
    ret = bal_sw_util_dpp_group_rem(unit, p_grp);
    if (ret != BCM_ERR_OK)
    {
       BCM_LOG(ERROR, log_id_sw_util, "MC:  destroy group 0x%x failed to free members \n", p_grp_list->l2_grp_id);
    }
    
    /* free the L2 multicast group */
    rv = bcm_multicast_destroy(unit, p_grp_list->l2_grp_id);
    if (rv != BCM_E_NONE)
    {
       BCM_LOG(ERROR, log_id_sw_util, "MC: in bcm_multicast_destroy 0x%x failed %d \n", p_grp_list->l2_grp_id, rv);
    }
    
    /* clean up the vsi */
    bal_sw_util_dpp_vsi_service_destroy(unit, p_grp_list->p_vsi);
    /* remove from the list */
    bal_sw_util_group_list_remove(p_grp_list);
  
    return BCM_ERR_OK;
}

#endif /* LOOPBACK */
/*@}*/
