/******************************************************************************
 *
 *  <: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 tm_sched_fsm.c
 * @brief Code to support the BAL tm_sched FSM
 *
 *
 */

/*@{*/

#include <bcmos_system.h>
#include <tm_sched_fsm.h>
#include <bal_msg.h>
#include <bal_osmsg.h>
#include "bal_worker.h"
#include "bal_mac_util.h"
#include "bal_switch_util.h"
#include <bal_api.h>
//#include <bal_mac_util_common_itu_pon.h>


#include <bal_objs.h>
#include <fsm_common.h>

#ifdef ENABLE_LOG
#include <bcm_dev_log.h>

 /*
 * @brief The logging device id for tm sched
 */
static dev_log_id log_id_tm_sched;
#endif

/* local function declarations */

static bcmos_errno tm_sched_fsm_create(tm_sched_inst *p_tm_sched_inst,
                                    void *msg,
                                    tm_sched_fsm_event *p_event);

static bcmos_errno tm_sched_free_by_entry(tm_sched_inst *p_entry);
static void tm_sched_inst_entry_obj_init(tm_sched_inst *p_entry);
static bcmos_errno queues_list_fill(tm_sched_inst *p_tm_sched_inst,
                                         bcmbal_tm_queue_id_list_u8 *queues_list);


static bcmos_errno tm_sched_fsm_state_err(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event);
static bcmos_errno tm_sched_fsm_assigned_process_util_msg(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event);
static bcmos_errno tm_sched_fsm_deleting_process_util_msg(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event);

static bcmos_errno tm_sched_fsm_inactive_destroy(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event);

static bcmos_errno tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event);

static bcmos_errno tm_sched_fsm_assigned_destroy(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event);

static bcmos_errno tm_sched_fsm_destroy(tm_sched_inst *p_tm_sched_inst);

static bcmos_errno tm_sched_fsm_exec(tm_sched_inst *p_tm_sched_inst, tm_sched_fsm_event *p_event);

static tm_sched_inst* tm_sched_find_by_owner(bcmbal_tm_sched_owner owner);

static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_add(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id);
static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_remove(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id);

static bcmos_errno sub_scheds_list_fill(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id_list_u8 *sub_scheds_list);
/*
 * @brief The Global tm_sched fsm context data structure
 */
static tm_sched_fsm_ctx g_tm_sched_fsm_tm_sched_list_ctx;

/*
 * Macros for tm_sched ctx access
 */
#define TM_SCHED_FSM_TM_SCHED_LIST_CTX      (g_tm_sched_fsm_tm_sched_list_ctx)
#define TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR  (&g_tm_sched_fsm_tm_sched_list_ctx)


/*
 *  @brief The definition of a tm_sched FSM state processing function
 */
typedef bcmos_errno (* tm_sched_fsm_state_processor)(tm_sched_inst *, void *, tm_sched_fsm_event *);
/*
 *  @brief The tm sched FSM state processing array
 */
static tm_sched_fsm_state_processor tm_sched_states[TM_SCHED_FSM_STATE__NUM_OF][TM_SCHED_FSM_EVENT_TYPE__NUM_OF] =
{

    [TM_SCHED_FSM_STATE_NULL] =
    {
        [TM_SCHED_FSM_EVENT_TYPE_CREATE]  = tm_sched_fsm_create,
        [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG]  = tm_sched_fsm_state_err,

    },
    [TM_SCHED_FSM_STATE_INACTIVE] =
    {
        [TM_SCHED_FSM_EVENT_TYPE_CREATE]  = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_inactive_destroy,
        [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG]  = tm_sched_fsm_state_err,
    },
    [TM_SCHED_FSM_STATE_ASSIGNED] =
    {
        [TM_SCHED_FSM_EVENT_TYPE_CREATE]  = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_assigned_destroy,
        [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG]  = tm_sched_fsm_assigned_process_util_msg,
    },
	[TM_SCHED_FSM_STATE_ACTIVE] =
	{
		[TM_SCHED_FSM_EVENT_TYPE_CREATE]  = tm_sched_fsm_state_err,
		[TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_active_destroy,
		[TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
		[TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG]  = tm_sched_fsm_state_err,
	},

    [TM_SCHED_FSM_STATE_DELETING] =
    {
        [TM_SCHED_FSM_EVENT_TYPE_CREATE]  = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_DESTROY] = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_ASSIGN] = tm_sched_fsm_state_err,
        [TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG]  = tm_sched_fsm_deleting_process_util_msg,

    },

};

static char *state_name_str[] =
{
    "TM_SCHED_FSM_STATE_NULL",
    "TM_SCHED_FSM_STATE_INACTIVE",		
    "TM_SCHED_FSM_STATE_ASSIGNED",
    "TM_SCHED_FSM_STATE_ACTIVE",
    "TM_SCHED_FSM_STATE_DELETING",
};

/* Ensure that the name array size matches the associated enum */
BAL_STATIC_ASSERT(TM_SCHED_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), tm_sched_fsm_state);

static char *tm_sched_state_name_get(tm_sched_fsm_state state)
{
    if(state < TM_SCHED_FSM_STATE__LAST)
    {
        return state_name_str[state];
    }
    else
    {
        return "TM_SCHED_UNKNOWN";
    }
}

static char *event_name_str[] =
{
    "TM_SCHED_FSM_CREATE_EVENT",
    "TM_SCHED_FSM_DESTROY_EVENT",
    "TM_SCHED_FSM_ASSIGN_EVENT",
    "FLOW_FSM_UTIL_MSG_EVENT",
};

/* Ensure that the name array size matches the associated enum */
BAL_STATIC_ASSERT(TM_SCHED_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), tm_sched_fsm_event_type);

static char *tm_sched_event_name_get(tm_sched_fsm_event_type event)
{
    if(event < TM_SCHED_FSM_EVENT_TYPE__LAST)
    {
        return event_name_str[event];
    }
    else
    {
        return "TM_SCHED_EVT_UNKNOWN";
    }
}




/*****************************************************************************/
/**
 * @brief A function to initialize the tm sched FSM infrastructure.
 *
 *        NOTE: This is called once on startup and NOT for each FSM instance.
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno tm_sched_fsm_init(void)
{
    int ii;
    tm_sched_inst *new_entry;
    bcmos_errno ret = BCM_ERR_OK;

#ifdef ENABLE_LOG
    log_id_tm_sched = bcm_dev_log_id_register("TM_SCHED", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    BUG_ON(log_id_tm_sched == DEV_LOG_INVALID_ID);
#endif

    /* Initialize all of the tm_sched queues */
    TAILQ_INIT(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list);
    TAILQ_INIT(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list);

    /* Populate the free list with it's initial set of tm_scheds */
    for(ii=0; ii<TM_SCHED_ALLOCATION_BLOCK_SIZE; ii++)
    {

        new_entry = bcmos_calloc(sizeof(tm_sched_inst));

        if(NULL == new_entry)
        {
            BCM_LOG(FATAL, log_id_tm_sched,  "Failed to initialize the tm_sched free list - FATAL\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

       tm_sched_free_by_entry(new_entry);
    }

    return ret;
}

/*****************************************************************************/
/**
 * @brief A function to un-initialize the tm sched FSM infrastructure.
 *
 *        NOTE: This is called once on shutdown and NOT for each FSM instance.
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno tm_sched_fsm_finish(void)
{

    tm_sched_inst *current_entry, *p_temp_entry;

    /* Free all the entries on the active list */
    TAILQ_FOREACH_SAFE(current_entry,
                       &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
                       tm_sched_inst_next,
                       p_temp_entry)
    {
        /* Remove it from the active list */
        TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list, current_entry, tm_sched_inst_next);

        bcmos_free(current_entry);

    }

    /* Free all the entries on the free list */
    TAILQ_FOREACH_SAFE(current_entry,
                       &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list,
                       tm_sched_inst_next,
                       p_temp_entry)
    {
        /* Remove it from the active list */
        TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list, current_entry, tm_sched_inst_next);

        bcmos_free(current_entry);
    }

    return BCM_ERR_OK;
}

/*****************************************************************************/
/**
 * @brief A function to retrieve a tm_sched instance of the specified class.
 *
 * @param key            A pointer to the key of the tm_sched being referenced
 * @param search_flag    A flag specifying the type of tm_sched
 *                       instance to be retrieved
 *
 * @returns tm_sched_inst_t* A pointer to the found tm_sched instance,
 *                       or NULL if one is not found
 *****************************************************************************/
tm_sched_inst *tm_sched_inst_get(bcmbal_tm_sched_key key, tm_sched_flag search_flag)
{
    tm_sched_inst *current_entry = NULL;

    /*
     * First, check the active list if the caller has chosen to do so
     */
    if(TM_SCHED_FLAG_ACTIVE & search_flag)
    {
        TAILQ_FOREACH(current_entry,
                      &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
                      tm_sched_inst_next)
        {

            if(current_entry->req_tm_sched_info.key.id == key.id
				&& current_entry->req_tm_sched_info.key.dir == key.dir)
            {
                BCM_LOG(DEBUG, log_id_tm_sched,  "Found active tm_sched\n");
                /* The tm_sched instance pointer is in current_entry */
                break;
            }
        }
    }

    /*
     * Next, check the free list if the caller has chosen to do so
     */
    if((TM_SCHED_FLAG_FREE & search_flag) && (NULL == current_entry))
    {
        /* Now check the free list */
        if(!TAILQ_EMPTY(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list))
        {
            /* Just grab the first entry */
            current_entry = TAILQ_FIRST(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list);

            /* Remove it from the free list */
            TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list, current_entry, tm_sched_inst_next);

            /* And add it to the active list */
            TAILQ_INSERT_TAIL(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list, current_entry, tm_sched_inst_next);

            /*
             * Initialize the fsm state
             */
            current_entry->fsm_state = TM_SCHED_FSM_STATE_NULL;

            BCM_LOG(DEBUG, log_id_tm_sched,  "Using new tm_sched\n");

        }
    }

    if((TM_SCHED_FLAG_ANY & search_flag) && (NULL == current_entry))
    {
        /*A tm_sched was not found on either list */

        BCM_LOG(DEBUG, log_id_tm_sched,  "************** ERROR: no tm_sched found\n");
    }

    return current_entry;
}

