/*
 * HCI based Driver for STMicroelectronics NFC Chip
 *
 * Copyright (C) 2014  STMicroelectronics SAS. All rights reserved.
 *
 * 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 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/module.h>
#include <linux/nfc.h>
#include <net/nfc/hci.h>
#include <net/nfc/llc.h>

#include "st21nfca.h"

#define DRIVER_DESC "HCI NFC driver for ST21NFCA"

#define FULL_VERSION_LEN 3

/* Proprietary gates, events, commands and registers */

/* Commands that apply to all RF readers */
#define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK	0x30

#define ST21NFCA_RF_READER_ISO15693_GATE	0x12
#define ST21NFCA_RF_READER_ISO15693_INVENTORY	0x01

/*
 * Reader gate for communication with contact-less cards using Type A
 * protocol ISO14443-3 but not compliant with ISO14443-4
 */
#define ST21NFCA_RF_READER_14443_3_A_GATE	0x15
#define ST21NFCA_RF_READER_14443_3_A_UID	0x02
#define ST21NFCA_RF_READER_14443_3_A_ATQA	0x03
#define ST21NFCA_RF_READER_14443_3_A_SAK	0x04

#define ST21NFCA_RF_READER_F_DATARATE		0x01
#define ST21NFCA_RF_READER_F_DATARATE_106	0x01
#define ST21NFCA_RF_READER_F_DATARATE_212	0x02
#define ST21NFCA_RF_READER_F_DATARATE_424	0x04
#define ST21NFCA_RF_READER_F_POL_REQ		0x02
#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT	0xffff0000
#define ST21NFCA_RF_READER_F_NFCID2		0x03
#define ST21NFCA_RF_READER_F_NFCID1		0x04

#define ST21NFCA_RF_CARD_F_MODE			0x01
#define ST21NFCA_RF_CARD_F_NFCID2_LIST		0x04
#define ST21NFCA_RF_CARD_F_NFCID1		0x05
#define ST21NFCA_RF_CARD_F_SENS_RES		0x06
#define ST21NFCA_RF_CARD_F_SEL_RES		0x07
#define ST21NFCA_RF_CARD_F_DATARATE		0x08
#define ST21NFCA_RF_CARD_F_DATARATE_212_424	0x01

#define ST21NFCA_DEVICE_MGNT_PIPE		0x02

#define ST21NFCA_DM_GETINFO			0x13
#define ST21NFCA_DM_GETINFO_PIPE_LIST		0x02
#define ST21NFCA_DM_GETINFO_PIPE_INFO		0x01
#define ST21NFCA_DM_PIPE_CREATED		0x02
#define ST21NFCA_DM_PIPE_OPEN			0x04
#define ST21NFCA_DM_RF_ACTIVE			0x80
#define ST21NFCA_DM_DISCONNECT			0x30

#define ST21NFCA_DM_IS_PIPE_OPEN(p) \
	((p & 0x0f) == (ST21NFCA_DM_PIPE_CREATED | ST21NFCA_DM_PIPE_OPEN))

#define ST21NFCA_NFC_MODE			0x03	/* NFC_MODE parameter*/

#define ST21NFCA_EVT_HOT_PLUG			0x03
#define ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80)

#define ST21NFCA_SE_TO_PIPES			2000

static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES);

static struct nfc_hci_gate st21nfca_gates[] = {
	{NFC_HCI_ADMIN_GATE, NFC_HCI_ADMIN_PIPE},
	{NFC_HCI_LINK_MGMT_GATE, NFC_HCI_LINK_MGMT_PIPE},
	{ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE},

