/*
 * Copyright 2020,2022-2023 Arm Limited and/or its affiliates
 *
 * 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.
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

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

#include "ethosu_network.h"

#include "ethosu_buffer.h"
#include "ethosu_device.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_info(dev, "Network destroy. net=0x%pK\n", net);

	if (net->buf != NULL)
		ethosu_buffer_put(net->buf);

	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_info(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;

	dev_info(dev,
		 "Network ioctl: file=0x%pK, net=0x%pK, cmd=0x%x, arg=0x%lx\n",
		 file, net, cmd, arg);

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

		dev_info(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_info(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;
	int ret = -ENOMEM;

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

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

	if (uapi->type == ETHOSU_UAPI_NETWORK_BUFFER) {
		net->buf = ethosu_buffer_get_from_fd(uapi->fd);
		if (IS_ERR(net->buf)) {
			ret = PTR_ERR(net->buf);
			goto free_net;
		}
	} else {
		net->index = uapi->index;
	}

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

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

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

	return ret;

put_buf:
	if (net->buf != NULL)
		ethosu_buffer_put(net->buf);

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);
}
