/******************************************************************************
 *
 *  <: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_common_itu_pon.c
 *
 * @brief mac util interfaces definition used by Bal Core, for ITU PON flavors : GPON, XG-PON1, XGS-PON , NG-PON2
 *
 * 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>
#include <bcm_topo.h>



/**
 * @brief get string for the indication object type
 */
char *mac_util_indication_get_obj_type_str(bcmolt_obj_id obj_type, mac_util_ind_obj_and_handlers handlers[], size_t handlers_size)
{
    return _mac_util_get_obj_type_str_for_indications(obj_type, handlers, handlers_size);
}


/**
 * @brief handle indications for any PON ITU flavor.
 */
bcmos_errno mac_util_handle_indication(bcmolt_devid device_id, bcmolt_msg *p_msg, mac_util_ind_obj_and_handlers handlers[], size_t handlers_size)
{
    int i = 0;
    for(i=0; i < handlers_size; i++)
    {
       if(p_msg->obj_type == handlers[i].obj_type)
       {
           if(NULL != handlers[i].ind_handler)
           {
               return handlers[i].ind_handler(device_id, p_msg);
           }
       }
    }
    /* log an error if unhandled */
    return BCM_ERR_INTERNAL;
}



/**
 * @brief checks if a gem port is configured in OLT already for the same PON If and ONU
 *
 * @param svc_port_id   gem port
 * @param if_id         PON NI
 * @param onu_id        ONU Id
 * @param is_config_required TRUE/FALSE
 * @param is_wait_for_indication TRUE/FALSE
 *
 * @return bcmos_errno
 *
 * @todo with multi-thread support in future, the code from checking the maple object
 * to the actual config will need to be atomic(i.e. using mutex). This, to avoid closely parallel threads
 * from getting a state of gem slightly before a new config another thread would make on the same gem,
 * before this thread could configure it. This applies to both gem and alloc id checks.
 *
 */
static bcmos_errno maple_mac_check_gem_port_id_config(uint16_t svc_port_id, uint32_t if_id, uint32_t onu_id,
                                                        bcmos_bool *is_config_required, bcmos_bool *is_wait_for_indication)
{
    bcmos_errno rc = BCM_ERR_OK;
	bcm_topo_pon_sub_family pon_sub_family;
    bcmos_bool is_configured = BCMOS_FALSE, is_activated = BCMOS_FALSE;

    /* assume config is not required, if there is an error */
    *is_config_required = BCMOS_FALSE;
    *is_wait_for_indication = BCMOS_FALSE;

    pon_sub_family = bcm_topo_pon_get_pon_sub_family(if_id);
    switch(pon_sub_family)
    {
        case BCM_TOPO_PON_SUB_FAMILY_GPON:
        {
            rc = maple_gpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
        }
        break;

	    case BCM_TOPO_PON_SUB_FAMILY_XGPON:
        {
            rc = maple_xgpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
        }
        break;

        default:
        {
            rc = BCM_ERR_NOT_SUPPORTED;
        }
    }

    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;
    }
	*is_config_required = !is_configured;
	*is_wait_for_indication = !is_activated;

    if(BCMOS_FALSE == *is_config_required)
    {
        BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "%s: gem port id is already configured: if_id = %d onu_id = %d svc_port_id = %d  is_wait_for_indication = %s\n",
                __FUNCTION__,
                if_id, onu_id,svc_port_id,
               (*is_wait_for_indication == BCMOS_TRUE ? "TRUE":"FALSE"));
    }

    return rc;
}


/**
 * @brief Checks if a gem port needs to be actually deconfigured.
 *          This would be used during flow remove.
 *
 * @param svc_port_id   gem port
 * @param if_id         PON NI
 * @param onu_id        ONU Id
 * @param is_deconfig_required TRUE/FALSE
 * @param is_wait_for_indication TRUE/FALSE
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_mac_check_gem_port_id_deconfig(uint16_t svc_port_id, uint32_t if_id, uint32_t onu_id,
                                                        bcmos_bool *is_deconfig_required, bcmos_bool *is_wait_for_indication)
{
    bcmos_errno rc = BCM_ERR_OK;
    uint32_t ref_count = 0;
    bcm_topo_pon_mode pon_mode;
    bcmos_bool is_configured = BCMOS_FALSE, is_activated = BCMOS_FALSE;

    /* assume De-config not required, in case of an error */
    *is_deconfig_required = BCMOS_FALSE;
    *is_wait_for_indication = BCMOS_FALSE;

    pon_mode = bcm_topo_pon_get_pon_mode(if_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        rc = maple_gpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
    }
    else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
    {
        rc = maple_xgpon_mac_check_gem_port_id(if_id, onu_id, svc_port_id, &is_configured, &is_activated);
    }
    else
    {
        rc = BCM_ERR_NOT_SUPPORTED;
    }

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

	if(!is_configured)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
            "%s error in gpon gem port state: svc_port_id = %d if_id = %d onu_id = %d, gem state: NOT_CONFIGURED\n",
            __FUNCTION__,
            svc_port_id, if_id, onu_id);

        return BCM_ERR_INTERNAL;
    }
    

    /** First: Check if gem deconfig is required:
     * gem deconfig is not needed if other flows are still using the same gem, or it is already being deconfigured.
     */
#if RSRC_MGR_KEEPS_FLOW_LIST_PER_GEM
    /** @todo the rsrc mgr ref count will not work for now since core fsm keeps the flow with admin down,
     * though mac util does a clear on the gem.
     */
    /* get the ref count for the gem from rsc mgr */
    rc = rsc_mgr_gem_lookup(if_id, svc_port_id, &ref_count);
    if(BCM_ERR_OK != rc)
    {
        return BCM_ERR_PARM;
    }