	{NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE},
	{ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
	{ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE},
	{ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
	{ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE},

	/* Secure element pipes are created by secure element host */
	{ST21NFCA_CONNECTIVITY_GATE, NFC_HCI_DO_NOT_CREATE_PIPE},
	{ST21NFCA_APDU_READER_GATE, NFC_HCI_DO_NOT_CREATE_PIPE},
};

struct st21nfca_pipe_info {
	u8 pipe_state;
	u8 src_host_id;
	u8 src_gate_id;
	u8 dst_host_id;
	u8 dst_gate_id;
} __packed;

/* Largest headroom needed for outgoing custom commands */
#define ST21NFCA_CMDS_HEADROOM  7

static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev)
{
	int i, j, r;
	struct sk_buff *skb_pipe_list, *skb_pipe_info;
	struct st21nfca_pipe_info *info;

	u8 pipe_list[] = { ST21NFCA_DM_GETINFO_PIPE_LIST,
		NFC_HCI_TERMINAL_HOST_ID
	};
	u8 pipe_info[] = { ST21NFCA_DM_GETINFO_PIPE_INFO,
		NFC_HCI_TERMINAL_HOST_ID, 0
	};

	/* On ST21NFCA device pipes number are dynamics
	 * A maximum of 16 pipes can be created at the same time
	 * If pipes are already created, hci_dev_up will fail.
	 * Doing a clear all pipe is a bad idea because:
	 * - It does useless EEPROM cycling
	 * - It might cause issue for secure elements support
	 * (such as removing connectivity or APDU reader pipe)
	 * A better approach on ST21NFCA is to:
	 * - get a pipe list for each host.
	 * (eg: NFC_HCI_HOST_CONTROLLER_ID for now).
	 * (TODO Later on UICC HOST and eSE HOST)
	 * - get pipe information
	 * - match retrieved pipe list in st21nfca_gates
	 * ST21NFCA_DEVICE_MGNT_GATE is a proprietary gate
	 * with ST21NFCA_DEVICE_MGNT_PIPE.
	 * Pipe can be closed and need to be open.
	 */
	r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
				ST21NFCA_DEVICE_MGNT_GATE,
				ST21NFCA_DEVICE_MGNT_PIPE);
	if (r < 0)
		return r;

	/* Get pipe list */
	r = nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
			ST21NFCA_DM_GETINFO, pipe_list, sizeof(pipe_list),
			&skb_pipe_list);
	if (r < 0)
		return r;

	/* Complete the existing gate_pipe table */
	for (i = 0; i < skb_pipe_list->len; i++) {
		pipe_info[2] = skb_pipe_list->data[i];
		r = nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
					ST21NFCA_DM_GETINFO, pipe_info,
					sizeof(pipe_info), &skb_pipe_info);
		if (r)
			continue;

		/*
		 * Match pipe ID and gate ID
		 * Output format from ST21NFC_DM_GETINFO is:
		 * - pipe state (1byte)
		 * - source hid (1byte)
		 * - source gid (1byte)
		 * - destination hid (1byte)
		 * - destination gid (1byte)
		 */
		info = (struct st21nfca_pipe_info *) skb_pipe_info->data;
		if (info->dst_gate_id == ST21NFCA_APDU_READER_GATE &&
			info->src_host_id == NFC_HCI_UICC_HOST_ID) {
			pr_err("Unexpected apdu_reader pipe on host %x\n",
				info->src_host_id);
			kfree_skb(skb_pipe_info);
			continue;
		}

		for (j = 3; (j < ARRAY_SIZE(st21nfca_gates)) &&
			(st21nfca_gates[j].gate != info->dst_gate_id) ; j++)
			;

		if (j < ARRAY_SIZE(st21nfca_gates) &&
			st21nfca_gates[j].gate == info->dst_gate_id &&
			ST21NFCA_DM_IS_PIPE_OPEN(info->pipe_state)) {
			hdev->init_data.gates[j].pipe = pipe_info[2];

			hdev->gate2pipe[st21nfca_gates[j].gate] =
						pipe_info[2];
			hdev->pipes[pipe_info[2]].gate =
						st21nfca_gates[j].gate;
			hdev->pipes[pipe_info[2]].dest_host =
						info->src_host_id;
		}
		kfree_skb(skb_pipe_info);
	}

	/*
	 * 3 gates have a well known pipe ID. Only NFC_HCI_LINK_MGMT_GATE
	 * is not yet open at this stage.
	 */
	r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
				 NFC_HCI_LINK_MGMT_GATE,
				 NFC_HCI_LINK_MGMT_PIPE);

	kfree_skb(skb_pipe_list);
	return r;
}

