X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_core%2Fbitalloc.c;h=af1397071bc3bff8c20dc916cbeda70021cee982;hb=7100b0e5511e58269498900aea30bc03e15ba2fd;hp=fb4df9a1995878c70860fa04411369e3fe184857;hpb=a0dcaea290be0d48b748d0bfa5726250adbf86d8;p=dpdk.git diff --git a/drivers/net/bnxt/tf_core/bitalloc.c b/drivers/net/bnxt/tf_core/bitalloc.c index fb4df9a199..af1397071b 100644 --- a/drivers/net/bnxt/tf_core/bitalloc.c +++ b/drivers/net/bnxt/tf_core/bitalloc.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019-2020 Broadcom + * Copyright(c) 2019-2021 Broadcom * All rights reserved. */ @@ -7,6 +7,40 @@ #define BITALLOC_MAX_LEVELS 6 + +/* Finds the last bit set plus 1, equivalent to gcc __builtin_fls */ +static int +ba_fls(bitalloc_word_t v) +{ + int c = 32; + + if (!v) + return 0; + + if (!(v & 0xFFFF0000u)) { + v <<= 16; + c -= 16; + } + if (!(v & 0xFF000000u)) { + v <<= 8; + c -= 8; + } + if (!(v & 0xF0000000u)) { + v <<= 4; + c -= 4; + } + if (!(v & 0xC0000000u)) { + v <<= 2; + c -= 2; + } + if (!(v & 0x80000000u)) { + v <<= 1; + c -= 1; + } + + return c; +} + /* Finds the first bit set plus 1, equivalent to gcc __builtin_ffs */ static int ba_ffs(bitalloc_word_t v) @@ -120,6 +154,79 @@ ba_alloc(struct bitalloc *pool) return ba_alloc_helper(pool, 0, 1, 32, 0, &clear); } +/** + * Help function to alloc entry from highest available index + * + * Searching the pool from highest index for the empty entry. + * + * [in] pool + * Pointer to the resource pool + * + * [in] offset + * Offset of the storage in the pool + * + * [in] words + * Number of words in this level + * + * [in] size + * Number of entries in this level + * + * [in] index + * Index of words that has the entry + * + * [in] clear + * Indicate if a bit needs to be clear due to the entry is allocated + * + * Returns: + * 0 - Success + * -1 - Failure + */ +static int +ba_alloc_reverse_helper(struct bitalloc *pool, + int offset, + int words, + unsigned int size, + int index, + int *clear) +{ + bitalloc_word_t *storage = &pool->storage[offset]; + int loc = ba_fls(storage[index]); + int r; + + if (loc == 0) + return -1; + + loc--; + + if (pool->size > size) { + r = ba_alloc_reverse_helper(pool, + offset + words + 1, + storage[words], + size * 32, + index * 32 + loc, + clear); + } else { + r = index * 32 + loc; + *clear = 1; + pool->free_count--; + } + + if (*clear) { + storage[index] &= ~(1 << loc); + *clear = (storage[index] == 0); + } + + return r; +} + +int +ba_alloc_reverse(struct bitalloc *pool) +{ + int clear = 0; + + return ba_alloc_reverse_helper(pool, 0, 1, 32, 0, &clear); +} + static int ba_alloc_index_helper(struct bitalloc *pool, int offset,