/******************************************************************************
 *
 *  <: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_mac_util_gpon.c
 *
 * @brief mac util interfaces definition used by Bal Core, for GPON
 *
 * This file expose the APIs to the core to configure the mac 
 * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
 *
 * @addtogroup mac_util
 */

/*@{*/

#include <bal_mac_util.h>
#include <bal_mac_util_common_itu_pon.h>

static bcmos_errno mac_util_indication_handle_for_gpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);
static bcmos_errno mac_util_indication_handle_for_gpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg);
static bcmos_errno mac_util_indication_handle_for_gpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg);
static bcmos_errno mac_util_indication_handle_for_gpon_gem_port (bcmolt_devid device_id, bcmolt_msg *p_msg);

/** @brief array stores the list of GPON related auto indications from Maple to subscribe */
static mac_util_ind_obj_and_handlers mac_util_gpon_ind_handlers[] =
{
    {BCMOLT_OBJ_ID_GPON_NI,         "BCMOLT_OBJ_ID_GPON_NI",       mac_util_indication_handle_for_gpon_ni},
    {BCMOLT_OBJ_ID_GPON_ONU,        "BCMOLT_OBJ_ID_GPON_ONU",      mac_util_indication_handle_for_gpon_onu},
    {BCMOLT_OBJ_ID_GPON_ALLOC,      "BCMOLT_OBJ_ID_GPON_ALLOC",    mac_util_indication_handle_for_gpon_alloc_id},
    {BCMOLT_OBJ_ID_GPON_GEM_PORT,   "BCMOLT_OBJ_ID_GPON_GEM_PORT", mac_util_indication_handle_for_gpon_gem_port}
};


/**
 * @brief Map bal GPON transceiver type to bcm68620 transceiver type
 */
static bcmolt_trx_type mac_gpon_bal_trx_type2bcm68620_trx_type(bcmbal_trx_type bal_trx_type, bcmbal_intf_id intf_id)
{
    bcmolt_trx_type trx_type = BCMOLT_TRX_TYPE__NUM_OF;

    switch (bal_trx_type)
    {
    case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
        trx_type = BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013;
        break;
    case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
        trx_type = BCMOLT_TRX_TYPE_SOG_4321_PSGB;
        break;
    case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
        trx_type = BCMOLT_TRX_TYPE_LTE_3680_M;
        break;
    case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
        trx_type = BCMOLT_TRX_TYPE_SOURCE_PHOTONICS;
        break;
    case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
        trx_type = BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS;
        break;
    default:
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_id), "Invalid trx_type %d\n", bal_trx_type);
    }
    return trx_type;
}




/**
 * @brief all the maple indication handlers for gpon
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 */ 
bcmos_errno mac_util_handle_all_olt_ind_for_gpon (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    BCM_LOG(DEBUG, log_id_mac_util,
        "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
        p_msg->obj_type, mac_util_indication_get_obj_type_str(p_msg->obj_type, mac_util_gpon_ind_handlers,  BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers)),
        p_msg->group, p_msg->subgroup);

    return mac_util_handle_indication(device_id, p_msg, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers));
}

/**
 * @brief Handler function for Maple auto indications for GPON NI
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 * @return bcmos_errno
 */
static bcmos_errno mac_util_indication_handle_for_gpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
	uint32_t logical_pon;

    do
   	{

        /* PON activation */
        if (BCMOLT_GPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
        {
            bcmolt_gpon_ni_state_change_completed * p_ind = (bcmolt_gpon_ni_state_change_completed*)p_msg;
    
		    rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
			    break;
		    }
    		
            BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), "Pon if %d is %s.\n", logical_pon,
                BCMOLT_PON_STATE_ACTIVE_WORKING == p_ind->data.new_state ? "up" : "down");
    
            /* if we got something from MAC HW, then it has to be PON interface */
            mac_util_report_if_event(logical_pon, BCMBAL_INTF_TYPE_PON, p_msg->err,
                p_ind->data.result, p_ind->data.new_state);

        }
        else if(BCMOLT_GPON_NI_AUTO_CFG_ID_ONU_DISCOVERED == p_msg->subgroup)
        {
            bcmolt_gpon_ni_onu_discovered *p_ind =
                (bcmolt_gpon_ni_onu_discovered *)p_msg;
    
		    rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
			    break;
		    }
    		
            BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "Pon if %d (ONUID:%d) found ONU serial number "
                    "%c%c%c%c%d%d%d%d%d%d%d%d\n",
                    logical_pon,
                    p_ind->data.onu_id,
                    p_ind->data.serial_number.vendor_id[0],
                    p_ind->data.serial_number.vendor_id[1],
                    p_ind->data.serial_number.vendor_id[2],
                    p_ind->data.serial_number.vendor_id[3],
                    p_ind->data.serial_number.vendor_specific[0]>>4 & 0x0f,
                    p_ind->data.serial_number.vendor_specific[0] & 0x0f,
                    p_ind->data.serial_number.vendor_specific[1]>>4 & 0x0f,
                    p_ind->data.serial_number.vendor_specific[1] & 0x0f,
                    p_ind->data.serial_number.vendor_specific[2]>>4 & 0x0f,
                    p_ind->data.serial_number.vendor_specific[2] & 0x0f,
                    p_ind->data.serial_number.vendor_specific[3]>>4 & 0x0f,
                    p_ind->data.serial_number.vendor_specific[3] & 0x0f
                    );
    
            bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
            mac_util_report_sub_term_event(logical_pon,
                                           p_ind->data.onu_id,
                                           &p_ind->data.serial_number,
                                           BAL_UTIL_OPER_SUB_TERM_DISCOVERY,
                                           p_msg->err, BCMOLT_RESULT_SUCCESS, 
                                           BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
        }
        else
        {
            /* just get the pon key by typecasting to a dummy structure */
            bcmolt_gpon_ni_key *p_pon_key = &(((bcmolt_gpon_ni_state_change_completed*)p_msg)->key);
    
		    rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
			    break;
		    }
    
            BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                "Unhandled message indication for obj Gpon_NI group %d "
                "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
        }
       	
   	}
	while(0);
    return rc;
}



/**
 * @brief Handler function for Maple auto indications for GPON ONU
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 * @return bcmos_errno
 */
static bcmos_errno mac_util_indication_handle_for_gpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
	uint32_t logical_pon;

	/* just get the pon key by typecasting to a dummy structure */
	bcmolt_gpon_onu_key *p_gpon_onu_key = &(((bcmolt_gpon_onu_onu_activation_completed*)p_msg)->key);

    do
    {		
        if (BCMOLT_GPON_ONU_AUTO_CFG_ID_ONU_ACTIVATION_COMPLETED == p_msg->subgroup)
	    {
		    bcmolt_gpon_onu_onu_activation_completed *p_ind = (bcmolt_gpon_onu_onu_activation_completed*) p_msg;
    	
		    rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
			    break;
		    }
    	
		    BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_ind->key.pon_ni),
				    "sub_term %d (PON%d) activation indication (%s)\n",
    				p_ind->key.onu_id,
				    p_ind->key.pon_ni,
				     bcmos_strerror(p_msg->err));
    
            mac_util_report_sub_term_event(logical_pon,
                p_ind->key.onu_id,
                (bcmolt_serial_number *)NULL,
                BAL_UTIL_OPER_SUB_TERM_ADD,
                p_msg->err, p_ind->data.status,
                p_ind->data.fail_reason, BCMBAL_INVALID_TUNNEL_ID);

	    }
    	else if(BCMOLT_GPON_ONU_AUTO_CFG_ID_ONU_DEACTIVATION_COMPLETED == p_msg->subgroup)
	    {
		    bcmolt_gpon_onu_onu_deactivation_completed *p_ind = (bcmolt_gpon_onu_onu_deactivation_completed*) p_msg;
    	
		    rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
			    break;
		    }
    	
		    BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
				    "sub_term %d (PON%d) deactivation indication (%s)\n",
    				p_ind->key.onu_id,
				    logical_pon,
    				bcmos_strerror(p_msg->err));
            mac_util_report_sub_term_event(logical_pon,
                p_ind->key.onu_id,
                (bcmolt_serial_number *)NULL,
                BAL_UTIL_OPER_SUB_TERM_REMOVE,
                p_msg->err, p_ind->data.status,
                MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
	     }
	    else
    	{	    
		    rc = bcm_topo_pon_get_physical2logical(device_id, p_gpon_onu_key->pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_gpon_onu_key->pon_ni, bcmos_strerror(rc));
			    break;
		    }
    	
		    BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
				    "Unhandled message indication for obj GPON_ONU group %d "
    				"subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
			break;
	    }

		rc = mac_util_update_flows_w_sub_term_update(logical_pon, p_gpon_onu_key->onu_id, maple_gpon_mac_check_gem_port_id, maple_gpon_mac_get_alloc_id_config);
		if (BCM_ERR_OK != rc)
		{
			BCM_LOG(ERROR, log_id_mac_util,
					"Failed to update related flows pon_id = %d onu_id = %d (%s)\n", logical_pon, p_gpon_onu_key->onu_id, bcmos_strerror(rc));
			break;
		}
        
   	}
    while(0);
    return rc;
}