static int st21nfca_hci_open(struct nfc_hci_dev *hdev)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
	int r;

	mutex_lock(&info->info_lock);

	if (info->state != ST21NFCA_ST_COLD) {
		r = -EBUSY;
		goto out;
	}

	r = info->phy_ops->enable(info->phy_id);

	if (r == 0)
		info->state = ST21NFCA_ST_READY;

out:
	mutex_unlock(&info->info_lock);
	return r;
}

static void st21nfca_hci_close(struct nfc_hci_dev *hdev)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	mutex_lock(&info->info_lock);

	if (info->state == ST21NFCA_ST_COLD)
		goto out;

	info->phy_ops->disable(info->phy_id);
	info->state = ST21NFCA_ST_COLD;

out:
	mutex_unlock(&info->info_lock);
}

static int st21nfca_hci_ready(struct nfc_hci_dev *hdev)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
	struct sk_buff *skb;

	u8 param;
	u8 white_list[2];
	int wl_size = 0;
	int r;

	if (info->se_status->is_uicc_present)
		white_list[wl_size++] = NFC_HCI_UICC_HOST_ID;
	if (info->se_status->is_ese_present)
		white_list[wl_size++] = ST21NFCA_ESE_HOST_ID;

	if (wl_size) {
		r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE,
					NFC_HCI_ADMIN_WHITELIST,
					(u8 *) &white_list, wl_size);
		if (r < 0)
			return r;
	}

	/* Set NFC_MODE in device management gate to enable */
	r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE,
			      ST21NFCA_NFC_MODE, &skb);
	if (r < 0)
		return r;

	param = skb->data[0];
	kfree_skb(skb);
	if (param == 0) {
		param = 1;

		r = nfc_hci_set_param(hdev, ST21NFCA_DEVICE_MGNT_GATE,
					ST21NFCA_NFC_MODE, &param, 1);
		if (r < 0)
			return r;
	}

	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
			       NFC_HCI_EVT_END_OPERATION, NULL, 0);
	if (r < 0)
		return r;

	r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
			      NFC_HCI_ID_MGMT_VERSION_SW, &skb);
	if (r < 0)
		return r;

	if (skb->len != FULL_VERSION_LEN) {
		kfree_skb(skb);
		return -EINVAL;
	}

	print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ",
		       DUMP_PREFIX_NONE, 16, 1,
		       skb->data, FULL_VERSION_LEN, false);

	kfree_skb(skb);

	return 0;
}

static int st21nfca_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	return info->phy_ops->write(info->phy_id, skb);
}

