/*
 * Copyright 2020-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_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_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 */

#define DMA_ADDR_BITS  32 /* Number of address bits */

/****************************************************************************
 * 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_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(&edev->mailbox);
		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(&edev->mailbox, 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(&edev->mailbox,
					    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(&edev->mailbox, 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(&edev->mailbox, 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(&edev->mailbox,
					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);

	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 settings for 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;
	}

	/* Set mask for coherent DMA addressing */
	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(DMA_ADDR_BITS));
	if (ret) {
		dev_err(parent, "Failed to set coherent DMA mask. 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);
}
