/*
 *  Texas Instrument's NFC Driver For Shared Transport.
 *
 *  NFC Driver acts as interface between NCI core and
 *  TI Shared Transport Layer.
 *
 *  Copyright (C) 2011 Texas Instruments, Inc.
 *
 *  Written by Ilan Elias <ilane@ti.com>
 *
 *  Acknowledgements:
 *  This file is based on btwilink.c, which was written
 *  by Raja Mani and Pavan Savoy.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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, see <http://www.gnu.org/licenses/>.
 *
 */
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/firmware.h>
#include <linux/nfc.h>
#include <net/nfc/nci.h>
#include <net/nfc/nci_core.h>
#include <linux/ti_wilink_st.h>

#define NFCWILINK_CHNL			12
#define NFCWILINK_OPCODE		7
#define NFCWILINK_MAX_FRAME_SIZE	300
#define NFCWILINK_HDR_LEN		4
#define NFCWILINK_OFFSET_LEN_IN_HDR	1
#define NFCWILINK_LEN_SIZE		2
#define NFCWILINK_REGISTER_TIMEOUT	8000	/* 8 sec */
#define NFCWILINK_CMD_TIMEOUT		5000	/* 5 sec */

#define BTS_FILE_NAME_MAX_SIZE		40
#define BTS_FILE_HDR_MAGIC		0x42535442
#define BTS_FILE_CMD_MAX_LEN		0xff
#define BTS_FILE_ACTION_TYPE_SEND_CMD	1

#define NCI_VS_NFCC_INFO_CMD_GID	0x2f
#define NCI_VS_NFCC_INFO_CMD_OID	0x12
#define NCI_VS_NFCC_INFO_RSP_GID	0x4f
#define NCI_VS_NFCC_INFO_RSP_OID	0x12

struct nfcwilink_hdr {
	__u8 chnl;
	__u8 opcode;
	__le16 len;
} __packed;

struct nci_vs_nfcc_info_cmd {
	__u8 gid;
	__u8 oid;
	__u8 plen;
} __packed;

struct nci_vs_nfcc_info_rsp {
	__u8 gid;
	__u8 oid;
	__u8 plen;
	__u8 status;
	__u8 hw_id;
	__u8 sw_ver_x;
	__u8 sw_ver_z;
	__u8 patch_id;
} __packed;

struct bts_file_hdr {
	__le32 magic;
	__le32 ver;
	__u8 rfu[24];
	__u8 actions[0];
} __packed;

struct bts_file_action {
	__le16 type;
	__le16 len;
	__u8 data[0];
} __packed;

struct nfcwilink {
	struct platform_device		*pdev;
	struct nci_dev			*ndev;
	unsigned long			flags;

	int				st_register_cb_status;
	long				(*st_write) (struct sk_buff *);

	struct completion		completed;

	struct nci_vs_nfcc_info_rsp	nfcc_info;
};

/* NFCWILINK driver flags */
enum {
	NFCWILINK_RUNNING,
	NFCWILINK_FW_DOWNLOAD,
};

static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb);

static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how)
{
	struct sk_buff *skb;

	skb = alloc_skb(len + NFCWILINK_HDR_LEN, how);
	if (skb)
		skb_reserve(skb, NFCWILINK_HDR_LEN);

	return skb;
}

static void nfcwilink_fw_download_receive(struct nfcwilink *drv,
						struct sk_buff *skb)
{
	struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data;

	/* Detect NCI_VS_NFCC_INFO_RSP and store the result */
	if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) &&
		(rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) {
		memcpy(&drv->nfcc_info, rsp,
			sizeof(struct nci_vs_nfcc_info_rsp));
	}

	kfree_skb(skb);

	complete(&drv->completed);
}

