52296fb9fc589126be9dbc38a7f25f3d346050d8
[pandora-kernel.git] / drivers / staging / brcm80211 / include / bcmendian.h
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #ifndef _BCMENDIAN_H_
18 #define _BCMENDIAN_H_
19
20 #include <typedefs.h>
21
22 /* Reverse the bytes in a 16-bit value */
23 #define BCMSWAP16(val) \
24         ((u16)((((u16)(val) & (u16)0x00ffU) << 8) | \
25                   (((u16)(val) & (u16)0xff00U) >> 8)))
26
27 /* Reverse the bytes in a 32-bit value */
28 #define BCMSWAP32(val) \
29         ((u32)((((u32)(val) & (u32)0x000000ffU) << 24) | \
30                   (((u32)(val) & (u32)0x0000ff00U) <<  8) | \
31                   (((u32)(val) & (u32)0x00ff0000U) >>  8) | \
32                   (((u32)(val) & (u32)0xff000000U) >> 24)))
33
34 /* Reverse the two 16-bit halves of a 32-bit value */
35 #define BCMSWAP32BY16(val) \
36         ((u32)((((u32)(val) & (u32)0x0000ffffU) << 16) | \
37                   (((u32)(val) & (u32)0xffff0000U) >> 16)))
38
39 /* Byte swapping macros
40  *    Host <=> Network (Big Endian) for 16- and 32-bit values
41  *    Host <=> Little-Endian for 16- and 32-bit values
42  */
43 #ifndef hton16
44 #ifndef IL_BIGENDIAN
45 #define HTON16(i) BCMSWAP16(i)
46 #define hton16(i) bcmswap16(i)
47 #define HTON32(i) BCMSWAP32(i)
48 #define hton32(i) bcmswap32(i)
49 #define NTOH16(i) BCMSWAP16(i)
50 #define ntoh16(i) bcmswap16(i)
51 #define NTOH32(i) BCMSWAP32(i)
52 #define ntoh32(i) bcmswap32(i)
53 #define LTOH16(i) (i)
54 #define ltoh16(i) (i)
55 #define LTOH32(i) (i)
56 #define ltoh32(i) (i)
57 #define HTOL16(i) (i)
58 #define htol16(i) (i)
59 #define HTOL32(i) (i)
60 #define htol32(i) (i)
61 #else                           /* IL_BIGENDIAN */
62 #define HTON16(i) (i)
63 #define hton16(i) (i)
64 #define HTON32(i) (i)
65 #define hton32(i) (i)
66 #define NTOH16(i) (i)
67 #define ntoh16(i) (i)
68 #define NTOH32(i) (i)
69 #define ntoh32(i) (i)
70 #define LTOH16(i) BCMSWAP16(i)
71 #define ltoh16(i) bcmswap16(i)
72 #define LTOH32(i) BCMSWAP32(i)
73 #define ltoh32(i) bcmswap32(i)
74 #define HTOL16(i) BCMSWAP16(i)
75 #define htol16(i) bcmswap16(i)
76 #define HTOL32(i) BCMSWAP32(i)
77 #define htol32(i) bcmswap32(i)
78 #endif                          /* IL_BIGENDIAN */
79 #endif                          /* hton16 */
80
81 #ifndef IL_BIGENDIAN
82 #define ltoh16_buf(buf, i)
83 #define htol16_buf(buf, i)
84 #else
85 #define ltoh16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i))
86 #define htol16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i))
87 #endif                          /* IL_BIGENDIAN */
88
89 /* Unaligned loads and stores in host byte order */
90 #ifndef IL_BIGENDIAN
91 #define load32_ua(a)            ltoh32_ua(a)
92 #define store32_ua(a, v)        htol32_ua_store(v, a)
93 #define load16_ua(a)            ltoh16_ua(a)
94 #define store16_ua(a, v)        htol16_ua_store(v, a)
95 #else
96 #define load32_ua(a)            ntoh32_ua(a)
97 #define store32_ua(a, v)        hton32_ua_store(v, a)
98 #define load16_ua(a)            ntoh16_ua(a)
99 #define store16_ua(a, v)        hton16_ua_store(v, a)
100 #endif                          /* IL_BIGENDIAN */
101
102 #define _LTOH16_UA(cp)  ((cp)[0] | ((cp)[1] << 8))
103 #define _LTOH32_UA(cp)  ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24))
104 #define _NTOH16_UA(cp)  (((cp)[0] << 8) | (cp)[1])
105 #define _NTOH32_UA(cp)  (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3])
106
107 #define ltoh_ua(ptr) \
108         (sizeof(*(ptr)) == sizeof(u8) ? *(const u8 *)(ptr) : \
109          sizeof(*(ptr)) == sizeof(u16) ? _LTOH16_UA((const u8 *)(ptr)) : \
110          sizeof(*(ptr)) == sizeof(u32) ? _LTOH32_UA((const u8 *)(ptr)) : \
111          *(u8 *)0)
112
113 #define ntoh_ua(ptr) \
114         (sizeof(*(ptr)) == sizeof(u8) ? *(const u8 *)(ptr) : \
115          sizeof(*(ptr)) == sizeof(u16) ? _NTOH16_UA((const u8 *)(ptr)) : \
116          sizeof(*(ptr)) == sizeof(u32) ? _NTOH32_UA((const u8 *)(ptr)) : \
117          *(u8 *)0)
118
119 #ifdef __GNUC__
120
121 /* GNU macro versions avoid referencing the argument multiple times, while also
122  * avoiding the -fno-inline used in ROM builds.
123  */
124
125 #define bcmswap16(val) ({ \
126         u16 _val = (val); \
127         BCMSWAP16(_val); \
128 })
129
130 #define bcmswap32(val) ({ \
131         u32 _val = (val); \
132         BCMSWAP32(_val); \
133 })
134
135 #define bcmswap32by16(val) ({ \
136         u32 _val = (val); \
137         BCMSWAP32BY16(_val); \
138 })
139
140 #define bcmswap16_buf(buf, len) ({ \
141         u16 *_buf = (u16 *)(buf); \
142         uint _wds = (len) / 2; \
143         while (_wds--) { \
144                 *_buf = bcmswap16(*_buf); \
145                 _buf++; \
146         } \
147 })
148
149 #define htol16_ua_store(val, bytes) ({ \
150         u16 _val = (val); \
151         u8 *_bytes = (u8 *)(bytes); \
152         _bytes[0] = _val & 0xff; \
153         _bytes[1] = _val >> 8; \
154 })
155
156 #define htol32_ua_store(val, bytes) ({ \
157         u32 _val = (val); \
158         u8 *_bytes = (u8 *)(bytes); \
159         _bytes[0] = _val & 0xff; \
160         _bytes[1] = (_val >> 8) & 0xff; \
161         _bytes[2] = (_val >> 16) & 0xff; \
162         _bytes[3] = _val >> 24; \
163 })
164
165 #define hton16_ua_store(val, bytes) ({ \
166         u16 _val = (val); \
167         u8 *_bytes = (u8 *)(bytes); \
168         _bytes[0] = _val >> 8; \
169         _bytes[1] = _val & 0xff; \
170 })
171
172 #define hton32_ua_store(val, bytes) ({ \
173         u32 _val = (val); \
174         u8 *_bytes = (u8 *)(bytes); \
175         _bytes[0] = _val >> 24; \
176         _bytes[1] = (_val >> 16) & 0xff; \
177         _bytes[2] = (_val >> 8) & 0xff; \
178         _bytes[3] = _val & 0xff; \
179 })
180
181 #define ltoh16_ua(bytes) ({ \
182         const u8 *_bytes = (const u8 *)(bytes); \
183         _LTOH16_UA(_bytes); \
184 })
185
186 #define ltoh32_ua(bytes) ({ \
187         const u8 *_bytes = (const u8 *)(bytes); \
188         _LTOH32_UA(_bytes); \
189 })
190
191 #define ntoh16_ua(bytes) ({ \
192         const u8 *_bytes = (const u8 *)(bytes); \
193         _NTOH16_UA(_bytes); \
194 })
195
196 #define ntoh32_ua(bytes) ({ \
197         const u8 *_bytes = (const u8 *)(bytes); \
198         _NTOH32_UA(_bytes); \
199 })
200
201 #else                           /* !__GNUC__ */
202
203 /* Inline versions avoid referencing the argument multiple times */
204 static inline u16 bcmswap16(u16 val)
205 {
206         return BCMSWAP16(val);
207 }
208
209 static inline u32 bcmswap32(u32 val)
210 {
211         return BCMSWAP32(val);
212 }
213
214 static inline u32 bcmswap32by16(u32 val)
215 {
216         return BCMSWAP32BY16(val);
217 }
218
219 /* Reverse pairs of bytes in a buffer (not for high-performance use) */
220 /* buf  - start of buffer of shorts to swap */
221 /* len  - byte length of buffer */
222 static inline void bcmswap16_buf(u16 *buf, uint len)
223 {
224         len = len / 2;
225
226         while (len--) {
227                 *buf = bcmswap16(*buf);
228                 buf++;
229         }
230 }
231
232 /*
233  * Store 16-bit value to unaligned little-endian byte array.
234  */
235 static inline void htol16_ua_store(u16 val, u8 *bytes)
236 {
237         bytes[0] = val & 0xff;
238         bytes[1] = val >> 8;
239 }
240
241 /*
242  * Store 32-bit value to unaligned little-endian byte array.
243  */
244 static inline void htol32_ua_store(u32 val, u8 *bytes)
245 {
246         bytes[0] = val & 0xff;
247         bytes[1] = (val >> 8) & 0xff;
248         bytes[2] = (val >> 16) & 0xff;
249         bytes[3] = val >> 24;
250 }
251
252 /*
253  * Store 16-bit value to unaligned network-(big-)endian byte array.
254  */
255 static inline void hton16_ua_store(u16 val, u8 *bytes)
256 {
257         bytes[0] = val >> 8;
258         bytes[1] = val & 0xff;
259 }
260
261 /*
262  * Store 32-bit value to unaligned network-(big-)endian byte array.
263  */
264 static inline void hton32_ua_store(u32 val, u8 *bytes)
265 {
266         bytes[0] = val >> 24;
267         bytes[1] = (val >> 16) & 0xff;
268         bytes[2] = (val >> 8) & 0xff;
269         bytes[3] = val & 0xff;
270 }
271
272 /*
273  * Load 16-bit value from unaligned little-endian byte array.
274  */
275 static inline u16 ltoh16_ua(const void *bytes)
276 {
277         return _LTOH16_UA((const u8 *)bytes);
278 }
279
280 /*
281  * Load 32-bit value from unaligned little-endian byte array.
282  */
283 static inline u32 ltoh32_ua(const void *bytes)
284 {
285         return _LTOH32_UA((const u8 *)bytes);
286 }
287
288 /*
289  * Load 16-bit value from unaligned big-(network-)endian byte array.
290  */
291 static inline u16 ntoh16_ua(const void *bytes)
292 {
293         return _NTOH16_UA((const u8 *)bytes);
294 }
295
296 /*
297  * Load 32-bit value from unaligned big-(network-)endian byte array.
298  */
299 static inline u32 ntoh32_ua(const void *bytes)
300 {
301         return _NTOH32_UA((const u8 *)bytes);
302 }
303
304 #endif                          /* !__GNUC__ */
305 #endif                          /* !_BCMENDIAN_H_ */