blob: b2050a5153e18c08d58a0fbab0e115a8fe523ebe [file] [log] [blame]
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06001#ifndef BASE_H
2#define BASE_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <asm/byteorder.h>
9#include <stddef.h>
10#include <stdint.h>
11
12/** @brief PLDM Types
13 */
14enum pldm_supported_types {
15 PLDM_BASE = 0x00,
16};
17
18/** @brief PLDM Commands
19 */
20enum pldm_supported_commands {
Sampa Misra432e1872019-02-13 03:49:43 -060021 PLDM_GET_PLDM_VERSION = 0x3,
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060022 PLDM_GET_PLDM_TYPES = 0x4,
23 PLDM_GET_PLDM_COMMANDS = 0x5
24};
25
26/** @brief PLDM base codes
27 */
28enum pldm_completion_codes {
29 PLDM_SUCCESS = 0x00,
30 PLDM_ERROR = 0x01,
31 PLDM_ERROR_INVALID_DATA = 0x02,
32 PLDM_ERROR_INVALID_LENGTH = 0x03,
33 PLDM_ERROR_NOT_READY = 0x04,
34 PLDM_ERROR_UNSUPPORTED_PLDM_CMD = 0x05,
35 PLDM_ERROR_INVALID_PLDM_TYPE = 0x20
36};
37
Sampa Misra432e1872019-02-13 03:49:43 -060038enum transfer_op_flag {
39 PLDM_GET_NEXTPART = 0,
40 PLDM_GET_FIRSTPART = 1,
41};
42
43enum transfer_resp_flag {
44 PLDM_START = 0x01,
45 PLDM_MIDDLE = 0x02,
46 PLDM_END = 0x04,
47 PLDM_START_AND_END = 0x05,
48};
49
Tom Joseph41251042019-02-07 16:17:07 +053050/** @enum MessageType
51 *
52 * The different message types supported by the PLDM specification.
53 */
54typedef enum {
55 PLDM_RESPONSE, //!< PLDM response
56 PLDM_REQUEST, //!< PLDM request
57 PLDM_RESERVED, //!< Reserved
58 PLDM_ASYNC_REQUEST_NOTIFY, //!< Unacknowledged PLDM request messages
59} MessageType;
60
61#define PLDM_INSTANCE_MAX 31
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060062#define PLDM_MAX_TYPES 64
63#define PLDM_MAX_CMDS_PER_TYPE 256
64
65/* Message payload lengths */
66#define PLDM_GET_COMMANDS_REQ_BYTES 5
Sampa Misra432e1872019-02-13 03:49:43 -060067#define PLDM_GET_VERSION_REQ_BYTES 6
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060068
69/* Response lengths are inclusive of completion code */
70#define PLDM_GET_TYPES_RESP_BYTES 9
71#define PLDM_GET_COMMANDS_RESP_BYTES 33
Sampa Misra432e1872019-02-13 03:49:43 -060072/* Response data has only one version and does not contain the checksum */
73#define PLDM_GET_VERSION_RESP_BYTES 10
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060074
75/** @struct pldm_msg_hdr
76 *
77 * Structure representing PLDM message header fields
78 */
79struct pldm_msg_hdr {
80#if defined(__LITTLE_ENDIAN_BITFIELD)
81 uint8_t instance_id : 5; //!< Instance ID
82 uint8_t reserved : 1; //!< Reserved
83 uint8_t datagram : 1; //!< Datagram bit
84 uint8_t request : 1; //!< Request bit
85#elif defined(__BIG_ENDIAN_BITFIELD)
86 uint8_t request : 1; //!< Request bit
87 uint8_t datagram : 1; //!< Datagram bit
88 uint8_t reserved : 1; //!< Reserved
89 uint8_t instance_id : 5; //!< Instance ID
90#endif
91
92#if defined(__LITTLE_ENDIAN_BITFIELD)
93 uint8_t type : 6; //!< PLDM type
94 uint8_t header_ver : 2; //!< Header version
95#elif defined(__BIG_ENDIAN_BITFIELD)
96 uint8_t header_ver : 2; //!< Header version
97 uint8_t type : 6; //!< PLDM type
98#endif
99 uint8_t command; //!< PLDM command code
100} __attribute__((packed));
101
102/** @struct pldm_msg_payload
103 *
104 * Structure representing PLDM message payload
105 */
106struct pldm_msg_payload {
107 uint8_t *payload; //!< Pointer to PLDM message payload
108 size_t payload_length; //!< PLDM message payload's length in bytes
109} __attribute__((packed));
110
111/** @struct pldm_msg
112 *
113 * Structure representing PLDM message
114 */
115struct pldm_msg {
116 struct pldm_msg_hdr hdr; //!< PLDM message header
117 struct pldm_msg_payload body; //!< PLDM message payload
118} __attribute__((packed));
119
120/** @struct pldm_version
121 *
122 * Structure representing PLDM ver32 type
123 */
124struct pldm_version {
125 uint8_t major;
126 uint8_t minor;
127 uint8_t update;
128 uint8_t alpha;
129} __attribute__((packed));
130
Tom Joseph41251042019-02-07 16:17:07 +0530131/** @struct pldm_header_info
132 *
133 * The information needed to prepare PLDM header and this is passed to the
134 * pack_pldm_header and unpack_pldm_header API.
135 */
136struct pldm_header_info {
137 MessageType msg_type; //!< PLDM message type
138 uint8_t instance; //!< PLDM instance id
139 uint8_t pldm_type; //!< PLDM type
140 uint8_t command; //!< PLDM command code
141 uint8_t completion_code; //!< PLDM completion code, applies for response
142};
143
144/**
145 * @brief Populate the PLDM message with the PLDM header.The caller of this API
146 * allocates buffer for the PLDM header when forming the PLDM message.
147 * The buffer is passed to this API to pack the PLDM header.
148 *
149 * @param[in] hdr - Pointer to the PLDM header information
150 * @param[out] msg - Pointer to PLDM message header
151 *
152 * @return 0 on success, otherwise PLDM error codes.
153 */
154int pack_pldm_header(const struct pldm_header_info *hdr,
155 struct pldm_msg_hdr *msg);
156
157/**
158 * @brief Unpack the PLDM header from the PLDM message.
159 *
160 * @param[in] msg - Pointer to the PLDM message header
161 * @param[out] hdr - Pointer to the PLDM header information
162 *
163 * @return 0 on success, otherwise PLDM error codes.
164 */
165int unpack_pldm_header(const struct pldm_msg_hdr *msg,
166 struct pldm_header_info *hdr);
167
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600168/* Requester */
169
170/* GetPLDMTypes */
171
172/** @brief Create a PLDM request message for GetPLDMTypes
173 *
174 * @param[in] instance_id - Message's instance id
175 * @param[in,out] msg - Message will be written to this
176 * @return pldm_completion_codes
177 * @note Caller is responsible for memory alloc and dealloc of param
178 * 'msg.body.payload'
179 */
180int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg);
181
182/** @brief Decode a GetPLDMTypes response message
183 *
184 * @param[in] msg - Response message payload
185 * @param[out] types - pointer to array uint8_t[8] containing supported
186 * types (MAX_TYPES/8) = 8), as per DSP0240
187 * @return pldm_completion_codes
188 */
189int decode_get_types_resp(const struct pldm_msg_payload *msg, uint8_t *types);
190
191/* GetPLDMCommands */
192
193/** @brief Create a PLDM request message for GetPLDMCommands
194 *
195 * @param[in] instance_id - Message's instance id
196 * @param[in] type - PLDM Type
197 * @param[in] version - Version for PLDM Type
198 * @param[in,out] msg - Message will be written to this
199 * @return pldm_completion_codes
200 * @note Caller is responsible for memory alloc and dealloc of param
201 * 'msg.body.payload'
202 */
203int encode_get_commands_req(uint8_t instance_id, uint8_t type,
204 struct pldm_version version, struct pldm_msg *msg);
205
206/** @brief Decode a GetPLDMCommands response message
207 *
208 * @param[in] msg - Response message payload
209 * @param[in] commands - pointer to array uint8_t[32] containing supported
210 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
211 * @return pldm_completion_codes
212 */
213int decode_get_commands_resp(const struct pldm_msg_payload *msg,
214 uint8_t *commands);
215
Sampa Misra432e1872019-02-13 03:49:43 -0600216/* GetPLDMVersion */
217
218/** @brief Create a PLDM request for GetPLDMVersion
219 *
220 * @param[in] instance_id - Message's instance id
221 * @param[in] transfer_handle - Handle to identify PLDM version data transfer.
222 * This handle is ignored by the responder when the
223 * transferop_flag is set to getFirstPart.
224 * @param[in] transfer_opflag - flag to indicate whether it is start of
225 * transfer
226 * @param[in] type - PLDM Type for which version is requested
227 * @param[in,out] msg - Message will be written to this
228 * @return pldm_completion_codes
229 * @note Caller is responsible for memory alloc and dealloc of param
230 * 'msg.body.payload'
231 */
232int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
233 uint8_t transfer_opflag, uint8_t type,
234 struct pldm_msg *msg);
235
236/** @brief Decode a GetPLDMVersion response message
237 *
238 * @param[in] msg - Response message payload
239 * @param[out] next_transfer_handle - the next handle for the next part of data
240 * @param[out] transfer_flag - flag to indicate the part of data
241 * @return pldm_completion_codes
242 */
243int decode_get_version_resp(const struct pldm_msg_payload *msg,
244 uint32_t *next_transfer_handle,
245 uint8_t *transfer_flag,
246 struct pldm_version *version);
247
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600248/* Responder */
249
250/* GetPLDMTypes */
251
252/** @brief Create a PLDM response message for GetPLDMTypes
253 *
254 * @param[in] instance_id - Message's instance id
255 * @param[in] completion_code - PLDM completion code
256 * @param[in] types - pointer to array uint8_t[8] containing supported
257 * types (MAX_TYPES/8) = 8), as per DSP0240
258 * @param[in,out] msg - Message will be written to this
259 * @return pldm_completion_codes
260 * @note Caller is responsible for memory alloc and dealloc of param
261 * 'msg.body.payload'
262 */
263int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
264 const uint8_t *types, struct pldm_msg *msg);
265
266/* GetPLDMCommands */
267
268/** @brief Decode GetPLDMCommands' request data
269 *
270 * @param[in] msg - Request message payload
271 * @param[out] type - PLDM Type
272 * @param[out] version - Version for PLDM Type
273 * @return pldm_completion_codes
274 */
275int decode_get_commands_req(const struct pldm_msg_payload *msg, uint8_t *type,
276 struct pldm_version *version);
277
278/** @brief Create a PLDM response message for GetPLDMCommands
279 *
280 * @param[in] instance_id - Message's instance id
281 * @param[in] completion_code - PLDM completion code
282 * @param[in] commands - pointer to array uint8_t[32] containing supported
283 * commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
284 * @param[in,out] msg - Message will be written to this
285 * @return pldm_completion_codes
286 * @note Caller is responsible for memory alloc and dealloc of param
287 * 'msg.body.payload'
288 */
289int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
290 const uint8_t *commands, struct pldm_msg *msg);
291
Sampa Misra432e1872019-02-13 03:49:43 -0600292/* GetPLDMVersion */
293
294/** @brief Create a PLDM response for GetPLDMVersion
295 *
296 * @param[in] instance_id - Message's instance id
297 * @param[in] completion_code - PLDM completion code
298 * @param[in] next_transfer_handle - Handle to identify next portion of
299 * data transfer
300 * @param[in] transfer_flag - Represents the part of transfer
301 * @param[in] version_data - the version data
302 * @param[in] version_size - size of version data
303 * @param[in,out] msg - Message will be written to this
304 * @return pldm_completion_codes
305 * @note Caller is responsible for memory alloc and dealloc of param
306 * 'msg.body.payload'
307 */
308int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
309 uint32_t next_transfer_handle,
310 uint8_t transfer_flag,
311 const struct pldm_version *version_data,
312 size_t version_size, struct pldm_msg *msg);
313
314/** @brief Decode a GetPLDMVersion request message
315 *
316 * @param[in] msg - Request message payload
317 * @param[out] transfer_handle - the handle of data
318 * @param[out] transfer_opflag - Transfer Flag
319 * @param[out] type - PLDM type for which version is requested
320 * @return pldm_completion_codes
321 */
322int decode_get_version_req(const struct pldm_msg_payload *msg,
323 uint32_t *transfer_handle, uint8_t *transfer_opflag,
324 uint8_t *type);
325
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600326#ifdef __cplusplus
327}
328#endif
329
330#endif /* BASE_H */