/**
 * @brief Handler function for Maple auto indications for GPON Alloc Id
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 * @return bcmos_errno
 */
static bcmos_errno mac_util_indication_handle_for_gpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
    uint32_t logical_pon;
    tm_sched_inst* p_tm_sched_inst = NULL;	
    do
    {		
        if (BCMOLT_GPON_ALLOC_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
        {
            bcmolt_gpon_alloc_configuration_completed *p_ind = (bcmolt_gpon_alloc_configuration_completed*) p_msg;
            
            rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
            if (BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, log_id_mac_util,
                            "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
                break;
            }
            
            /* Find tn_mode inst owned by that alloc_id and ni */
            p_tm_sched_inst =  tm_sched_find_agg_port_node(logical_pon, p_ind->key.alloc_id);
            if (NULL == p_tm_sched_inst )
            {
                BCM_LOG(ERROR, log_id_mac_util,
                            "Failed to find tm sched owned by that agg port (intf %d id %d)\n", logical_pon,p_ind->key.alloc_id);
                rc = BCM_ERR_NOENT;
                break;            
            }
            /*the tm owned by that alloc found, update it with the ind*/
            mac_util_report_tm_sched_set_indication(p_tm_sched_inst->req_tm_sched_info.key ,p_msg->err, p_ind->data.status);
        }
        else
        {
            /* just get the pon key by typecasting to a dummy structure */
            bcmolt_gpon_alloc_key *p_pon_key = &(((bcmolt_gpon_alloc_configuration_completed*)p_msg)->key);
            
            rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
            if (BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, log_id_mac_util,
                        "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
                break;
            }
            BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "Unhandled message indication for obj GPON_ALLOC group %d "
                    "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
        }
    }while (0);
    return rc;
}
	

/**
 * @brief Handler function for Maple auto indications for GPON GEM Port
 *
 * @param device_id the maple device id generating the current indication
 * @param p_msg pointer to the maple indication message
 *
 * @return bcmos_errno
 */
static bcmos_errno mac_util_indication_handle_for_gpon_gem_port (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
	uint32_t logical_pon;
    flow_list_entry *p_current_entry = NULL;
    void *p_rsc_mgr_curr_entry = NULL;
    void *p_rsc_mgr_next_entry = NULL;
	
    do
   	{

        if (BCMOLT_GPON_GEM_PORT_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
        {
            bcmolt_gpon_gem_port_configuration_completed *p_ind =
                (bcmolt_gpon_gem_port_configuration_completed *) p_msg;
    

		    rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
			    break;
		    }
    
            /* Find all entries in flows list matching the gem port id and pon ni */
            /* use safe walk here because an entry can be removed from list during the walk */
            /* get first */
            p_current_entry = _mac_util_db_flow_get_next_w_gem (logical_pon, p_ind->key.gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
            while (NULL != p_current_entry)
            {
                /** @note For now this assumes that there is only one op type (add or remove) ,
                 * that all the flows in an onu are waiting for. We can not have flows waiting on same
                 * gem for multiple op types, because Maple does not allow multiple configs with
                 * different op types at the same time.
                 */
                /* update gem port complete configuration indication received */
                p_current_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
                /* check if should send flow configuration indication complete to bal core */
                rc = check_send_flow_bal_ind_msg(p_current_entry, p_msg->err, p_ind->data.status);

                /* any DB cleanup for error should be triggered by Core fsm
                 * (mac util should not cleanup on its own)
                 * */
                if (BCM_ERR_OK != rc)
                {
                    BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                            "Failed to send flow configured ind: Error %s, gem port id = %d, pon ni = %d\n",
                            bcmos_strerror(rc), p_ind->key.gem_port_id, logical_pon);
                    /* don't break, but continue to check if more flows use the same gem port id */
                }
    
                /* get next */
                p_current_entry = _mac_util_db_flow_get_next_w_gem (logical_pon, p_ind->key.gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
            }
        }
        else
        {
            /* just get the pon key by typecasting to a dummy structure */
            bcmolt_gpon_gem_port_key *p_pon_key = &(((bcmolt_gpon_gem_port_configuration_completed*)p_msg)->key);

		    rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);				
    		if (BCM_ERR_OK != rc)
		    {
			    BCM_LOG(ERROR, log_id_mac_util,
					    "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
			    break;
		    }
    
            BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "Unhandled message indication for obj GPON_GEM_PORT group %d "
                    "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
        }
       	
   	}
    while(0);	
    return rc;
}

/**
 * @brief  Maple auto indication register for specific GPON based indications
 *
 * @param p_rx_cfg         handler config structure
 * @param  device_id                         specific device id (for multiple devices support)  
 *
 * @return bcmos_errno
 */
bcmos_errno mac_util_register_for_gpon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
{
    return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers), device_id);
}

/*****************************************************************************/
/**
 * @brief Map iwf_mode to bcmolt_iwf_mode
 *
 * @param bal_iwf_mode     BAL iwfmode
 * @return bcm68620 iwf mode
 */
static bcmolt_iwf_mode bal_iwf_mode2iwf_mode(bcmbal_iwf_mode bal_iwf_mode)
{
    bcmolt_iwf_mode iwf_mode = BCMOLT_IWF_MODE__NUM_OF;
    switch (bal_iwf_mode)
    {
    case BCMBAL_IWF_MODE_DIRECT_MAPPING:
        iwf_mode = BCMOLT_IWF_MODE_DIRECT_MAPPING_MODE;
        break;
    case BCMBAL_IWF_MODE_PER_FLOW:
        iwf_mode = BCMOLT_IWF_MODE_PER_FLOW_MODE;
        break;
    default:
        BCM_LOG(ERROR, log_id_mac_util, "Invalid iwf_mode %d\n", bal_iwf_mode);
    }
    return iwf_mode;
}