#else
    rc = _mac_util_db_flow_count_w_gem(if_id, svc_port_id, &ref_count);
    if(BCM_ERR_OK != rc)
    {
        return rc;
    }
#endif

    /* if more than 1 flow is using the gem in whatever state, skip deconfig */
    if(1 < ref_count)
    {
        *is_deconfig_required = BCMOS_FALSE;
    }
    else
    {
        *is_deconfig_required = BCMOS_TRUE;
    }

    /* Gem port configuration indications are available on GPON only */
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        /** Next: Check if need to wait for indication */
        if(BCMOS_TRUE == *is_deconfig_required)
        {
            if(!is_activated)
            {
               *is_wait_for_indication = BCMOS_FALSE;
            }
            else
            {
                *is_wait_for_indication = BCMOS_TRUE;
            }
        }
        else
        {
            *is_wait_for_indication = BCMOS_FALSE;

        }
    }
    else
    {
        *is_wait_for_indication = BCMOS_FALSE;
    }


    if(BCMOS_FALSE == *is_deconfig_required)
    {
        BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "Skip gem port deconfig: is_deconfig_required = %s, is_wait_for_indication = %s, svc_port_id = %d if_id = %d onu_id = %d, [ref_count=%d, gem_is configured=%d, gem_is_activated=%d]\n",
               (*is_deconfig_required == BCMOS_TRUE ? "TRUE":"FALSE"),
               (*is_wait_for_indication == BCMOS_TRUE ? "TRUE":"FALSE"),
                svc_port_id, if_id, onu_id,
                ref_count, is_configured, is_activated);
    }

    return rc;
}


/**
 * @brief maple_gem_port_id_add
 *
 * This routine is used for configuring at maple a specific gem port id on a given pon interface
 * and assign it to a given onu id
 * currently all sla properties are hard coded
 *
 * @param svc_port_id       the gem port id
 * @param if_id                   the interface id
 * @param onu_id               the onu id it will assign to
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_gem_port_id_add(uint16_t svc_port_id, uint32_t if_id, uint32_t onu_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_gem_port_configuration configuration = {};
    bcm_topo_pon_mode pon_mode;

    if(onu_id < MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM)
    {
        configuration.direction = BCMOLT_GEM_PORT_DIRECTION_BIDIRECTIONAL;
        configuration.type = BCMOLT_GEM_PORT_TYPE_UNICAST;
    }
    else
    {
        configuration.direction = BCMOLT_GEM_PORT_DIRECTION_DOWNSTREAM;
        configuration.type = BCMOLT_GEM_PORT_TYPE_MULTICAST;
    }

    pon_mode = bcm_topo_pon_get_pon_mode(if_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        rc = maple_gpon_gem_port_id_add(if_id, svc_port_id, onu_id, &configuration);
    }
    else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
    {
        rc = maple_xgpon_gem_port_id_add(if_id, svc_port_id, onu_id, &configuration);
    }
    else
    {
        rc = BCM_ERR_NOT_SUPPORTED;
    }

    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 maple_gem_port_id_remove
 *
 * This routine is used Clear a specific gem port id config in OLT on a given pon interface.
 *
 * @param svc_port_id       the gem port id
 * @param if_id             the interface id
 *
 * @return bcmos_errno
 *
 * @todo do we need to fill in all parameters to disable GEM or just the gem key ?
 */
static bcmos_errno maple_gem_port_id_remove(uint16_t svc_port_id, uint32_t if_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcm_topo_pon_mode pon_mode;

    pon_mode = bcm_topo_pon_get_pon_mode(if_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
    }
    else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
    {
        rc = maple_xgpon_gem_port_id_remove(if_id, svc_port_id);
    }
    else
    {
        rc = BCM_ERR_NOT_SUPPORTED;
    }

    if(BCM_ERR_OK != rc)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                  "Failed to clear gem port configuration(%s) in OLT\n",
                  bcmos_strerror(rc));
    }

    return rc;
}


/**
 * @brief checks if a alloc id is configured in OLT already for the same PON If and ONU
 *
 * @param agg_id        alloc id
 * @param if_id         PON NI
 * @param onu_id        ONU Id
 * @param p_alloc_id_state alloc id current state
 *
 * @return bcmos_errno
 */
static bcmos_errno maple_mac_check_alloc_id_state(uint16_t agg_id, uint32_t if_id, uint32_t onu_id, bcmolt_alloc_state *p_alloc_id_state)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcm_topo_pon_mode pon_mode;
		
    pon_mode = bcm_topo_pon_get_pon_mode(if_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        rc = maple_gpon_mac_get_alloc_id_config(if_id, onu_id, agg_id, p_alloc_id_state);
    }
    else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
    {
        rc = maple_xgpon_mac_get_alloc_id_config(if_id, onu_id, agg_id, p_alloc_id_state);
    }
    else
    {
        rc = BCM_ERR_NOT_SUPPORTED;
    }
	
    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;
    }
	
    return rc;
}

	