static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
				   u32 im_protocols, u32 tm_protocols)
{
	int r;
	u32 pol_req;
	u8 param[19];
	struct sk_buff *datarate_skb;

	pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n",
		__func__, im_protocols, tm_protocols);

	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
			       NFC_HCI_EVT_END_OPERATION, NULL, 0);
	if (r < 0)
		return r;
	if (im_protocols) {
		/*
		 * enable polling according to im_protocols & tm_protocols
		 * - CLOSE pipe according to im_protocols & tm_protocols
		 */
		if ((NFC_HCI_RF_READER_B_GATE & im_protocols) == 0) {
			r = nfc_hci_disconnect_gate(hdev,
					NFC_HCI_RF_READER_B_GATE);
			if (r < 0)
				return r;
		}

		if ((NFC_HCI_RF_READER_A_GATE & im_protocols) == 0) {
			r = nfc_hci_disconnect_gate(hdev,
					NFC_HCI_RF_READER_A_GATE);
			if (r < 0)
				return r;
		}

		if ((ST21NFCA_RF_READER_F_GATE & im_protocols) == 0) {
			r = nfc_hci_disconnect_gate(hdev,
					ST21NFCA_RF_READER_F_GATE);
			if (r < 0)
				return r;
		} else {
			hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
							       &hdev->gb_len);

			if (hdev->gb == NULL || hdev->gb_len == 0) {
				im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
				tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
			}

			param[0] = ST21NFCA_RF_READER_F_DATARATE_106 |
			    ST21NFCA_RF_READER_F_DATARATE_212 |
			    ST21NFCA_RF_READER_F_DATARATE_424;
			r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
					      ST21NFCA_RF_READER_F_DATARATE,
					      param, 1);
			if (r < 0)
				return r;

			pol_req = be32_to_cpu((__force __be32)
					ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
			r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
					      ST21NFCA_RF_READER_F_POL_REQ,
					      (u8 *) &pol_req, 4);
			if (r < 0)
				return r;
		}

		if ((ST21NFCA_RF_READER_14443_3_A_GATE & im_protocols) == 0) {
			r = nfc_hci_disconnect_gate(hdev,
					ST21NFCA_RF_READER_14443_3_A_GATE);
			if (r < 0)
				return r;
		}

		if ((ST21NFCA_RF_READER_ISO15693_GATE & im_protocols) == 0) {
			r = nfc_hci_disconnect_gate(hdev,
					ST21NFCA_RF_READER_ISO15693_GATE);
			if (r < 0)
				return r;
		}

		r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
				       NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
		if (r < 0)
			nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
					   NFC_HCI_EVT_END_OPERATION, NULL, 0);
	}

	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
		r = nfc_hci_get_param(hdev, ST21NFCA_RF_CARD_F_GATE,
				      ST21NFCA_RF_CARD_F_DATARATE,
				      &datarate_skb);
		if (r < 0)
			return r;

		/* Configure the maximum supported datarate to 424Kbps */
		if (datarate_skb->len > 0 &&
		    datarate_skb->data[0] !=
		    ST21NFCA_RF_CARD_F_DATARATE_212_424) {
			param[0] = ST21NFCA_RF_CARD_F_DATARATE_212_424;
			r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
					      ST21NFCA_RF_CARD_F_DATARATE,
					      param, 1);
			if (r < 0) {
				kfree_skb(datarate_skb);
				return r;
			}
		}
		kfree_skb(datarate_skb);

		/*
		 * Configure sens_res
		 *
		 * NFC Forum Digital Spec Table 7:
		 * NFCID1 size: triple (10 bytes)
		 */
		param[0] = 0x00;
		param[1] = 0x08;
		r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
				      ST21NFCA_RF_CARD_F_SENS_RES, param, 2);
		if (r < 0)
			return r;

		/*
		 * Configure sel_res
		 *
		 * NFC Forum Digistal Spec Table 17:
		 * b3 set to 0b (value b7-b6):
		 * - 10b: Configured for NFC-DEP Protocol
		 */
		param[0] = 0x40;
		r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
				      ST21NFCA_RF_CARD_F_SEL_RES, param, 1);
		if (r < 0)
			return r;

		/* Configure NFCID1 Random uid */
		r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
				      ST21NFCA_RF_CARD_F_NFCID1, NULL, 0);
		if (r < 0)
			return r;

		/* Configure NFCID2_LIST */
		/* System Code */
		param[0] = 0x00;
		param[1] = 0x00;
		/* NFCID2 */
		param[2] = 0x01;
		param[3] = 0xfe;
		param[4] = 'S';
		param[5] = 'T';
		param[6] = 'M';
		param[7] = 'i';
		param[8] = 'c';
		param[9] = 'r';
		/* 8 byte Pad bytes used for polling respone frame */

		/*
		 * Configuration byte:
		 * - bit 0: define the default NFCID2 entry used when the
		 * system code is equal to 'FFFF'
		 * - bit 1: use a random value for lowest 6 bytes of
		 * NFCID2 value
		 * - bit 2: ignore polling request frame if request code
		 * is equal to '01'
		 * - Other bits are RFU
		 */
		param[18] = 0x01;
		r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
				      ST21NFCA_RF_CARD_F_NFCID2_LIST, param,
				      19);
		if (r < 0)
			return r;

		param[0] = 0x02;
		r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
				      ST21NFCA_RF_CARD_F_MODE, param, 1);
	}

	return r;
}

