/******************************************************************************
 *
 *  <: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_xgpon.c
 *
 * @brief mac util interfaces definition used by Bal Core, for xgpon
 *
 * 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_xgpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);
static bcmos_errno mac_util_indication_handle_for_xgpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg);
static bcmos_errno mac_util_indication_handle_for_xgpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg);

/* On XG-PON1 there is no indication such as GEM port configuration completed.
 * GEM configuration at the ONU is taken care of completely by OMCI without any PLOAM sent from the OLT
 * */

/**
 * @brief array stores the list of xgpon (XG-PON1) related auto indications from Maple to subscribe
 */
static mac_util_ind_obj_and_handlers mac_util_xgpon_ind_handlers[] =
{
    {BCMOLT_OBJ_ID_XGPON_NI,        "BCMOLT_OBJ_ID_XGPON_NI",    mac_util_indication_handle_for_xgpon_ni},
    {BCMOLT_OBJ_ID_XGPON_ONU,       "BCMOLT_OBJ_ID_XGPON_ONU",   mac_util_indication_handle_for_xgpon_onu},
    {BCMOLT_OBJ_ID_XGPON_ALLOC,     "BCMOLT_OBJ_ID_XGPON_ALLOC", mac_util_indication_handle_for_xgpon_alloc_id},
};

/**
 * @brief Map bal XGPON transceiver type to bcm68620 transceiver type
 */
static bcmolt_xgpon_trx_type mac_xgpon_bal_trx_type2bcm68620_trx_type(bcmbal_trx_type bal_trx_type)
{
    bcmolt_xgpon_trx_type trx_type = BCMOLT_XGPON_TRX_TYPE__NUM_OF;

    if (BCMBAL_TRX_TYPE_XGPON_LTH_7222_PC == bal_trx_type)
    {
        trx_type = BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC;
    }
    else if (BCMBAL_TRX_TYPE_XGPON_LTH_7226_PC == bal_trx_type)
    {
        trx_type = BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC;
    }
    else if (BCMBAL_TRX_TYPE_XGPON_LTH_5302_PC == bal_trx_type)
    {
        trx_type = BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC;
    }
    else
    {
        trx_type = BCMOLT_XGPON_TRX_TYPE_USER_DEFINED;
    }

    return trx_type;
}

