// SPDX-License-Identifier: GPL-2.0-only
/*
 * WWAN device simulator for WWAN framework testing.
 *
 * Copyright (c) 2021, Sergey Ryazanov <ryazanov.s.a@gmail.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/wwan.h>
#include <linux/debugfs.h>
#include <linux/workqueue.h>

#include <net/arp.h>

static int wwan_hwsim_devsnum = 2;
module_param_named(devices, wwan_hwsim_devsnum, int, 0444);
MODULE_PARM_DESC(devices, "Number of simulated devices");

static struct class *wwan_hwsim_class;

static struct dentry *wwan_hwsim_debugfs_topdir;
static struct dentry *wwan_hwsim_debugfs_devcreate;

static DEFINE_SPINLOCK(wwan_hwsim_devs_lock);
static LIST_HEAD(wwan_hwsim_devs);
static unsigned int wwan_hwsim_dev_idx;

struct wwan_hwsim_dev {
	struct list_head list;
	unsigned int id;
	struct device dev;
	struct work_struct del_work;
	struct dentry *debugfs_topdir;
	struct dentry *debugfs_portcreate;
	spinlock_t ports_lock;	/* Serialize ports creation/deletion */
	unsigned int port_idx;
	struct list_head ports;
};

struct wwan_hwsim_port {
	struct list_head list;
	unsigned int id;
	struct wwan_hwsim_dev *dev;
	struct wwan_port *wwan;
	struct work_struct del_work;
	struct dentry *debugfs_topdir;
	enum {			/* AT command parser state */
		AT_PARSER_WAIT_A,
		AT_PARSER_WAIT_T,
		AT_PARSER_WAIT_TERM,
		AT_PARSER_SKIP_LINE,
	} pstate;
};

static const struct file_operations wwan_hwsim_debugfs_portdestroy_fops;
static const struct file_operations wwan_hwsim_debugfs_portcreate_fops;
static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops;
static void wwan_hwsim_port_del_work(struct work_struct *work);
static void wwan_hwsim_dev_del_work(struct work_struct *work);

static netdev_tx_t wwan_hwsim_netdev_xmit(struct sk_buff *skb,
					  struct net_device *ndev)
{
	ndev->stats.tx_packets++;
	ndev->stats.tx_bytes += skb->len;
	consume_skb(skb);
	return NETDEV_TX_OK;
}

static const struct net_device_ops wwan_hwsim_netdev_ops = {
	.ndo_start_xmit = wwan_hwsim_netdev_xmit,
};

static void wwan_hwsim_netdev_setup(struct net_device *ndev)
{
	ndev->netdev_ops = &wwan_hwsim_netdev_ops;
	ndev->needs_free_netdev = true;

	ndev->mtu = ETH_DATA_LEN;
	ndev->min_mtu = ETH_MIN_MTU;
	ndev->max_mtu = ETH_MAX_MTU;

	ndev->type = ARPHRD_NONE;
	ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
}

static const struct wwan_ops wwan_hwsim_wwan_rtnl_ops = {
	.priv_size = 0,			/* No private data */
	.setup = wwan_hwsim_netdev_setup,
};

static int wwan_hwsim_port_start(struct wwan_port *wport)
{
	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);

	port->pstate = AT_PARSER_WAIT_A;

	return 0;
}

static void wwan_hwsim_port_stop(struct wwan_port *wport)
{
}

/* Implements a minimalistic AT commands parser that echo input back and
 * reply with 'OK' to each input command. See AT command protocol details in the
 * ITU-T V.250 recomendations document.
 *
 * Be aware that this processor is not fully V.250 compliant.
 */