static bcmos_errno bcmbal_tm_sched_validate_sched_parent(const bcmbal_tm_sched_cfg *p_tm_sched_cfg, tm_sched_inst **p_parent_tm_sched_inst)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_tm_sched_key tm_sched_key;
    tm_sched_key.dir = p_tm_sched_cfg->key.dir;
    tm_sched_key.id = p_tm_sched_cfg->data.sched_parent.sched_id;

    do
    {
        (*p_parent_tm_sched_inst) = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
        if(NULL == (*p_parent_tm_sched_inst))
        {
            BCM_LOG(ERROR, log_id_tm_sched, "Sched parent dir = %s id = %d does not exist and therefor can not be set at the tm sched parent\n",
            TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id);
            ret = BCM_ERR_NOENT;
            break;
        }

        /*check weight/priority setting based on parent sched_type*/
        if(BCMBAL_TM_SCHED_TYPE_SP == (*p_parent_tm_sched_inst)->req_tm_sched_info.data.sched_type)
        {
            if(!BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority))
            {
                BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with a priority, as its sched_parent' sched_type is sp\n");
                ret = BCM_ERR_PARM;
                break;
            }
            if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
            {
                BCM_LOG(ERROR, log_id_tm_sched, "Sched parent can not be set with a weight, as its sched_parent' sched_type is sp\n");
                ret = BCM_ERR_PARM;
                break;
            }
            if(p_tm_sched_cfg->data.sched_parent.priority >= (*p_parent_tm_sched_inst)->req_tm_sched_info.data.num_priorities)
            {
                BCM_LOG(ERROR, log_id_tm_sched,  "sched priority (%d) is higher than the allowed at parent sched (id = %d dir = %s num of priorities = %d )\n",
                        p_tm_sched_cfg->data.sched_parent.priority , tm_sched_key.id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir),
                        (*p_parent_tm_sched_inst)->req_tm_sched_info.data.num_priorities);
                
                ret = BCM_ERR_PARM;
                break;
            }
        }     
        else
            if(BCMBAL_TM_SCHED_TYPE_WFQ == (*p_parent_tm_sched_inst)->req_tm_sched_info.data.sched_type)
            {
                if(!BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
                {
                    BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with a weight, as its sched_parent' sched_type is wrr\n");
                    ret = BCM_ERR_PARM;
                    break;
                }
                if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority))
                {
                    BCM_LOG(ERROR, log_id_tm_sched, "Sched parent can not be set with a priority, as its sched_parent' sched_type is wrr \n");
                    ret = BCM_ERR_PARM;
                    break;
                }
            }
        else
            if(BCMBAL_TM_SCHED_TYPE_SP_WFQ == (*p_parent_tm_sched_inst)->req_tm_sched_info.data.sched_type)
            {
                if(BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority)
                    && BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
                {
                    BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with either weight or priority, not both. as its sched_parent' sched_type is sp_wrr\n");
                    ret = BCM_ERR_PARM;
                    break;
                }        
                if(!BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, priority)
                    && !BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_tm_sched_cfg->data.sched_parent), tm_sched_parent, weight))
                {
                    BCM_LOG(ERROR, log_id_tm_sched, "Sched parent must be set with either weight or priority, as its sched_parent' sched_type is sp_wrr\n");
                    ret = BCM_ERR_PARM;
                    break;
                }
            }
    }while(0);
	
    return ret;

}

/*****************************************************************************/
/**
 * @brief tm_sched_fsm_info_validate
 *
 * This routine is used to validate all input attributes required for a tm_sched
 * settings
 *
 * @param p_tm_sched_cfg     A pointer to a tm sched object
 *
 * @return bcmos_errno
 */
