/*
 *  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;

	char				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, char 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");