static int wwan_hwsim_port_tx(struct wwan_port *wport, struct sk_buff *in)
{
	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
	struct sk_buff *out;
	int i, n, s;

	/* Estimate a max possible number of commands by counting the number of
	 * termination chars (S3 param, CR by default). And then allocate the
	 * output buffer that will be enough to fit the echo and result codes of
	 * all commands.
	 */
	for (i = 0, n = 0; i < in->len; ++i)
		if (in->data[i] == '\r')
			n++;
	n = in->len + n * (2 + 2 + 2);	/* Output buffer size */
	out = alloc_skb(n, GFP_KERNEL);
	if (!out)
		return -ENOMEM;

	for (i = 0, s = 0; i < in->len; ++i) {
		char c = in->data[i];

		if (port->pstate == AT_PARSER_WAIT_A) {
			if (c == 'A' || c == 'a')
				port->pstate = AT_PARSER_WAIT_T;
			else if (c != '\n')	/* Ignore formating char */
				port->pstate = AT_PARSER_SKIP_LINE;
		} else if (port->pstate == AT_PARSER_WAIT_T) {
			if (c == 'T' || c == 't')
				port->pstate = AT_PARSER_WAIT_TERM;
			else
				port->pstate = AT_PARSER_SKIP_LINE;
		} else if (port->pstate == AT_PARSER_WAIT_TERM) {
			if (c != '\r')
				continue;
			/* Consume the trailing formatting char as well */
			if ((i + 1) < in->len && in->data[i + 1] == '\n')
				i++;
			n = i - s + 1;
			memcpy(skb_put(out, n), &in->data[s], n);/* Echo */
			memcpy(skb_put(out, 6), "\r\nOK\r\n", 6);
			s = i + 1;
			port->pstate = AT_PARSER_WAIT_A;
		} else if (port->pstate == AT_PARSER_SKIP_LINE) {
			if (c != '\r')
				continue;
			port->pstate = AT_PARSER_WAIT_A;
		}
	}

	if (i > s) {
		/* Echo the processed portion of a not yet completed command */
		n = i - s;
		memcpy(skb_put(out, n), &in->data[s], n);
	}

	consume_skb(in);

	wwan_port_rx(wport, out);

	return 0;
}

static const struct wwan_port_ops wwan_hwsim_port_ops = {
	.start = wwan_hwsim_port_start,
	.stop = wwan_hwsim_port_stop,
	.tx = wwan_hwsim_port_tx,
};

static struct wwan_hwsim_port *wwan_hwsim_port_new(struct wwan_hwsim_dev *dev)
{
	struct wwan_hwsim_port *port;
	char name[0x10];
	int err;

	port = kzalloc(sizeof(*port), GFP_KERNEL);
	if (!port)
		return ERR_PTR(-ENOMEM);

	port->dev = dev;

	spin_lock(&dev->ports_lock);
	port->id = dev->port_idx++;
	spin_unlock(&dev->ports_lock);

	port->wwan = wwan_create_port(&dev->dev, WWAN_PORT_AT,
				      &wwan_hwsim_port_ops,
				      port);
	if (IS_ERR(port->wwan)) {
		err = PTR_ERR(port->wwan);
		goto err_free_port;
	}

	INIT_WORK(&port->del_work, wwan_hwsim_port_del_work);

	snprintf(name, sizeof(name), "port%u", port->id);
	port->debugfs_topdir = debugfs_create_dir(name, dev->debugfs_topdir);
	debugfs_create_file("destroy", 0200, port->debugfs_topdir, port,
			    &wwan_hwsim_debugfs_portdestroy_fops);

	return port;

err_free_port:
	kfree(port);

	return ERR_PTR(err);
}

static void wwan_hwsim_port_del(struct wwan_hwsim_port *port)
{
	debugfs_remove(port->debugfs_topdir);

	/* Make sure that there is no pending deletion work */
	if (current_work() != &port->del_work)
		cancel_work_sync(&port->del_work);

	wwan_remove_port(port->wwan);
	kfree(port);
}

static void wwan_hwsim_port_del_work(struct work_struct *work)
{
	struct wwan_hwsim_port *port =
				container_of(work, typeof(*port), del_work);
	struct wwan_hwsim_dev *dev = port->dev;

	spin_lock(&dev->ports_lock);
	if (list_empty(&port->list)) {
		/* Someone else deleting port at the moment */
		spin_unlock(&dev->ports_lock);
		return;
	}
	list_del_init(&port->list);
	spin_unlock(&dev->ports_lock);

	wwan_hwsim_port_del(port);
}

static void wwan_hwsim_dev_release(struct device *sysdev)
{
	struct wwan_hwsim_dev *dev = container_of(sysdev, typeof(*dev), dev);

	kfree(dev);
}

static struct wwan_hwsim_dev *wwan_hwsim_dev_new(void)
{
	struct wwan_hwsim_dev *dev;
	int err;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return ERR_PTR(-ENOMEM);

	spin_lock(&wwan_hwsim_devs_lock);
	dev->id = wwan_hwsim_dev_idx++;
	spin_unlock(&wwan_hwsim_devs_lock);

	dev->dev.release = wwan_hwsim_dev_release;
	dev->dev.class = wwan_hwsim_class;
	dev_set_name(&dev->dev, "hwsim%u", dev->id);

