#ifndef common_ipmbox_msg_h #define common_ipmbox_msg_h /* Cesar project {{{ * * Copyright (C) 2012 Spidcom * * <<>> * * }}} */ /** * \file common/ipmbox/msg.h * \brief IPMBox message format. */ #include "common/universe.h" /** * MBX message types. */ enum ipmbox_msg_mbx_type_t { IPMBOX_MSG_MBX_TYPE_MME_PRIV = 0, IPMBOX_MSG_MBX_TYPE_DEBUG_DUMP = 1, IPMBOX_MSG_MBX_TYPE_RPC = 2, }; /** * Number of words for one message on each queue. */ #define IPMBOX_MSG_MBX_WORDS \ (sizeof (ipmbox_msg_mbx_t) / sizeof (u32)) #define IPMBOX_MSG_EMPTY_BUF_WORDS \ (sizeof (ipmbox_msg_empty_buf_t) / sizeof (u32)) #define IPMBOX_MSG_DATA_WORDS \ (sizeof (ipmbox_msg_data_t) / sizeof (u32)) /** * Structure of an empty buffer message. */ typedef struct ipmbox_msg_empty_buf_t { /** Buffer address (physical). */ u32 buffer_addr; } ipmbox_msg_empty_buf_t; /** * Structure of a data message. */ typedef struct ipmbox_msg_data_t { /** Message header. */ u32 header; /** Buffer address (physical). */ u32 buffer_addr; } ipmbox_msg_data_t; /** * Structure of a mailbox message. */ typedef struct ipmbox_msg_mbx_t { /** Message header. */ u32 header; /** Buffer address (physical). */ u32 buffer_addr; } ipmbox_msg_mbx_t; /** * Build an header for data type. * \param length length of data frame * \param prio_tag VLAN priority tag * \return the built header */ extern inline u32 ipmbox_msg_create_header_data (unsigned int length, unsigned int prio_tag) { dbg_claim (length && length < (1 << 11)); dbg_claim (prio_tag < (1 << 3)); return length | (prio_tag << 11); } /** Get length from data header. */ extern inline unsigned int ipmbox_msg_get_data_length (u32 header) { return header & ((1 << 11) - 1); } /** Get prio_tag from data header. */ extern inline unsigned int ipmbox_msg_get_data_prio_tag (u32 header) { return (header >> 11) & ((1 << 3) - 1); } /** Get message type from mbx header. */ extern inline unsigned int ipmbox_msg_get_mbx_type (u32 header) { return header & ((1 << 8) - 1); } /** * Build an header for private MME type. * \param length length of data frame * \return the built header */ extern inline u32 ipmbox_msg_create_header_mme_priv (unsigned int length) { dbg_assert (length && length < (1 << 11)); return IPMBOX_MSG_MBX_TYPE_MME_PRIV | (length << 8); } /** Get length from mme_priv header. */ extern inline unsigned int ipmbox_msg_get_mme_priv_length (u32 header) { return (header >> 8) & ((1 << 11) - 1); } /** * Build an header for debug dump type. * \param length length of data frame * \return the built header */ extern inline u32 ipmbox_msg_create_header_debug_dump (unsigned int length) { dbg_assert (length < (1 << 16)); return IPMBOX_MSG_MBX_TYPE_DEBUG_DUMP | (length << 8); } /** Get length from debug dump header. */ extern inline unsigned int ipmbox_msg_get_debug_dump_length (u32 header) { return (header >> 8) & ((1 << 16) - 1); } /** * Build an header for RPC request type (A2L). * \param forward_length length of readable data in buffer * \param reverse_length_kb length of writable space in buffer in kilobyte * \param cookie cookie to identify request */ extern inline u32 ipmbox_msg_create_header_rpc_a2l (unsigned int forward_length, unsigned int reverse_length_kb, unsigned int cookie) { dbg_assert (forward_length < (1 << 13)); dbg_assert (reverse_length_kb < (1 << 3)); dbg_assert (cookie < (1 << 4)); return IPMBOX_MSG_MBX_TYPE_RPC | (forward_length << 8) | (reverse_length_kb << (8 + 13)) | (cookie << (8 + 13 + 3)); } /** * Build an header for RPC response type (L2A). * \param forward_length length of readable data in buffer * \param more_data 1 if more data is to be read * \param cookie cookie to identify response */ extern inline u32 ipmbox_msg_create_header_rpc_l2a (unsigned int forward_length, bool more_data, unsigned int cookie) { dbg_assert (forward_length < (1 << 13)); dbg_assert (cookie < (1 << 4)); return IPMBOX_MSG_MBX_TYPE_RPC | (forward_length << 8) | (more_data ? (1 << (8 + 13)) : 0) | 0 /* 2 padding bits */ | (cookie << (8 + 13 + 1 + 2)); } /** Get length from RPC header. */ extern inline unsigned int ipmbox_msg_get_rpc_forward_length (u32 header) { return (header >> 8) & ((1 << 13) - 1); } /** Get reverse length from RPC request header. */ extern inline unsigned int ipmbox_msg_get_rpc_a2l_reverse_length_kb (u32 header) { return (header >> (8 + 13)) & ((1 << 3) - 1); } /** Get more_data from RPC response header. */ extern inline bool ipmbox_msg_get_rpc_l2a_more_data (u32 header) { return ((header >> (8 + 13)) & 1) ? true : false; } /** Get cookie from RPC header. */ extern inline unsigned int ipmbox_msg_get_rpc_cookie (u32 header) { return (header >> (8 + 13 + 3)) & ((1 << 4) - 1); } #endif /* common_ipmbox_msg_h */