/*
 * 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);

	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 = -EINVAL;

	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;

		if (copy_from_user(&uapi, udata, sizeof(uapi)))
			break;

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