static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
{
	struct nci_vs_nfcc_info_cmd *cmd;
	struct sk_buff *skb;
	unsigned long comp_ret;
	int rc;

	skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd),
					GFP_KERNEL);
	if (!skb) {
		nfc_err(&drv->pdev->dev,
			"no memory for nci_vs_nfcc_info_cmd\n");
		return -ENOMEM;
	}

	cmd = (struct nci_vs_nfcc_info_cmd *)
			skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd));
	cmd->gid = NCI_VS_NFCC_INFO_CMD_GID;
	cmd->oid = NCI_VS_NFCC_INFO_CMD_OID;
	cmd->plen = 0;

	drv->nfcc_info.plen = 0;

	rc = nfcwilink_send(drv->ndev, skb);
	if (rc)
		return rc;

	comp_ret = wait_for_completion_timeout(&drv->completed,
				msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
	dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n",
		comp_ret);
	if (comp_ret == 0) {
		nfc_err(&drv->pdev->dev,
			"timeout on wait_for_completion_timeout\n");
		return -ETIMEDOUT;
	}

	dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d\n",
		drv->nfcc_info.plen, drv->nfcc_info.status);

	if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) {
		nfc_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp\n");
		return -EINVAL;
	}

	snprintf(file_name, BTS_FILE_NAME_MAX_SIZE,
			"TINfcInit_%d.%d.%d.%d.bts",
			drv->nfcc_info.hw_id,
			drv->nfcc_info.sw_ver_x,
			drv->nfcc_info.sw_ver_z,
			drv->nfcc_info.patch_id);

	nfc_info(&drv->pdev->dev, "nfcwilink FW file name: %s\n", file_name);

	return 0;
}

static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
{
	struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data;
	struct sk_buff *skb;
	unsigned long comp_ret;
	int rc;

	/* verify valid cmd for the NFC channel */
	if ((len <= sizeof(struct nfcwilink_hdr)) ||
		(len > BTS_FILE_CMD_MAX_LEN) ||
		(hdr->chnl != NFCWILINK_CHNL) ||
		(hdr->opcode != NFCWILINK_OPCODE)) {
		nfc_err(&drv->pdev->dev,
			"ignoring invalid bts cmd, len %d, chnl %d, opcode %d\n",
			len, hdr->chnl, hdr->opcode);
		return 0;
	}

	/* remove the ST header */
	len -= sizeof(struct nfcwilink_hdr);
	data += sizeof(struct nfcwilink_hdr);

	skb = nfcwilink_skb_alloc(len, GFP_KERNEL);
	if (!skb) {
		nfc_err(&drv->pdev->dev, "no memory for bts cmd\n");
		return -ENOMEM;
	}

	memcpy(skb_put(skb, len), data, len);

	rc = nfcwilink_send(drv->ndev, skb);
	if (rc)
		return rc;

	comp_ret = wait_for_completion_timeout(&drv->completed,
				msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
	dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n",
		comp_ret);
	if (comp_ret == 0) {
		nfc_err(&drv->pdev->dev,
			"timeout on wait_for_completion_timeout\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static int nfcwilink_download_fw(struct nfcwilink *drv)
{
	unsigned char file_name[BTS_FILE_NAME_MAX_SIZE];
	const struct firmware *fw;
	__u16 action_type, action_len;
	__u8 *ptr;
	int len, rc;

	set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);

	rc = nfcwilink_get_bts_file_name(drv, file_name);
	if (rc)
		goto exit;

	rc = request_firmware(&fw, file_name, &drv->pdev->dev);
	if (rc) {
		nfc_err(&drv->pdev->dev, "request_firmware failed %d\n", rc);

		/* if the file is not found, don't exit with failure */
		if (rc == -ENOENT)
			rc = 0;

		goto exit;
	}

	len = fw->size;
	ptr = (__u8 *)fw->data;

	if ((len == 0) || (ptr == NULL)) {
		dev_dbg(&drv->pdev->dev,
			"request_firmware returned size %d\n", len);
		goto release_fw;
	}

	if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) !=
			BTS_FILE_HDR_MAGIC) {
		nfc_err(&drv->pdev->dev, "wrong bts magic number\n");
		rc = -EINVAL;
		goto release_fw;
	}

	/* remove the BTS header */
	len -= sizeof(struct bts_file_hdr);
	ptr += sizeof(struct bts_file_hdr);

	while (len > 0) {
		action_type =
			__le16_to_cpu(((struct bts_file_action *)ptr)->type);
		action_len =
			__le16_to_cpu(((struct bts_file_action *)ptr)->len);

		dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d\n",
			action_type, action_len);

		switch (action_type) {
		case BTS_FILE_ACTION_TYPE_SEND_CMD:
			rc = nfcwilink_send_bts_cmd(drv,
					((struct bts_file_action *)ptr)->data,
					action_len);
			if (rc)
				goto release_fw;
			break;
		}

		/* advance to the next action */
		len -= (sizeof(struct bts_file_action) + action_len);
		ptr += (sizeof(struct bts_file_action) + action_len);
	}

