1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/* Copyright (c) 2021 Mellanox Technologies. */
3
4#include "fs_ft_pool.h"
5
6/* Firmware currently has 4 pool of 4 sizes that it supports (FT_POOLS),
7 * and a virtual memory region of 16M (MLX5_FT_SIZE), this region is duplicated
8 * for each flow table pool. We can allocate up to 16M of each pool,
9 * and we keep track of how much we used via mlx5_ft_pool_get_avail_sz.
10 * Firmware doesn't report any of this for now.
11 * ESW_POOL is expected to be sorted from large to small and match firmware
12 * pools.
13 */
14#define FT_SIZE (16 * 1024 * 1024)
15static const unsigned int FT_POOLS[] = { 4 * 1024 * 1024,
16 1 * 1024 * 1024,
17 64 * 1024,
18 128,
19 1 /* size for termination tables */ };
20struct mlx5_ft_pool {
21 int ft_left[ARRAY_SIZE(FT_POOLS)];
22};
23
24int mlx5_ft_pool_init(struct mlx5_core_dev *dev)
25{
26 struct mlx5_ft_pool *ft_pool;
27 int i;
28
29 ft_pool = kzalloc(size: sizeof(*ft_pool), GFP_KERNEL);
30 if (!ft_pool)
31 return -ENOMEM;
32
33 for (i = ARRAY_SIZE(FT_POOLS) - 1; i >= 0; i--)
34 ft_pool->ft_left[i] = FT_SIZE / FT_POOLS[i];
35
36 dev->priv.ft_pool = ft_pool;
37 return 0;
38}
39
40void mlx5_ft_pool_destroy(struct mlx5_core_dev *dev)
41{
42 kfree(objp: dev->priv.ft_pool);
43}
44
45int
46mlx5_ft_pool_get_avail_sz(struct mlx5_core_dev *dev, enum fs_flow_table_type table_type,
47 int desired_size)
48{
49 u32 max_ft_size = 1 << MLX5_CAP_FLOWTABLE_TYPE(dev, log_max_ft_size, table_type);
50 int i, found_i = -1;
51
52 for (i = ARRAY_SIZE(FT_POOLS) - 1; i >= 0; i--) {
53 if (dev->priv.ft_pool->ft_left[i] && FT_POOLS[i] >= desired_size &&
54 FT_POOLS[i] <= max_ft_size) {
55 found_i = i;
56 if (desired_size != POOL_NEXT_SIZE)
57 break;
58 }
59 }
60
61 if (found_i != -1) {
62 --dev->priv.ft_pool->ft_left[found_i];
63 return FT_POOLS[found_i];
64 }
65
66 return 0;
67}
68
69void
70mlx5_ft_pool_put_sz(struct mlx5_core_dev *dev, int sz)
71{
72 int i;
73
74 if (!sz)
75 return;
76
77 for (i = ARRAY_SIZE(FT_POOLS) - 1; i >= 0; i--) {
78 if (sz == FT_POOLS[i]) {
79 ++dev->priv.ft_pool->ft_left[i];
80 return;
81 }
82 }
83
84 WARN_ONCE(1, "Couldn't find size %d in flow table size pool", sz);
85}
86

source code of linux/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c