/**
 * @brief all the maple indication handlers for xgpon
 *
 * @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_xgpon (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_xgpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_xgpon_ind_handlers)),
        p_msg->group, p_msg->subgroup);

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


/**
 * @brief Handler function for Maple auto indications for xgpon (XG-PON1) 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_xgpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
{
    bcmos_errno rc = BCM_ERR_OK;
	uint32_t logical_pon;

    do
   	{
   
     /* PON activation */
        if (BCMOLT_XGPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
        {
            bcmolt_xgpon_ni_state_change_completed * p_ind = (bcmolt_xgpon_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");
    
            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_XGPON_NI_AUTO_CFG_ID_ONU_DISCOVERED == p_msg->subgroup)
        {
            bcmolt_xgpon_ni_onu_discovered *p_ind =
                (bcmolt_xgpon_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 found ONU serial number "
                    "%c%c%c%c%d%d%d%d%d%d%d%d\n",
                    logical_pon,
                    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
                    );
    
            /* if we got something from MAC HW, then it has to be PON interface */
            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, BCM_ERR_OK,
                                           BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
        }

        else
        {
            /* just get the pon key by typecasting to a dummy structure */
            bcmolt_xgpon_ni_key *p_pon_key = &(((bcmolt_xgpon_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(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                "Unhandled message indication for obj XGPON_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 xgpon (XG-PON1) 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_xgpon_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_xgpon_onu_key *p_xgpon_onu_key = &(((bcmolt_xgpon_onu_onu_activation_completed*)p_msg)->key);
    do
    {    
        if (BCMOLT_XGPON_ONU_AUTO_CFG_ID_ONU_ACTIVATION_COMPLETED == p_msg->subgroup)
        {
            bcmolt_xgpon_onu_onu_activation_completed *p_ind = (bcmolt_xgpon_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(logical_pon),
                "sub_term %d (PON%d) activation 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_ADD,
                p_msg->err, p_ind->data.status,
                p_ind->data.fail_reason, BCMBAL_INVALID_TUNNEL_ID);
            
        }
        else if(BCMOLT_XGPON_ONU_AUTO_CFG_ID_ONU_DEACTIVATION_COMPLETED == p_msg->subgroup)
        {
            bcmolt_xgpon_onu_onu_deactivation_completed *p_ind = (bcmolt_xgpon_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,
                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_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_xgpon_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_xgpon_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 XGPON_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_xgpon_onu_key->onu_id, maple_xgpon_mac_check_gem_port_id, maple_xgpon_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_xgpon_onu_key->onu_id, bcmos_strerror(rc));
			break;
		}
		
    }while(0);
    
    return rc;
}


/**
 * @brief Handler function for Maple auto indications for xgpon (XG-PON1) 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_xgpon_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_XGPON_ALLOC_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
        {
            bcmolt_xgpon_alloc_configuration_completed *p_ind = (bcmolt_xgpon_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_xgpon_alloc_key *p_pon_key = &(((bcmolt_xgpon_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 XGPON_ALLOC group %d "
                    "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
        }

	}
	while (0);
    return rc;
}


/**
 * @brief  Maple auto indication register for specific xgpon (XG-PON1) 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_xgpon_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_xgpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_xgpon_ind_handlers),device_id);
}


/**
 * @brief common access terminal set for 10G pon if
 */

bcmos_errno mac_util_access_terminal_set_for_10G_itu_pon (bcmolt_device_cfg dev_cfg, bcmolt_devid device_id)
{
    bcmos_errno rc;
    bcmolt_device_nni_speed nni_speed_cfg;

#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
	
		rc = bcmolt_cfg_set(device_id, &dev_cfg.hdr);

		return rc;
}


/**
 * @brief access terminal set for xgpon1_8
 */
bcmos_errno mac_util_access_terminal_set_for_xgpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
{
    bcmos_errno rc;
    bcmolt_device_key key = {};
    bcmolt_device_cfg dev_cfg;

    rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
    if (rc != BCM_ERR_OK)
        return rc;

    BCMOLT_CFG_INIT(&dev_cfg, device, key);
    BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, BCMOLT_SYSTEM_MODE_XGPON_1__8_X);

    rc = mac_util_access_terminal_set_for_10G_itu_pon(dev_cfg,device_id);
    if (rc != BCM_ERR_OK)	
        return rc;

    return maple_access_terminal_connect_common(device_id);
}


/**
 * @brief access terminal set for xgs_2_10
 */
bcmos_errno mac_util_access_terminal_set_for_xgs (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
{
    bcmos_errno rc;
    bcmolt_device_key key = {};
    bcmolt_device_cfg dev_cfg;

    rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
    if (rc != BCM_ERR_OK)
        return rc;

    BCMOLT_CFG_INIT(&dev_cfg, device, key);
    BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X_10_G);

    rc = mac_util_access_terminal_set_for_10G_itu_pon(dev_cfg, 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_xgpon_xgs(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_xgpon_ni_key ni_key = {};
    bcmolt_xgpon_ni_cfg ni_cfg = {};
    bcmolt_automatic_onu_deactivation automatic_onu_deactivation  = {};
    bcmolt_xgpon_sn_acquisition sn_acquisition_cfg = {};
    bcmolt_xgpon_ni_auto_cfg xgpon_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, xgpon_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;
        sn_acquisition_cfg.burst_profile = 0;  /* Ranging burst profile - No FEC */
        BCMOLT_CFG_PROP_SET(&ni_cfg, xgpon_ni, sn_acquisition, sn_acquisition_cfg);

        /* Unlike GPON, the default behavior on Maple for XG-PON1 is not to deactivate the ONU in the below cases
         * so here we specifically configure the Maple to behave on XG-PON1 as it does on GPON */
        automatic_onu_deactivation.ack_timeout = BCMOS_TRUE;
        automatic_onu_deactivation.loki = BCMOS_TRUE;
        automatic_onu_deactivation.los = BCMOS_TRUE;
        automatic_onu_deactivation.onu_alarms = BCMOS_TRUE;
        automatic_onu_deactivation.sfi = BCMOS_TRUE;
        automatic_onu_deactivation.tiwi = BCMOS_TRUE;
        BCMOLT_CFG_PROP_SET(&ni_cfg, xgpon_ni, automatic_onu_deactivation, automatic_onu_deactivation);

        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 and automatic onu deactivation configuration (%s),"
                    " device_id=%d, ni_key.pon_ni=%d, err_text=%s)\n",
                    bcmos_strerror(rc), device_id, ni_key.pon_ni, ni_cfg.hdr.hdr.err_text);
            break;
        }


        /* turn off the auto indication messages for xgpon_ni.serial_number_acquisition_cycle_start  */
        BCMOLT_AUTO_CFG_INIT(&xgpon_ni_auto_cfg, xgpon_ni, ni_key);
        BCMOLT_AUTO_CFG_PROP_SET(&xgpon_ni_auto_cfg, xgpon_ni, serial_number_acquisition_cycle_start, BCMOS_FALSE);
        rc = bcmolt_auto_cfg_set(device_id, &xgpon_ni_auto_cfg.hdr);
        if (rc != BCM_ERR_OK)
        {
            BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
                    "bcmolt_auto_cfg_set for xgpon_ni.serial_number_acquisition_cycle_start, Failed (%s), err_text=%s)\n",
                    bcmos_strerror(rc), xgpon_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 xgpon (XG-PON1)
 *
 * 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_xgpon(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;

    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_xgpon_ni_set_pon_state oper_ni;
        bcmolt_xgpon_ni_key ni_key = { .pon_ni = physical_if_id };
        bcmolt_xgpon_trx_cfg cfg = {};
        bcmolt_xgpon_trx_key trx_key = { .pon_ni = physical_if_id };
        bcmolt_xgpon_trx_type trx_type;

        if (BAL_UTIL_OPER_IF_UP == op_type)
        {

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

            /* Get the current default burst profiles */
            rc = bcmolt_cfg_get(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 get trx configuration (%s), err_text=%s\n", bcmos_strerror(rc), cfg.hdr.hdr.err_text);
                break;
            }

            /* 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))
            {
                if(BCM_TOPO_PON_MODE_XGPON == bcm_topo_pon_get_pon_mode(intf_key.intf_id))
              	{
                    /* The user didn't choose a transceiver type, so override it here
                     * with the default value for XGPON
                     */
                    BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_XGPON);                                 
               	}
                else if (BCM_TOPO_PON_MODE_XGS == bcm_topo_pon_get_pon_mode(intf_key.intf_id))
                {
                    /* The user didn't choose a transceiver type, so override it here
                     * with the default value for XGS
                     */
                    BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_XGS);                                                                         			
                }
            }

            /* Set the (default or chosen) transceiver configuration into the MAC device */

            trx_type = mac_xgpon_bal_trx_type2bcm68620_trx_type(p_interface_req->data.transceiver_type);

            BCMOLT_CFG_PROP_SET(&cfg, xgpon_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;
            }

            /* No need to Configure pon_ni Inter-working on XG-PON1 as 
             * direct mode is the only option available on this system mode 
             */
        }


        /* invoke the pon_ni state change to the requested state */
        BCMOLT_OPER_INIT(&oper_ni, xgpon_ni, set_pon_state, ni_key);
        BCMOLT_OPER_PROP_SET(&oper_ni, xgpon_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 mac_util_validate_subscriber_terminal_info_for_xgpon (XG-PON1)
 *
 * 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_xgpon(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 xgpon 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, registration_id))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
                    "Registration id is a mandatory parameter for a xgpon 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 xgpon (XG-PON1)
 *
 * 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_xgpon(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_xgpon_onu_cfg cfg = {};
        bcmolt_xgpon_onu_cfg onu_cfg_get = {};
        bcmolt_xgpon_onu_set_onu_state oper = {};
        bcmolt_xgpon_onu_key key = {};
        bcmolt_onu_operation new_onu_state;

        /* 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, xgpon_onu, key);

       /* invoke onu state change operation to the new state */
        BCMOLT_OPER_INIT(&oper, xgpon_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, xgpon_onu, key);
            BCMOLT_CFG_PROP_GET(&onu_cfg_get, xgpon_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 & Registration ID only if it being configured for the first time */
            if (BCMOS_FALSE == is_post_discovery)
            {
                BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, serial_number,
                                    *((bcmolt_serial_number *)&p_sub_term_req->data.serial_number));

                BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_id,
                                    *((bcmolt_arr_u8_36 *)&p_sub_term_req->data.registration_id));

                BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_id_auto_learning, BCMOS_TRUE);

                /* Ranging burst profile - No FEC */
                BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_burst_profile, 0);

                /* Data burst profile - No FEC */
                BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, data_burst_profile, 1);


                /* XG-PON1 - No need to set US FEC - it is part of the burst profile */
                /* XG-PON1 - No need to set ONU management channel port as it is identical to the ONU 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;
            }

            /*
             * 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(INFO, 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, xgpon_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 xgpon (XG-PON1)
 *
 * This routine is used to validate all input attributes required for a flow
 * setting received from core for XG-PON1
 *
 * @param p_flow_req     A pointer to a flow object
 *
 * @return bcmos_errno
 */
bcmos_errno mac_util_validate_flow_info_for_xgpon (const bcmbal_flow_cfg *p_flow_req)
{
    bcmos_errno rc = BCM_ERR_OK;

    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;
}
/* As there is no indication on gem port configuration completion, for xgpon
    we will have to initiate querying it right after configuring it and retrieve the gem port state.
    we can not assume it is activated (for example if the onu is not present)
*/
static bcmos_errno maple_mac_xgpon_update_svc_port_ind_flag (bcmbal_flow_cfg *p_flow_req, flow_list_entry *p_mac_util_flow_entry)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_xgpon_gem_port_key gem_key = {};
    bcmolt_xgpon_gem_port_cfg gem_cfg = {};
    bcmolt_devid device_id;
    uint32_t physical_if_id;
    
    GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(p_flow_req->data.access_int_id, device_id, physical_if_id);
    
    /* set the gem port object key */
    gem_key.pon_ni = physical_if_id;
    gem_key.gem_port_id = p_flow_req->data.svc_port_id;
    BCMOLT_CFG_INIT(&gem_cfg, xgpon_gem_port, gem_key);
    BCMOLT_CFG_PROP_GET(&gem_cfg, xgpon_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(p_flow_req->data.access_int_id),
            "%s FAILED to gem xgpon_gem_port configuration : device_id = %d if_id = %d gem_port_id = %d \n",
            __FUNCTION__,
            device_id, p_flow_req->data.access_int_id, p_flow_req->data.svc_port_id);
        
        return rc;
    }
    
    if ( BCMOLT_XGPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state)
    {
        p_mac_util_flow_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;    
    }
    return rc;
}