static bcmos_errno mac_util_access_terminal_set_for_gpon (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_system_mode system_mode, bcmolt_devid device_id)
{
    bcmolt_device_key key = {};
    bcmolt_device_nni_speed nni_speed_cfg;
    bcmolt_device_cfg dev_cfg;
    bcmolt_iwf_mode iwf_mode;
    uint32_t logical_pon;

    if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&(p_acc_term->api_req_acc_term_obj_info), access_terminal, iwf_mode))
    {
        iwf_mode = bal_iwf_mode2iwf_mode(p_acc_term->api_req_acc_term_obj_info.data.iwf_mode);
    }
    else
    {
        iwf_mode = BCMOLT_IWF_MODE_DIRECT_MAPPING_MODE;
    }

    BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
    {
        mac_util_topo_pon_context *topo_context, *old_topo_context;

        old_topo_context = bcm_topo_pon_get_context(logical_pon, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
        if (old_topo_context)
            bcmos_free(old_topo_context);

        topo_context = bcmos_calloc(sizeof(*topo_context));
        topo_context->iwf_mode = iwf_mode;
        bcm_topo_pon_set_context(logical_pon, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL, topo_context);
    }

    BCMOLT_CFG_INIT(&dev_cfg, device, key);
    BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, acc_term_connectivity.devices[device_id].system_mode);

#ifdef QAX_SWITCH
    /* until speed is configurable through topology settings hardcode it based on switch type */ 
    BCM_LOG(INFO, log_id_mac_util, "nni speed is: 10G\n");
    nni_speed_cfg.first_half = BCMOLT_NNI_SPEED_GBPS_10;
    nni_speed_cfg.second_half = BCMOLT_NNI_SPEED_GBPS_10;
    BCMOLT_CFG_PROP_SET(&dev_cfg, device, nni_speed, nni_speed_cfg);
#endif

    return bcmolt_cfg_set(device_id, &dev_cfg.hdr);
}

/**
 * @brief access terminal set for gpon_16
 */
bcmos_errno mac_util_access_terminal_set_for_gpon_16 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
{
    bcmos_errno rc;
    rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
    if (rc != BCM_ERR_OK)
        return rc;
    rc = mac_util_access_terminal_set_for_gpon(p_acc_term, op_type, BCMOLT_SYSTEM_MODE_GPON__16_X, device_id);
    if (rc != BCM_ERR_OK)
        return rc;
    return maple_access_terminal_connect_common(device_id);
	
}

/**
 * @brief access terminal set for gpon_8
 */
bcmos_errno mac_util_access_terminal_set_for_gpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
{
    bcmos_errno rc;
    
    rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
    if (rc != BCM_ERR_OK)
        return rc;
    rc = mac_util_access_terminal_set_for_gpon(p_acc_term, op_type, BCMOLT_SYSTEM_MODE_GPON__8_X, device_id);
    if (rc != BCM_ERR_OK)
        return rc;
    return maple_access_terminal_connect_common(device_id);
}

/** 
  * @brief post access terminal up configurations on Maple
  */
bcmos_errno mac_util_access_terminal_post_indication_set_for_gpon(bcmolt_devid device_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_devid dummy;
    uint32_t physical_if_id;
    uint32_t logical_pon = BCM_TOPO_PON_INVALID;
    bcmolt_gpon_ni_key ni_key = {};
    bcmolt_gpon_ni_cfg ni_cfg = {};
    bcmolt_gpon_sn_acquisition sn_acquisition_cfg = {};
    bcmolt_gpon_ni_auto_cfg gpon_ni_auto_cfg = {};  /* main auto cfg api struct */

    /* configure one time settings for all the interfaces on this device */
    BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
    {
        /* get physical interface from logical interface */
        rc = bcm_topo_pon_get_logical2physical (logical_pon, &dummy, &physical_if_id);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
            break;
        }

        ni_key.pon_ni = physical_if_id; 


        /* Set the SN acquisition mode to enable */
        BCMOLT_CFG_INIT(&ni_cfg, gpon_ni, ni_key);

        sn_acquisition_cfg.control = BCMOLT_CONTROL_STATE_ENABLE;
        sn_acquisition_cfg.interval = 5000;
        sn_acquisition_cfg.onu_post_discovery_mode = BCMOLT_ONU_POST_DISCOVERY_MODE_NONE;
        
        BCMOLT_CFG_PROP_SET(&ni_cfg, gpon_ni, sn_acquisition, sn_acquisition_cfg);

        rc = bcmolt_cfg_set(device_id, &ni_cfg.hdr);
        if (rc != BCM_ERR_OK)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), 
                    "Failed to set sn acquisition configuration (%s), err_text=%s)\n", 
                    bcmos_strerror(rc), ni_cfg.hdr.hdr.err_text);
            break;
        }
        

        /* turn off the auto indication messages for gpon_ni.serial_number_acquisition_cycle_start  */
        BCMOLT_AUTO_CFG_INIT(&gpon_ni_auto_cfg, gpon_ni, ni_key);
        BCMOLT_AUTO_CFG_PROP_SET(&gpon_ni_auto_cfg, gpon_ni, serial_number_acquisition_cycle_start, BCMOS_FALSE);
        rc = bcmolt_auto_cfg_set(device_id, &gpon_ni_auto_cfg.hdr);
        if (rc != BCM_ERR_OK)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), 
                    "bcmolt_auto_cfg_set for gpon_ni.serial_number_acquisition_cycle_start, Failed (%s), err_text=%s)\n", 
                    bcmos_strerror(rc), gpon_ni_auto_cfg.hdr.hdr.err_text);

            /* ignore any error, just continue anyway */
        }
    }

    return rc;
}

/**
 * @brief Command Set setup routine for interface up to mac application for GPON
 * 
 * This routine is called by if_fsm in the BAL core to initialize the command
 * set to up the interface of the mac application. The cmdset actually 
 * consists of two commands, one is to send the if up request message to the mac
 * App and handle the relevant response, the other is to handle the indication message
 * from the mac APP when the operation is completed. 
 * 
 * @param p_interface_inst  Pointer to interface instance
 * @param op_type           Operation type on access terminal/interface instance
 * 
 * @return bcmos_errno 
 *
 */
