/*
 * SPDX-FileCopyrightText: Copyright 2020-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_device.h"

#include "ethosu_buffer.h"
#include "ethosu_core_rpmsg.h"
#include "ethosu_capabilities.h"
#include "ethosu_inference.h"
#include "ethosu_cancel_inference.h"
#include "ethosu_network.h"
#include "ethosu_network_info.h"
#include "ethosu_version.h"
#include "uapi/ethosu.h"

#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/remoteproc.h>
#include <linux/slab.h>
#include <linux/uaccess.h>

/****************************************************************************
 * Defines
 ****************************************************************************/

#define MINOR_BASE      0 /* Minor version starts at 0 */
#define MINOR_COUNT    64 /* Allocate minor versions */

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

static DECLARE_BITMAP(minors, MINOR_COUNT);

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

/* Incoming messages */
static int ethosu_handle_rpmsg(struct rpmsg_device *rpdev,
			       void *data,
			       int len,
			       void *priv,
			       u32 src)
{
	struct ethosu_device *edev = dev_get_drvdata(&rpdev->dev);
	struct device *dev = &edev->dev;
	struct ethosu_mailbox *mbox = &edev->mailbox;
	struct ethosu_core_rpmsg *rpmsg = data;
	int length = len - sizeof(rpmsg->header);
	int ret = 0;

	if (unlikely(rpmsg->header.magic != ETHOSU_CORE_MSG_MAGIC)) {
		dev_warn(dev, "Msg: Error invalid message magic. magic=0x%08x",
			 rpmsg->header.magic);

		return -EBADMSG;
	}

	device_lock(dev);

	dev_info(dev,
		 "Msg: magic=0x%08x, type=%u, msg_id=%llu",
		 rpmsg->header.magic, rpmsg->header.type, rpmsg->header.msg_id);

	switch (rpmsg->header.type) {
	case ETHOSU_CORE_MSG_ERR:
		if (length != sizeof(rpmsg->error)) {
			dev_warn(dev,
				 "Msg: Error message of incorrect size. size=%u, expected=%zu", length,
				 sizeof(rpmsg->error));
			ret = -EBADMSG;
			break;
		}

		rpmsg->error.msg[sizeof(rpmsg->error.msg) - 1] = '\0';
		dev_warn(dev, "Msg: Error. type=%u, msg=\"%s\"",
			 rpmsg->error.type, rpmsg->error.msg);

		rproc_report_crash(rproc_get_by_child(dev), RPROC_FATAL_ERROR);
		break;
	case ETHOSU_CORE_MSG_PING:
		dev_info(dev, "Msg: Ping");
		ret = ethosu_mailbox_pong(mbox);
		break;
	case ETHOSU_CORE_MSG_PONG:
		dev_info(dev, "Msg: Pong");
		break;
	case ETHOSU_CORE_MSG_INFERENCE_RSP:
		if (length != sizeof(rpmsg->inf_rsp)) {
			dev_warn(dev,
				 "Msg: Inference response of incorrect size. size=%u, expected=%zu", length,
				 sizeof(rpmsg->inf_rsp));
			ret = -EBADMSG;
			break;
		}

		dev_info(dev,
			 "Msg: Inference response. ofm_count=%u, status=%u",
			 rpmsg->inf_rsp.ofm_count, rpmsg->inf_rsp.status);

		ethosu_inference_rsp(mbox, rpmsg->header.msg_id,
				     &rpmsg->inf_rsp);
		break;
	case ETHOSU_CORE_MSG_CANCEL_INFERENCE_RSP:
		if (length != sizeof(rpmsg->cancel_rsp)) {
			dev_warn(dev,
				 "Msg: Cancel Inference response of incorrect size. size=%u, expected=%zu", length,
				 sizeof(rpmsg->cancel_rsp));
			ret = -EBADMSG;
			break;
		}

		dev_info(dev,
			 "Msg: Cancel Inference response. status=%u",
			 rpmsg->cancel_rsp.status);
		ethosu_cancel_inference_rsp(mbox,
					    rpmsg->header.msg_id,
					    &rpmsg->cancel_rsp);
		break;
	case ETHOSU_CORE_MSG_VERSION_RSP:
		if (length != sizeof(rpmsg->version_rsp)) {
			dev_warn(dev,
				 "Msg: Protocol version response of incorrect size. size=%u, expected=%zu", length,
				 sizeof(rpmsg->version_rsp));
			ret = -EBADMSG;
			break;
		}

		dev_dbg(dev, "Msg: Protocol version response %u.%u.%u",
			rpmsg->version_rsp.major, rpmsg->version_rsp.minor,
			rpmsg->version_rsp.patch);

		ethosu_version_rsp(mbox, rpmsg->header.msg_id,
				   &rpmsg->version_rsp);
		break;
	case ETHOSU_CORE_MSG_CAPABILITIES_RSP:
		if (length != sizeof(rpmsg->cap_rsp)) {
			dev_warn(dev,
				 "Msg: Capabilities response of incorrect size. size=%u, expected=%zu", length,
				 sizeof(rpmsg->cap_rsp));
			ret = -EBADMSG;
			break;
		}

		dev_info(dev,
			 "Msg: Capabilities response vs%hhu v%hhu.%hhu p%hhu av%hhu.%hhu.%hhu dv%hhu.%hhu.%hhu mcc%hhu csv%hhu cd%hhu",
			 rpmsg->cap_rsp.version_status,
			 rpmsg->cap_rsp.version_major,
			 rpmsg->cap_rsp.version_minor,
			 rpmsg->cap_rsp.product_major,
			 rpmsg->cap_rsp.arch_major_rev,
			 rpmsg->cap_rsp.arch_minor_rev,
			 rpmsg->cap_rsp.arch_patch_rev,
			 rpmsg->cap_rsp.driver_major_rev,
			 rpmsg->cap_rsp.driver_minor_rev,
			 rpmsg->cap_rsp.driver_patch_rev,
			 rpmsg->cap_rsp.macs_per_cc,
			 rpmsg->cap_rsp.cmd_stream_version,
			 rpmsg->cap_rsp.custom_dma);

		ethosu_capability_rsp(mbox, rpmsg->header.msg_id,
				      &rpmsg->cap_rsp);
		break;
	case ETHOSU_CORE_MSG_NETWORK_INFO_RSP:
		if (length != sizeof(rpmsg->net_info_rsp)) {
			dev_warn(dev,
				 "Msg: Network info response of incorrect size. size=%u, expected=%zu", length,
				 sizeof(rpmsg->net_info_rsp));
			ret = -EBADMSG;
			break;
		}

		dev_info(dev,
			 "Msg: Network info response. status=%u",
			 rpmsg->net_info_rsp.status);

		ethosu_network_info_rsp(mbox,
					rpmsg->header.msg_id,
					&rpmsg->net_info_rsp);

		break;
	default:
		/* This should not happen due to version checks */
		dev_warn(dev, "Msg: Protocol error. type=%u",
			 rpmsg->header.type);
		ret = -EPROTO;
		break;
	}

	device_unlock(dev);

	wake_up(&mbox->send_queue);

	return ret;
}

