cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

se.c (20518B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Secure Element driver for STMicroelectronics NFC NCI chip
      4 *
      5 * Copyright (C) 2014-2015 STMicroelectronics SAS. All rights reserved.
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/nfc.h>
     10#include <linux/delay.h>
     11#include <net/nfc/nci.h>
     12#include <net/nfc/nci_core.h>
     13
     14#include "st-nci.h"
     15
     16struct st_nci_pipe_info {
     17	u8 pipe_state;
     18	u8 src_host_id;
     19	u8 src_gate_id;
     20	u8 dst_host_id;
     21	u8 dst_gate_id;
     22} __packed;
     23
     24/* Hosts */
     25#define ST_NCI_HOST_CONTROLLER_ID     0x00
     26#define ST_NCI_TERMINAL_HOST_ID       0x01
     27#define ST_NCI_UICC_HOST_ID           0x02
     28#define ST_NCI_ESE_HOST_ID            0xc0
     29
     30/* Gates */
     31#define ST_NCI_APDU_READER_GATE       0xf0
     32#define ST_NCI_CONNECTIVITY_GATE      0x41
     33
     34/* Pipes */
     35#define ST_NCI_DEVICE_MGNT_PIPE               0x02
     36
     37/* Connectivity pipe only */
     38#define ST_NCI_SE_COUNT_PIPE_UICC             0x01
     39/* Connectivity + APDU Reader pipe */
     40#define ST_NCI_SE_COUNT_PIPE_EMBEDDED         0x02
     41
     42#define ST_NCI_SE_TO_HOT_PLUG			1000 /* msecs */
     43#define ST_NCI_SE_TO_PIPES			2000
     44
     45#define ST_NCI_EVT_HOT_PLUG_IS_INHIBITED(x)   (x->data[0] & 0x80)
     46
     47#define NCI_HCI_APDU_PARAM_ATR                     0x01
     48#define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY       0x01
     49#define NCI_HCI_ADMIN_PARAM_WHITELIST              0x03
     50#define NCI_HCI_ADMIN_PARAM_HOST_LIST              0x04
     51
     52#define ST_NCI_EVT_SE_HARD_RESET		0x20
     53#define ST_NCI_EVT_TRANSMIT_DATA		0x10
     54#define ST_NCI_EVT_WTX_REQUEST			0x11
     55#define ST_NCI_EVT_SE_SOFT_RESET		0x11
     56#define ST_NCI_EVT_SE_END_OF_APDU_TRANSFER	0x21
     57#define ST_NCI_EVT_HOT_PLUG			0x03
     58
     59#define ST_NCI_SE_MODE_OFF                    0x00
     60#define ST_NCI_SE_MODE_ON                     0x01
     61
     62#define ST_NCI_EVT_CONNECTIVITY       0x10
     63#define ST_NCI_EVT_TRANSACTION        0x12
     64
     65#define ST_NCI_DM_GETINFO             0x13
     66#define ST_NCI_DM_GETINFO_PIPE_LIST   0x02
     67#define ST_NCI_DM_GETINFO_PIPE_INFO   0x01
     68#define ST_NCI_DM_PIPE_CREATED        0x02
     69#define ST_NCI_DM_PIPE_OPEN           0x04
     70#define ST_NCI_DM_RF_ACTIVE           0x80
     71#define ST_NCI_DM_DISCONNECT          0x30
     72
     73#define ST_NCI_DM_IS_PIPE_OPEN(p) \
     74	((p & 0x0f) == (ST_NCI_DM_PIPE_CREATED | ST_NCI_DM_PIPE_OPEN))
     75
     76#define ST_NCI_ATR_DEFAULT_BWI        0x04
     77
     78/*
     79 * WT = 2^BWI/10[s], convert into msecs and add a secure
     80 * room by increasing by 2 this timeout
     81 */
     82#define ST_NCI_BWI_TO_TIMEOUT(x)      ((1 << x) * 200)
     83#define ST_NCI_ATR_GET_Y_FROM_TD(x)   (x >> 4)
     84
     85/* If TA is present bit 0 is set */
     86#define ST_NCI_ATR_TA_PRESENT(x) (x & 0x01)
     87/* If TB is present bit 1 is set */
     88#define ST_NCI_ATR_TB_PRESENT(x) (x & 0x02)
     89
     90#define ST_NCI_NUM_DEVICES           256
     91
     92static DECLARE_BITMAP(dev_mask, ST_NCI_NUM_DEVICES);
     93
     94/* Here are the mandatory pipe for st_nci */
     95static struct nci_hci_gate st_nci_gates[] = {
     96	{NCI_HCI_ADMIN_GATE, NCI_HCI_ADMIN_PIPE,
     97					ST_NCI_HOST_CONTROLLER_ID},
     98	{NCI_HCI_LINK_MGMT_GATE, NCI_HCI_LINK_MGMT_PIPE,
     99					ST_NCI_HOST_CONTROLLER_ID},
    100	{ST_NCI_DEVICE_MGNT_GATE, ST_NCI_DEVICE_MGNT_PIPE,
    101					ST_NCI_HOST_CONTROLLER_ID},
    102
    103	{NCI_HCI_IDENTITY_MGMT_GATE, NCI_HCI_INVALID_PIPE,
    104					ST_NCI_HOST_CONTROLLER_ID},
    105
    106	/* Secure element pipes are created by secure element host */
    107	{ST_NCI_CONNECTIVITY_GATE, NCI_HCI_DO_NOT_OPEN_PIPE,
    108					ST_NCI_HOST_CONTROLLER_ID},
    109	{ST_NCI_APDU_READER_GATE, NCI_HCI_DO_NOT_OPEN_PIPE,
    110					ST_NCI_HOST_CONTROLLER_ID},
    111};
    112
    113static u8 st_nci_se_get_bwi(struct nci_dev *ndev)
    114{
    115	int i;
    116	u8 td;
    117	struct st_nci_info *info = nci_get_drvdata(ndev);
    118
    119	/* Bits 8 to 5 of the first TB for T=1 encode BWI from zero to nine */
    120	for (i = 1; i < ST_NCI_ESE_MAX_LENGTH; i++) {
    121		td = ST_NCI_ATR_GET_Y_FROM_TD(info->se_info.atr[i]);
    122		if (ST_NCI_ATR_TA_PRESENT(td))
    123			i++;
    124		if (ST_NCI_ATR_TB_PRESENT(td)) {
    125			i++;
    126			return info->se_info.atr[i] >> 4;
    127		}
    128	}
    129	return ST_NCI_ATR_DEFAULT_BWI;
    130}
    131
    132static void st_nci_se_get_atr(struct nci_dev *ndev)
    133{
    134	struct st_nci_info *info = nci_get_drvdata(ndev);
    135	int r;
    136	struct sk_buff *skb;
    137
    138	r = nci_hci_get_param(ndev, ST_NCI_APDU_READER_GATE,
    139				NCI_HCI_APDU_PARAM_ATR, &skb);
    140	if (r < 0)
    141		return;
    142
    143	if (skb->len <= ST_NCI_ESE_MAX_LENGTH) {
    144		memcpy(info->se_info.atr, skb->data, skb->len);
    145
    146		info->se_info.wt_timeout =
    147			ST_NCI_BWI_TO_TIMEOUT(st_nci_se_get_bwi(ndev));
    148	}
    149	kfree_skb(skb);
    150}
    151
    152int st_nci_hci_load_session(struct nci_dev *ndev)
    153{
    154	int i, j, r;
    155	struct sk_buff *skb_pipe_list, *skb_pipe_info;
    156	struct st_nci_pipe_info *dm_pipe_info;
    157	u8 pipe_list[] = { ST_NCI_DM_GETINFO_PIPE_LIST,
    158			ST_NCI_TERMINAL_HOST_ID};
    159	u8 pipe_info[] = { ST_NCI_DM_GETINFO_PIPE_INFO,
    160			ST_NCI_TERMINAL_HOST_ID, 0};
    161
    162	/* On ST_NCI device pipes number are dynamics
    163	 * If pipes are already created, hci_dev_up will fail.
    164	 * Doing a clear all pipe is a bad idea because:
    165	 * - It does useless EEPROM cycling
    166	 * - It might cause issue for secure elements support
    167	 * (such as removing connectivity or APDU reader pipe)
    168	 * A better approach on ST_NCI is to:
    169	 * - get a pipe list for each host.
    170	 * (eg: ST_NCI_HOST_CONTROLLER_ID for now).
    171	 * (TODO Later on UICC HOST and eSE HOST)
    172	 * - get pipe information
    173	 * - match retrieved pipe list in st_nci_gates
    174	 * ST_NCI_DEVICE_MGNT_GATE is a proprietary gate
    175	 * with ST_NCI_DEVICE_MGNT_PIPE.
    176	 * Pipe can be closed and need to be open.
    177	 */
    178	r = nci_hci_connect_gate(ndev, ST_NCI_HOST_CONTROLLER_ID,
    179				ST_NCI_DEVICE_MGNT_GATE,
    180				ST_NCI_DEVICE_MGNT_PIPE);
    181	if (r < 0)
    182		return r;
    183
    184	/* Get pipe list */
    185	r = nci_hci_send_cmd(ndev, ST_NCI_DEVICE_MGNT_GATE,
    186			ST_NCI_DM_GETINFO, pipe_list, sizeof(pipe_list),
    187			&skb_pipe_list);
    188	if (r < 0)
    189		return r;
    190
    191	/* Complete the existing gate_pipe table */
    192	for (i = 0; i < skb_pipe_list->len; i++) {
    193		pipe_info[2] = skb_pipe_list->data[i];
    194		r = nci_hci_send_cmd(ndev, ST_NCI_DEVICE_MGNT_GATE,
    195					ST_NCI_DM_GETINFO, pipe_info,
    196					sizeof(pipe_info), &skb_pipe_info);
    197
    198		if (r)
    199			continue;
    200
    201		/*
    202		 * Match pipe ID and gate ID
    203		 * Output format from ST21NFC_DM_GETINFO is:
    204		 * - pipe state (1byte)
    205		 * - source hid (1byte)
    206		 * - source gid (1byte)
    207		 * - destination hid (1byte)
    208		 * - destination gid (1byte)
    209		 */
    210		dm_pipe_info = (struct st_nci_pipe_info *)skb_pipe_info->data;
    211		if (dm_pipe_info->dst_gate_id == ST_NCI_APDU_READER_GATE &&
    212		    dm_pipe_info->src_host_id == ST_NCI_UICC_HOST_ID) {
    213			pr_err("Unexpected apdu_reader pipe on host %x\n",
    214			       dm_pipe_info->src_host_id);
    215			kfree_skb(skb_pipe_info);
    216			continue;
    217		}
    218
    219		for (j = 3; (j < ARRAY_SIZE(st_nci_gates)) &&
    220		     (st_nci_gates[j].gate != dm_pipe_info->dst_gate_id); j++)
    221			;
    222
    223		if (j < ARRAY_SIZE(st_nci_gates) &&
    224		    st_nci_gates[j].gate == dm_pipe_info->dst_gate_id &&
    225		    ST_NCI_DM_IS_PIPE_OPEN(dm_pipe_info->pipe_state)) {
    226			ndev->hci_dev->init_data.gates[j].pipe = pipe_info[2];
    227
    228			ndev->hci_dev->gate2pipe[st_nci_gates[j].gate] =
    229						pipe_info[2];
    230			ndev->hci_dev->pipes[pipe_info[2]].gate =
    231						st_nci_gates[j].gate;
    232			ndev->hci_dev->pipes[pipe_info[2]].host =
    233						dm_pipe_info->src_host_id;
    234		}
    235		kfree_skb(skb_pipe_info);
    236	}
    237
    238	/*
    239	 * 3 gates have a well known pipe ID. Only NCI_HCI_LINK_MGMT_GATE
    240	 * is not yet open at this stage.
    241	 */
    242	r = nci_hci_connect_gate(ndev, ST_NCI_HOST_CONTROLLER_ID,
    243				 NCI_HCI_LINK_MGMT_GATE,
    244				 NCI_HCI_LINK_MGMT_PIPE);
    245
    246	kfree_skb(skb_pipe_list);
    247	return r;
    248}
    249EXPORT_SYMBOL_GPL(st_nci_hci_load_session);
    250
    251static void st_nci_hci_admin_event_received(struct nci_dev *ndev,
    252					      u8 event, struct sk_buff *skb)
    253{
    254	struct st_nci_info *info = nci_get_drvdata(ndev);
    255
    256	switch (event) {
    257	case ST_NCI_EVT_HOT_PLUG:
    258		if (info->se_info.se_active) {
    259			if (!ST_NCI_EVT_HOT_PLUG_IS_INHIBITED(skb)) {
    260				del_timer_sync(&info->se_info.se_active_timer);
    261				info->se_info.se_active = false;
    262				complete(&info->se_info.req_completion);
    263			} else {
    264				mod_timer(&info->se_info.se_active_timer,
    265				      jiffies +
    266				      msecs_to_jiffies(ST_NCI_SE_TO_PIPES));
    267			}
    268		}
    269	break;
    270	default:
    271		nfc_err(&ndev->nfc_dev->dev, "Unexpected event on admin gate\n");
    272	}
    273}
    274
    275static int st_nci_hci_apdu_reader_event_received(struct nci_dev *ndev,
    276						   u8 event,
    277						   struct sk_buff *skb)
    278{
    279	struct st_nci_info *info = nci_get_drvdata(ndev);
    280
    281	pr_debug("apdu reader gate event: %x\n", event);
    282
    283	switch (event) {
    284	case ST_NCI_EVT_TRANSMIT_DATA:
    285		del_timer_sync(&info->se_info.bwi_timer);
    286		info->se_info.bwi_active = false;
    287		info->se_info.cb(info->se_info.cb_context,
    288				 skb->data, skb->len, 0);
    289	break;
    290	case ST_NCI_EVT_WTX_REQUEST:
    291		mod_timer(&info->se_info.bwi_timer, jiffies +
    292			  msecs_to_jiffies(info->se_info.wt_timeout));
    293	break;
    294	default:
    295		nfc_err(&ndev->nfc_dev->dev, "Unexpected event on apdu reader gate\n");
    296		return 1;
    297	}
    298
    299	kfree_skb(skb);
    300	return 0;
    301}
    302
    303/*
    304 * Returns:
    305 * <= 0: driver handled the event, skb consumed
    306 *    1: driver does not handle the event, please do standard processing
    307 */
    308static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
    309						u8 host, u8 event,
    310						struct sk_buff *skb)
    311{
    312	int r = 0;
    313	struct device *dev = &ndev->nfc_dev->dev;
    314	struct nfc_evt_transaction *transaction;
    315
    316	pr_debug("connectivity gate event: %x\n", event);
    317
    318	switch (event) {
    319	case ST_NCI_EVT_CONNECTIVITY:
    320		r = nfc_se_connectivity(ndev->nfc_dev, host);
    321	break;
    322	case ST_NCI_EVT_TRANSACTION:
    323		/* According to specification etsi 102 622
    324		 * 11.2.2.4 EVT_TRANSACTION Table 52
    325		 * Description  Tag     Length
    326		 * AID          81      5 to 16
    327		 * PARAMETERS   82      0 to 255
    328		 */
    329		if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
    330		    skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
    331			return -EPROTO;
    332
    333		transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
    334		if (!transaction)
    335			return -ENOMEM;
    336
    337		transaction->aid_len = skb->data[1];
    338		memcpy(transaction->aid, &skb->data[2], transaction->aid_len);
    339
    340		/* Check next byte is PARAMETERS tag (82) */
    341		if (skb->data[transaction->aid_len + 2] !=
    342		    NFC_EVT_TRANSACTION_PARAMS_TAG)
    343			return -EPROTO;
    344
    345		transaction->params_len = skb->data[transaction->aid_len + 3];
    346		memcpy(transaction->params, skb->data +
    347		       transaction->aid_len + 4, transaction->params_len);
    348
    349		r = nfc_se_transaction(ndev->nfc_dev, host, transaction);
    350		break;
    351	default:
    352		nfc_err(&ndev->nfc_dev->dev, "Unexpected event on connectivity gate\n");
    353		return 1;
    354	}
    355	kfree_skb(skb);
    356	return r;
    357}
    358
    359void st_nci_hci_event_received(struct nci_dev *ndev, u8 pipe,
    360				 u8 event, struct sk_buff *skb)
    361{
    362	u8 gate = ndev->hci_dev->pipes[pipe].gate;
    363	u8 host = ndev->hci_dev->pipes[pipe].host;
    364
    365	switch (gate) {
    366	case NCI_HCI_ADMIN_GATE:
    367		st_nci_hci_admin_event_received(ndev, event, skb);
    368	break;
    369	case ST_NCI_APDU_READER_GATE:
    370		st_nci_hci_apdu_reader_event_received(ndev, event, skb);
    371	break;
    372	case ST_NCI_CONNECTIVITY_GATE:
    373		st_nci_hci_connectivity_event_received(ndev, host, event, skb);
    374	break;
    375	}
    376}
    377EXPORT_SYMBOL_GPL(st_nci_hci_event_received);
    378
    379void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd,
    380			       struct sk_buff *skb)
    381{
    382	struct st_nci_info *info = nci_get_drvdata(ndev);
    383	u8 gate = ndev->hci_dev->pipes[pipe].gate;
    384
    385	pr_debug("cmd: %x\n", cmd);
    386
    387	switch (cmd) {
    388	case NCI_HCI_ANY_OPEN_PIPE:
    389		if (gate != ST_NCI_APDU_READER_GATE &&
    390		    ndev->hci_dev->pipes[pipe].host != ST_NCI_UICC_HOST_ID)
    391			ndev->hci_dev->count_pipes++;
    392
    393		if (ndev->hci_dev->count_pipes ==
    394		    ndev->hci_dev->expected_pipes) {
    395			del_timer_sync(&info->se_info.se_active_timer);
    396			info->se_info.se_active = false;
    397			ndev->hci_dev->count_pipes = 0;
    398			complete(&info->se_info.req_completion);
    399		}
    400	break;
    401	}
    402}
    403EXPORT_SYMBOL_GPL(st_nci_hci_cmd_received);
    404
    405static int st_nci_control_se(struct nci_dev *ndev, u8 se_idx,
    406			     u8 state)
    407{
    408	struct st_nci_info *info = nci_get_drvdata(ndev);
    409	int r, i;
    410	struct sk_buff *sk_host_list;
    411	u8 host_id;
    412
    413	switch (se_idx) {
    414	case ST_NCI_UICC_HOST_ID:
    415		ndev->hci_dev->count_pipes = 0;
    416		ndev->hci_dev->expected_pipes = ST_NCI_SE_COUNT_PIPE_UICC;
    417		break;
    418	case ST_NCI_ESE_HOST_ID:
    419		ndev->hci_dev->count_pipes = 0;
    420		ndev->hci_dev->expected_pipes = ST_NCI_SE_COUNT_PIPE_EMBEDDED;
    421		break;
    422	default:
    423		return -EINVAL;
    424	}
    425
    426	/*
    427	 * Wait for an EVT_HOT_PLUG in order to
    428	 * retrieve a relevant host list.
    429	 */
    430	reinit_completion(&info->se_info.req_completion);
    431	r = nci_nfcee_mode_set(ndev, se_idx, state);
    432	if (r != NCI_STATUS_OK)
    433		return r;
    434
    435	mod_timer(&info->se_info.se_active_timer, jiffies +
    436		msecs_to_jiffies(ST_NCI_SE_TO_HOT_PLUG));
    437	info->se_info.se_active = true;
    438
    439	/* Ignore return value and check in any case the host_list */
    440	wait_for_completion_interruptible(&info->se_info.req_completion);
    441
    442	/* There might be some "collision" after receiving a HOT_PLUG event
    443	 * This may cause the CLF to not answer to the next hci command.
    444	 * There is no possible synchronization to prevent this.
    445	 * Adding a small delay is the only way to solve the issue.
    446	 */
    447	if (info->se_info.se_status->is_ese_present &&
    448	    info->se_info.se_status->is_uicc_present)
    449		usleep_range(15000, 20000);
    450
    451	r = nci_hci_get_param(ndev, NCI_HCI_ADMIN_GATE,
    452			NCI_HCI_ADMIN_PARAM_HOST_LIST, &sk_host_list);
    453	if (r != NCI_HCI_ANY_OK)
    454		return r;
    455
    456	for (i = 0; i < sk_host_list->len &&
    457		sk_host_list->data[i] != se_idx; i++)
    458		;
    459	host_id = sk_host_list->data[i];
    460	kfree_skb(sk_host_list);
    461	if (state == ST_NCI_SE_MODE_ON && host_id == se_idx)
    462		return se_idx;
    463	else if (state == ST_NCI_SE_MODE_OFF && host_id != se_idx)
    464		return se_idx;
    465
    466	return -1;
    467}
    468
    469int st_nci_disable_se(struct nci_dev *ndev, u32 se_idx)
    470{
    471	int r;
    472
    473	/*
    474	 * According to upper layer, se_idx == NFC_SE_UICC when
    475	 * info->se_info.se_status->is_uicc_enable is true should never happen
    476	 * Same for eSE.
    477	 */
    478	r = st_nci_control_se(ndev, se_idx, ST_NCI_SE_MODE_OFF);
    479	if (r < 0) {
    480		/* Do best effort to release SWP */
    481		if (se_idx == NFC_SE_EMBEDDED) {
    482			r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE,
    483					ST_NCI_EVT_SE_END_OF_APDU_TRANSFER,
    484					NULL, 0);
    485		}
    486		return r;
    487	}
    488
    489	return 0;
    490}
    491EXPORT_SYMBOL_GPL(st_nci_disable_se);
    492
    493int st_nci_enable_se(struct nci_dev *ndev, u32 se_idx)
    494{
    495	int r;
    496
    497	/*
    498	 * According to upper layer, se_idx == NFC_SE_UICC when
    499	 * info->se_info.se_status->is_uicc_enable is true should never happen.
    500	 * Same for eSE.
    501	 */
    502	r = st_nci_control_se(ndev, se_idx, ST_NCI_SE_MODE_ON);
    503	if (r == ST_NCI_ESE_HOST_ID) {
    504		st_nci_se_get_atr(ndev);
    505		r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE,
    506				ST_NCI_EVT_SE_SOFT_RESET, NULL, 0);
    507	}
    508
    509	if (r < 0) {
    510		/*
    511		 * The activation procedure failed, the secure element
    512		 * is not connected. Remove from the list.
    513		 */
    514		nfc_remove_se(ndev->nfc_dev, se_idx);
    515		return r;
    516	}
    517
    518	return 0;
    519}
    520EXPORT_SYMBOL_GPL(st_nci_enable_se);
    521
    522static int st_nci_hci_network_init(struct nci_dev *ndev)
    523{
    524	struct st_nci_info *info = nci_get_drvdata(ndev);
    525	struct core_conn_create_dest_spec_params *dest_params;
    526	struct dest_spec_params spec_params;
    527	struct nci_conn_info    *conn_info;
    528	int r, dev_num;
    529
    530	dest_params =
    531		kzalloc(sizeof(struct core_conn_create_dest_spec_params) +
    532			sizeof(struct dest_spec_params), GFP_KERNEL);
    533	if (dest_params == NULL)
    534		return -ENOMEM;
    535
    536	dest_params->type = NCI_DESTINATION_SPECIFIC_PARAM_NFCEE_TYPE;
    537	dest_params->length = sizeof(struct dest_spec_params);
    538	spec_params.id = ndev->hci_dev->nfcee_id;
    539	spec_params.protocol = NCI_NFCEE_INTERFACE_HCI_ACCESS;
    540	memcpy(dest_params->value, &spec_params,
    541	       sizeof(struct dest_spec_params));
    542	r = nci_core_conn_create(ndev, NCI_DESTINATION_NFCEE, 1,
    543				 sizeof(struct core_conn_create_dest_spec_params) +
    544				 sizeof(struct dest_spec_params),
    545				 dest_params);
    546	if (r != NCI_STATUS_OK)
    547		goto free_dest_params;
    548
    549	conn_info = ndev->hci_dev->conn_info;
    550	if (!conn_info)
    551		goto free_dest_params;
    552
    553	ndev->hci_dev->init_data.gate_count = ARRAY_SIZE(st_nci_gates);
    554	memcpy(ndev->hci_dev->init_data.gates, st_nci_gates,
    555	       sizeof(st_nci_gates));
    556
    557	/*
    558	 * Session id must include the driver name + i2c bus addr
    559	 * persistent info to discriminate 2 identical chips
    560	 */
    561	dev_num = find_first_zero_bit(dev_mask, ST_NCI_NUM_DEVICES);
    562	if (dev_num >= ST_NCI_NUM_DEVICES) {
    563		r = -ENODEV;
    564		goto free_dest_params;
    565	}
    566
    567	scnprintf(ndev->hci_dev->init_data.session_id,
    568		  sizeof(ndev->hci_dev->init_data.session_id),
    569		  "%s%2x", "ST21BH", dev_num);
    570
    571	r = nci_hci_dev_session_init(ndev);
    572	if (r != NCI_HCI_ANY_OK)
    573		goto free_dest_params;
    574
    575	/*
    576	 * In factory mode, we prevent secure elements activation
    577	 * by disabling nfcee on the current HCI connection id.
    578	 * HCI will be used here only for proprietary commands.
    579	 */
    580	if (test_bit(ST_NCI_FACTORY_MODE, &info->flags))
    581		r = nci_nfcee_mode_set(ndev,
    582				       ndev->hci_dev->conn_info->dest_params->id,
    583				       NCI_NFCEE_DISABLE);
    584	else
    585		r = nci_nfcee_mode_set(ndev,
    586				       ndev->hci_dev->conn_info->dest_params->id,
    587				       NCI_NFCEE_ENABLE);
    588
    589free_dest_params:
    590	kfree(dest_params);
    591	return r;
    592}
    593
    594int st_nci_discover_se(struct nci_dev *ndev)
    595{
    596	u8 white_list[2];
    597	int r, wl_size = 0;
    598	int se_count = 0;
    599	struct st_nci_info *info = nci_get_drvdata(ndev);
    600
    601	r = st_nci_hci_network_init(ndev);
    602	if (r != 0)
    603		return r;
    604
    605	if (test_bit(ST_NCI_FACTORY_MODE, &info->flags))
    606		return 0;
    607
    608	if (info->se_info.se_status->is_uicc_present)
    609		white_list[wl_size++] = ST_NCI_UICC_HOST_ID;
    610	if (info->se_info.se_status->is_ese_present)
    611		white_list[wl_size++] = ST_NCI_ESE_HOST_ID;
    612
    613	if (wl_size) {
    614		r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE,
    615				      NCI_HCI_ADMIN_PARAM_WHITELIST,
    616				      white_list, wl_size);
    617		if (r != NCI_HCI_ANY_OK)
    618			return r;
    619	}
    620
    621	if (info->se_info.se_status->is_uicc_present) {
    622		nfc_add_se(ndev->nfc_dev, ST_NCI_UICC_HOST_ID, NFC_SE_UICC);
    623		se_count++;
    624	}
    625
    626	if (info->se_info.se_status->is_ese_present) {
    627		nfc_add_se(ndev->nfc_dev, ST_NCI_ESE_HOST_ID, NFC_SE_EMBEDDED);
    628		se_count++;
    629	}
    630
    631	return !se_count;
    632}
    633EXPORT_SYMBOL_GPL(st_nci_discover_se);
    634
    635int st_nci_se_io(struct nci_dev *ndev, u32 se_idx,
    636		       u8 *apdu, size_t apdu_length,
    637		       se_io_cb_t cb, void *cb_context)
    638{
    639	struct st_nci_info *info = nci_get_drvdata(ndev);
    640
    641	switch (se_idx) {
    642	case ST_NCI_ESE_HOST_ID:
    643		info->se_info.cb = cb;
    644		info->se_info.cb_context = cb_context;
    645		mod_timer(&info->se_info.bwi_timer, jiffies +
    646			  msecs_to_jiffies(info->se_info.wt_timeout));
    647		info->se_info.bwi_active = true;
    648		return nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE,
    649					ST_NCI_EVT_TRANSMIT_DATA, apdu,
    650					apdu_length);
    651	default:
    652		return -ENODEV;
    653	}
    654}
    655EXPORT_SYMBOL(st_nci_se_io);
    656
    657static void st_nci_se_wt_timeout(struct timer_list *t)
    658{
    659	/*
    660	 * No answer from the secure element
    661	 * within the defined timeout.
    662	 * Let's send a reset request as recovery procedure.
    663	 * According to the situation, we first try to send a software reset
    664	 * to the secure element. If the next command is still not
    665	 * answering in time, we send to the CLF a secure element hardware
    666	 * reset request.
    667	 */
    668	/* hardware reset managed through VCC_UICC_OUT power supply */
    669	u8 param = 0x01;
    670	struct st_nci_info *info = from_timer(info, t, se_info.bwi_timer);
    671
    672	info->se_info.bwi_active = false;
    673
    674	if (!info->se_info.xch_error) {
    675		info->se_info.xch_error = true;
    676		nci_hci_send_event(info->ndlc->ndev, ST_NCI_APDU_READER_GATE,
    677				ST_NCI_EVT_SE_SOFT_RESET, NULL, 0);
    678	} else {
    679		info->se_info.xch_error = false;
    680		nci_hci_send_event(info->ndlc->ndev, ST_NCI_DEVICE_MGNT_GATE,
    681				ST_NCI_EVT_SE_HARD_RESET, &param, 1);
    682	}
    683	info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME);
    684}
    685
    686static void st_nci_se_activation_timeout(struct timer_list *t)
    687{
    688	struct st_nci_info *info = from_timer(info, t,
    689					      se_info.se_active_timer);
    690
    691	info->se_info.se_active = false;
    692
    693	complete(&info->se_info.req_completion);
    694}
    695
    696int st_nci_se_init(struct nci_dev *ndev, struct st_nci_se_status *se_status)
    697{
    698	struct st_nci_info *info = nci_get_drvdata(ndev);
    699
    700	init_completion(&info->se_info.req_completion);
    701	/* initialize timers */
    702	timer_setup(&info->se_info.bwi_timer, st_nci_se_wt_timeout, 0);
    703	info->se_info.bwi_active = false;
    704
    705	timer_setup(&info->se_info.se_active_timer,
    706		    st_nci_se_activation_timeout, 0);
    707	info->se_info.se_active = false;
    708
    709	info->se_info.xch_error = false;
    710
    711	info->se_info.wt_timeout =
    712		ST_NCI_BWI_TO_TIMEOUT(ST_NCI_ATR_DEFAULT_BWI);
    713
    714	info->se_info.se_status = se_status;
    715
    716	return 0;
    717}
    718EXPORT_SYMBOL(st_nci_se_init);
    719
    720void st_nci_se_deinit(struct nci_dev *ndev)
    721{
    722	struct st_nci_info *info = nci_get_drvdata(ndev);
    723
    724	if (info->se_info.bwi_active)
    725		del_timer_sync(&info->se_info.bwi_timer);
    726	if (info->se_info.se_active)
    727		del_timer_sync(&info->se_info.se_active_timer);
    728
    729	info->se_info.se_active = false;
    730	info->se_info.bwi_active = false;
    731}
    732EXPORT_SYMBOL(st_nci_se_deinit);
    733