bcmos_errno mac_util_interface_set_for_gpon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
{
    bcmos_errno rc = BCM_ERR_OK;

    bcmbal_interface_cfg *p_interface_req = &(p_interface_inst->api_req_int_obj_info);
    bcmbal_interface_key intf_key = p_interface_req->key;
    mac_util_topo_pon_context *topo_context;

    do
    {
        bcmolt_devid device_id;
        uint32_t physical_if_id;
        /* get physical interface from logical interface */
        rc = bcm_topo_pon_get_logical2physical (intf_key.intf_id, &device_id, &physical_if_id);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id), 
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
            break;
        }


        bcmolt_gpon_ni_set_pon_state oper_ni;
        bcmolt_gpon_ni_key ni_key = { .pon_ni = physical_if_id };
        bcmolt_gpon_trx_cfg cfg = {};
        bcmolt_gpon_trx_key trx_key = { .pon_ni = physical_if_id };
        bcmolt_trx_type trx_type;
        bcmolt_gpon_iwf_key iwf_key = { .pon_ni = physical_if_id };
        bcmolt_gpon_iwf_cfg iwf_cfg = {};
        bcmolt_mac_table_configuration mac_table_configuration = {};

        if (BAL_UTIL_OPER_IF_UP == op_type)
        {

            /* set the pon_ni transceiver configuration */
            BCMOLT_CFG_INIT(&cfg, gpon_trx, trx_key);

            /* If the user didn't specify a transceiver, then use the default */
            if (BCMOS_TRUE != BCMBAL_CFG_PROP_IS_SET(p_interface_req, interface, transceiver_type))
            {
                /* The user didn't choose a transceiver type, so override it here
                 * with the default value for GPON
                 */
                BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_GPON);
            }

            /* Set the (default or chosen) transceiver configuration into the MAC device */
            trx_type = mac_gpon_bal_trx_type2bcm68620_trx_type(p_interface_req->data.transceiver_type, intf_key.intf_id);
            BCMOLT_CFG_PROP_SET(&cfg, gpon_trx, transceiver_type, trx_type);

            rc = bcmolt_cfg_set(device_id, &cfg.hdr);
            if (rc != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id), 
                        "Failed to set trx configuration (%s), err_text=%s\n", bcmos_strerror(rc), cfg.hdr.hdr.err_text);
                break;
            }


            /* Configure pon_ni interworking and mac table configuration based on the system global interworking mode
             *
             * We only have to change the mode if the user has chosen per-flow, because direct mode is the default
             * iwf mode in MAPLE
             */
            topo_context = bcm_topo_pon_get_context(intf_key.intf_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
            if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
            {
                /* set the iwf configuration */
                BCMOLT_CFG_INIT(&iwf_cfg, gpon_iwf, iwf_key);
                BCMOLT_CFG_PROP_SET(&iwf_cfg, gpon_iwf, iwf_mode, BCMOLT_IWF_MODE_PER_FLOW_MODE);
                /* set the mac table configuration */
                mac_table_configuration.aging_time = 10000;
                mac_table_configuration.automatic_mac_move = BCMOLT_CONTROL_STATE_DISABLE;
                mac_table_configuration.automatic_static_mode = BCMOLT_CONTROL_STATE_DISABLE;
                mac_table_configuration.default_flow_id = 0;
                mac_table_configuration.learning_mode = BCMOLT_MAC_TABLE_LEARNING_MODE_NORMAL;
                mac_table_configuration.miss_fallback = BCMOLT_MAC_TABLE_MISS_FALLBACK_DROP;
                mac_table_configuration.automatic_mac_learning = BCMOLT_CONTROL_STATE_ENABLE;
                mac_table_configuration.automatic_mac_aging = BCMOLT_CONTROL_STATE_ENABLE;
                BCMOLT_CFG_PROP_SET(&iwf_cfg, gpon_iwf, mac_table_configuration, mac_table_configuration);

                rc = bcmolt_cfg_set(device_id, &iwf_cfg.hdr);
                if (rc != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id), 
                            "Failed to set iwf / mac table configuration (%s), err_text=%s)\n", 
                        bcmos_strerror(rc), iwf_cfg.hdr.hdr.err_text);
                    break;
                }
            }
        }


        /* invoke the pon_ni state change to the requested state */
        BCMOLT_OPER_INIT(&oper_ni, gpon_ni, set_pon_state, ni_key);
        BCMOLT_OPER_PROP_SET(&oper_ni, gpon_ni, set_pon_state, pon_state,
            (BAL_UTIL_OPER_IF_UP == op_type) ? 
            BCMOLT_PON_OPERATION_ACTIVE_WORKING : BCMOLT_PON_OPERATION_INACTIVE);
        rc = bcmolt_oper_submit(device_id, &oper_ni.hdr);
        if (rc != BCM_ERR_OK)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id), 
                    "Failed to %s (submit) pon interface (%s), err_text=%s\n", 
                    (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
                    bcmos_strerror(rc), oper_ni.hdr.hdr.err_text);
        }

    } while (0);

    if (BCM_ERR_OK == rc)
    {
        BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id), 
                "Submitted INTERFACE-%s operation for IF %d\n",
                (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN",
                intf_key.intf_id);
    }

    return rc;
}


/**
 * @brief maple_mac_ds_iwf_cfg
 *
 * This routine is used to configure the relevant downstream ingress and egress iwf at the device
 *
 * @param p_flow                   Pointer to the flow info
 * @param per_flow_mode_vlan_id    vlan id for GEM port mapping in per flow mode
 * @param is_pbit_enabled          Flag indicating whether or not to resolve pbits to GEM IDs
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_mac_ds_iwf_cfg(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bcmos_bool is_pbit_enabled)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_iwf_ds_ingress_flow_key in_key = {};
    bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg = {};
    bcmolt_gpon_iwf_ds_egress_flow_key egr_key = {};
    bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;


    do
    {
        /* get physical interface from logical interface */
        rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
            break;
        }

        /* configure the new ds ingress flow */
        in_key.pon_ni = physical_if_id;
        in_key.vlan_id = per_flow_mode_vlan_id;
        BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
        if (BCMOS_TRUE == p_flow->data.resolve_mac)
        {
            /* mapping method */
            BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
                BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_MACPLUSVID);
        }
        else
        {
            /* mapping method */
            BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
                BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_VID);
        }

        /* mapping tag */
        BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_tag,
            BCMOLT_MAPPING_TAG_METHOD_OUTER_VID);
        BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, vlan_action, BCMOLT_DS_VLAN_ACTION_TRANSPARENT);

        rc = bcmolt_cfg_set(device_id, &in_cfg.hdr);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "Failed to configure ingress flow pon_ni = %d vlan_id = %d rc = %s (%d), err_text=%s\n",
                in_key.pon_ni,
                in_key.vlan_id,
                bcmos_strerror(rc),
                rc,
                in_cfg.hdr.hdr.err_text);
            break;
        }


        /* configure the new ds egress flow */
        egr_key.pon_ni = physical_if_id;
        egr_key.flow_id = p_flow->data.svc_port_id;

        /* Configure DS egress handling: flow -> GEM */
        BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
        BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, gem_port, p_flow->data.svc_port_id);
        BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, pbit_control, is_pbit_enabled);

        rc = bcmolt_cfg_set(device_id, &egr_cfg.hdr);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "Failed to configure egress flow pon_ni = %d flow_id = %d rc = %s (%d), err_text=%s\n",
                egr_key.pon_ni,
                egr_key.flow_id,
                bcmos_strerror(rc),
                rc,
                egr_cfg.hdr.hdr.err_text);
        }

    } while (0);

    BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
            "going out of %s rc = %s (%d)\n",
            __FUNCTION__,
            bcmos_strerror(rc), rc);
    return rc;
}


/**
 * @brief maple_mac_ds_iwf_cfg_remove
 *
 * This routine is used to remove configuration from Maple of the relevant downstream ingress and egress iwf
 *
 * @param p_flow                   Pointer to the flow info
 * @param per_flow_mode_vlan_id    vlan id for per flow mode
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_mac_ds_iwf_cfg_remove(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_iwf_ds_ingress_flow_key in_key = {};
    bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg = {};
    bcmolt_gpon_iwf_ds_egress_flow_key egr_key = {};
    bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    do
    {
        /* config clear ds ingress flow */
        rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
            break;
        }

        in_key.pon_ni = physical_if_id;
        in_key.vlan_id = per_flow_mode_vlan_id;
        BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);

        rc = bcmolt_cfg_clear(device_id, &in_cfg.hdr);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "Failed to Clear ingress flow pon_ni = %d vlan_id = %d rc = %s (%d)\n",
                in_key.pon_ni,
                in_key.vlan_id,
                bcmos_strerror(rc),
                rc);
            break;
        }


        /* config clear ds egress flow */
        egr_key.pon_ni = physical_if_id;
        egr_key.flow_id = p_flow->data.svc_port_id;

        /* Configure DS egress handling: flow -> GEM */
        BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);

        rc = bcmolt_cfg_clear(device_id, &egr_cfg.hdr);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "Failed to Clear egress flow pon_ni = %d flow_id = %d rc = %s (%d)\n",
                egr_key.pon_ni,
                egr_key.flow_id,
                bcmos_strerror(rc),
                rc);
        }

    } while (0);

    BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
            "%s: config clear: rc = %s (%d)\n",
            __FUNCTION__,
            bcmos_strerror(rc), rc);

    return rc;
}


