/******************************************************************************
 *
 *  <: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_switch_group.c
 * @brief BAL Switch util functions that handle group requests
 * @addtogroup sw_util
 */
 
 /*@{*/
#include <bal_common.h>
#include <bcm_dev_log.h>
#include <bal_msg.h>
#include "bcmos_errno.h"
#include "bal_switch_util.h"  /* include bal_util.msg.h for bal_util_oper_group */
#include "group_fsm.h"        /* for struct group_inst */


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

#ifdef TEST_SW_UTIL_LOOPBACK
/* nothing to check in loop back mode */
bcmos_errno sw_util_group_info_validate(void *p_msg)
{
    return BCM_ERR_OK;    
}

#else
/**
 * @brief The group check function validate the group parameters from the core
 * 
 * @param p_msg    A pointer to the group object to validate
 * @return error code
 */
bcmos_errno sw_util_group_info_validate(void *p_msg)
{
    bcmbal_group_cfg *p_grp = (bcmbal_group_cfg *)p_msg;
    int i, num_of_pon;

    if (p_grp == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util,
                           " No group specified during validation\n" ); 
        return BCM_ERR_PARM;                           
    }
    
    /* if members field is set, make sure the PON interfaces are valid */
    if (BCMBAL_CFG_PROP_IS_SET(p_grp, group, members))
    {
        num_of_pon = bal_bcm_pon_inf_map_size_get();
        for(i=0; i<p_grp->data.members.len; i++)
        {
            bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
              
            if (p_member->intf_id >= num_of_pon)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                               " invalid group member with pon id = %d\n", p_member->intf_id ); 
                return BCM_ERR_PARM;
            }
        }
    }

    /* member action is not supported yet */ 
    return BCM_ERR_OK;    
}

/**
 * @brief The group remove function program switch to release resource that have
 * been allocated during the group add operation.
 *
 * @param p_group_inst A pointer to the group instance being referenced
 * @return error code
 */
static bcmos_errno bal_sw_util_group_remove(group_inst *p_group_inst)
{
    bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
    bcmos_errno ret = BCM_ERR_OK;
    int unit;
    uint32_t dev_type;
    
    BCM_LOG(INFO, log_id_sw_util,
            " Got a group remove request - group_id=%d \n", p_group->key.group_id);
    
    /* remove must have at least one member */
    if(p_group->data.members.len == 0)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group remove request must have at least one member\n");
        return BCM_ERR_PARM; 
    }
    
    unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
    dev_type = bal_bcm_dev_type_get(unit);
    
    /* call the group add function based on device type */
     if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
     {
         ret = bal_sw_util_dpp_group_rem(unit, p_group);  
     }
     else
     {
         BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group remove: 0x%x\n", dev_type );
         ret = BCM_ERR_INTERNAL;
     }
     
     BCM_LOG(INFO, log_id_sw_util, " Return group remove request with %d on device 0x%x\n", ret, dev_type );  
          
     return ret;
}
/**
 * @brief The group add function program switch to add a member interface to the group
 *
 * @param p_group_inst A pointer to the group instance being referenced
 * @return error code
 */
static bcmos_errno bal_sw_util_group_add(group_inst *p_group_inst)
{
    bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
    bcmos_errno ret = BCM_ERR_OK;
    int unit;
    uint32_t dev_type;
    
    BCM_LOG(INFO, log_id_sw_util,
            " Got a group add request - group_id=%d \n", p_group->key.group_id);
    
    /* add must have at least one member */
    if(p_group->data.members.len == 0)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group add request must have at least one member\n");
        return BCM_ERR_PARM; 
    }
    
    unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
    dev_type = bal_bcm_dev_type_get(unit);
    
    /* call the group add function based on device type */
     if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
     {
         ret = bal_sw_util_dpp_group_add(unit, p_group);  
     }
     else
     {
         BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group add: 0x%x\n", dev_type );
         ret = BCM_ERR_INTERNAL;
     }
     
     BCM_LOG(INFO, log_id_sw_util, " Return group add request with %d on device 0x%x\n", ret, dev_type );  
          
     return ret;
}

/**
 * @brief The group set function program switch to replace member interfaces of a group
 *
 * @param p_group_inst A pointer to the group instance being referenced
 * @return error code
 */
static bcmos_errno bal_sw_util_group_set(group_inst *p_group_inst)
{
    bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
    bcmos_errno ret = BCM_ERR_OK;
    int unit;
    uint32_t dev_type;
    
    BCM_LOG(INFO, log_id_sw_util,
            " Got a group set request - group_id=%d \n", p_group->key.group_id);
    
    if(p_group->data.members.len == 0)
    {
        unit = bal_bcm_dft_dev_get();
    }
    else
    {
        unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
    }
    dev_type = bal_bcm_dev_type_get(unit);
    
    /* call the group set function based on device type */
     if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
     {
         ret = bal_sw_util_dpp_group_set(unit, p_group);  
     }
     else
     {
         BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group set: 0x%x\n", dev_type );
         ret = BCM_ERR_INTERNAL;
     }
     
     BCM_LOG(INFO, log_id_sw_util, " Return group set request with %d on device 0x%x\n", ret, dev_type );  
          
     return ret;
}
/**
 * @brief The group create function program switch to create an empty group
 *
 * @param p_group_inst A pointer to the group instance being referenced
 * @return error code
 */
