Commit 8494ab06 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum_router: Query number of LPM trees from firmware

Instead of hard coding the number of LPM trees in the driver, query it
from the firmware, as it may change in future devices.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ba82427d
...@@ -61,6 +61,7 @@ enum mlxsw_res_id { ...@@ -61,6 +61,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_MAX_CPU_POLICERS, MLXSW_RES_ID_MAX_CPU_POLICERS,
MLXSW_RES_ID_MAX_VRS, MLXSW_RES_ID_MAX_VRS,
MLXSW_RES_ID_MAX_RIFS, MLXSW_RES_ID_MAX_RIFS,
MLXSW_RES_ID_MAX_LPM_TREES,
/* Internal resources. /* Internal resources.
* Determined by the SW, not queried from the HW. * Determined by the SW, not queried from the HW.
...@@ -95,6 +96,7 @@ static u16 mlxsw_res_ids[] = { ...@@ -95,6 +96,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13, [MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13,
[MLXSW_RES_ID_MAX_VRS] = 0x2C01, [MLXSW_RES_ID_MAX_VRS] = 0x2C01,
[MLXSW_RES_ID_MAX_RIFS] = 0x2C02, [MLXSW_RES_ID_MAX_RIFS] = 0x2C02,
[MLXSW_RES_ID_MAX_LPM_TREES] = 0x2C30,
}; };
struct mlxsw_res { struct mlxsw_res {
......
...@@ -63,10 +63,6 @@ ...@@ -63,10 +63,6 @@
#define MLXSW_SP_PORTS_PER_CLUSTER_MAX 4 #define MLXSW_SP_PORTS_PER_CLUSTER_MAX 4
#define MLXSW_SP_LPM_TREE_MIN 2 /* trees 0 and 1 are reserved */
#define MLXSW_SP_LPM_TREE_MAX 22
#define MLXSW_SP_LPM_TREE_COUNT (MLXSW_SP_LPM_TREE_MAX - MLXSW_SP_LPM_TREE_MIN)
#define MLXSW_SP_PORT_BASE_SPEED 25000 /* Mb/s */ #define MLXSW_SP_PORT_BASE_SPEED 25000 /* Mb/s */
#define MLXSW_SP_BYTES_PER_CELL 96 #define MLXSW_SP_BYTES_PER_CELL 96
...@@ -230,11 +226,14 @@ struct mlxsw_sp_port_mall_tc_entry { ...@@ -230,11 +226,14 @@ struct mlxsw_sp_port_mall_tc_entry {
}; };
struct mlxsw_sp_router { struct mlxsw_sp_router {
struct mlxsw_sp_lpm_tree lpm_trees[MLXSW_SP_LPM_TREE_COUNT];
struct mlxsw_sp_vr *vrs; struct mlxsw_sp_vr *vrs;
struct rhashtable neigh_ht; struct rhashtable neigh_ht;
struct rhashtable nexthop_group_ht; struct rhashtable nexthop_group_ht;
struct rhashtable nexthop_ht; struct rhashtable nexthop_ht;
struct {
struct mlxsw_sp_lpm_tree *trees;
unsigned int tree_count;
} lpm;
struct { struct {
struct delayed_work dw; struct delayed_work dw;
unsigned long interval; /* ms */ unsigned long interval; /* ms */
......
...@@ -206,8 +206,8 @@ mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp) ...@@ -206,8 +206,8 @@ mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp)
static struct mlxsw_sp_lpm_tree *lpm_tree; static struct mlxsw_sp_lpm_tree *lpm_tree;
int i; int i;
for (i = 0; i < MLXSW_SP_LPM_TREE_COUNT; i++) { for (i = 0; i < mlxsw_sp->router.lpm.tree_count; i++) {
lpm_tree = &mlxsw_sp->router.lpm_trees[i]; lpm_tree = &mlxsw_sp->router.lpm.trees[i];
if (lpm_tree->ref_count == 0) if (lpm_tree->ref_count == 0)
return lpm_tree; return lpm_tree;
} }
...@@ -303,8 +303,8 @@ mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp, ...@@ -303,8 +303,8 @@ mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree; struct mlxsw_sp_lpm_tree *lpm_tree;
int i; int i;
for (i = 0; i < MLXSW_SP_LPM_TREE_COUNT; i++) { for (i = 0; i < mlxsw_sp->router.lpm.tree_count; i++) {
lpm_tree = &mlxsw_sp->router.lpm_trees[i]; lpm_tree = &mlxsw_sp->router.lpm.trees[i];
if (lpm_tree->ref_count != 0 && if (lpm_tree->ref_count != 0 &&
lpm_tree->proto == proto && lpm_tree->proto == proto &&
mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage, mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage,
...@@ -329,15 +329,36 @@ static int mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp, ...@@ -329,15 +329,36 @@ static int mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
return 0; return 0;
} }
static void mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp) #define MLXSW_SP_LPM_TREE_MIN 2 /* trees 0 and 1 are reserved */
static int mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_sp_lpm_tree *lpm_tree; struct mlxsw_sp_lpm_tree *lpm_tree;
u64 max_trees;
int i; int i;
for (i = 0; i < MLXSW_SP_LPM_TREE_COUNT; i++) { if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LPM_TREES))
lpm_tree = &mlxsw_sp->router.lpm_trees[i]; return -EIO;
max_trees = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LPM_TREES);
mlxsw_sp->router.lpm.tree_count = max_trees - MLXSW_SP_LPM_TREE_MIN;
mlxsw_sp->router.lpm.trees = kcalloc(mlxsw_sp->router.lpm.tree_count,
sizeof(struct mlxsw_sp_lpm_tree),
GFP_KERNEL);
if (!mlxsw_sp->router.lpm.trees)
return -ENOMEM;
for (i = 0; i < mlxsw_sp->router.lpm.tree_count; i++) {
lpm_tree = &mlxsw_sp->router.lpm.trees[i];
lpm_tree->id = i + MLXSW_SP_LPM_TREE_MIN; lpm_tree->id = i + MLXSW_SP_LPM_TREE_MIN;
} }
return 0;
}
static void mlxsw_sp_lpm_fini(struct mlxsw_sp *mlxsw_sp)
{
kfree(mlxsw_sp->router.lpm.trees);
} }
static bool mlxsw_sp_vr_is_used(const struct mlxsw_sp_vr *vr) static bool mlxsw_sp_vr_is_used(const struct mlxsw_sp_vr *vr)
...@@ -3372,7 +3393,10 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) ...@@ -3372,7 +3393,10 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
if (err) if (err)
goto err_nexthop_group_ht_init; goto err_nexthop_group_ht_init;
mlxsw_sp_lpm_init(mlxsw_sp); err = mlxsw_sp_lpm_init(mlxsw_sp);
if (err)
goto err_lpm_init;
err = mlxsw_sp_vrs_init(mlxsw_sp); err = mlxsw_sp_vrs_init(mlxsw_sp);
if (err) if (err)
goto err_vrs_init; goto err_vrs_init;
...@@ -3394,6 +3418,8 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) ...@@ -3394,6 +3418,8 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
err_neigh_init: err_neigh_init:
mlxsw_sp_vrs_fini(mlxsw_sp); mlxsw_sp_vrs_fini(mlxsw_sp);
err_vrs_init: err_vrs_init:
mlxsw_sp_lpm_fini(mlxsw_sp);
err_lpm_init:
rhashtable_destroy(&mlxsw_sp->router.nexthop_group_ht); rhashtable_destroy(&mlxsw_sp->router.nexthop_group_ht);
err_nexthop_group_ht_init: err_nexthop_group_ht_init:
rhashtable_destroy(&mlxsw_sp->router.nexthop_ht); rhashtable_destroy(&mlxsw_sp->router.nexthop_ht);
...@@ -3407,6 +3433,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) ...@@ -3407,6 +3433,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
unregister_fib_notifier(&mlxsw_sp->fib_nb); unregister_fib_notifier(&mlxsw_sp->fib_nb);
mlxsw_sp_neigh_fini(mlxsw_sp); mlxsw_sp_neigh_fini(mlxsw_sp);
mlxsw_sp_vrs_fini(mlxsw_sp); mlxsw_sp_vrs_fini(mlxsw_sp);
mlxsw_sp_lpm_fini(mlxsw_sp);
rhashtable_destroy(&mlxsw_sp->router.nexthop_group_ht); rhashtable_destroy(&mlxsw_sp->router.nexthop_group_ht);
rhashtable_destroy(&mlxsw_sp->router.nexthop_ht); rhashtable_destroy(&mlxsw_sp->router.nexthop_ht);
__mlxsw_sp_router_fini(mlxsw_sp); __mlxsw_sp_router_fini(mlxsw_sp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment