X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fbase%2Fice_bitops.h;h=b786bf7a18b0cc7b33fa6dac14d2c6d23a8ee899;hb=cb71192486c34eada5b65c6c46d32afd05cc091b;hp=32f64cac0c376a05420586b42bc84566cf3937a5;hpb=6b1172d4dc603bdf3a5a5a906deffb6e0853441c;p=dpdk.git diff --git a/drivers/net/ice/base/ice_bitops.h b/drivers/net/ice/base/ice_bitops.h index 32f64cac0c..b786bf7a18 100644 --- a/drivers/net/ice/base/ice_bitops.h +++ b/drivers/net/ice/base/ice_bitops.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2001-2019 + * Copyright(c) 2001-2020 Intel Corporation */ #ifndef _ICE_BITOPS_H_ @@ -214,7 +214,7 @@ ice_or_bitmap(ice_bitmap_t *dst, const ice_bitmap_t *bmp1, ice_bitmap_t mask; u16 i; - /* Handle all but last chunk*/ + /* Handle all but last chunk */ for (i = 0; i < BITS_TO_CHUNKS(size) - 1; i++) dst[i] = bmp1[i] | bmp2[i]; @@ -245,7 +245,7 @@ ice_xor_bitmap(ice_bitmap_t *dst, const ice_bitmap_t *bmp1, ice_bitmap_t mask; u16 i; - /* Handle all but last chunk*/ + /* Handle all but last chunk */ for (i = 0; i < BITS_TO_CHUNKS(size) - 1; i++) dst[i] = bmp1[i] ^ bmp2[i]; @@ -258,6 +258,37 @@ ice_xor_bitmap(ice_bitmap_t *dst, const ice_bitmap_t *bmp1, dst[i] = (dst[i] & ~mask) | ((bmp1[i] ^ bmp2[i]) & mask); } +/** + * ice_andnot_bitmap - bitwise ANDNOT 2 bitmaps and result in dst bitmap + * @dst: Destination bitmap that receive the result of the operation + * @bmp1: The first bitmap of ANDNOT operation + * @bmp2: The second bitmap to ANDNOT operation + * @size: Size of the bitmaps in bits + * + * This function performs a bitwise ANDNOT on two "source" bitmaps of the same + * size, and stores the result to "dst" bitmap. The "dst" bitmap must be of the + * same size as the "source" bitmaps to avoid buffer overflows. + */ +static inline void +ice_andnot_bitmap(ice_bitmap_t *dst, const ice_bitmap_t *bmp1, + const ice_bitmap_t *bmp2, u16 size) +{ + ice_bitmap_t mask; + u16 i; + + /* Handle all but last chunk */ + for (i = 0; i < BITS_TO_CHUNKS(size) - 1; i++) + dst[i] = bmp1[i] & ~bmp2[i]; + + /* We want to only clear bits within the size. Furthermore, we also do + * not want to modify destination bits which are beyond the specified + * size. Use a bitmask to ensure that we only modify the bits that are + * within the specified size. + */ + mask = LAST_CHUNK_MASK(size); + dst[i] = (dst[i] & ~mask) | ((bmp1[i] & ~bmp2[i]) & mask); +} + /** * ice_find_next_bit - Find the index of the next set bit of a bitmap * @bitmap: the bitmap to scan @@ -315,6 +346,11 @@ static inline u16 ice_find_first_bit(const ice_bitmap_t *bitmap, u16 size) return ice_find_next_bit(bitmap, size, 0); } +#define ice_for_each_set_bit(_bitpos, _addr, _maxlen) \ + for ((_bitpos) = ice_find_first_bit((_addr), (_maxlen)); \ + (_bitpos) < (_maxlen); \ + (_bitpos) = ice_find_next_bit((_addr), (_maxlen), (_bitpos) + 1)) + /** * ice_is_any_bit_set - Return true of any bit in the bitmap is set * @bitmap: the bitmap to check @@ -344,6 +380,48 @@ static inline void ice_cp_bitmap(ice_bitmap_t *dst, ice_bitmap_t *src, u16 size) ICE_NONDMA_TO_NONDMA); } +/** + * ice_bitmap_set - set a number of bits in bitmap from a starting position + * @dst: bitmap destination + * @pos: first bit position to set + * @num_bits: number of bits to set + * + * This function sets bits in a bitmap from pos to (pos + num_bits) - 1. + * Note that this function assumes it is operating on a bitmap declared using + * ice_declare_bitmap. + */ +static inline void +ice_bitmap_set(ice_bitmap_t *dst, u16 pos, u16 num_bits) +{ + u16 i; + + for (i = pos; i < pos + num_bits; i++) + ice_set_bit(i, dst); +} + +/** + * ice_bitmap_hweight - hamming weight of bitmap + * @bm: bitmap pointer + * @size: size of bitmap (in bits) + * + * This function determines the number of set bits in a bitmap. + * Note that this function assumes it is operating on a bitmap declared using + * ice_declare_bitmap. + */ +static inline int +ice_bitmap_hweight(ice_bitmap_t *bm, u16 size) +{ + int count = 0; + u16 bit = 0; + + while (size > (bit = ice_find_next_bit(bm, size, bit))) { + count++; + bit++; + } + + return count; +} + /** * ice_cmp_bitmaps - compares two bitmaps. * @bmp1: the bitmap to compare @@ -358,12 +436,12 @@ ice_cmp_bitmap(ice_bitmap_t *bmp1, ice_bitmap_t *bmp2, u16 size) ice_bitmap_t mask; u16 i; - /* Handle all but last chunk*/ + /* Handle all but last chunk */ for (i = 0; i < BITS_TO_CHUNKS(size) - 1; i++) if (bmp1[i] != bmp2[i]) return false; - /* We want to only compare bits within the size.*/ + /* We want to only compare bits within the size */ mask = LAST_CHUNK_MASK(size); if ((bmp1[i] & mask) != (bmp2[i] & mask)) return false; @@ -371,4 +449,49 @@ ice_cmp_bitmap(ice_bitmap_t *bmp1, ice_bitmap_t *bmp2, u16 size) return true; } +/** + * ice_bitmap_from_array32 - copies u32 array source into bitmap destination + * @dst: the destination bitmap + * @src: the source u32 array + * @size: size of the bitmap (in bits) + * + * This function copies the src bitmap stored in an u32 array into the dst + * bitmap stored as an ice_bitmap_t. + */ +static inline void +ice_bitmap_from_array32(ice_bitmap_t *dst, u32 *src, u16 size) +{ + u32 remaining_bits, i; + +#define BITS_PER_U32 (sizeof(u32) * BITS_PER_BYTE) + /* clear bitmap so we only have to set when iterating */ + ice_zero_bitmap(dst, size); + + for (i = 0; i < (u32)(size / BITS_PER_U32); i++) { + u32 bit_offset = i * BITS_PER_U32; + u32 entry = src[i]; + u32 j; + + for (j = 0; j < BITS_PER_U32; j++) { + if (entry & BIT(j)) + ice_set_bit((u16)(j + bit_offset), dst); + } + } + + /* still need to check the leftover bits (i.e. if size isn't evenly + * divisible by BITS_PER_U32 + **/ + remaining_bits = size % BITS_PER_U32; + if (remaining_bits) { + u32 bit_offset = i * BITS_PER_U32; + u32 entry = src[i]; + u32 j; + + for (j = 0; j < remaining_bits; j++) { + if (entry & BIT(j)) + ice_set_bit((u16)(j + bit_offset), dst); + } + } +} + #endif /* _ICE_BITOPS_H_ */