/*
 * NFC hardware simulation driver
 * Copyright (c) 2013, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/nfc.h>
#include <net/nfc/nfc.h>

#define DEV_ERR(_dev, fmt, args...) nfc_dev_err(&_dev->nfc_dev->dev, \
						"%s: " fmt, __func__, ## args)

#define DEV_DBG(_dev, fmt, args...) dev_dbg(&_dev->nfc_dev->dev, \
						"%s: " fmt, __func__, ## args)

#define NFCSIM_VERSION "0.1"

#define NFCSIM_POLL_NONE	0
#define NFCSIM_POLL_INITIATOR	1
#define NFCSIM_POLL_TARGET	2
#define NFCSIM_POLL_DUAL	(NFCSIM_POLL_INITIATOR | NFCSIM_POLL_TARGET)

struct nfcsim {
	struct nfc_dev *nfc_dev;

	struct mutex lock;

	struct delayed_work recv_work;

	struct sk_buff *clone_skb;

	struct delayed_work poll_work;
	u8 polling_mode;
	u8 curr_polling_mode;

	u8 shutting_down;

	u8 up;

	u8 initiator;

	data_exchange_cb_t cb;
	void *cb_context;

	struct nfcsim *peer_dev;
};

static struct nfcsim *dev0;
static struct nfcsim *dev1;

static struct workqueue_struct *wq;

static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown)
{
	DEV_DBG(dev, "shutdown=%d\n", shutdown);

	mutex_lock(&dev->lock);

	dev->polling_mode = NFCSIM_POLL_NONE;
	dev->shutting_down = shutdown;
	dev->cb = NULL;
	dev_kfree_skb(dev->clone_skb);
	dev->clone_skb = NULL;

	mutex_unlock(&dev->lock);

	cancel_delayed_work_sync(&dev->poll_work);
	cancel_delayed_work_sync(&dev->recv_work);
}

static int nfcsim_target_found(struct nfcsim *dev)
{
	struct nfc_target nfc_tgt;

	DEV_DBG(dev, "\n");

	memset(&nfc_tgt, 0, sizeof(struct nfc_target));

	nfc_tgt.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
	nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1);

	return 0;
}

static int nfcsim_dev_up(struct nfc_dev *nfc_dev)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);

	DEV_DBG(dev, "\n");

	mutex_lock(&dev->lock);

	dev->up = 1;

	mutex_unlock(&dev->lock);

	return 0;
}

static int nfcsim_dev_down(struct nfc_dev *nfc_dev)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);

	DEV_DBG(dev, "\n");

	mutex_lock(&dev->lock);

	dev->up = 0;

	mutex_unlock(&dev->lock);

	return 0;
}

static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev,
			      struct nfc_target *target,
			      u8 comm_mode, u8 *gb, size_t gb_len)
{
	int rc;
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
	struct nfcsim *peer = dev->peer_dev;
	u8 *remote_gb;
	size_t remote_gb_len;

	DEV_DBG(dev, "target_idx: %d, comm_mode: %d\n", target->idx, comm_mode);

	mutex_lock(&peer->lock);

	nfc_tm_activated(peer->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
			 NFC_COMM_ACTIVE, gb, gb_len);

	remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len);
	if (!remote_gb) {
		DEV_ERR(peer, "Can't get remote general bytes");

		mutex_unlock(&peer->lock);
		return -EINVAL;
	}

	mutex_unlock(&peer->lock);

	mutex_lock(&dev->lock);

	rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len);
	if (rc) {
		DEV_ERR(dev, "Can't set remote general bytes");
		mutex_unlock(&dev->lock);
		return rc;
	}

	rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_ACTIVE,
				NFC_RF_INITIATOR);

	mutex_unlock(&dev->lock);

	return rc;
}

static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);

	DEV_DBG(dev, "\n");

	nfcsim_cleanup_dev(dev, 0);

	return 0;
}

static int nfcsim_start_poll(struct nfc_dev *nfc_dev,
			     u32 im_protocols, u32 tm_protocols)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
	int rc;

	mutex_lock(&dev->lock);

	if (dev->polling_mode != NFCSIM_POLL_NONE) {
		DEV_ERR(dev, "Already in polling mode");
		rc = -EBUSY;
		goto exit;
	}

	if (im_protocols & NFC_PROTO_NFC_DEP_MASK)
		dev->polling_mode |= NFCSIM_POLL_INITIATOR;

	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK)
		dev->polling_mode |= NFCSIM_POLL_TARGET;

	if (dev->polling_mode == NFCSIM_POLL_NONE) {
		DEV_ERR(dev, "Unsupported polling mode");
		rc = -EINVAL;
		goto exit;
	}

	dev->initiator = 0;
	dev->curr_polling_mode = NFCSIM_POLL_NONE;

	queue_delayed_work(wq, &dev->poll_work, 0);

	DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X\n", im_protocols,
		tm_protocols);

	rc = 0;
exit:
	mutex_unlock(&dev->lock);

	return rc;
}

static void nfcsim_stop_poll(struct nfc_dev *nfc_dev)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);

	DEV_DBG(dev, "Stop poll\n");

	mutex_lock(&dev->lock);

	dev->polling_mode = NFCSIM_POLL_NONE;

	mutex_unlock(&dev->lock);

	cancel_delayed_work_sync(&dev->poll_work);
}

static int nfcsim_activate_target(struct nfc_dev *nfc_dev,
				  struct nfc_target *target, u32 protocol)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);

	DEV_DBG(dev, "\n");

	return -ENOTSUPP;
}

static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev,
				     struct nfc_target *target)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);

	DEV_DBG(dev, "\n");
}

static void nfcsim_wq_recv(struct work_struct *work)
{
	struct nfcsim *dev = container_of(work, struct nfcsim,
					  recv_work.work);

	mutex_lock(&dev->lock);

	if (dev->shutting_down || !dev->up || !dev->clone_skb) {
		dev_kfree_skb(dev->clone_skb);
		goto exit;
	}

	if (dev->initiator) {
		if (!dev->cb) {
			DEV_ERR(dev, "Null recv callback");
			dev_kfree_skb(dev->clone_skb);
			goto exit;
		}

		dev->cb(dev->cb_context, dev->clone_skb, 0);
		dev->cb = NULL;
	} else {
		nfc_tm_data_received(dev->nfc_dev, dev->clone_skb);
	}

exit:
	dev->clone_skb = NULL;

	mutex_unlock(&dev->lock);
}

static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target,
		     struct sk_buff *skb, data_exchange_cb_t cb,
		     void *cb_context)
{
	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
	struct nfcsim *peer = dev->peer_dev;
	int err;

	mutex_lock(&dev->lock);

	if (dev->shutting_down || !dev->up) {
		mutex_unlock(&dev->lock);
		err = -ENODEV;
		goto exit;
	}

	dev->cb = cb;
	dev->cb_context = cb_context;

	mutex_unlock(&dev->lock);

	mutex_lock(&peer->lock);

	peer->clone_skb = skb_clone(skb, GFP_KERNEL);

	if (!peer->clone_skb) {
		DEV_ERR(dev, "skb_clone failed");
		mutex_unlock(&peer->lock);
		err = -ENOMEM;
		goto exit;
	}

	/* This simulates an arbitrary transmission delay between the 2 devices.
	 * If packet transmission occurs immediately between them, we have a
	 * non-stop flow of several tens of thousands SYMM packets per second
	 * and a burning cpu.
	 *
	 * TODO: Add support for a sysfs entry to control this delay.
	 */
	queue_delayed_work(wq, &peer->recv_work, msecs_to_jiffies(5));

	mutex_unlock(&peer->lock);

	err = 0;
