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