// SPDX-License-Identifier: GPL-2.0-only
/*
 * Common file system operations for devices with MCU support.
 *
 * Copyright (C) 2022 Google LLC
 */

#include <linux/bits.h>
#include <linux/dma-fence-array.h>
#include <linux/fs.h>
#include <linux/mm_types.h>
#include <linux/rwsem.h>
#include <linux/slab.h>

#include <gcip/gcip-fence-array.h>
#include <gcip/gcip-fence.h>
#include <gcip/gcip-telemetry.h>

#include "gxp-client.h"
#include "gxp-internal.h"
#include "gxp-mcu-fs.h"
#include "gxp-mcu-telemetry.h"
#include "gxp-mcu.h"
#include "gxp-uci.h"
#include "gxp.h"

static int gxp_ioctl_uci_command_compat(struct gxp_client *client,
					struct gxp_mailbox_uci_command_compat_ioctl __user *argp)
{
	struct gxp_mailbox_uci_command_compat_ioctl ibuf;
	struct gxp_dev *gxp = client->gxp;
	struct gxp_mcu *mcu = gxp_mcu_of(gxp);
	u64 cmd_seq;
	int ret;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	cmd_seq = gcip_mailbox_inc_seq_num(mcu->uci.mbx->mbx_impl.gcip_mbx, 1);

	ret = gxp_uci_create_and_send_cmd(client, cmd_seq, 0, ibuf.opaque, 0, NULL, NULL);
	if (ret) {
		dev_err(gxp->dev, "Failed to request an UCI command (ret=%d)", ret);
		return ret;
	}

	ibuf.sequence_number = cmd_seq;

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		return -EFAULT;

	return 0;
}

/**
 * polled_dma_fence_get() - Generate a dma-fence to represent all the fan-in fences.
 * @in_fences: The pointer to the gcip_fence_array object containing fan-in fances.
 *
 * Use dma_fence_array to handle all the fan-in fences if @in_fences->size > 1.
 * The caller should hold the reference count of the fences in @in_fences to make sure they will not
 * be released during the process.
 * The output fence will acquired 1 reference count in this function either with dma_fence_get() or
 * dma_fence_array_create().
 *
 * Return: The pointer to the generated dma-fence or the error pointer on error.
 *         A NULL pointer is returned if no in-kernel fence is passed in.
 */
static struct dma_fence *polled_dma_fence_get(struct gcip_fence_array *in_fences)
{
	static int array_seq;
	const int size = in_fences->size;
	struct dma_fence_array *fence_array;
	struct dma_fence **in_dma_fences;
	int i;

	if (!in_fences->size || !in_fences->same_type || in_fences->type != GCIP_IN_KERNEL_FENCE)
		return NULL;

	/* TODO(b/320401031): Remove this constraint after dma-fence-unwrap adopted. */
	/* dma-fence-array as in-fences is currently not supported. */
	for (i = 0; i < size; i++) {
		if (dma_fence_is_array(in_fences->fences[i]->fence.ikf))
			return ERR_PTR(-EINVAL);
	}

	if (size == 1)
		return dma_fence_get(in_fences->fences[0]->fence.ikf);

	in_dma_fences = kcalloc(size, sizeof(*in_dma_fences), GFP_KERNEL);
	if (!in_dma_fences)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < size; i++)
		in_dma_fences[i] = dma_fence_get(in_fences->fences[i]->fence.ikf);

	/* fence_array will take care of the life cycle of in_dma_fences.*/
	fence_array = dma_fence_array_create(size, in_dma_fences, dma_fence_context_alloc(1),
					     array_seq++, false);
	if (!fence_array) {
		kfree(in_dma_fences);
		/* dma_fence_array_create only returns NULL on allocation failure. */
		return ERR_PTR(-ENOMEM);
	}

	return &fence_array->base;
}

/*
 * Returns the number of fences. If the runtime passed an invalid fence, returns an errno
 * accordingly.
 */
static int get_num_fences(const int *fences)
{
	int i;
	struct gcip_fence *fence;

	for (i = 0; i < GXP_MAX_FENCES_PER_UCI_COMMAND; i++) {
		if (fences[i] == GXP_FENCE_ARRAY_TERMINATION)
			break;
		fence = gcip_fence_fdget(fences[i]);
		/*
		 * TODO(b/312819593): once the runtime adopts `GXP_FENCE_ARRAY_TERMINATION` to
		 * indicate the end of array, always returns PTR_ERR(fence).
		 */
		if (IS_ERR(fence))
			return !fences[i] ? 0 : PTR_ERR(fence);
		gcip_fence_put(fence);
	}

	return i;
}

static int gxp_ioctl_uci_command(struct gxp_client *client,
				 struct gxp_mailbox_uci_command_ioctl __user *argp)
{
	struct gxp_mcu *mcu = gxp_mcu_of(client->gxp);
	struct gxp_mailbox_uci_command_ioctl ibuf;
	struct gcip_fence_array *in_fences, *out_fences;
	struct dma_fence *polled_dma_fence;
	u64 cmd_seq;
	int ret, num_in_fences, num_out_fences;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	cmd_seq = gcip_mailbox_inc_seq_num(mcu->uci.mbx->mbx_impl.gcip_mbx, 1);

	num_in_fences = get_num_fences(ibuf.in_fences);
	if (num_in_fences < 0)
		return num_in_fences;

	num_out_fences = get_num_fences(ibuf.out_fences);
	if (num_out_fences < 0)
		return num_out_fences;

	in_fences = gcip_fence_array_create(ibuf.in_fences, num_in_fences, true);
	if (IS_ERR(in_fences))
		return PTR_ERR(in_fences);

	out_fences = gcip_fence_array_create(ibuf.out_fences, num_out_fences, false);
	if (IS_ERR(out_fences)) {
		gcip_fence_array_put(in_fences);
		return PTR_ERR(out_fences);
	}

	polled_dma_fence = polled_dma_fence_get(in_fences);
	if (IS_ERR(polled_dma_fence)) {
		ret = PTR_ERR(polled_dma_fence);
		goto out;
	}

	ret = gxp_uci_cmd_work_create_and_schedule(polled_dma_fence, client, &ibuf, cmd_seq,
						   in_fences, out_fences);
	if (ret) {
		dev_err(client->gxp->dev, "Failed to request an UCI command (ret=%d)", ret);
		goto err_put_fence;
	}

	ibuf.sequence_number = cmd_seq;

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		ret = -EFAULT;

err_put_fence:
	/*
	 * Put the reference count of the fence acqurired in polled_dma_fence_get.
	 * If the fence is a dma_fence_array and the callback is failed to be added,
	 * the whole object and the array it holds will be freed.
	 * If it is a NULL pointer, it's still safe to call this function.
	 */
	dma_fence_put(polled_dma_fence);
out:
	gcip_fence_array_put(out_fences);
	gcip_fence_array_put(in_fences);
	return ret;
}

static int
gxp_ioctl_uci_response(struct gxp_client *client,
		       struct gxp_mailbox_uci_response_ioctl __user *argp)
{
	struct gxp_mailbox_uci_response_ioctl ibuf;
	int ret = 0;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	down_read(&client->semaphore);

	if (!client->vd) {
		dev_err(client->gxp->dev,
			"GXP_MAILBOX_UCI_RESPONSE requires the client allocate a VIRTUAL_DEVICE\n");
		ret = -ENODEV;
		goto out;
	}

	/* Caller must hold BLOCK wakelock */
	if (!client->has_block_wakelock) {
		dev_err(client->gxp->dev,
			"GXP_MAILBOX_UCI_RESPONSE requires the client hold a BLOCK wakelock\n");
		ret = -ENODEV;
		goto out;
	}

	ret = gxp_uci_wait_async_response(
		&client->vd->mailbox_resp_queues[UCI_RESOURCE_ID],
		&ibuf.sequence_number, &ibuf.error_code, ibuf.opaque);
	if (ret == -ENOENT || ret == -EAGAIN)
		goto out;

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		ret = -EFAULT;

out:
	up_read(&client->semaphore);

	return ret;
}

static int gxp_ioctl_set_device_properties(
	struct gxp_dev *gxp,
	struct gxp_set_device_properties_ioctl __user *argp)
{
	struct gxp_dev_prop *device_prop = &gxp->device_prop;
	struct gxp_set_device_properties_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	mutex_lock(&device_prop->lock);

	memcpy(&device_prop->opaque, &ibuf.opaque, sizeof(device_prop->opaque));
	device_prop->initialized = true;

	mutex_unlock(&device_prop->lock);

	return 0;
}

static int gxp_ioctl_create_iif_fence(struct gxp_client *client,
				      struct gxp_create_iif_fence_ioctl __user *argp)
{
	struct gxp_create_iif_fence_ioctl ibuf;
	int fd;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	fd = gcip_fence_create_iif(client->gxp->iif_mgr, ibuf.signaler_ip, ibuf.total_signalers);
	if (fd < 0)
		return fd;

	ibuf.fence = fd;

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		return -EFAULT;

	return 0;
}