/*****************************************************************************/
static bcmos_errno tm_sched_fsm_info_validate(const bcmbal_tm_sched_cfg *p_tm_sched_cfg)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_tm_sched_owner owner = p_tm_sched_cfg->data.owner;
    bcmbal_interface_key intf_key;
    bcmbal_subscriber_terminal_key sub_term_key;
    sub_term_inst *p_sub_term_inst = NULL;
    tm_sched_inst *p_tm_sched_inst;
    bcmos_bool is_sched_type_and_level_mandatory = BCMOS_TRUE;

    do
    {
        if(!_rsc_mgr_tm_sched_id_validate(p_tm_sched_cfg->key.id))
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                   "Illegal tm sched id (reserved for auto created) \n");
            ret = BCM_ERR_PARM;
            break;
        }
        
        if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, owner))
        {
            switch(owner.type)
            {
                case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
                {
                    /*tm sched owned by agg port is  the only case sched type might be unset*/
                    is_sched_type_and_level_mandatory = BCMOS_FALSE;
					
                    if(BCMBAL_TM_SCHED_DIR_US != p_tm_sched_cfg->key.dir)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,
                               "tm sched owned by agg port must be of US direction, while tm sched id = %d is not\n", p_tm_sched_cfg->key.dir);
                        return BCM_ERR_PARM;
                    }
                    /*agg port owned tm sched can not be part of hqos, therefor can not have sched parent set*/
                    if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_parent))					
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,
                               "tm sched owned by agg port is a tsand alone and can not have sched_parent set to it");
                        return BCM_ERR_PARM;
                    }
                    /*validate all required parameters are set*/
                    if((owner.u.agg_port.intf_id == BAL_API_MAX_INTF_ID)
                    || (owner.u.agg_port.sub_term_id == BCMBAL_SUB_ID_UNKNOWN))
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,
                               "Illegal owner agg port settings intf_id = %d sub_id = %d \n",
                        owner.u.agg_port.intf_id, owner.u.agg_port.sub_term_id);
                        return BCM_ERR_PARM;
                    }
                    
                    /*validate interface is up*/
                    intf_key.intf_id = owner.u.agg_port.intf_id;
                    intf_key.intf_type = BCMBAL_INTF_TYPE_PON;
                    
                    if(bcmbal_interface_status_get(intf_key)!= BCMBAL_STATUS_UP)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,
                               "intf = %d is not UP\n",
                        intf_key.intf_id);
                        return BCM_ERR_NOT_CONNECTED;
                    }
                    
                    /*validate sub terminal exist*/
                    sub_term_key.intf_id = owner.u.agg_port.intf_id;
                    sub_term_key.sub_term_id = owner.u.agg_port.sub_term_id;
                    
                    p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE);
                    
                    if(!p_sub_term_inst)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,
                               "Failed to get subscriber terminal with intf = %d id = %u\n",
                        sub_term_key.intf_id, sub_term_key.sub_term_id);
                        return BCM_ERR_NOENT;
                    }
                }
                break;
				
                case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
                {
                    /*validate sub terminal exist*/
                    sub_term_key.intf_id = owner.u.uni.intf_id;
                    sub_term_key.sub_term_id = owner.u.uni.sub_term_id;

                    p_sub_term_inst = sub_term_inst_get(&sub_term_key, SUB_TERM_FLAG_ACTIVE);
                    
                    if(!p_sub_term_inst)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,
                               "Failed to get subscriber terminal with intf = %d id = %u\n",
                        sub_term_key.intf_id, sub_term_key.sub_term_id);
                        return BCM_ERR_NOENT;
                    }
                    
                }
                break;
                
                default:
                break;
            }
        }
		
        if(BCMOS_TRUE == is_sched_type_and_level_mandatory)
        {
            if(!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_type))
            {
                BCM_LOG(ERROR, log_id_tm_sched, "Sched type is a mandatory parameter for setting tm sched\n");
                ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
                break;
            }
            /*if sched type is sp or wrr_sp, num_of_priorities is a mandatory parameter*/
            if(BCMBAL_TM_SCHED_TYPE_SP == p_tm_sched_cfg->data.sched_type
              || BCMBAL_TM_SCHED_TYPE_SP_WFQ == p_tm_sched_cfg->data.sched_type)
            {
                if(!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, num_priorities))
                {
                    BCM_LOG(ERROR, log_id_tm_sched, "num_priorities is a mandatory parameter for setting tm sched with sched type %s\n",
                            BCMBAL_TM_SCHED_TYPE_SP == p_tm_sched_cfg->data.sched_type ? "sp" : "sp_wrr");
                    ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
                    break;
                }
            }
            if(!BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_child_type))
            {
                BCM_LOG(ERROR, log_id_tm_sched, "Sched child type is a mandatory parameter for setting tm sched\n");
                ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
                break;
            }
        }

        if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg, tm_sched, sched_parent))
        {
            if(BCM_ERR_OK == (ret = bcmbal_tm_sched_validate_sched_parent(p_tm_sched_cfg, &p_tm_sched_inst)))
            {
                if(BCM_ERR_OK != (ret = bcmbal_tm_sched_sub_scheds_list_entry_add(p_tm_sched_inst, p_tm_sched_cfg->key.id)))
                {
                    BCM_LOG(ERROR, log_id_tm_sched,	"could not set scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
                        TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_cfg->data.sched_parent.sched_id,
                        TM_SCHED_DIR_TO_STR(p_tm_sched_cfg->key.dir), p_tm_sched_cfg->key.id, bcmos_strerror(ret));
                    break;
                }              
            }
            else
            {
            
                BCM_LOG(ERROR, log_id_tm_sched,	"could not validate scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
                TM_SCHED_DIR_TO_STR(p_tm_sched_cfg->key.dir), p_tm_sched_cfg->data.sched_parent.sched_id,
                TM_SCHED_DIR_TO_STR(p_tm_sched_cfg->key.dir), p_tm_sched_cfg->key.id, bcmos_strerror(ret));
                break;
            }   
        }

    }while(0);

    return ret;

}
/*****************************************************************************/
/**
 * @brief A function called by the core worker thread to process an
 *        tm_sched object message (SET, GET, CLEAR, STATS) received
 *        from the BAL Public API.
 *
 * @param msg_payload      Pointer to a BAL message received from the
 *                         BAL Public API.
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno process_tm_sched_object(void *msg_payload)
{
    bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;	
    bcmbal_tm_sched_cfg *p_tm_sched_cfg = (bcmbal_tm_sched_cfg *)msg_payload;
    tm_sched_inst *p_tm_sched_inst = NULL;
    tm_sched_fsm_event fsm_event;
    bcmbal_tm_sched_key tm_sched_key;
    bcmbal_obj_msg_type oper_type;
    bcmbal_tm_sched_owner owner;
    uint32_t ref_count; 
    queue_entry *current_queue_entry;
    bcmbal_tm_queue_key current_queue_key;
    tm_queue_inst *current_queue_inst;
    bcmbal_interface_key intf_key;
	
    do
    {
        BUG_ON(NULL == msg_payload);
        
        BCM_LOG(DEBUG, log_id_tm_sched,  "Processing a tm sched object\n");
        
        tm_sched_key = p_tm_sched_cfg->key;
        oper_type = p_tm_sched_cfg->hdr.hdr.type;
        
        /*
        * A message pointer may be passed inside the event structure.
        */
        fsm_event.msg = msg_payload;
        
        /* SET or GET or CLEAR...? */
        switch(oper_type)
        {
            case(BCMBAL_OBJ_MSG_TYPE_SET):
            {
                BCM_LOG(DEBUG, log_id_tm_sched,  "Processing a tm sched SET REQ mgmt message\n");
                do
                {
                    if(BCMBAL_STATUS_UP != acc_term_status_get())
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,  
                            "ERROR - Access-terminal is not UP.  No further processing\n");
                        ret = BCM_ERR_STATE;
                        break;
                    }
                    
                    /*Find the specified tm_sched instance is already created */
                    p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
					
                    if(NULL != p_tm_sched_inst)
                    {
                        /* This is a fatal error condition */
                        BCM_LOG(ERROR, log_id_tm_sched,
                            "ERROR - tm sched found.  Set after create is currently not supported. No further processing\n");
                        ret = BCM_ERR_NOT_SUPPORTED;
                        break;
                    }
					
                    p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_FREE);
                    if(NULL == p_tm_sched_inst)
                    {
                        /* This is a fatal error condition */
                        BCM_LOG(ERROR, log_id_tm_sched,
                            "ERROR - tm sched not found.  No further processing\n");
                        ret = BCM_ERR_NOMEM;
                        break;
                    }

					BCM_LOG(DEBUG, log_id_tm_sched,
						"Creating a new tm sched\n");
					
                    BCMBAL_CFG_PROP_SET(p_tm_sched_cfg, tm_sched, creation_mode, BCMBAL_TM_CREATION_MODE_MANUAL);

                    /* Fill in given cfg with current tm sched instance API request data structure and validate it*/
                    bcmbal_tm_sched_object_overlay_w_src_priority(&p_tm_sched_inst->req_tm_sched_info, p_tm_sched_cfg);
					
                    /* Check if the mandatory tm sched attributes have been set, and range check where applicable */
                    if(BCM_ERR_OK != (ret = tm_sched_fsm_info_validate(p_tm_sched_cfg)))
                    {
                        BCM_LOG(ERROR, log_id_tm_sched, "tm_sched fsm validation Failed (%d)\n", ret);
						tm_sched_free_by_entry(p_tm_sched_inst);
                        break;
                    }
                    
                    
                    /* Perform the validation check(s) that the utils require */
                    if(BCM_ERR_OK != (ret = sw_util_tm_sched_validate(p_tm_sched_cfg)))
                    {
                        BCM_LOG(ERROR, log_id_tm_sched, "tm_sched switch validation Failed (%d)\n", ret);
                        tm_sched_free_by_entry(p_tm_sched_inst);
                        break;
                    }
                    
                }while(0);
                /* We respond to the BAL public API backend with a result. We always
                * send a complete msg_payload back to the API, but the data portion
                * of the object is only relevant when a GET or GET-STATS has been requested.
                */
                rsp_ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_sched);
                if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
                {
                    break;
                }
                
                /*
                * Initial checks complete.	Process the request
                */
                fsm_event.event_type = TM_SCHED_FSM_EVENT_TYPE_CREATE;
                /*
                * Run the tm sched FSM to process this event
                */
                ret = tm_sched_fsm_exec(p_tm_sched_inst, &fsm_event);       
            
            }//SET
            break;
			
            case(BCMBAL_OBJ_MSG_TYPE_GET):
            {        
                bcmbal_tm_queue_id_list_u8 queues_list = {};
                bcmbal_tm_sched_id_list_u8 sub_scheds_list = {};
                
                BCM_LOG(DEBUG, log_id_tm_sched,	"Processing a tm sched GET REQ mgmt message\n");
                
                /* Just return the tm sched data info that we have on record for tm sched instance */
                /*Find the specified tm sched  instance       */
                p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
                
                if(NULL == p_tm_sched_inst)
                {
                    BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched not found on GET\n");
                    ret = BCM_ERR_NOENT;
                }
                else
                {
                    /* Return the queues list if requested */
                    BCMBAL_CFG_PROP_CLEAR(&p_tm_sched_inst->req_tm_sched_info,
                        tm_sched,
                        queues);
						
                    /* If the user requested the list of queues for this tm sched then return the list.*/
                    if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg,
                        tm_sched, 
                        queues))
                    {
                
                        if(BCM_ERR_OK == queues_list_fill(p_tm_sched_inst, &queues_list))
                        {
                            /* NOTE: The returned list may be empty */
                            BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info,
                                tm_sched,
                                queues,
                                queues_list);
                        }
                        else
                        {
                            BCM_LOG(ERROR, log_id_tm_sched, "Error trying to fill queues list to return\n");
                            ret = BCM_ERR_INTERNAL;
                            break;    
                        }
                    }
                
                    /* Return the sub scheds list if requested */
                    BCMBAL_CFG_PROP_CLEAR(&p_tm_sched_inst->req_tm_sched_info,
                        tm_sched,
                        sub_scheds);
						
                    /* If the user requested the list of sub scheds for this tm sched then return the list.*/
                    if(BCMBAL_CFG_PROP_IS_SET(p_tm_sched_cfg,
                        tm_sched, 
                        sub_scheds))
                    {
                
                        if(BCM_ERR_OK == sub_scheds_list_fill(p_tm_sched_inst, &sub_scheds_list))
                        {
                            /* NOTE: The returned list may be empty */
                            BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info,
                                tm_sched,
                                sub_scheds,
                                sub_scheds_list);
                        }
                        else
                        {
                            BCM_LOG(ERROR, log_id_tm_sched, "Error trying to fill sub_scheds list to return\n");
                            ret = BCM_ERR_INTERNAL;
                            break;    
                        }
                    }
                /* We respond to the BAL public API backend with a result. We always 
                    * send a complete msg_payload back to the API, but the data portion 
                    * of the object is only relevant when a GET or GET-STATS has been requested.
                    */
                    
                    p_tm_sched_inst->req_tm_sched_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
                    *((bcmbal_tm_sched_cfg *)msg_payload) = p_tm_sched_inst->req_tm_sched_info;
                    
                }
                
				mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_sched);
                
                /* Free the temporary lists if they were used */
                if(queues_list.val)
                {
                    bcmos_free(queues_list.val);
                }
            }//GET
            break;
            
            case(BCMBAL_OBJ_MSG_TYPE_CLEAR):
            {
                do
                {
                    BCM_LOG(DEBUG, log_id_tm_sched,  "Processing a tm sched CLEAR REQ mgmt message\n");
                    /*Find the specified tm sched  instance       */
                    p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
                    
                    if(NULL == p_tm_sched_inst)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched not found on Clear\n");
                        ret = BCM_ERR_NOENT;
                        break;
                    }
					
                    /*user can not clear auto created sched owned by agg port*/
                    if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
                    {
                        owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
                        if(BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT == owner.type
                           && BCMBAL_TM_CREATION_MODE_AUTO == p_tm_sched_inst->req_tm_sched_info.data.creation_mode)
                        {
                            BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is auto created, therefor can not be manually deleted\n");
                            ret = BCM_ERR_PARM;
                            break;
                        }

                    /*check that a tm is not active, 
                     if that tm owned by interface, it is active if any of its queue is active.
                     if it is owned by agg port, it is active if the agg port id has ref count > 1 */
                    switch(owner.type)
                    {
                        case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
                        {
                            rsc_mgr_alloc_id_get_ref_count(owner.u.agg_port.intf_id,owner.u.agg_port.agg_port_id,&ref_count);
                            if(ref_count > 1)
                            {
                                BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is active and therefor can not be deleted (if = %d agg id = %d, ref count = %d \n",
                                    owner.u.agg_port.intf_id,owner.u.agg_port.agg_port_id, ref_count);
                                ret = BCM_ERR_PARM;
                            }
                            break;
                        }//BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT
						
                        case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
                        {
                            TAILQ_FOREACH(current_queue_entry,
                                &p_tm_sched_inst->queues_list,
                                next)
                            {
                                if(NULL != current_queue_entry)
                                {
                                    current_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
                                    current_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
                                    current_queue_key.id = current_queue_entry->queue_id;
                                    current_queue_inst = tm_queue_inst_get(current_queue_key, TM_QUEUE_FLAG_ACTIVE);
                                    if(NULL == current_queue_inst)
                                    {
                                        ret = BCM_ERR_INTERNAL;
                                        break;
                                    }
                                    if(TM_QUEUE_FSM_STATE_IN_USE == current_queue_inst->fsm_state)
                                    {
                                        BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is active (has an in use queue) and therefor can not be deleted (queue id = %d \n",
                                                                        current_queue_key.id);
                                        ret = BCM_ERR_PARM;
                                        break;        
                                    }
                                }                    
                            }//TAILQ_FOREACH
                            if(BCM_ERR_OK == ret)
                            {
                                /*TM_SCHEDs  (either auto or manually created) with owner interface may only be deleted there are no attached TM_QUEUEs, and only when the associated interface is in the ADMIN-DOWN state*/
     							intf_key.intf_type = owner.u.interface.intf_type;
	    						intf_key.intf_id = owner.u.interface.intf_id;
                                if(BCMBAL_STATUS_DOWN != bcmbal_interface_status_get(intf_key))
                                {
                                    BCM_LOG(ERROR, log_id_tm_sched, "Specified tm_sched is owned by interface that is not admin down, and can be removed only when the associated interface is in the ADMIN-DOWN state\n");
                                    ret = BCM_ERR_PARM;
                                    break; 	   
	                            }
                            }
                        }//BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE
                        break;
			            
                        default:
                        break;
                    }//switch owner.type
				}//owner is set
                /*generate destroy event*/
                if(BCM_ERR_OK == ret)
                {
                    fsm_event.event_type = TM_SCHED_FSM_EVENT_TYPE_DESTROY;
                    fsm_event.msg = msg_payload;
                    ret = tm_sched_fsm_exec(p_tm_sched_inst,&fsm_event);
                }
            }while(0);
                
                mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_tm_sched);			                
            }//CLEAR
            break;
            
            default:
            {
                BCM_LOG(ERROR, log_id_tm_sched,  "Unsupported operation on tm sched object (%d)\n",
                oper_type);
                ret = BCM_ERR_NOT_SUPPORTED;         
            }
        }
    }while(0);
    BCM_LOG(DEBUG, log_id_tm_sched, "%s returns\n", __FUNCTION__);
	
    return ret;
}