/**
 * @brief maple_mac_us_iwf_cfg
 *
 * This routine is used to configure the relevant upstream iwf at the device
 *
 * @param p_flow       A pointer to a flow object
 *
 * @param pbit         A pbit value being configured for the specified flow
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_mac_us_iwf_cfg(bcmbal_flow_cfg *p_flow, uint8_t pbit)
{
    bcmos_errno rc = BCM_ERR_PARM;
    bcmolt_gpon_iwf_us_flow_key us_key = {};
    bcmolt_gpon_iwf_us_flow_cfg us_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    /* get physical interface from logical interface */
    rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
    if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
    }
    else
    {
        /* configure the related iwf us flow */
        us_key.pon_ni = physical_if_id;
        us_key.gem_port_id = p_flow->data.svc_port_id;
        BCMOLT_CFG_INIT(&us_cfg, gpon_iwf_us_flow, us_key);
        BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, flow_id, p_flow->data.svc_port_id);
        if (BCMOS_TRUE == p_flow->data.resolve_mac)
        {
            BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, mac_learning, BCMOS_TRUE);
        }
        else
        {
            BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, mac_learning, BCMOS_FALSE);
        }
        BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, vlan_action, BCMOLT_US_VLAN_ACTION_TRANSPARENT);

        rc = bcmolt_cfg_set(device_id, &us_cfg.hdr);
    }

    if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "%s FAILED, rc = %s (%d), err_text = %s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc, us_cfg.hdr.hdr.err_text);
    }
    return rc;
}


/**
 * @brief maple_mac_us_iwf_cfg_remove
 *
 * This routine is used to remove configuration from Maple of the relevant upstream iwf
 *
 * @param p_flow       A pointer to a flow object
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_mac_us_iwf_cfg_remove(bcmbal_flow_cfg *p_flow)
{
    bcmos_errno rc = BCM_ERR_PARM;
    bcmolt_gpon_iwf_us_flow_key us_key = {};
    bcmolt_gpon_iwf_us_flow_cfg us_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    /* configure the related iwf us flow */
    rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
    if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
            "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
        return rc;
    }

    us_key.pon_ni = physical_if_id;
    us_key.gem_port_id = p_flow->data.svc_port_id;
    BCMOLT_CFG_INIT(&us_cfg, gpon_iwf_us_flow, us_key);

    rc = bcmolt_cfg_clear(device_id, &us_cfg.hdr);
    if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "%s FAILED, rc = %s (%d)\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc);
    }

    return rc;
}


/**
 * @brief mac_util_validate_subscriber_terminal_info_for_gpon
 *
 * This routine is used to validate all input attributes required for a sub term setting
 * received from core for GPON
 *
 * @param p_sub_term_req       A pointer to a subscriber terminal object
 *
 * @return bcmos_errno
 */
bcmos_errno mac_util_validate_subscriber_terminal_info_for_gpon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
{
    if(BCMBAL_STATE_UP == p_sub_term_req->data.admin_state)
    {
        if (!BCMBAL_CFG_PROP_IS_SET (p_sub_term_req, subscriber_terminal, serial_number))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                    "Serial number is a mandatory parameter for a gpon subscriber terminal, and it is not set\n");
            return BCM_ERR_MANDATORY_PARM_IS_MISSING;
        }

        if (!BCMBAL_CFG_PROP_IS_SET(p_sub_term_req, subscriber_terminal, password))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                    "Password is a mandatory parameter for a gpon subscriber terminal, and it is not set\n");
            return BCM_ERR_MANDATORY_PARM_IS_MISSING;
        }
    }

    return BCM_ERR_OK;
}


/**
 * @brief Command Set setup routine for subscriber terminal connect to mac application for GPON
 * 
 * This routine is called by sub_term_fsm in the BAL core to initialize the command
 * set to connect the subscriber terminal of the mac application. The cmdset actually 
 * consists of two commands, one is to send the sub_term request message to the mac
 * App and handle the relevant response, the other is to handle the indication message
 * from the mac APP when the operation is completed. 
 * 
 * @param p_sub_term_inst   A pointer to a subscriber terminal instance
 * @param op_type          Type of operation being performed on the subscriber terminal instance
 * @param is_post_discovery  Used for ADD, indicates if this is a request after a ONU discovery
 * 
 * @return bcmos_errno 
 *
 * @note we configure Maple for ONU in 2 stages:
 *  \li Stage 1: do cfg_set with the serial num, password, omci port, as part of first sub_term_set from Core
 *  \li Stage 2: set the ONU state to ACTIVE using oper_submit, as part of second sub_term_set from Core (after 
 *                  receiving a Discovery indication)
 */