static int
gxp_ioctl_fence_remaining_signalers(struct gxp_client *client,
				    struct gxp_fence_remaining_signalers_ioctl __user *argp)
{
	struct gxp_fence_remaining_signalers_ioctl ibuf;
	struct gcip_fence_array *fences;
	int ret, num_fences;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	num_fences = get_num_fences(ibuf.fences);
	if (num_fences < 0)
		return num_fences;

	fences = gcip_fence_array_create(ibuf.fences, num_fences, true);
	if (IS_ERR(fences))
		return PTR_ERR(fences);

	ret = gcip_fence_array_wait_signaler_submission(fences, ibuf.eventfd,
							ibuf.remaining_signalers);
	if (ret)
		goto out;

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		ret = -EFAULT;

out:
	gcip_fence_array_put(fences);
	return ret;
}

static inline enum gcip_telemetry_type to_gcip_telemetry_type(u8 type)
{
	if (type == GXP_TELEMETRY_TYPE_LOGGING)
		return GCIP_TELEMETRY_LOG;
	else
		return GCIP_TELEMETRY_TRACE;
}

static int
gxp_ioctl_register_mcu_telemetry_eventfd(struct gxp_client *client,
					 struct gxp_register_telemetry_eventfd_ioctl __user *argp)
{
	struct gxp_mcu *mcu = gxp_mcu_of(client->gxp);
	struct gxp_register_telemetry_eventfd_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	return gxp_mcu_telemetry_register_eventfd(
		mcu, to_gcip_telemetry_type(ibuf.type), ibuf.eventfd);
}

static int
gxp_ioctl_unregister_mcu_telemetry_eventfd(struct gxp_client *client,
					   struct gxp_register_telemetry_eventfd_ioctl __user *argp)
{
	struct gxp_mcu *mcu = gxp_mcu_of(client->gxp);
	struct gxp_register_telemetry_eventfd_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
		return -EFAULT;

	return gxp_mcu_telemetry_unregister_eventfd(
		mcu, to_gcip_telemetry_type(ibuf.type));
}

long gxp_mcu_ioctl(struct file *file, uint cmd, ulong arg)
{
	struct gxp_client *client = file->private_data;
	void __user *argp = (void __user *)arg;
	long ret;

	if (gxp_is_direct_mode(client->gxp))
		return -ENOTTY;
	switch (cmd) {
	case GXP_MAILBOX_COMMAND:
		ret = -EOPNOTSUPP;
		break;
	case GXP_MAILBOX_RESPONSE:
		ret = -EOPNOTSUPP;
		break;
	case GXP_REGISTER_MCU_TELEMETRY_EVENTFD:
		ret = gxp_ioctl_register_mcu_telemetry_eventfd(client, argp);
		break;
	case GXP_UNREGISTER_MCU_TELEMETRY_EVENTFD:
		ret = gxp_ioctl_unregister_mcu_telemetry_eventfd(client, argp);
		break;
	case GXP_MAILBOX_UCI_COMMAND_COMPAT:
		ret = gxp_ioctl_uci_command_compat(client, argp);
		break;
	case GXP_MAILBOX_UCI_COMMAND:
		ret = gxp_ioctl_uci_command(client, argp);
		break;
	case GXP_MAILBOX_UCI_RESPONSE:
		ret = gxp_ioctl_uci_response(client, argp);
		break;
	case GXP_SET_DEVICE_PROPERTIES:
		ret = gxp_ioctl_set_device_properties(client->gxp, argp);
		break;
	case GXP_CREATE_IIF_FENCE:
		ret = gxp_ioctl_create_iif_fence(client, argp);
		break;
	case GXP_FENCE_REMAINING_SIGNALERS:
		ret = gxp_ioctl_fence_remaining_signalers(client, argp);
		break;
	default:
		ret = -ENOTTY; /* unknown command */
	}

	return ret;
}

int gxp_mcu_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct gxp_client *client = file->private_data;
	struct gxp_mcu *mcu = gxp_mcu_of(client->gxp);
	int ret;

	if (gxp_is_direct_mode(client->gxp))
		return -EOPNOTSUPP;

	switch (vma->vm_pgoff << PAGE_SHIFT) {
	case GXP_MMAP_MCU_LOG_BUFFER_OFFSET:
		ret = gxp_mcu_telemetry_mmap_buffer(mcu, GCIP_TELEMETRY_LOG,
						    vma);
		break;
	case GXP_MMAP_MCU_TRACE_BUFFER_OFFSET:
		ret = gxp_mcu_telemetry_mmap_buffer(mcu, GCIP_TELEMETRY_TRACE,
						    vma);
		break;
	default:
		ret = -EOPNOTSUPP; /* unknown offset */
	}

	return ret;
}
