// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Virtual NCI device simulation driver
 *
 * Copyright (C) 2020 Samsung Electrnoics
 * Bongsu Jeon <bongsu.jeon@samsung.com>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <net/nfc/nci_core.h>

enum virtual_ncidev_mode {
	virtual_ncidev_enabled,
	virtual_ncidev_disabled,
	virtual_ncidev_disabling,
};

#define IOCTL_GET_NCIDEV_IDX    0
#define VIRTUAL_NFC_PROTOCOLS	(NFC_PROTO_JEWEL_MASK | \
				 NFC_PROTO_MIFARE_MASK | \
				 NFC_PROTO_FELICA_MASK | \
				 NFC_PROTO_ISO14443_MASK | \
				 NFC_PROTO_ISO14443_B_MASK | \
				 NFC_PROTO_ISO15693_MASK)

static enum virtual_ncidev_mode state;
static struct miscdevice miscdev;
static struct sk_buff *send_buff;
static struct nci_dev *ndev;
static DEFINE_MUTEX(nci_mutex);

static int virtual_nci_open(struct nci_dev *ndev)
{
	return 0;
}

static int virtual_nci_close(struct nci_dev *ndev)
{
	mutex_lock(&nci_mutex);
	kfree_skb(send_buff);
	send_buff = NULL;
	mutex_unlock(&nci_mutex);

	return 0;
}

static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
{
	mutex_lock(&nci_mutex);
	if (state != virtual_ncidev_enabled) {
		mutex_unlock(&nci_mutex);
		return 0;
	}

	if (send_buff) {
		mutex_unlock(&nci_mutex);
		return -1;
	}
	send_buff = skb_copy(skb, GFP_KERNEL);
	mutex_unlock(&nci_mutex);

	return 0;
}

static struct nci_ops virtual_nci_ops = {
	.open = virtual_nci_open,
	.close = virtual_nci_close,
	.send = virtual_nci_send
};

static ssize_t virtual_ncidev_read(struct file *file, char __user *buf,
				   size_t count, loff_t *ppos)
{
	size_t actual_len;

	mutex_lock(&nci_mutex);
	if (!send_buff) {
		mutex_unlock(&nci_mutex);
		return 0;
	}

	actual_len = min_t(size_t, count, send_buff->len);

	if (copy_to_user(buf, send_buff->data, actual_len)) {
		mutex_unlock(&nci_mutex);
		return -EFAULT;
	}

	skb_pull(send_buff, actual_len);
	if (send_buff->len == 0) {
		consume_skb(send_buff);
		send_buff = NULL;
	}
	mutex_unlock(&nci_mutex);

	return actual_len;
}

static ssize_t virtual_ncidev_write(struct file *file,
				    const char __user *buf,
				    size_t count, loff_t *ppos)
{
	struct sk_buff *skb;

	skb = alloc_skb(count, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	if (copy_from_user(skb_put(skb, count), buf, count)) {
		kfree_skb(skb);
		return -EFAULT;
	}

	nci_recv_frame(ndev, skb);
	return count;
}

static int virtual_ncidev_open(struct inode *inode, struct file *file)
{
	int ret = 0;

	mutex_lock(&nci_mutex);
	if (state != virtual_ncidev_disabled) {
		mutex_unlock(&nci_mutex);
		return -EBUSY;
	}

	ndev = nci_allocate_device(&virtual_nci_ops, VIRTUAL_NFC_PROTOCOLS,
				   0, 0);
	if (!ndev) {
		mutex_unlock(&nci_mutex);
		return -ENOMEM;
	}

	ret = nci_register_device(ndev);
	if (ret < 0) {
		nci_free_device(ndev);
		mutex_unlock(&nci_mutex);
		return ret;
	}
	state = virtual_ncidev_enabled;
	mutex_unlock(&nci_mutex);

	return 0;
}

static int virtual_ncidev_close(struct inode *inode, struct file *file)
{
	mutex_lock(&nci_mutex);

	if (state == virtual_ncidev_enabled) {
		state = virtual_ncidev_disabling;
		mutex_unlock(&nci_mutex);

		nci_unregister_device(ndev);
		nci_free_device(ndev);

		mutex_lock(&nci_mutex);
	}

	state = virtual_ncidev_disabled;
	mutex_unlock(&nci_mutex);

	return 0;
}

static long virtual_ncidev_ioctl(struct file *flip, unsigned int cmd,
				 unsigned long arg)
{
	struct nfc_dev *nfc_dev = ndev->nfc_dev;
	void __user *p = (void __user *)arg;

	if (cmd != IOCTL_GET_NCIDEV_IDX)
		return -ENOTTY;

	if (copy_to_user(p, &nfc_dev->idx, sizeof(nfc_dev->idx)))
		return -EFAULT;

	return 0;
}

static const struct file_operations virtual_ncidev_fops = {
	.owner = THIS_MODULE,
	.read = virtual_ncidev_read,
	.write = virtual_ncidev_write,
	.open = virtual_ncidev_open,
	.release = virtual_ncidev_close,
	.unlocked_ioctl = virtual_ncidev_ioctl
};

static int __init virtual_ncidev_init(void)
{
	state = virtual_ncidev_disabled;
	miscdev.minor = MISC_DYNAMIC_MINOR;
	miscdev.name = "virtual_nci";
	miscdev.fops = &virtual_ncidev_fops;
	miscdev.mode = S_IALLUGO;

	return misc_register(&miscdev);
}

static void __exit virtual_ncidev_exit(void)
{
	misc_deregister(&miscdev);
}

module_init(virtual_ncidev_init);
module_exit(virtual_ncidev_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Virtual NCI device simulation driver");
MODULE_AUTHOR("Bongsu Jeon <bongsu.jeon@samsung.com>");
