@@ -2,13 +2,71 @@
/* Copyright (c) 2018 Mellanox Technologies */
#include <devlink.h>
+#include <linux/mlx5/driver.h>
+#include "lib/mlx5.h"
+
+static int mlx5_devlink_get_crdump_snapshot(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+
+ ctx->val.vbool = mlx5_crdump_is_snapshot_enabled(dev);
+ return 0;
+}
+
+static int mlx5_devlink_set_crdump_snapshot(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+
+ return mlx5_crdump_set_snapshot_enabled(dev, ctx->val.vbool);
+}
+
+static const struct devlink_param mlx5_devlink_params[] = {
+ DEVLINK_PARAM_GENERIC(REGION_SNAPSHOT,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME) |
+ BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
+ mlx5_devlink_get_crdump_snapshot,
+ mlx5_devlink_set_crdump_snapshot, NULL),
+};
int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
{
- return devlink_register(devlink, dev);
+ union devlink_param_value init_val;
+ int err;
+
+ err = devlink_register(devlink, dev);
+ if (err) {
+ dev_warn(dev,
+ "devlink register failed (err = %d)", 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;
+ }
+
+ init_val.vbool = false;
+ err = devlink_param_driverinit_value_set(devlink,
+ DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
+ init_val);
+ if (err)
+ dev_warn(dev,
+ "devlink param init failed (err = %d)", err);
+
+ 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);
}
@@ -15,6 +15,7 @@ static const char *region_cr_space_str = "cr-space";
struct mlx5_fw_crdump {
u32 size;
+ bool snapshot_enable;
struct devlink_region *region_crspace;
};
@@ -102,6 +103,27 @@ int mlx5_crdump_collect(struct mlx5_core_dev *dev,
return ret;
}
+bool mlx5_crdump_is_snapshot_enabled(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ if (mlx5_crdump_enbaled(dev))
+ return priv->health.crdump->snapshot_enable;
+
+ return false;
+}
+
+int mlx5_crdump_set_snapshot_enabled(struct mlx5_core_dev *dev, bool value)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ if (!mlx5_crdump_enbaled(dev))
+ return -ENODEV;
+
+ priv->health.crdump->snapshot_enable = value;
+ return 0;
+}
+
int mlx5_crdump_init(struct mlx5_core_dev *dev)
{
struct devlink *devlink = priv_to_devlink(dev);
@@ -45,6 +45,8 @@ int mlx5_crdump_init(struct mlx5_core_dev *dev);
void mlx5_crdump_cleanup(struct mlx5_core_dev *dev);
int mlx5_crdump_collect(struct mlx5_core_dev *dev,
char *crdump_region, u32 *snapshot_id);
+bool mlx5_crdump_is_snapshot_enabled(struct mlx5_core_dev *dev);
+int mlx5_crdump_set_snapshot_enabled(struct mlx5_core_dev *dev, bool value);
/* TODO move to lib/events.h */