diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:35:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:31 +0000 |
commit | 85c675d0d09a45a135bddd15d7b385f8758c32fb (patch) | |
tree | 76267dbc9b9a130337be3640948fe397b04ac629 /drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c | |
parent | Adding upstream version 6.6.15. (diff) | |
download | linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.tar.xz linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.zip |
Adding upstream version 6.7.7.upstream/6.7.7
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c index 70f9b5e85a..0d5e6f9b46 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c @@ -32,8 +32,7 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8), MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2), MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6), - MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_MSB, 0x18, 17, 4), - MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_LSB, 0x18, 21, 8), + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER, 0x18, 17, 12), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4), @@ -44,6 +43,9 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4), MLXSW_AFK_ELEMENT_INFO_U32(FDB_MISS, 0x40, 0, 1), MLXSW_AFK_ELEMENT_INFO_U32(L4_PORT_RANGE, 0x40, 1, 16), + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_3, 0x40, 17, 4), + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_4_7, 0x40, 21, 4), + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_MSB, 0x40, 25, 4), }; struct mlxsw_afk { @@ -136,6 +138,7 @@ mlxsw_afk_key_info_find(struct mlxsw_afk *mlxsw_afk, struct mlxsw_afk_picker { DECLARE_BITMAP(element, MLXSW_AFK_ELEMENT_MAX); + DECLARE_BITMAP(chosen_element, MLXSW_AFK_ELEMENT_MAX); unsigned int total; }; @@ -206,7 +209,7 @@ static int mlxsw_afk_picker_key_info_add(struct mlxsw_afk *mlxsw_afk, if (key_info->blocks_count == mlxsw_afk->max_blocks) return -EINVAL; - for_each_set_bit(element, picker[block_index].element, + for_each_set_bit(element, picker[block_index].chosen_element, MLXSW_AFK_ELEMENT_MAX) { key_info->element_to_block[element] = key_info->blocks_count; mlxsw_afk_element_usage_add(&key_info->elusage, element); @@ -218,11 +221,43 @@ static int mlxsw_afk_picker_key_info_add(struct mlxsw_afk *mlxsw_afk, return 0; } +static int mlxsw_afk_keys_fill(struct mlxsw_afk *mlxsw_afk, + unsigned long *chosen_blocks_bm, + struct mlxsw_afk_picker *picker, + struct mlxsw_afk_key_info *key_info) +{ + int i, err; + + /* First fill only key blocks with high_entropy. */ + for_each_set_bit(i, chosen_blocks_bm, mlxsw_afk->blocks_count) { + if (!mlxsw_afk->blocks[i].high_entropy) + continue; + + err = mlxsw_afk_picker_key_info_add(mlxsw_afk, picker, i, + key_info); + if (err) + return err; + __clear_bit(i, chosen_blocks_bm); + } + + /* Fill the rest of key blocks. */ + for_each_set_bit(i, chosen_blocks_bm, mlxsw_afk->blocks_count) { + err = mlxsw_afk_picker_key_info_add(mlxsw_afk, picker, i, + key_info); + if (err) + return err; + } + + return 0; +} + static int mlxsw_afk_picker(struct mlxsw_afk *mlxsw_afk, struct mlxsw_afk_key_info *key_info, struct mlxsw_afk_element_usage *elusage) { + DECLARE_BITMAP(elusage_chosen, MLXSW_AFK_ELEMENT_MAX) = {0}; struct mlxsw_afk_picker *picker; + unsigned long *chosen_blocks_bm; enum mlxsw_afk_element element; int err; @@ -230,6 +265,12 @@ static int mlxsw_afk_picker(struct mlxsw_afk *mlxsw_afk, if (!picker) return -ENOMEM; + chosen_blocks_bm = bitmap_zalloc(mlxsw_afk->blocks_count, GFP_KERNEL); + if (!chosen_blocks_bm) { + err = -ENOMEM; + goto err_bitmap_alloc; + } + /* Since the same elements could be present in multiple blocks, * we must find out optimal block list in order to make the * block count as low as possible. @@ -254,15 +295,26 @@ static int mlxsw_afk_picker(struct mlxsw_afk *mlxsw_afk, err = block_index; goto out; } - err = mlxsw_afk_picker_key_info_add(mlxsw_afk, picker, - block_index, key_info); - if (err) - goto out; + + __set_bit(block_index, chosen_blocks_bm); + + bitmap_copy(picker[block_index].chosen_element, + picker[block_index].element, MLXSW_AFK_ELEMENT_MAX); + + bitmap_or(elusage_chosen, elusage_chosen, + picker[block_index].chosen_element, + MLXSW_AFK_ELEMENT_MAX); + mlxsw_afk_picker_subtract_hits(mlxsw_afk, picker, block_index); - } while (!mlxsw_afk_key_info_elements_eq(key_info, elusage)); - err = 0; + } while (!bitmap_equal(elusage_chosen, elusage->usage, + MLXSW_AFK_ELEMENT_MAX)); + + err = mlxsw_afk_keys_fill(mlxsw_afk, chosen_blocks_bm, picker, + key_info); out: + bitmap_free(chosen_blocks_bm); +err_bitmap_alloc: kfree(picker); return err; } |