• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Byte order utilities
3  *
4  * Copyright (C) 1999-2017, Broadcom Corporation
5  *
6  *      Unless you and Broadcom execute a separate written software license
7  * agreement governing use of this software, this software is licensed to you
8  * under the terms of the GNU General Public License version 2 (the "GPL"),
9  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10  * following added to such license:
11  *
12  *      As a special exception, the copyright holders of this software give you
13  * permission to link this software with independent modules, and to copy and
14  * distribute the resulting executable under terms of your choice, provided that
15  * you also meet, for each linked independent module, the terms and conditions of
16  * the license of that module.  An independent module is a module which is not
17  * derived from this software.  The special exception does not apply to any
18  * modifications of the software.
19  *
20  *      Notwithstanding the above, under no circumstances may you combine this
21  * software in any way with any other Broadcom software provided under a license
22  * other than the GPL, without Broadcom's express prior written consent.
23  *
24  *
25  * <<Broadcom-WL-IPTag/Open:>>
26  *
27  *  $Id: bcmendian.h 514727 2014-11-12 03:02:48Z $
28  *
29  * This file by default provides proper behavior on little-endian architectures.
30  * On big-endian architectures, IL_BIGENDIAN should be defined.
31  */
32 
33 #ifndef _BCMENDIAN_H_
34 #define _BCMENDIAN_H_
35 
36 #include <typedefs.h>
37 
38 /* Reverse the bytes in a 16-bit value */
39 #define BCMSWAP16(val) \
40     ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \
41           (((uint16)(val) & (uint16)0xff00U) >> 8)))
42 
43 /* Reverse the bytes in a 32-bit value */
44 #define BCMSWAP32(val) \
45     ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \
46           (((uint32)(val) & (uint32)0x0000ff00U) <<  8) | \
47           (((uint32)(val) & (uint32)0x00ff0000U) >>  8) | \
48           (((uint32)(val) & (uint32)0xff000000U) >> 24)))
49 
50 /* Reverse the two 16-bit halves of a 32-bit value */
51 #define BCMSWAP32BY16(val) \
52     ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \
53           (((uint32)(val) & (uint32)0xffff0000U) >> 16)))
54 
55 /* Reverse the bytes in a 64-bit value */
56 #define BCMSWAP64(val) \
57     ((uint64)((((uint64)(val) & 0x00000000000000ffULL) << 56) | \
58               (((uint64)(val) & 0x000000000000ff00ULL) << 40) | \
59               (((uint64)(val) & 0x0000000000ff0000ULL) << 24) | \
60               (((uint64)(val) & 0x00000000ff000000ULL) <<  8) | \
61               (((uint64)(val) & 0x000000ff00000000ULL) >>  8) | \
62               (((uint64)(val) & 0x0000ff0000000000ULL) >> 24) | \
63               (((uint64)(val) & 0x00ff000000000000ULL) >> 40) | \
64               (((uint64)(val) & 0xff00000000000000ULL) >> 56)))
65 
66 /* Reverse the two 32-bit halves of a 64-bit value */
67 #define BCMSWAP64BY32(val) \
68     ((uint64)((((uint64)(val) & 0x00000000ffffffffULL) << 32) | \
69               (((uint64)(val) & 0xffffffff00000000ULL) >> 32)))
70 
71 
72 /* Byte swapping macros
73  *    Host <=> Network (Big Endian) for 16- and 32-bit values
74  *    Host <=> Little-Endian for 16- and 32-bit values
75  */
76 #ifndef hton16
77 #define HTON16(i) BCMSWAP16(i)
78 #define    hton16(i) bcmswap16(i)
79 #define    HTON32(i) BCMSWAP32(i)
80 #define    hton32(i) bcmswap32(i)
81 #define    NTOH16(i) BCMSWAP16(i)
82 #define    ntoh16(i) bcmswap16(i)
83 #define    NTOH32(i) BCMSWAP32(i)
84 #define    ntoh32(i) bcmswap32(i)
85 #define LTOH16(i) (i)
86 #define ltoh16(i) (i)
87 #define LTOH32(i) (i)
88 #define ltoh32(i) (i)
89 #define HTOL16(i) (i)
90 #define htol16(i) (i)
91 #define HTOL32(i) (i)
92 #define htol32(i) (i)
93 #define HTOL64(i) (i)
94 #define htol64(i) (i)
95 #endif /* hton16 */
96 
97 #define ltoh16_buf(buf, i)
98 #define htol16_buf(buf, i)
99 
100 /* Unaligned loads and stores in host byte order */
101 #define load32_ua(a)        ltoh32_ua(a)
102 #define store32_ua(a, v)    htol32_ua_store(v, a)
103 #define load16_ua(a)        ltoh16_ua(a)
104 #define store16_ua(a, v)    htol16_ua_store(v, a)
105 
106 #define _LTOH16_UA(cp)    ((cp)[0] | ((cp)[1] << 8))
107 #define _LTOH32_UA(cp)    ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24))
108 #define _NTOH16_UA(cp)    (((cp)[0] << 8) | (cp)[1])
109 #define _NTOH32_UA(cp)    (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3])
110 
111 #define ltoh_ua(ptr) \
112     (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
113      sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \
114      sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \
115      *(uint8 *)0)
116 
117 #define ntoh_ua(ptr) \
118     (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
119      sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \
120      sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \
121      *(uint8 *)0)
122 
123 #ifdef __GNUC__
124 
125 /* GNU macro versions avoid referencing the argument multiple times, while also
126  * avoiding the -fno-inline used in ROM builds.
127  */
128 
129 #define bcmswap16(val) ({ \
130     uint16 _val = (val); \
131     BCMSWAP16(_val); \
132 })
133 
134 #define bcmswap32(val) ({ \
135     uint32 _val = (val); \
136     BCMSWAP32(_val); \
137 })
138 
139 #define bcmswap64(val) ({ \
140     uint64 _val = (val); \
141     BCMSWAP64(_val); \
142 })
143 
144 #define bcmswap32by16(val) ({ \
145     uint32 _val = (val); \
146     BCMSWAP32BY16(_val); \
147 })
148 
149 #define bcmswap16_buf(buf, len) ({ \
150     uint16 *_buf = (uint16 *)(buf); \
151     uint _wds = (len) / 2; \
152     while (_wds--) { \
153         *_buf = bcmswap16(*_buf); \
154         _buf++; \
155     } \
156 })
157 
158 #define htol16_ua_store(val, bytes) ({ \
159     uint16 _val = (val); \
160     uint8 *_bytes = (uint8 *)(bytes); \
161     _bytes[0] = _val & 0xff; \
162     _bytes[1] = _val >> 8; \
163 })
164 
165 #define htol32_ua_store(val, bytes) ({ \
166     uint32 _val = (val); \
167     uint8 *_bytes = (uint8 *)(bytes); \
168     _bytes[0] = _val & 0xff; \
169     _bytes[1] = (_val >> 8) & 0xff; \
170     _bytes[2] = (_val >> 16) & 0xff; \
171     _bytes[3] = _val >> 24; \
172 })
173 
174 #define hton16_ua_store(val, bytes) ({ \
175     uint16 _val = (val); \
176     uint8 *_bytes = (uint8 *)(bytes); \
177     _bytes[0] = _val >> 8; \
178     _bytes[1] = _val & 0xff; \
179 })
180 
181 #define hton32_ua_store(val, bytes) ({ \
182     uint32 _val = (val); \
183     uint8 *_bytes = (uint8 *)(bytes); \
184     _bytes[0] = _val >> 24; \
185     _bytes[1] = (_val >> 16) & 0xff; \
186     _bytes[2] = (_val >> 8) & 0xff; \
187     _bytes[3] = _val & 0xff; \
188 })
189 
190 #define ltoh16_ua(bytes) ({ \
191     const uint8 *_bytes = (const uint8 *)(bytes); \
192     _LTOH16_UA(_bytes); \
193 })
194 
195 #define ltoh32_ua(bytes) ({ \
196     const uint8 *_bytes = (const uint8 *)(bytes); \
197     _LTOH32_UA(_bytes); \
198 })
199 
200 #define ntoh16_ua(bytes) ({ \
201     const uint8 *_bytes = (const uint8 *)(bytes); \
202     _NTOH16_UA(_bytes); \
203 })
204 
205 #define ntoh32_ua(bytes) ({ \
206     const uint8 *_bytes = (const uint8 *)(bytes); \
207     _NTOH32_UA(_bytes); \
208 })
209 
210 #else /* !__GNUC__ */
211 
212 /* Inline versions avoid referencing the argument multiple times */
213 static INLINE uint16
bcmswap16(uint16 val)214 bcmswap16(uint16 val)
215 {
216     return BCMSWAP16(val);
217 }
218 
219 static INLINE uint32
bcmswap32(uint32 val)220 bcmswap32(uint32 val)
221 {
222     return BCMSWAP32(val);
223 }
224 
225 static INLINE uint64
bcmswap64(uint64 val)226 bcmswap64(uint64 val)
227 {
228     return BCMSWAP64(val);
229 }
230 
231 static INLINE uint32
bcmswap32by16(uint32 val)232 bcmswap32by16(uint32 val)
233 {
234     return BCMSWAP32BY16(val);
235 }
236 
237 /* Reverse pairs of bytes in a buffer (not for high-performance use) */
238 /* buf    - start of buffer of shorts to swap */
239 /* len  - byte length of buffer */
240 static INLINE void
bcmswap16_buf(uint16 * buf,uint len)241 bcmswap16_buf(uint16 *buf, uint len)
242 {
243     len = len / 2;
244 
245     while (len--) {
246         *buf = bcmswap16(*buf);
247         buf++;
248     }
249 }
250 
251 /*
252  * Store 16-bit value to unaligned little-endian byte array.
253  */
254 static INLINE void
htol16_ua_store(uint16 val,uint8 * bytes)255 htol16_ua_store(uint16 val, uint8 *bytes)
256 {
257     bytes[0] = val & 0xff;
258     bytes[1] = val >> 8;
259 }
260 
261 /*
262  * Store 32-bit value to unaligned little-endian byte array.
263  */
264 static INLINE void
htol32_ua_store(uint32 val,uint8 * bytes)265 htol32_ua_store(uint32 val, uint8 *bytes)
266 {
267     bytes[0] = val & 0xff;
268     bytes[1] = (val >> 8) & 0xff;
269     bytes[2] = (val >> 16) & 0xff;
270     bytes[3] = val >> 24;
271 }
272 
273 /*
274  * Store 16-bit value to unaligned network-(big-)endian byte array.
275  */
276 static INLINE void
hton16_ua_store(uint16 val,uint8 * bytes)277 hton16_ua_store(uint16 val, uint8 *bytes)
278 {
279     bytes[0] = val >> 8;
280     bytes[1] = val & 0xff;
281 }
282 
283 /*
284  * Store 32-bit value to unaligned network-(big-)endian byte array.
285  */
286 static INLINE void
hton32_ua_store(uint32 val,uint8 * bytes)287 hton32_ua_store(uint32 val, uint8 *bytes)
288 {
289     bytes[0] = val >> 24;
290     bytes[1] = (val >> 16) & 0xff;
291     bytes[2] = (val >> 8) & 0xff;
292     bytes[3] = val & 0xff;
293 }
294 
295 /*
296  * Load 16-bit value from unaligned little-endian byte array.
297  */
298 static INLINE uint16
ltoh16_ua(const void * bytes)299 ltoh16_ua(const void *bytes)
300 {
301     return _LTOH16_UA((const uint8 *)bytes);
302 }
303 
304 /*
305  * Load 32-bit value from unaligned little-endian byte array.
306  */
307 static INLINE uint32
ltoh32_ua(const void * bytes)308 ltoh32_ua(const void *bytes)
309 {
310     return _LTOH32_UA((const uint8 *)bytes);
311 }
312 
313 /*
314  * Load 16-bit value from unaligned big-(network-)endian byte array.
315  */
316 static INLINE uint16
ntoh16_ua(const void * bytes)317 ntoh16_ua(const void *bytes)
318 {
319     return _NTOH16_UA((const uint8 *)bytes);
320 }
321 
322 /*
323  * Load 32-bit value from unaligned big-(network-)endian byte array.
324  */
325 static INLINE uint32
ntoh32_ua(const void * bytes)326 ntoh32_ua(const void *bytes)
327 {
328     return _NTOH32_UA((const uint8 *)bytes);
329 }
330 
331 #endif /* !__GNUC__ */
332 #endif /* !_BCMENDIAN_H_ */
333