static bcmos_errno maple_mac_check_alloc_id_config(uint16_t agg_id, uint32_t if_id, uint32_t onu_id)
{
    bcmos_errno rc;
    bcmolt_alloc_state alloc_id_state;
    
    
    rc = maple_mac_check_alloc_id_state(agg_id, if_id, onu_id, &alloc_id_state);
    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;
    }
    if(BCMOLT_ALLOC_STATE_NOT_CONFIGURED != alloc_id_state)
        rc = BCM_ERR_PARM;
    return rc;
}
static bcmos_errno maple_mac_check_alloc_id_active(uint16_t agg_id, uint32_t if_id, uint32_t onu_id, bcmos_bool *is_alloc_id_wait_for_ind)
{
    bcmos_errno rc;
    bcmolt_alloc_state alloc_id_state;
    
    rc = maple_mac_check_alloc_id_state(agg_id, if_id, onu_id, &alloc_id_state);
    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;
    }
    *is_alloc_id_wait_for_ind = BCMOLT_ALLOC_STATE_ACTIVE != alloc_id_state;
    return rc;
}

/**
 * @brief helper function to check flow with double tag and with action remove outer tag.
 *  Used for validation as well as flow config.
 *
 * @param p_flow_req     A pointer to a flow object
 *
 * @return bcmos_errno
 */
bcmos_bool  mac_util_check_flow_is_double_tag_remove_o_tag(const bcmbal_flow_cfg *p_flow_req)
{
    if(NULL != p_flow_req)
    {
        if(BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type &&
            BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, action) &&
           (p_flow_req->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG) &&
           (p_flow_req->data.classifier.pkt_tag_type == BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG))
        {
            return BCMOS_TRUE;
        }
    }

    return BCMOS_FALSE;
}


/**
 * @brief maple_mac_unicast_flow_add
 *
 * This routine is used to configure a flow at the internal flows list to
 * handle incoming and outgoing relevant indications.
 * the flow svc_port is defined using a single gem port by a base_gem_port
 * and single pbit(=0 in case of pbit is not available)
 * it will also configure gem port and alloc id at the device if required.
 *
 * 
 * @param if_id - the pon interface id 
 * @param onu_id -  the onu id 
 * @param agg_id -  the alloc id 
 * @param sla -  the sla configuration of the alloc id
 *
 * @return bcmos_errno
 */
bcmos_errno  maple_mac_agg_port_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla sla)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcm_topo_pon_mode pon_mode;
    do
    {
        rc = maple_mac_check_alloc_id_config(agg_id, if_id, onu_id);
        
        if(BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
                "Failed to query alloc state\n");
            break;
        }
		
		pon_mode = bcm_topo_pon_get_pon_mode(if_id);
		if(pon_mode == BCM_TOPO_PON_MODE_GPON)
		{
			rc = maple_gpon_us_alloc_id_add(if_id, onu_id, agg_id, sla);
		}
		else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
		{
			rc = maple_xgpon_us_alloc_id_add(if_id, onu_id, agg_id, sla);
		}
		else
		{
			rc = BCM_ERR_NOT_SUPPORTED;
		}
		
		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));
		}  
    }while(0);
    return rc;
}

/**
 * @brief maple_mac_agg_port_remove
 *
 * This routine is used for De-configuring at maple a  specific alloc_id on a given pon interface
 *
 * @param if_id - the pon interface id 
 *
 * @param agg_id -	the alloc id 
 *
 * @return bcmos_errno 
 */
