/*
 * SPDX-FileCopyrightText: Copyright 2020,2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: GPL-2.0-only
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

#include "ethosu_network.h"

#include "ethosu_device.h"
#include "ethosu_dma_mem.h"
#include "ethosu_inference.h"
#include "ethosu_network_info.h"
#include "uapi/ethosu.h"

#include <linux/anon_inodes.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

/****************************************************************************
 * Variables
 ****************************************************************************/

static int ethosu_network_release(struct inode *inode,
				  struct file *file);

static long ethosu_network_ioctl(struct file *file,
				 unsigned int cmd,
				 unsigned long arg);

static const struct file_operations ethosu_network_fops = {
	.release        = &ethosu_network_release,
	.unlocked_ioctl = &ethosu_network_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl   = &ethosu_network_ioctl,
#endif
};

/****************************************************************************
 * Functions
 ****************************************************************************/

static bool ethosu_network_verify(struct file *file)
{
	return file->f_op == &ethosu_network_fops;
}

static void ethosu_network_destroy(struct kref *kref)
{
	struct ethosu_network *net =
		container_of(kref, struct ethosu_network, kref);
	struct device *dev = net->dev;

	dev_dbg(dev, "Network destroy. net=0x%pK\n", net);

	if (net->dma_mem != NULL)
		ethosu_dma_mem_free(&net->dma_mem);

	memset(net, 0, sizeof(*net));
	devm_kfree(dev, net);
}

static int ethosu_network_release(struct inode *inode,
				  struct file *file)
{
	struct ethosu_network *net = file->private_data;
	struct device *dev = net->dev;

	dev_dbg(dev, "Network release. file=0x%pK, net=0x%pK\n",
		file, net);

	ethosu_network_put(net);

	return 0;
}

static long ethosu_network_ioctl(struct file *file,
				 unsigned int cmd,
				 unsigned long arg)
{
	struct ethosu_network *net = file->private_data;
	struct device *dev = net->dev;
	void __user *udata = (void __user *)arg;
	int ret;

	ret = device_lock_interruptible(net->dev);
	if (ret)
		return ret;

	switch (cmd) {
	case ETHOSU_IOCTL_NETWORK_INFO: {
		struct ethosu_uapi_network_info uapi = { 0 };

		dev_dbg(dev, "Network ioctl: Network info. net=0x%pK\n", net);

		ret = ethosu_network_info_request(dev, net->mailbox, net,
						  &uapi);
		if (ret)
			break;

		ret = copy_to_user(udata, &uapi, sizeof(uapi)) ? -EFAULT : 0;
		break;
	}
	case ETHOSU_IOCTL_INFERENCE_CREATE: {
		struct ethosu_uapi_inference_create uapi;

		if (copy_from_user(&uapi, udata, sizeof(uapi))) {
			ret = -EFAULT;
			break;
		}

		dev_dbg(dev,
			"Network ioctl: Inference. ifm_fd=%u, ofm_fd=%u\n",
			uapi.ifm_fd[0], uapi.ofm_fd[0]);

		ret = ethosu_inference_create(dev, net->mailbox, net, &uapi);
		break;
	}
	default: {
		dev_err(dev, "Invalid ioctl. cmd=%u, arg=%lu",
			cmd, arg);
		ret = -ENOIOCTLCMD;
		break;
	}
	}

	device_unlock(net->dev);

	return ret;
}

int ethosu_network_create(struct device *dev,
			  struct ethosu_mailbox *mailbox,
			  struct ethosu_uapi_network_create *uapi)
{
	struct ethosu_network *net;
	const void __user *data;
	int ret;

	net = devm_kzalloc(dev, sizeof(*net), GFP_KERNEL);
	if (!net)
		return -ENOMEM;

	net->dev = dev;
	net->mailbox = mailbox;
	kref_init(&net->kref);

	switch (uapi->type) {
	case ETHOSU_UAPI_NETWORK_USER_BUFFER:
		if (!uapi->network.data_ptr) {
			dev_err(dev, "Invalid network data ptr\n");
			ret = -EINVAL;
			goto free_net;
		}

		if (!uapi->network.size) {
			dev_err(dev, "Invalid network data size\n");
			ret = -EINVAL;
			goto free_net;
		}

		net->dma_mem = ethosu_dma_mem_alloc(dev, uapi->network.size);
		if (IS_ERR(net->dma_mem)) {
			ret = PTR_ERR(net->dma_mem);
			goto free_net;
		}

		data = u64_to_user_ptr(uapi->network.data_ptr);
		ret = copy_from_user(net->dma_mem->cpu_addr, data,
				     uapi->network.size);
		if (ret)
			goto free_dma_mem;

		break;
	case ETHOSU_UAPI_NETWORK_INDEX:
		net->index = uapi->index;
		break;
	default:
		ret = -EINVAL;
		goto free_net;
	}

	ret = anon_inode_getfd("ethosu-network", &ethosu_network_fops, net,
			       O_RDWR | O_CLOEXEC);
	if (ret < 0)
		goto free_dma_mem;

	net->file = fget(ret);
	fput(net->file);

	dev_dbg(dev,
		"Network create. file=0x%pK, fd=%d, net=0x%pK, buf=0x%pK, index=%u",
		net->file, ret, net, net->dma_mem, net->index);

	return ret;

free_dma_mem:
	if (net->dma_mem != NULL)
		ethosu_dma_mem_free(&net->dma_mem);

free_net:
	memset(net, 0, sizeof(*net));
	devm_kfree(dev, net);

	return ret;
}

struct ethosu_network *ethosu_network_get_from_fd(int fd)
{
	struct ethosu_network *net;
	struct file *file;

	file = fget(fd);
	if (!file)
		return ERR_PTR(-EINVAL);

	if (!ethosu_network_verify(file)) {
		fput(file);

		return ERR_PTR(-EINVAL);
	}

	net = file->private_data;
	ethosu_network_get(net);
	fput(file);

	return net;
}

void ethosu_network_get(struct ethosu_network *net)
{
	kref_get(&net->kref);
}

int ethosu_network_put(struct ethosu_network *net)
{
	return kref_put(&net->kref, ethosu_network_destroy);
}
