| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- /*
- * Byte order utilities
- *
- * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * Copyright (C) 1999-2020, Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2 (the "GPL"),
- * available at http://www.broadcom.com/licenses/GPLv2.php, with the
- * following added to such license:
- *
- * As a special exception, the copyright holders of this software give you
- * permission to link this software with independent modules, and to copy and
- * distribute the resulting executable under terms of your choice, provided that
- * you also meet, for each linked independent module, the terms and conditions of
- * the license of that module. An independent module is a module which is not
- * derived from this software. The special exception does not apply to any
- * modifications of the software.
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a license
- * other than the GPL, without Broadcom's express prior written consent.
- *
- *
- * <<Broadcom-WL-IPTag/Open:>>
- *
- * $Id: bcmendian.h 633810 2016-04-25 16:46:55Z $
- *
- * This file by default provides proper behavior on little-endian architectures.
- * On big-endian architectures, IL_BIGENDIAN should be defined.
- */
- #ifndef _BCMENDIAN_H_
- #define _BCMENDIAN_H_
- #include <typedefs.h>
- /* Reverse the bytes in a 16-bit value */
- #define BCMSWAP16(val) \
- ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \
- (((uint16)(val) & (uint16)0xff00U) >> 8)))
- /* Reverse the bytes in a 32-bit value */
- #define BCMSWAP32(val) \
- ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \
- (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \
- (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \
- (((uint32)(val) & (uint32)0xff000000U) >> 24)))
- /* Reverse the two 16-bit halves of a 32-bit value */
- #define BCMSWAP32BY16(val) \
- ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \
- (((uint32)(val) & (uint32)0xffff0000U) >> 16)))
- /* Reverse the bytes in a 64-bit value */
- #define BCMSWAP64(val) \
- ((uint64)((((uint64)(val) & 0x00000000000000ffULL) << 56) | \
- (((uint64)(val) & 0x000000000000ff00ULL) << 40) | \
- (((uint64)(val) & 0x0000000000ff0000ULL) << 24) | \
- (((uint64)(val) & 0x00000000ff000000ULL) << 8) | \
- (((uint64)(val) & 0x000000ff00000000ULL) >> 8) | \
- (((uint64)(val) & 0x0000ff0000000000ULL) >> 24) | \
- (((uint64)(val) & 0x00ff000000000000ULL) >> 40) | \
- (((uint64)(val) & 0xff00000000000000ULL) >> 56)))
- /* Reverse the two 32-bit halves of a 64-bit value */
- #define BCMSWAP64BY32(val) \
- ((uint64)((((uint64)(val) & 0x00000000ffffffffULL) << 32) | \
- (((uint64)(val) & 0xffffffff00000000ULL) >> 32)))
- /* Byte swapping macros
- * Host <=> Network (Big Endian) for 16- and 32-bit values
- * Host <=> Little-Endian for 16- and 32-bit values
- */
- #ifndef hton16
- #define HTON16(i) BCMSWAP16(i)
- #define hton16(i) bcmswap16(i)
- #define HTON32(i) BCMSWAP32(i)
- #define hton32(i) bcmswap32(i)
- #define NTOH16(i) BCMSWAP16(i)
- #define ntoh16(i) bcmswap16(i)
- #define NTOH32(i) BCMSWAP32(i)
- #define ntoh32(i) bcmswap32(i)
- #define LTOH16(i) (i)
- #define ltoh16(i) (i)
- #define LTOH32(i) (i)
- #define ltoh32(i) (i)
- #define HTOL16(i) (i)
- #define htol16(i) (i)
- #define HTOL32(i) (i)
- #define htol32(i) (i)
- #define HTOL64(i) (i)
- #define htol64(i) (i)
- #endif /* hton16 */
- #define ltoh16_buf(buf, i)
- #define htol16_buf(buf, i)
- #define ltoh32_buf(buf, i)
- #define htol32_buf(buf, i)
- #define ltoh64_buf(buf, i)
- #define htol64_buf(buf, i)
- /* Unaligned loads and stores in host byte order */
- #define load32_ua(a) ltoh32_ua(a)
- #define store32_ua(a, v) htol32_ua_store(v, a)
- #define load16_ua(a) ltoh16_ua(a)
- #define store16_ua(a, v) htol16_ua_store(v, a)
- #define load64_ua(a) ltoh64_ua(a)
- #define store64_ua(a, v) htol64_ua_store(v, a)
- #define _LTOH16_UA(cp) (uint16)((cp)[0] | ((cp)[1] << 8))
- #define _LTOH32_UA(cp) (uint32)((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24))
- #define _NTOH16_UA(cp) (uint16)(((cp)[0] << 8) | (cp)[1])
- #define _NTOH32_UA(cp) (uint32)(((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3])
- #define _LTOH64_UA(cp) ((uint64)(cp)[0] | ((uint64)(cp)[1] << 8) | \
- ((uint64)(cp)[2] << 16) | ((uint64)(cp)[3] << 24) | \
- ((uint64)(cp)[4] << 32) | ((uint64)(cp)[5] << 40) | \
- ((uint64)(cp)[6] << 48) | ((uint64)(cp)[7] << 56))
- #define _NTOH64_UA(cp) ((uint64)(cp)[7] | ((uint64)(cp)[6] << 8) | \
- ((uint64)(cp)[5] << 16) | ((uint64)(cp)[4] << 24) | \
- ((uint64)(cp)[3] << 32) | ((uint64)(cp)[2] << 40) | \
- ((uint64)(cp)[1] << 48) | ((uint64)(cp)[0] << 56))
- #define ltoh_ua(ptr) \
- (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
- sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \
- sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \
- *(uint8 *)0)
- #define ntoh_ua(ptr) \
- (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
- sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \
- sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \
- *(uint8 *)0)
- #ifdef __GNUC__
- /* GNU macro versions avoid referencing the argument multiple times, while also
- * avoiding the -fno-inline used in ROM builds.
- */
- #define bcmswap16(val) ({ \
- uint16 _val = (val); \
- BCMSWAP16(_val); \
- })
- #define bcmswap32(val) ({ \
- uint32 _val = (val); \
- BCMSWAP32(_val); \
- })
- #define bcmswap64(val) ({ \
- uint64 _val = (val); \
- BCMSWAP64(_val); \
- })
- #define bcmswap32by16(val) ({ \
- uint32 _val = (val); \
- BCMSWAP32BY16(_val); \
- })
- #define bcmswap16_buf(buf, len) ({ \
- uint16 *_buf = (uint16 *)(buf); \
- uint _wds = (len) / 2; \
- while (_wds--) { \
- *_buf = bcmswap16(*_buf); \
- _buf++; \
- } \
- })
- #define bcmswap32_buf(buf, len) ({ \
- uint32 *_buf = (uint32 *)(buf); \
- uint _wds = (len) / 4; \
- while (_wds--) { \
- *_buf = bcmswap32(*_buf); \
- _buf++; \
- } \
- })
- #define bcmswap64_buf(buf, len) ({ \
- uint64 *_buf = (uint64 *)(buf); \
- uint _wds = (len) / 8; \
- while (_wds--) { \
- *_buf = bcmswap64(*_buf); \
- _buf++; \
- } \
- })
- #define htol16_ua_store(val, bytes) ({ \
- uint16 _val = (val); \
- uint8 *_bytes = (uint8 *)(bytes); \
- _bytes[0] = _val & 0xff; \
- _bytes[1] = _val >> 8; \
- })
- #define htol32_ua_store(val, bytes) ({ \
- uint32 _val = (val); \
- uint8 *_bytes = (uint8 *)(bytes); \
- _bytes[0] = _val & 0xff; \
- _bytes[1] = (_val >> 8) & 0xff; \
- _bytes[2] = (_val >> 16) & 0xff; \
- _bytes[3] = _val >> 24; \
- })
- #define htol64_ua_store(val, bytes) ({ \
- uint64 _val = (val); \
- uint8 *_bytes = (uint8 *)(bytes); \
- int i; \
- for (i = 0; i < (int)sizeof(_val); ++i) { \
- *_bytes++ = _val & 0xff; \
- _val >>= 8; \
- } \
- })
- #define hton16_ua_store(val, bytes) ({ \
- uint16 _val = (val); \
- uint8 *_bytes = (uint8 *)(bytes); \
- _bytes[0] = _val >> 8; \
- _bytes[1] = _val & 0xff; \
- })
- #define hton32_ua_store(val, bytes) ({ \
- uint32 _val = (val); \
- uint8 *_bytes = (uint8 *)(bytes); \
- _bytes[0] = _val >> 24; \
- _bytes[1] = (_val >> 16) & 0xff; \
- _bytes[2] = (_val >> 8) & 0xff; \
- _bytes[3] = _val & 0xff; \
- })
- #define ltoh16_ua(bytes) ({ \
- const uint8 *_bytes = (const uint8 *)(bytes); \
- _LTOH16_UA(_bytes); \
- })
- #define ltoh32_ua(bytes) ({ \
- const uint8 *_bytes = (const uint8 *)(bytes); \
- _LTOH32_UA(_bytes); \
- })
- #define ltoh64_ua(bytes) ({ \
- const uint8 *_bytes = (const uint8 *)(bytes); \
- _LTOH64_UA(_bytes); \
- })
- #define ntoh16_ua(bytes) ({ \
- const uint8 *_bytes = (const uint8 *)(bytes); \
- _NTOH16_UA(_bytes); \
- })
- #define ntoh32_ua(bytes) ({ \
- const uint8 *_bytes = (const uint8 *)(bytes); \
- _NTOH32_UA(_bytes); \
- })
- #define ntoh64_ua(bytes) ({ \
- const uint8 *_bytes = (const uint8 *)(bytes); \
- _NTOH64_UA(_bytes); \
- })
- #else /* !__GNUC__ */
- /* Inline versions avoid referencing the argument multiple times */
- static INLINE uint16
- bcmswap16(uint16 val)
- {
- return BCMSWAP16(val);
- }
- static INLINE uint32
- bcmswap32(uint32 val)
- {
- return BCMSWAP32(val);
- }
- static INLINE uint64
- bcmswap64(uint64 val)
- {
- return BCMSWAP64(val);
- }
- static INLINE uint32
- bcmswap32by16(uint32 val)
- {
- return BCMSWAP32BY16(val);
- }
- /* Reverse pairs of bytes in a buffer (not for high-performance use) */
- /* buf - start of buffer of shorts to swap */
- /* len - byte length of buffer */
- static INLINE void
- bcmswap16_buf(uint16 *buf, uint len)
- {
- len = len / 2;
- while (len--) {
- *buf = bcmswap16(*buf);
- buf++;
- }
- }
- /*
- * Store 16-bit value to unaligned little-endian byte array.
- */
- static INLINE void
- htol16_ua_store(uint16 val, uint8 *bytes)
- {
- bytes[0] = val & 0xff;
- bytes[1] = val >> 8;
- }
- /*
- * Store 32-bit value to unaligned little-endian byte array.
- */
- static INLINE void
- htol32_ua_store(uint32 val, uint8 *bytes)
- {
- bytes[0] = val & 0xff;
- bytes[1] = (val >> 8) & 0xff;
- bytes[2] = (val >> 16) & 0xff;
- bytes[3] = val >> 24;
- }
- /*
- * Store 64-bit value to unaligned little-endian byte array.
- */
- static INLINE void
- htol64_ua_store(uint64 val, uint8 *bytes)
- {
- int i;
- for (i = 0; i < sizeof(val); ++i) {
- *bytes++ = (uint8)(val & 0xff);
- val >>= 8;
- }
- }
- /*
- * Store 16-bit value to unaligned network-(big-)endian byte array.
- */
- static INLINE void
- hton16_ua_store(uint16 val, uint8 *bytes)
- {
- bytes[0] = val >> 8;
- bytes[1] = val & 0xff;
- }
- /*
- * Store 32-bit value to unaligned network-(big-)endian byte array.
- */
- static INLINE void
- hton32_ua_store(uint32 val, uint8 *bytes)
- {
- bytes[0] = val >> 24;
- bytes[1] = (val >> 16) & 0xff;
- bytes[2] = (val >> 8) & 0xff;
- bytes[3] = val & 0xff;
- }
- /*
- * Load 16-bit value from unaligned little-endian byte array.
- */
- static INLINE uint16
- ltoh16_ua(const void *bytes)
- {
- return _LTOH16_UA((const uint8 *)bytes);
- }
- /*
- * Load 32-bit value from unaligned little-endian byte array.
- */
- static INLINE uint32
- ltoh32_ua(const void *bytes)
- {
- return _LTOH32_UA((const uint8 *)bytes);
- }
- /*
- * Load 64-bit value from unaligned little-endian byte array.
- */
- static INLINE uint64
- ltoh64_ua(const void *bytes)
- {
- return _LTOH64_UA((const uint8 *)bytes);
- }
- /*
- * Load 16-bit value from unaligned big-(network-)endian byte array.
- */
- static INLINE uint16
- ntoh16_ua(const void *bytes)
- {
- return _NTOH16_UA((const uint8 *)bytes);
- }
- /*
- * Load 32-bit value from unaligned big-(network-)endian byte array.
- */
- static INLINE uint32
- ntoh32_ua(const void *bytes)
- {
- return _NTOH32_UA((const uint8 *)bytes);
- }
- /*
- * Load 64-bit value from unaligned big-(network-)endian byte array.
- */
- static INLINE uint64
- ntoh64_ua(const void *bytes)
- {
- return _NTOH64_UA((const uint8 *)bytes);
- }
- #endif /* !__GNUC__ */
- #endif /* !_BCMENDIAN_H_ */
|