blob: 519af971c5b7aae5935564daead9a5fac76a3c1b [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001#include <bcmos_system.h>
2#include <bal_msg.h>
3#include "bal_obj_msg_pack_unpack.h"
4
5typedef uint32_t (*bcmbal_func_packed_len) (void *this, bcmbal_presence_mask fields_present);
6typedef bcmos_bool (*bcmbal_func_pack) (void *this, bcmbal_buf *buf, bcmbal_presence_mask fields_present);
7typedef bcmos_bool (*bcmbal_func_unpack) (void *this, bcmbal_buf *buf, void **extra_mem, bcmbal_presence_mask fields_present);
8typedef bcmos_bool (*bcmbal_func_mem_scan) (bcmbal_buf * buf, uint32_t * extra_mem, bcmbal_presence_mask fields_present);
9
10/******************************************************************************/
11typedef struct bcmbal_group_info
12{
13 bcmbal_obj_id obj_type;
14 bcmbal_mgt_group group;
15 uint16_t subgroup;
16 uint32_t size;
17 uint32_t container_size; /* sizeof() the key/data container struct (0 for key groups) */
18 uint32_t data_offset; /* offsetof() data field within container struct (0 for key groups) */
19 bcmbal_func_packed_len get_packed_length;
20 bcmbal_func_pack pack;
21 bcmbal_func_unpack unpack;
22 bcmbal_func_mem_scan mem_scan;
23} bcmbal_group_info;
24
25/******************************************************************************/
26typedef struct bcmbal_group_ids
27{
28 uint32_t subgroup_count;
29 bcmbal_obj_group_id *subgroup_ids;
30} bcmbal_group_ids;
31
32/******************************************************************************/
33typedef struct bcmbal_instance_info
34{
35 int8_t offset;
36 int8_t size;
37} bcmbal_instance_info;
38
39/******************************************************************************/
40static 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 };
41static 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 };
42static 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 };
43static 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 };
44static 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 };
45static 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 };
46static 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 };
47static 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 };
48static 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 };
49static 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 };
50static 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 };
51static 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 };
52static 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 };
53static 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 };
54static 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 };
55static 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 };
56static 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 };
57static 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 };
58static 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 };
59static 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 };
60static 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 };
61static 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 };
62static 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 };
63static 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 };
64static 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 };
65static 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 };
66static 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 };
67static 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 };
68static bcmbal_obj_group_id group_ids_access_terminal_key[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_KEY };
69static bcmbal_obj_group_id group_ids_access_terminal_cfg[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_CFG };
70static bcmbal_obj_group_id group_ids_access_terminal_auto[] = { BCMBAL_OBJ_GROUP_ID_ACCESS_TERMINAL_IND };
71static bcmbal_obj_group_id group_ids_flow_key[] = { BCMBAL_OBJ_GROUP_ID_FLOW_KEY };
72static bcmbal_obj_group_id group_ids_flow_cfg[] = { BCMBAL_OBJ_GROUP_ID_FLOW_CFG };
73static bcmbal_obj_group_id group_ids_flow_stat[] = { BCMBAL_OBJ_GROUP_ID_FLOW_STAT };
74static bcmbal_obj_group_id group_ids_flow_auto[] = { BCMBAL_OBJ_GROUP_ID_FLOW_IND };
75static bcmbal_obj_group_id group_ids_group_key[] = { BCMBAL_OBJ_GROUP_ID_GROUP_KEY };
76static bcmbal_obj_group_id group_ids_group_cfg[] = { BCMBAL_OBJ_GROUP_ID_GROUP_CFG };
77static bcmbal_obj_group_id group_ids_interface_key[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_KEY };
78static bcmbal_obj_group_id group_ids_interface_cfg[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_CFG };
79static bcmbal_obj_group_id group_ids_interface_stat[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_STAT };
80static bcmbal_obj_group_id group_ids_interface_auto[] = { BCMBAL_OBJ_GROUP_ID_INTERFACE_IND };
81static bcmbal_obj_group_id group_ids_packet_key[] = { BCMBAL_OBJ_GROUP_ID_PACKET_KEY };
82static bcmbal_obj_group_id group_ids_packet_cfg[] = { BCMBAL_OBJ_GROUP_ID_PACKET_CFG };
83static bcmbal_obj_group_id group_ids_packet_auto[] = { BCMBAL_OBJ_GROUP_ID_PACKET_IND };
84static bcmbal_obj_group_id group_ids_subscriber_terminal_key[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_KEY };
85static bcmbal_obj_group_id group_ids_subscriber_terminal_cfg[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_CFG };
86static bcmbal_obj_group_id group_ids_subscriber_terminal_stat[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_STAT };
87static bcmbal_obj_group_id group_ids_subscriber_terminal_auto[] = { BCMBAL_OBJ_GROUP_ID_SUBSCRIBER_TERMINAL_IND };
88static bcmbal_obj_group_id group_ids_tm_queue_key[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_KEY };
89static bcmbal_obj_group_id group_ids_tm_queue_cfg[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_CFG };
90static bcmbal_obj_group_id group_ids_tm_queue_stat[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_STAT };
91static bcmbal_obj_group_id group_ids_tm_queue_auto[] = { BCMBAL_OBJ_GROUP_ID_TM_QUEUE_IND };
92static bcmbal_obj_group_id group_ids_tm_sched_key[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_KEY };
93static bcmbal_obj_group_id group_ids_tm_sched_cfg[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_CFG };
94static bcmbal_obj_group_id group_ids_tm_sched_auto[] = { BCMBAL_OBJ_GROUP_ID_TM_SCHED_IND };
95static 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 } };
96static 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 } };
97static bcmbal_group_ids group_ids_obj_group[] = { { 1, group_ids_group_key }, { 1, group_ids_group_cfg }, { 0, NULL }, { 0, NULL }, { 0, NULL } };
98static 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 } };
99static 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 } };
100static 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 } };
101static 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 } };
102static 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 } };
103static 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 };
104static 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) };
105static 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) } };
106
107/** Converts a specific object type, group and subgroup into a generic group ID.
108 *
109 * \param obj The object type that corresponds to the group ID.
110 * \param group The group type that corresponds to the group ID.
111 * \param subgroup The subgroup index that corresponds to the group ID.
112 * \param group_id The generic group ID.
113 * \return An error code or BCM_ERR_OK for success.
114 */
115static bcmos_errno _bcmbal_obj_group_id_combine(bcmbal_obj_id obj, bcmbal_mgt_group group, uint16_t subgroup, bcmbal_obj_group_id *group_id)
116{
117 if ((obj >= BCMBAL_OBJ_ID__NUM_OF) || (group >= BCMBAL_MGT_GROUP__NUM_OF) || (group_ids[obj] == NULL) || (subgroup >= group_ids[obj][group].subgroup_count))
118 {
119 return BCM_ERR_RANGE;
120 }
121
122 *group_id = group_ids[obj][group].subgroup_ids[subgroup];
123 return BCM_ERR_OK;
124}
125
126/******************************************************************************/
127static bcmos_bool _bcmbal_get_group_info(const bcmbal_obj *msg, bcmbal_group_info **group, bcmbal_group_info **key)
128{
129 bcmbal_obj_group_id group_id;
130 bcmbal_obj_group_id key_id;
131 bcmos_errno err;
132
133 err = _bcmbal_obj_group_id_combine(msg->obj_type, msg->group, msg->subgroup, &group_id);
134 if (err != BCM_ERR_OK)
135 {
136 return BCMOS_FALSE;
137 }
138
139 err = _bcmbal_obj_group_id_combine(msg->obj_type, BCMBAL_MGT_GROUP_KEY, 0, &key_id);
140 if (err != BCM_ERR_OK)
141 {
142 return BCMOS_FALSE;
143 }
144
145 *group = group_info[group_id];
146 *key = group_info[key_id];
147 return BCMOS_TRUE;
148}
149
150/** Gets the number of bytes a message would occupy when packed.
151 *
152 * \param msg The message to scan.
153 * \return The size in bytes if > 0, or an error as defined in bcmos_errno.
154 */
155static int32_t _bcmbal_obj_msg_packed_length_get(bcmbal_obj *msg)
156{
157 uint8_t *key_ptr;
158 bcmbal_group_info *group;
159 bcmbal_group_info *key;
160 int32_t ret;
161
162 /* First, get the total length of the packed BAL msg header and the packed BAL object header */
163 ret = bcmbal_bal_msg_hdr_get_packed_length() + bcmbal_obj_msg_hdr_get_packed_length();
164
165 if (!_bcmbal_get_group_info(msg, &group, &key))
166 {
167 return (int32_t) BCM_ERR_MSG_ERROR;
168 }
169
170 key_ptr = (uint8_t *) (msg + 1);
171
172 /* Add the length of the packed key */
173 ret += key->get_packed_length(key_ptr, BCMBAL_PRESENCE_MASK_ALL);
174
175 /* Add the length of the packed object itself (for those attributes that have been specified, if any) */
176 if (bcmbal_obj_msg_should_pack_data(msg) && (group->get_packed_length != NULL))
177 {
178 uint8_t *data_ptr = (uint8_t *) ((long)msg + group->data_offset);
179 ret += group->get_packed_length(data_ptr, msg->presence_mask);
180 }
181
182 return ret;
183}
184
185/** Packs a message to a byte stream.
186 *
187 * \param msg The message to pack.
188 * \param buf The stream to pack into.
189 * \return An error code or BCM_ERR_OK for success.
190 */
191static bcmos_errno _bcmbal_obj_msg_pack(bal_comm_msg_hdr *msg, bcmbal_buf *buf)
192{
193 uint8_t *key_ptr;
194 bcmos_errno err;
195 bcmbal_group_info *group;
196 bcmbal_group_info *key;
197 bcmbal_obj *bal_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(msg);
198
199 if (!_bcmbal_get_group_info(bal_obj, &group, &key))
200 {
201 return BCM_ERR_MSG_ERROR;
202 }
203
204 err = bcmbal_bal_msg_hdr_pack(msg, buf);
205 if (err != BCM_ERR_OK)
206 {
207 return err;
208 }
209
210 err = bcmbal_obj_msg_hdr_pack(bal_obj, buf);
211 if (err != BCM_ERR_OK)
212 {
213 return err;
214 }
215
216 key_ptr = (uint8_t *) (bal_obj + 1);
217 if (!key->pack(key_ptr, buf, BCMBAL_PRESENCE_MASK_ALL))
218 {
219 return BCM_ERR_OVERFLOW;
220 }
221
222 if (bcmbal_obj_msg_should_pack_data(bal_obj) && (group->pack != NULL))
223 {
224 uint8_t *data_ptr = (uint8_t *) ((long)bal_obj + group->data_offset);
225 if (!group->pack(data_ptr, buf, bal_obj->presence_mask))
226 {
227 return BCM_ERR_OVERFLOW;
228 }
229 }
230
231 return err;
232}
233
234/* scan the input buffer to determine how much memory will be required to unpack variable-sized lists */
235static 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)
236{
237 uint32_t pos_before_scan = bcmbal_buf_get_used(buf);
238
239 if (!key->mem_scan(buf, size, BCMBAL_PRESENCE_MASK_ALL))
240 {
241 return BCM_ERR_OVERFLOW;
242 }
243
244 if (bcmbal_obj_msg_should_pack_data(hdr) && (group->mem_scan != NULL) && !group->mem_scan(buf, size, hdr->presence_mask))
245 {
246 return BCM_ERR_OVERFLOW;
247 }
248
249 if (!bcmbal_buf_rewind(buf, bcmbal_buf_get_used(buf) - pos_before_scan))
250 {
251 return BCM_ERR_OVERFLOW;
252 }
253
254 return BCM_ERR_OK;
255}
256
257/** Unpacks a message from a byte stream.
258 *
259 * This unpacks the message from the packed form into the struct following the "unpacked" pointer. There are several
260 * special cases:
261 *
262 * if *unpacked == NULL:
263 * *unpacked will be allocated dynamically via bcmos_calloc, in a contiguous block of memory with the struct
264 * itself followed by the memory required for all variable-sized lists.
265 *
266 * if (*unpacked)->list_buf != NULL:
267 * When a variable-length list is encountered in the input stream, and the array field we're unpacking into is NULL,
268 * memory will be allocated starting from (*unpacked)->list_buf. If multiple such lists exist, they will share this
269 * buffer. If the (*unpacked)->list_buf_size is not large enough, this will return BCM_ERR_INSUFFICIENT_LIST_MEM.
270 *
271 * \param buf The stream to unpack from.
272 * \param unpacked A pointer to the resulting unpacked BAL message starting at the bal header.
273 * \return The number of bytes unpacked if > 0, or an error as defined in bcmos_errno.
274 */
275static int32_t _bcmbal_obj_msg_unpack(bcmbal_buf *buf, bal_comm_msg_hdr **unpacked)
276{
277 bcmbal_obj bal_obj_hdr;
278 bal_comm_msg_hdr *bal_msg_hdr = &bal_obj_hdr.comm_hdr;
279 bcmos_errno err;
280 bcmbal_group_info *group;
281 bcmbal_group_info *key;
282 bcmos_bool did_malloc = BCMOS_FALSE;
283 uint8_t *key_ptr;
284 void *list_mem = NULL;
285 void **list_mem_ptr = NULL;
286 uint32_t size = 0;
287 bcmbal_obj *unpacked_bal_obj;
288
289 /* Preserve header fields that are not packed */
290 if (*unpacked != NULL)
291 memcpy(&bal_obj_hdr, bcmbal_payload_ptr_get(*unpacked), sizeof(bal_obj_hdr));
292 else
293 memset(&bal_obj_hdr, 0, sizeof(bal_obj_hdr));
294
295 err = bcmbal_bal_msg_hdr_unpack(bal_msg_hdr, buf);
296 if (err != BCM_ERR_OK)
297 {
298 return err;
299 }
300
301 err = bcmbal_obj_msg_hdr_unpack(&bal_obj_hdr, buf);
302 if (err != BCM_ERR_OK)
303 {
304 return err;
305 }
306
307 if (!_bcmbal_get_group_info(&bal_obj_hdr, &group, &key))
308 {
309 return BCM_ERR_MSG_ERROR;
310 }
311
312 /* If the caller did not allocate a space to unpack into, then alloc one */
313 if (*unpacked == NULL)
314 {
315 size = group->container_size == 0 ? sizeof(bcmbal_obj) + key->size : group->container_size;
316
317 err = bcmbal_obj_msg_list_mem_scan(buf, &bal_obj_hdr, group, key, &size);
318 if (err != BCM_ERR_OK)
319 {
320 return err;
321 }
322
323 /* allocate a bal msg header, and a BAL object with data length of "size" */
324 unpacked_bal_obj = bcmbal_msg_calloc(size);
325 if (unpacked_bal_obj == NULL)
326 {
327 return BCM_ERR_NOMEM;
328 }
329
330 *unpacked = bcmbal_bal_hdr_get(unpacked_bal_obj);
331
332 list_mem = (uint8_t *)unpacked_bal_obj + group->container_size;
333 list_mem_ptr = &list_mem;
334 did_malloc = BCMOS_TRUE;
335 }
336 else
337 {
338 unpacked_bal_obj = bcmbal_payload_ptr_get(*unpacked);
339
340 if (unpacked_bal_obj->list_buf != NULL)
341 {
342 err = bcmbal_obj_msg_list_mem_scan(buf, &bal_obj_hdr, group, key, &size);
343 if (err != BCM_ERR_OK)
344 {
345 return err;
346 }
347
348 if (size > unpacked_bal_obj->list_buf_size)
349 {
350 return BCM_ERR_INSUFFICIENT_LIST_MEM;
351 }
352
353 list_mem = unpacked_bal_obj->list_buf;
354 list_mem_ptr = &list_mem;
355 }
356
357 size += group->container_size == 0 ? sizeof(bcmbal_obj) + key->size : group->container_size;
358 }
359
360 /* copy the bal message header into the unpack buffer */
361 bal_msg_hdr->m.size = size - sizeof(bcmos_msg);
362
363 /* copy the bal object header into the unpack buffer */
364 *unpacked_bal_obj = bal_obj_hdr;
365
366 key_ptr = (uint8_t *) (unpacked_bal_obj + 1);
367 if (!key->unpack(key_ptr, buf, list_mem_ptr, BCMBAL_PRESENCE_MASK_ALL))
368 {
369 if (did_malloc)
370 {
371 bcmbal_msg_free(unpacked_bal_obj);
372 *unpacked = NULL;
373 }
374
375 return BCM_ERR_OVERFLOW;
376 }
377
378 if (bcmbal_obj_msg_should_pack_data(&bal_obj_hdr))
379 {
380 uint8_t *data_ptr = (uint8_t *)unpacked_bal_obj + group->data_offset;
381 if ((group->unpack != NULL) && !group->unpack(data_ptr, buf, list_mem_ptr, unpacked_bal_obj->presence_mask))
382 {
383 if (did_malloc)
384 {
385 bcmbal_msg_free(unpacked_bal_obj);
386 *unpacked = NULL;
387 }
388
389 return BCM_ERR_OVERFLOW;
390 }
391 }
392
393 return size;
394}
395
396bcmos_errno bcmbal_obj_msg_pack(bal_comm_msg_hdr *unpacked_bal_msg, /* unpacked msg */ bcmos_msg **packed_msg) /* packed message */
397{
398 bcmbal_buf buf;
399 bcmos_errno ret;
400 bcmbal_obj *unpacked_obj;
401 int32_t packed_payload_len;
402 uint8_t *packed_payload;
403 bcmos_msg *os_msg;
404
405 *packed_msg = NULL; /* Initialization */
406
407 /* Recover a pointer to the UNPACKED bal object */
408 unpacked_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(unpacked_bal_msg);
409
410 /* Calculate packed length */
411 packed_payload_len = _bcmbal_obj_msg_packed_length_get(unpacked_obj);
412 if (packed_payload_len < 0) return (bcmos_errno) packed_payload_len;
413
414 os_msg = (bcmos_msg *)bcmos_alloc(packed_payload_len + sizeof(bcmos_msg));
415
416 if (NULL == os_msg) return BCM_ERR_NORES;
417
418 memset(os_msg, 0, sizeof(bcmos_msg));
419 packed_payload = (uint8_t *) (os_msg + 1);
420 bcmbal_buf_init(&buf, packed_payload_len, packed_payload);
421 if (BCM_ERR_OK != (ret = _bcmbal_obj_msg_pack(unpacked_bal_msg, &buf)))
422 {
423 bcmos_free(os_msg);
424 return ret;
425 }
426
427 os_msg->data = packed_payload;
428 os_msg->size = packed_payload_len;
429 os_msg->type = unpacked_bal_msg->m.type;
430 os_msg->instance = unpacked_bal_msg->m.instance;
431 os_msg->sender = unpacked_bal_msg->m.sender;
432 *packed_msg = os_msg;
433
434 return BCM_ERR_OK;
435}
436
437bcmos_errno bcmbal_obj_msg_unpack(bcmos_msg *packed_msg, /* packed message */ bal_comm_msg_hdr **unpacked_bal_msg) /* the unpacked bal msg */
438{
439 bcmbal_buf buf;
440 int32_t unpacked_len;
441 bal_comm_msg_hdr *bal_msg_hdr = *unpacked_bal_msg;
442 uint8_t *packed_payload = packed_msg->data;
443 uint32_t packed_payload_len = packed_msg->size;
444
445 bcmbal_buf_init(&buf, packed_payload_len, packed_payload);
446
447 unpacked_len = _bcmbal_obj_msg_unpack(&buf, &bal_msg_hdr);
448
449 if (unpacked_len < 0)
450 {
451 return (bcmos_errno) unpacked_len;
452 }
453
454 if (((bcmbal_obj *) (bcmbal_payload_ptr_get(bal_msg_hdr)))->version != BCMBAL_OBJ_VERSION)
455 {
456 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);
457
458 return BCM_ERR_PARSE;
459 }
460
461 *unpacked_bal_msg = bal_msg_hdr;
462
463 /* NOTE: Do NOT Free the passed in original received message! */
464 return BCM_ERR_OK;
465}
466
467bcmos_errno _bcmbal_obj_group_id_split(bcmbal_obj_group_id group_id, bcmbal_obj_id *obj, bcmbal_mgt_group *group, uint16_t *subgroup)
468{
469 if ((group_id >= BCMBAL_OBJ_GROUP_ID__NUM_OF) || (group_info[group_id] == NULL))
470 {
471 return BCM_ERR_RANGE;
472 }
473
474 *obj = group_info[group_id]->obj_type;
475 *group = group_info[group_id]->group;
476 *subgroup = group_info[group_id]->subgroup;
477 return BCM_ERR_OK;
478}
479
480/******************************************************************************/
481uint8_t bcmbal_obj_msg_instance(const bcmbal_obj *msg)
482{
483 const void *val_ptr;
484
485 if (msg->obj_type >= BCMBAL_OBJ_ID__NUM_OF)
486 {
487 return 0;
488 }
489
490 if (instance_info[msg->obj_type].offset < 0)
491 {
492 return 0;
493 }
494
495 val_ptr = ((const uint8_t *)(msg + 1)) + instance_info[msg->obj_type].offset;
496
497 /** This is probably not the smartest way to do this... TODO: revisit */
498 switch (instance_info[msg->obj_type].size)
499 {
500 case 1:
501 return *((const uint8_t *)val_ptr);
502 case 2:
503 return (uint8_t) (*((const uint16_t *)val_ptr));
504 case 4:
505 return (uint8_t) (*((const uint32_t *)val_ptr));
506 case 8:
507 return (uint8_t) (*((const uint64_t *)val_ptr));
508 default:
509 return 0;
510 }
511}
512
513/******************************************************************************/
514bcmos_errno bcmbal_obj_msg_clone(bal_comm_msg_hdr **dest, bal_comm_msg_hdr *src)
515{
516 bcmos_errno err;
517 int32_t packed_obj_msg_len;
518 uint8_t *mem;
519 bcmbal_buf buf;
520
521 packed_obj_msg_len = _bcmbal_obj_msg_packed_length_get(bcmbal_payload_ptr_get(src));
522 if (packed_obj_msg_len < 0)
523 {
524 return (bcmos_errno) packed_obj_msg_len;
525 }
526
527 /* Allocate a BAL msg (this includes the BAL msg hdr PLUS the BAL object) */
528 mem = bcmos_calloc((uint32_t) packed_obj_msg_len);
529 if (mem == NULL)
530 {
531 return BCM_ERR_NOMEM;
532 }
533
534 bcmbal_buf_init(&buf, (uint32_t) packed_obj_msg_len, mem);
535 err = _bcmbal_obj_msg_pack(src, &buf);
536 if (err != BCM_ERR_OK)
537 {
538 bcmos_free(mem);
539 return err;
540 }
541
542 buf.curr = buf.start;
543 err = _bcmbal_obj_msg_unpack(&buf, dest);
544 bcmos_free(mem);
545 return err;
546}
547
548/******************************************************************************/
549bcmos_errno bcmbal_get_prop_readonly_mask(bcmbal_obj_id obj, bcmbal_presence_mask *mask)
550{
551 if (obj >= BCMBAL_OBJ_ID__NUM_OF)
552 {
553 return BCM_ERR_RANGE;
554 }
555
556 *mask = readonly_prop_mask[obj];
557 return BCM_ERR_OK;
558}