static void tm_sched_inst_entry_obj_init(tm_sched_inst *p_entry)
{
    /* The actual key content is irrelevant for free tm_scheds */
    bcmbal_tm_sched_key key = { .id = 0, .dir = BCMBAL_TM_SCHED_DIR_DS};

    BCMBAL_CFG_INIT(&p_entry->current_tm_sched_info,
                    tm_sched,
                    key);
    p_entry->fsm_state = TM_SCHED_FSM_STATE_NULL;	
    /* Initialize the queues and suc scheds lists */
    p_entry->num_queues_on_node = 0;
    TAILQ_INIT(&p_entry->queues_list);
     
    p_entry->num_sub_scheds_on_node = 0;
    TAILQ_INIT(&p_entry->sub_scheds_list);

    BCMBAL_OBJ_IN_PROGRESS_SET(&(p_entry->current_tm_sched_info), BCMOS_FALSE);
}
/*****************************************************************************/
/**
 * @brief A function to free a tm_sched instance specified by a the supplied
 *        entry pointer.
 *
 * @param p_entry A pointer to the entry to be freed
 *
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno tm_sched_free_by_entry(tm_sched_inst *p_entry)
{
    bcmos_errno ret = BCM_ERR_OK;
    tm_sched_inst *current_entry;
    tm_sched_inst *p_temp_entry;
    /*
     * First, check the active list (an active tm_sched can be in the adding or removing state)
     */
    TAILQ_FOREACH_SAFE(current_entry,
                       &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
                       tm_sched_inst_next,
                       p_temp_entry)
    {
        if(current_entry == p_entry)
        {
           /* Remove it from the active list */
            TAILQ_REMOVE(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list, current_entry, tm_sched_inst_next);
            break;
        }
    }
    tm_sched_inst_entry_obj_init(p_entry);

    /* And add it to the free list */
    TAILQ_INSERT_TAIL(&TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->free_tm_sched_list, p_entry, tm_sched_inst_next);

    return ret;
}

/*****************************************************************************/
/**
 * @brief The tm sched FSM state processing executive function
 *
 * @param p_tm_sched_inst  Pointer to a tm_sched instance
 * @param p_event      Pointer to a tm_sched event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno tm_sched_fsm_exec(tm_sched_inst *p_tm_sched_inst, tm_sched_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;
    tm_sched_fsm_state pre_state;
    tm_sched_fsm_state_processor tm_sched_state_processor;

    /* Parameter checks */
    BUG_ON(NULL == p_tm_sched_inst);
    BUG_ON(NULL == p_event);

    /* Record the present state for debug printing
     */
    pre_state = p_tm_sched_inst->fsm_state;

    /*
     * Get the state processing function
     */
    tm_sched_state_processor = tm_sched_states[p_tm_sched_inst->fsm_state][p_event->event_type];

    /*
     * If there's a state processing function for this event and state, execute it.
     * Otherwise, process a generic error.
     */
    if(tm_sched_state_processor)
    {
        ret = tm_sched_state_processor(p_tm_sched_inst, p_event->msg, p_event);
    } 
	else
    {
        tm_sched_fsm_state_err(p_tm_sched_inst, p_event->msg, p_event);
    }

    if(BCM_ERR_OK != ret)
    {
        BCM_LOG(ERROR, log_id_tm_sched, "*** Error detected during state processing\n");
        p_tm_sched_inst->fsm_state = pre_state;
    }

    BCM_LOG(DEBUG, log_id_tm_sched,  "*** Event %s, State: %s --> %s\n\n",
            tm_sched_event_name_get(p_event->event_type),
            tm_sched_state_name_get(pre_state),
            tm_sched_state_name_get(p_tm_sched_inst->fsm_state));

    return ret;
}



/*****************************************************************************/
/**
 * @brief The tm sched FSM function which is executed when an error
 *        is encountered during FSM processing.
 *
 * @param p_tm_sched_inst     Pointer to a tm_sched instance
 * @param msg              Pointer to a BAL message received from one of
 *                         the BAL apps.
 * @param p_event          Pointer to a tm_sched event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno tm_sched_fsm_state_err(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_INVALID_OP;

    BCM_LOG(DEBUG, log_id_tm_sched,
            "Error encountered processing TM_SCHED FSM"
            " - BAD EVENT ()\n");

    return ret;
}

/*****************************************************************************/
/**
 * @brief A function to process a tm sched object event received
 *        from one of the BAL apps.
 *
 * @param msg_payload  A pointer to the util message
 *                         
 * @returns bcmos_errno 
 *****************************************************************************/
bcmos_errno process_tm_sched_util_msg(void *msg_payload)
{


    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_msg_type type;
    bcmbal_tm_sched_key key;
	tm_sched_inst *p_tm_sched_inst;
    tm_sched_fsm_event tm_sched_event;


    BUG_ON(NULL == msg_payload);
    do
    {
        type = bcmbal_type_minor_get(msg_payload);	
    
	    BCM_LOG(DEBUG, log_id_tm_sched,
                "Processing a tm sched %s util message from %s\n",
                bcmbal_msg_t_str[type],
                subsystem_str[bcmbal_sender_get(msg_payload)]);
    
        if(BAL_MSG_TYPE_IND == type)
    	{
	    
        /* recover the key from the message */
        key = ((bal_util_msg_ind *)msg_payload)->obj_key.tm_sched_key;
    
	    
    	/*
	     * Get the sub_term instance that's being referenced
    	 */
	    p_tm_sched_inst = tm_sched_inst_get(key, TM_SCHED_FLAG_ACTIVE);
    
	    if(NULL == p_tm_sched_inst)
    	{  
		    BCM_LOG(ERROR, log_id_tm_sched, 
				    "invalid tm sched (dir %s id %d) found while processing a util message type %s from %s\n",
    				TM_SCHED_DIR_TO_STR(key.dir),
				    key.id,
    				bcmbal_msg_t_str[type],
				    subsystem_str[bcmbal_sender_get(msg_payload)]);
		    ret = BCM_ERR_INTERNAL;
    		break;
	    }
    	tm_sched_event.msg = msg_payload;	
	    
		    tm_sched_event.event_type = TM_SCHED_FSM_EVENT_TYPE_UTIL_MSG;
    		
                BCM_LOG(DEBUG, log_id_tm_sched, "p_tm_sched_inst->fsm_state=%d, tm_sched_event.event_type = %d\n",
                         p_tm_sched_inst->fsm_state,  tm_sched_event.event_type);
		            /*Run the tm sched FSM to process this event */
            if(BCM_ERR_OK == ret)
            {
                ret = tm_sched_fsm_exec(p_tm_sched_inst, &tm_sched_event);
            }
	    }
    	
	    else
    	{
		    ret = BCM_ERR_NOT_SUPPORTED;
    		BCM_LOG(ERROR, log_id_tm_sched, 
				    "Unknown message type received from the APP (not one of RSP:ACK:IND:AUTO_IND) (type:%d)\n",
    				type);
	    }
    }while(0);	
    return ret;
}