bcmos_errno  maple_mac_agg_port_remove(uint32_t if_id, uint16_t agg_id)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcm_topo_pon_mode pon_mode;

    pon_mode = bcm_topo_pon_get_pon_mode(if_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        rc = maple_gpon_us_alloc_id_remove(if_id, agg_id);
    }
    else if(BCM_TOPO_PON_SUB_FAMILY_XGPON == bcm_topo_pon_get_pon_sub_family(if_id))
    {
        rc = maple_xgpon_us_alloc_id_remove(if_id, agg_id);
    }
    else
    {
        rc = BCM_ERR_NOT_SUPPORTED;
    }

    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_mac_unicast_flow_add(bcmbal_flow_cfg *p_flow, uint16_t pbit, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type, 	
                                        flow_list_entry **pp_mac_util_flow_entry)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmos_bool is_gem_config_required = BCMOS_TRUE;
    bcmos_bool is_gem_wait_for_ind = BCMOS_TRUE , is_alloc_id_wait_for_ind = BCMOS_TRUE;
    flow_list_entry *p_new_flow_entry = NULL;


    *pp_mac_util_flow_entry = NULL;
    do
    {
        /* Allocate & add the new flow to the flow list to follow indications/gem reuse/alloc reuse */
        p_new_flow_entry = _mac_util_db_flow_alloc();
        if(NULL == p_new_flow_entry)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                    "Failed to allocate the flow entry\n");
            rc = BCM_ERR_NOMEM;
            break;
        }

        memcpy(&p_new_flow_entry->bal_flow_key, &p_flow->key,
            sizeof(bcmbal_flow_key));
        p_new_flow_entry->if_id = p_flow->data.access_int_id;
        p_new_flow_entry->sub_term_id = p_flow->data.sub_term_id;
        p_new_flow_entry->svc_port_id = p_flow->data.svc_port_id;
        if(BCMBAL_FLOW_TYPE_UPSTREAM == p_flow->key.flow_type)
        {
            p_new_flow_entry->agg_id = p_flow->data.agg_port_id;
        }
        p_new_flow_entry->vlan_id = per_flow_mode_vlan_id;
        p_new_flow_entry->is_waiting_for_svc_port_active = BCMOS_TRUE;
        p_new_flow_entry->ind_sent  = BAL_UTIL_FLOW_IND_SEND_NONE;
        p_new_flow_entry->is_configuration_completed = BCMOS_FALSE;


        /* save the operation type so as to report back the right indication type to core on an indication from Maple */
        p_new_flow_entry->op_type = op_type;

        /* check if gem configuration is required or it was already configured,
           could happen in case of us flow configured after a ds flow(with the same flow_id)
           and vise versus, or if that is a case of different flow sharing the same gem port id */
        if(BCMOS_TRUE == is_gem_config_required)
        {
            rc = maple_mac_check_gem_port_id_config(p_new_flow_entry->svc_port_id,
                                                     p_new_flow_entry->if_id,
                                                     p_new_flow_entry->sub_term_id,
                                                     &is_gem_config_required,
                                                     &is_gem_wait_for_ind);
            if(BCM_ERR_OK != rc)
            {
                /* free the flow entry */
                _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
                rc = BCM_ERR_PARM;
                break;
            }
            /* set wait for ind flag */
            p_new_flow_entry->is_waiting_for_svc_port_active = is_gem_wait_for_ind;
        }

        /* if that's an us flow, check if alloc configuration is required or it was already configured */
        if(p_new_flow_entry->bal_flow_key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
        {
            rc = maple_mac_check_alloc_id_active(p_new_flow_entry->agg_id,
                                                  p_new_flow_entry->if_id,
                                                  p_new_flow_entry->sub_term_id,
                                                  &is_alloc_id_wait_for_ind);
            if(BCM_ERR_OK != rc)
            {
                /* free the flow entry */
                _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
                rc = BCM_ERR_PARM;
                break;
            }
        }
		
        /* add the new flow to the flow DB */
        rc = _mac_util_db_flow_add(p_flow->data.access_int_id, p_new_flow_entry);
        if(BCM_ERR_OK != rc)
        {
            /* free the flow entry */
            _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
            break;
        }

        /* configure the gem port id if required */
        if(BCMOS_TRUE == is_gem_config_required)
        {
            rc = maple_gem_port_id_add(p_new_flow_entry->svc_port_id, p_new_flow_entry->if_id, p_new_flow_entry->sub_term_id);
            if(BCM_ERR_OK != rc)
            {
                break;
            }
        }

    } while(0);
	
    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), flow Id/Type=%d/%d, pbit=%d, if_id=%d, sub_term_id=%d, "
                "svc_port_id=%d, agg_id=%d, vlan_id=%d, op type=%s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc,
                p_flow->key.flow_id, p_flow->key.flow_type,  pbit,
                p_flow->data.access_int_id, p_flow->data.sub_term_id,
                p_flow->data.svc_port_id, p_flow->data.agg_port_id, per_flow_mode_vlan_id,
               (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW_ADD":"INVALID"));
    }

    /* set the arg to return the local flow entry to caller */
    *pp_mac_util_flow_entry = p_new_flow_entry;

    return rc;
}


/**
 * @brief utility routine to correctly assign the SLAs  to new tm sched owned by agg port
 *  This routine adjusts the BW values to be aligned with 8KBytes/sec boundary. It also
 *  adjusts the difference between pbr & sbr to be at least 32KBytes/sec
 *
 * @param p_tm_sched_req        new tm sched instance
 * @param p_agg_sla              pointer to the sla configuration
 *
 * @note For Maple to accept the sla config:
 *     (1) the sbr and pbr values from BAL user should be in increments of 256 KBits/sec.
 *     (2) Also, the sbr  should be at least 256 Kbits/sec less than the pbr.
 *     (3) sbr value can be 0 or else at least 256 Kbits/sec
 *     (4) pbr value can be 256 Kbits/sec or above
 *
 * @note  The SLA is used for the upstream alloc_id really, even though this is being called for downstream and upstream.
 *
 */