static void st21nfca_hci_stop_poll(struct nfc_hci_dev *hdev)
{
	nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
			ST21NFCA_DM_DISCONNECT, NULL, 0, NULL);
}

static int st21nfca_get_iso14443_3_atqa(struct nfc_hci_dev *hdev, u16 *atqa)
{
	int r;
	struct sk_buff *atqa_skb = NULL;

	r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_14443_3_A_GATE,
			      ST21NFCA_RF_READER_14443_3_A_ATQA, &atqa_skb);
	if (r < 0)
		goto exit;

	if (atqa_skb->len != 2) {
		r = -EPROTO;
		goto exit;
	}

	*atqa = be16_to_cpu(*(__be16 *) atqa_skb->data);

exit:
	kfree_skb(atqa_skb);
	return r;
}

static int st21nfca_get_iso14443_3_sak(struct nfc_hci_dev *hdev, u8 *sak)
{
	int r;
	struct sk_buff *sak_skb = NULL;

	r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_14443_3_A_GATE,
			      ST21NFCA_RF_READER_14443_3_A_SAK, &sak_skb);
	if (r < 0)
		goto exit;

	if (sak_skb->len != 1) {
		r = -EPROTO;
		goto exit;
	}

	*sak = sak_skb->data[0];

exit:
	kfree_skb(sak_skb);
	return r;
}

static int st21nfca_get_iso14443_3_uid(struct nfc_hci_dev *hdev, u8 *uid,
				       int *len)
{
	int r;
	struct sk_buff *uid_skb = NULL;

	r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_14443_3_A_GATE,
			      ST21NFCA_RF_READER_14443_3_A_UID, &uid_skb);
	if (r < 0)
		goto exit;

	if (uid_skb->len == 0 || uid_skb->len > NFC_NFCID1_MAXSIZE) {
		r = -EPROTO;
		goto exit;
	}

	memcpy(uid, uid_skb->data, uid_skb->len);
	*len = uid_skb->len;
exit:
	kfree_skb(uid_skb);
	return r;
}

static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev,
					   struct nfc_target *target)
{
	int r;
	struct sk_buff *inventory_skb = NULL;

	r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_ISO15693_GATE,
			      ST21NFCA_RF_READER_ISO15693_INVENTORY,
			      &inventory_skb);
	if (r < 0)
		goto exit;

	skb_pull(inventory_skb, 2);

	if (inventory_skb->len == 0 ||
	    inventory_skb->len > NFC_ISO15693_UID_MAXSIZE) {
		r = -EPROTO;
		goto exit;
	}

	memcpy(target->iso15693_uid, inventory_skb->data, inventory_skb->len);
	target->iso15693_dsfid	= inventory_skb->data[1];
	target->is_iso15693 = 1;
exit:
	kfree_skb(inventory_skb);
	return r;
}

static int st21nfca_hci_dep_link_up(struct nfc_hci_dev *hdev,
				    struct nfc_target *target, u8 comm_mode,
				    u8 *gb, size_t gb_len)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	info->dep_info.idx = target->idx;
	return st21nfca_im_send_atr_req(hdev, gb, gb_len);
}

static int st21nfca_hci_dep_link_down(struct nfc_hci_dev *hdev)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	info->state = ST21NFCA_ST_READY;

	return nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
				ST21NFCA_DM_DISCONNECT, NULL, 0, NULL);
}

static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
					 struct nfc_target *target)
{
	int r, len;
	u16 atqa;
	u8 sak;
	u8 uid[NFC_NFCID1_MAXSIZE];