/*****************************************************************************/
/**
 * @brief The tm sched  FSM state processing for a tm sched create command received
 *        from the BAL Public API.
 *
 * @param p_tm_sched_inst      Pointer to a tm sched instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to a tm sched event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno tm_sched_fsm_create(tm_sched_inst *p_tm_sched_inst,
                                    void *msg,
                                    tm_sched_fsm_event *p_event)
{

    bcmos_errno ret = BCM_ERR_OK;
    p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_INACTIVE;

    if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched,owner))
    {
        ret = bcmbal_tm_sched_set_owner(p_tm_sched_inst);
    }

    return ret;
}

bcmos_errno bcmbal_tm_sched_set_owner(tm_sched_inst *p_tm_sched_inst)
{
    bcmos_errno ret = BCM_ERR_OK;
	bcmbal_tm_sched_owner owner;
    bcmbal_tm_queue_key tm_queue_key; 	
    bcmbal_tm_sched_key tm_sched_key = p_tm_sched_inst->req_tm_sched_info.key;
    queue_entry *current_queue_entry;


    BUG_ON(NULL == p_tm_sched_inst);
    do
    {
        if(	BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched,owner))
        {
            p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_ASSIGNED;
            owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
            switch(owner.type)
            {    
                case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
                case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
                case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
                {
                    /*no need to validate owner attributes as these are read only and set by VALID internal objects*/
                    if(BCM_ERR_OK != (ret = sw_util_tm_sched_set(p_tm_sched_inst)))
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,  "error %s detected by switch util while adding tm sched\n", bcmos_strerror(ret));
                        break;
                    }
                    /* The hardware has properly accepted the object info, so the request object becomes  the current state. */
                    bcmbal_tm_sched_object_overlay_w_src_priority(&p_tm_sched_inst->current_tm_sched_info,
                                                                 &p_tm_sched_inst->req_tm_sched_info);
                    p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_ACTIVE;
                    /*configure all assigned queues*/
                    
                    TAILQ_FOREACH(current_queue_entry,
                        &p_tm_sched_inst->queues_list,
                        next)
                    {
                        tm_queue_key.id = current_queue_entry->queue_id;
                        tm_queue_key.sched_id = tm_sched_key.id;
                        tm_queue_key.sched_dir = tm_sched_key.dir;
                        if(BCM_ERR_OK != (ret = bcmbal_tm_queue_set_owner(tm_queue_key)))
                        {
                            BCM_LOG(ERROR, log_id_tm_sched, "Could not set queue sched id = %d sched dir = %s queue id = %d of the tm sched (%s)\n", 
                                    tm_queue_key.sched_id, TM_SCHED_DIR_TO_STR(tm_queue_key.sched_dir), tm_queue_key.id, bcmos_strerror(ret));
                            break;
                        }
                    }
                    BCMBAL_OBJ_IN_PROGRESS_SET(&(p_tm_sched_inst->current_tm_sched_info), BCMOS_FALSE);
                    p_tm_sched_inst->current_tm_sched_info.hdr.hdr.status = ret;
                    
                }
                break;
			
                case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
                {
                    bcmbal_interface_key intf_key = {.intf_type = BCMBAL_INTF_TYPE_PON, .intf_id = owner.u.agg_port.intf_id};
                    bcmbal_subscriber_terminal_key sub_key = {.sub_term_id = owner.u.agg_port.sub_term_id, .intf_id = intf_key.intf_id};
                    /*for agg port, should validate intf and sub term validity*/
                    if(NULL == sub_term_inst_get(&sub_key, SUB_TERM_FLAG_ACTIVE))
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,	"Can not set an agg port for onu (if-%d id-%d) which does not exist\n", intf_key.intf_id, sub_key.sub_term_id);
                        ret = BCM_ERR_PARM;
                        break;
                    }
                    
                    BCM_LOG(DEBUG, log_id_tm_sched,	"Getting a new ALLOC ID from resource manager\n");	
                    
                    owner.u.agg_port.agg_port_id = 0; /* 0 is a magic number telling the resource manager that it should provide the initial allocation of the ALLOC ID */
                    ret = rsc_mgr_alloc_id_alloc(intf_key.intf_id, &owner.u.agg_port.agg_port_id, 1, NULL);
                    
                    if(BCM_ERR_OK != ret)
                    {
                        /* An error has occurred trying to get mandatory data */
                        BCM_LOG(ERROR, log_id_tm_sched,	"Failed to get ALLOC ID from resource manager\n");
                        ret = BCM_ERR_NORES;
                        break;		
                    }
					/*set the agg port id into the inst*/
					BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner, owner);
					
                    ret = mac_util_agg_port_set(p_tm_sched_inst, BAL_UTIL_OPER_AGG_PORT_ADD);	
                    if(BCM_ERR_OK != ret)
                    {
                        /* An error has occurred trying to configure mac*/
                        BCM_LOG(ERROR, log_id_tm_sched,	"Failed to configure ALLOC ID at mac (%s)\n",bcmos_strerror(ret));
                        break;		
                    }
                }
                break;
            
                case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
                default:
                    BCM_LOG(ERROR, log_id_tm_sched, "nothing to do with owner type %d \n", p_tm_sched_inst->current_tm_sched_info.data.owner.type);
                    return BCM_ERR_PARM;
                break;
            }
        }
    }while(0);

    return ret;
}


bcmos_errno bcmbal_tm_sched_unset_owner(tm_sched_inst *p_tm_sched_inst)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_tm_sched_owner *owner;
    bcmbal_tm_queue_key tm_queue_key;	
    queue_entry *current_queue_entry;
	tm_sched_inst *p_parent_tm_sched_inst;
	
    BUG_ON(NULL == p_tm_sched_inst);

    tm_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
    tm_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;

    do
    {
        if( BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
        {
            owner = &(p_tm_sched_inst->req_tm_sched_info.data.owner);
            switch(owner->type)
            {	 
                case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
                {
                    /*remove all assigned queues*/
                    TAILQ_FOREACH(current_queue_entry,
                        &p_tm_sched_inst->queues_list,
                        next)
                    {
                        tm_queue_key.id = current_queue_entry->queue_id;
                        if(BCM_ERR_OK != (ret = bcmbal_tm_queue_unset_owner(tm_queue_key)))
                        {
                            BCM_LOG(ERROR, log_id_tm_sched,	"Could not unset queue sched id = %d sched dir = %s queue id = %d of the tm sched (%s) \n", 
                                tm_queue_key.sched_id, TM_SCHED_DIR_TO_STR(tm_queue_key.sched_dir), tm_queue_key.id, bcmos_strerror(ret));                        
                            break;
                        }
                    }
                    /*unset from parent scheduler*/
                    if(BCMBAL_CFG_PROP_IS_SET(&(p_tm_sched_inst->req_tm_sched_info), tm_sched, sched_parent))					
                    {
                        if(BCM_ERR_OK == (ret = bcmbal_tm_sched_validate_sched_parent(&(p_tm_sched_inst->req_tm_sched_info), &p_parent_tm_sched_inst)))
                        {
                            if(BCM_ERR_OK == (ret = bcmbal_tm_sched_sub_scheds_list_entry_remove(p_parent_tm_sched_inst, p_tm_sched_inst->req_tm_sched_info.key.id)))
                            {
                                BCM_LOG(ERROR, log_id_tm_sched,	"could not remove scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
                                        TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.data.sched_parent.sched_id,
                                        TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.key.id, bcmos_strerror(ret));
                            }
                        }
                        else
                        {
                            BCM_LOG(ERROR, log_id_tm_sched,	"could not validate scheduler dir = %s id = %d as parent of sched dir = %s id = %d (err= %s)\n",
                                    TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.data.sched_parent.sched_id,
                                    TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.key.id, bcmos_strerror(ret));
                        }
                    }
					
                    /*no need to validate owner attributes as these are read only and set by VALID internal objects*/
                    if(BCM_ERR_OK != (ret = sw_util_tm_sched_clear(p_tm_sched_inst)))
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,	"error %s detected by switch util while clearing tm sched\n", bcmos_strerror(ret));
                        break;
                    }
                    p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_INACTIVE;
                
                }
                break;

                case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
                case BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM:
                case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
                case BCMBAL_TM_SCHED_OWNER_TYPE_VIRTUAL:
                default:
				{
                    BCM_LOG(ERROR, log_id_tm_sched, "nothing to do with unsetting owner type %d \n", 
                           p_tm_sched_inst->current_tm_sched_info.data.owner.type);
                    ret = BCM_ERR_PARM;
				}
                break;
            }
        }
    }while(0);
    return ret;

}

/*for the auto create, only key dir is set, id will be allocated from rsc mgr*/
bcmos_errno bcmbal_tm_sched_auto_create(bcmbal_tm_sched_cfg cfg, tm_sched_inst **p_tm_sched_inst)
{
    bcmos_errno ret = BCM_ERR_OK;
    do
    {
        cfg.key.id = 0;  /* 0 is a magic number telling the resource manager that it should provide the initial allocation of the  tm sched id*/
        if(BCM_ERR_OK != (ret = _rsc_mgr_tm_sched_auto_id_alloc(&cfg.key.id)))
        {    
            BCM_LOG(ERROR, log_id_tm_sched,"Could not allocate a tm sched auto id \n");
            break;
        }
        *p_tm_sched_inst = tm_sched_inst_get(cfg.key, TM_SCHED_FLAG_FREE);
        if(NULL == p_tm_sched_inst)
        {
            /* This is a fatal error condition */
            BCM_LOG(ERROR, log_id_tm_sched,
                "ERROR - could not allocate tm sched No further processing\n");
            ret = BCM_ERR_NOMEM;
            break;
        }
        BCM_LOG(DEBUG, log_id_tm_sched,
            "\n Tm Sched id %d dir %s was created \n", cfg.key.id, TM_SCHED_DIR_TO_STR(cfg.key.dir));
        
        (*p_tm_sched_inst)->req_tm_sched_info = cfg;
        ret = tm_sched_fsm_create(*p_tm_sched_inst, NULL,NULL);	
    }while(0);
    return ret;
}