bcmos_errno mac_util_subscriber_terminal_set_for_gpon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
{
    bcmos_errno rc = BCM_ERR_OK;

    bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;

    do
    { 
        bcmolt_devid device_id;
        uint32_t physical_if_id;
        /* get physical interface from logical interface */
        rc = bcm_topo_pon_get_logical2physical (p_sub_term_req->key.intf_id, &device_id, &physical_if_id);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                    "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
            break;
        }

        bcmolt_gpon_onu_cfg cfg = {};
        bcmolt_gpon_onu_cfg onu_cfg_get = {};
        bcmolt_gpon_onu_set_onu_state oper = {};
        bcmolt_gpon_onu_key key = {};
        bcmolt_onu_operation new_onu_state;
        bcmolt_gpon_onu_auto_cfg gpon_onu_auto_cfg = {};  /* main auto cfg api struct */

        /* set the onu key - set it to the physical if id */
        key.pon_ni = physical_if_id;
        key.onu_id = p_sub_term_req->key.sub_term_id;

        /* set the onu key */
        BCMOLT_CFG_INIT(&cfg, gpon_onu, key);

       /* invoke onu state change operation to the new state */
        BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);

        if(BAL_UTIL_OPER_SUB_TERM_CLEAR == op_type)
        {
            /* Delete the configuration of the ONU */
            rc = bcmolt_cfg_clear(device_id, &cfg.hdr);
            if (BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                        "Failed to clear onu configuration(%s)\n", 
                        bcmos_strerror(rc));
            }

            /* No indication from Maple will result from the clear operation
             * so fake it here
             */
            mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
                                           p_sub_term_req->key.sub_term_id,
                                           (bcmolt_serial_number *)NULL,
                                           BAL_UTIL_OPER_SUB_TERM_CLEAR,
                                           rc, rc,
                                           MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);

            /* No further processing is required for the CLEAR operation */
            break;
 

        }
        else if(BAL_UTIL_OPER_SUB_TERM_ADD == op_type)
        {
            /* first do a get, to see if onu is in active state already */
            BCMOLT_CFG_INIT(&onu_cfg_get, gpon_onu, key);
            BCMOLT_CFG_PROP_GET(&onu_cfg_get, gpon_onu, onu_state);
            rc = bcmolt_cfg_get(device_id, &onu_cfg_get.hdr);
            if (rc != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                        "Failed to get onu configuration(%s), err_text=%s, ... continue to configure\n", 
                        bcmos_strerror(rc), onu_cfg_get.hdr.hdr.err_text);

                /* don't break, but continue with the set anyways */
            }
            else
            {
                BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                            "%s: ONU state = %d, [pon_ni=%d, onu_id=%d], BEFORE doing cfg_set on Maple\n", 
                            __FUNCTION__, onu_cfg_get.data.onu_state, onu_cfg_get.key.pon_ni, onu_cfg_get.key.onu_id);
            }


            if ((BCM_ERR_OK == rc) && (BCMOLT_ONU_STATE_ACTIVE == onu_cfg_get.data.onu_state))
            {
                BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                        "%s: ONU already in active state during ADD. Skipping further config\n", 
                        __FUNCTION__);

                mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
                                       p_sub_term_req->key.sub_term_id,
                                       (bcmolt_serial_number *)NULL,
                                       BAL_UTIL_OPER_SUB_TERM_ADD,
                                       rc, rc,
                                       BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
                break;
            }


            /* set the  sn & password only if it being configured for the first time */
            if (BCMOS_FALSE == is_post_discovery)
            {
                BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, serial_number, 
                                    *((bcmolt_serial_number *)&p_sub_term_req->data.serial_number));

                BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, password, 
                                    *((bcmolt_arr_u8_10 *)&p_sub_term_req->data.password));

                /* set the onu configuration */
                BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, auto_password_learning, BCMOS_TRUE);
                BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, us_fec, BCMOS_FALSE);

                /* set the onu management channel port */
                BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, omci_port_id, p_sub_term_req->data.svc_port_id);
 

                rc = bcmolt_cfg_set(device_id, &cfg.hdr);
                if (rc != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                            "Failed to set onu configuration(%s), err_text=%s\n", 
                            bcmos_strerror(rc), cfg.hdr.hdr.err_text);
                    break;
                }

                /**
                 * @note If this is first time set for ADD, then skip setting the ONU state for now. 
                 * Wait until ONU Discovery is received.
                 */
                break;
            }


            /* turn off the auto indication messages for gpon_onu.rei */
            BCMOLT_AUTO_CFG_INIT(&gpon_onu_auto_cfg, gpon_onu, key);
            BCMOLT_AUTO_CFG_PROP_SET(&gpon_onu_auto_cfg, gpon_onu, rei, BCMOS_FALSE);
            rc = bcmolt_auto_cfg_set(device_id, &gpon_onu_auto_cfg.hdr);
            if (rc != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                        "bcmolt_auto_cfg_set for gpon_onu.rei  Failed (%s), err_text=%s)\n", 
                        bcmos_strerror(rc), gpon_onu_auto_cfg.hdr.hdr.err_text);

                /* This is not fatal, so just continue anyway */
            }

            /*
             * Set the new onu state for the ADD operation
             */
            BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                    "Setting ONU state to active\n");

            new_onu_state = BCMOLT_ONU_OPERATION_ACTIVE; 
        }
        else if (BAL_UTIL_OPER_SUB_TERM_REMOVE == op_type)
        {
            /* If the ONU is not present, then it will never respond to the deactivate command
             * with an indication, so just allow the FSM to continue as if it did.
             */
            if(BCMBAL_STATUS_NOT_PRESENT != p_sub_term_inst->current_sub_term_info.data.oper_status)
            {
                /*
                 * Set the new onu state for the REMOVE operation
                 */
                BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                        "Setting ONU state to IN-active\n");

                new_onu_state = BCMOLT_ONU_OPERATION_INACTIVE;
            }
        }
        else /* This should never happen */
        {
            BCM_LOG(ERROR, log_id_mac_util, "Bad request from core\n"); 
            rc = BCM_ERR_INTERNAL;
            break;
        }

        /* Do oper_submit to set the ONU state */
        BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, new_onu_state);
        rc = bcmolt_oper_submit(device_id, &oper.hdr);
        if (BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                    "bcmolt_oper_submit Failed for onu state  Failed (%s), err_text=%s\n", 
                    bcmos_strerror(rc), &(oper.hdr.hdr.err_text[0]));
        }


        /* If the ONU is not present, then it will never respond to the deactivate command
         * with an indication, so just allow the FSM to continue as if it did.
         */
        if((BCMOLT_ONU_OPERATION_INACTIVE == new_onu_state) &&
           (BCMBAL_STATUS_NOT_PRESENT == p_sub_term_inst->current_sub_term_info.data.oper_status))
        {
            mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
                                           p_sub_term_req->key.sub_term_id,
                                           (bcmolt_serial_number *)NULL,
                                           BAL_UTIL_OPER_SUB_TERM_REMOVE,
                                           rc, rc,
                                           MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
        }

    } while (0);



    if (rc == BCM_ERR_STATE)
    {
        BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                "%s failed to set state, possibly because interface is not configured yet, pon fiber disconnect, or onu disconnect: rc = %s (%d)\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc);
    }
    else if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id), 
                "%s Failed: rc = %s (%d)\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc);
    }

    return rc;
}


/**
 * @brief validate_flow_info for gpon
 *
 * This routine is used to validate all input attributes required for a flow
 * setting received from core for GPON
 *
 * @param p_flow_req     A pointer to a flow object
 *
 * @return bcmos_errno
 */
bcmos_errno mac_util_validate_flow_info_for_gpon (const bcmbal_flow_cfg *p_flow_req)
{
    bcmos_errno rc = BCM_ERR_OK;
    mac_util_topo_pon_context *topo_context;

    topo_context = bcm_topo_pon_get_context(p_flow_req->data.access_int_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
    if ((BCM_ERR_OK == rc) && (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode))
    {
        if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, o_vid))
        {
            /* if the flow has an action to remove the outer tag from a double tagged OLT downstream packets,
               the outer tag will be removed by the SWITCH in front of the MAC, the MAC should take the inner
               tag vid for GEM decision.  Sep-28-2015 IL
               */
            if (BCMOS_TRUE == mac_util_check_flow_is_double_tag_remove_o_tag (p_flow_req))
            {
                if (BCMOS_TRUE != BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, i_vid))
                {
                    BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
                            "classifier i_vid id is a mandatory downstream parameter for double tagged action, "
                            "and it is not set\n");
                    rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
                } 
            }
        }
        else
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                    "o_vid id is a mandatory parameter for a flow classifier, and it is not set\n");
            rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
        }
    }

    if (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
    {
        if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, agg_port_id))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                    "agg port id is a mandatory parameter for an US flow, and it is not set\n");
            rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
        }

    }

    return rc;
}


/**
 * @brief flow set for GPON
 *
 * @param p_flow_req    pointer to flow request structure from core
 * @param op_type       ADD, REMOVE or CLEAR
 * @param p_flow_core   local DB flow context passed as a cookie
 *
 * @return errno    error
 */