	switch (gate) {
	case ST21NFCA_RF_READER_F_GATE:
		target->supported_protocols = NFC_PROTO_FELICA_MASK;
		break;
	case ST21NFCA_RF_READER_14443_3_A_GATE:
		/* ISO14443-3 type 1 or 2 tags */
		r = st21nfca_get_iso14443_3_atqa(hdev, &atqa);
		if (r < 0)
			return r;
		if (atqa == 0x000c) {
			target->supported_protocols = NFC_PROTO_JEWEL_MASK;
			target->sens_res = 0x0c00;
		} else {
			r = st21nfca_get_iso14443_3_sak(hdev, &sak);
			if (r < 0)
				return r;

			r = st21nfca_get_iso14443_3_uid(hdev, uid, &len);
			if (r < 0)
				return r;

			target->supported_protocols =
			    nfc_hci_sak_to_protocol(sak);
			if (target->supported_protocols == 0xffffffff)
				return -EPROTO;

			target->sens_res = atqa;
			target->sel_res = sak;
			memcpy(target->nfcid1, uid, len);
			target->nfcid1_len = len;
		}

		break;
	case ST21NFCA_RF_READER_ISO15693_GATE:
		target->supported_protocols = NFC_PROTO_ISO15693_MASK;
		r = st21nfca_get_iso15693_inventory(hdev, target);
		if (r < 0)
			return r;
		break;
	default:
		return -EPROTO;
	}

	return 0;
}

static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev,
						u8 gate,
						struct nfc_target *target)
{
	int r;
	struct sk_buff *nfcid_skb = NULL;

	if (gate == ST21NFCA_RF_READER_F_GATE) {
		r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
				ST21NFCA_RF_READER_F_NFCID2, &nfcid_skb);
		if (r < 0)
			goto exit;

		if (nfcid_skb->len > NFC_SENSF_RES_MAXSIZE) {
			r = -EPROTO;
			goto exit;
		}

		/*
		 * - After the recepton of polling response for type F frame
		 * at 212 or 424 Kbit/s, NFCID2 registry parameters will be
		 * updated.
		 * - After the reception of SEL_RES with NFCIP-1 compliant bit
		 * set for type A frame NFCID1 will be updated
		 */
		if (nfcid_skb->len > 0) {
			/* P2P in type F */
			memcpy(target->sensf_res, nfcid_skb->data,
				nfcid_skb->len);
			target->sensf_res_len = nfcid_skb->len;
			/* NFC Forum Digital Protocol Table 44 */
			if (target->sensf_res[0] == 0x01 &&
			    target->sensf_res[1] == 0xfe)
				target->supported_protocols =
							NFC_PROTO_NFC_DEP_MASK;
			else
				target->supported_protocols =
							NFC_PROTO_FELICA_MASK;
		} else {
			kfree_skb(nfcid_skb);
			/* P2P in type A */
			r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
					ST21NFCA_RF_READER_F_NFCID1,
					&nfcid_skb);
			if (r < 0)
				goto exit;

			if (nfcid_skb->len > NFC_NFCID1_MAXSIZE) {
				r = -EPROTO;
				goto exit;
			}
			memcpy(target->sensf_res, nfcid_skb->data,
				nfcid_skb->len);
			target->sensf_res_len = nfcid_skb->len;
			target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
		}
		target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE;
	}
	r = 1;
exit:
	kfree_skb(nfcid_skb);
	return r;
}

#define ST21NFCA_CB_TYPE_READER_ISO15693 1
static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb,
					  int err)
{
	struct st21nfca_hci_info *info = context;

	switch (info->async_cb_type) {
	case ST21NFCA_CB_TYPE_READER_ISO15693:
		if (err == 0)
			skb_trim(skb, skb->len - 1);
		info->async_cb(info->async_cb_context, skb, err);
		break;
	default:
		if (err == 0)
			kfree_skb(skb);
		break;
	}
}

/*
 * Returns:
 * <= 0: driver handled the data exchange
 *    1: driver doesn't especially handle, please do standard processing
 */