release_fw:
	release_firmware(fw);

exit:
	clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
	return rc;
}

/* Called by ST when registration is complete */
static void nfcwilink_register_complete(void *priv_data, int data)
{
	struct nfcwilink *drv = priv_data;

	/* store ST registration status */
	drv->st_register_cb_status = data;

	/* complete the wait in nfc_st_open() */
	complete(&drv->completed);
}

/* Called by ST when receive data is available */
static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
{
	struct nfcwilink *drv = priv_data;
	int rc;

	if (!skb)
		return -EFAULT;

	if (!drv) {
		kfree_skb(skb);
		return -EFAULT;
	}

	dev_dbg(&drv->pdev->dev, "receive entry, len %d\n", skb->len);

	/* strip the ST header
	(apart for the chnl byte, which is not received in the hdr) */
	skb_pull(skb, (NFCWILINK_HDR_LEN-1));

	if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) {
		nfcwilink_fw_download_receive(drv, skb);
		return 0;
	}

	/* Forward skb to NCI core layer */
	rc = nci_recv_frame(drv->ndev, skb);
	if (rc < 0) {
		nfc_err(&drv->pdev->dev, "nci_recv_frame failed %d\n", rc);
		return rc;
	}

	return 0;
}

/* protocol structure registered with ST */
static struct st_proto_s nfcwilink_proto = {
	.chnl_id = NFCWILINK_CHNL,
	.max_frame_size = NFCWILINK_MAX_FRAME_SIZE,
	.hdr_len = (NFCWILINK_HDR_LEN-1),	/* not including chnl byte */
	.offset_len_in_hdr = NFCWILINK_OFFSET_LEN_IN_HDR,
	.len_size = NFCWILINK_LEN_SIZE,
	.reserve = 0,
	.recv = nfcwilink_receive,
	.reg_complete_cb = nfcwilink_register_complete,
	.write = NULL,
};

static int nfcwilink_open(struct nci_dev *ndev)
{
	struct nfcwilink *drv = nci_get_drvdata(ndev);
	unsigned long comp_ret;
	int rc;

	if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) {
		rc = -EBUSY;
		goto exit;
	}

	nfcwilink_proto.priv_data = drv;

	init_completion(&drv->completed);
	drv->st_register_cb_status = -EINPROGRESS;

	rc = st_register(&nfcwilink_proto);
	if (rc < 0) {
		if (rc == -EINPROGRESS) {
			comp_ret = wait_for_completion_timeout(
			&drv->completed,
			msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT));

			dev_dbg(&drv->pdev->dev,
				"wait_for_completion_timeout returned %ld\n",
				comp_ret);

			if (comp_ret == 0) {
				/* timeout */
				rc = -ETIMEDOUT;
				goto clear_exit;
			} else if (drv->st_register_cb_status != 0) {
				rc = drv->st_register_cb_status;
				nfc_err(&drv->pdev->dev,
					"st_register_cb failed %d\n", rc);
				goto clear_exit;
			}
		} else {
			nfc_err(&drv->pdev->dev, "st_register failed %d\n", rc);
			goto clear_exit;
		}
	}

	/* st_register MUST fill the write callback */
	BUG_ON(nfcwilink_proto.write == NULL);
	drv->st_write = nfcwilink_proto.write;

	if (nfcwilink_download_fw(drv)) {
		nfc_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d\n",
			rc);
		/* open should succeed, even if the FW download failed */
	}

	goto exit;

