Commit | Line | Data |
---|---|---|
d2839953 RC |
1 | /* |
2 | * Byte order utilities | |
3 | * | |
965f77c4 | 4 | * Copyright (C) 1999-2019, Broadcom. |
d2839953 RC |
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 | * | |
965f77c4 | 27 | * $Id: bcmendian.h 788572 2018-11-13 03:52:19Z $ |
d2839953 RC |
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 | /* Byte swapping macros | |
72 | * Host <=> Network (Big Endian) for 16- and 32-bit values | |
73 | * Host <=> Little-Endian for 16- and 32-bit values | |
74 | */ | |
75 | #ifndef hton16 | |
76 | #define HTON16(i) BCMSWAP16(i) | |
77 | #define hton16(i) bcmswap16(i) | |
78 | #define HTON32(i) BCMSWAP32(i) | |
79 | #define hton32(i) bcmswap32(i) | |
80 | #define NTOH16(i) BCMSWAP16(i) | |
81 | #define ntoh16(i) bcmswap16(i) | |
82 | #define NTOH32(i) BCMSWAP32(i) | |
83 | #define ntoh32(i) bcmswap32(i) | |
84 | #define LTOH16(i) (i) | |
85 | #define ltoh16(i) (i) | |
86 | #define LTOH32(i) (i) | |
87 | #define ltoh32(i) (i) | |
88 | #define HTOL16(i) (i) | |
89 | #define htol16(i) (i) | |
90 | #define HTOL32(i) (i) | |
91 | #define htol32(i) (i) | |
92 | #define HTOL64(i) (i) | |
93 | #define htol64(i) (i) | |
94 | #endif /* hton16 */ | |
95 | ||
96 | #define ltoh16_buf(buf, i) | |
97 | #define htol16_buf(buf, i) | |
98 | #define ltoh32_buf(buf, i) | |
99 | #define htol32_buf(buf, i) | |
100 | #define ltoh64_buf(buf, i) | |
101 | #define htol64_buf(buf, i) | |
102 | ||
103 | /* Unaligned loads and stores in host byte order */ | |
104 | #define load32_ua(a) ltoh32_ua(a) | |
105 | #define store32_ua(a, v) htol32_ua_store(v, a) | |
106 | #define load16_ua(a) ltoh16_ua(a) | |
107 | #define store16_ua(a, v) htol16_ua_store(v, a) | |
108 | #define load64_ua(a) ltoh64_ua(a) | |
109 | #define store64_ua(a, v) htol64_ua_store(v, a) | |
110 | ||
965f77c4 RC |
111 | #define _LTOH16_UA(cp) (uint16)((cp)[0] | ((cp)[1] << 8)) |
112 | #define _LTOH32_UA(cp) (uint32)((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) | |
113 | #define _NTOH16_UA(cp) (uint16)(((cp)[0] << 8) | (cp)[1]) | |
114 | #define _NTOH32_UA(cp) (uint32)(((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) | |
d2839953 RC |
115 | |
116 | #define _LTOH64_UA(cp) ((uint64)(cp)[0] | ((uint64)(cp)[1] << 8) | \ | |
117 | ((uint64)(cp)[2] << 16) | ((uint64)(cp)[3] << 24) | \ | |
118 | ((uint64)(cp)[4] << 32) | ((uint64)(cp)[5] << 40) | \ | |
119 | ((uint64)(cp)[6] << 48) | ((uint64)(cp)[7] << 56)) | |
120 | ||
121 | #define _NTOH64_UA(cp) ((uint64)(cp)[7] | ((uint64)(cp)[6] << 8) | \ | |
122 | ((uint64)(cp)[5] << 16) | ((uint64)(cp)[4] << 24) | \ | |
123 | ((uint64)(cp)[3] << 32) | ((uint64)(cp)[2] << 40) | \ | |
124 | ((uint64)(cp)[1] << 48) | ((uint64)(cp)[0] << 56)) | |
125 | ||
126 | #define ltoh_ua(ptr) \ | |
127 | (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ | |
128 | sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \ | |
129 | sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \ | |
130 | *(uint8 *)0) | |
131 | ||
132 | #define ntoh_ua(ptr) \ | |
133 | (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ | |
134 | sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \ | |
135 | sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \ | |
136 | *(uint8 *)0) | |
137 | ||
138 | #ifdef __GNUC__ | |
139 | ||
140 | /* GNU macro versions avoid referencing the argument multiple times, while also | |
141 | * avoiding the -fno-inline used in ROM builds. | |
142 | */ | |
143 | ||
144 | #define bcmswap16(val) ({ \ | |
145 | uint16 _val = (val); \ | |
146 | BCMSWAP16(_val); \ | |
147 | }) | |
148 | ||
149 | #define bcmswap32(val) ({ \ | |
150 | uint32 _val = (val); \ | |
151 | BCMSWAP32(_val); \ | |
152 | }) | |
153 | ||
154 | #define bcmswap64(val) ({ \ | |
155 | uint64 _val = (val); \ | |
156 | BCMSWAP64(_val); \ | |
157 | }) | |
158 | ||
159 | #define bcmswap32by16(val) ({ \ | |
160 | uint32 _val = (val); \ | |
161 | BCMSWAP32BY16(_val); \ | |
162 | }) | |
163 | ||
164 | #define bcmswap16_buf(buf, len) ({ \ | |
165 | uint16 *_buf = (uint16 *)(buf); \ | |
166 | uint _wds = (len) / 2; \ | |
167 | while (_wds--) { \ | |
168 | *_buf = bcmswap16(*_buf); \ | |
169 | _buf++; \ | |
170 | } \ | |
171 | }) | |
172 | ||
173 | #define bcmswap32_buf(buf, len) ({ \ | |
174 | uint32 *_buf = (uint32 *)(buf); \ | |
175 | uint _wds = (len) / 4; \ | |
176 | while (_wds--) { \ | |
177 | *_buf = bcmswap32(*_buf); \ | |
178 | _buf++; \ | |
179 | } \ | |
180 | }) | |
181 | ||
182 | #define bcmswap64_buf(buf, len) ({ \ | |
183 | uint64 *_buf = (uint64 *)(buf); \ | |
184 | uint _wds = (len) / 8; \ | |
185 | while (_wds--) { \ | |
186 | *_buf = bcmswap64(*_buf); \ | |
187 | _buf++; \ | |
188 | } \ | |
189 | }) | |
190 | ||
191 | #define htol16_ua_store(val, bytes) ({ \ | |
192 | uint16 _val = (val); \ | |
193 | uint8 *_bytes = (uint8 *)(bytes); \ | |
194 | _bytes[0] = _val & 0xff; \ | |
195 | _bytes[1] = _val >> 8; \ | |
196 | }) | |
197 | ||
198 | #define htol32_ua_store(val, bytes) ({ \ | |
199 | uint32 _val = (val); \ | |
200 | uint8 *_bytes = (uint8 *)(bytes); \ | |
201 | _bytes[0] = _val & 0xff; \ | |
202 | _bytes[1] = (_val >> 8) & 0xff; \ | |
203 | _bytes[2] = (_val >> 16) & 0xff; \ | |
204 | _bytes[3] = _val >> 24; \ | |
205 | }) | |
206 | ||
207 | #define htol64_ua_store(val, bytes) ({ \ | |
208 | uint64 _val = (val); \ | |
209 | uint8 *_bytes = (uint8 *)(bytes); \ | |
210 | int i; \ | |
211 | for (i = 0; i < (int)sizeof(_val); ++i) { \ | |
212 | *_bytes++ = _val & 0xff; \ | |
213 | _val >>= 8; \ | |
214 | } \ | |
215 | }) | |
216 | ||
217 | #define hton16_ua_store(val, bytes) ({ \ | |
218 | uint16 _val = (val); \ | |
219 | uint8 *_bytes = (uint8 *)(bytes); \ | |
220 | _bytes[0] = _val >> 8; \ | |
221 | _bytes[1] = _val & 0xff; \ | |
222 | }) | |
223 | ||
224 | #define hton32_ua_store(val, bytes) ({ \ | |
225 | uint32 _val = (val); \ | |
226 | uint8 *_bytes = (uint8 *)(bytes); \ | |
227 | _bytes[0] = _val >> 24; \ | |
228 | _bytes[1] = (_val >> 16) & 0xff; \ | |
229 | _bytes[2] = (_val >> 8) & 0xff; \ | |
230 | _bytes[3] = _val & 0xff; \ | |
231 | }) | |
232 | ||
233 | #define ltoh16_ua(bytes) ({ \ | |
234 | const uint8 *_bytes = (const uint8 *)(bytes); \ | |
235 | _LTOH16_UA(_bytes); \ | |
236 | }) | |
237 | ||
238 | #define ltoh32_ua(bytes) ({ \ | |
239 | const uint8 *_bytes = (const uint8 *)(bytes); \ | |
240 | _LTOH32_UA(_bytes); \ | |
241 | }) | |
242 | ||
243 | #define ltoh64_ua(bytes) ({ \ | |
244 | const uint8 *_bytes = (const uint8 *)(bytes); \ | |
245 | _LTOH64_UA(_bytes); \ | |
246 | }) | |
247 | ||
248 | #define ntoh16_ua(bytes) ({ \ | |
249 | const uint8 *_bytes = (const uint8 *)(bytes); \ | |
250 | _NTOH16_UA(_bytes); \ | |
251 | }) | |
252 | ||
253 | #define ntoh32_ua(bytes) ({ \ | |
254 | const uint8 *_bytes = (const uint8 *)(bytes); \ | |
255 | _NTOH32_UA(_bytes); \ | |
256 | }) | |
257 | ||
258 | #define ntoh64_ua(bytes) ({ \ | |
259 | const uint8 *_bytes = (const uint8 *)(bytes); \ | |
260 | _NTOH64_UA(_bytes); \ | |
261 | }) | |
262 | ||
263 | #else /* !__GNUC__ */ | |
264 | ||
265 | /* Inline versions avoid referencing the argument multiple times */ | |
266 | static INLINE uint16 | |
267 | bcmswap16(uint16 val) | |
268 | { | |
269 | return BCMSWAP16(val); | |
270 | } | |
271 | ||
272 | static INLINE uint32 | |
273 | bcmswap32(uint32 val) | |
274 | { | |
275 | return BCMSWAP32(val); | |
276 | } | |
277 | ||
278 | static INLINE uint64 | |
279 | bcmswap64(uint64 val) | |
280 | { | |
281 | return BCMSWAP64(val); | |
282 | } | |
283 | ||
284 | static INLINE uint32 | |
285 | bcmswap32by16(uint32 val) | |
286 | { | |
287 | return BCMSWAP32BY16(val); | |
288 | } | |
289 | ||
290 | /* Reverse pairs of bytes in a buffer (not for high-performance use) */ | |
291 | /* buf - start of buffer of shorts to swap */ | |
292 | /* len - byte length of buffer */ | |
293 | static INLINE void | |
294 | bcmswap16_buf(uint16 *buf, uint len) | |
295 | { | |
296 | len = len / 2; | |
297 | ||
298 | while (len--) { | |
299 | *buf = bcmswap16(*buf); | |
300 | buf++; | |
301 | } | |
302 | } | |
303 | ||
304 | /* | |
305 | * Store 16-bit value to unaligned little-endian byte array. | |
306 | */ | |
307 | static INLINE void | |
308 | htol16_ua_store(uint16 val, uint8 *bytes) | |
309 | { | |
310 | bytes[0] = val & 0xff; | |
311 | bytes[1] = val >> 8; | |
312 | } | |
313 | ||
314 | /* | |
315 | * Store 32-bit value to unaligned little-endian byte array. | |
316 | */ | |
317 | static INLINE void | |
318 | htol32_ua_store(uint32 val, uint8 *bytes) | |
319 | { | |
320 | bytes[0] = val & 0xff; | |
321 | bytes[1] = (val >> 8) & 0xff; | |
322 | bytes[2] = (val >> 16) & 0xff; | |
323 | bytes[3] = val >> 24; | |
324 | } | |
325 | ||
326 | /* | |
327 | * Store 64-bit value to unaligned little-endian byte array. | |
328 | */ | |
329 | static INLINE void | |
330 | htol64_ua_store(uint64 val, uint8 *bytes) | |
331 | { | |
332 | int i; | |
333 | for (i = 0; i < sizeof(val); ++i) { | |
334 | *bytes++ = (uint8)(val & 0xff); | |
335 | val >>= 8; | |
336 | } | |
337 | } | |
338 | ||
339 | /* | |
340 | * Store 16-bit value to unaligned network-(big-)endian byte array. | |
341 | */ | |
342 | static INLINE void | |
343 | hton16_ua_store(uint16 val, uint8 *bytes) | |
344 | { | |
345 | bytes[0] = val >> 8; | |
346 | bytes[1] = val & 0xff; | |
347 | } | |
348 | ||
349 | /* | |
350 | * Store 32-bit value to unaligned network-(big-)endian byte array. | |
351 | */ | |
352 | static INLINE void | |
353 | hton32_ua_store(uint32 val, uint8 *bytes) | |
354 | { | |
355 | bytes[0] = val >> 24; | |
356 | bytes[1] = (val >> 16) & 0xff; | |
357 | bytes[2] = (val >> 8) & 0xff; | |
358 | bytes[3] = val & 0xff; | |
359 | } | |
360 | ||
361 | /* | |
362 | * Load 16-bit value from unaligned little-endian byte array. | |
363 | */ | |
364 | static INLINE uint16 | |
365 | ltoh16_ua(const void *bytes) | |
366 | { | |
367 | return _LTOH16_UA((const uint8 *)bytes); | |
368 | } | |
369 | ||
370 | /* | |
371 | * Load 32-bit value from unaligned little-endian byte array. | |
372 | */ | |
373 | static INLINE uint32 | |
374 | ltoh32_ua(const void *bytes) | |
375 | { | |
376 | return _LTOH32_UA((const uint8 *)bytes); | |
377 | } | |
378 | ||
379 | /* | |
380 | * Load 64-bit value from unaligned little-endian byte array. | |
381 | */ | |
382 | static INLINE uint64 | |
383 | ltoh64_ua(const void *bytes) | |
384 | { | |
385 | return _LTOH64_UA((const uint8 *)bytes); | |
386 | } | |
387 | ||
388 | /* | |
389 | * Load 16-bit value from unaligned big-(network-)endian byte array. | |
390 | */ | |
391 | static INLINE uint16 | |
392 | ntoh16_ua(const void *bytes) | |
393 | { | |
394 | return _NTOH16_UA((const uint8 *)bytes); | |
395 | } | |
396 | ||
397 | /* | |
398 | * Load 32-bit value from unaligned big-(network-)endian byte array. | |
399 | */ | |
400 | static INLINE uint32 | |
401 | ntoh32_ua(const void *bytes) | |
402 | { | |
403 | return _NTOH32_UA((const uint8 *)bytes); | |
404 | } | |
405 | ||
406 | /* | |
407 | * Load 64-bit value from unaligned big-(network-)endian byte array. | |
408 | */ | |
409 | static INLINE uint64 | |
410 | ntoh64_ua(const void *bytes) | |
411 | { | |
412 | return _NTOH64_UA((const uint8 *)bytes); | |
413 | } | |
414 | ||
415 | #endif /* !__GNUC__ */ | |
416 | #endif /* !_BCMENDIAN_H_ */ |