[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1547737521-29888-21-git-send-email-eranbe@mellanox.com>
Date: Thu, 17 Jan 2019 17:05:14 +0200
From: Eran Ben Elisha <eranbe@...lanox.com>
To: netdev@...r.kernel.org, Jiri Pirko <jiri@...lanox.com>,
"David S. Miller" <davem@...emloft.net>,
Ariel Almog <ariela@...lanox.com>,
Aya Levin <ayal@...lanox.com>,
Eran Ben Elisha <eranbe@...lanox.com>,
Moshe Shemesh <moshe@...lanox.com>
Subject: [PATCH net-next 20/27] net/mlx5: Create FW devlink_health_reporter
From: Moshe Shemesh <moshe@...lanox.com>
Create mlx5_devlink_health_reporter for FW reporter. The FW reporter
implements devlink_health_reporter diagnose callback.
Signed-off-by: Moshe Shemesh <moshe@...lanox.com>
Reviewed-by: Saeed Mahameed <saeedm@...lanox.com>
---
.../net/ethernet/mellanox/mlx5/core/devlink.c | 114 ++++++++++++++++++
.../net/ethernet/mellanox/mlx5/core/devlink.h | 8 ++
.../net/ethernet/mellanox/mlx5/core/main.c | 5 +
include/linux/mlx5/driver.h | 1 +
4 files changed, 128 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index 88190acae873..b28a923e3645 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -5,6 +5,120 @@
#include <linux/mlx5/driver.h>
#include "lib/mlx5.h"
+static int
+mlx5_devlink_health_buffer_fill_syndrom(struct devlink_health_buffer *dh_buffer,
+ u8 syndrom)
+{
+ int err;
+
+ err = devlink_health_buffer_nest_start(dh_buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT);
+ if (err)
+ return err;
+ err = devlink_health_buffer_nest_start(dh_buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT_PAIR);
+ if (err)
+ return err;
+ err = devlink_health_buffer_put_object_name(dh_buffer, "Syndrom");
+ if (err)
+ return err;
+ err = devlink_health_buffer_nest_start(dh_buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT_VALUE);
+ if (err)
+ return err;
+ err = devlink_health_buffer_put_value_u8(dh_buffer, syndrom);
+ if (err)
+ return err;
+ devlink_health_buffer_nest_end(dh_buffer);
+ devlink_health_buffer_nest_end(dh_buffer);
+ devlink_health_buffer_nest_end(dh_buffer);
+
+ return 0;
+}
+
+static int
+mlx5_fw_reporter_diagnose(struct devlink_health_reporter *reporter,
+ struct devlink_health_buffer **buffers_array,
+ unsigned int buff_size, unsigned int num_buffers)
+{
+ struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);
+ char lines_buf[HEALTH_INFO_LINES][HEALTH_INFO_MAX_LINE] = {};
+ struct devlink_health_buffer *buffer;
+ u8 synd;
+ int err;
+ int i;
+
+ if (!buffers_array || buff_size < HEALTH_INFO_MAX_BUFF ||
+ num_buffers < 1 || !buffers_array[0])
+ return -EINVAL;
+
+ buffer = buffers_array[0];
+ mlx5_get_health_info(dev, &synd, lines_buf);
+ mlx5_devlink_health_buffer_fill_syndrom(buffer, synd);
+
+ if (!synd)
+ return 0;
+
+ err = devlink_health_buffer_nest_start(buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT);
+ if (err)
+ return err;
+ err = devlink_health_buffer_nest_start(buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT_PAIR);
+ if (err)
+ return err;
+ err = devlink_health_buffer_put_object_name(buffer, "diagnose data");
+ if (err)
+ return err;
+ err = devlink_health_buffer_nest_start(buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT_VALUE);
+ if (err)
+ return err;
+ err = devlink_health_buffer_nest_start(buffer,
+ DEVLINK_ATTR_HEALTH_BUFFER_OBJECT_VALUE_ARRAY);
+ if (err)
+ return err;
+
+ for (i = 0; i < HEALTH_INFO_LINES; i++) {
+ err = devlink_health_buffer_nest_start(buffer, DEVLINK_ATTR_HEALTH_BUFFER_OBJECT_VALUE);
+ if (err)
+ return err;
+ err = devlink_health_buffer_put_value_string(buffer, lines_buf[i]);
+ if (err)
+ return err;
+ devlink_health_buffer_nest_end(buffer);
+ }
+ devlink_health_buffer_nest_end(buffer); /* DEVLINK_HEALTH_BUFFER_OBJECT_VALUE_ARRAY */
+ devlink_health_buffer_nest_end(buffer); /* DEVLINK_HEALTH_BUFFER_OBJECT_VALUE */
+ devlink_health_buffer_nest_end(buffer); /* DEVLINK_HEALTH_BUFFER_OBJECT_PAIR */
+ devlink_health_buffer_nest_end(buffer); /* DEVLINK_HEALTH_BUFFER_OBJECT */
+
+ return 0;
+}
+
+static const struct devlink_health_reporter_ops mlx5_fw_reporter_ops = {
+ .name = "FW",
+ .diagnose_size = HEALTH_INFO_MAX_BUFF,
+ .diagnose = mlx5_fw_reporter_diagnose,
+};
+
+int mlx5_fw_reporter_create(struct mlx5_core_dev *dev)
+{
+ struct devlink *devlink = priv_to_devlink(dev);
+
+ dev->fw_reporter = devlink_health_reporter_create(devlink, &mlx5_fw_reporter_ops,
+ 0, false, dev);
+ return PTR_ERR_OR_ZERO(dev->fw_reporter);
+}
+
+void mlx5_fw_reporter_destroy(struct mlx5_core_dev *dev)
+{
+ if (!dev->fw_reporter)
+ return;
+
+ devlink_health_reporter_destroy(dev->fw_reporter);
+}
+
static int mlx5_devlink_get_crdump_snapshot(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
index 455bfa4e89c0..34f6bfed1cfb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
@@ -5,8 +5,16 @@
#define __MLX5_DEVLINK_H__
#include <net/devlink.h>
+#include "mlx5_core.h"
+
+struct mlx5_fw_reporter_ctx {
+ u8 err_synd;
+ int miss_counter;
+};
int mlx5_devlink_register(struct devlink *devlink, struct device *dev);
void mlx5_devlink_unregister(struct devlink *devlink);
+int mlx5_fw_reporter_create(struct mlx5_core_dev *dev);
+void mlx5_fw_reporter_destroy(struct mlx5_core_dev *dev);
#endif /* __MLX5_DEVLINK_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index c6c07ca0e423..010a6a28e08d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -980,6 +980,10 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
goto err_fw_tracer;
}
+ err = mlx5_fw_reporter_create(dev);
+ if (err)
+ dev_warn(&pdev->dev, "Failed to create FW reporter\n");
+
err = mlx5_fpga_device_start(dev);
if (err) {
dev_err(&pdev->dev, "fpga device start failed %d\n", err);
@@ -1112,6 +1116,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
mlx5_accel_ipsec_cleanup(dev);
mlx5_accel_tls_cleanup(dev);
mlx5_fpga_device_stop(dev);
+ mlx5_fw_reporter_destroy(dev);
mlx5_fw_tracer_cleanup(dev->tracer);
mlx5_eq_table_destroy(dev);
mlx5_pagealloc_stop(dev);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 778710ff77c9..350f11fa0c99 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -682,6 +682,7 @@ struct mlx5_core_dev {
struct mlx5_ib_clock_info *clock_info;
struct page *clock_info_page;
struct mlx5_fw_tracer *tracer;
+ struct devlink_health_reporter *fw_reporter;
u32 vsc_addr;
};
--
2.17.1
Powered by blists - more mailing lists