// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2020 Marvell. */

#include "otx2_cpt_common.h"
#include "otx2_cptlf.h"

int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
{
	int ret;

	otx2_mbox_msg_send(mbox, 0);
	ret = otx2_mbox_wait_for_rsp(mbox, 0);
	if (ret == -EIO) {
		dev_err(&pdev->dev, "RVU MBOX timeout.\n");
		return ret;
	} else if (ret) {
		dev_err(&pdev->dev, "RVU MBOX error: %d.\n", ret);
		return -EFAULT;
	}
	return ret;
}

int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
{
	struct mbox_msghdr *req;

	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
				      sizeof(struct ready_msg_rsp));
	if (req == NULL) {
		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}
	req->id = MBOX_MSG_READY;
	req->sig = OTX2_MBOX_REQ_SIG;
	req->pcifunc = 0;

	return otx2_cpt_send_mbox_msg(mbox, pdev);
}

int otx2_cpt_send_af_reg_requests(struct otx2_mbox *mbox, struct pci_dev *pdev)
{
	return otx2_cpt_send_mbox_msg(mbox, pdev);
}

int otx2_cpt_add_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
			     u64 reg, u64 *val)
{
	struct cpt_rd_wr_reg_msg *reg_msg;

	reg_msg = (struct cpt_rd_wr_reg_msg *)
			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg),
						sizeof(*reg_msg));
	if (reg_msg == NULL) {
		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}

	reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
	reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG;
	reg_msg->hdr.pcifunc = 0;

	reg_msg->is_write = 0;
	reg_msg->reg_offset = reg;
	reg_msg->ret_val = val;

	return 0;
}

int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
			      u64 reg, u64 val)
{
	struct cpt_rd_wr_reg_msg *reg_msg;

	reg_msg = (struct cpt_rd_wr_reg_msg *)
			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg),
						sizeof(*reg_msg));
	if (reg_msg == NULL) {
		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}

	reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
	reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG;
	reg_msg->hdr.pcifunc = 0;

	reg_msg->is_write = 1;
	reg_msg->reg_offset = reg;
	reg_msg->val = val;

	return 0;
}

int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
			 u64 reg, u64 *val)
{
	int ret;

	ret = otx2_cpt_add_read_af_reg(mbox, pdev, reg, val);
	if (ret)
		return ret;

	return otx2_cpt_send_mbox_msg(mbox, pdev);
}

int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
			  u64 reg, u64 val)
{
	int ret;

	ret = otx2_cpt_add_write_af_reg(mbox, pdev, reg, val);
	if (ret)
		return ret;

	return otx2_cpt_send_mbox_msg(mbox, pdev);
}

int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs)
{
	struct otx2_mbox *mbox = lfs->mbox;
	struct rsrc_attach *req;
	int ret;

	req = (struct rsrc_attach *)
			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
						sizeof(struct msg_rsp));
	if (req == NULL) {
		dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}

	req->hdr.id = MBOX_MSG_ATTACH_RESOURCES;
	req->hdr.sig = OTX2_MBOX_REQ_SIG;
	req->hdr.pcifunc = 0;
	req->cptlfs = lfs->lfs_num;
	ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev);
	if (ret)
		return ret;

	if (!lfs->are_lfs_attached)
		ret = -EINVAL;

	return ret;
}

int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs)
{
	struct otx2_mbox *mbox = lfs->mbox;
	struct rsrc_detach *req;
	int ret;

	req = (struct rsrc_detach *)
				otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
							sizeof(struct msg_rsp));
	if (req == NULL) {
		dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}

	req->hdr.id = MBOX_MSG_DETACH_RESOURCES;
	req->hdr.sig = OTX2_MBOX_REQ_SIG;
	req->hdr.pcifunc = 0;
	ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev);
	if (ret)
		return ret;

	if (lfs->are_lfs_attached)
		ret = -EINVAL;

	return ret;
}

int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs)
{
	struct otx2_mbox *mbox = lfs->mbox;
	struct pci_dev *pdev = lfs->pdev;
	struct mbox_msghdr *req;
	int ret, i;

	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
				      sizeof(struct msix_offset_rsp));
	if (req == NULL) {
		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}

	req->id = MBOX_MSG_MSIX_OFFSET;
	req->sig = OTX2_MBOX_REQ_SIG;
	req->pcifunc = 0;
	ret = otx2_cpt_send_mbox_msg(mbox, pdev);
	if (ret)
		return ret;

	for (i = 0; i < lfs->lfs_num; i++) {
		if (lfs->lf[i].msix_offset == MSIX_VECTOR_INVALID) {
			dev_err(&pdev->dev,
				"Invalid msix offset %d for LF %d\n",
				lfs->lf[i].msix_offset, i);
			return -EINVAL;
		}
	}
	return ret;
}
