From d144e3a2c9f79af5202d832e85fb72b0d6954ef5 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Thu, 20 Sep 2018 09:21:29 +0300 Subject: mlxsw: spectrum_buffers: Allow an infinite maximum for per-TC pool limit The SBCM register configures the shared buffer configuration according to port and TC. So far all pools have had a dynamic size, where the infinite size is easy to express by using max_buff of 0xff. However the MC pool should be configured with static size, and the infinite size thus needs to be set using the field SBCM.infi_max. Therefore add the field infi_max to the SBCM register and to mlxsw_reg_sbcm_pack(). Extend mlxsw_sp_sb_cm_write() to handle infinite sizes as well. Report infinite pool limits as if the limit actually were the total shared buffer size. Signed-off-by: Petr Machata Reviewed-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 11 ++++++++++- .../net/ethernet/mellanox/mlxsw/spectrum_buffers.c | 23 +++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 694f6a443769..df81e0a1eb64 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -8418,6 +8418,12 @@ MLXSW_ITEM32(reg, sbcm, min_buff, 0x18, 0, 24); #define MLXSW_REG_SBXX_DYN_MAX_BUFF_MIN 1 #define MLXSW_REG_SBXX_DYN_MAX_BUFF_MAX 14 +/* reg_sbcm_infi_max + * Max buffer is infinite. + * Access: RW + */ +MLXSW_ITEM32(reg, sbcm, infi_max, 0x1C, 31, 1); + /* reg_sbcm_max_buff * When the pool associated to the port-pg/tclass is configured to * static, Maximum buffer size for the limiter configured in cells. @@ -8427,6 +8433,7 @@ MLXSW_ITEM32(reg, sbcm, min_buff, 0x18, 0, 24); * 0: 0 * i: (1/128)*2^(i-1), for i=1..14 * 0xFF: Infinity + * Reserved when infi_max = 1. * Access: RW */ MLXSW_ITEM32(reg, sbcm, max_buff, 0x1C, 0, 24); @@ -8439,7 +8446,8 @@ MLXSW_ITEM32(reg, sbcm, pool, 0x24, 0, 4); static inline void mlxsw_reg_sbcm_pack(char *payload, u8 local_port, u8 pg_buff, enum mlxsw_reg_sbxx_dir dir, - u32 min_buff, u32 max_buff, u8 pool) + u32 min_buff, u32 max_buff, + bool infi_max, u8 pool) { MLXSW_REG_ZERO(sbcm, payload); mlxsw_reg_sbcm_local_port_set(payload, local_port); @@ -8447,6 +8455,7 @@ static inline void mlxsw_reg_sbcm_pack(char *payload, u8 local_port, u8 pg_buff, mlxsw_reg_sbcm_dir_set(payload, dir); mlxsw_reg_sbcm_min_buff_set(payload, min_buff); mlxsw_reg_sbcm_max_buff_set(payload, max_buff); + mlxsw_reg_sbcm_infi_max_set(payload, infi_max); mlxsw_reg_sbcm_pool_set(payload, pool); } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c index 646022fa4cbe..de51f567a76b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c @@ -142,20 +142,24 @@ static int mlxsw_sp_sb_pr_write(struct mlxsw_sp *mlxsw_sp, u16 pool_index, static int mlxsw_sp_sb_cm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 pg_buff, u32 min_buff, u32 max_buff, - u16 pool_index) + bool infi_max, u16 pool_index) { const struct mlxsw_sp_sb_pool_des *des = &mlxsw_sp_sb_pool_dess[pool_index]; char sbcm_pl[MLXSW_REG_SBCM_LEN]; + struct mlxsw_sp_sb_cm *cm; int err; mlxsw_reg_sbcm_pack(sbcm_pl, local_port, pg_buff, des->dir, - min_buff, max_buff, des->pool); + min_buff, max_buff, infi_max, des->pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbcm), sbcm_pl); if (err) return err; + if (mlxsw_sp_sb_cm_exists(pg_buff, des->dir)) { - struct mlxsw_sp_sb_cm *cm; + if (infi_max) + max_buff = mlxsw_sp_bytes_cells(mlxsw_sp, + mlxsw_sp->sb->sb_size); cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, pg_buff, des->dir); @@ -451,9 +455,14 @@ static int __mlxsw_sp_sb_cms_init(struct mlxsw_sp *mlxsw_sp, u8 local_port, * therefore 'max_buff' isn't specified in cells. */ min_buff = mlxsw_sp_bytes_cells(mlxsw_sp, cm->min_buff); - err = mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, i, - min_buff, cm->max_buff, - cm->pool_index); + if (cm->max_buff == MLXSW_SP_SB_INFI) + err = mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, i, + min_buff, 0, + true, cm->pool_index); + else + err = mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, i, + min_buff, cm->max_buff, + false, cm->pool_index); if (err) return err; } @@ -813,7 +822,7 @@ int mlxsw_sp_sb_tc_pool_bind_set(struct mlxsw_core_port *mlxsw_core_port, return err; return mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, pg_buff, - 0, max_buff, pool_index); + 0, max_buff, false, pool_index); } #define MASKED_COUNT_MAX \ -- cgit v1.2.3