	spin_lock_init(&dev->ports_lock);
	INIT_LIST_HEAD(&dev->ports);

	err = device_register(&dev->dev);
	if (err)
		goto err_free_dev;

	INIT_WORK(&dev->del_work, wwan_hwsim_dev_del_work);

	err = wwan_register_ops(&dev->dev, &wwan_hwsim_wwan_rtnl_ops, dev, 1);
	if (err)
		goto err_unreg_dev;

	dev->debugfs_topdir = debugfs_create_dir(dev_name(&dev->dev),
						 wwan_hwsim_debugfs_topdir);
	debugfs_create_file("destroy", 0200, dev->debugfs_topdir, dev,
			    &wwan_hwsim_debugfs_devdestroy_fops);
	dev->debugfs_portcreate =
		debugfs_create_file("portcreate", 0200,
				    dev->debugfs_topdir, dev,
				    &wwan_hwsim_debugfs_portcreate_fops);

	return dev;

err_unreg_dev:
	device_unregister(&dev->dev);
	/* Memory will be freed in the device release callback */

	return ERR_PTR(err);

err_free_dev:
	kfree(dev);

	return ERR_PTR(err);
}

static void wwan_hwsim_dev_del(struct wwan_hwsim_dev *dev)
{
	debugfs_remove(dev->debugfs_portcreate);	/* Avoid new ports */

	spin_lock(&dev->ports_lock);
	while (!list_empty(&dev->ports)) {
		struct wwan_hwsim_port *port;

		port = list_first_entry(&dev->ports, struct wwan_hwsim_port,
					list);
		list_del_init(&port->list);
		spin_unlock(&dev->ports_lock);
		wwan_hwsim_port_del(port);
		spin_lock(&dev->ports_lock);
	}
	spin_unlock(&dev->ports_lock);

	debugfs_remove(dev->debugfs_topdir);

	/* This will remove all child netdev(s) */
	wwan_unregister_ops(&dev->dev);

	/* Make sure that there is no pending deletion work */
	if (current_work() != &dev->del_work)
		cancel_work_sync(&dev->del_work);

	device_unregister(&dev->dev);
	/* Memory will be freed in the device release callback */
}

static void wwan_hwsim_dev_del_work(struct work_struct *work)
{
	struct wwan_hwsim_dev *dev = container_of(work, typeof(*dev), del_work);

	spin_lock(&wwan_hwsim_devs_lock);
	if (list_empty(&dev->list)) {
		/* Someone else deleting device at the moment */
		spin_unlock(&wwan_hwsim_devs_lock);
		return;
	}
	list_del_init(&dev->list);
	spin_unlock(&wwan_hwsim_devs_lock);

	wwan_hwsim_dev_del(dev);
}

static ssize_t wwan_hwsim_debugfs_portdestroy_write(struct file *file,
						    const char __user *usrbuf,
						    size_t count, loff_t *ppos)
{
	struct wwan_hwsim_port *port = file->private_data;

	/* We can not delete port here since it will cause a deadlock due to
	 * waiting this callback to finish in the debugfs_remove() call. So,
	 * use workqueue.
	 */
	schedule_work(&port->del_work);

	return count;
}

static const struct file_operations wwan_hwsim_debugfs_portdestroy_fops = {
	.write = wwan_hwsim_debugfs_portdestroy_write,
	.open = simple_open,
	.llseek = noop_llseek,
};

static ssize_t wwan_hwsim_debugfs_portcreate_write(struct file *file,
						   const char __user *usrbuf,
						   size_t count, loff_t *ppos)
{
	struct wwan_hwsim_dev *dev = file->private_data;
	struct wwan_hwsim_port *port;

	port = wwan_hwsim_port_new(dev);
	if (IS_ERR(port))
		return PTR_ERR(port);

	spin_lock(&dev->ports_lock);
	list_add_tail(&port->list, &dev->ports);
	spin_unlock(&dev->ports_lock);

	return count;
}

static const struct file_operations wwan_hwsim_debugfs_portcreate_fops = {
	.write = wwan_hwsim_debugfs_portcreate_write,
	.open = simple_open,
	.llseek = noop_llseek,
};

