Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2010 Broadcom Corporation |
| 3 | * |
| 4 | * Permission to use, copy, modify, and/or distribute this software for any |
| 5 | * purpose with or without fee is hereby granted, provided that the above |
| 6 | * copyright notice and this permission notice appear in all copies. |
| 7 | * |
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 15 | */ |
| 16 | |
| 17 | #ifndef _BCMENDIAN_H_ |
| 18 | #define _BCMENDIAN_H_ |
| 19 | |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 20 | /* Reverse the bytes in a 16-bit value */ |
| 21 | #define BCMSWAP16(val) \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 22 | ((u16)((((u16)(val) & (u16)0x00ffU) << 8) | \ |
| 23 | (((u16)(val) & (u16)0xff00U) >> 8))) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 24 | |
| 25 | /* Reverse the bytes in a 32-bit value */ |
| 26 | #define BCMSWAP32(val) \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 27 | ((u32)((((u32)(val) & (u32)0x000000ffU) << 24) | \ |
| 28 | (((u32)(val) & (u32)0x0000ff00U) << 8) | \ |
| 29 | (((u32)(val) & (u32)0x00ff0000U) >> 8) | \ |
| 30 | (((u32)(val) & (u32)0xff000000U) >> 24))) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 31 | |
| 32 | /* Reverse the two 16-bit halves of a 32-bit value */ |
| 33 | #define BCMSWAP32BY16(val) \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 34 | ((u32)((((u32)(val) & (u32)0x0000ffffU) << 16) | \ |
| 35 | (((u32)(val) & (u32)0xffff0000U) >> 16))) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 36 | |
| 37 | /* Byte swapping macros |
| 38 | * Host <=> Network (Big Endian) for 16- and 32-bit values |
| 39 | * Host <=> Little-Endian for 16- and 32-bit values |
| 40 | */ |
| 41 | #ifndef hton16 |
| 42 | #ifndef IL_BIGENDIAN |
| 43 | #define HTON16(i) BCMSWAP16(i) |
| 44 | #define hton16(i) bcmswap16(i) |
| 45 | #define HTON32(i) BCMSWAP32(i) |
| 46 | #define hton32(i) bcmswap32(i) |
| 47 | #define NTOH16(i) BCMSWAP16(i) |
| 48 | #define ntoh16(i) bcmswap16(i) |
| 49 | #define NTOH32(i) BCMSWAP32(i) |
| 50 | #define ntoh32(i) bcmswap32(i) |
| 51 | #define LTOH16(i) (i) |
| 52 | #define ltoh16(i) (i) |
| 53 | #define LTOH32(i) (i) |
| 54 | #define ltoh32(i) (i) |
| 55 | #define HTOL16(i) (i) |
| 56 | #define htol16(i) (i) |
| 57 | #define HTOL32(i) (i) |
| 58 | #define htol32(i) (i) |
| 59 | #else /* IL_BIGENDIAN */ |
| 60 | #define HTON16(i) (i) |
| 61 | #define hton16(i) (i) |
| 62 | #define HTON32(i) (i) |
| 63 | #define hton32(i) (i) |
| 64 | #define NTOH16(i) (i) |
| 65 | #define ntoh16(i) (i) |
| 66 | #define NTOH32(i) (i) |
| 67 | #define ntoh32(i) (i) |
| 68 | #define LTOH16(i) BCMSWAP16(i) |
| 69 | #define ltoh16(i) bcmswap16(i) |
| 70 | #define LTOH32(i) BCMSWAP32(i) |
| 71 | #define ltoh32(i) bcmswap32(i) |
| 72 | #define HTOL16(i) BCMSWAP16(i) |
| 73 | #define htol16(i) bcmswap16(i) |
| 74 | #define HTOL32(i) BCMSWAP32(i) |
| 75 | #define htol32(i) bcmswap32(i) |
| 76 | #endif /* IL_BIGENDIAN */ |
| 77 | #endif /* hton16 */ |
| 78 | |
| 79 | #ifndef IL_BIGENDIAN |
| 80 | #define ltoh16_buf(buf, i) |
| 81 | #define htol16_buf(buf, i) |
| 82 | #else |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 83 | #define ltoh16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i)) |
| 84 | #define htol16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i)) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 85 | #endif /* IL_BIGENDIAN */ |
| 86 | |
| 87 | /* Unaligned loads and stores in host byte order */ |
| 88 | #ifndef IL_BIGENDIAN |
| 89 | #define load32_ua(a) ltoh32_ua(a) |
| 90 | #define store32_ua(a, v) htol32_ua_store(v, a) |
| 91 | #define load16_ua(a) ltoh16_ua(a) |
| 92 | #define store16_ua(a, v) htol16_ua_store(v, a) |
| 93 | #else |
| 94 | #define load32_ua(a) ntoh32_ua(a) |
| 95 | #define store32_ua(a, v) hton32_ua_store(v, a) |
| 96 | #define load16_ua(a) ntoh16_ua(a) |
| 97 | #define store16_ua(a, v) hton16_ua_store(v, a) |
| 98 | #endif /* IL_BIGENDIAN */ |
| 99 | |
| 100 | #define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) |
| 101 | #define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) |
| 102 | #define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) |
| 103 | #define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) |
| 104 | |
| 105 | #define ltoh_ua(ptr) \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 106 | (sizeof(*(ptr)) == sizeof(u8) ? *(const u8 *)(ptr) : \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 107 | sizeof(*(ptr)) == sizeof(u16) ? _LTOH16_UA((const u8 *)(ptr)) : \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 108 | sizeof(*(ptr)) == sizeof(u32) ? _LTOH32_UA((const u8 *)(ptr)) : \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 109 | *(u8 *)0) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 110 | |
| 111 | #define ntoh_ua(ptr) \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 112 | (sizeof(*(ptr)) == sizeof(u8) ? *(const u8 *)(ptr) : \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 113 | sizeof(*(ptr)) == sizeof(u16) ? _NTOH16_UA((const u8 *)(ptr)) : \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 114 | sizeof(*(ptr)) == sizeof(u32) ? _NTOH32_UA((const u8 *)(ptr)) : \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 115 | *(u8 *)0) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 116 | |
| 117 | #ifdef __GNUC__ |
| 118 | |
| 119 | /* GNU macro versions avoid referencing the argument multiple times, while also |
| 120 | * avoiding the -fno-inline used in ROM builds. |
| 121 | */ |
| 122 | |
| 123 | #define bcmswap16(val) ({ \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 124 | u16 _val = (val); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 125 | BCMSWAP16(_val); \ |
| 126 | }) |
| 127 | |
| 128 | #define bcmswap32(val) ({ \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 129 | u32 _val = (val); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 130 | BCMSWAP32(_val); \ |
| 131 | }) |
| 132 | |
| 133 | #define bcmswap32by16(val) ({ \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 134 | u32 _val = (val); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 135 | BCMSWAP32BY16(_val); \ |
| 136 | }) |
| 137 | |
| 138 | #define bcmswap16_buf(buf, len) ({ \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 139 | u16 *_buf = (u16 *)(buf); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 140 | uint _wds = (len) / 2; \ |
| 141 | while (_wds--) { \ |
| 142 | *_buf = bcmswap16(*_buf); \ |
| 143 | _buf++; \ |
| 144 | } \ |
| 145 | }) |
| 146 | |
| 147 | #define htol16_ua_store(val, bytes) ({ \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 148 | u16 _val = (val); \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 149 | u8 *_bytes = (u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 150 | _bytes[0] = _val & 0xff; \ |
| 151 | _bytes[1] = _val >> 8; \ |
| 152 | }) |
| 153 | |
| 154 | #define htol32_ua_store(val, bytes) ({ \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 155 | u32 _val = (val); \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 156 | u8 *_bytes = (u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 157 | _bytes[0] = _val & 0xff; \ |
| 158 | _bytes[1] = (_val >> 8) & 0xff; \ |
| 159 | _bytes[2] = (_val >> 16) & 0xff; \ |
| 160 | _bytes[3] = _val >> 24; \ |
| 161 | }) |
| 162 | |
| 163 | #define hton16_ua_store(val, bytes) ({ \ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 164 | u16 _val = (val); \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 165 | u8 *_bytes = (u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 166 | _bytes[0] = _val >> 8; \ |
| 167 | _bytes[1] = _val & 0xff; \ |
| 168 | }) |
| 169 | |
| 170 | #define hton32_ua_store(val, bytes) ({ \ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 171 | u32 _val = (val); \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 172 | u8 *_bytes = (u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 173 | _bytes[0] = _val >> 24; \ |
| 174 | _bytes[1] = (_val >> 16) & 0xff; \ |
| 175 | _bytes[2] = (_val >> 8) & 0xff; \ |
| 176 | _bytes[3] = _val & 0xff; \ |
| 177 | }) |
| 178 | |
| 179 | #define ltoh16_ua(bytes) ({ \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 180 | const u8 *_bytes = (const u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 181 | _LTOH16_UA(_bytes); \ |
| 182 | }) |
| 183 | |
| 184 | #define ltoh32_ua(bytes) ({ \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 185 | const u8 *_bytes = (const u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 186 | _LTOH32_UA(_bytes); \ |
| 187 | }) |
| 188 | |
| 189 | #define ntoh16_ua(bytes) ({ \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 190 | const u8 *_bytes = (const u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 191 | _NTOH16_UA(_bytes); \ |
| 192 | }) |
| 193 | |
| 194 | #define ntoh32_ua(bytes) ({ \ |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 195 | const u8 *_bytes = (const u8 *)(bytes); \ |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 196 | _NTOH32_UA(_bytes); \ |
| 197 | }) |
| 198 | |
| 199 | #else /* !__GNUC__ */ |
| 200 | |
| 201 | /* Inline versions avoid referencing the argument multiple times */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 202 | static inline u16 bcmswap16(u16 val) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 203 | { |
| 204 | return BCMSWAP16(val); |
| 205 | } |
| 206 | |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 207 | static inline u32 bcmswap32(u32 val) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 208 | { |
| 209 | return BCMSWAP32(val); |
| 210 | } |
| 211 | |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 212 | static inline u32 bcmswap32by16(u32 val) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 213 | { |
| 214 | return BCMSWAP32BY16(val); |
| 215 | } |
| 216 | |
| 217 | /* Reverse pairs of bytes in a buffer (not for high-performance use) */ |
| 218 | /* buf - start of buffer of shorts to swap */ |
| 219 | /* len - byte length of buffer */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 220 | static inline void bcmswap16_buf(u16 *buf, uint len) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 221 | { |
| 222 | len = len / 2; |
| 223 | |
| 224 | while (len--) { |
| 225 | *buf = bcmswap16(*buf); |
| 226 | buf++; |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | /* |
| 231 | * Store 16-bit value to unaligned little-endian byte array. |
| 232 | */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 233 | static inline void htol16_ua_store(u16 val, u8 *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 234 | { |
| 235 | bytes[0] = val & 0xff; |
| 236 | bytes[1] = val >> 8; |
| 237 | } |
| 238 | |
| 239 | /* |
| 240 | * Store 32-bit value to unaligned little-endian byte array. |
| 241 | */ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 242 | static inline void htol32_ua_store(u32 val, u8 *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 243 | { |
| 244 | bytes[0] = val & 0xff; |
| 245 | bytes[1] = (val >> 8) & 0xff; |
| 246 | bytes[2] = (val >> 16) & 0xff; |
| 247 | bytes[3] = val >> 24; |
| 248 | } |
| 249 | |
| 250 | /* |
| 251 | * Store 16-bit value to unaligned network-(big-)endian byte array. |
| 252 | */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 253 | static inline void hton16_ua_store(u16 val, u8 *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 254 | { |
| 255 | bytes[0] = val >> 8; |
| 256 | bytes[1] = val & 0xff; |
| 257 | } |
| 258 | |
| 259 | /* |
| 260 | * Store 32-bit value to unaligned network-(big-)endian byte array. |
| 261 | */ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 262 | static inline void hton32_ua_store(u32 val, u8 *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 263 | { |
| 264 | bytes[0] = val >> 24; |
| 265 | bytes[1] = (val >> 16) & 0xff; |
| 266 | bytes[2] = (val >> 8) & 0xff; |
| 267 | bytes[3] = val & 0xff; |
| 268 | } |
| 269 | |
| 270 | /* |
| 271 | * Load 16-bit value from unaligned little-endian byte array. |
| 272 | */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 273 | static inline u16 ltoh16_ua(const void *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 274 | { |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 275 | return _LTOH16_UA((const u8 *)bytes); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 276 | } |
| 277 | |
| 278 | /* |
| 279 | * Load 32-bit value from unaligned little-endian byte array. |
| 280 | */ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 281 | static inline u32 ltoh32_ua(const void *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 282 | { |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 283 | return _LTOH32_UA((const u8 *)bytes); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 284 | } |
| 285 | |
| 286 | /* |
| 287 | * Load 16-bit value from unaligned big-(network-)endian byte array. |
| 288 | */ |
Greg Kroah-Hartman | 7d4df48 | 2010-10-07 17:04:47 -0700 | [diff] [blame] | 289 | static inline u16 ntoh16_ua(const void *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 290 | { |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 291 | return _NTOH16_UA((const u8 *)bytes); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 292 | } |
| 293 | |
| 294 | /* |
| 295 | * Load 32-bit value from unaligned big-(network-)endian byte array. |
| 296 | */ |
Greg Kroah-Hartman | 66cbd3a | 2010-10-08 11:05:47 -0700 | [diff] [blame] | 297 | static inline u32 ntoh32_ua(const void *bytes) |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 298 | { |
Greg Kroah-Hartman | de9bca6 | 2010-10-05 10:23:40 -0700 | [diff] [blame] | 299 | return _NTOH32_UA((const u8 *)bytes); |
Henry Ptasinski | a9533e7 | 2010-09-08 21:04:42 -0700 | [diff] [blame] | 300 | } |
| 301 | |
| 302 | #endif /* !__GNUC__ */ |
| 303 | #endif /* !_BCMENDIAN_H_ */ |