|  | /* | 
|  | * Byte order utilities | 
|  | * | 
|  | * Copyright (C) 1999-2016, 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 514727 2014-11-12 03:02:48Z $ | 
|  | * | 
|  | * 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) | 
|  |  | 
|  | /* 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 _LTOH16_UA(cp)	((cp)[0] | ((cp)[1] << 8)) | 
|  | #define _LTOH32_UA(cp)	((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) | 
|  | #define _NTOH16_UA(cp)	(((cp)[0] << 8) | (cp)[1]) | 
|  | #define _NTOH32_UA(cp)	(((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) | 
|  |  | 
|  | #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 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 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 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); \ | 
|  | }) | 
|  |  | 
|  | #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 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 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); | 
|  | } | 
|  |  | 
|  | #endif /* !__GNUC__ */ | 
|  | #endif /* !_BCMENDIAN_H_ */ |