wifi: mt76: fix index accounting in __mt76_wcid_alloc for offset ranges

The allocator advances the mask pointer by min / 32 words but computes
the returned index relative to the shifted base, while the size bound
check treats the same value as absolute. For the WED WDS range
(min 256, size 272), a free slot at absolute index 256 + n marked bit
256 + n in the mask but returned n, colliding with regular WTBL
entries, and the relative bound check allowed scanning far beyond the
requested range.

Keep the word offset in the loop index instead of shifting the mask
pointer, so marking, return value and bound check all use absolute
indices.

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2026-07-22 09:50:21 +02:00
parent 968dc6335a
commit 8e1889a5ba
+4 -6
View File
@@ -45,14 +45,12 @@ EXPORT_SYMBOL_GPL(____mt76_poll_msec);
int __mt76_wcid_alloc(u32 *mask, int min, int size) int __mt76_wcid_alloc(u32 *mask, int min, int size)
{ {
u32 min_mask = ~0; u32 min_mask = ~0;
int i, idx = 0, cur; int i, idx, cur;
mask += min / 32; if (min % 32)
min %= 32; min_mask = ~((1 << (min % 32)) - 1);
if (min > 0)
min_mask = ~((1 << min) - 1);
for (i = 0; i < DIV_ROUND_UP(size, 32); i++) { for (i = min / 32; i < DIV_ROUND_UP(size, 32); i++) {
idx = ffs(~mask[i] & min_mask); idx = ffs(~mask[i] & min_mask);
min_mask = ~0; min_mask = ~0;
if (!idx) if (!idx)