summaryrefslogtreecommitdiff
path: root/common/ipmbox/msg.h
blob: caa0674393dca4b2d3a384f49bda872c4601bb18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#ifndef common_ipmbox_msg_h
#define common_ipmbox_msg_h
/* Cesar project {{{
 *
 * Copyright (C) 2012 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \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 */