static ssize_t wwan_hwsim_debugfs_devdestroy_write(struct file *file,
						   const char __user *usrbuf,
						   size_t count, loff_t *ppos)
{
	struct wwan_hwsim_dev *dev = file->private_data;

	/* We can not delete device here since it will cause a deadlock due to
	 * waiting this callback to finish in the debugfs_remove() call. So,
	 * use workqueue.
	 */
	schedule_work(&dev->del_work);

	return count;
}

static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops = {
	.write = wwan_hwsim_debugfs_devdestroy_write,
	.open = simple_open,
	.llseek = noop_llseek,
};

static ssize_t wwan_hwsim_debugfs_devcreate_write(struct file *file,
						  const char __user *usrbuf,
						  size_t count, loff_t *ppos)
{
	struct wwan_hwsim_dev *dev;

	dev = wwan_hwsim_dev_new();
	if (IS_ERR(dev))
		return PTR_ERR(dev);

	spin_lock(&wwan_hwsim_devs_lock);
	list_add_tail(&dev->list, &wwan_hwsim_devs);
	spin_unlock(&wwan_hwsim_devs_lock);

	return count;
}

static const struct file_operations wwan_hwsim_debugfs_devcreate_fops = {
	.write = wwan_hwsim_debugfs_devcreate_write,
	.open = simple_open,
	.llseek = noop_llseek,
};

static int __init wwan_hwsim_init_devs(void)
{
	struct wwan_hwsim_dev *dev;
	int i, j;

	for (i = 0; i < wwan_hwsim_devsnum; ++i) {
		dev = wwan_hwsim_dev_new();
		if (IS_ERR(dev))
			return PTR_ERR(dev);

		spin_lock(&wwan_hwsim_devs_lock);
		list_add_tail(&dev->list, &wwan_hwsim_devs);
		spin_unlock(&wwan_hwsim_devs_lock);

		/* Create a couple of ports per each device to accelerate
		 * the simulator readiness time.
		 */
		for (j = 0; j < 2; ++j) {
			struct wwan_hwsim_port *port;

			port = wwan_hwsim_port_new(dev);
			if (IS_ERR(port))
				return PTR_ERR(port);

			spin_lock(&dev->ports_lock);
			list_add_tail(&port->list, &dev->ports);
			spin_unlock(&dev->ports_lock);
		}
	}

	return 0;
}

static void wwan_hwsim_free_devs(void)
{
	struct wwan_hwsim_dev *dev;

	spin_lock(&wwan_hwsim_devs_lock);
	while (!list_empty(&wwan_hwsim_devs)) {
		dev = list_first_entry(&wwan_hwsim_devs, struct wwan_hwsim_dev,
				       list);
		list_del_init(&dev->list);
		spin_unlock(&wwan_hwsim_devs_lock);
		wwan_hwsim_dev_del(dev);
		spin_lock(&wwan_hwsim_devs_lock);
	}
	spin_unlock(&wwan_hwsim_devs_lock);
}

static int __init wwan_hwsim_init(void)
{
	int err;

	if (wwan_hwsim_devsnum < 0 || wwan_hwsim_devsnum > 128)
		return -EINVAL;

	wwan_hwsim_class = class_create(THIS_MODULE, "wwan_hwsim");
	if (IS_ERR(wwan_hwsim_class))
		return PTR_ERR(wwan_hwsim_class);

	wwan_hwsim_debugfs_topdir = debugfs_create_dir("wwan_hwsim", NULL);
	wwan_hwsim_debugfs_devcreate =
			debugfs_create_file("devcreate", 0200,
					    wwan_hwsim_debugfs_topdir, NULL,
					    &wwan_hwsim_debugfs_devcreate_fops);

	err = wwan_hwsim_init_devs();
	if (err)
		goto err_clean_devs;

	return 0;

err_clean_devs:
	wwan_hwsim_free_devs();
	debugfs_remove(wwan_hwsim_debugfs_topdir);
	class_destroy(wwan_hwsim_class);

	return err;
}

static void __exit wwan_hwsim_exit(void)
{
	debugfs_remove(wwan_hwsim_debugfs_devcreate);	/* Avoid new devs */
	wwan_hwsim_free_devs();
	flush_scheduled_work();		/* Wait deletion works completion */
	debugfs_remove(wwan_hwsim_debugfs_topdir);
	class_destroy(wwan_hwsim_class);
}

module_init(wwan_hwsim_init);
module_exit(wwan_hwsim_exit);

MODULE_AUTHOR("Sergey Ryazanov");
MODULE_DESCRIPTION("Device simulator for WWAN framework");
MODULE_LICENSE("GPL");