static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
				      struct nfc_target *target,
				      struct sk_buff *skb,
				      data_exchange_cb_t cb, void *cb_context)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__,
		target->hci_reader_gate, skb->len);

	switch (target->hci_reader_gate) {
	case ST21NFCA_RF_READER_F_GATE:
		if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK)
			return st21nfca_im_send_dep_req(hdev, skb);

		*(u8 *)skb_push(skb, 1) = 0x1a;
		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
					      ST21NFCA_WR_XCHG_DATA, skb->data,
					      skb->len, cb, cb_context);
	case ST21NFCA_RF_READER_14443_3_A_GATE:
		*(u8 *)skb_push(skb, 1) = 0x1a;	/* CTR, see spec:10.2.2.1 */

		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
					      ST21NFCA_WR_XCHG_DATA, skb->data,
					      skb->len, cb, cb_context);
	case ST21NFCA_RF_READER_ISO15693_GATE:
		info->async_cb_type = ST21NFCA_CB_TYPE_READER_ISO15693;
		info->async_cb = cb;
		info->async_cb_context = cb_context;

		*(u8 *)skb_push(skb, 1) = 0x17;

		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
					      ST21NFCA_WR_XCHG_DATA, skb->data,
					      skb->len,
					      st21nfca_hci_data_exchange_cb,
					      info);
		break;
	default:
		return 1;
	}
}

static int st21nfca_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
{
	return st21nfca_tm_send_dep_res(hdev, skb);
}

static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
				       struct nfc_target *target)
{
	u8 fwi = 0x11;

	switch (target->hci_reader_gate) {
	case NFC_HCI_RF_READER_A_GATE:
	case NFC_HCI_RF_READER_B_GATE:
		/*
		 * PRESENCE_CHECK on those gates is available
		 * However, the answer to this command is taking 3 * fwi
		 * if the card is no present.
		 * Instead, we send an empty I-Frame with a very short
		 * configurable fwi ~604µs.
		 */
		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
					ST21NFCA_WR_XCHG_DATA, &fwi, 1, NULL);
	case ST21NFCA_RF_READER_14443_3_A_GATE:
		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
					ST21NFCA_RF_READER_CMD_PRESENCE_CHECK,
					NULL, 0, NULL);
	default:
		return -EOPNOTSUPP;
	}
}

static void st21nfca_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
				struct sk_buff *skb)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
	u8 gate = hdev->pipes[pipe].gate;

	pr_debug("cmd: %x\n", cmd);

	switch (cmd) {
	case NFC_HCI_ANY_OPEN_PIPE:
		if (gate != ST21NFCA_APDU_READER_GATE &&
			hdev->pipes[pipe].dest_host != NFC_HCI_UICC_HOST_ID)
			info->se_info.count_pipes++;

		if (info->se_info.count_pipes == info->se_info.expected_pipes) {
			del_timer_sync(&info->se_info.se_active_timer);
			info->se_info.se_active = false;
			info->se_info.count_pipes = 0;
			complete(&info->se_info.req_completion);
		}
	break;
	}
}

static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event,
					struct sk_buff *skb)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	pr_debug("admin event: %x\n", event);

	switch (event) {
	case ST21NFCA_EVT_HOT_PLUG:
		if (info->se_info.se_active) {
			if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) {
				del_timer_sync(&info->se_info.se_active_timer);
				info->se_info.se_active = false;
				complete(&info->se_info.req_completion);
			} else {
				mod_timer(&info->se_info.se_active_timer,
					jiffies +
					msecs_to_jiffies(ST21NFCA_SE_TO_PIPES));
			}
		}
	break;
	default:
		nfc_err(&hdev->ndev->dev, "Unexpected event on admin gate\n");
	}
	kfree_skb(skb);
	return 0;
}

/*
 * Returns:
 * <= 0: driver handled the event, skb consumed
 *    1: driver does not handle the event, please do standard processing
 */
static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe,
				       u8 event, struct sk_buff *skb)
{
	u8 gate = hdev->pipes[pipe].gate;
	u8 host = hdev->pipes[pipe].dest_host;

	pr_debug("hci event: %d gate: %x\n", event, gate);

	switch (gate) {
	case NFC_HCI_ADMIN_GATE:
		return st21nfca_admin_event_received(hdev, event, skb);
	case ST21NFCA_RF_CARD_F_GATE:
		return st21nfca_dep_event_received(hdev, event, skb);
	case ST21NFCA_CONNECTIVITY_GATE:
		return st21nfca_connectivity_event_received(hdev, host,
							event, skb);
	case ST21NFCA_APDU_READER_GATE:
		return st21nfca_apdu_reader_event_received(hdev, event, skb);
	case NFC_HCI_LOOPBACK_GATE:
		return st21nfca_hci_loopback_event_received(hdev, event, skb);
	default:
		return 1;
	}
}