bcmos_errno mac_util_flow_set_for_gpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
{
    bcmos_errno rc = BCM_ERR_OK;

    bcmos_bool is_pbit_enabled = BCMOS_FALSE;
    uint16_t per_flow_mode_vlan_id = 0; /* hold the value of the vlan tag to use in per-flow mode */
    uint8_t pbits_val = 0;
    mac_util_topo_pon_context *topo_context;
    flow_list_entry *p_mac_util_flow_entry = NULL;

    topo_context = bcm_topo_pon_get_context(p_flow_req->data.access_int_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
    if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
    {
        per_flow_mode_vlan_id = 0; /* set to default */

        if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, o_vid))
        {
            /* if the flow has an action to remove the outer tag from a double tagged OLT downstream packets,
               the outer tag will be removed by the SWITCH in front of the MAC, the MAC should take the inner
               tag vid for GEM decision.  Sep-28-2015 IL
               */
            if (BCMOS_TRUE == mac_util_check_flow_is_double_tag_remove_o_tag (p_flow_req))
            {
                if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, i_vid))
                {
                    per_flow_mode_vlan_id = p_flow_req->data.classifier.i_vid;
                }
                //else should not happen here really, since this was validated in a previous step
            }
            else
            {
                per_flow_mode_vlan_id = p_flow_req->data.classifier.o_vid;
            }
        }
        //else should not happen here really, since this was validated in a previous step
    }


    /* Check the operation id */
    if ((BAL_UTIL_OPER_FLOW_ADD != op_type)    && 
        (BAL_UTIL_OPER_FLOW_REMOVE != op_type) && 
        (BAL_UTIL_OPER_FLOW_CLEAR != op_type))
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
                "Unexpected mac_util flow operation %d \n", op_type);
        return BCM_ERR_PARM;
    }

    /* flow Add or Modify */
    if (BAL_UTIL_OPER_FLOW_ADD == op_type)
    {
        switch (p_flow_req->key.flow_type)
        {
            /* unicast flows */
            case BCMBAL_FLOW_TYPE_UPSTREAM:
            case BCMBAL_FLOW_TYPE_DOWNSTREAM:
            {
                if (p_flow_req->data.classifier.o_pbits)
                {
                    /* o_pbits  can only take one p-bit value */
                    pbits_val = p_flow_req->data.classifier.o_pbits;
                    is_pbit_enabled = BCMOS_TRUE;
                }
                else
                {
                    pbits_val = 0;
                    is_pbit_enabled = BCMOS_FALSE;
                }

                /* create a gem port id and relevant flow for a single pbit, or with no pbit */
                /* pass on the op type also to specify if it is FLOW_ADD OR FLOW_MODIFY */
                rc = maple_mac_unicast_flow_add(p_flow_req, pbits_val, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
                if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
                {
                    break;
                }


                /* configure iwf flows in case of per flow interworking mode */
                if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
                {
                    if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type) 
                    {
                        rc = maple_mac_ds_iwf_cfg(p_flow_req, per_flow_mode_vlan_id, is_pbit_enabled);
                    }
                    else
                        /* FLOW_TYPE_UPSTREAM */
                    {
                        rc = maple_mac_us_iwf_cfg(p_flow_req, pbits_val);
                    }
                    if (BCM_ERR_OK != rc)
                    {
                        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                                "Failed to add iwf flows in per flow mode (%s))\n", 
                                bcmos_strerror(rc));
                        break;
                    }
                }

                /* mark flow configuration to device completed */
                mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
            }
            break;

            case BCMBAL_FLOW_TYPE_BROADCAST:
            {
                rc = maple_mac_broadcast_flow_add(p_flow_req, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
                if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
                {
                    break;
                }

            }
            break;

            default:
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                        "Unknown flow type %d\n",
                        p_flow_req->key.flow_type);
                rc = BCM_ERR_PARM;
                break;
        }
    }
    else if ((BAL_UTIL_OPER_FLOW_REMOVE == op_type) ||
             (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
    {
        /* find the flow */
        p_mac_util_flow_entry = _mac_util_db_flow_get_w_flow_key(p_flow_req->data.access_int_id, &(p_flow_req->key));
        if (NULL == p_mac_util_flow_entry)
        {
            rc = BCM_ERR_NOENT;
            if (BAL_UTIL_OPER_FLOW_CLEAR != op_type)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
                    "%s: NULL mac util flow entry to remove: flow id: %d, flow_type: %s\n",
                    __FUNCTION__,
                    p_flow_req->key.flow_id,
                    (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ? "up":"down"));
            }

            goto exit;
        }

        switch (p_flow_req->key.flow_type)
        {
            /* unicast flows */
            case BCMBAL_FLOW_TYPE_UPSTREAM:
            case BCMBAL_FLOW_TYPE_DOWNSTREAM:
            {
                /* First De-configure IWF flows in case of per flow interworking mode */
                if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
                {
                    if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type) 
                    {
                        rc = maple_mac_ds_iwf_cfg_remove(p_flow_req, per_flow_mode_vlan_id);
                    }
                    else
                    {
                        rc = maple_mac_us_iwf_cfg_remove(p_flow_req);
                    }
                    if (BCM_ERR_OK != rc)
                    {
                        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                                "Failed to remove iwf flows in per flow mode (%s))\n", 
                                bcmos_strerror(rc));
                        break;
                    }
                }


                /** Then remove unicast GEM/Alloc Id from Maple and flow entry from local database */
                rc = maple_mac_unicast_flow_remove(p_flow_req, op_type, p_mac_util_flow_entry);
                if (BCM_ERR_OK != rc)
                {
                    break;
                }

                /* mark flow De-configuration to device completed */
                mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
            }
            break;

            case BCMBAL_FLOW_TYPE_BROADCAST:
            {
                rc = maple_mac_broadcast_flow_remove(p_flow_req, per_flow_mode_vlan_id, op_type, p_mac_util_flow_entry);
            }
            break;

            default:
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                        "Unknown flow type %d\n",
                        p_flow_req->key.flow_type);
                rc = BCM_ERR_PARM;
                break;
        }

    } 
    else
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id), 
                "Unknown flow op type %d for flow id/type = %d/%d\n",
                op_type, p_flow_req->key.flow_id, p_flow_req->key.flow_type);
        rc = BCM_ERR_PARM;
    }

exit:
    if (BCM_ERR_OK == rc)
    {
        /* 
         * Check flow entry flags to see if an indication to Core should be triggered immediately:
         *  (Special handling for flow configuration, for the case no device configuration is needed, 
         *  and/or no indication from device is expected - could be the case of a single/multiple 
         *  gem ports used for us and ds, and us was already configured.
         *  - send the flow ind immediately 
         */
        check_send_flow_bal_ind_msg(p_mac_util_flow_entry, BCM_ERR_OK, BCMOLT_RESULT_SUCCESS);
    }
    else
    {
        if ((BCM_ERR_NOENT == rc) && (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
        {
            /*
             * For flow CLEAR, and if no flow entry is found, then fake an indication success to Core,
             * for it to execute the flow state machine.
             * The reasons for flow entry not found could be because the flow was already admin-ed Down.
             * Admin-down of a flow causes mac util to clear flow config and flow instance from itself
             * and the maple HW. However, Core FSM still keeps it's flow instance during admin down state.
             */
            mac_util_report_flow_remove_success (p_flow_req->key, p_flow_req->data.access_int_id, op_type);
            rc = BCM_ERR_OK;
        }
    }
    //else if there was an error during config, just return a failure; no need to send back indication for that.


    return rc;
}

bcmos_errno maple_gpon_mac_check_gem_port_id(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id, 
                                                                bcmos_bool *is_configured, bcmos_bool *is_activated)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_gem_port_key gem_key = {};
    bcmolt_gpon_gem_port_cfg gem_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;
    
    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
    
    /* set the gem port object key */
    gem_key.pon_ni = physical_if_id;
    gem_key.gem_port_id = svc_port_id;
    BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
    BCMOLT_CFG_PROP_GET(&gem_cfg, gpon_gem_port, all_properties);
    
    rc = bcmolt_cfg_get(device_id, &gem_cfg.hdr);
    if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
            "%s FAILED in bcmolt_cfg_get: svc_port_id = %d if_id = %d onu_id = %d\n",
            __FUNCTION__,
            svc_port_id, if_id, onu_id);
        
        return rc;
    }
    
    
    /* may be configured; does gem belong to same onu ? */
    if (BCMOLT_GPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state && onu_id != gem_cfg.data.onu_id)
    {	
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
            "%s FAILED, onu id mismatch: svc_port_id = %d if_id = %d is already assigned to onu_id = %d (not to onu id %d) \n",
            __FUNCTION__,
            svc_port_id, if_id, gem_cfg.data.onu_id, onu_id);
        
        return BCM_ERR_PARM;
    }
    *is_configured = BCMOLT_GPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state;
    *is_activated = BCMOLT_GPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state;
    
    return rc;
}


bcmos_errno maple_gpon_gem_port_id_add(uint32_t if_id, uint16_t svc_port_id, uint32_t onu_id, bcmolt_gem_port_configuration *configuration)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_gem_port_key gem_key = {};
    bcmolt_gpon_gem_port_cfg gem_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);

    /* set the gem port object key */
    gem_key.pon_ni = physical_if_id;
    gem_key.gem_port_id = svc_port_id;
    BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);

    /* set the gem port configuration */
    if (onu_id < MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM)
    {
        BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, onu_id, onu_id);
        BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, upstream_destination_queue,
            BCMOLT_US_GEM_PORT_DESTINATION_DATA);
    }
    BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, downstream_encryption_mode,
        BCMOLT_CONTROL_STATE_DISABLE);
    BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, configuration, *configuration);
    BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, control, BCMOLT_CONTROL_STATE_ENABLE);

    rc = bcmolt_cfg_set(device_id, &gem_cfg.hdr);
    if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "%s FAILED: rc=%s (%d), svc_port_id = %d dev_id = %d if_id = %d onu_id = %d, err_text=%s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc, svc_port_id, device_id, if_id, onu_id, gem_cfg.hdr.hdr.err_text);
    }

    return rc;
}