void mac_util_assign_agg_port_sla(bcmbal_tm_sched_cfg *p_tm_sched_req, bcmolt_pon_alloc_sla *p_agg_sla)
{

    BUG_ON(NULL == p_tm_sched_req);

    if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.rate,tm_shaping, sbr))
    {
        p_agg_sla->guaranteed_bw = KILOBITS_PER_SEC2BYTES_PER_SEC(p_tm_sched_req->data.rate.sbr);
        /* Align the BW to 8KBytes granularity(always upward adjustment) */
        p_agg_sla->guaranteed_bw = SLA_BW_NKBYTES_ALIGNED(p_agg_sla->guaranteed_bw, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
        if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.rate, tm_shaping, pbr))
        {
            p_agg_sla->maximum_bw = KILOBITS_PER_SEC2BYTES_PER_SEC(p_tm_sched_req->data.rate.pbr);
            /* max rate should be bigger by 32KBytes/sec than guaranteed rate */
            if(MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID >(p_agg_sla->maximum_bw - p_agg_sla->guaranteed_bw))
            {
                p_agg_sla->maximum_bw = p_agg_sla->guaranteed_bw + MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID;
            }
            else
            {
                /* Else, align the BW to 8KBytes granularity(always upward adjustment) */
                p_agg_sla->maximum_bw = SLA_BW_NKBYTES_ALIGNED(p_agg_sla->maximum_bw, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
            }
        }
        else
        {
            /* max rate should be bigger by 32KBytes/sec than guaranteed rate */
            p_agg_sla->maximum_bw = p_agg_sla->guaranteed_bw + MAPLE_MIN_BYTES_PER_SEC_FOR_DEFAULT_ALLOC_ID;
        }
    }
    else if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.rate, tm_shaping, pbr))
    {
        p_agg_sla->maximum_bw = KILOBITS_PER_SEC2BYTES_PER_SEC(p_tm_sched_req->data.rate.pbr);

        /* Align the BW to 8KBytes granularity(always upward adjustment) */
        p_agg_sla->maximum_bw  = SLA_BW_NKBYTES_ALIGNED(p_agg_sla->maximum_bw , MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
        /* since only max_rate was specified, it is best effort, so set the min rate = 0 */
        p_agg_sla->guaranteed_bw = 0;
    }
    else
    {

        /* Nothing is set, so assign the defaults(that suits GPON) times the SLA US rate factor(GPON=1, XG-PON1=2, XGS-PON,NG-PON2=8) */
        p_agg_sla->guaranteed_bw = SLA_GUARANTEED_BW_DEFAULT_BYTES_PER_SEC * MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor;
        p_agg_sla->maximum_bw = SLA_MAX_BW_DEFAULT_BYTES_PER_SEC * MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor;
    }
    if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, nrt_cbr))
    {
        /* Align the BW to 8KBytes granularity(always upward adjustment) */
        p_agg_sla->cbr_nrt_bw = SLA_BW_NKBYTES_ALIGNED(p_tm_sched_req->data.tcont_sla.nrt_cbr, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);	
    }
    else
    {
        p_agg_sla->cbr_nrt_bw = 0;
    }

    if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, rt_cbr))
    {
        /* Align the BW to 8KBytes granularity(always upward adjustment) */
        p_agg_sla->cbr_rt_bw = SLA_BW_NKBYTES_ALIGNED(p_tm_sched_req->data.tcont_sla.rt_cbr, MAC_UTIL_PMDB(p_tm_sched_req->data.owner.u.agg_port.intf_id).sla_us_rate_factor);
    }
    else
    {
        p_agg_sla->cbr_rt_bw = 0;
    }

    if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, extra_bw_elig))
    {
        p_agg_sla->additional_bw_eligibility = p_tm_sched_req->data.tcont_sla.extra_bw_elig;
    }
    else
    {
        p_agg_sla->additional_bw_eligibility = BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT;
    }
    
    if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, rt_profile))
    {
        p_agg_sla->cbr_rt_ap_index = p_tm_sched_req->data.tcont_sla.rt_profile;
    }
    else
    {
        p_agg_sla->cbr_rt_ap_index = 0;
    }
    
    if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_tm_sched_req->data.tcont_sla, tm_tcont_sla, nrt_profile))
    {
        p_agg_sla->cbr_nrt_ap_index = p_tm_sched_req->data.tcont_sla.nrt_profile;
    }
    else
    {
        p_agg_sla->cbr_nrt_ap_index = 0;
    }
    
    p_agg_sla->alloc_type = BCMOLT_ALLOC_TYPE_NSR;
    p_agg_sla->cbr_rt_compensation = BCMOS_FALSE;
    p_agg_sla->weight = 0;
    p_agg_sla->priority = 0;
 
}


/**
 * @brief mark_flow_config_complete
 *
 * This routine is used to mark all related flow entries, that the flow configuration requests to device was completed,
 * meaning now it is ready to be checked for configuration completion indication from device, and to be indicated to core.
 *
 * @param p_flow_entry  pointer to mac util flow instance
 *
 * @return void
 */
void mac_util_mark_flow_config_complete(flow_list_entry *p_flow_entry)
{
    if(NULL != p_flow_entry)
    {
        p_flow_entry->is_configuration_completed = BCMOS_TRUE;
    }
}


/**
 * @brief maple_mac_broadcast_flow_add
 *
 * This routine is used for setting required configuration for a new broadcast flow :
 * gem port id, iwf ds flow and configure it as a miss fallback of its assigned interface.
 * it will also create an entry for the new flow at the internal flows list to follow relevant indication
 *
 * @param p_flow       A pointer to a flow object
 * @param per_flow_mode_vlan_id vlan id used for GEM port mapping in per flow mode
 * @param op_type      flow "add" or "modify"
 * @param pp_mac_util_flow_entry    addr of pointer to flow entry in mac util DB
 *
 * @return bcmos_errno
 */