static bcmos_errno bcmbal_tm_sched_queues_list_entry_add(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_queue_key queue_key)
{
    bcmos_errno ret = BCM_ERR_OK;
    queue_entry *current_entry;

    do
    {
        /* Check if the id is already on the list before adding it */
        TAILQ_FOREACH(current_entry,
                      &p_tm_sched_inst->queues_list,
                      next)
        {
            if(current_entry->queue_id == queue_key.id)
            {
                return BCM_ERR_ALREADY;
            }
        }

        /* Get a new entry and configure it */
        current_entry = bcmos_calloc(sizeof(queue_entry));

        if(NULL == current_entry)
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                    "No memory available to add queue\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

        current_entry->queue_id  = queue_key.id;

        BCM_LOG(DEBUG, log_id_tm_sched,
                "adding queue id %u to tm sched %u\n", queue_key.id, p_tm_sched_inst->req_tm_sched_info.key.id);

        /* Save the entry on the list of queues ids on this sched*/
        TAILQ_INSERT_TAIL(&p_tm_sched_inst->queues_list,
                          current_entry, next);
        (p_tm_sched_inst->num_queues_on_node)++;
    } while(0);
    return ret;
}

static bcmos_errno bcmbal_tm_sched_queues_list_entry_remove(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_queue_key queue_key)
{
    bcmos_errno ret = BCM_ERR_NOENT;
    queue_entry *current_entry, *p_temp_entry;

    do
    {

        /* Check if the id is on the list */
        TAILQ_FOREACH_SAFE(current_entry,
                           &p_tm_sched_inst->queues_list,
                           next,
                           p_temp_entry)
        {
            if(current_entry->queue_id == queue_key.id)
            {
                /* Remove it from the list of queues ids on this sched*/
                TAILQ_REMOVE(&p_tm_sched_inst->queues_list,
                             current_entry, next);

                bcmos_free(current_entry);

                (p_tm_sched_inst->num_queues_on_node)--;
                ret = BCM_ERR_OK;
                break;

            }
        }
    } while(0);

    return ret;
}

static bcmos_errno queues_list_fill(tm_sched_inst *p_tm_sched_inst,
                                         bcmbal_tm_queue_id_list_u8 *queues_list)
{
    bcmos_errno ret = BCM_ERR_OK;
    queue_entry *current_entry = NULL;
    int ii = 0;

    do
    {
     
        /* Traverse the list of queues recorded and fill in the list to be returned */
        queues_list->len = p_tm_sched_inst->num_queues_on_node;
        queues_list->val = bcmos_calloc(sizeof(bcmbal_tm_queue_id) * queues_list->len);

        if(NULL == queues_list->val)
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                    "No memory available\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

       TAILQ_FOREACH(current_entry,
                      &p_tm_sched_inst->queues_list,
                      next)
        {
            BCM_LOG(DEBUG, log_id_tm_sched,
                    "adding queue %d to response at array location %d\n",
                    current_entry->queue_id,
                    ii);
            queues_list->val[ii++] = current_entry->queue_id;
        }
    } while(0);
    return ret;
}

static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_add(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id)
{
    bcmos_errno ret = BCM_ERR_OK;
    sub_sched_entry *current_entry;

	BUG_ON(NULL == p_tm_sched_inst);

    do
    {
        /* Check if the id is already on the list before adding it */
        TAILQ_FOREACH(current_entry,
                      &p_tm_sched_inst->sub_scheds_list,
                      next)
        {
            if(current_entry->sched_id == sched_id)
            {
                return BCM_ERR_ALREADY;
            }
        }

        /* Get a new entry and configure it */
        current_entry = bcmos_calloc(sizeof(sub_sched_entry));

        if(NULL == current_entry)
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                    "No memory available to add sub sched\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

        current_entry->sched_id = sched_id;

        BCM_LOG(DEBUG, log_id_tm_sched,
                "adding sub sched id %u to tm sched dir = %s id = %u\n", 
                sched_id, TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir), p_tm_sched_inst->req_tm_sched_info.key.id);

        /* Save the entry on the list of sub_scheds on that tm sched */
        TAILQ_INSERT_TAIL(&p_tm_sched_inst->sub_scheds_list,
                          current_entry, next);
        (p_tm_sched_inst->num_sub_scheds_on_node)++;
		
    } while(0);
    return ret;
}

static bcmos_errno bcmbal_tm_sched_sub_scheds_list_entry_remove(tm_sched_inst *p_tm_sched_inst, bcmbal_tm_sched_id sched_id)
{
    bcmos_errno ret = BCM_ERR_NOENT;
    sub_sched_entry *current_entry, *p_temp_entry;

    do
    {

        /* Check if the id is on the list */
        TAILQ_FOREACH_SAFE(current_entry,
                           &p_tm_sched_inst->sub_scheds_list,
                           next,
                           p_temp_entry)
        {
            if(current_entry->sched_id == sched_id)
            {
                /* Remove it from the list of sub_scheds ids on this sched*/
                TAILQ_REMOVE(&p_tm_sched_inst->sub_scheds_list,
                             current_entry, next);

                bcmos_free(current_entry);

                (p_tm_sched_inst->num_sub_scheds_on_node)--;
                ret = BCM_ERR_OK;
                break;

            }
        }
    } while(0);

    return ret;
}

static bcmos_errno sub_scheds_list_fill(tm_sched_inst *p_tm_sched_inst,
                                         bcmbal_tm_sched_id_list_u8 *sub_scheds_list)
{
    bcmos_errno ret = BCM_ERR_OK;
    sub_sched_entry *current_entry = NULL;
    int ii = 0;

    do
    {
     
        /* Traverse the list of sub_scheds_ids recorded and fill in the list to be returned */
        sub_scheds_list->len = p_tm_sched_inst->num_sub_scheds_on_node;
        sub_scheds_list->val = bcmos_calloc(sizeof(bcmbal_tm_sched_id) * sub_scheds_list->len);

        if(NULL == sub_scheds_list->val)
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                    "No memory available\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

       TAILQ_FOREACH(current_entry,
                      &p_tm_sched_inst->sub_scheds_list,
                      next)
        {
            BCM_LOG(DEBUG, log_id_tm_sched,
                    "adding sub sched %d to response at array location %d\n",
                    current_entry->sched_id,
                    ii);
            sub_scheds_list->val[ii++] = current_entry->sched_id;
        }

    } while(0);

    return ret;
}

bcmos_errno bcmbal_tm_sched_set_queue(tm_queue_inst *p_tm_queue_inst)
{
	bcmos_errno  ret = BCM_ERR_OK;
	tm_sched_inst *p_tm_sched_inst = NULL;
	bcmbal_tm_sched_key tm_sched_key;
	BUG_ON(NULL == p_tm_queue_inst);
	do
    {
        tm_sched_key.id = p_tm_queue_inst->api_req_tm_queue_info.key.sched_id;
        tm_sched_key.dir= p_tm_queue_inst->api_req_tm_queue_info.key.sched_dir;
        p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
		
        if(NULL == p_tm_sched_inst)
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                    "ERROR - could not find an active tm sched (dir = %s id = %d) to attach the queue (id = %d)\n",
                    TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id,p_tm_queue_inst->api_req_tm_queue_info.key.id);
            ret = BCM_ERR_NOENT;
            break;
        }
        ret = bcmbal_tm_sched_queues_list_entry_add(p_tm_sched_inst, p_tm_queue_inst->api_req_tm_queue_info.key);
        if(BCM_ERR_OK != ret)
       	{
            BCM_LOG(ERROR, log_id_tm_sched,
                    "ERROR - could not add the queue entry to the sched\n");
            break;
        }
        if(TM_SCHED_FSM_STATE_ACTIVE == p_tm_sched_inst->fsm_state)
        {
            if(BCM_ERR_OK != (ret = bcmbal_tm_queue_activate(p_tm_queue_inst)))
            {
                BCM_LOG(ERROR, log_id_tm_sched,
                        "ERROR - could not activate the newly added queue \n");
                break;
            }
        }
    }while(0);
    return ret;
}

bcmos_errno bcmbal_tm_sched_remove_queue(tm_queue_inst *p_tm_queue_inst)
{
    bcmos_errno  ret = BCM_ERR_OK;
    tm_sched_inst *p_tm_sched_inst = NULL;
    bcmbal_tm_sched_key tm_sched_key;
    BUG_ON(NULL == p_tm_queue_inst);
    do
    {
        tm_sched_key.id = p_tm_queue_inst->api_req_tm_queue_info.key.sched_id;
        tm_sched_key.dir= p_tm_queue_inst->api_req_tm_queue_info.key.sched_dir;
        p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
        
        if(NULL == p_tm_sched_inst)
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                    "ERROR - could not find an active tm sched (dir = %s id = %d) to attach the queue (id = %d)\n",
                    TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id,p_tm_queue_inst->api_req_tm_queue_info.key.id);
            ret = BCM_ERR_NOENT;
            break;
        }
        if(BCM_ERR_OK != (ret = bcmbal_tm_sched_queues_list_entry_remove(p_tm_sched_inst, p_tm_queue_inst->api_req_tm_queue_info.key)))
        {
            BCM_LOG(ERROR, log_id_tm_sched,
                "ERROR - could not remove the queue entry from the sched\n");
            break;
        }
    
    }while(0);
    return ret;
}

