Resync with broadcom drivers 5.100.138.20 and utilities.
[tomato.git] / release / src-rt / include / bcmendian.h
blob598e437a764ab21306bec73738be51f5812bd24a
1 /*
2 * Byte order utilities
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: bcmendian.h,v 1.36 2009-11-09 05:29:43 Exp $
20 * This file by default provides proper behavior on little-endian architectures.
21 * On big-endian architectures, IL_BIGENDIAN should be defined.
24 #ifndef _BCMENDIAN_H_
25 #define _BCMENDIAN_H_
27 #include <typedefs.h>
29 /* Reverse the bytes in a 16-bit value */
30 #define BCMSWAP16(val) \
31 ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \
32 (((uint16)(val) & (uint16)0xff00U) >> 8)))
34 /* Reverse the bytes in a 32-bit value */
35 #define BCMSWAP32(val) \
36 ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \
37 (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \
38 (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \
39 (((uint32)(val) & (uint32)0xff000000U) >> 24)))
41 /* Reverse the two 16-bit halves of a 32-bit value */
42 #define BCMSWAP32BY16(val) \
43 ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \
44 (((uint32)(val) & (uint32)0xffff0000U) >> 16)))
46 /* Byte swapping macros
47 * Host <=> Network (Big Endian) for 16- and 32-bit values
48 * Host <=> Little-Endian for 16- and 32-bit values
50 #ifndef hton16
51 #ifndef IL_BIGENDIAN
52 #define HTON16(i) BCMSWAP16(i)
53 #define hton16(i) bcmswap16(i)
54 #define HTON32(i) BCMSWAP32(i)
55 #define hton32(i) bcmswap32(i)
56 #define NTOH16(i) BCMSWAP16(i)
57 #define ntoh16(i) bcmswap16(i)
58 #define NTOH32(i) BCMSWAP32(i)
59 #define ntoh32(i) bcmswap32(i)
60 #define LTOH16(i) (i)
61 #define ltoh16(i) (i)
62 #define LTOH32(i) (i)
63 #define ltoh32(i) (i)
64 #define HTOL16(i) (i)
65 #define htol16(i) (i)
66 #define HTOL32(i) (i)
67 #define htol32(i) (i)
68 #else /* IL_BIGENDIAN */
69 #define HTON16(i) (i)
70 #define hton16(i) (i)
71 #define HTON32(i) (i)
72 #define hton32(i) (i)
73 #define NTOH16(i) (i)
74 #define ntoh16(i) (i)
75 #define NTOH32(i) (i)
76 #define ntoh32(i) (i)
77 #define LTOH16(i) BCMSWAP16(i)
78 #define ltoh16(i) bcmswap16(i)
79 #define LTOH32(i) BCMSWAP32(i)
80 #define ltoh32(i) bcmswap32(i)
81 #define HTOL16(i) BCMSWAP16(i)
82 #define htol16(i) bcmswap16(i)
83 #define HTOL32(i) BCMSWAP32(i)
84 #define htol32(i) bcmswap32(i)
85 #endif /* IL_BIGENDIAN */
86 #endif /* hton16 */
88 #ifndef IL_BIGENDIAN
89 #define ltoh16_buf(buf, i)
90 #define htol16_buf(buf, i)
91 #else
92 #define ltoh16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i))
93 #define htol16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i))
94 #endif /* IL_BIGENDIAN */
96 /* Unaligned loads and stores in host byte order */
97 #ifndef IL_BIGENDIAN
98 #define load32_ua(a) ltoh32_ua(a)
99 #define store32_ua(a, v) htol32_ua_store(v, a)
100 #define load16_ua(a) ltoh16_ua(a)
101 #define store16_ua(a, v) htol16_ua_store(v, a)
102 #else
103 #define load32_ua(a) ntoh32_ua(a)
104 #define store32_ua(a, v) hton32_ua_store(v, a)
105 #define load16_ua(a) ntoh16_ua(a)
106 #define store16_ua(a, v) hton16_ua_store(v, a)
107 #endif /* IL_BIGENDIAN */
109 #define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8))
110 #define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24))
111 #define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1])
112 #define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3])
114 #define ltoh_ua(ptr) \
115 (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
116 sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \
117 sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \
118 *(uint8 *)0)
120 #define ntoh_ua(ptr) \
121 (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
122 sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \
123 sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \
124 *(uint8 *)0)
126 #ifdef __GNUC__
128 /* GNU macro versions avoid referencing the argument multiple times, while also
129 * avoiding the -fno-inline used in ROM builds.
132 #define bcmswap16(val) ({ \
133 uint16 _val = (val); \
134 BCMSWAP16(_val); \
137 #define bcmswap32(val) ({ \
138 uint32 _val = (val); \
139 BCMSWAP32(_val); \
142 #define bcmswap32by16(val) ({ \
143 uint32 _val = (val); \
144 BCMSWAP32BY16(_val); \
147 #define bcmswap16_buf(buf, len) ({ \
148 uint16 *_buf = (uint16 *)(buf); \
149 uint _wds = (len) / 2; \
150 while (_wds--) { \
151 *_buf = bcmswap16(*_buf); \
152 _buf++; \
156 #define htol16_ua_store(val, bytes) ({ \
157 uint16 _val = (val); \
158 uint8 *_bytes = (uint8 *)(bytes); \
159 _bytes[0] = _val & 0xff; \
160 _bytes[1] = _val >> 8; \
163 #define htol32_ua_store(val, bytes) ({ \
164 uint32 _val = (val); \
165 uint8 *_bytes = (uint8 *)(bytes); \
166 _bytes[0] = _val & 0xff; \
167 _bytes[1] = (_val >> 8) & 0xff; \
168 _bytes[2] = (_val >> 16) & 0xff; \
169 _bytes[3] = _val >> 24; \
172 #define hton16_ua_store(val, bytes) ({ \
173 uint16 _val = (val); \
174 uint8 *_bytes = (uint8 *)(bytes); \
175 _bytes[0] = _val >> 8; \
176 _bytes[1] = _val & 0xff; \
179 #define hton32_ua_store(val, bytes) ({ \
180 uint32 _val = (val); \
181 uint8 *_bytes = (uint8 *)(bytes); \
182 _bytes[0] = _val >> 24; \
183 _bytes[1] = (_val >> 16) & 0xff; \
184 _bytes[2] = (_val >> 8) & 0xff; \
185 _bytes[3] = _val & 0xff; \
188 #define ltoh16_ua(bytes) ({ \
189 const uint8 *_bytes = (const uint8 *)(bytes); \
190 _LTOH16_UA(_bytes); \
193 #define ltoh32_ua(bytes) ({ \
194 const uint8 *_bytes = (const uint8 *)(bytes); \
195 _LTOH32_UA(_bytes); \
198 #define ntoh16_ua(bytes) ({ \
199 const uint8 *_bytes = (const uint8 *)(bytes); \
200 _NTOH16_UA(_bytes); \
203 #define ntoh32_ua(bytes) ({ \
204 const uint8 *_bytes = (const uint8 *)(bytes); \
205 _NTOH32_UA(_bytes); \
208 #else /* !__GNUC__ */
210 /* Inline versions avoid referencing the argument multiple times */
211 static INLINE uint16
212 bcmswap16(uint16 val)
214 return BCMSWAP16(val);
217 static INLINE uint32
218 bcmswap32(uint32 val)
220 return BCMSWAP32(val);
223 static INLINE uint32
224 bcmswap32by16(uint32 val)
226 return BCMSWAP32BY16(val);
229 /* Reverse pairs of bytes in a buffer (not for high-performance use) */
230 /* buf - start of buffer of shorts to swap */
231 /* len - byte length of buffer */
232 static INLINE void
233 bcmswap16_buf(uint16 *buf, uint len)
235 len = len / 2;
237 while (len--) {
238 *buf = bcmswap16(*buf);
239 buf++;
244 * Store 16-bit value to unaligned little-endian byte array.
246 static INLINE void
247 htol16_ua_store(uint16 val, uint8 *bytes)
249 bytes[0] = val & 0xff;
250 bytes[1] = val >> 8;
254 * Store 32-bit value to unaligned little-endian byte array.
256 static INLINE void
257 htol32_ua_store(uint32 val, uint8 *bytes)
259 bytes[0] = val & 0xff;
260 bytes[1] = (val >> 8) & 0xff;
261 bytes[2] = (val >> 16) & 0xff;
262 bytes[3] = val >> 24;
266 * Store 16-bit value to unaligned network-(big-)endian byte array.
268 static INLINE void
269 hton16_ua_store(uint16 val, uint8 *bytes)
271 bytes[0] = val >> 8;
272 bytes[1] = val & 0xff;
276 * Store 32-bit value to unaligned network-(big-)endian byte array.
278 static INLINE void
279 hton32_ua_store(uint32 val, uint8 *bytes)
281 bytes[0] = val >> 24;
282 bytes[1] = (val >> 16) & 0xff;
283 bytes[2] = (val >> 8) & 0xff;
284 bytes[3] = val & 0xff;
288 * Load 16-bit value from unaligned little-endian byte array.
290 static INLINE uint16
291 ltoh16_ua(const void *bytes)
293 return _LTOH16_UA((const uint8 *)bytes);
297 * Load 32-bit value from unaligned little-endian byte array.
299 static INLINE uint32
300 ltoh32_ua(const void *bytes)
302 return _LTOH32_UA((const uint8 *)bytes);
306 * Load 16-bit value from unaligned big-(network-)endian byte array.
308 static INLINE uint16
309 ntoh16_ua(const void *bytes)
311 return _NTOH16_UA((const uint8 *)bytes);
315 * Load 32-bit value from unaligned big-(network-)endian byte array.
317 static INLINE uint32
318 ntoh32_ua(const void *bytes)
320 return _NTOH32_UA((const uint8 *)bytes);
323 #endif /* !__GNUC__ */
324 #endif /* !_BCMENDIAN_H_ */