blob: 519af971c5b7aae5935564daead9a5fac76a3c1b [file] [log] [blame]
#include <bcmos_system.h>
#include <bal_msg.h>
#include "bal_obj_msg_pack_unpack.h"
typedef uint32_t (*bcmbal_func_packed_len) (void *this, bcmbal_presence_mask fields_present);
typedef bcmos_bool (*bcmbal_func_pack) (void *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
typedef bcmos_bool (*bcmbal_func_unpack) (void *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
typedef bcmos_bool (*bcmbal_func_mem_scan) (bcmbal_buf * buf, uint32_t * extra_mem, bcmbal_presence_mask fields_present);
/******************************************************************************/
typedef struct bcmbal_group_info
{
bcmbal_obj_id obj_type;
bcmbal_mgt_group group;
uint16_t subgroup;
uint32_t size;
uint32_t container_size; /* sizeof() the key/data container struct (0 for key groups) */
uint32_t data_offset; /* offsetof() data field within container struct (0 for key groups) */
bcmbal_func_packed_len get_packed_length;
bcmbal_func_pack pack;
bcmbal_func_unpack unpack;
bcmbal_func_mem_scan mem_scan;
} bcmbal_group_info;
/******************************************************************************/
typedef struct bcmbal_group_ids
{
uint32_t subgroup_count;
bcmbal_obj_group_id *subgroup_ids;
} bcmbal_group_ids;
/******************************************************************************/
typedef struct bcmbal_instance_info
{
int8_t offset;
int8_t size;
} bcmbal_instance_info;
/******************************************************************************/
static bcmbal_group_info group_info_access_terminal_key = { BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_access_terminal_key), 0, 0, (bcmbal_func_packed_len) bcmbal_access_terminal_key_get_packed_length, (bcmbal_func_pack) bcmbal_access_terminal_key_pack, (bcmbal_func_unpack) bcmbal_access_terminal_key_unpack, bcmbal_access_terminal_key_scan };
static bcmbal_group_info group_info_access_terminal_cfg = { BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_access_terminal_cfg_data), sizeof(bcmbal_access_terminal_cfg), offsetof(bcmbal_access_terminal_cfg, data), (bcmbal_func_packed_len) bcmbal_access_terminal_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_access_terminal_cfg_data_pack, (bcmbal_func_unpack) bcmbal_access_terminal_cfg_data_unpack, bcmbal_access_terminal_cfg_data_scan };
static bcmbal_group_info group_info_access_terminal_ind = { BCMBAL_OBJ_ID_ACCESS_TERMINAL, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_access_terminal_ind_data), sizeof(bcmbal_access_terminal_ind), offsetof(bcmbal_access_terminal_ind, data), (bcmbal_func_packed_len) bcmbal_access_terminal_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_access_terminal_ind_data_pack, (bcmbal_func_unpack) bcmbal_access_terminal_ind_data_unpack, bcmbal_access_terminal_ind_data_scan };
static bcmbal_group_info group_info_flow_key = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_flow_key), 0, 0, (bcmbal_func_packed_len) bcmbal_flow_key_get_packed_length, (bcmbal_func_pack) bcmbal_flow_key_pack, (bcmbal_func_unpack) bcmbal_flow_key_unpack, bcmbal_flow_key_scan };
static bcmbal_group_info group_info_flow_cfg = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_flow_cfg_data), sizeof(bcmbal_flow_cfg), offsetof(bcmbal_flow_cfg, data), (bcmbal_func_packed_len) bcmbal_flow_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_flow_cfg_data_pack, (bcmbal_func_unpack) bcmbal_flow_cfg_data_unpack, bcmbal_flow_cfg_data_scan };
static bcmbal_group_info group_info_flow_stat = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_flow_stat_data), sizeof(bcmbal_flow_stat), offsetof(bcmbal_flow_stat, data), (bcmbal_func_packed_len) bcmbal_flow_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_flow_stat_data_pack, (bcmbal_func_unpack) bcmbal_flow_stat_data_unpack, bcmbal_flow_stat_data_scan };
static bcmbal_group_info group_info_flow_ind = { BCMBAL_OBJ_ID_FLOW, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_flow_ind_data), sizeof(bcmbal_flow_ind), offsetof(bcmbal_flow_ind, data), (bcmbal_func_packed_len) bcmbal_flow_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_flow_ind_data_pack, (bcmbal_func_unpack) bcmbal_flow_ind_data_unpack, bcmbal_flow_ind_data_scan };
static bcmbal_group_info group_info_group_key = { BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_group_key), 0, 0, (bcmbal_func_packed_len) bcmbal_group_key_get_packed_length, (bcmbal_func_pack) bcmbal_group_key_pack, (bcmbal_func_unpack) bcmbal_group_key_unpack, bcmbal_group_key_scan };
static bcmbal_group_info group_info_group_cfg = { BCMBAL_OBJ_ID_GROUP, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_group_cfg_data), sizeof(bcmbal_group_cfg), offsetof(bcmbal_group_cfg, data), (bcmbal_func_packed_len) bcmbal_group_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_group_cfg_data_pack, (bcmbal_func_unpack) bcmbal_group_cfg_data_unpack, bcmbal_group_cfg_data_scan };
static bcmbal_group_info group_info_interface_key = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_interface_key), 0, 0, (bcmbal_func_packed_len) bcmbal_interface_key_get_packed_length, (bcmbal_func_pack) bcmbal_interface_key_pack, (bcmbal_func_unpack) bcmbal_interface_key_unpack, bcmbal_interface_key_scan };
static bcmbal_group_info group_info_interface_cfg = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_interface_cfg_data), sizeof(bcmbal_interface_cfg), offsetof(bcmbal_interface_cfg, data), (bcmbal_func_packed_len) bcmbal_interface_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_interface_cfg_data_pack, (bcmbal_func_unpack) bcmbal_interface_cfg_data_unpack, bcmbal_interface_cfg_data_scan };
static bcmbal_group_info group_info_interface_stat = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_interface_stat_data), sizeof(bcmbal_interface_stat), offsetof(bcmbal_interface_stat, data), (bcmbal_func_packed_len) bcmbal_interface_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_interface_stat_data_pack, (bcmbal_func_unpack) bcmbal_interface_stat_data_unpack, bcmbal_interface_stat_data_scan };
static bcmbal_group_info group_info_interface_ind = { BCMBAL_OBJ_ID_INTERFACE, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_interface_ind_data), sizeof(bcmbal_interface_ind), offsetof(bcmbal_interface_ind, data), (bcmbal_func_packed_len) bcmbal_interface_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_interface_ind_data_pack, (bcmbal_func_unpack) bcmbal_interface_ind_data_unpack, bcmbal_interface_ind_data_scan };
static bcmbal_group_info group_info_packet_key = { BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_packet_key), 0, 0, (bcmbal_func_packed_len) bcmbal_packet_key_get_packed_length, (bcmbal_func_pack) bcmbal_packet_key_pack, (bcmbal_func_unpack) bcmbal_packet_key_unpack, bcmbal_packet_key_scan };
static bcmbal_group_info group_info_packet_cfg = { BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_packet_cfg_data), sizeof(bcmbal_packet_cfg), offsetof(bcmbal_packet_cfg, data), (bcmbal_func_packed_len) bcmbal_packet_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_packet_cfg_data_pack, (bcmbal_func_unpack) bcmbal_packet_cfg_data_unpack, bcmbal_packet_cfg_data_scan };
static bcmbal_group_info group_info_packet_ind = { BCMBAL_OBJ_ID_PACKET, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_packet_ind_data), sizeof(bcmbal_packet_ind), offsetof(bcmbal_packet_ind, data), (bcmbal_func_packed_len) bcmbal_packet_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_packet_ind_data_pack, (bcmbal_func_unpack) bcmbal_packet_ind_data_unpack, bcmbal_packet_ind_data_scan };
static bcmbal_group_info group_info_subscriber_terminal_key = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_subscriber_terminal_key), 0, 0, (bcmbal_func_packed_len) bcmbal_subscriber_terminal_key_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_key_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_key_unpack, bcmbal_subscriber_terminal_key_scan };
static bcmbal_group_info group_info_subscriber_terminal_cfg = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_subscriber_terminal_cfg_data), sizeof(bcmbal_subscriber_terminal_cfg), offsetof(bcmbal_subscriber_terminal_cfg, data), (bcmbal_func_packed_len) bcmbal_subscriber_terminal_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_cfg_data_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_cfg_data_unpack, bcmbal_subscriber_terminal_cfg_data_scan };
static bcmbal_group_info group_info_subscriber_terminal_stat = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_subscriber_terminal_stat_data), sizeof(bcmbal_subscriber_terminal_stat), offsetof(bcmbal_subscriber_terminal_stat, data), (bcmbal_func_packed_len) bcmbal_subscriber_terminal_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_stat_data_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_stat_data_unpack, bcmbal_subscriber_terminal_stat_data_scan };
static bcmbal_group_info group_info_subscriber_terminal_ind = { BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_subscriber_terminal_ind_data), sizeof(bcmbal_subscriber_terminal_ind), offsetof(bcmbal_subscriber_terminal_ind, data), (bcmbal_func_packed_len) bcmbal_subscriber_terminal_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_subscriber_terminal_ind_data_pack, (bcmbal_func_unpack) bcmbal_subscriber_terminal_ind_data_unpack, bcmbal_subscriber_terminal_ind_data_scan };
static bcmbal_group_info group_info_tm_queue_key = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_tm_queue_key), 0, 0, (bcmbal_func_packed_len) bcmbal_tm_queue_key_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_key_pack, (bcmbal_func_unpack) bcmbal_tm_queue_key_unpack, bcmbal_tm_queue_key_scan };
static bcmbal_group_info group_info_tm_queue_cfg = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_tm_queue_cfg_data), sizeof(bcmbal_tm_queue_cfg), offsetof(bcmbal_tm_queue_cfg, data), (bcmbal_func_packed_len) bcmbal_tm_queue_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_cfg_data_pack, (bcmbal_func_unpack) bcmbal_tm_queue_cfg_data_unpack, bcmbal_tm_queue_cfg_data_scan };
static bcmbal_group_info group_info_tm_queue_stat = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_STAT, 0, sizeof(bcmbal_tm_queue_stat_data), sizeof(bcmbal_tm_queue_stat), offsetof(bcmbal_tm_queue_stat, data), (bcmbal_func_packed_len) bcmbal_tm_queue_stat_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_stat_data_pack, (bcmbal_func_unpack) bcmbal_tm_queue_stat_data_unpack, bcmbal_tm_queue_stat_data_scan };
static bcmbal_group_info group_info_tm_queue_ind = { BCMBAL_OBJ_ID_TM_QUEUE, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_tm_queue_ind_data), sizeof(bcmbal_tm_queue_ind), offsetof(bcmbal_tm_queue_ind, data), (bcmbal_func_packed_len) bcmbal_tm_queue_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_queue_ind_data_pack, (bcmbal_func_unpack) bcmbal_tm_queue_ind_data_unpack, bcmbal_tm_queue_ind_data_scan };
static bcmbal_group_info group_info_tm_sched_key = { BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_KEY, 0, sizeof(bcmbal_tm_sched_key), 0, 0, (bcmbal_func_packed_len) bcmbal_tm_sched_key_get_packed_length, (bcmbal_func_pack) bcmbal_tm_sched_key_pack, (bcmbal_func_unpack) bcmbal_tm_sched_key_unpack, bcmbal_tm_sched_key_scan };
static bcmbal_group_info group_info_tm_sched_cfg = { BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_CFG, 0, sizeof(bcmbal_tm_sched_cfg_data), sizeof(bcmbal_tm_sched_cfg), offsetof(bcmbal_tm_sched_cfg, data), (bcmbal_func_packed_len) bcmbal_tm_sched_cfg_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_sched_cfg_data_pack, (bcmbal_func_unpack) bcmbal_tm_sched_cfg_data_unpack, bcmbal_tm_sched_cfg_data_scan };
static bcmbal_group_info group_info_tm_sched_ind = { BCMBAL_OBJ_ID_TM_SCHED, BCMBAL_MGT_GROUP_AUTO, 0, sizeof(bcmbal_tm_sched_ind_data), sizeof(bcmbal_tm_sched_ind), offsetof(bcmbal_tm_sched_ind, data), (bcmbal_func_packed_len) bcmbal_tm_sched_ind_data_get_packed_length, (bcmbal_func_pack) bcmbal_tm_sched_ind_data_pack, (bcmbal_func_unpack) bcmbal_tm_sched_ind_data_unpack, bcmbal_tm_sched_ind_data_scan };
static bcmbal_group_info *group_info[] = { &group_info_access_terminal_key, &group_info_access_terminal_cfg, &group_info_access_terminal_ind, &group_info_flow_key, &group_info_flow_cfg, &group_info_flow_stat, &group_info_flow_ind, &group_info_group_key, &group_info_group_cfg, &group_info_interface_key, &group_info_interface_cfg, &group_info_interface_stat, &group_info_interface_ind, &group_info_packet_key, &group_info_packet_cfg, &group_info_packet_ind, &group_info_subscriber_terminal_key, &group_info_subscriber_terminal_cfg, &group_info_subscriber_terminal_stat, &group_info_subscriber_terminal_ind, &group_info_tm_queue_key, &group_info_tm_queue_cfg, &group_info_tm_queue_stat, &group_info_tm_queue_ind, &group_info_tm_sched_key, &group_info_tm_sched_cfg, &group_info_tm_sched_ind };
static bcmbal_obj_group_id group_ids_access_terminal_key[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_KEY };
static bcmbal_obj_group_id group_ids_access_terminal_cfg[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_CFG };
static bcmbal_obj_group_id group_ids_access_terminal_auto[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_IND };
static bcmbal_obj_group_id group_ids_flow_key[] = { BCMBAL_OBJ_GROUP_ID_FLOW_KEY };
static bcmbal_obj_group_id group_ids_flow_cfg[] = { BCMBAL_OBJ_GROUP_ID_FLOW_CFG };
static bcmbal_obj_group_id group_ids_flow_stat[] = { BCMBAL_OBJ_GROUP_ID_FLOW_STAT };
static bcmbal_obj_group_id group_ids_flow_auto[] = { BCMBAL_OBJ_GROUP_ID_FLOW_IND };
static bcmbal_obj_group_id group_ids_group_key[] = { BCMBAL_OBJ_GROUP_ID_GROUP_KEY };
static bcmbal_obj_group_id group_ids_group_cfg[] = { BCMBAL_OBJ_GROUP_ID_GROUP_CFG };
static bcmbal_obj_group_id group_ids_interface_key[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_KEY };
static bcmbal_obj_group_id group_ids_interface_cfg[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_CFG };
static bcmbal_obj_group_id group_ids_interface_stat[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_STAT };
static bcmbal_obj_group_id group_ids_interface_auto[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_IND };
static bcmbal_obj_group_id group_ids_packet_key[] = { BCMBAL_OBJ_GROUP_ID_PACKET_KEY };
static bcmbal_obj_group_id group_ids_packet_cfg[] = { BCMBAL_OBJ_GROUP_ID_PACKET_CFG };
static bcmbal_obj_group_id group_ids_packet_auto[] = { BCMBAL_OBJ_GROUP_ID_PACKET_IND };
static bcmbal_obj_group_id group_ids_subscriber_terminal_key[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_KEY };
static bcmbal_obj_group_id group_ids_subscriber_terminal_cfg[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_CFG };
static bcmbal_obj_group_id group_ids_subscriber_terminal_stat[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_STAT };
static bcmbal_obj_group_id group_ids_subscriber_terminal_auto[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_IND };
static bcmbal_obj_group_id group_ids_tm_queue_key[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_KEY };
static bcmbal_obj_group_id group_ids_tm_queue_cfg[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_CFG };
static bcmbal_obj_group_id group_ids_tm_queue_stat[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_STAT };
static bcmbal_obj_group_id group_ids_tm_queue_auto[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_IND };
static bcmbal_obj_group_id group_ids_tm_sched_key[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_KEY };
static bcmbal_obj_group_id group_ids_tm_sched_cfg[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_CFG };
static bcmbal_obj_group_id group_ids_tm_sched_auto[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_IND };
static bcmbal_group_ids group_ids_obj_access_terminal[] = { { 1, group_ids_access_terminal_key }, { 1, group_ids_access_terminal_cfg }, { 0, NULL }, { 1, group_ids_access_terminal_auto }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_flow[] = { { 1, group_ids_flow_key }, { 1, group_ids_flow_cfg }, { 1, group_ids_flow_stat }, { 1, group_ids_flow_auto }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_group[] = { { 1, group_ids_group_key }, { 1, group_ids_group_cfg }, { 0, NULL }, { 0, NULL }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_interface[] = { { 1, group_ids_interface_key }, { 1, group_ids_interface_cfg }, { 1, group_ids_interface_stat }, { 1, group_ids_interface_auto }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_packet[] = { { 1, group_ids_packet_key }, { 1, group_ids_packet_cfg }, { 0, NULL }, { 1, group_ids_packet_auto }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_subscriber_terminal[] = { { 1, group_ids_subscriber_terminal_key }, { 1, group_ids_subscriber_terminal_cfg }, { 1, group_ids_subscriber_terminal_stat }, { 1, group_ids_subscriber_terminal_auto }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_tm_queue[] = { { 1, group_ids_tm_queue_key }, { 1, group_ids_tm_queue_cfg }, { 1, group_ids_tm_queue_stat }, { 1, group_ids_tm_queue_auto }, { 0, NULL } };
static bcmbal_group_ids group_ids_obj_tm_sched[] = { { 1, group_ids_tm_sched_key }, { 1, group_ids_tm_sched_cfg }, { 0, NULL }, { 1, group_ids_tm_sched_auto }, { 0, NULL } };
static bcmbal_group_ids *group_ids[] = { group_ids_obj_access_terminal, group_ids_obj_flow, group_ids_obj_group, group_ids_obj_interface, group_ids_obj_packet, group_ids_obj_subscriber_terminal, group_ids_obj_tm_queue, group_ids_obj_tm_sched };
static bcmbal_presence_mask readonly_prop_mask[] = { (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_OPER_STATUS) | (1ULL << BCMBAL_ACCESS_TERMINAL_CFG_ID_IWF_MODE), 1ULL << BCMBAL_FLOW_CFG_ID_OPER_STATUS, (1ULL << BCMBAL_GROUP_CFG_ID_FLOWS) | (1ULL << BCMBAL_GROUP_CFG_ID_OWNER), (1ULL << BCMBAL_INTERFACE_CFG_ID_OPER_STATUS) | (1ULL << BCMBAL_INTERFACE_CFG_ID_SUB_TERM_ID_LIST), 0, (((1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_OPER_STATUS) | (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID)) | (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_SVC_PORT_ID_LIST)) | (1ULL << BCMBAL_SUBSCRIBER_TERMINAL_CFG_ID_AGG_PORT_ID_LIST), (1ULL << BCMBAL_TM_QUEUE_CFG_ID_CREATION_MODE) | (1ULL << BCMBAL_TM_QUEUE_CFG_ID_REF_COUNT), ((1ULL << BCMBAL_TM_SCHED_CFG_ID_CREATION_MODE) | (1ULL << BCMBAL_TM_SCHED_CFG_ID_QUEUES)) | (1ULL << BCMBAL_TM_SCHED_CFG_ID_SUB_SCHEDS) };
static bcmbal_instance_info instance_info[] = { { offsetof(bcmbal_access_terminal_key, access_term_id), sizeof(bcmbal_access_id) }, { offsetof(bcmbal_flow_key, flow_id), sizeof(bcmbal_flow_id) }, { offsetof(bcmbal_group_key, group_id), sizeof(bcmbal_group_id) }, { offsetof(bcmbal_interface_key, intf_id), sizeof(uint32_t) }, { offsetof(bcmbal_packet_key, reserved), sizeof(uint32_t) }, { offsetof(bcmbal_subscriber_terminal_key, sub_term_id), sizeof(bcmbal_sub_id) }, { offsetof(bcmbal_tm_queue_key, id), sizeof(bcmbal_tm_queue_id) }, { offsetof(bcmbal_tm_sched_key, id), sizeof(bcmbal_tm_sched_id) } };
/** Converts a specific object type, group and subgroup into a generic group ID.
*
* \param obj The object type that corresponds to the group ID.
* \param group The group type that corresponds to the group ID.
* \param subgroup The subgroup index that corresponds to the group ID.
* \param group_id The generic group ID.
* \return An error code or BCM_ERR_OK for success.
*/
static bcmos_errno _bcmbal_obj_group_id_combine(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, bcmbal_obj_group_id *group_id)
{
if ((obj >= BCMBAL_OBJ_ID__NUM_OF) || (group >= BCMBAL_MGT_GROUP__NUM_OF) || (group_ids[obj] == NULL) || (subgroup >= group_ids[obj][group].subgroup_count))
{
return BCM_ERR_RANGE;
}
*group_id = group_ids[obj][group].subgroup_ids[subgroup];
return BCM_ERR_OK;
}
/******************************************************************************/
static bcmos_bool _bcmbal_get_group_info(const bcmbal_obj *msg, bcmbal_group_info **group, bcmbal_group_info **key)
{
bcmbal_obj_group_id group_id;
bcmbal_obj_group_id key_id;
bcmos_errno err;
err = _bcmbal_obj_group_id_combine(msg->obj_type, msg->group, msg->subgroup, &group_id);
if (err != BCM_ERR_OK)
{
return BCMOS_FALSE;
}
err = _bcmbal_obj_group_id_combine(msg->obj_type, BCMBAL_MGT_GROUP_KEY, 0, &key_id);
if (err != BCM_ERR_OK)
{
return BCMOS_FALSE;
}
*group = group_info[group_id];
*key = group_info[key_id];
return BCMOS_TRUE;
}
/** Gets the number of bytes a message would occupy when packed.
*
* \param msg The message to scan.
* \return The size in bytes if > 0, or an error as defined in bcmos_errno.
*/
static int32_t _bcmbal_obj_msg_packed_length_get(bcmbal_obj *msg)
{
uint8_t *key_ptr;
bcmbal_group_info *group;
bcmbal_group_info *key;
int32_t ret;
/* First, get the total length of the packed BAL msg header and the packed BAL object header */
ret = bcmbal_bal_msg_hdr_get_packed_length() + bcmbal_obj_msg_hdr_get_packed_length();
if (!_bcmbal_get_group_info(msg, &group, &key))
{
return (int32_t) BCM_ERR_MSG_ERROR;
}
key_ptr = (uint8_t *) (msg + 1);
/* Add the length of the packed key */
ret += key->get_packed_length(key_ptr, BCMBAL_PRESENCE_MASK_ALL);
/* Add the length of the packed object itself (for those attributes that have been specified, if any) */
if (bcmbal_obj_msg_should_pack_data(msg) && (group->get_packed_length != NULL))
{
uint8_t *data_ptr = (uint8_t *) ((long)msg + group->data_offset);
ret += group->get_packed_length(data_ptr, msg->presence_mask);
}
return ret;
}
/** Packs a message to a byte stream.
*
* \param msg The message to pack.
* \param buf The stream to pack into.
* \return An error code or BCM_ERR_OK for success.
*/
static bcmos_errno _bcmbal_obj_msg_pack(bal_comm_msg_hdr *msg, bcmbal_buf *buf)
{
uint8_t *key_ptr;
bcmos_errno err;
bcmbal_group_info *group;
bcmbal_group_info *key;
bcmbal_obj *bal_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(msg);
if (!_bcmbal_get_group_info(bal_obj, &group, &key))
{
return BCM_ERR_MSG_ERROR;
}
err = bcmbal_bal_msg_hdr_pack(msg, buf);
if (err != BCM_ERR_OK)
{
return err;
}
err = bcmbal_obj_msg_hdr_pack(bal_obj, buf);
if (err != BCM_ERR_OK)
{
return err;
}
key_ptr = (uint8_t *) (bal_obj + 1);
if (!key->pack(key_ptr, buf, BCMBAL_PRESENCE_MASK_ALL))
{
return BCM_ERR_OVERFLOW;
}
if (bcmbal_obj_msg_should_pack_data(bal_obj) && (group->pack != NULL))
{
uint8_t *data_ptr = (uint8_t *) ((long)bal_obj + group->data_offset);
if (!group->pack(data_ptr, buf, bal_obj->presence_mask))
{
return BCM_ERR_OVERFLOW;
}
}
return err;
}
/* scan the input buffer to determine how much memory will be required to unpack variable-sized lists */
static bcmos_errno bcmbal_obj_msg_list_mem_scan(bcmbal_buf *buf, const bcmbal_obj *hdr, const bcmbal_group_info *group, const bcmbal_group_info *key, uint32_t *size)
{
uint32_t pos_before_scan = bcmbal_buf_get_used(buf);
if (!key->mem_scan(buf, size, BCMBAL_PRESENCE_MASK_ALL))
{
return BCM_ERR_OVERFLOW;
}
if (bcmbal_obj_msg_should_pack_data(hdr) && (group->mem_scan != NULL) && !group->mem_scan(buf, size, hdr->presence_mask))
{
return BCM_ERR_OVERFLOW;
}
if (!bcmbal_buf_rewind(buf, bcmbal_buf_get_used(buf) - pos_before_scan))
{
return BCM_ERR_OVERFLOW;
}
return BCM_ERR_OK;
}
/** Unpacks a message from a byte stream.
*
* This unpacks the message from the packed form into the struct following the "unpacked" pointer. There are several
* special cases:
*
* if *unpacked == NULL:
* *unpacked will be allocated dynamically via bcmos_calloc, in a contiguous block of memory with the struct
* itself followed by the memory required for all variable-sized lists.
*
* if (*unpacked)->list_buf != NULL:
* When a variable-length list is encountered in the input stream, and the array field we're unpacking into is NULL,
* memory will be allocated starting from (*unpacked)->list_buf. If multiple such lists exist, they will share this
* buffer. If the (*unpacked)->list_buf_size is not large enough, this will return BCM_ERR_INSUFFICIENT_LIST_MEM.
*
* \param buf The stream to unpack from.
* \param unpacked A pointer to the resulting unpacked BAL message starting at the bal header.
* \return The number of bytes unpacked if > 0, or an error as defined in bcmos_errno.
*/
static int32_t _bcmbal_obj_msg_unpack(bcmbal_buf *buf, bal_comm_msg_hdr **unpacked)
{
bcmbal_obj bal_obj_hdr;
bal_comm_msg_hdr *bal_msg_hdr = &bal_obj_hdr.comm_hdr;
bcmos_errno err;
bcmbal_group_info *group;
bcmbal_group_info *key;
bcmos_bool did_malloc = BCMOS_FALSE;
uint8_t *key_ptr;
void *list_mem = NULL;
void **list_mem_ptr = NULL;
uint32_t size = 0;
bcmbal_obj *unpacked_bal_obj;
/* Preserve header fields that are not packed */
if (*unpacked != NULL)
memcpy(&bal_obj_hdr, bcmbal_payload_ptr_get(*unpacked), sizeof(bal_obj_hdr));
else
memset(&bal_obj_hdr, 0, sizeof(bal_obj_hdr));
err = bcmbal_bal_msg_hdr_unpack(bal_msg_hdr, buf);
if (err != BCM_ERR_OK)
{
return err;
}
err = bcmbal_obj_msg_hdr_unpack(&bal_obj_hdr, buf);
if (err != BCM_ERR_OK)
{
return err;
}
if (!_bcmbal_get_group_info(&bal_obj_hdr, &group, &key))
{
return BCM_ERR_MSG_ERROR;
}
/* If the caller did not allocate a space to unpack into, then alloc one */
if (*unpacked == NULL)
{
size = group->container_size == 0 ? sizeof(bcmbal_obj) + key->size : group->container_size;
err = bcmbal_obj_msg_list_mem_scan(buf, &bal_obj_hdr, group, key, &size);
if (err != BCM_ERR_OK)
{
return err;
}
/* allocate a bal msg header, and a BAL object with data length of "size" */
unpacked_bal_obj = bcmbal_msg_calloc(size);
if (unpacked_bal_obj == NULL)
{
return BCM_ERR_NOMEM;
}
*unpacked = bcmbal_bal_hdr_get(unpacked_bal_obj);
list_mem = (uint8_t *)unpacked_bal_obj + group->container_size;
list_mem_ptr = &list_mem;
did_malloc = BCMOS_TRUE;
}
else
{
unpacked_bal_obj = bcmbal_payload_ptr_get(*unpacked);
if (unpacked_bal_obj->list_buf != NULL)
{
err = bcmbal_obj_msg_list_mem_scan(buf, &bal_obj_hdr, group, key, &size);
if (err != BCM_ERR_OK)
{
return err;
}
if (size > unpacked_bal_obj->list_buf_size)
{
return BCM_ERR_INSUFFICIENT_LIST_MEM;
}
list_mem = unpacked_bal_obj->list_buf;
list_mem_ptr = &list_mem;
}
size += group->container_size == 0 ? sizeof(bcmbal_obj) + key->size : group->container_size;
}
/* copy the bal message header into the unpack buffer */
bal_msg_hdr->m.size = size - sizeof(bcmos_msg);
/* copy the bal object header into the unpack buffer */
*unpacked_bal_obj = bal_obj_hdr;
key_ptr = (uint8_t *) (unpacked_bal_obj + 1);
if (!key->unpack(key_ptr, buf, list_mem_ptr, BCMBAL_PRESENCE_MASK_ALL))
{
if (did_malloc)
{
bcmbal_msg_free(unpacked_bal_obj);
*unpacked = NULL;
}
return BCM_ERR_OVERFLOW;
}
if (bcmbal_obj_msg_should_pack_data(&bal_obj_hdr))
{
uint8_t *data_ptr = (uint8_t *)unpacked_bal_obj + group->data_offset;
if ((group->unpack != NULL) && !group->unpack(data_ptr, buf, list_mem_ptr, unpacked_bal_obj->presence_mask))
{
if (did_malloc)
{
bcmbal_msg_free(unpacked_bal_obj);
*unpacked = NULL;
}
return BCM_ERR_OVERFLOW;
}
}
return size;
}
bcmos_errno bcmbal_obj_msg_pack(bal_comm_msg_hdr *unpacked_bal_msg, /* unpacked msg */ bcmos_msg **packed_msg) /* packed message */
{
bcmbal_buf buf;
bcmos_errno ret;
bcmbal_obj *unpacked_obj;
int32_t packed_payload_len;
uint8_t *packed_payload;
bcmos_msg *os_msg;
*packed_msg = NULL; /* Initialization */
/* Recover a pointer to the UNPACKED bal object */
unpacked_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(unpacked_bal_msg);
/* Calculate packed length */
packed_payload_len = _bcmbal_obj_msg_packed_length_get(unpacked_obj);
if (packed_payload_len < 0) return (bcmos_errno) packed_payload_len;
os_msg = (bcmos_msg *)bcmos_alloc(packed_payload_len + sizeof(bcmos_msg));
if (NULL == os_msg) return BCM_ERR_NORES;
memset(os_msg, 0, sizeof(bcmos_msg));
packed_payload = (uint8_t *) (os_msg + 1);
bcmbal_buf_init(&buf, packed_payload_len, packed_payload);
if (BCM_ERR_OK != (ret = _bcmbal_obj_msg_pack(unpacked_bal_msg, &buf)))
{
bcmos_free(os_msg);
return ret;
}
os_msg->data = packed_payload;
os_msg->size = packed_payload_len;
os_msg->type = unpacked_bal_msg->m.type;
os_msg->instance = unpacked_bal_msg->m.instance;
os_msg->sender = unpacked_bal_msg->m.sender;
*packed_msg = os_msg;
return BCM_ERR_OK;
}
bcmos_errno bcmbal_obj_msg_unpack(bcmos_msg *packed_msg, /* packed message */ bal_comm_msg_hdr **unpacked_bal_msg) /* the unpacked bal msg */
{
bcmbal_buf buf;
int32_t unpacked_len;
bal_comm_msg_hdr *bal_msg_hdr = *unpacked_bal_msg;
uint8_t *packed_payload = packed_msg->data;
uint32_t packed_payload_len = packed_msg->size;
bcmbal_buf_init(&buf, packed_payload_len, packed_payload);
unpacked_len = _bcmbal_obj_msg_unpack(&buf, &bal_msg_hdr);
if (unpacked_len < 0)
{
return (bcmos_errno) unpacked_len;
}
if (((bcmbal_obj *) (bcmbal_payload_ptr_get(bal_msg_hdr)))->version != BCMBAL_OBJ_VERSION)
{
bcmos_printf("Illegal BAL object version detected. Found: %d, Should be:%d\n", ((bcmbal_obj *) (bcmbal_payload_ptr_get(bal_msg_hdr)))->version, BCMBAL_OBJ_VERSION);
return BCM_ERR_PARSE;
}
*unpacked_bal_msg = bal_msg_hdr;
/* NOTE: Do NOT Free the passed in original received message! */
return BCM_ERR_OK;
}
bcmos_errno _bcmbal_obj_group_id_split(bcmbal_obj_group_id group_id, bcmbal_obj_id *obj, bcmbal_mgt_group *group, uint16_t *subgroup)
{
if ((group_id >= BCMBAL_OBJ_GROUP_ID__NUM_OF) || (group_info[group_id] == NULL))
{
return BCM_ERR_RANGE;
}
*obj = group_info[group_id]->obj_type;
*group = group_info[group_id]->group;
*subgroup = group_info[group_id]->subgroup;
return BCM_ERR_OK;
}
/******************************************************************************/
uint8_t bcmbal_obj_msg_instance(const bcmbal_obj *msg)
{
const void *val_ptr;
if (msg->obj_type >= BCMBAL_OBJ_ID__NUM_OF)
{
return 0;
}
if (instance_info[msg->obj_type].offset < 0)
{
return 0;
}
val_ptr = ((const uint8_t *)(msg + 1)) + instance_info[msg->obj_type].offset;
/** This is probably not the smartest way to do this... TODO: revisit */
switch (instance_info[msg->obj_type].size)
{
case 1:
return *((const uint8_t *)val_ptr);
case 2:
return (uint8_t) (*((const uint16_t *)val_ptr));
case 4:
return (uint8_t) (*((const uint32_t *)val_ptr));
case 8:
return (uint8_t) (*((const uint64_t *)val_ptr));
default:
return 0;
}
}
/******************************************************************************/
bcmos_errno bcmbal_obj_msg_clone(bal_comm_msg_hdr **dest, bal_comm_msg_hdr *src)
{
bcmos_errno err;
int32_t packed_obj_msg_len;
uint8_t *mem;
bcmbal_buf buf;
packed_obj_msg_len = _bcmbal_obj_msg_packed_length_get(bcmbal_payload_ptr_get(src));
if (packed_obj_msg_len < 0)
{
return (bcmos_errno) packed_obj_msg_len;
}
/* Allocate a BAL msg (this includes the BAL msg hdr PLUS the BAL object) */
mem = bcmos_calloc((uint32_t) packed_obj_msg_len);
if (mem == NULL)
{
return BCM_ERR_NOMEM;
}
bcmbal_buf_init(&buf, (uint32_t) packed_obj_msg_len, mem);
err = _bcmbal_obj_msg_pack(src, &buf);
if (err != BCM_ERR_OK)
{
bcmos_free(mem);
return err;
}
buf.curr = buf.start;
err = _bcmbal_obj_msg_unpack(&buf, dest);
bcmos_free(mem);
return err;
}
/******************************************************************************/
bcmos_errno bcmbal_get_prop_readonly_mask(bcmbal_obj_id obj, bcmbal_presence_mask *mask)
{
if (obj >= BCMBAL_OBJ_ID__NUM_OF)
{
return BCM_ERR_RANGE;
}
*mask = readonly_prop_mask[obj];
return BCM_ERR_OK;
}