/**
 * @brief flow set for xgpon (XG-PON1)
 * @param p_flow_req   pointer to flow request structure from core
 * @param op_type      ADD, REMOVE or CLEAR
 * @param p_flow_core  core FSM DB flow context passed as a cookie
 *
 * @return errno    error
 *
 * @todo shift this out to mac specific files
 */
bcmos_errno mac_util_flow_set_for_xgpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
{
    bcmos_errno rc = BCM_ERR_OK;
    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;
    flow_list_entry *p_mac_util_flow_entry = NULL;

    /* 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;
                }
                else
                {
                    pbits_val = 0;
                }

                /* 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;
                }

                /* mark flow configuration to device completed */
                mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
                rc = maple_mac_xgpon_update_svc_port_ind_flag (p_flow_req, 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);
            }
            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:
            {
                /** 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;
        }

    } /* Flow Remove */
    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_xgpon_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_xgpon_gem_port_key gem_key = {};
    bcmolt_xgpon_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, xgpon_gem_port, gem_key);
    BCMOLT_CFG_PROP_GET(&gem_cfg, xgpon_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 to gem xgpon_gem_port configuration : device_id = %d if_id = %d gem_port_id = %d \n",
                    __FUNCTION__,
                    device_id, if_id, svc_port_id);
        return rc;
    }
    
    /* may be configured; does gem belong to same onu ? */
    if (BCMOLT_XGPON_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_XGPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state;
    *is_activated = BCMOLT_XGPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state;
    
    return rc;
}