bcmos_errno maple_gpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_gem_port_key gem_key = {};
    bcmolt_gpon_gem_port_cfg gem_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);

    gem_key.pon_ni = physical_if_id;
    gem_key.gem_port_id = svc_port_id;
    BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
    rc = bcmolt_cfg_clear(device_id, &gem_cfg.hdr);
    if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s id=%d, gem=%d, failed with error %s\n",__FUNCTION__, if_id, svc_port_id, bcmos_strerror(rc));
    }


    return rc;
}


bcmos_errno maple_gpon_mac_get_alloc_id_config (uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_alloc_key alloc_key = {};
    bcmolt_gpon_alloc_cfg alloc_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);

    /* set the alloc-id key */
    alloc_key.pon_ni = physical_if_id;
    alloc_key.alloc_id = agg_id;
    BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
    BCMOLT_CFG_PROP_GET(&alloc_cfg, gpon_alloc, all_properties);

    rc = bcmolt_cfg_get(device_id, &alloc_cfg.hdr);
    if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "%s: FAILED in bcmolt_cfg_get rc = %s, agg_id = %d if_id = %d\n",
                __FUNCTION__,
                bcmos_strerror(rc), agg_id, if_id);

        return rc;
    }
	
    /* may be configured; does alloc id belong to the expected onu ? */
    if (alloc_cfg.data.state != BCMOLT_ALLOC_STATE_NOT_CONFIGURED
		&& alloc_cfg.data.onu_id != onu_id)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "%s FAILED, onu id mismatch: agg_id = %d if_id = %d is set to onu %d NOT to onu_id = %d\n",
                __FUNCTION__,
                agg_id, if_id, alloc_cfg.data.onu_id, onu_id);

        return BCM_ERR_PARM;
    }

    *alloc_id_state = alloc_cfg.data.state;

    return BCM_ERR_OK;
}


bcmos_errno maple_gpon_us_alloc_id_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla agg_sla)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_alloc_key alloc_key = {};
    bcmolt_gpon_alloc_cfg alloc_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);

    /* set the alloc-id key */
    alloc_key.pon_ni = physical_if_id;
    alloc_key.alloc_id = agg_id;
    BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
    BCMOLT_CFG_PROP_SET(&alloc_cfg, gpon_alloc, sla, agg_sla);
    /* set the alloc-id - onu assignment */
    BCMOLT_CFG_PROP_SET(&alloc_cfg, gpon_alloc, onu_id, onu_id);

    rc = bcmolt_cfg_set(device_id, &alloc_cfg.hdr);
     if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "%s: rc = %s, agg_id = %d if_id = %d, err_text = %s \n",
                __FUNCTION__,
                bcmos_strerror(rc), agg_id, if_id, alloc_cfg.hdr.hdr.err_text);
    }
    return rc;

}


bcmos_errno maple_gpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gpon_alloc_key alloc_key = {};
    bcmolt_gpon_alloc_cfg alloc_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;

    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);

    /* set the alloc-id key */
    alloc_key.pon_ni = physical_if_id;
    alloc_key.alloc_id = agg_id;
    BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);

    rc = bcmolt_cfg_clear(device_id, &alloc_cfg.hdr);
    if (BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
    }

    return rc;
}

/**
 * @brief group set for gpon 
 * @param p_group_req  pointer to group request structure from core
 * @param op_type      ADD, REMOVE or SET
 * @param p_group_inst pointer to the Core Group Object instance
 *
 * @return errno    error
 *
 * @todo shift this out to mac specific files
 */
bcmos_errno mac_util_group_set_for_gpon (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_inst)
{
    bcmos_errno rc = BCM_ERR_OK;
    uint16_t svc_port_id;
    uint32_t if_id, i, ref_count;
    bcmolt_gem_port_configuration configuration = {0};

    /* Check the operation id */
    if ((BAL_UTIL_OPER_GROUP_ADD != op_type)    &&
        (BAL_UTIL_OPER_GROUP_REMOVE != op_type) &&
        (BAL_UTIL_OPER_GROUP_SET != op_type))
    {
        BCM_LOG(ERROR, log_id_mac_util,
                "Unexpected mac_util gpon group operation %d \n", op_type);
        return BCM_ERR_PARM;
    }
        
    configuration.direction = BCMOLT_GEM_PORT_DIRECTION_DOWNSTREAM;
    configuration.type = BCMOLT_GEM_PORT_TYPE_MULTICAST;
        
    /* for group SET operation, first remove the old multicast GEM */
    if (BAL_UTIL_OPER_GROUP_SET == op_type)
    {
        bcmbal_group_cfg *p_group_rem_req;
        /* use the Core DB for existing members - store in current_flow_info */
        p_group_rem_req = &p_group_inst->current_group_info;
        for(i=0; i< p_group_rem_req->data.members.len; i++)
        {  
            if_id = p_group_rem_req->data.members.val[i].intf_id;
            svc_port_id = p_group_rem_req->data.members.val[i].svc_port_id;
            /* svc_port_id can be 0 (not assigned) when group had no owner, no need to remove  */
            if(svc_port_id)
            { 
                rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
                if(BCM_ERR_OK != rc)
                {
                    BCM_LOG(ERROR, log_id_mac_util,
                    "mac_util gpon group get reference count on interface %d (gem %d) failed \n", if_id, svc_port_id);
                    return rc;
                }
                /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
                   The core will ask Resource Manger to decrease the counter if everything is good */
                if ( ref_count == 1)
                {  
                    rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
                
                    if(BCM_ERR_OK != rc)
                    {
                        BCM_LOG(ERROR, log_id_mac_util,
                        "mac_util gpon group set operation SET on remove interface %d (gem %d) failed \n", if_id, svc_port_id);
                        return rc;
                    }
                }
                else if ( ref_count == 0)
                {  
                    BCM_LOG(WARNING, log_id_mac_util,
                        "mac_util gpon group set operation SET on interface %d (gem %d) remove with 0 reference counter \n", if_id, svc_port_id);
                }
           }
        }
    }
    
    /* walk through every member interface */
    for(i=0; i< p_group_req->data.members.len; i++)
    {  
        if_id = p_group_req->data.members.val[i].intf_id;
        svc_port_id = p_group_req->data.members.val[i].svc_port_id;
        /* group Add */
        if (BAL_UTIL_OPER_GROUP_ADD == op_type || BAL_UTIL_OPER_GROUP_SET == op_type)
        {
            rc = maple_gpon_gem_port_id_add(if_id, svc_port_id, MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM, &configuration);
        }
        else if (BAL_UTIL_OPER_GROUP_REMOVE == op_type)
        {
            rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
            if(BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, log_id_mac_util,
                "mac_util gpon group operation REM on interface %d (gem %d) failed \n", if_id, svc_port_id);
                break;    
            }
            /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
               The core will ask Resource Manger to decrease the counter if everything is good */
            if ( ref_count == 1)
            {
                rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
            }
            else if ( ref_count == 0)
            {  
                BCM_LOG(WARNING, log_id_mac_util,
                    "mac_util gpon group operation REM on interface %d (gem %d) with 0 reference count \n", if_id, svc_port_id);
            }
        }
 
        if(BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, log_id_mac_util,
            "mac_util gpon group set of operation %d on interface %d (gem %d) failed \n", op_type, if_id, svc_port_id);
            break;
        }
    }

    
    return rc;
}

/*@}*/