exit:
	dev_kfree_skb(skb);

	return err;
}

static int nfcsim_im_transceive(struct nfc_dev *nfc_dev,
				struct nfc_target *target, struct sk_buff *skb,
				data_exchange_cb_t cb, void *cb_context)
{
	return nfcsim_tx(nfc_dev, target, skb, cb, cb_context);
}

static int nfcsim_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
{
	return nfcsim_tx(nfc_dev, NULL, skb, NULL, NULL);
}

static struct nfc_ops nfcsim_nfc_ops = {
	.dev_up = nfcsim_dev_up,
	.dev_down = nfcsim_dev_down,
	.dep_link_up = nfcsim_dep_link_up,
	.dep_link_down = nfcsim_dep_link_down,
	.start_poll = nfcsim_start_poll,
	.stop_poll = nfcsim_stop_poll,
	.activate_target = nfcsim_activate_target,
	.deactivate_target = nfcsim_deactivate_target,
	.im_transceive = nfcsim_im_transceive,
	.tm_send = nfcsim_tm_send,
};

static void nfcsim_set_polling_mode(struct nfcsim *dev)
{
	if (dev->polling_mode == NFCSIM_POLL_NONE) {
		dev->curr_polling_mode = NFCSIM_POLL_NONE;
		return;
	}

	if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
		if (dev->polling_mode & NFCSIM_POLL_INITIATOR)
			dev->curr_polling_mode = NFCSIM_POLL_INITIATOR;
		else
			dev->curr_polling_mode = NFCSIM_POLL_TARGET;

		return;
	}

	if (dev->polling_mode == NFCSIM_POLL_DUAL) {
		if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
			dev->curr_polling_mode = NFCSIM_POLL_INITIATOR;
		else
			dev->curr_polling_mode = NFCSIM_POLL_TARGET;
	}
}