bcmos_errno maple_xgpon_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_xgpon_gem_port_key gem_key = {};
    bcmolt_xgpon_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, xgpon_gem_port, gem_key);

    /* set the gem port configuration */
    if (onu_id < BCMOLT_XGPON_ONU_ID_ANY)
    {
        BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, onu_id, onu_id);
        BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, upstream_destination_queue,
            BCMOLT_US_GEM_PORT_DESTINATION_DATA);
    }
    BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, encryption_mode,
        BCMOLT_CONTROL_STATE_DISABLE);
    BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_gem_port, configuration, *configuration);
    BCMOLT_CFG_PROP_SET(&gem_cfg, xgpon_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 if_id = %d onu_id = %d, err_text=%s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc, svc_port_id, if_id, onu_id, gem_cfg.hdr.hdr.err_text);
    }

    return rc;
}


bcmos_errno maple_xgpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_xgpon_gem_port_key gem_key = {};
    bcmolt_xgpon_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, xgpon_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 failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
    }

    return rc;
}


bcmos_errno maple_xgpon_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_xgpon_alloc_key alloc_key = {};
    bcmolt_xgpon_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, xgpon_alloc, alloc_key);
    BCMOLT_CFG_PROP_GET(&alloc_cfg, xgpon_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_xgpon_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_xgpon_alloc_key alloc_key = {};
    bcmolt_xgpon_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, xgpon_alloc, alloc_key);

    BCMOLT_CFG_PROP_SET(&alloc_cfg, xgpon_alloc, sla, agg_sla);
    /* set the alloc-id - onu assignment */
    BCMOLT_CFG_PROP_SET(&alloc_cfg, xgpon_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, sla = {g bw: %d, max bw: %d, cb_nrt_bw: %d, cb_rt_bw: %d}\n",
                __FUNCTION__,
                bcmos_strerror(rc), agg_id, if_id, 
                agg_sla.guaranteed_bw, agg_sla.maximum_bw, agg_sla.cbr_nrt_bw, agg_sla.cbr_rt_bw);

        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "err_text = %s\n",
                alloc_cfg.hdr.hdr.err_text);
    }
    return rc;
}


bcmos_errno maple_xgpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_xgpon_alloc_key alloc_key = {};
    bcmolt_xgpon_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, xgpon_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 xgpon (XG-PON1)
 * @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_xgpon (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 xgpon 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 may be 0 in the current info when the group had no owner.
               skip the remove if that is the case */
            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 xgpon 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_xgpon_gem_port_id_remove(if_id, svc_port_id);
                
                    if(BCM_ERR_OK != rc)
                    {
                        BCM_LOG(ERROR, log_id_mac_util,
                        "mac_util xgpon 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 xgpon group operation SET on interface %d (gem %d) remove with 0 reference count \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_xgpon_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 xgpon group REM get reference count 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_xgpon_gem_port_id_remove(if_id, svc_port_id);
            }
            else if ( ref_count == 0)
            {  
                BCM_LOG(WARNING, log_id_mac_util,
                    "mac_util xgpon group operation REM on interface %d (gem %d) remove with 0 reference count \n", if_id, svc_port_id);
            }
        }
 
        if(BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, log_id_mac_util,
            "mac_util xgpon group set of operation %d on interface %d (gem %d) failed \n", op_type, if_id, svc_port_id);
            break;
        }
    }

    return rc;
}


/*@}*/