bcmos_errno maple_mac_broadcast_flow_add(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type,
                                        flow_list_entry **pp_mac_util_flow_entry)
{
    bcmos_errno rc = BCM_ERR_PARM;
    flow_list_entry *p_new_flow_entry = NULL;
    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_gpon_iwf_key iwf_key;
    bcmolt_gpon_iwf_cfg get_iwf_cfg, set_iwf_cfg;
    bcmolt_mac_table_configuration mac_table_configuration;
    bcmos_bool is_gem_config_required = BCMOS_TRUE;
    bcmos_bool is_gem_wait_for_ind = BCMOS_TRUE;
    bcmolt_devid device_id;
    uint32_t physical_if_id;
    bcm_topo_pon_mode pon_mode;

    *pp_mac_util_flow_entry = NULL;

    /* add the new flow to the flow list */
    p_new_flow_entry = _mac_util_db_flow_alloc();
    if(NULL == p_new_flow_entry)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "Failed to allocate the flow entry\n");
        return BCM_ERR_NOMEM;
    }

    memcpy(&p_new_flow_entry->bal_flow_key, &p_flow->key, sizeof(bcmbal_flow_key));
    p_new_flow_entry->if_id = p_flow->data.access_int_id;
    p_new_flow_entry->sub_term_id = p_flow->data.sub_term_id;
    p_new_flow_entry->svc_port_id = p_flow->data.svc_port_id;
    /* broadcast gem are active by default once they are set, no indications */
    p_new_flow_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
    p_new_flow_entry->ind_sent  = BAL_UTIL_FLOW_IND_SEND_NONE;
    p_new_flow_entry->is_configuration_completed = BCMOS_FALSE;

    /* make sure the broadcast gem port is not already configured / assigned to any onu on the if */
    rc = maple_mac_check_gem_port_id_config(p_new_flow_entry->svc_port_id,
                                             p_new_flow_entry->if_id,
                                             p_new_flow_entry->sub_term_id,
                                             &is_gem_config_required,
                                             &is_gem_wait_for_ind);
    if(BCM_ERR_OK != rc)
    {
        /* free the flow */
        _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
        return BCM_ERR_PARM;
    }

    if(BCMOS_FALSE == is_gem_config_required)
    {
        /* some error, can't have the broadcast flow already configured for the onu */
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                    "Gem %d is already configured on if %d(assigned to onu_id %d)\n",
                    p_new_flow_entry->svc_port_id, p_new_flow_entry->if_id, p_new_flow_entry->sub_term_id);

        /* free the flow */
        _mac_util_db_flow_free(p_flow->data.access_int_id, p_new_flow_entry);
        return BCM_ERR_PARM;
    }

    /* add the new flow to the local flows list */
    rc = _mac_util_db_flow_add(p_flow->data.access_int_id, p_new_flow_entry);
    if(BCM_ERR_OK != rc)
    {
        return rc;
    }

    /* a broadcast gem port is 'assigned' to the special MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM onu id */
    rc = maple_gem_port_id_add(p_new_flow_entry->svc_port_id, p_new_flow_entry->if_id, MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM);
    if(BCM_ERR_OK != rc)
    {
        return rc;
    }

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

    /* Inter-working(IWF) stuff is relevant for GPON only */
    pon_mode = bcm_topo_pon_get_pon_mode(p_flow->data.access_int_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        /* configure the ingress flow as default fallback 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);
        BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
            BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_MACPLUSVID);
        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(ERROR, 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);
            return rc;
        }

        /* configure the egress flow as default fallback 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, BCMOS_FALSE);

        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, rc = %s(%d), err_text = %s\n",
                    egr_key.pon_ni, bcmos_strerror(rc), rc, egr_cfg.hdr.hdr.err_text);
            return rc;
        }

        /* update the if miss fallback flow */
        iwf_key.pon_ni = physical_if_id;
        BCMOLT_CFG_INIT(&get_iwf_cfg, gpon_iwf, iwf_key);
        BCMOLT_CFG_INIT(&set_iwf_cfg, gpon_iwf, iwf_key);

        BCMOLT_CFG_PROP_GET(&get_iwf_cfg, gpon_iwf, all_properties);
        rc = bcmolt_cfg_get(device_id, &get_iwf_cfg.hdr);
        if(BCM_ERR_OK != rc)
        {
            return rc;
        }

        mac_table_configuration = get_iwf_cfg.data.mac_table_configuration;
        mac_table_configuration.miss_fallback = BCMOLT_MAC_TABLE_MISS_FALLBACK_DEFAULT_FLOW;
        mac_table_configuration.default_flow_id = egr_key.flow_id;
        BCMOLT_CFG_PROP_SET(&set_iwf_cfg, gpon_iwf, mac_table_configuration, mac_table_configuration);

        rc = bcmolt_cfg_set(device_id, &set_iwf_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 iwf:  pon_ni = %d, rc = %s(%d), err_text = %s\n",
                    iwf_key.pon_ni, bcmos_strerror(rc), rc, set_iwf_cfg.hdr.hdr.err_text);
            return rc;
        }
    }

    p_new_flow_entry->is_configuration_completed = BCMOS_TRUE;

    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), flow Id/Type=%d/%d, if_id=%d, sub_term_id=%d, "
                "svc_port_id=%d, agg_id=%d, vlan_id=%d, op type=%s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc,
                p_flow->key.flow_id, p_flow->key.flow_type,
                p_flow->data.access_int_id, p_flow->data.sub_term_id,
                p_flow->data.svc_port_id, p_flow->data.agg_port_id, per_flow_mode_vlan_id,
               (BAL_UTIL_OPER_FLOW_ADD == op_type ? "FLOW_ADD": "INVALID"));
    }

    /* set the arg to return the local flow entry to caller */
    *pp_mac_util_flow_entry = p_new_flow_entry;

    return rc;
}


/**
 * @brief maple_mac_broadcast_flow_remove
 *
 * This routine is removes a broadcast flow from Maple
 *
 * @param p_flow                    A pointer to a flow object
 * @param per_flow_mode_vlan_id     vlan id for per flow mode
 * @param op_type                   flow "remove" or "clear"
 * @param p_mac_util_flow_entry     mac util flow entry
 *
 * @return bcmos_errno
 */
