blob: 5f24b26a932ae4ea652bd87563adf8e492f3d7b1 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/*
2<:copyright-BRCM:2016:DUAL/GPL:standard
3
4 Broadcom Proprietary and Confidential.(c) 2016 Broadcom
5 All Rights Reserved
6
7Unless you and Broadcom execute a separate written software license
8agreement governing use of this software, this software is licensed
9to you under the terms of the GNU General Public License version 2
10(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
11with the following added to such license:
12
13 As a special exception, the copyright holders of this software give
14 you permission to link this software with independent modules, and
15 to copy and distribute the resulting executable under terms of your
16 choice, provided that you also meet, for each linked independent
17 module, the terms and conditions of the license of that module.
18 An independent module is a module which is not derived from this
19 software. The special exception does not apply to any modifications
20 of the software.
21
22Not withstanding the above, under no circumstances may you combine
23this software in any way with any other Broadcom software provided
24under a license other than the GPL, without Broadcom's express prior
25written consent.
26
27:>
28 */
29
30#ifndef BCMOLT_MSG_H_
31#define BCMOLT_MSG_H_
32
33#include "bcmos_system.h"
34#include "bcmolt_buf.h"
35#include "bcmolt_model_ids.h"
36#include "bcm_dev_log_task.h"
37
38/** \defgroup \api_data_types Data Types
39 * \ingroup api
40 * @{
41 */
42
43/** Device ID */
44typedef uint8_t bcmolt_devid;
45
46/** Bitmask of fields that are present in a message */
47typedef uint64_t bcmolt_presence_mask;
48
49/** Presence mask indicating all fields present */
50#define BCMOLT_PRESENCE_MASK_ALL ((bcmolt_presence_mask)0xFFFFFFFFFFFFFFFF)
51
52/** Message direction - request or response */
53typedef enum bcmolt_msg_dir
54{
55 BCMOLT_MSG_DIR_REQUEST,
56 BCMOLT_MSG_DIR_RESPONSE
57} bcmolt_msg_dir;
58
59/** Message type. Can be a combination of flags */
60typedef enum bcmolt_msg_type
61{
62 BCMOLT_MSG_TYPE_GET = 0x01, /**< Get: configuration or statistics */
63 BCMOLT_MSG_TYPE_SET = 0x02, /**< Set: Configuration, Statistics, Auto, Proxy */
64 BCMOLT_MSG_TYPE_CLEAR= 0x04, /**< Clear: configuration */
65 BCMOLT_MSG_TYPE_MULTI= 0x08, /**< Multi-object: configuration, statistics */
66
67 BCMOLT_MSG_TYPE_GET_MULTI = BCMOLT_MSG_TYPE_GET | BCMOLT_MSG_TYPE_MULTI,
68} bcmolt_msg_type;
69
70/** Management group - key, config, operation, etc */
71typedef enum bcmolt_mgt_group
72{
73 BCMOLT_MGT_GROUP_KEY, /**< key that uniquely identifies object instance */
74 BCMOLT_MGT_GROUP_CFG, /**< Configuration */
75 BCMOLT_MGT_GROUP_STAT, /**< Statistics */
76 BCMOLT_MGT_GROUP_STAT_CFG, /**< Statistics threshold configuration */
77 BCMOLT_MGT_GROUP_AUTO, /**< Autonomous indications */
78 BCMOLT_MGT_GROUP_AUTO_CFG, /**< Autonomous indication configuration */
79 BCMOLT_MGT_GROUP_OPER, /**< Operations */
80 BCMOLT_MGT_GROUP_PROXY, /**< Messages to ONU */
81 BCMOLT_MGT_GROUP_PROXY_RX, /**< Messages from ONU */
82 BCMOLT_MGT_GROUP__NUM_OF
83} bcmolt_mgt_group;
84
85/** Any object */
86#define BCMOLT_OBJECT_ANY (bcmolt_obj_id)0xffff
87
88/** Any group */
89#define BCMOLT_MGT_GROUP_ANY (bcmolt_mgt_group)0xffff
90
91/** Any subgroup */
92#define BCMOLT_SUBGROUP_ANY 0xffff
93
94/** Indicator that no fields contained errors */
95#define BCMOLT_ERR_FIELD_NONE 0xffff
96
97/** Max error text length */
98#define BCMOLT_MAX_ERR_TEXT_LENGTH 256
99
100/* Transport sub-channel handle */
101typedef uint16_t bcmolt_subchannel;
102
103/** Message set - for multi-instance APIs */
104typedef struct bcmolt_msg_set bcmolt_msg_set;
105
106/** Common message header */
107typedef struct bcmolt_msg
108{
109 bcmolt_obj_id obj_type; /**< Object type */
110 bcmolt_mgt_group group; /**< Management group */
111 uint16_t subgroup; /**< Subgroup: for operations, autonomous messages, proxy */
112 bcmolt_msg_type type; /**< Set, Get, Clear */
113 bcmolt_msg_dir dir; /**< Request/autonomous or Response */
114 bcmos_errno err; /**< Remote error code */
115 uint16_t err_field_idx; /**< If not BCMOLT_ERR_FIELD_NONE, index of erroneous field within struct */
116 uint16_t corr_tag; /**< Correlation tag */
117 bcmolt_presence_mask presence_mask; /**< Indicates which parameters are present */
118 char err_text[BCMOLT_MAX_ERR_TEXT_LENGTH]; /**< Error text - if err != 0 */
119 /* The following fields are internal. They are not sent on the line */
120 bcmolt_subchannel subch; /* Transport sub-channel via which the message arrived */
121 bcmos_msg os_msg; /* Internal OS message for easy task routing */
122 void *list_buf; /* Memory buffer in which to store variable-sized lists when unpacking */
123 uint32_t list_buf_size; /* Number of bytes in the variable-sized list buffer */
124 bcmolt_msg_set *msg_set; /* Message set the message belongs to */
125} bcmolt_msg;
126
127/** Configuration group message header */
128typedef struct bcmolt_cfg
129{
130 bcmolt_msg hdr; /** Common header */
131} bcmolt_cfg;
132
133/** Statistic flags */
134typedef enum
135{
136 BCMOLT_STAT_FLAGS_NONE = 0x0000, /**< No statistics options set (no clear on read, etc) */
137 BCMOLT_STAT_FLAGS_CLEAR_ON_READ = 0x0001, /**< Clear the requested statistics as part of the read operation */
138} bcmolt_stat_flags;
139
140/** Statistics group message header */
141typedef struct bcmolt_stat
142{
143 bcmolt_msg hdr; /** Common header */
144} bcmolt_stat;
145
146/** Statistics configuration message header */
147typedef struct bcmolt_stat_cfg
148{
149 bcmolt_msg hdr; /** Common header */
150} bcmolt_stat_cfg;
151
152/** Operation group message header */
153typedef struct bcmolt_oper
154{
155 bcmolt_msg hdr; /** Common header */
156} bcmolt_oper;
157
158/** Autonomous message header */
159typedef struct bcmolt_auto
160{
161 bcmolt_msg hdr; /** Common header */
162} bcmolt_auto;
163
164/** Autonomous message configuration header */
165typedef struct bcmolt_auto_cfg
166{
167 bcmolt_msg hdr; /** Common header */
168} bcmolt_auto_cfg;
169
170/** Message handler */
171typedef void (*f_bcmolt_msg_handler)(bcmolt_devid olt, bcmolt_msg *msg);
172
173/** Autonomous message flags */
174typedef enum
175{
176 BCMOLT_AUTO_FLAGS_NONE = 0, /**< Invoke callback in context of RX task */
177 BCMOLT_AUTO_FLAGS_DISPATCH = 0x0001, /**< Dispatch message to application module */
178} bcmolt_auto_flags;
179
180/** Proxy message header */
181typedef struct bcmolt_proxy
182{
183 bcmolt_msg hdr; /** Common header */
184} bcmolt_proxy;
185
186/** Proxy RX message header */
187typedef struct bcmolt_proxy_rx
188{
189 bcmolt_msg hdr; /** Common header */
190} bcmolt_proxy_rx;
191
192/** Filter flags */
193typedef enum
194{
195 BCMOLT_FILTER_FLAGS_NONE = 0,
196 BCMOLT_FILTER_FLAGS_INVERT_SELECTION = 0x00000001 /** Return objects NOT selected by filter */
197} bcmolt_filter_flags;
198
199/* Message set */
200struct bcmolt_msg_set
201{
202 uint16_t max_instances; /**< Max number of instances in the set. Set when set is created and doesn't change */
203 bcmolt_mgt_group group; /**< Management group */
204 bcmolt_presence_mask presence_mask; /**< Indicates which parameters should be fetched */
205 bcmolt_filter_flags filter_flags; /**< Filter flags */
206
207 /* Multi-msg API output */
208 uint16_t num_instances; /**< Number of instances in the set. */
209 bcmos_bool more; /**< BCMOS_TRUE if not all instances have been retrieved by the last
210 bcmolt_get_multi() call. */
211 void *next_key; /**< Key of the next object instance after those that were returned. Only valid if
212 'more' is BCMOS_FALSE. Treat this as a pointer to the object's key struct. This
213 can be used for subsequent invocations of bcmolt_cfg_get_multiple() by copying this
214 into the filter's key field. */
215#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /**< Check whether C99 is supported */
216 bcmolt_msg *msg[]; /**< Set of API objects returned by bcmolt_cfg_get_multiple(). */
217#else
218 bcmolt_msg *msg[0]; /**< Set of API objects returned by bcmolt_cfg_get_multiple(). */
219#endif
220};
221
222/** @} */
223
224
225/*lint -ecall(633, bcmolt_msg_err) - 4th argument will be a specific enum type, but must be treated as a uint16. */
226/** Set message error. Cannot be static inline, as it uses variable argument list. */
227bcmos_errno bcmolt_msg_err(bcmolt_msg *msg, dev_log_id log_id, bcmos_errno err, uint16_t err_field_idx, const char *fmt, ...)__attribute__((format(__printf__, 5, 6)));
228
229/** Whether we pack the entire structure of a message */
230static inline bcmos_bool bcmolt_msg_should_pack_data(const bcmolt_msg *msg)
231{
232 switch (msg->group)
233 {
234 case BCMOLT_MGT_GROUP_CFG:
235 case BCMOLT_MGT_GROUP_STAT:
236 case BCMOLT_MGT_GROUP_STAT_CFG:
237 case BCMOLT_MGT_GROUP_AUTO_CFG:
238 if ((msg->type & BCMOLT_MSG_TYPE_GET))
239 {
240 bcmos_bool should_pack = (msg->dir == BCMOLT_MSG_DIR_RESPONSE);
241 /* For multi-message get request should_pack must be inverted because the 1st part
242 * of multi-object request is filter
243 */
244 return (msg->type & BCMOLT_MSG_TYPE_MULTI) ? !should_pack : should_pack;
245 }
246 else if ((msg->type & BCMOLT_MSG_TYPE_SET))
247 {
248 return (msg->dir == BCMOLT_MSG_DIR_REQUEST);
249 }
250 else
251 {
252 return BCMOS_FALSE;
253 }
254
255 case BCMOLT_MGT_GROUP_OPER:
256 case BCMOLT_MGT_GROUP_PROXY:
257 return (msg->dir == BCMOLT_MSG_DIR_REQUEST);
258
259 default:
260 return BCMOS_TRUE;
261 }
262}
263
264/** Get the length of the header portion of a message */
265static inline int32_t bcmolt_msg_hdr_get_packed_length(const bcmolt_msg *msg)
266{
267 return 18 + (msg->err ? strlen(msg->err_text) + 2 : 0);
268}
269
270/** Pack a message header to a byte stream */
271static inline bcmos_errno bcmolt_msg_hdr_pack(const bcmolt_msg *msg, bcmolt_buf *buf)
272{
273 bcmos_bool ret;
274
275 ret = bcmolt_buf_write_u8(buf, (uint8_t)msg->obj_type);
276 ret = ret && bcmolt_buf_write_u8(buf, (uint8_t)msg->group);
277 ret = ret && bcmolt_buf_write_u16(buf, msg->subgroup);
278 ret = ret && bcmolt_buf_write_u8(buf, (uint8_t)msg->type);
279 ret = ret && bcmolt_buf_write_u8(buf, (uint8_t)msg->dir);
280 ret = ret && bcmolt_buf_write_s16(buf, (int16_t)msg->err);
281 ret = ret && bcmolt_buf_write_u64(buf, (uint64_t)msg->presence_mask);
282 ret = ret && bcmolt_buf_write_u16(buf, msg->err_field_idx);
283 if (msg->err)
284 {
285 uint16_t len = strlen(msg->err_text);
286 ret = ret && bcmolt_buf_write_u16(buf, len);
287 ret = ret && bcmolt_buf_write(buf, msg->err_text, len);
288 }
289
290 return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
291}
292
293/** Unpack a message header from a byte stream */
294static inline bcmos_errno bcmolt_msg_hdr_unpack(bcmolt_msg *msg, bcmolt_buf *buf)
295{
296 uint8_t obj_type;
297 uint8_t group;
298 uint16_t subgroup;
299 uint8_t type;
300 uint8_t dir;
301 int16_t err = 0;
302 uint64_t presence_mask;
303 uint16_t err_field_idx;
304 bcmos_bool ret;
305
306 ret = bcmolt_buf_read_u8(buf, &obj_type);
307 ret = ret && bcmolt_buf_read_u8(buf, &group);
308 ret = ret && bcmolt_buf_read_u16(buf, &subgroup);
309 ret = ret && bcmolt_buf_read_u8(buf, &type);
310 ret = ret && bcmolt_buf_read_u8(buf, &dir);
311 ret = ret && bcmolt_buf_read_s16(buf, &err);
312 ret = ret && bcmolt_buf_read_u64(buf, &presence_mask);
313 ret = ret && bcmolt_buf_read_u16(buf, &err_field_idx);
314 if (err)
315 {
316 uint16_t len = 0;
317 ret = ret && bcmolt_buf_read_u16(buf, &len);
318 if (len >= sizeof(msg->err_text))
319 len = sizeof(msg->err_text) - 1;
320 ret = ret && bcmolt_buf_read(buf, msg->err_text, len);
321 msg->err_text[len] = 0;
322 }
323 else
324 {
325 msg->err_text[0] = 0;
326 }
327
328 if (ret)
329 {
330 msg->obj_type = (bcmolt_obj_id)obj_type;
331 msg->group = (bcmolt_mgt_group)group;
332 msg->subgroup = subgroup;
333 msg->type = (bcmolt_msg_type)type;
334 msg->dir = (bcmolt_msg_dir)dir;
335 msg->err = (bcmos_errno)err;
336 msg->presence_mask = (bcmolt_presence_mask)presence_mask;
337 msg->err_field_idx = err_field_idx;
338 msg->msg_set = NULL;
339 }
340
341 return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
342}
343
344/* Create message set
345 *
346 * \param[in] obj Object id
347 * \param[in] group Management group
348 * \param[in] max_instances Max number of objects returned by a single API call
349 * \param[out] msg_set Message set
350 * \returns error code
351 */
352bcmos_errno bcmolt_msg_set_alloc(bcmolt_obj_id obj, bcmolt_mgt_group group,
353 uint32_t max_instances, bcmolt_msg_set **msg_set);
354
355/* Release message set
356 * \param[in] msg_set
357 */
358void bcmolt_msg_set_free(bcmolt_msg_set *msg_set);
359
360/* Release dynamically allocated message.
361 */
362static inline void bcmolt_msg_free(bcmolt_msg *msg)
363{
364 if (msg->msg_set)
365 {
366 bcmolt_msg_set_free(msg->msg_set);
367 }
368 bcmos_free(msg);
369}
370
371static inline void bcmolt_os_msg_release_cb(bcmos_msg *os_msg)
372{
373 bcmolt_msg *msg = os_msg->data;
374
375 /* We can be here if target module or transport queue overflows.
376 Release the message
377 */
378 bcmolt_msg_free(msg);
379}
380
381static inline bcmos_module_id bcmos_module_id_for_device(bcmos_module_id module, bcmolt_devid devid)
382{
383 return module + (bcmos_module_id)devid;
384}
385#endif