static int ethosu_open(struct inode *inode,
		       struct file *file)
{
	struct cdev *cdev = inode->i_cdev;
	struct ethosu_device *edev = container_of(cdev, struct ethosu_device,
						  cdev);
	struct rpmsg_device *rpdev = edev->rpdev;
	struct device *dev = &edev->dev;

	dev_info(dev, "Device open. file=0x%pK", file);

	file->private_data = rpdev;

	return nonseekable_open(inode, file);
}

static long ethosu_ioctl(struct file *file,
			 unsigned int cmd,
			 unsigned long arg)
{
	struct rpmsg_device *rpdev = file->private_data;
	struct ethosu_device *edev = dev_get_drvdata(&rpdev->dev);
	struct device *dev = &edev->dev;
	void __user *udata = (void __user *)arg;
	int ret;

	dev_info(dev, "Device ioctl. file=0x%pK, cmd=0x%x, arg=0x%lx",
		 file, cmd, arg);

	switch (cmd) {
	case ETHOSU_IOCTL_DRIVER_VERSION_GET: {
		const struct ethosu_uapi_kernel_driver_version version = {
			.major = ETHOSU_KERNEL_DRIVER_VERSION_MAJOR,
			.minor = ETHOSU_KERNEL_DRIVER_VERSION_MINOR,
			.patch = ETHOSU_KERNEL_DRIVER_VERSION_PATCH,
		};

		ret = copy_to_user(udata, &version,
				   sizeof(version)) ? -EFAULT : 0;
		break;
	}
	case ETHOSU_IOCTL_CAPABILITIES_REQ: {
		dev_info(dev, "Device ioctl: Capabilities request");

		ret = copy_to_user(udata, &edev->capabilities,
				   sizeof(edev->capabilities)) ? -EFAULT : 0;
		break;
	}
	case ETHOSU_IOCTL_PING: {
		ret = device_lock_interruptible(dev);
		if (ret)
			return ret;

		dev_info(dev, "Device ioctl: Send ping");

		ret = ethosu_mailbox_ping(&edev->mailbox);

		device_unlock(dev);

		break;
	}
	case ETHOSU_IOCTL_BUFFER_CREATE: {
		struct ethosu_uapi_buffer_create uapi;

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

		ret = device_lock_interruptible(dev);
		if (ret)
			return ret;

		dev_info(dev,
			 "Device ioctl: Buffer create. capacity=%u",
			 uapi.capacity);

		ret = ethosu_buffer_create(dev, uapi.capacity);

		device_unlock(dev);

		break;
	}
	case ETHOSU_IOCTL_NETWORK_CREATE: {
		struct ethosu_uapi_network_create uapi;

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

		ret = device_lock_interruptible(dev);
		if (ret)
			return ret;

		dev_info(dev,
			 "Device ioctl: Network create. type=%u, fd/index=%u",
			 uapi.type, uapi.fd);

		ret = ethosu_network_create(dev, &edev->mailbox, &uapi);

		device_unlock(dev);

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

	return ret;
}

static struct rpmsg_endpoint *ethosu_create_ept(struct rpmsg_device *rpdev)
{
	struct device *dev = &rpdev->dev;
	struct rpmsg_channel_info info;
	struct rpmsg_endpoint *ept;

	/* Create rpmsg endpoint */
	strncpy(info.name, rpdev->id.name, sizeof(info.name));
	info.src = 0;
	info.dst = rpdev->dst;

	dev_info(dev, "Creating rpmsg endpoint. name=%s, src=%u, dst=%u",
		 info.name, info.src, info.dst);

	ept = rpmsg_create_ept(rpdev, ethosu_handle_rpmsg, NULL, info);
	if (!ept) {
		dev_err(&rpdev->dev, "Failed to create endpoint");

		return ERR_PTR(-EINVAL);
	}

	return ept;
}

static const struct file_operations fops = {
	.owner          = THIS_MODULE,
	.open           = &ethosu_open,
	.unlocked_ioctl = &ethosu_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl   = &ethosu_ioctl,
#endif
};

static void ethosu_dev_release(struct device *dev)
{
	struct ethosu_device *edev = dev_get_drvdata(dev);

	dev_info(dev, "%s", __FUNCTION__);

	clear_bit(MINOR(edev->cdev.dev), minors);

	ethosu_mailbox_deinit(&edev->mailbox);
	device_destroy(edev->class, edev->cdev.dev);
	kfree(edev);
}

static int ethosu_device_register(struct device *dev,
				  struct device *parent,
				  void *drvdata,
				  dev_t devt)
{
	struct rproc *rproc = rproc_get_by_child(parent);
	int ret;

	dev->parent = parent;
	dev->release = ethosu_dev_release;
	dev_set_drvdata(dev, drvdata);

	ret = dev_set_name(dev, "ethosu%d", MINOR(devt));
	if (ret) {
		dev_err(parent, "Failed to set device name. ret=%d", ret);

		return ret;
	}

	/* Inherit DMA mask from rproc device */
	ret = dma_coerce_mask_and_coherent(dev,
					   dma_get_mask(rproc->dev.parent));
	if (ret) {
		dev_err(parent, "Failed to set DMA mask. ret=%d", ret);

		return ret;
	}

	/* Inherit DMA configuration from rproc device */
	ret = of_dma_configure(dev, rproc->dev.parent->of_node, false);
	if (ret) {
		dev_err(parent, "Failed to configure DMA. ret=%d",
			ret);

		return ret;
	}

	/* Inherit reserved memory from rproc device */
	ret = of_reserved_mem_device_init_by_idx(dev,
						 rproc->dev.parent->of_node, 0);
	if (ret) {
		dev_err(parent, "Failed to initialize reserved memory. ret=%d",
			ret);

		return ret;
	}

	ret = device_register(dev);
	if (ret) {
		dev_err(parent, "Failed to register device. ret=%d", ret);

		return ret;
	}

	return 0;
}

int ethosu_dev_init(struct rpmsg_device *rpdev,
		    struct class *class,
		    dev_t devt)
{
	struct device *dev = &rpdev->dev;
	struct ethosu_device *edev;
	struct device *sysdev;
	int minor;
	int ret;

	dev_info(dev, "%s", __FUNCTION__);

	/* Reserve minor number for device node */
	minor = find_first_zero_bit(minors, MINOR_COUNT);
	if (minor >= MINOR_COUNT) {
		dev_err(dev, "No more minor numbers.");

		return -ENOMEM;
	}

	devt = MKDEV(MAJOR(devt), minor);

	/* Allocate and create Ethos-U device */
	edev = kzalloc(sizeof(*edev), GFP_KERNEL);
	if (!edev)
		return -ENOMEM;

	dev_set_drvdata(&rpdev->dev, edev);

	edev->rpdev = rpdev;
	edev->class = class;

	/* Create device object */
	ret = ethosu_device_register(&edev->dev, &rpdev->dev, edev,
				     devt);
	if (ret) {
		kfree(edev);

		return ret;
	}

	/* Continue with new device */
	dev = &edev->dev;

	/* Create RPMsg endpoint */
	edev->ept = ethosu_create_ept(rpdev);
	if (IS_ERR(edev->ept)) {
		ret = PTR_ERR(edev->ept);
		goto device_unregister;
	}

	ret = ethosu_mailbox_init(&edev->mailbox, dev, edev->ept);
	if (ret)
		goto free_rpmsg_ept;

	device_lock(dev);
	ret = ethosu_version_check_request(dev, &edev->mailbox);
	device_unlock(dev);
	if (ret) {
		dev_err(dev, "Protocol version check failed: %d", ret);
		goto deinit_mailbox;
	}

	device_lock(dev);
	ret = ethosu_capabilities_request(dev, &edev->mailbox,
					  &edev->capabilities);
	device_unlock(dev);
	if (ret) {
		dev_err(dev, "Failed to get device capabilities: %d", ret);
		goto deinit_mailbox;
	}

	/* Create device node */
	cdev_init(&edev->cdev, &fops);
	edev->cdev.owner = THIS_MODULE;

	cdev_set_parent(&edev->cdev, &dev->kobj);

	ret = cdev_add(&edev->cdev, devt, 1);
	if (ret) {
		dev_err(dev, "Failed to add character device.");
		goto deinit_mailbox;
	}

	sysdev = device_create(edev->class, NULL, devt, rpdev,
			       "ethosu%d", MINOR(devt));
	if (IS_ERR(sysdev)) {
		dev_err(dev, "Failed to create device.");
		ret = PTR_ERR(sysdev);
		goto del_cdev;
	}

	set_bit(minor, minors);

	dev_info(dev,
		 "Created Arm Ethos-U device. name=%s, major=%d, minor=%d",
		 dev_name(sysdev), MAJOR(devt), MINOR(devt));

	return 0;

del_cdev:
	cdev_del(&edev->cdev);

deinit_mailbox:
	ethosu_mailbox_deinit(&edev->mailbox);

free_rpmsg_ept:
	rpmsg_destroy_ept(edev->ept);

device_unregister:
	device_unregister(dev);

	return ret;
}

void ethosu_dev_deinit(struct rpmsg_device *rpdev)
{
	struct device *dev = &rpdev->dev;
	struct ethosu_device *edev = dev_get_drvdata(dev);

	dev_info(dev, "%s", __FUNCTION__);

	device_lock(&edev->dev);
	ethosu_mailbox_fail(&edev->mailbox);
	device_unlock(&edev->dev);

	rpmsg_destroy_ept(edev->ept);
	cdev_del(&edev->cdev);
	device_unregister(&edev->dev);
}
