// SPDX-License-Identifier: GPL-2.0-or-later
/* Marvell/Qlogic FastLinQ NIC driver
 *
 * Copyright (C) 2020 Marvell International Ltd.
 */

#include <linux/kernel.h>
#include <linux/qed/qed_if.h>
#include <linux/vmalloc.h>
#include "qed.h"
#include "qed_devlink.h"

enum qed_devlink_param_id {
	QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
	QED_DEVLINK_PARAM_ID_IWARP_CMT,
};

struct qed_fw_fatal_ctx {
	enum qed_hw_err_type err_type;
};

int qed_report_fatal_error(struct devlink *devlink, enum qed_hw_err_type err_type)
{
	struct qed_devlink *qdl = devlink_priv(devlink);
	struct qed_fw_fatal_ctx fw_fatal_ctx = {
		.err_type = err_type,
	};

	if (qdl->fw_reporter)
		devlink_health_report(qdl->fw_reporter,
				      "Fatal error occurred", &fw_fatal_ctx);

	return 0;
}

static int
qed_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter,
			   struct devlink_fmsg *fmsg, void *priv_ctx,
			   struct netlink_ext_ack *extack)
{
	struct qed_devlink *qdl = devlink_health_reporter_priv(reporter);
	struct qed_fw_fatal_ctx *fw_fatal_ctx = priv_ctx;
	struct qed_dev *cdev = qdl->cdev;
	u32 dbg_data_buf_size;
	u8 *p_dbg_data_buf;
	int err;

	/* Having context means that was a dump request after fatal,
	 * so we enable extra debugging while gathering the dump,
	 * just in case
	 */
	cdev->print_dbg_data = fw_fatal_ctx ? true : false;

	dbg_data_buf_size = qed_dbg_all_data_size(cdev);
	p_dbg_data_buf = vzalloc(dbg_data_buf_size);
	if (!p_dbg_data_buf) {
		DP_NOTICE(cdev,
			  "Failed to allocate memory for a debug data buffer\n");
		return -ENOMEM;
	}

	err = qed_dbg_all_data(cdev, p_dbg_data_buf);
	if (err) {
		DP_NOTICE(cdev, "Failed to obtain debug data\n");
		vfree(p_dbg_data_buf);
		return err;
	}

	devlink_fmsg_binary_pair_put(fmsg, "dump_data", p_dbg_data_buf,
				     dbg_data_buf_size);

	vfree(p_dbg_data_buf);

	return 0;
}

static int
qed_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
			      void *priv_ctx,
			      struct netlink_ext_ack *extack)
{
	struct qed_devlink *qdl = devlink_health_reporter_priv(reporter);
	struct qed_dev *cdev = qdl->cdev;

	qed_recovery_process(cdev);

	return 0;
}

static const struct devlink_health_reporter_ops qed_fw_fatal_reporter_ops = {
		.name = "fw_fatal",
		.recover = qed_fw_fatal_reporter_recover,
		.dump = qed_fw_fatal_reporter_dump,
};

#define QED_REPORTER_FW_GRACEFUL_PERIOD 0

void qed_fw_reporters_create(struct devlink *devlink)
{
	struct qed_devlink *dl = devlink_priv(devlink);

	dl->fw_reporter = devlink_health_reporter_create(devlink, &qed_fw_fatal_reporter_ops,
							 QED_REPORTER_FW_GRACEFUL_PERIOD, dl);
	if (IS_ERR(dl->fw_reporter)) {
		DP_NOTICE(dl->cdev, "Failed to create fw reporter, err = %ld\n",
			  PTR_ERR(dl->fw_reporter));
		dl->fw_reporter = NULL;
	}
}

void qed_fw_reporters_destroy(struct devlink *devlink)
{
	struct qed_devlink *dl = devlink_priv(devlink);
	struct devlink_health_reporter *rep;

	rep = dl->fw_reporter;

	if (!IS_ERR_OR_NULL(rep))
		devlink_health_reporter_destroy(rep);
}

static int qed_dl_param_get(struct devlink *dl, u32 id,
			    struct devlink_param_gset_ctx *ctx)
{
	struct qed_devlink *qed_dl = devlink_priv(dl);
	struct qed_dev *cdev;

	cdev = qed_dl->cdev;
	ctx->val.vbool = cdev->iwarp_cmt;

	return 0;
}

static int qed_dl_param_set(struct devlink *dl, u32 id,
			    struct devlink_param_gset_ctx *ctx)
{
	struct qed_devlink *qed_dl = devlink_priv(dl);
	struct qed_dev *cdev;

	cdev = qed_dl->cdev;
	cdev->iwarp_cmt = ctx->val.vbool;

	return 0;
}

static const struct devlink_param qed_devlink_params[] = {
	DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
			     "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
			     qed_dl_param_get, qed_dl_param_set, NULL),
};

static int qed_devlink_info_get(struct devlink *devlink,
				struct devlink_info_req *req,
				struct netlink_ext_ack *extack)
{
	struct qed_devlink *qed_dl = devlink_priv(devlink);
	struct qed_dev *cdev = qed_dl->cdev;
	struct qed_dev_info *dev_info;
	char buf[100];
	int err;

	dev_info = &cdev->common_dev_info;

	memcpy(buf, cdev->hwfns[0].hw_info.part_num, sizeof(cdev->hwfns[0].hw_info.part_num));
	buf[sizeof(cdev->hwfns[0].hw_info.part_num)] = 0;

	if (buf[0]) {
		err = devlink_info_board_serial_number_put(req, buf);
		if (err)
			return err;
	}

	snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_3),
		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_2),
		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_1),
		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_0));

	err = devlink_info_version_stored_put(req,
					      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, buf);
	if (err)
		return err;

	snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
		 dev_info->fw_major,
		 dev_info->fw_minor,
		 dev_info->fw_rev,
		 dev_info->fw_eng);

	return devlink_info_version_running_put(req,
						DEVLINK_INFO_VERSION_GENERIC_FW_APP, buf);
}

static const struct devlink_ops qed_dl_ops = {
	.info_get = qed_devlink_info_get,
};

struct devlink *qed_devlink_register(struct qed_dev *cdev)
{
	struct qed_devlink *qdevlink;
	struct devlink *dl;
	int rc;

	dl = devlink_alloc(&qed_dl_ops, sizeof(struct qed_devlink),
			   &cdev->pdev->dev);
	if (!dl)
		return ERR_PTR(-ENOMEM);

	qdevlink = devlink_priv(dl);
	qdevlink->cdev = cdev;

	rc = devlink_params_register(dl, qed_devlink_params,
				     ARRAY_SIZE(qed_devlink_params));
	if (rc)
		goto err_unregister;

	cdev->iwarp_cmt = false;

	qed_fw_reporters_create(dl);
	devlink_register(dl);
	return dl;

err_unregister:
	devlink_free(dl);

	return ERR_PTR(rc);
}

void qed_devlink_unregister(struct devlink *devlink)
{
	if (!devlink)
		return;

	devlink_unregister(devlink);
	qed_fw_reporters_destroy(devlink);

	devlink_params_unregister(devlink, qed_devlink_params,
				  ARRAY_SIZE(qed_devlink_params));

	devlink_free(devlink);
}
