#ifndef __NET_BITOPS_H__ #define __NET_BITOPS_H__ #include "net_defs.h" #include "byteorder.h" #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) #define BITS_PER_BYTE 8 #ifndef BITS_TO_LONGS /* Older kernels define this already */ #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #endif #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) #define BITMAP_LAST_WORD_MASK(nbits) \ ( \ ((nbits) % BITS_PER_LONG) ? \ (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ ) extern int bitmap_empty(const unsigned long *bitmap, int bits); extern unsigned int __sw_hweight16(unsigned int w); #define hweight16(w) __sw_hweight16(w) extern unsigned int hweight32(unsigned int w); extern unsigned long hweight64(__u64 w); static inline void __clear_bit(int nr, volatile unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); *p &= ~mask; } static inline void __set_bit(int nr, volatile unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); *p |= mask; } static __INLINE void set_bit(unsigned long nr, volatile void * addr) { int *m = ((int *) addr) + (nr >> 5); *m |= 1 << (nr & 31); } static __INLINE void clear_bit(unsigned long nr, volatile void * addr) { int *m = ((int *) addr) + (nr >> 5); *m &= ~(1 << (nr & 31)); } static inline int test_bit(unsigned long nr, volatile void * addr) { unsigned long mask = 1 << (nr & 0x1f); int *m = ((int *) addr) + (nr >> 5); return ((*m) & mask) != 0; } static inline int test_and_set_bit(unsigned long nr, volatile void * addr) { unsigned long mask = 1 << (nr & 0x1f); int *m = ((int *) addr) + (nr >> 5); int old = *m; *m = old | mask; return (old & mask) != 0; } static inline int test_and_clear_bit(unsigned long nr, volatile void * addr) { unsigned long mask = 1 << (nr & 0x1f); int *m = ((int *) addr) + (nr >> 5); int old = *m; *m = old & ~mask; return (old & mask) != 0; } int fls(int x); /** * __ffs - find first bit in word. * @word: The word to search * * Undefined if no bit exists, so code should check against 0 first. */ static inline unsigned long __ffs(unsigned long word) { int num = 0; #if BITS_PER_LONG == 64 if ((word & 0xffffffff) == 0) { num += 32; word >>= 32; } #endif if ((word & 0xffff) == 0) { num += 16; word >>= 16; } if ((word & 0xff) == 0) { num += 8; word >>= 8; } if ((word & 0xf) == 0) { num += 4; word >>= 4; } if ((word & 0x3) == 0) { num += 2; word >>= 2; } if ((word & 0x1) == 0) num += 1; return num; } static inline unsigned long __ffs64(u64 word) { #if BITS_PER_LONG == 32 if (((u32)word) == 0UL) return __ffs((u32)(word >> 32)) + 32; #elif BITS_PER_LONG != 64 #error BITS_PER_LONG not 32 or 64 #endif return __ffs((unsigned long)word); } #if 0 static inline int ffs(int x) { int r = 1; if (!x) return 0; if (!(x & 0xffff)) { x >>= 16; r += 16; } if (!(x & 0xff)) { x >>= 8; r += 8; } if (!(x & 0xf)) { x >>= 4; r += 4; } if (!(x & 3)) { x >>= 2; r += 2; } if (!(x & 1)) { x >>= 1; r += 1; } return r; } #endif static __INLINE int fls64(__u64 x) { __u32 h = x >> 32; if (h) return fls(h) + 32; return fls(x); } /** * rol32 - rotate a 32-bit value left * @word: value to rotate * @shift: bits to roll */ static __INLINE __u32 rol32(__u32 word, unsigned int shift) { return (word << shift) | (word >> (32 - shift)); } /** * ror32 - rotate a 32-bit value right * @word: value to rotate * @shift: bits to roll */ static __INLINE __u32 ror32(__u32 word, unsigned int shift) { return (word >> shift) | (word << (32 - shift)); } #endif