static struct nfc_hci_ops st21nfca_hci_ops = {
	.open = st21nfca_hci_open,
	.close = st21nfca_hci_close,
	.load_session = st21nfca_hci_load_session,
	.hci_ready = st21nfca_hci_ready,
	.xmit = st21nfca_hci_xmit,
	.start_poll = st21nfca_hci_start_poll,
	.stop_poll = st21nfca_hci_stop_poll,
	.dep_link_up = st21nfca_hci_dep_link_up,
	.dep_link_down = st21nfca_hci_dep_link_down,
	.target_from_gate = st21nfca_hci_target_from_gate,
	.complete_target_discovered = st21nfca_hci_complete_target_discovered,
	.im_transceive = st21nfca_hci_im_transceive,
	.tm_send = st21nfca_hci_tm_send,
	.check_presence = st21nfca_hci_check_presence,
	.event_received = st21nfca_hci_event_received,
	.cmd_received = st21nfca_hci_cmd_received,
	.discover_se = st21nfca_hci_discover_se,
	.enable_se = st21nfca_hci_enable_se,
	.disable_se = st21nfca_hci_disable_se,
	.se_io = st21nfca_hci_se_io,
};

int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
		       char *llc_name, int phy_headroom, int phy_tailroom,
		       int phy_payload, struct nfc_hci_dev **hdev,
			   struct st21nfca_se_status *se_status)
{
	struct st21nfca_hci_info *info;
	int r = 0;
	int dev_num;
	u32 protocols;
	struct nfc_hci_init_data init_data;
	unsigned long quirks = 0;

	info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->phy_ops = phy_ops;
	info->phy_id = phy_id;
	info->state = ST21NFCA_ST_COLD;
	mutex_init(&info->info_lock);

	init_data.gate_count = ARRAY_SIZE(st21nfca_gates);

	memcpy(init_data.gates, st21nfca_gates, sizeof(st21nfca_gates));

	/*
	 * Session id must include the driver name + i2c bus addr
	 * persistent info to discriminate 2 identical chips
	 */
	dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES);
	if (dev_num >= ST21NFCA_NUM_DEVICES) {
		r = -ENODEV;
		goto err_alloc_hdev;
	}

	set_bit(dev_num, dev_mask);

	scnprintf(init_data.session_id, sizeof(init_data.session_id), "%s%2x",
		  "ST21AH", dev_num);

	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 |
	    NFC_PROTO_NFC_DEP_MASK;

	set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);

	info->hdev =
	    nfc_hci_allocate_device(&st21nfca_hci_ops, &init_data, quirks,
				    protocols, llc_name,
				    phy_headroom + ST21NFCA_CMDS_HEADROOM,
				    phy_tailroom, phy_payload);

	if (!info->hdev) {
		pr_err("Cannot allocate nfc hdev.\n");
		r = -ENOMEM;
		goto err_alloc_hdev;
	}

	info->se_status = se_status;

	nfc_hci_set_clientdata(info->hdev, info);

	r = nfc_hci_register_device(info->hdev);
	if (r)
		goto err_regdev;

	*hdev = info->hdev;
	st21nfca_dep_init(info->hdev);
	st21nfca_se_init(info->hdev);
	st21nfca_vendor_cmds_init(info->hdev);

	return 0;

err_regdev:
	nfc_hci_free_device(info->hdev);

err_alloc_hdev:
	kfree(info);

	return r;
}
EXPORT_SYMBOL(st21nfca_hci_probe);

void st21nfca_hci_remove(struct nfc_hci_dev *hdev)
{
	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);

	st21nfca_dep_deinit(hdev);
	st21nfca_se_deinit(hdev);
	nfc_hci_unregister_device(hdev);
	nfc_hci_free_device(hdev);
	kfree(info);
}
EXPORT_SYMBOL(st21nfca_hci_remove);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DRIVER_DESC);