/*tm_sched_find_by_owner - currently might be called for agg port and uni port only*/
static tm_sched_inst* tm_sched_find_by_owner(bcmbal_tm_sched_owner owner)
{
    tm_sched_inst *current_entry = NULL;
    
    TAILQ_FOREACH(current_entry,
        &TM_SCHED_FSM_TM_SCHED_LIST_CTX_PTR->active_tm_sched_list,
        tm_sched_inst_next)
    {    
        if(BCMBAL_CFG_PROP_IS_SET(&current_entry->req_tm_sched_info, tm_sched,owner))
        {
            switch(current_entry->req_tm_sched_info.data.owner.type)
            {
                case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
                {
                    if((owner.u.agg_port.intf_id == current_entry->req_tm_sched_info.data.owner.u.agg_port.intf_id)
                        && (owner.u.agg_port.agg_port_id == current_entry->req_tm_sched_info.data.owner.u.agg_port.agg_port_id))
                    {            
                        BCM_LOG(DEBUG, log_id_tm_sched,  "Found active tm_sched dir = us id= %d for agg_port_id %d intf_id %d\n",
                            current_entry->req_tm_sched_info.key.id, owner.u.agg_port.agg_port_id, owner.u.agg_port.intf_id);
				        return current_entry;
                    }
                }
                break;
                
        		case BCMBAL_TM_SCHED_OWNER_TYPE_UNI:
                {
                    if((owner.u.uni.intf_id == current_entry->req_tm_sched_info.data.owner.u.uni.intf_id)
                        && (owner.u.uni.sub_term_id == current_entry->req_tm_sched_info.data.owner.u.uni.sub_term_id)
                        && (owner.u.uni.idx == current_entry->req_tm_sched_info.data.owner.u.uni.idx))
                    {    
                        BCM_LOG(DEBUG, log_id_tm_sched, "Found active tm_sched id = %d for uni intf_id = %d sub_id = %d uni_id = %d\n",
                            current_entry->req_tm_sched_info.key.id, owner.u.uni.intf_id, owner.u.uni.sub_term_id, owner.u.uni.idx);
                        return current_entry;
                    }				
                }
        		
                default:
                break;
            }
        }
    }
    return current_entry;
}

tm_sched_inst* tm_sched_find_agg_port_node(uint8_t intf_id, bcmbal_aggregation_port_id agg_port_id)
{
    bcmbal_tm_sched_owner owner;
	owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
	owner.u.agg_port.intf_id = intf_id;
	owner.u.agg_port.agg_port_id = agg_port_id;

	return tm_sched_find_by_owner(owner);
}



static bcmos_errno tm_sched_fsm_assigned_process_util_msg(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
{

    bcmos_errno ret;
    bal_util_msg_ind *ind_msg;

    /* Parameter checks */
    BUG_ON(NULL == p_tm_sched_inst);
    BUG_ON(NULL == msg);
    BUG_ON(NULL == p_event);

    ind_msg = (bal_util_msg_ind *)msg;
	
    BCM_LOG(DEBUG, log_id_tm_sched, 
            " Received a IND message from BAL UTIL (%s) during %s state\n",
             subsystem_str[bcmbal_sender_get(msg)],
      tm_sched_state_name_get(p_tm_sched_inst->fsm_state));

    /* Handle response */
    ret = ind_msg->status;
    
    if(BCM_ERR_OK == ret)
    {
        p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_ACTIVE;
        bcmbal_tm_sched_object_overlay_w_src_priority(&p_tm_sched_inst->current_tm_sched_info,
									  &p_tm_sched_inst->req_tm_sched_info);
   	}
    else
    {
        /* Error */
        BCM_LOG(ERROR, log_id_tm_sched, 
                "Failed in state %s;%s\n",
                tm_sched_state_name_get(p_tm_sched_inst->fsm_state),
                bcmos_strerror(ret));
    }

    mgmt_msg_send_balapi_ind(ret,
                             (void *)&p_tm_sched_inst->current_tm_sched_info.hdr,
                             log_id_tm_sched);

    return ret;
}

/*currently handling util msg of alloc id setting complete only for agg port tm sched only*/
static bcmos_errno tm_sched_fsm_deleting_process_util_msg(tm_sched_inst *p_tm_sched_inst,
                                      void *msg,
                                      tm_sched_fsm_event *p_event)
{
    bcmos_errno ret;
    bal_util_msg_ind *ind_msg;
    
    /* Parameter checks */
    BUG_ON(NULL == p_tm_sched_inst);
    BUG_ON(NULL == msg);
    BUG_ON(NULL == p_event);
    
    do
    {
        ind_msg = (bal_util_msg_ind *)msg;
		
        BCM_LOG(DEBUG, log_id_tm_sched, 
                    " Received a IND message from BAL UTIL (%s) during %s state\n",
                    subsystem_str[bcmbal_sender_get(msg)],
                    tm_sched_state_name_get(p_tm_sched_inst->fsm_state));
        
        /* Handle response */
        ret = ind_msg->status;
        
        if(BCM_ERR_OK == ret)
        {
             ret = tm_sched_fsm_destroy(p_tm_sched_inst);   
        }
        else
        {
            /* Error */
            BCM_LOG(ERROR, log_id_tm_sched, 
                    "Failed in state %s;%s\n",
                    tm_sched_state_name_get(p_tm_sched_inst->fsm_state),
                    bcmos_strerror(ret));
        }    
    }while(0);		
    return ret;
}

static bcmos_errno tm_sched_fsm_destroy(tm_sched_inst *p_tm_sched_inst)
{
    queue_entry *current_entry = NULL;
    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_tm_queue_key tm_queue_key; 	
    tm_queue_inst *p_tm_queue_inst;
    int i=0;	
    bcmbal_tm_sched_owner owner;
	
    do
    {
        switch(p_tm_sched_inst->req_tm_sched_info.data.owner.type)
        {
            case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
            {
                p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_NULL;
                owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
            
                ret = rsc_mgr_alloc_id_free(owner.u.agg_port.intf_id, owner.u.agg_port.agg_port_id, NULL);
                if(BCM_ERR_OK != ret)
                {
                    BCM_LOG(ERROR, log_id_tm_sched, 
                            "Failed to free alloc id if=%d id=%d at resource manager", 
                            owner.u.agg_port.intf_id, owner.u.agg_port.agg_port_id);
                    break;
                }
                ret = tm_sched_fsm_destroy(p_tm_sched_inst);
                if(BCM_ERR_OK != ret)
                {
                    BCM_LOG(ERROR, log_id_tm_sched, 
                            "Failed to free auto created tm sched id,  id=%d at resource manager", 
                            p_tm_sched_inst->req_tm_sched_info.key.id);
                    break;
                }
                break;
            }
            case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
            {            
                tm_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
                tm_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
            
			/*delete all attached queues*/
                TAILQ_FOREACH(current_entry,
                    &p_tm_sched_inst->queues_list,
                    next)
                {
                    
                    BCM_LOG(DEBUG, log_id_tm_sched,
                        "deleting queue %u (location %u)\n",
                        current_entry->queue_id,
                        i);
                    tm_queue_key.id = current_entry->queue_id;
                    
                    p_tm_queue_inst = tm_queue_inst_get(tm_queue_key, TM_QUEUE_FLAG_ACTIVE);
                    if(NULL == p_tm_queue_inst)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,"ERROR - tm queue not found.  No further processing\n");
                        ret = BCM_ERR_NOENT;
                        break;
                    }
                
                    ret = bcmbal_tm_queue_destroy(p_tm_queue_inst, BCMOS_FALSE);
                    if(BCM_ERR_OK != ret)
                    {
                        BCM_LOG(ERROR, log_id_tm_sched,"ERROR - could not destroy tm queue %d  .No further processing\n",
							    tm_queue_key.id);
                        ret = BCM_ERR_NOENT;
                        break;
                    }
                
                    bcmos_free(current_entry); 
                    i++;                    
                }
            }
            break;
			
            default:
            break;
        }
        if(p_tm_sched_inst->req_tm_sched_info.data.creation_mode == BCMBAL_TM_CREATION_MODE_AUTO)
        {
            ret = _rsc_mgr_tm_sched_auto_id_free(p_tm_sched_inst->req_tm_sched_info.key.id);
            if(BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_tm_sched, 
                       "Failed to free auto created tm sched id, id=%d at resource manager ",
                       p_tm_sched_inst->req_tm_sched_info.key.id);
                break;
            }
        }
		
        mgmt_msg_send_balapi_ind(ret,
            (void *)&p_tm_sched_inst->req_tm_sched_info.hdr,
            log_id_tm_sched);
        
        ret = tm_sched_free_by_entry(p_tm_sched_inst);
        if(BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_tm_sched, 
                "Failed to free tm sched id=%d dir = %s",p_tm_sched_inst->req_tm_sched_info.key.id,
                TM_SCHED_DIR_TO_STR(p_tm_sched_inst->req_tm_sched_info.key.dir));
            break;
        }
    }while(0);
    return ret;

}
	
static bcmos_errno tm_sched_fsm_inactive_destroy(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
{
    return tm_sched_fsm_destroy(p_tm_sched_inst);
}

static bcmos_errno tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
{
    return bcmbal_tm_sched_fsm_active_destroy(p_tm_sched_inst);
}

static bcmos_errno tm_sched_fsm_assigned_destroy(tm_sched_inst *p_tm_sched_inst, void *msg, tm_sched_fsm_event *p_event)
{
	bcmos_errno ret = bcmbal_tm_sched_fsm_active_destroy(p_tm_sched_inst);
	if (BCM_ERR_OK == ret)
		ret = tm_sched_fsm_destroy(p_tm_sched_inst);

    return ret;
	
}
bcmos_errno bcmbal_tm_sched_fsm_active_destroy(tm_sched_inst *p_tm_sched_inst)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_tm_sched_owner owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
    bcmbal_interface_key intf_key;

		
    switch(owner.type)
    {
        case BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT:
        {
            uint32_t ref_count;
            ret = rsc_mgr_alloc_id_get_ref_count(p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.intf_id,
                                                 p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.agg_port_id, &ref_count);
            if(1!= ref_count)
            {
                BCM_LOG(ERROR, log_id_tm_sched, "Cant destroy tm sched owned by agg port (if %d id %d) "
					                           "with reference count %d (greated than 1)\n",
                                               p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.intf_id,
                                               p_tm_sched_inst->req_tm_sched_info.data.owner.u.agg_port.agg_port_id, ref_count);
				ret = BCM_ERR_INTERNAL;
                break;		
            
            }
            ret = mac_util_agg_port_set(p_tm_sched_inst, BAL_UTIL_OPER_AGG_PORT_REMOVE);	
            if(BCM_ERR_OK != ret)
            {
                /* An error has occurred trying to configure mac*/
                BCM_LOG(ERROR, log_id_tm_sched,	"Failed to remove ALLOC ID at mac (%s)\n",bcmos_strerror(ret));
                break;		
            }
            else
            {
                p_tm_sched_inst->fsm_state = TM_SCHED_FSM_STATE_DELETING;
            }
            break;
        }
        case BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE:
        {
            /*remove the setting of the sched from the owner configuration*/
            intf_key.intf_type = owner.u.interface.intf_type;
            intf_key.intf_id = owner.u.interface.intf_id;
            ret = interface_tm_sched_unset(intf_key, p_tm_sched_inst->req_tm_sched_info.key);
            tm_sched_fsm_destroy(p_tm_sched_inst);
            break;
        }

        default:
        break;
    }	
    return ret;

}