clear_exit:
	clear_bit(NFCWILINK_RUNNING, &drv->flags);

exit:
	return rc;
}

static int nfcwilink_close(struct nci_dev *ndev)
{
	struct nfcwilink *drv = nci_get_drvdata(ndev);
	int rc;

	if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags))
		return 0;

	rc = st_unregister(&nfcwilink_proto);
	if (rc)
		nfc_err(&drv->pdev->dev, "st_unregister failed %d\n", rc);

	drv->st_write = NULL;

	return rc;
}

static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb)
{
	struct nfcwilink *drv = nci_get_drvdata(ndev);
	struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000};
	long len;

	dev_dbg(&drv->pdev->dev, "send entry, len %d\n", skb->len);

	if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) {
		kfree_skb(skb);
		return -EINVAL;
	}

	/* add the ST hdr to the start of the buffer */
	hdr.len = cpu_to_le16(skb->len);
	memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN);

	/* Insert skb to shared transport layer's transmit queue.
	 * Freeing skb memory is taken care in shared transport layer,
	 * so don't free skb memory here.
	 */
	len = drv->st_write(skb);
	if (len < 0) {
		kfree_skb(skb);
		nfc_err(&drv->pdev->dev, "st_write failed %ld\n", len);
		return -EFAULT;
	}

	return 0;
}

static struct nci_ops nfcwilink_ops = {
	.open = nfcwilink_open,
	.close = nfcwilink_close,
	.send = nfcwilink_send,
};

static int nfcwilink_probe(struct platform_device *pdev)
{
	struct nfcwilink *drv;
	int rc;
	__u32 protocols;

	drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL);
	if (!drv) {
		rc = -ENOMEM;
		goto exit;
	}

	drv->pdev = pdev;

	protocols = NFC_PROTO_JEWEL_MASK
		| NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK
		| NFC_PROTO_ISO14443_MASK
		| NFC_PROTO_ISO14443_B_MASK
		| NFC_PROTO_NFC_DEP_MASK;

	drv->ndev = nci_allocate_device(&nfcwilink_ops,
					protocols,
					NFCWILINK_HDR_LEN,
					0);
	if (!drv->ndev) {
		nfc_err(&pdev->dev, "nci_allocate_device failed\n");
		rc = -ENOMEM;
		goto exit;
	}

	nci_set_parent_dev(drv->ndev, &pdev->dev);
	nci_set_drvdata(drv->ndev, drv);

	rc = nci_register_device(drv->ndev);
	if (rc < 0) {
		nfc_err(&pdev->dev, "nci_register_device failed %d\n", rc);
		goto free_dev_exit;
	}

	dev_set_drvdata(&pdev->dev, drv);

	goto exit;

free_dev_exit:
	nci_free_device(drv->ndev);

exit:
	return rc;
}

static int nfcwilink_remove(struct platform_device *pdev)
{
	struct nfcwilink *drv = dev_get_drvdata(&pdev->dev);
	struct nci_dev *ndev;

	if (!drv)
		return -EFAULT;

	ndev = drv->ndev;

	nci_unregister_device(ndev);
	nci_free_device(ndev);

	return 0;
}

static struct platform_driver nfcwilink_driver = {
	.probe = nfcwilink_probe,
	.remove = nfcwilink_remove,
	.driver = {
		.name = "nfcwilink",
	},
};

module_platform_driver(nfcwilink_driver);

/* ------ Module Info ------ */

MODULE_AUTHOR("Ilan Elias <ilane@ti.com>");
MODULE_DESCRIPTION("NFC Driver for TI Shared Transport");
MODULE_LICENSE("GPL");
