Commit cf735d4c authored by Amit Cohen's avatar Amit Cohen Committed by Jakub Kicinski

mlxsw: Add a helper function for getting maximum LAG ID

Currently the driver queries the maximum supported LAG ID from firmware.
This will not be accurate anymore once the driver will configure 'max_lag'
via CONFIG_PROFILE command.

For resource query, firmware returns the maximum LAG ID which is supported
by hardware. Software can configure firmware to do not allocate entries for
all the supported LAGs, and to limit LAG IDs. In this case, the resource
query will not return the actual maximum LAG ID.

Add a helper function for getting this value. In case that 'max_lag' field
was set during initialization, return the value which was used, otherwise,
query firmware for the maximum supported ID.
Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent eb907e97
...@@ -186,6 +186,23 @@ unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core) ...@@ -186,6 +186,23 @@ unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core)
} }
EXPORT_SYMBOL(mlxsw_core_max_ports); EXPORT_SYMBOL(mlxsw_core_max_ports);
int mlxsw_core_max_lag(struct mlxsw_core *mlxsw_core, u16 *p_max_lag)
{
struct mlxsw_driver *driver = mlxsw_core->driver;
if (driver->profile->used_max_lag) {
*p_max_lag = driver->profile->max_lag;
return 0;
}
if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG))
return -EIO;
*p_max_lag = MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG);
return 0;
}
EXPORT_SYMBOL(mlxsw_core_max_lag);
void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core) void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core)
{ {
return mlxsw_core->driver_priv; return mlxsw_core->driver_priv;
...@@ -2099,6 +2116,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -2099,6 +2116,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
struct mlxsw_core *mlxsw_core; struct mlxsw_core *mlxsw_core;
struct mlxsw_driver *mlxsw_driver; struct mlxsw_driver *mlxsw_driver;
size_t alloc_size; size_t alloc_size;
u16 max_lag;
int err; int err;
mlxsw_driver = mlxsw_core_driver_get(device_kind); mlxsw_driver = mlxsw_core_driver_get(device_kind);
...@@ -2140,10 +2158,9 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -2140,10 +2158,9 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (err) if (err)
goto err_ports_init; goto err_ports_init;
if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG) && err = mlxsw_core_max_lag(mlxsw_core, &max_lag);
MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG_MEMBERS)) { if (!err && MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG_MEMBERS)) {
alloc_size = sizeof(*mlxsw_core->lag.mapping) * alloc_size = sizeof(*mlxsw_core->lag.mapping) * max_lag *
MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG) *
MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG_MEMBERS); MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG_MEMBERS);
mlxsw_core->lag.mapping = kzalloc(alloc_size, GFP_KERNEL); mlxsw_core->lag.mapping = kzalloc(alloc_size, GFP_KERNEL);
if (!mlxsw_core->lag.mapping) { if (!mlxsw_core->lag.mapping) {
......
...@@ -35,6 +35,8 @@ struct mlxsw_fw_rev; ...@@ -35,6 +35,8 @@ struct mlxsw_fw_rev;
unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core); unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
int mlxsw_core_max_lag(struct mlxsw_core *mlxsw_core, u16 *p_max_lag);
void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core); void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
struct mlxsw_linecards *mlxsw_core_linecards(struct mlxsw_core *mlxsw_core); struct mlxsw_linecards *mlxsw_core_linecards(struct mlxsw_core *mlxsw_core);
......
...@@ -2691,6 +2691,7 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp) ...@@ -2691,6 +2691,7 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp) static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
{ {
char slcr_pl[MLXSW_REG_SLCR_LEN]; char slcr_pl[MLXSW_REG_SLCR_LEN];
u16 max_lag;
u32 seed; u32 seed;
int err; int err;
...@@ -2709,12 +2710,14 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp) ...@@ -2709,12 +2710,14 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
if (err) if (err)
return err; return err;
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG) || err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG_MEMBERS)) if (err)
return err;
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG_MEMBERS))
return -EIO; return -EIO;
mlxsw_sp->lags = kcalloc(MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG), mlxsw_sp->lags = kcalloc(max_lag, sizeof(struct mlxsw_sp_upper),
sizeof(struct mlxsw_sp_upper),
GFP_KERNEL); GFP_KERNEL);
if (!mlxsw_sp->lags) if (!mlxsw_sp->lags)
return -ENOMEM; return -ENOMEM;
...@@ -4263,10 +4266,13 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp, ...@@ -4263,10 +4266,13 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
{ {
struct mlxsw_sp_upper *lag; struct mlxsw_sp_upper *lag;
int free_lag_id = -1; int free_lag_id = -1;
u64 max_lag; u16 max_lag;
int i; int err, i;
err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
if (err)
return err;
max_lag = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG);
for (i = 0; i < max_lag; i++) { for (i = 0; i < max_lag; i++) {
lag = mlxsw_sp_lag_get(mlxsw_sp, i); lag = mlxsw_sp_lag_get(mlxsw_sp, i);
if (lag->ref_count) { if (lag->ref_count) {
......
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