/*****************************************************************************/
/**
 * @brief A function to set an interface as a tm sched owner
 *
 * @param interface_key  the interface to become the owner
 * @param p_tm_sched_inst          the tm sched instance to be set
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno bcmbal_tm_sched_set_interface_owner(bcmbal_interface_key interface_key, tm_sched_inst *p_tm_sched_inst)
{
    BUG_ON(NULL == p_tm_sched_inst);
    
    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_tm_sched_owner owner;
    do
    {
        if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
        {
            owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
            if (BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE!= owner.type )
            {    
                BCM_LOG(ERROR, log_id_tm_sched, "tm sched %s%d is already assigned with an owner of type %d", 				
                    p_tm_sched_inst->current_tm_sched_info.key.dir == BCMBAL_TM_SCHED_DIR_US ? "us" : "ds",
                    p_tm_sched_inst->current_tm_sched_info.key.id,	owner.type );
                break;
            }
            if(owner.u.interface.intf_type != interface_key.intf_type
               || owner.u.interface.intf_id != interface_key.intf_id)
            {
                BCM_LOG(ERROR, log_id_tm_sched, "tm sched %s%d is already assigned with an interface owner", 
                    p_tm_sched_inst->current_tm_sched_info.key.dir == BCMBAL_TM_SCHED_DIR_US ? "us" : "ds",
                    p_tm_sched_inst->current_tm_sched_info.key.id);
                
                ret = BCM_ERR_ALREADY;		
                break;
            }
        }
        else
        {
            owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_INTERFACE;
            owner.u.interface.intf_type = interface_key.intf_type;
            owner.u.interface.intf_id = interface_key.intf_id;
            BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner, owner);
            ret = bcmbal_tm_sched_set_owner(p_tm_sched_inst);
        }
    }while(0);
    return ret;
}

#define BCMBAL_INTERFACE_DEFAULT_NUM_OF_TM_QUEUES 4
#define BCMBAL_INTERFACE_DEFAULT_SCHED_TYPE BCMBAL_TM_SCHED_TYPE_SP_WFQ
#define BCMBAL_INTERFACE_DEFAULT_SCHED_CHILD_TYPE BCMBAL_TM_SCHED_CHILD_TYPE_QUEUE

#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_SIZE 128
#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_SBR 128
#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_PBR 128
#define BCMBAL_TM_QUEUE_AUTO_DEFAULT_BURST_SIZE 128

bcmos_errno bcmbal_tm_sched_interface_tm_auto_create(bcmbal_interface_cfg *p_interface_info)
{

    bcmos_errno ret = BCM_ERR_OK;
    tm_sched_inst *p_tm_sched_inst = NULL;
    bcmbal_tm_sched_cfg tm_sched_default_cfg;
    bcmbal_tm_queue_cfg tm_queue_default_cfg;
    bcmbal_tm_shaping default_shaping;
    bcmbal_tm_sched_key tm_sched_key;
    bcmbal_tm_queue_key tm_queue_key;
    int i;

     do
    {
	    /*create the auto tm sched*/
    	tm_sched_key.dir = p_interface_info->key.intf_type == BCMBAL_INTF_TYPE_PON ? BCMBAL_TM_SCHED_DIR_DS : BCMBAL_TM_SCHED_DIR_US;
	    BCMBAL_CFG_INIT(&tm_sched_default_cfg, tm_sched, tm_sched_key);
    	BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, sched_type, BCMBAL_INTERFACE_DEFAULT_SCHED_TYPE);
	    BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, sched_child_type, BCMBAL_INTERFACE_DEFAULT_SCHED_CHILD_TYPE);
    	BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, num_priorities, BCMBAL_INTERFACE_DEFAULT_NUM_OF_TM_QUEUES);
	    BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_sched, creation_mode, BCMBAL_TM_CREATION_MODE_AUTO);

	    if (BCM_ERR_OK != (ret = bcmbal_tm_sched_auto_create(tm_sched_default_cfg, &p_tm_sched_inst)))
    	{
		    BCM_LOG(ERROR, log_id_tm_sched,"Could not create the auto tm sched \n");
    		break;
	    }
	    if (tm_sched_key.dir == BCMBAL_TM_SCHED_DIR_US)
    	{
		    BCMBAL_CFG_PROP_SET(p_interface_info, interface, us_tm, p_tm_sched_inst->req_tm_sched_info.key.id);
	    }
    	else
	    {
		    BCMBAL_CFG_PROP_SET(p_interface_info, interface, ds_tm, p_tm_sched_inst->req_tm_sched_info.key.id);
	    }

	    /*SET THE DEFAULT ATTRIBUTES FOR AUTO CREATED QUEUE*/
    	tm_queue_key.sched_id = p_tm_sched_inst->req_tm_sched_info.key.id;
	    tm_queue_key.sched_dir = p_tm_sched_inst->req_tm_sched_info.key.dir;
		default_shaping.sbr = (uint8_t)BCMBAL_TM_QUEUE_AUTO_DEFAULT_SBR;
		default_shaping.pbr = (uint8_t)BCMBAL_TM_QUEUE_AUTO_DEFAULT_PBR;
		default_shaping.burst = (uint8_t)BCMBAL_TM_QUEUE_AUTO_DEFAULT_BURST_SIZE;
	    BCMBAL_CFG_PROP_SET(&tm_queue_default_cfg, tm_queue, rate, default_shaping);
    	BCMBAL_CFG_PROP_SET(&tm_sched_default_cfg, tm_queue, creation_mode, BCMBAL_TM_CREATION_MODE_AUTO);

    	/*create its queues*/
	    for(i=0; i<BCMBAL_INTERFACE_DEFAULT_NUM_OF_TM_QUEUES; i++)
        {
		    tm_queue_key.id = i;
    		BCMBAL_CFG_INIT(&tm_queue_default_cfg, tm_queue, tm_queue_key);

    		BCMBAL_CFG_PROP_SET(&tm_queue_default_cfg, tm_queue, priority, i);
		    BCMBAL_CFG_PROP_SET(&tm_queue_default_cfg, tm_queue, rate, default_shaping);
            if (BCM_ERR_OK != (ret = bcmbal_tm_queue_auto_create(tm_queue_default_cfg)))
            {
                BCM_LOG(ERROR, log_id_tm_sched,"Could not create the %d tm queue\n", i);
                break;
            }
        }

        ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);

    }while(0);

    return ret;
}

bcmos_errno bcmbal_tm_sched_set_sub_term_owner(	bcmbal_tm_sched_key tm_sched_key, const bcmbal_subscriber_terminal_cfg *p_sub_term_cfg)
{
    bcmos_errno ret = BCM_ERR_OK;
    tm_sched_inst *p_tm_sched_inst;
    bcmbal_tm_sched_owner owner;
    
    do
    {
        p_tm_sched_inst = tm_sched_inst_get(tm_sched_key, TM_SCHED_FLAG_ACTIVE);
        if (NULL == p_tm_sched_inst)
        {
            BCM_LOG(ERROR, log_id_tm_sched, 
                "tm sched dir = %s id = %d which is set as the subscriber tm does not exist \n",
                TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id);
            ret = BCM_ERR_NOENT;
            break;			
        }
        if(BCMBAL_CFG_PROP_IS_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner))
        {
            /*check if it is already owned by that sub term*/
            owner = p_tm_sched_inst->req_tm_sched_info.data.owner;
            if (owner.type != BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM)
            {
                BCM_LOG(ERROR, log_id_tm_sched, 
                    "tm sched dir = %s id = %d which is set as the subscriber tm already owned with owner type %d\n",
                    TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id, owner.type);
                ret =  BCM_ERR_PARM;
                break;			
            
            }
            if (owner.u.sub_term.intf_id != p_sub_term_cfg->key.intf_id
                || owner.u.sub_term.sub_term_id != p_sub_term_cfg->key.sub_term_id)
            {	
                BCM_LOG(ERROR, log_id_tm_sched, 
                    "tm sched dir = %s id = %d which is set as the subscriber tm already owned by sub_term intf_id = %d sub_term_id = %d\n",
                    TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id, owner.u.sub_term.intf_id, owner.u.sub_term.sub_term_id);
                ret =  BCM_ERR_PARM;
                break;			
            }
        }
        else
        {
            owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM;
            owner.u.sub_term.intf_id = p_sub_term_cfg->key.intf_id;
            owner.u.sub_term.sub_term_id = p_sub_term_cfg->key.sub_term_id;
            BCMBAL_CFG_PROP_SET(&p_tm_sched_inst->req_tm_sched_info, tm_sched, owner, owner);
			
            if (BCM_ERR_OK!= (ret = bcmbal_tm_sched_set_owner(p_tm_sched_inst)))
            {            
                BCM_LOG(ERROR, log_id_tm_sched, 
                    "could not set sub term intf_id = %d sub_term_id = %d as the owner of tm sched dir = %s id = %d which is set as the subscriber tm \n",
                    owner.u.sub_term.intf_id, owner.u.sub_term.sub_term_id, TM_SCHED_DIR_TO_STR(tm_sched_key.dir), tm_sched_key.id);
                break;			
            }
        }        
    }while (0);
    return ret;
}

/*@}*/