bcmos_errno maple_mac_broadcast_flow_remove(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bal_util_oper_flow op_type,
                                        flow_list_entry *p_mac_util_flow_entry)
{
    bcmos_errno rc = BCM_ERR_OK;
    flow_list_entry *p_target_flow_entry = NULL;
    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_gpon_iwf_key iwf_key;
    bcmolt_gpon_iwf_cfg set_iwf_cfg;
    bcmolt_devid device_id;
    uint32_t physical_if_id;
    bcm_topo_pon_mode pon_mode;

    /* First find the flow in local database */
    p_target_flow_entry = _mac_util_db_flow_get_w_flow_key(p_flow->data.access_int_id, &(p_flow->key));

    if(NULL == p_target_flow_entry)
    {
        BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "%s: Failed to find the flow entry: flow id: %d, flow_type: %s\n",
                __FUNCTION__,
                p_flow->key.flow_id,
               (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_BROADCAST ? "broadcast":"unicast/multicast"));

        return BCM_ERR_NOENT;
    }


    /* broadcast gem are active by default once they are set, no indications */
    p_target_flow_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
    p_target_flow_entry->ind_sent  = BAL_UTIL_FLOW_IND_SEND_NONE;
    p_target_flow_entry->is_configuration_completed = BCMOS_FALSE;



    /* clear broadcast gem port */
    rc = maple_gem_port_id_remove(p_target_flow_entry->svc_port_id, p_target_flow_entry->if_id);
    if(BCM_ERR_OK != rc)
    {
        return rc;
    }

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

    /* Inter-working(IWF) stuff is relevant for GPON only */
    pon_mode = bcm_topo_pon_get_pon_mode(p_flow->data.access_int_id);
    if(pon_mode == BCM_TOPO_PON_MODE_GPON)
    {
        /* clear the ingress flow as default fallback 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);

        rc = bcmolt_cfg_clear(device_id, &in_cfg.hdr);
        if(BCM_ERR_OK != rc)
        {
            BCM_LOG(WARNING, 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);

            return rc;
        }

        /* clear the egress flow as default fallback 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(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                    "Failed to clear egress flow pon_ni = %d gem port = %d rc = %s(%d)\n",
                    egr_key.pon_ni, egr_key.flow_id, bcmos_strerror(rc), rc);

            return rc;
        }

        /* update the if miss fallback flow */
        iwf_key.pon_ni = physical_if_id;
        BCMOLT_CFG_INIT(&set_iwf_cfg, gpon_iwf, iwf_key);

        rc = bcmolt_cfg_clear(device_id, &set_iwf_cfg.hdr);
        if(BCM_ERR_OK != rc)
        {
            BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                    "Failed to clear iwf flow pon_ni = %d rc = %s(%d)\n",
                    iwf_key.pon_ni, bcmos_strerror(rc), rc);

            return rc;
        }
    }

    /* all De-config done */
    p_target_flow_entry->is_configuration_completed = BCMOS_TRUE;

    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), flow Id/Type=%d/%d, if_id=%d, sub_term_id=%d, "
                "svc_port_id=%d, agg_id=%d, vlan_id=%d, op type=%s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc,
                p_flow->key.flow_id, p_flow->key.flow_type,
                p_flow->data.access_int_id, p_flow->data.sub_term_id,
                p_flow->data.svc_port_id, p_flow->data.agg_port_id, per_flow_mode_vlan_id,
               (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW_REMOVE":(BAL_UTIL_OPER_FLOW_CLEAR == op_type ? "FLOW_CLEAR":"INVALID")));
    }

    return rc;
}


/**
 * @brief maple_mac_unicast_flow_remove
 *
 * This routine is used to De-configure a flow at the internal flows list to
 * handle incoming and outgoing relevant indications.
 * It will also De-configure gem port and alloc id at the device if required.
 *
 * @param p_flow                Pointer to the flow info
 * @param op_type               Flow operation type i.e. FLOW_REMOVE, FLOW_CLEAR
 * @param p_mac_util_flow_entry Pointer to mac util flow entry
 *
 * @return bcmos_errno
 */
