| /****************************************************************************** |
| * |
| * <: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. |
| * |
| * :> |
| * |
| *****************************************************************************/ |
| |
| #include <bcmolt_host_api.h> |
| #include <bcm_dev_log.h> |
| #include <bal_objs.h> |
| #include <bal_api.h> |
| #include <bal_cli.h> |
| #include <bcmolt_math.h> |
| #include <bcm_topo.h> |
| #include "rsc_mgr_common.h" |
| #include "rsc_mgr.h" |
| |
| #define GPON_NUM_OF_ALLOC_IDS 1024 |
| #define XGPON_NUM_OF_ALLOC_IDS 2048 |
| |
| #define GPON_NUM_OF_GEM_PORT_IDS_PER_PON 4096 |
| #define XGPON_NUM_OF_GEM_PORT_IDS_PER_PON 8192 |
| |
| #define RSC_MGR_ALLOC_ID_LAST_DATA(pon_id, first_data_alloc_id) \ |
| ((first_data_alloc_id) + (bcmolt_pon_alloc_id)(RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_alloc_ids - 1)) |
| #define RSC_MGR_ALLOC_ID_IS_VALID_DATA(pon_id, alloc_id, first_data_alloc_id) ( \ |
| ((alloc_id) >= (first_data_alloc_id) && (alloc_id) <= RSC_MGR_ALLOC_ID_LAST_DATA(pon_id, first_data_alloc_id))) |
| #define RSC_MGR_ALLOC_ID_IS_VALID(pon_id, alloc_id, first_data_alloc_id) ( \ |
| ((alloc_id) <= RSC_MGR_ALLOC_ID_LAST_DEFAULT(pon_id)) || \ |
| RSC_MGR_ALLOC_ID_IS_VALID_DATA(pon_id, alloc_id, first_data_alloc_id)) |
| |
| #define RSC_MGR_GEM_PORT_ID_LAST_DEFAULT(pon_id) ((bcmolt_pon_gem_port_id)(bcm_topo_pon_get_max_num_of_onus(pon_id) - 1)) |
| #define RSC_MGR_GEM_PORT_ID_LAST_DATA(pon_id, first_data_port_id) \ |
| ((first_data_port_id) + (bcmolt_pon_gem_port_id)(RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_gem_ports - bcm_topo_pon_get_max_num_of_onus(pon_id) - 1)) |
| #define RSC_MGR_GEM_PORT_ID_IS_VALID_DATA(pon_id, gem_port_id, first_data_port_id) ( \ |
| ((gem_port_id) >= (first_data_port_id) && (gem_port_id) <= RSC_MGR_GEM_PORT_ID_LAST_DATA(pon_id, first_data_port_id))) |
| #define RSC_MGR_GEM_PORT_ID_IS_VALID(pon_id, gem_port_id, first_data_port_id) ( \ |
| ((gem_port_id) <= RSC_MGR_GEM_PORT_ID_LAST_DEFAULT(pon_id)) || \ |
| RSC_MGR_GEM_PORT_ID_IS_VALID_DATA(pon_id, gem_port_id, first_data_port_id)) |
| |
| #define RSC_MGR_FOR_EACH_ALLOC_INDEX(pon_id, alloc_index) \ |
| for (alloc_index = (bcmolt_pon_alloc_index)0; alloc_index < (bcmolt_pon_alloc_index)RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_alloc_ids; alloc_index++) |
| |
| #define RSC_MGR_FOR_EACH_GEM_INDEX(pon_id, gem_port_index) \ |
| for (gem_port_index = 0; (bcmolt_pon_gem_port_index)gem_port_index < (bcmolt_pon_gem_port_index)RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_gem_ports; gem_port_index++) |
| |
| #define RSC_MGR_FOR_EACH_TM_SCHED_AUTO_INDEX(tm_sched_auto_index) \ |
| for (tm_sched_auto_index = 0; (bcmbal_tm_sched_id_index)tm_sched_auto_index < (bcmbal_tm_sched_id_index)tm_context.num_of_tm_sched_auto_key_ids; tm_sched_auto_index++) |
| |
| /* Because GEM port 0 .. 127 are used for OMCI, we can start allocating from 128. But due to a bug in Maple A0, 128 .. 159 must not be used. So we start from 256. */ |
| #define MIN_BASE_GEM_PORT_ID_GPON 256 |
| |
| #define NUM_OF_TM_SCHED_AUTO_KEY_IDS 2048 |
| #define MIN_BASE_TM_SCHED_AUTO_ID 2048 |
| |
| |
| rsc_mgr_context_t rsc_mgr_context; |
| rsc_mgr_tm_context tm_context; |
| |
| |
| static bcmos_errno rsc_mgr_alloc_validate_common(bcmbal_intf_id access_int_id); |
| static bcmos_errno rsc_mgr_obj_get(bcmbal_intf_id access_int_id, rsc_mgr_obj_id obj_id, rsc_mgr_obj_rsc *obj_rsc, rsc_mgr_obj **obj, dev_log_id log_id); |
| static bcmos_errno rsc_mgr_obj_store_user_data(rsc_mgr_obj *obj, void *user_data); |
| static bcmos_errno rsc_mgr_obj_remove_user_data(rsc_mgr_obj *obj, void *user_data); |
| |
| |
| static bcmos_bool rsc_mgr_is_valid_data_alloc_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id) |
| { |
| return (bcm_topo_pon_is_valid(pon_id) && RSC_MGR_ALLOC_ID_IS_VALID_DATA(pon_id, id, min_data_obj_id)); |
| } |
| |
| static rsc_mgr_obj_id rsc_mgr_get_last_data_alloc_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id) |
| { |
| return (rsc_mgr_obj_id)(bcmolt_pon_alloc_id)RSC_MGR_ALLOC_ID_LAST_DATA(pon_id, min_data_obj_id); |
| } |
| |
| static bcmos_bool rsc_mgr_is_valid_data_gem_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id) |
| { |
| return (bcm_topo_pon_is_valid(pon_id) && RSC_MGR_GEM_PORT_ID_IS_VALID_DATA(pon_id, id, min_data_obj_id)); |
| } |
| |
| static rsc_mgr_obj_id rsc_mgr_get_last_data_gem_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id) |
| { |
| return (rsc_mgr_obj_id)(bcmolt_pon_gem_port_id)RSC_MGR_GEM_PORT_ID_LAST_DATA(pon_id, min_data_obj_id); |
| } |
| static bcmos_bool rsc_mgr_is_valid_data_tm_sched_auto_id(rsc_mgr_obj_id id) |
| { |
| return (id >= MIN_BASE_TM_SCHED_AUTO_ID && id < MIN_BASE_TM_SCHED_AUTO_ID + NUM_OF_TM_SCHED_AUTO_KEY_IDS); |
| } |
| |
| static bcmos_bool rsc_mgr_is_valid_data_tm_sched_auto_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id id, rsc_mgr_obj_id min_data_obj_id) |
| { |
| return rsc_mgr_is_valid_data_tm_sched_auto_id(id); |
| } |
| |
| static rsc_mgr_obj_id rsc_mgr_get_last_data_tm_sched_auto_id_cb(bcmolt_pon_ni pon_id, rsc_mgr_obj_id min_data_obj_id) |
| { |
| return (rsc_mgr_obj_id)(min_data_obj_id + NUM_OF_TM_SCHED_AUTO_KEY_IDS - 1); |
| } |
| |
| |
| static bcmos_errno rsc_mgr_obj_alloc(bcmbal_intf_id access_int_id, rsc_mgr_obj_id *obj_id, uint32_t range_size, rsc_mgr_obj_type type, rsc_mgr_obj_rsc *obj_rsc, void *user_data, dev_log_id log_id) |
| { |
| rsc_mgr_obj *obj; |
| bcmos_errno rc; |
| |
| if (range_size < RSC_MGR_MIN_RANGE_SIZE || range_size > RSC_MGR_MAX_RANGE_SIZE) |
| { |
| BCM_LOG(ERROR, log_id, "Range size must be in the range %u .. %u\n", RSC_MGR_MIN_RANGE_SIZE, RSC_MGR_MAX_RANGE_SIZE); |
| return BCM_ERR_PARM; |
| } |
| |
| if (*obj_id) |
| { |
| rc = rsc_mgr_obj_get(access_int_id, *obj_id, obj_rsc, &obj, log_id); |
| if (rc != BCM_ERR_OK) |
| return rc; |
| |
| if (obj->range_size != range_size) |
| { |
| BCM_LOG(ERROR, log_id, "When reusing a range of %ss, range size (%d) must be exactly the same as the range from creation (%u)\n", |
| obj_rsc->obj_name, range_size, obj->range_size); |
| return BCM_ERR_PARM; |
| } |
| |
| if (obj->type != type) |
| { |
| BCM_LOG(ERROR, log_id, "When reusing %ss, type (%d) must be exactly the same as the type from creation (%u)\n", |
| obj_rsc->obj_name, type, obj->type); |
| return BCM_ERR_PARM; |
| } |
| } |
| else |
| { |
| rsc_mgr_obj *base_obj; |
| rsc_mgr_obj *last_obj; |
| rsc_mgr_obj *obj_iter; |
| |
| /* Find the first free range that fits ("first-fit" algorithm). */ |
| TAILQ_FOREACH(obj_iter, &obj_rsc->free_objs, list) |
| { |
| if (range_size <= obj_iter->range_size) |
| break; |
| } |
| if (!obj_iter) |
| { |
| BCM_LOG(ERROR, log_id, "No free %ss\n", obj_rsc->obj_name); |
| return BCM_ERR_NORES; |
| } |
| *obj_id = obj_iter->id; |
| |
| if (range_size < obj_iter->range_size) |
| { |
| /* Insert a smaller range (decrease by 'range_size') to the list of free objects. It will replace the old free range. */ |
| base_obj = &obj_iter[range_size]; |
| last_obj = &obj_iter[obj_iter->range_size - 1]; |
| TAILQ_INSERT_HEAD(&obj_rsc->free_objs, base_obj, list); |
| base_obj->range_size = obj_iter->range_size - range_size; |
| last_obj->base_obj = base_obj; |
| } |
| |
| /* Move 'range_size' objects from the list of free objects to the list of allocated objects. */ |
| base_obj = obj_iter; |
| last_obj = &obj_iter[range_size - 1]; |
| TAILQ_REMOVE(&obj_rsc->free_objs, base_obj, list); |
| TAILQ_INSERT_HEAD(&obj_rsc->allocated_objs, base_obj, list); |
| base_obj->range_size = range_size; |
| base_obj->type = type; |
| last_obj->base_obj = base_obj; |
| |
| obj = obj_iter; |
| /* since new object, initialize the user data list */ |
| TAILQ_INIT(&obj->user_data_list); |
| |
| } |
| obj->ref_count++; |
| |
| /** store user data (flow entry pointer) in a linked list inside the object */ |
| rsc_mgr_obj_store_user_data(obj, user_data); |
| |
| return BCM_ERR_OK; |
| } |
| |
| static bcmos_errno rsc_mgr_obj_free(bcmbal_intf_id access_int_id, rsc_mgr_obj_id obj_id, rsc_mgr_obj_rsc *obj_rsc, void *user_data, dev_log_id log_id) |
| { |
| rsc_mgr_obj *obj; |
| rsc_mgr_obj *last_obj; |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_obj_get(access_int_id, obj_id, obj_rsc, &obj, log_id); |
| if (rc != BCM_ERR_OK) |
| return rc; |
| |
| obj->ref_count--; |
| /** remove user data (flow entry pointer) from the linked list inside the object */ |
| rsc_mgr_obj_remove_user_data(obj, user_data); |
| |
| if (!obj->ref_count) |
| { |
| rsc_mgr_obj *next_obj = NULL; |
| rsc_mgr_obj *prev_obj = NULL; |
| |
| /* Validate that going to the next object won't overflow the array. */ |
| if (obj < &obj_rsc->objs[obj_rsc->num_of_objs - 1] && &obj[obj->range_size] <= &obj_rsc->objs[obj_rsc->num_of_objs - 1]) |
| { |
| /* Check if the next ID is in the free list (according to its reference count). |
| * If true -> we can merge obj's range with the next range. */ |
| if (!obj[obj->range_size].ref_count) |
| next_obj = &obj[obj->range_size]; |
| } |
| |
| /* Validate that going to the base of the previous range won't underflow the array. */ |
| if (obj > obj_rsc->objs) |
| { |
| /* Check if the base ID of the previous range is in the free list (according to the base ID's reference count). |
| * If true -> we can merge obj's range with the previous range. */ |
| if (obj[-1].base_obj && !obj[-1].base_obj->ref_count) |
| prev_obj = obj[-1].base_obj; |
| } |
| |
| /* First remove the object from the allocated linked list. */ |
| TAILQ_REMOVE(&obj_rsc->allocated_objs, obj, list); |
| last_obj = &obj[obj->range_size - 1]; |
| obj->type = RSC_MGR_OBJ_TYPE_INVALID; /* Clear type. */ |
| if (next_obj && !prev_obj) |
| { |
| /* Merge only with next range. */ |
| TAILQ_INSERT_BEFORE(next_obj, obj, list); |
| TAILQ_REMOVE(&obj_rsc->free_objs, next_obj, list); |
| obj->range_size += next_obj->range_size; |
| last_obj->base_obj = NULL; |
| next_obj->range_size = 0; |
| last_obj = &obj[obj->range_size - 1]; |
| last_obj->base_obj = obj; |
| } |
| else if (!next_obj && prev_obj) |
| { |
| /* Merge only with previous range. */ |
| prev_obj->range_size += obj->range_size; |
| obj->range_size = 0; |
| last_obj->base_obj = prev_obj; |
| } |
| else if (next_obj && prev_obj) |
| { |
| /* Merge with both next and previous ranges. */ |
| prev_obj->range_size += obj->range_size + next_obj->range_size; |
| obj->range_size = 0; |
| next_obj->range_size = 0; |
| TAILQ_REMOVE(&obj_rsc->free_objs, next_obj, list); |
| last_obj->base_obj = NULL; |
| last_obj = &prev_obj[prev_obj->range_size - 1]; |
| last_obj->base_obj = prev_obj; |
| } |
| else |
| { |
| /* No merge at all. */ |
| TAILQ_INSERT_TAIL(&obj_rsc->free_objs, obj, list); |
| } |
| } |
| |
| return BCM_ERR_OK; |
| } |
| |
| static bcmos_errno rsc_mgr_obj_get(bcmbal_intf_id access_int_id, rsc_mgr_obj_id obj_id, rsc_mgr_obj_rsc *obj_rsc, rsc_mgr_obj **obj, dev_log_id log_id) |
| { |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| if (!obj_rsc->is_valid_data_obj_id_cb(access_int_id, obj_id, obj_rsc->min_data_obj_id)) |
| { |
| BCM_LOG(ERROR, log_id, "%s must be in the range %u .. %u\n", |
| obj_rsc->obj_name, obj_rsc->min_data_obj_id, obj_rsc->get_last_data_obj_id_cb(access_int_id, obj_rsc->min_data_obj_id)); |
| return BCM_ERR_PARM; |
| } |
| |
| *obj = &obj_rsc->objs[obj_id - obj_rsc->min_data_obj_id]; |
| /* Only base object must have its reference count > 0. */ |
| if (!(*obj)->ref_count) |
| { |
| BCM_LOG(ERROR, log_id, "%s hasn't been allocated before\n", obj_rsc->obj_name); |
| return BCM_ERR_PARM; |
| } |
| |
| return BCM_ERR_OK; |
| } |
| |
| /** @brief stores user passed in data in the linked list inside the obj */ |
| static bcmos_errno rsc_mgr_obj_store_user_data(rsc_mgr_obj *obj, void *user_data) |
| { |
| rsc_mgr_user_data_entry *user_data_entry = NULL; |
| |
| if (NULL == user_data) |
| return BCM_ERR_OK; |
| |
| user_data_entry = bcmos_calloc(sizeof(rsc_mgr_user_data_entry)); |
| user_data_entry->user_data = user_data; |
| TAILQ_INSERT_HEAD(&obj->user_data_list, user_data_entry, next); |
| |
| return BCM_ERR_OK; |
| } |
| |
| /** @brief removes user data from the linked list inside the obj */ |
| static bcmos_errno rsc_mgr_obj_remove_user_data(rsc_mgr_obj *obj, void *user_data) |
| { |
| rsc_mgr_user_data_entry *user_data_entry = NULL, *user_data_entry_tmp; |
| |
| if (NULL == user_data) |
| return BCM_ERR_OK; |
| |
| TAILQ_FOREACH_SAFE(user_data_entry, &obj->user_data_list, next, user_data_entry_tmp) |
| { |
| if (user_data == user_data_entry->user_data) |
| break; |
| } |
| TAILQ_REMOVE(&obj->user_data_list, user_data_entry, next); |
| |
| user_data_entry->user_data = NULL; |
| bcmos_free(user_data_entry); |
| |
| return BCM_ERR_OK; |
| } |
| |
| /** @brief iterator to iterate through the user data list in obj |
| * @note the assumption is if a NULL is returned, then caller code stop the iteration. |
| * */ |
| static void *rsc_mgr_obj_get_next_user_data(rsc_mgr_obj *obj, void **curr_user_data_entry, void **next_user_data_entry) |
| { |
| if (NULL == *curr_user_data_entry) |
| { |
| *curr_user_data_entry = TAILQ_FIRST(&obj->user_data_list); |
| if (*curr_user_data_entry) |
| { |
| *next_user_data_entry = TAILQ_NEXT(((rsc_mgr_user_data_entry *)*curr_user_data_entry), next); |
| return ((rsc_mgr_user_data_entry *)(*curr_user_data_entry))->user_data; |
| } |
| } |
| else |
| { |
| *curr_user_data_entry = *next_user_data_entry; |
| if (*next_user_data_entry) |
| { |
| *next_user_data_entry = TAILQ_NEXT(((rsc_mgr_user_data_entry *)*next_user_data_entry), next); |
| return ((rsc_mgr_user_data_entry *)(*curr_user_data_entry))->user_data; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| |
| /* Alloc ID (aggregation port ID) */ |
| static bcmos_errno _rsc_mgr_access_int_base_alloc_id_set(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id min_data_agg_port_id) |
| { |
| bcmolt_pon_alloc_index alloc_index; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| if (bcm_topo_pon_get_pon_mode(access_int_id) == BCM_TOPO_PON_MODE_GPON) |
| { |
| bcmolt_gpon_ni_cfg gpon_ni_cfg = {}; |
| bcmolt_gpon_ni_cfg_id failed_prop; |
| |
| BCMOLT_CFG_PROP_SET(&gpon_ni_cfg, gpon_ni, min_data_alloc_id, min_data_agg_port_id); |
| if (!bcmolt_gpon_ni_cfg_data_bounds_check(&gpon_ni_cfg.data, (1ULL << BCMOLT_GPON_NI_CFG_ID_MIN_DATA_ALLOC_ID), &failed_prop)) |
| { |
| BCM_LOG(ERROR, topo_context->log_id, "Minimal data alloc ID is not in the allowed range\n"); |
| return BCM_ERR_PARM; |
| } |
| } |
| else |
| { |
| bcmolt_xgpon_ni_cfg xgpon_ni_cfg = {}; |
| bcmolt_xgpon_ni_cfg_id failed_prop; |
| |
| BCMOLT_CFG_PROP_SET(&xgpon_ni_cfg, xgpon_ni, min_data_alloc_id, min_data_agg_port_id); |
| if (!bcmolt_xgpon_ni_cfg_data_bounds_check(&xgpon_ni_cfg.data, (1ULL << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_ALLOC_ID), &failed_prop)) |
| { |
| BCM_LOG(ERROR, topo_context->log_id, "Minimal data alloc ID is not in the allowed range\n"); |
| return BCM_ERR_PARM; |
| } |
| } |
| |
| if (!TAILQ_EMPTY(&topo_context->alloc_ids.allocated_objs)) |
| { |
| BCM_LOG(ERROR, topo_context->log_id, "Minimal alloc ID cannot be set when there are allocated alloc IDs\n"); |
| return BCM_ERR_STATE; |
| } |
| |
| topo_context->alloc_ids.min_data_obj_id = (rsc_mgr_obj_id)min_data_agg_port_id; |
| RSC_MGR_FOR_EACH_ALLOC_INDEX(access_int_id, alloc_index) |
| topo_context->alloc_ids.objs[alloc_index].id = topo_context->alloc_ids.min_data_obj_id + alloc_index; |
| |
| return BCM_ERR_OK; |
| } |
| |
| bcmos_errno rsc_mgr_access_int_base_alloc_id_set(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id min_data_agg_port_id) |
| { |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| return _rsc_mgr_access_int_base_alloc_id_set(access_int_id, min_data_agg_port_id); |
| } |
| |
| |
| static bcmos_errno rsc_mgr_alloc_validate_common(bcmbal_intf_id access_int_id) |
| { |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_init_validate(); |
| if (rc != BCM_ERR_OK) |
| { |
| BCM_LOG(ERROR, rsc_mgr_log_id, "Resource manager is uninitialized\n"); |
| return rc; |
| } |
| |
| if (!bcm_topo_pon_is_valid(access_int_id)) |
| return BCM_ERR_PARM; |
| |
| return BCM_ERR_OK; |
| } |
| |
| static bcmos_errno rsc_mgr_alloc_validate_non_unicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id topo_context_gem_port, |
| bcmbal_service_port_id req_gem_port, uint32_t range_size, rsc_mgr_obj_type type, |
| dev_log_id log_id) |
| { |
| if (topo_context_gem_port != BCMOLT_PON_GEM_PORT_ID_INVALID && req_gem_port && req_gem_port != topo_context_gem_port) |
| { |
| BCM_LOG(ERROR, log_id, "Access interface already has %s service port ID=%u configured\n", RSC_MGR_OBJ_TYPE_STR(type), topo_context_gem_port); |
| return BCM_ERR_ALREADY; |
| } |
| |
| if (range_size > 1) |
| { |
| BCM_LOG(ERROR, log_id, "Range bigger than 1 for %s GEM port is not allowed\n", RSC_MGR_OBJ_TYPE_STR(type)); |
| return BCM_ERR_PARM; |
| } |
| |
| return BCM_ERR_OK; |
| } |
| |
| bcmos_errno rsc_mgr_alloc_id_alloc(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id *agg_port_id, uint32_t range_size, void *user_data) |
| { |
| bcmos_errno rc; |
| rsc_mgr_obj_id obj_id = *agg_port_id; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_ALLOC_ID, &topo_context->alloc_ids, user_data, topo_context->log_id); |
| *agg_port_id = obj_id; |
| |
| return rc; |
| } |
| |
| bcmos_errno rsc_mgr_alloc_id_free(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, void *user_data) |
| { |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| if (!bcm_topo_pon_is_valid(access_int_id)) |
| return BCM_ERR_PARM; |
| |
| return rsc_mgr_obj_free(access_int_id, (rsc_mgr_obj_id)agg_port_id, &topo_context->alloc_ids, user_data, topo_context->log_id); |
| } |
| |
| bcmos_errno rsc_mgr_alloc_id_get_ref_count(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, uint32_t *ref_count) |
| { |
| rsc_mgr_obj *obj; |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)agg_port_id, &topo_context->alloc_ids, &obj, topo_context->log_id); |
| if (rc != BCM_ERR_OK) |
| return rc; |
| |
| *ref_count = obj->ref_count; |
| |
| return BCM_ERR_OK; |
| } |
| |
| /** @brief iterates through user data list of an alloc id object */ |
| void *rsc_mgr_alloc_id_get_next_user_data(bcmbal_intf_id access_int_id, bcmbal_aggregation_port_id agg_port_id, void **curr_user_data_entry, void **next_user_data_entry) |
| { |
| rsc_mgr_obj *obj; |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)agg_port_id, &topo_context->alloc_ids, &obj, topo_context->log_id); |
| if (rc != BCM_ERR_OK) |
| return NULL; |
| |
| return rsc_mgr_obj_get_next_user_data(obj, curr_user_data_entry, next_user_data_entry); |
| } |
| |
| /* GEM (service port ID) */ |
| static bcmos_errno _rsc_mgr_access_int_base_gem_set(bcmbal_intf_id access_int_id, bcmbal_service_port_id min_data_svc_port_id) |
| { |
| bcmolt_pon_gem_port_index gem_index; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| if (bcm_topo_pon_get_pon_mode(access_int_id) == BCM_TOPO_PON_MODE_GPON) |
| { |
| bcmolt_gpon_gem_port_cfg gpon_gem_port_cfg = { .key.gem_port_id = min_data_svc_port_id }; |
| bcmolt_gpon_gem_port_key_id failed_prop; |
| |
| if (!bcmolt_gpon_gem_port_key_bounds_check(&gpon_gem_port_cfg.key, 1ULL << BCMOLT_GPON_GEM_PORT_KEY_ID_GEM_PORT_ID, &failed_prop) || |
| min_data_svc_port_id < MIN_BASE_GEM_PORT_ID_GPON) |
| { |
| BCM_LOG(ERROR, topo_context->log_id, "Minimal data GEM port is not in the allowed range\n"); |
| return BCM_ERR_PARM; |
| } |
| } |
| else |
| { |
| bcmolt_xgpon_ni_cfg xgpon_ni_cfg = {}; |
| bcmolt_xgpon_ni_cfg_id failed_prop; |
| |
| BCMOLT_CFG_PROP_SET(&xgpon_ni_cfg, xgpon_ni, min_data_gem_port_id, min_data_svc_port_id); |
| if (!bcmolt_xgpon_ni_cfg_data_bounds_check(&xgpon_ni_cfg.data, 1ULL << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_GEM_PORT_ID, &failed_prop)) |
| { |
| BCM_LOG(ERROR, topo_context->log_id, "Minimal data GEM port is not in the allowed range\n"); |
| return BCM_ERR_PARM; |
| } |
| } |
| |
| if (!TAILQ_EMPTY(&topo_context->gems.allocated_objs)) |
| { |
| BCM_LOG(ERROR, topo_context->log_id, "Minimal GEM port cannot be set when there are allocated GEM ports\n"); |
| return BCM_ERR_STATE; |
| } |
| |
| topo_context->gems.min_data_obj_id = (rsc_mgr_obj_id)min_data_svc_port_id; |
| RSC_MGR_FOR_EACH_GEM_INDEX(access_int_id, gem_index) |
| topo_context->gems.objs[gem_index].id = topo_context->gems.min_data_obj_id + gem_index; |
| |
| return BCM_ERR_OK; |
| } |
| |
| bcmos_errno rsc_mgr_access_int_base_gem_set(bcmbal_intf_id access_int_id, bcmbal_service_port_id min_data_svc_port_id) |
| { |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| return _rsc_mgr_access_int_base_gem_set(access_int_id, min_data_svc_port_id); |
| } |
| |
| static bcmos_errno _rsc_mgr_base_tm_sched_auto_id_set (bcmbal_tm_sched_id min_tm_sched_auto_id) |
| { |
| bcmbal_tm_sched_id_index i; |
| |
| |
| if (!TAILQ_EMPTY(&tm_context.tm_sched_auto_key_ids.allocated_objs)) |
| { |
| BCM_LOG(ERROR, tm_context.log_id, "Minimal tm node auto id cannot be set when there are allocated ids \n"); |
| return BCM_ERR_STATE; |
| } |
| |
| tm_context.tm_sched_auto_key_ids.min_data_obj_id = (rsc_mgr_obj_id)min_tm_sched_auto_id; |
| RSC_MGR_FOR_EACH_TM_SCHED_AUTO_INDEX(i) |
| { |
| tm_context.tm_sched_auto_key_ids.objs[i].id = tm_context.tm_sched_auto_key_ids.min_data_obj_id + i; |
| } |
| |
| return BCM_ERR_OK; |
| } |
| |
| bcmos_errno rsc_mgr_gem_alloc_unicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data) |
| { |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = NULL; |
| rsc_mgr_obj_id obj_id = *svc_port_id; |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_UNICAST, &topo_context->gems, user_data, topo_context->log_id); |
| *svc_port_id = obj_id; |
| |
| return rc; |
| } |
| |
| |
| bcmos_errno rsc_mgr_gem_alloc_multicast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data) |
| { |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = NULL; |
| rsc_mgr_obj_id obj_id = *svc_port_id; |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| #ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON |
| rc = rsc_mgr_alloc_validate_non_unicast(access_int_id, topo_context->multicast_gem_port, *svc_port_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST, topo_context->log_id); |
| |
| if (topo_context->multicast_gem_port != BCMOLT_PON_GEM_PORT_ID_INVALID) |
| obj_id = topo_context->multicast_gem_port; /* This will cause the reference count of the multicast GEM to increase. */ |
| #endif |
| |
| rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_MULTICAST, &topo_context->gems, user_data, topo_context->log_id); |
| *svc_port_id = obj_id; |
| |
| #ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON |
| if (!rc) |
| RSC_MGR_PON_TOPO_CONTEXT(access_int_id)->multicast_gem_port = *svc_port_id; |
| #endif |
| |
| return rc; |
| } |
| |
| bcmos_errno rsc_mgr_gem_alloc_broadcast(bcmbal_intf_id access_int_id, bcmbal_service_port_id *svc_port_id, uint32_t range_size, void *user_data) |
| { |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = NULL; |
| rsc_mgr_obj_id obj_id = *svc_port_id; |
| |
| rc = rsc_mgr_alloc_validate_common(access_int_id); |
| if (BCM_ERR_OK != rc) |
| return rc; |
| |
| topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| #ifndef MULTIPLE_BROADCAST_GEM_PORTS_PER_PON |
| rc = rsc_mgr_alloc_validate_non_unicast(access_int_id, topo_context->broadcast_gem_port, *svc_port_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST, topo_context->log_id); |
| |
| if (topo_context->broadcast_gem_port != BCMOLT_PON_GEM_PORT_ID_INVALID) |
| obj_id = topo_context->broadcast_gem_port; /* This will cause the reference count of the broadcast GEM to increase. */ |
| #endif |
| |
| rc = rsc_mgr_obj_alloc(access_int_id, &obj_id, range_size, RSC_MGR_OBJ_TYPE_GEM_PORT_BROADCAST, &topo_context->gems, user_data, topo_context->log_id); |
| *svc_port_id = obj_id; |
| |
| #ifndef MULTIPLE_BROADCAST_GEM_PORTS_PER_PON |
| if (!rc) |
| RSC_MGR_PON_TOPO_CONTEXT(access_int_id)->broadcast_gem_port = *svc_port_id; |
| #endif |
| |
| return rc; |
| } |
| |
| bcmos_errno rsc_mgr_gem_free(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, void *user_data) |
| { |
| bcmos_errno rc; |
| #ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON |
| rsc_mgr_topo_pon_context *topo_context; |
| #endif |
| |
| if (!bcm_topo_pon_is_valid(access_int_id)) |
| return BCM_ERR_PARM; |
| |
| #ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON |
| topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| #endif |
| |
| rc = rsc_mgr_obj_free(access_int_id, (rsc_mgr_obj_id)svc_port_id, &topo_context->gems, user_data, topo_context->log_id); |
| |
| #ifndef MULTIPLE_MULTICAST_GEM_PORTS_PER_PON |
| if (!rc && topo_context->multicast_gem_port == svc_port_id) |
| RSC_MGR_PON_TOPO_CONTEXT(access_int_id)->multicast_gem_port = BCMOLT_PON_GEM_PORT_ID_INVALID; |
| #endif |
| |
| return rc; |
| } |
| |
| bcmos_errno rsc_mgr_gem_get_ref_count(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, uint32_t *ref_count) |
| { |
| rsc_mgr_obj *obj; |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)svc_port_id, &topo_context->gems, &obj, topo_context->log_id); |
| if (rc != BCM_ERR_OK) |
| return rc; |
| |
| *ref_count = obj->ref_count; |
| |
| return BCM_ERR_OK; |
| } |
| |
| /** @brief iterates through user data list of a gem object */ |
| void *rsc_mgr_gem_get_next_user_data(bcmbal_intf_id access_int_id, bcmbal_service_port_id svc_port_id, void **curr_user_data_entry, void **next_user_data_entry) |
| { |
| rsc_mgr_obj *obj; |
| bcmos_errno rc; |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(access_int_id); |
| |
| rc = rsc_mgr_obj_get(access_int_id, (rsc_mgr_obj_id)svc_port_id, &topo_context->gems, &obj, topo_context->log_id); |
| if (rc != BCM_ERR_OK) |
| return NULL; |
| |
| return rsc_mgr_obj_get_next_user_data(obj, curr_user_data_entry, next_user_data_entry); |
| } |
| |
| |
| |
| bcmos_errno _rsc_mgr_tm_sched_auto_id_alloc(bcmbal_tm_sched_id *tm_sched_id) |
| { |
| bcmos_errno rc; |
| rsc_mgr_obj_id obj_id = *tm_sched_id; |
| |
| rc = rsc_mgr_init_validate(); |
| if (rc != BCM_ERR_OK) |
| { |
| BCM_LOG(ERROR, rsc_mgr_log_id, "Resource manager is uninitialized\n"); |
| return rc; |
| } |
| |
| /* Allocate a new object. */ |
| rc = rsc_mgr_obj_alloc(0, &obj_id, 1, RSC_MGR_OBJ_TYPE_TM_SCHED, &tm_context.tm_sched_auto_key_ids, NULL, tm_context.log_id); |
| *tm_sched_id = obj_id; |
| |
| return rc; |
| } |
| |
| bcmos_errno _rsc_mgr_tm_sched_auto_id_free(bcmbal_tm_sched_id tm_sched_id) |
| { |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_obj_free(0, (rsc_mgr_obj_id)tm_sched_id, &tm_context.tm_sched_auto_key_ids, NULL, tm_context.log_id); |
| |
| return rc; |
| } |
| |
| bcmos_errno _rsc_mgr_tm_sched_auto_id_get_ref_count(bcmbal_tm_sched_id tm_sched_id, uint32_t *ref_count) |
| { |
| rsc_mgr_obj *obj; |
| bcmos_errno rc; |
| |
| rc = rsc_mgr_obj_get(0, (rsc_mgr_obj_id)tm_sched_id, &tm_context.tm_sched_auto_key_ids, &obj, tm_context.log_id); |
| if (rc != BCM_ERR_OK) |
| return rc; |
| |
| *ref_count = obj->ref_count; |
| |
| return BCM_ERR_OK; |
| } |
| |
| bcmos_bool _rsc_mgr_tm_sched_id_validate(bcmbal_tm_sched_id tm_sched_key_id) |
| { |
| return (!rsc_mgr_is_valid_data_tm_sched_auto_id(tm_sched_key_id)); |
| } |
| |
| static void rsc_mgr_init_obj_rsc(rsc_mgr_obj_rsc *obj_rsc, rsc_mgr_is_valid_data_obj_id_cb_t is_valid_data_obj_id_cb, |
| rsc_mgr_get_last_data_obj_id_cb_t get_last_data_obj_id_cb, uint32_t num_of_objs, const char *obj_name) |
| { |
| rsc_mgr_obj *obj; |
| |
| obj_rsc->obj_name = obj_name; |
| obj_rsc->is_valid_data_obj_id_cb = is_valid_data_obj_id_cb; |
| obj_rsc->get_last_data_obj_id_cb = get_last_data_obj_id_cb; |
| TAILQ_INIT(&obj_rsc->free_objs); |
| TAILQ_INIT(&obj_rsc->allocated_objs); |
| obj_rsc->objs = bcmos_calloc(num_of_objs * sizeof(*obj_rsc->objs)); |
| obj_rsc->num_of_objs = num_of_objs; |
| |
| /* Insert a first entry to the list of free objects. */ |
| obj = &obj_rsc->objs[0]; |
| obj->range_size = num_of_objs; |
| TAILQ_INSERT_HEAD(&obj_rsc->free_objs, obj, list); |
| } |
| |
| static void rsc_mgr_uninit_obj_rsc(rsc_mgr_obj_rsc *obj_rsc) |
| { |
| bcmos_free(obj_rsc->objs); |
| } |
| |
| bcmos_errno rsc_mgr_mac_init(void) |
| { |
| bcmos_errno rc = BCM_ERR_OK; |
| bcmolt_devid device_id; |
| uint32_t pon_id; |
| rsc_mgr_topo_pon_context *topo_context, *old_topo_context; |
| |
| do |
| { |
| rc = rsc_mgr_init_validate(); |
| if (rc != BCM_ERR_OK) |
| { |
| BCM_LOG(INFO, rsc_mgr_log_id, "Resource Manager was not initialized"); |
| break; |
| } |
| BCM_TOPO_FOR_EACH_PON(device_id, pon_id) |
| { |
| old_topo_context = bcm_topo_pon_get_context(pon_id, BCM_TOPO_PON_CONTEXT_ID_RSC_MGR); |
| if (old_topo_context) |
| { |
| bcmos_free(old_topo_context); |
| } |
| topo_context = bcmos_calloc(sizeof(*topo_context)); |
| if (bcm_topo_pon_get_pon_mode(pon_id) == BCM_TOPO_PON_MODE_GPON) |
| { |
| topo_context->num_of_alloc_ids = GPON_NUM_OF_ALLOC_IDS; |
| topo_context->num_of_gem_ports = GPON_NUM_OF_GEM_PORT_IDS_PER_PON; |
| } |
| else |
| { |
| topo_context->num_of_alloc_ids = XGPON_NUM_OF_ALLOC_IDS; |
| topo_context->num_of_gem_ports = XGPON_NUM_OF_GEM_PORT_IDS_PER_PON; |
| } |
| topo_context->multicast_gem_port = BCMOLT_PON_GEM_PORT_ID_INVALID; |
| topo_context->broadcast_gem_port = BCMOLT_PON_GEM_PORT_ID_INVALID; |
| bcm_topo_pon_set_context(pon_id, BCM_TOPO_PON_CONTEXT_ID_RSC_MGR, topo_context); |
| #ifdef ENABLE_LOG |
| snprintf(topo_context->log_id_name, sizeof(topo_context->log_id_name), "RSC_MGR%u", pon_id); |
| topo_context->log_id = bcm_dev_log_id_register(topo_context->log_id_name, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH); |
| BUG_ON(topo_context->log_id == DEV_LOG_INVALID_ID); |
| #endif |
| rsc_mgr_init_obj_rsc(&topo_context->alloc_ids, rsc_mgr_is_valid_data_alloc_id_cb, rsc_mgr_get_last_data_alloc_id_cb, |
| RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_alloc_ids, "alloc ID"); |
| rsc_mgr_init_obj_rsc(&topo_context->gems, rsc_mgr_is_valid_data_gem_cb, rsc_mgr_get_last_data_gem_cb, |
| RSC_MGR_PON_TOPO_CONTEXT(pon_id)->num_of_gem_ports, "GEM port"); |
| |
| if (bcm_topo_pon_get_pon_mode(pon_id) == BCM_TOPO_PON_MODE_GPON) |
| { |
| bcmolt_gpon_ni_cfg gpon_ni_cfg = {}; |
| |
| bcmolt_gpon_ni_cfg_data_set_default(&gpon_ni_cfg.data, 1 << BCMOLT_GPON_NI_CFG_ID_MIN_DATA_ALLOC_ID); |
| _rsc_mgr_access_int_base_alloc_id_set(pon_id, gpon_ni_cfg.data.min_data_alloc_id); |
| |
| _rsc_mgr_access_int_base_gem_set(pon_id, MIN_BASE_GEM_PORT_ID_GPON); |
| } |
| else |
| { |
| bcmolt_xgpon_ni_cfg xgpon_ni_cfg = {}; |
| |
| bcmolt_xgpon_ni_cfg_data_set_default(&xgpon_ni_cfg.data, 1 << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_ALLOC_ID); |
| _rsc_mgr_access_int_base_alloc_id_set(pon_id, xgpon_ni_cfg.data.min_data_alloc_id); |
| |
| bcmolt_xgpon_ni_cfg_data_set_default(&xgpon_ni_cfg.data, 1 << BCMOLT_XGPON_NI_CFG_ID_MIN_DATA_GEM_PORT_ID); |
| _rsc_mgr_access_int_base_gem_set(pon_id, xgpon_ni_cfg.data.min_data_gem_port_id); |
| } |
| } |
| |
| }while(0); |
| return rc; |
| } |
| |
| bcmos_errno rsc_mgr_init(void) |
| { |
| if (rsc_mgr_init_validate() == BCM_ERR_OK) |
| { |
| BCM_LOG(INFO, rsc_mgr_log_id, "Resource Manager was already initialized"); |
| return BCM_ERR_OK; |
| } |
| |
| #ifdef ENABLE_LOG |
| if (rsc_mgr_log_id == DEV_LOG_INVALID_ID) |
| { |
| rsc_mgr_log_id = bcm_dev_log_id_register("RSC_MGR", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH); |
| BUG_ON(rsc_mgr_log_id == DEV_LOG_INVALID_ID); |
| } |
| #endif |
| |
| /*Init the tm object*/ |
| tm_context.num_of_tm_sched_auto_key_ids = NUM_OF_TM_SCHED_AUTO_KEY_IDS; |
| snprintf(tm_context.log_id_name , sizeof(tm_context.log_id_name) , "RSC_MGR_TM"); |
| tm_context.log_id = bcm_dev_log_id_register(tm_context.log_id_name, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH); |
| BUG_ON(tm_context.log_id == DEV_LOG_INVALID_ID); |
| |
| rsc_mgr_init_obj_rsc(&tm_context.tm_sched_auto_key_ids, rsc_mgr_is_valid_data_tm_sched_auto_id_cb, rsc_mgr_get_last_data_tm_sched_auto_id_cb, |
| tm_context.num_of_tm_sched_auto_key_ids, "TM node auto id"); |
| |
| _rsc_mgr_base_tm_sched_auto_id_set(MIN_BASE_TM_SCHED_AUTO_ID); |
| |
| rsc_mgr_context.is_initialized = BCMOS_TRUE; |
| return BCM_ERR_OK; |
| } |
| |
| void rsc_mgr_uninit(void) |
| { |
| bcmolt_devid device_id; |
| uint32_t pon_id; |
| |
| if (!rsc_mgr_context.is_initialized) |
| return; |
| |
| BCM_TOPO_FOR_EACH_PON(device_id, pon_id) |
| { |
| rsc_mgr_topo_pon_context *topo_context = RSC_MGR_PON_TOPO_CONTEXT(pon_id); |
| |
| rsc_mgr_uninit_obj_rsc(&topo_context->gems); |
| rsc_mgr_uninit_obj_rsc(&topo_context->alloc_ids); |
| } |
| rsc_mgr_context.is_initialized = BCMOS_FALSE; |
| } |
| |