blob: 285be8067cf8018c28fd80ef4b0d06275993f599 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/******************************************************************************
2 *
3 * <:copyright-BRCM:2016:DUAL/GPL:standard
4 *
5 * Copyright (c) 2016 Broadcom
6 * All Rights Reserved
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed
10 * to you under the terms of the GNU General Public License version 2
11 * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
12 * with the following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give
15 * you permission to link this software with independent modules, and
16 * to copy and distribute the resulting executable under terms of your
17 * choice, provided that you also meet, for each linked independent
18 * module, the terms and conditions of the license of that module.
19 * An independent module is a module which is not derived from this
20 * software. The special exception does not apply to any modifications
21 * of the software.
22 *
23 * Not withstanding the above, under no circumstances may you combine
24 * this software in any way with any other Broadcom software provided
25 * under a license other than the GPL, without Broadcom's express prior
26 * written consent.
27 *
28 * :>
29 *
30 *****************************************************************************/
31
32/**
33 * @file bal_msg.c
34 * @brief BAL message helper functions
35 * @addtogroup ctrlr
36 */
37#include <bal_msg.h>
38#include <bal_obj_msg_pack_unpack.h>
39
40/*
41 * Clone BAL message
42 * Returns payload_ptr of the clone
43 */
44void *bcmbal_msg_clone(void *bal_obj)
45{
46 bal_comm_msg_hdr *msg_hdr = bcmbal_bal_hdr_get(bal_obj);
47 bal_comm_msg_hdr *clone_hdr = NULL;
48 bcmos_errno err = bcmbal_obj_msg_clone(&clone_hdr, msg_hdr);
49 return ((int)err >= 0) ? bcmbal_payload_ptr_get(clone_hdr) : NULL;
50}
51
52/*
53 * Send a BAL message given the payload pointer
54 */
55bcmos_errno bcmbal_msg_send(bcmos_msg_queue *queue, void *msg_payload, bcmos_msg_send_flags flags)
56{
57 bcmos_msg *packed_msg = NULL;
58 bcmos_errno err;
59
60 /* pack and send */
61 err = bcmbal_obj_msg_pack(bcmbal_bal_hdr_get(msg_payload), &packed_msg);
62 if (err != BCM_ERR_OK)
63 return err;
64
65 err = bcmos_msg_send(queue, packed_msg, flags);
66
67 if ((flags & BCMOS_MSG_SEND_NO_FREE_ON_ERROR) == 0)
68 {
69 /* Release the original message */
70 bcmbal_msg_free(msg_payload);
71 }
72 else if (err != BCM_ERR_OK)
73 {
74 /* bcmos_msg_send() failed, but packed_msg wasn't released because of the flag. */
75 bcmos_msg_free(packed_msg);
76 }
77
78 return err;
79}
80
81/*
82 * Call callback in the context of the target module and pass it the BAL message pointer
83 */
84bcmos_errno bcmbal_msg_call(void *msg_payload,
85 bcmos_module_id module, F_bcmos_msg_handler cb, bcmos_msg_send_flags flags)
86{
87 bcmos_msg *m = bcmbal_bcmos_hdr_get(msg_payload);
88 m->handler = cb;
89 return bcmos_msg_send_to_module(module, m, flags);
90}
91
92bcmos_errno bcmbal_msg_recv(bcmos_msg_queue *queue, uint32_t timeout, void **msg_payload)
93{
94 bcmos_errno ret;
95 bcmos_msg *msg;
96 bal_comm_msg_hdr *unpacked_msg = (*msg_payload) ? bcmbal_bal_hdr_get(*msg_payload) : NULL;
97
98 do {
99 ret = bcmos_msg_recv(queue, timeout, &msg);
100 if(BCM_ERR_OK != ret)
101 {
102 bcmos_printf("%s: error during bcmos_msg_recv (error:%s)\n",
103 __FUNCTION__,
104 bcmos_strerror(ret));
105 break;
106 }
107
108 /* Got a message. Now unpack it */
109 ret = bcmbal_obj_msg_unpack(msg, &unpacked_msg);
110 bcmos_msg_free(msg); /* release packed message. It is no longer needed */
111 if (BCM_ERR_OK != ret)
112 {
113 bcmos_printf("%s: bcmbal_obj_msg_unpack (error:%s)\n",
114 __FUNCTION__, bcmos_strerror(ret));
115 break;
116 }
117
118 /* If message was allocated in unpack - assign it */
119 if (! *msg_payload)
120 *msg_payload = bcmbal_payload_ptr_get(unpacked_msg);
121
122 } while (0);
123
124 return ret;
125}
126
127int32_t bcmbal_bal_msg_hdr_get_packed_length(void)
128{
129 return 21; /* See bcmbal_bal_msg_hdr_pack() */
130}
131
132static int32_t bcmbal_bal_msg_hdr_get_ex_id_offset(void)
133{
134 return 16; /* See bcmbal_bal_msg_hdr_pack() */
135}
136
137/** Pack a BAL message header to a byte stream */
138bcmos_errno bcmbal_bal_msg_hdr_pack(const bal_comm_msg_hdr *msg, bcmbal_buf *buf)
139{
140 bcmos_bool ret;
141
142 /* bcmos_msg header pack... (8 bytes post-pack) */
143 ret = bcmbal_buf_write_u32(buf, buf->len);
144
145 ret = ret && bcmbal_buf_write_u16(buf, (uint16_t)msg->m.type);
146 ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->m.instance);
147 ret = ret && bcmbal_buf_write_u8(buf, (uint8_t)msg->m.sender);
148
149 /* ...and then the rest of the header (15 bytes post-pack) */
150 ret = ret && bcmbal_buf_write_u8(buf, msg->version_major);
151 ret = ret && bcmbal_buf_write_u8(buf, msg->version_minor);
152 ret = ret && bcmbal_buf_write_u32(buf, msg->msg_id); /* the msg_id cannot be compressed */
153 ret = ret && bcmbal_buf_write_u16(buf, (uint16_t)msg->msg_type);
154 ret = ret && bcmbal_buf_write_u32(buf, msg->ex_id);
155 ret = ret && bcmbal_buf_write_u8(buf, msg->sender);
156
157 return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
158}
159
160/** Unpack a BAL message header from a byte stream */
161bcmos_errno bcmbal_bal_msg_hdr_unpack(bal_comm_msg_hdr *msg, bcmbal_buf *buf)
162{
163 uint16_t m_type;
164 uint8_t m_instance;
165 uint8_t m_sender;
166 uint32_t m_size;
167
168 uint8_t version_major;
169 uint8_t version_minor;
170 uint32_t msg_id;
171 uint16_t msg_type;
172 uint32_t ex_id;
173 uint8_t sender;
174
175 bcmos_bool ret;
176
177 ret = bcmbal_buf_read_u32(buf, &m_size);
178 ret = ret && bcmbal_buf_read_u16(buf, &m_type);
179 ret = ret && bcmbal_buf_read_u8(buf, &m_instance);
180 ret = ret && bcmbal_buf_read_u8(buf, &m_sender);
181
182 ret = ret && bcmbal_buf_read_u8(buf, &version_major);
183 ret = ret && bcmbal_buf_read_u8(buf, &version_minor);
184 ret = ret && bcmbal_buf_read_u32(buf, &msg_id);
185 ret = ret && bcmbal_buf_read_u16(buf, &msg_type);
186 ret = ret && bcmbal_buf_read_u32(buf, &ex_id);
187 ret = ret && bcmbal_buf_read_u8(buf, &sender);
188
189 if (ret)
190 {
191 msg->m.type = (bcmos_msg_id)m_type;
192 msg->m.instance = (bcmos_msg_instance)m_instance;
193 msg->m.sender = (bcmos_module_id)m_sender;
194 msg->m.size = m_size;
195
196 msg->version_major = version_major;
197 msg->version_minor = version_minor;
198 msg->msg_id = msg_id;
199 msg->msg_type = msg_type;
200 msg->ex_id = ex_id;
201 msg->sender = sender;
202 }
203
204 return ret ? BCM_ERR_OK : BCM_ERR_OVERFLOW;
205}
206
207/** Peek exchange_id in the received message without unpacking */
208bcmos_errno bcmbal_bal_msg_peek_ex_id(bcmos_msg *msg, uint32_t *ex_id)
209{
210 bcmbal_buf buf;
211 if (msg->size < bcmbal_bal_msg_hdr_get_packed_length())
212 return BCM_ERR_INTERNAL;
213 bcmbal_buf_init(&buf, msg->size, msg->data);
214 bcmolt_buf_set_pos(&buf, bcmbal_bal_msg_hdr_get_ex_id_offset());
215 bcmbal_buf_read_u32(&buf, ex_id);
216 return BCM_ERR_OK;
217}
218
219
220