bcmos_errno maple_mac_unicast_flow_remove(bcmbal_flow_cfg *p_flow, bal_util_oper_flow op_type,
                                        flow_list_entry *p_mac_util_flow_entry)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmos_bool is_gem_deconfig_required = BCMOS_TRUE;
    bcmos_bool is_gem_wait_for_ind = BCMOS_TRUE;
    flow_list_entry *p_target_flow_entry = NULL;
    
    BUG_ON(NULL == p_mac_util_flow_entry);
   
    do
    {
        p_target_flow_entry = p_mac_util_flow_entry;       
        p_target_flow_entry->is_waiting_for_svc_port_active = BCMOS_TRUE;
        p_target_flow_entry->ind_sent  = BAL_UTIL_FLOW_IND_SEND_NONE;
        p_target_flow_entry->is_configuration_completed = BCMOS_FALSE;
        /* save the operation type so as to report back the right indication type to core on an indication from Maple */
        p_target_flow_entry->op_type = op_type;
        
        /* check if gem configuration is used by other flows still.
        could happen in case of us flow configured after a ds flow(with the same flow_id)
        and vice versa, or if that is a case of different flow sharing the same gem port id */
        if(BCMOS_TRUE == is_gem_deconfig_required)
        {
            rc = maple_mac_check_gem_port_id_deconfig(p_target_flow_entry->svc_port_id,
                p_target_flow_entry->if_id,
                p_target_flow_entry->sub_term_id,
                &is_gem_deconfig_required,
                &is_gem_wait_for_ind);
            /* set wait for ind flag */
            p_target_flow_entry->is_waiting_for_svc_port_active = is_gem_wait_for_ind;
            
            if(BCM_ERR_OK != rc)
            {
                rc = BCM_ERR_PARM;
                break;
            }
        }
        
        /* do not remove the flow entry from local flows list yet; wait for indication before removing */        
        /* De-configure the gem port id if required */
        if(BCMOS_TRUE == is_gem_deconfig_required)
        {
            rc = maple_gem_port_id_remove(p_target_flow_entry->svc_port_id, p_target_flow_entry->if_id);
            if(BCM_ERR_OK != rc)
            {
                break;
            }
        }
    } while(0);
    
    if(BCM_ERR_OK != rc)
    {
        if(!((BCM_ERR_NOENT == rc) &&(BAL_UTIL_OPER_FLOW_CLEAR == op_type)))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
                "%s Failed: rc = %s(%d), flow Id/Type=%d/%d, if_id=%d, sub_term_id=%d, "
                "svc_port_id=%d, agg_id=%d, op type=%s\n",
                __FUNCTION__,
                bcmos_strerror(rc), rc,
                p_flow->key.flow_id, p_flow->key.flow_type,
                p_flow->data.access_int_id, p_flow->data.sub_term_id,
                p_flow->data.svc_port_id, p_flow->data.agg_port_id,
               (BAL_UTIL_OPER_FLOW_REMOVE == op_type ? "FLOW_REMOVE":(BAL_UTIL_OPER_FLOW_CLEAR == op_type ? "FLOW_CLEAR":"INVALID")));
        }
    }
    
    return rc;

}
bcmos_errno mac_util_update_flows_w_sub_term_update(uint32_t pon_if, uint32_t sub_term_id, maple_mac_check_gem_port_id check_gem_port_id_func, maple_mac_check_agg_port_id check_agg_port_id_func)
{
    flow_list_entry *p_current_entry = NULL;
    flow_list_entry *p_next_entry = NULL;
    bcmos_bool dummy;
    bcmos_bool 	is_gem_activated;
    bcmos_bool 	is_wait_for_gem_activated;
    bcmolt_alloc_state alloc_id_state;
    bcmos_errno rc = BCM_ERR_OK;

    /*find all related flows, check their state and update if needed*/
    do
    {
        p_current_entry = _mac_util_db_flow_get_next_w_sub_term_id(pon_if, sub_term_id, p_current_entry, &p_next_entry);
        if(NULL == p_current_entry)
            break;
        
        rc = check_gem_port_id_func(pon_if,sub_term_id, p_current_entry->svc_port_id, &dummy, &is_gem_activated);
        if(BCM_ERR_OK != rc)
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
            continue;
        }
        
        is_wait_for_gem_activated = !is_gem_activated;
        
        if(p_current_entry->agg_id)
        {
            rc = check_agg_port_id_func(pon_if, sub_term_id, p_current_entry->agg_id, &alloc_id_state);
            
            if(BCM_ERR_OK != rc)
            {
                BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(pon_if), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
                continue;            
            }
        }
        
        /*if something was changed.....*/
        if(p_current_entry->is_waiting_for_svc_port_active != is_wait_for_gem_activated)
        {
            /*update current flow entry*/
            p_current_entry->is_waiting_for_svc_port_active = is_wait_for_gem_activated;					
            
            /*check if a flow became up*/
            if(p_current_entry->op_type == BAL_UTIL_OPER_FLOW_ADD
                &&(is_wait_for_gem_activated)
                && BAL_UTIL_FLOW_IND_SEND_FAIL != p_current_entry->ind_sent)
            {
                mac_util_report_flow_auto_ind(pon_if,p_current_entry->bal_flow_key,p_current_entry->op_type, BAL_UTIL_FLOW_IND_SEND_FAIL);
                p_current_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_FAIL;
            }
            /*check if a flow became down*/
            if(p_current_entry->op_type == BAL_UTIL_OPER_FLOW_ADD
                &&(!is_wait_for_gem_activated)
                &&(BAL_UTIL_FLOW_IND_SEND_SUCCESS != p_current_entry->ind_sent))				 
            {
                mac_util_report_flow_auto_ind(pon_if,p_current_entry->bal_flow_key,p_current_entry->op_type, BAL_UTIL_FLOW_IND_SEND_SUCCESS);
                p_current_entry->ind_sent = BAL_UTIL_FLOW_IND_SEND_SUCCESS;
            }
        }
		/* go through all flows(assigned with the given sub term) until break by 
		   _mac_util_db_flow_get_next_w_sub_term_id returning NULL*/
    }while(1);
    
    return rc;
}

/**
 * @brief agg_port set 
 * @param p_tm_sched_req  pointer to tm_sched request structure from core
 * @param op_type      ADD, REMOVE or CLEAR
 * @param p_tm_sched_inst pointer to the core tm sched Object instance
 *
 * @return errno    error
 *
 */
bcmos_errno  maple_mac_util_agg_port_set(bcmbal_tm_sched_cfg *p_tm_sched_req, bal_util_oper_agg_port op_type, tm_sched_inst *p_tm_sched_inst)
{
	bcmos_errno  ret = BCM_ERR_OK;
    do
    {
        /* Check the operation id */
        if((BAL_UTIL_OPER_AGG_PORT_ADD != op_type)    &&
           (BAL_UTIL_OPER_AGG_PORT_REMOVE != op_type) &&
           (BAL_UTIL_OPER_AGG_PORT_REMOVE != op_type))
        {
            BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_tm_sched_req->data.owner.u.agg_port.intf_id),
                "Unexpected mac_util agg port operation %d \n", op_type);
            ret = BCM_ERR_PARM;
            break;
        }
        
        /* agg port Add or Modify */
        if(BAL_UTIL_OPER_AGG_PORT_ADD == op_type)
        {
            bcmolt_pon_alloc_sla agg_sla;    
            mac_util_assign_agg_port_sla(p_tm_sched_req, &agg_sla);
            ret = maple_mac_agg_port_add(p_tm_sched_req->data.owner.u.agg_port.intf_id, p_tm_sched_req->data.owner.u.agg_port.sub_term_id, p_tm_sched_req->data.owner.u.agg_port.agg_port_id, agg_sla);
        }
        if(BAL_UTIL_OPER_AGG_PORT_REMOVE== op_type)
        {
            ret = maple_mac_agg_port_remove(p_tm_sched_req->data.owner.u.agg_port.intf_id, p_tm_sched_req->data.owner.u.agg_port.agg_port_id);
        }
    
    }while(0);
    return ret;

}

/*@}*/
