// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022, Microsoft Corporation. All rights reserved.
 */

#include "mana_ib.h"

#define VALID_MR_FLAGS                                                         \
	(IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ)

static enum gdma_mr_access_flags
mana_ib_verbs_to_gdma_access_flags(int access_flags)
{
	enum gdma_mr_access_flags flags = GDMA_ACCESS_FLAG_LOCAL_READ;

	if (access_flags & IB_ACCESS_LOCAL_WRITE)
		flags |= GDMA_ACCESS_FLAG_LOCAL_WRITE;

	if (access_flags & IB_ACCESS_REMOTE_WRITE)
		flags |= GDMA_ACCESS_FLAG_REMOTE_WRITE;

	if (access_flags & IB_ACCESS_REMOTE_READ)
		flags |= GDMA_ACCESS_FLAG_REMOTE_READ;

	return flags;
}

static int mana_ib_gd_create_mr(struct mana_ib_dev *dev, struct mana_ib_mr *mr,
				struct gdma_create_mr_params *mr_params)
{
	struct gdma_create_mr_response resp = {};
	struct gdma_create_mr_request req = {};
	struct gdma_dev *mdev = dev->gdma_dev;
	struct gdma_context *gc;
	int err;

	gc = mdev->gdma_context;

	mana_gd_init_req_hdr(&req.hdr, GDMA_CREATE_MR, sizeof(req),
			     sizeof(resp));
	req.pd_handle = mr_params->pd_handle;
	req.mr_type = mr_params->mr_type;

	switch (mr_params->mr_type) {
	case GDMA_MR_TYPE_GVA:
		req.gva.dma_region_handle = mr_params->gva.dma_region_handle;
		req.gva.virtual_address = mr_params->gva.virtual_address;
		req.gva.access_flags = mr_params->gva.access_flags;
		break;

	default:
		ibdev_dbg(&dev->ib_dev,
			  "invalid param (GDMA_MR_TYPE) passed, type %d\n",
			  req.mr_type);
		return -EINVAL;
	}

	err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp);

	if (err || resp.hdr.status) {
		ibdev_dbg(&dev->ib_dev, "Failed to create mr %d, %u", err,
			  resp.hdr.status);
		if (!err)
			err = -EPROTO;

		return err;
	}

	mr->ibmr.lkey = resp.lkey;
	mr->ibmr.rkey = resp.rkey;
	mr->mr_handle = resp.mr_handle;

	return 0;
}

static int mana_ib_gd_destroy_mr(struct mana_ib_dev *dev, u64 mr_handle)
{
	struct gdma_destroy_mr_response resp = {};
	struct gdma_destroy_mr_request req = {};
	struct gdma_dev *mdev = dev->gdma_dev;
	struct gdma_context *gc;
	int err;

	gc = mdev->gdma_context;

	mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_MR, sizeof(req),
			     sizeof(resp));

	req.mr_handle = mr_handle;

	err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp);
	if (err || resp.hdr.status) {
		dev_err(gc->dev, "Failed to destroy MR: %d, 0x%x\n", err,
			resp.hdr.status);
		if (!err)
			err = -EPROTO;
		return err;
	}

	return 0;
}

struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length,
				  u64 iova, int access_flags,
				  struct ib_udata *udata)
{
	struct mana_ib_pd *pd = container_of(ibpd, struct mana_ib_pd, ibpd);
	struct gdma_create_mr_params mr_params = {};
	struct ib_device *ibdev = ibpd->device;
	struct mana_ib_dev *dev;
	struct mana_ib_mr *mr;
	u64 dma_region_handle;
	int err;

	dev = container_of(ibdev, struct mana_ib_dev, ib_dev);

	ibdev_dbg(ibdev,
		  "start 0x%llx, iova 0x%llx length 0x%llx access_flags 0x%x",
		  start, iova, length, access_flags);

	if (access_flags & ~VALID_MR_FLAGS)
		return ERR_PTR(-EINVAL);

	mr = kzalloc(sizeof(*mr), GFP_KERNEL);
	if (!mr)
		return ERR_PTR(-ENOMEM);

	mr->umem = ib_umem_get(ibdev, start, length, access_flags);
	if (IS_ERR(mr->umem)) {
		err = PTR_ERR(mr->umem);
		ibdev_dbg(ibdev,
			  "Failed to get umem for register user-mr, %d\n", err);
		goto err_free;
	}

	err = mana_ib_gd_create_dma_region(dev, mr->umem, &dma_region_handle);
	if (err) {
		ibdev_dbg(ibdev, "Failed create dma region for user-mr, %d\n",
			  err);
		goto err_umem;
	}

	ibdev_dbg(ibdev,
		  "mana_ib_gd_create_dma_region ret %d gdma_region %llx\n", err,
		  dma_region_handle);

	mr_params.pd_handle = pd->pd_handle;
	mr_params.mr_type = GDMA_MR_TYPE_GVA;
	mr_params.gva.dma_region_handle = dma_region_handle;
	mr_params.gva.virtual_address = iova;
	mr_params.gva.access_flags =
		mana_ib_verbs_to_gdma_access_flags(access_flags);

	err = mana_ib_gd_create_mr(dev, mr, &mr_params);
	if (err)
		goto err_dma_region;

	/*
	 * There is no need to keep track of dma_region_handle after MR is
	 * successfully created. The dma_region_handle is tracked in the PF
	 * as part of the lifecycle of this MR.
	 */

	return &mr->ibmr;

err_dma_region:
	mana_gd_destroy_dma_region(dev->gdma_dev->gdma_context,
				   dma_region_handle);

err_umem:
	ib_umem_release(mr->umem);

err_free:
	kfree(mr);
	return ERR_PTR(err);
}

int mana_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
{
	struct mana_ib_mr *mr = container_of(ibmr, struct mana_ib_mr, ibmr);
	struct ib_device *ibdev = ibmr->device;
	struct mana_ib_dev *dev;
	int err;

	dev = container_of(ibdev, struct mana_ib_dev, ib_dev);

	err = mana_ib_gd_destroy_mr(dev, mr->mr_handle);
	if (err)
		return err;

	if (mr->umem)
		ib_umem_release(mr->umem);

	kfree(mr);

	return 0;
}