static void nfcsim_wq_poll(struct work_struct *work)
{
	struct nfcsim *dev = container_of(work, struct nfcsim, poll_work.work);
	struct nfcsim *peer = dev->peer_dev;

	/* These work items run on an ordered workqueue and are therefore
	 * serialized. So we can take both mutexes without being dead locked.
	 */
	mutex_lock(&dev->lock);
	mutex_lock(&peer->lock);

	nfcsim_set_polling_mode(dev);

	if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
		DEV_DBG(dev, "Not polling\n");
		goto unlock;
	}

	DEV_DBG(dev, "Polling as %s",
		dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ?
		"initiator\n" : "target\n");

	if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
		goto sched_work;

	if (peer->curr_polling_mode == NFCSIM_POLL_TARGET) {
		peer->polling_mode = NFCSIM_POLL_NONE;
		dev->polling_mode = NFCSIM_POLL_NONE;

		dev->initiator = 1;

		nfcsim_target_found(dev);

		goto unlock;
	}

sched_work:
	/* This defines the delay for an initiator to check if the other device
	 * is polling in target mode.
	 * If the device starts in dual mode polling, it switches between
	 * initiator and target at every round.
	 * Because the wq is ordered and only 1 work item is executed at a time,
	 * we'll always have one device polling as initiator and the other as
	 * target at some point, even if both are started in dual mode.
	 */
	queue_delayed_work(wq, &dev->poll_work, msecs_to_jiffies(200));

unlock:
	mutex_unlock(&peer->lock);
	mutex_unlock(&dev->lock);
}

static struct nfcsim *nfcsim_init_dev(void)
{
	struct nfcsim *dev;
	int rc = -ENOMEM;

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

	mutex_init(&dev->lock);

	INIT_DELAYED_WORK(&dev->recv_work, nfcsim_wq_recv);
	INIT_DELAYED_WORK(&dev->poll_work, nfcsim_wq_poll);

	dev->nfc_dev = nfc_allocate_device(&nfcsim_nfc_ops,
					   NFC_PROTO_NFC_DEP_MASK,
					   0, 0);
	if (!dev->nfc_dev)
		goto error;

	nfc_set_drvdata(dev->nfc_dev, dev);

	rc = nfc_register_device(dev->nfc_dev);
	if (rc)
		goto free_nfc_dev;

	return dev;

free_nfc_dev:
	nfc_free_device(dev->nfc_dev);

error:
	kfree(dev);

	return ERR_PTR(rc);
}

static void nfcsim_free_device(struct nfcsim *dev)
{
	nfc_unregister_device(dev->nfc_dev);

	nfc_free_device(dev->nfc_dev);

	kfree(dev);
}

static int __init nfcsim_init(void)
{
	int rc;

	/* We need an ordered wq to ensure that poll_work items are executed
	 * one at a time.
	 */
	wq = alloc_ordered_workqueue("nfcsim", 0);
	if (!wq) {
		rc = -ENOMEM;
		goto exit;
	}

	dev0 = nfcsim_init_dev();
	if (IS_ERR(dev0)) {
		rc = PTR_ERR(dev0);
		goto exit;
	}

	dev1 = nfcsim_init_dev();
	if (IS_ERR(dev1)) {
		kfree(dev0);

		rc = PTR_ERR(dev1);
		goto exit;
	}

	dev0->peer_dev = dev1;
	dev1->peer_dev = dev0;

	pr_debug("NFCsim " NFCSIM_VERSION " initialized\n");

	rc = 0;
exit:
	if (rc)
		pr_err("Failed to initialize nfcsim driver (%d)\n",
		       rc);

	return rc;
}

static void __exit nfcsim_exit(void)
{
	nfcsim_cleanup_dev(dev0, 1);
	nfcsim_cleanup_dev(dev1, 1);

	nfcsim_free_device(dev0);
	nfcsim_free_device(dev1);

	destroy_workqueue(wq);
}

module_init(nfcsim_init);
module_exit(nfcsim_exit);

MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION);
MODULE_VERSION(NFCSIM_VERSION);
MODULE_LICENSE("GPL");
