Thu, Jul 19, 2018 at 03:01:01AM CEST, sae...@mellanox.com wrote: >From: Eran Ben Elisha <era...@mellanox.com> > >Add support for two driver parameters via devlink params interface: >- Congestion action > HW mechanism in the PCIe buffer which monitors the amount of > consumed PCIe buffer per host. This mechanism supports the > following actions in case of threshold overflow: > - Disabled - NOP (Default) > - Drop > - Mark - Mark CE bit in the CQE of received packet >- Congestion mode > - Aggressive - Aggressive static trigger threshold (Default) > - Dynamic - Dynamically change the trigger threshold > >Signed-off-by: Eran Ben Elisha <era...@mellanox.com> >Reviewed-by: Moshe Shemesh <mo...@mellanox.com> >Signed-off-by: Saeed Mahameed <sae...@mellanox.com> >--- > .../net/ethernet/mellanox/mlx5/core/devlink.c | 105 +++++++++++++++++- > 1 file changed, 104 insertions(+), 1 deletion(-) > >diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c >b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c >index 9800c98b01d3..1f04decef043 100644 >--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c >+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c >@@ -153,12 +153,115 @@ static int mlx5_devlink_query_tx_overflow_sense(struct >mlx5_core_dev *mdev, > return 0; > } > >+static int mlx5_devlink_set_congestion_action(struct devlink *devlink, u32 id, >+ struct devlink_param_gset_ctx >*ctx) >+{ >+ struct mlx5_core_dev *dev = devlink_priv(devlink); >+ u8 max = MLX5_DEVLINK_CONGESTION_ACTION_MAX; >+ u8 sense; >+ int err; >+ >+ if (!MLX5_CAP_MCAM_FEATURE(dev, mark_tx_action_cqe) && >+ !MLX5_CAP_MCAM_FEATURE(dev, mark_tx_action_cnp)) >+ max = MLX5_DEVLINK_CONGESTION_ACTION_MARK - 1; >+ >+ if (ctx->val.vu8 > max)
This should not be num. It should be a string. Same for "mode". >+ return -ERANGE; >+ >+ err = mlx5_devlink_query_tx_overflow_sense(dev, &sense); >+ if (err) >+ return err; >+ >+ if (ctx->val.vu8 == MLX5_DEVLINK_CONGESTION_ACTION_DISABLED && >+ sense != MLX5_DEVLINK_CONGESTION_MODE_AGGRESSIVE) >+ return -EINVAL; >+ >+ return mlx5_devlink_set_tx_lossy_overflow(dev, ctx->val.vu8); >+} >+ >+static int mlx5_devlink_get_congestion_action(struct devlink *devlink, u32 id, >+ struct devlink_param_gset_ctx >*ctx) >+{ >+ struct mlx5_core_dev *dev = devlink_priv(devlink); >+ >+ return mlx5_devlink_query_tx_lossy_overflow(dev, &ctx->val.vu8); >+} >+ >+static int mlx5_devlink_set_congestion_mode(struct devlink *devlink, u32 id, >+ struct devlink_param_gset_ctx *ctx) >+{ >+ struct mlx5_core_dev *dev = devlink_priv(devlink); >+ u8 tx_lossy_overflow; >+ int err; >+ >+ if (ctx->val.vu8 > MLX5_DEVLINK_CONGESTION_MODE_MAX) >+ return -ERANGE; >+ >+ err = mlx5_devlink_query_tx_lossy_overflow(dev, &tx_lossy_overflow); >+ if (err) >+ return err; >+ >+ if (ctx->val.vu8 != MLX5_DEVLINK_CONGESTION_MODE_AGGRESSIVE && >+ tx_lossy_overflow == MLX5_DEVLINK_CONGESTION_ACTION_DISABLED) >+ return -EINVAL; >+ >+ return mlx5_devlink_set_tx_overflow_sense(dev, ctx->val.vu8); >+} >+ >+static int mlx5_devlink_get_congestion_mode(struct devlink *devlink, u32 id, >+ struct devlink_param_gset_ctx *ctx) >+{ >+ struct mlx5_core_dev *dev = devlink_priv(devlink); >+ >+ return mlx5_devlink_query_tx_overflow_sense(dev, &ctx->val.vu8); >+} >+ >+enum mlx5_devlink_param_id { >+ MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, >+ MLX5_DEVLINK_PARAM_ID_CONGESTION_ACTION, >+ MLX5_DEVLINK_PARAM_ID_CONGESTION_MODE, >+}; >+ >+static const struct devlink_param mlx5_devlink_params[] = { >+ DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_CONGESTION_ACTION, >+ "congestion_action", >+ DEVLINK_PARAM_TYPE_U8, >+ BIT(DEVLINK_PARAM_CMODE_RUNTIME), >+ mlx5_devlink_get_congestion_action, >+ mlx5_devlink_set_congestion_action, NULL), >+ DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_CONGESTION_MODE, >+ "congestion_mode", >+ DEVLINK_PARAM_TYPE_U8, >+ BIT(DEVLINK_PARAM_CMODE_RUNTIME), >+ mlx5_devlink_get_congestion_mode, >+ mlx5_devlink_set_congestion_mode, NULL), >+}; >+ > int mlx5_devlink_register(struct devlink *devlink, struct device *dev) > { >- return devlink_register(devlink, dev); >+ int err; >+ >+ err = devlink_register(devlink, dev); >+ if (err) >+ return err; >+ >+ err = devlink_params_register(devlink, mlx5_devlink_params, >+ ARRAY_SIZE(mlx5_devlink_params)); >+ if (err) { >+ dev_err(dev, "devlink_params_register failed, err = %d\n", err); >+ goto unregister; >+ } >+ >+ return 0; >+ >+unregister: >+ devlink_unregister(devlink); >+ return err; > } > > void mlx5_devlink_unregister(struct devlink *devlink) > { >+ devlink_params_unregister(devlink, mlx5_devlink_params, >+ ARRAY_SIZE(mlx5_devlink_params)); > devlink_unregister(devlink); > } >-- >2.17.0 >