static bcmos_errno bal_sw_util_group_create(group_inst *p_group_inst)
{
    bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
    bcmos_errno ret = BCM_ERR_OK;
    int unit;
    uint32_t dev_type;
    
    BCM_LOG(INFO, log_id_sw_util,
            " Got a group create request - group_id=%d \n", p_group->key.group_id);
    

    /* For now, only one switch device for a system. If multiple devices support is required,
       need to loop through all devices to create the group */    
    unit = bal_bcm_dft_dev_get();
    dev_type = bal_bcm_dev_type_get(unit);
    
    /* call the group create function based on device type */
     if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
     {
         if( NULL == bal_sw_util_dpp_group_create(unit, p_group))
         {
             BCM_LOG(ERROR, log_id_sw_util, " switch group create failed\n");
             ret = BCM_ERR_INTERNAL;             
         }             
     }
     else
     {
         BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group create: 0x%x\n", dev_type );
         ret = BCM_ERR_INTERNAL;
     }
     
     BCM_LOG(INFO, log_id_sw_util, " Return group create request with %d on device 0x%x\n", ret, dev_type );  
          
     return ret;
}
/**
 * @brief The group destroy function program switch to release all resource used in a group
 *
 * @param p_group_inst A pointer to the group instance being referenced
 * @return error code
 */
static bcmos_errno bal_sw_util_group_destroy(group_inst *p_group_inst)
{
    bcmbal_group_cfg *p_group = &p_group_inst->current_group_info;
    bcmos_errno ret = BCM_ERR_OK;
    int unit;
    uint32_t dev_type;
    
    BCM_LOG(INFO, log_id_sw_util,
            " Got a group destroy request - group_id=%d \n", p_group->key.group_id);
    

    /* For now, only one switch device for a system. If multiple devices support is required,
       need to loop through all devices to create the group */    
    unit = bal_bcm_dft_dev_get();
    dev_type = bal_bcm_dev_type_get(unit);
    
    /* call the group destroy function based on device type */
     if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
     {
         ret = bal_sw_util_dpp_group_destroy(unit, p_group);  
     }
     else
     {
         BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group destroy: 0x%x\n", dev_type );
         ret = BCM_ERR_INTERNAL;
     }
     
     BCM_LOG(INFO, log_id_sw_util, " Return group destroy request with %d on device 0x%x\n", ret, dev_type );  
          
     return ret;
}

static uint32_t g_group_inited = 0;

#endif
/**
 * @brief SWITCH module: group SET handler
 *
 * This routine is called by group_fsm in the BAL core upon
 * SET request for group object.
 *
 * @param p_group_inst      Pointer to group instance
 * @param opt_type          Operation type on group instance
 *
 * @return bcmos_errno
 */
bcmos_errno sw_util_group_set(group_inst *p_group_inst, bal_util_oper_group opt_type)
{
    bcmos_errno ret = BCM_ERR_OK;   
   
#ifndef TEST_SW_UTIL_LOOPBACK  
    bal_sw_util_vsi_list_init(); 
    if (g_group_inited == 0)
    {
        /* initialized the internal group link list */
        bal_sw_util_dpp_group_list_init();
 
        g_group_inited = 1;
    }
    
    if(p_group_inst == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, "group set request with NULL pointer to the group instance\n");
        return BCM_ERR_PARM;        
    }
    
    if (opt_type == BAL_UTIL_OPER_GROUP_CREATE)
    {
        ret = bal_sw_util_group_create(p_group_inst);
    }
    else if (opt_type == BAL_UTIL_OPER_GROUP_ADD)
    {
        ret = bal_sw_util_group_add(p_group_inst);
    }
    else if( BAL_UTIL_OPER_GROUP_REMOVE == opt_type )
    { 
        ret = bal_sw_util_group_remove(p_group_inst);
    }
    else if( BAL_UTIL_OPER_GROUP_SET == opt_type )
    { 
        ret = bal_sw_util_group_set(p_group_inst);
    }
    else if( BAL_UTIL_OPER_GROUP_DESTROY == opt_type )
    { 
        ret = bal_sw_util_group_destroy(p_group_inst);
    }
    else
    {
        BCM_LOG(ERROR, log_id_sw_util, "Only CREATE/ADD/REMOVE/SET/DESTROY request is supported for GROUP object\n");
        return BCM_ERR_NOT_SUPPORTED;        
    }
#else
    BCM_LOG(INFO, log_id_sw_util, "dummy group %s SUCCESS\n", 
            BCMBAL_UTIL_GROUP_OPER_STR_GET(opt_type));
#endif

    return ret;
}

/**
 * @brief SWITCH module: group clean up function
 *
 * This routine is called from the bal_switch_util() when Core calls the finish function.
 *
 * @return bcmos_errno
 */
bcmos_errno sw_util_group_finish()
{
    bcmos_errno ret = BCM_ERR_OK;   
   
#ifndef TEST_SW_UTIL_LOOPBACK  
    if (g_group_inited)
    {
        /* release the internal group link list */
        bal_sw_util_dpp_group_list_finish();
 
        g_group_inited = 0;
    }
#endif	
	return ret;
}
/*@}*/

 
