xref: /OK3568_Linux_fs/kernel/drivers/nfc/pn544/pn544.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * HCI based Driver for NXP PN544 NFC Chip
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2012  Intel Corporation. All rights reserved.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/delay.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/nfc.h>
15*4882a593Smuzhiyun #include <net/nfc/hci.h>
16*4882a593Smuzhiyun #include <net/nfc/llc.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "pn544.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /* Timing restrictions (ms) */
21*4882a593Smuzhiyun #define PN544_HCI_RESETVEN_TIME		30
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun enum pn544_state {
24*4882a593Smuzhiyun 	PN544_ST_COLD,
25*4882a593Smuzhiyun 	PN544_ST_FW_READY,
26*4882a593Smuzhiyun 	PN544_ST_READY,
27*4882a593Smuzhiyun };
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define FULL_VERSION_LEN 11
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /* Proprietary commands */
32*4882a593Smuzhiyun #define PN544_WRITE		0x3f
33*4882a593Smuzhiyun #define PN544_TEST_SWP		0x21
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* Proprietary gates, events, commands and registers */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* NFC_HCI_RF_READER_A_GATE additional registers and commands */
38*4882a593Smuzhiyun #define PN544_RF_READER_A_AUTO_ACTIVATION			0x10
39*4882a593Smuzhiyun #define PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION		0x12
40*4882a593Smuzhiyun #define PN544_MIFARE_CMD					0x21
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* Commands that apply to all RF readers */
43*4882a593Smuzhiyun #define PN544_RF_READER_CMD_PRESENCE_CHECK	0x30
44*4882a593Smuzhiyun #define PN544_RF_READER_CMD_ACTIVATE_NEXT	0x32
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /* NFC_HCI_ID_MGMT_GATE additional registers */
47*4882a593Smuzhiyun #define PN544_ID_MGMT_FULL_VERSION_SW		0x10
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define PN544_RF_READER_ISO15693_GATE		0x12
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define PN544_RF_READER_F_GATE			0x14
52*4882a593Smuzhiyun #define PN544_FELICA_ID				0x04
53*4882a593Smuzhiyun #define PN544_FELICA_RAW			0x20
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define PN544_RF_READER_JEWEL_GATE		0x15
56*4882a593Smuzhiyun #define PN544_JEWEL_RAW_CMD			0x23
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun #define PN544_RF_READER_NFCIP1_INITIATOR_GATE	0x30
59*4882a593Smuzhiyun #define PN544_RF_READER_NFCIP1_TARGET_GATE	0x31
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #define PN544_SYS_MGMT_GATE			0x90
62*4882a593Smuzhiyun #define PN544_SYS_MGMT_INFO_NOTIFICATION	0x02
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define PN544_POLLING_LOOP_MGMT_GATE		0x94
65*4882a593Smuzhiyun #define PN544_DEP_MODE				0x01
66*4882a593Smuzhiyun #define PN544_DEP_ATR_REQ			0x02
67*4882a593Smuzhiyun #define PN544_DEP_ATR_RES			0x03
68*4882a593Smuzhiyun #define PN544_DEP_MERGE				0x0D
69*4882a593Smuzhiyun #define PN544_PL_RDPHASES			0x06
70*4882a593Smuzhiyun #define PN544_PL_EMULATION			0x07
71*4882a593Smuzhiyun #define PN544_PL_NFCT_DEACTIVATED		0x09
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun #define PN544_SWP_MGMT_GATE			0xA0
74*4882a593Smuzhiyun #define PN544_SWP_DEFAULT_MODE			0x01
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #define PN544_NFC_WI_MGMT_GATE			0xA1
77*4882a593Smuzhiyun #define PN544_NFC_ESE_DEFAULT_MODE		0x01
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun #define PN544_HCI_EVT_SND_DATA			0x01
80*4882a593Smuzhiyun #define PN544_HCI_EVT_ACTIVATED			0x02
81*4882a593Smuzhiyun #define PN544_HCI_EVT_DEACTIVATED		0x03
82*4882a593Smuzhiyun #define PN544_HCI_EVT_RCV_DATA			0x04
83*4882a593Smuzhiyun #define PN544_HCI_EVT_CONTINUE_MI		0x05
84*4882a593Smuzhiyun #define PN544_HCI_EVT_SWITCH_MODE		0x03
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun #define PN544_HCI_CMD_ATTREQUEST		0x12
87*4882a593Smuzhiyun #define PN544_HCI_CMD_CONTINUE_ACTIVATION	0x13
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun static struct nfc_hci_gate pn544_gates[] = {
90*4882a593Smuzhiyun 	{NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE},
91*4882a593Smuzhiyun 	{NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE},
92*4882a593Smuzhiyun 	{NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE},
93*4882a593Smuzhiyun 	{NFC_HCI_LINK_MGMT_GATE, NFC_HCI_INVALID_PIPE},
94*4882a593Smuzhiyun 	{NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE},
95*4882a593Smuzhiyun 	{NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE},
96*4882a593Smuzhiyun 	{PN544_SYS_MGMT_GATE, NFC_HCI_INVALID_PIPE},
97*4882a593Smuzhiyun 	{PN544_SWP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
98*4882a593Smuzhiyun 	{PN544_POLLING_LOOP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
99*4882a593Smuzhiyun 	{PN544_NFC_WI_MGMT_GATE, NFC_HCI_INVALID_PIPE},
100*4882a593Smuzhiyun 	{PN544_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
101*4882a593Smuzhiyun 	{PN544_RF_READER_JEWEL_GATE, NFC_HCI_INVALID_PIPE},
102*4882a593Smuzhiyun 	{PN544_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
103*4882a593Smuzhiyun 	{PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_INVALID_PIPE},
104*4882a593Smuzhiyun 	{PN544_RF_READER_NFCIP1_TARGET_GATE, NFC_HCI_INVALID_PIPE}
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /* Largest headroom needed for outgoing custom commands */
108*4882a593Smuzhiyun #define PN544_CMDS_HEADROOM	2
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun struct pn544_hci_info {
111*4882a593Smuzhiyun 	struct nfc_phy_ops *phy_ops;
112*4882a593Smuzhiyun 	void *phy_id;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	struct nfc_hci_dev *hdev;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	enum pn544_state state;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	struct mutex info_lock;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	int async_cb_type;
121*4882a593Smuzhiyun 	data_exchange_cb_t async_cb;
122*4882a593Smuzhiyun 	void *async_cb_context;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	fw_download_t fw_download;
125*4882a593Smuzhiyun };
126*4882a593Smuzhiyun 
pn544_hci_open(struct nfc_hci_dev * hdev)127*4882a593Smuzhiyun static int pn544_hci_open(struct nfc_hci_dev *hdev)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
130*4882a593Smuzhiyun 	int r = 0;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	mutex_lock(&info->info_lock);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	if (info->state != PN544_ST_COLD) {
135*4882a593Smuzhiyun 		r = -EBUSY;
136*4882a593Smuzhiyun 		goto out;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	r = info->phy_ops->enable(info->phy_id);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	if (r == 0)
142*4882a593Smuzhiyun 		info->state = PN544_ST_READY;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun out:
145*4882a593Smuzhiyun 	mutex_unlock(&info->info_lock);
146*4882a593Smuzhiyun 	return r;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
pn544_hci_close(struct nfc_hci_dev * hdev)149*4882a593Smuzhiyun static void pn544_hci_close(struct nfc_hci_dev *hdev)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun 	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	mutex_lock(&info->info_lock);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	if (info->state == PN544_ST_COLD)
156*4882a593Smuzhiyun 		goto out;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	info->phy_ops->disable(info->phy_id);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	info->state = PN544_ST_COLD;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun out:
163*4882a593Smuzhiyun 	mutex_unlock(&info->info_lock);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
pn544_hci_ready(struct nfc_hci_dev * hdev)166*4882a593Smuzhiyun static int pn544_hci_ready(struct nfc_hci_dev *hdev)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	struct sk_buff *skb;
169*4882a593Smuzhiyun 	static struct hw_config {
170*4882a593Smuzhiyun 		u8 adr[2];
171*4882a593Smuzhiyun 		u8 value;
172*4882a593Smuzhiyun 	} hw_config[] = {
173*4882a593Smuzhiyun 		{{0x9f, 0x9a}, 0x00},
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 		{{0x98, 0x10}, 0xbc},
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 		{{0x9e, 0x71}, 0x00},
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 		{{0x98, 0x09}, 0x00},
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 		{{0x9e, 0xb4}, 0x00},
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 		{{0x9c, 0x01}, 0x08},
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 		{{0x9e, 0xaa}, 0x01},
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		{{0x9b, 0xd1}, 0x17},
188*4882a593Smuzhiyun 		{{0x9b, 0xd2}, 0x58},
189*4882a593Smuzhiyun 		{{0x9b, 0xd3}, 0x10},
190*4882a593Smuzhiyun 		{{0x9b, 0xd4}, 0x47},
191*4882a593Smuzhiyun 		{{0x9b, 0xd5}, 0x0c},
192*4882a593Smuzhiyun 		{{0x9b, 0xd6}, 0x37},
193*4882a593Smuzhiyun 		{{0x9b, 0xdd}, 0x33},
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 		{{0x9b, 0x84}, 0x00},
196*4882a593Smuzhiyun 		{{0x99, 0x81}, 0x79},
197*4882a593Smuzhiyun 		{{0x99, 0x31}, 0x79},
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		{{0x98, 0x00}, 0x3f},
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 		{{0x9f, 0x09}, 0x02},
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 		{{0x9f, 0x0a}, 0x05},
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 		{{0x9e, 0xd1}, 0xa1},
206*4882a593Smuzhiyun 		{{0x99, 0x23}, 0x01},
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 		{{0x9e, 0x74}, 0x00},
209*4882a593Smuzhiyun 		{{0x9e, 0x90}, 0x00},
210*4882a593Smuzhiyun 		{{0x9f, 0x28}, 0x10},
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 		{{0x9f, 0x35}, 0x04},
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 		{{0x9f, 0x36}, 0x11},
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 		{{0x9c, 0x31}, 0x00},
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 		{{0x9c, 0x32}, 0x00},
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 		{{0x9c, 0x19}, 0x0a},
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 		{{0x9c, 0x1a}, 0x0a},
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 		{{0x9c, 0x0c}, 0x00},
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 		{{0x9c, 0x0d}, 0x00},
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 		{{0x9c, 0x12}, 0x00},
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 		{{0x9c, 0x13}, 0x00},
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 		{{0x98, 0xa2}, 0x09},
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 		{{0x98, 0x93}, 0x00},
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 		{{0x98, 0x7d}, 0x08},
237*4882a593Smuzhiyun 		{{0x98, 0x7e}, 0x00},
238*4882a593Smuzhiyun 		{{0x9f, 0xc8}, 0x00},
239*4882a593Smuzhiyun 	};
240*4882a593Smuzhiyun 	struct hw_config *p = hw_config;
241*4882a593Smuzhiyun 	int count = ARRAY_SIZE(hw_config);
242*4882a593Smuzhiyun 	struct sk_buff *res_skb;
243*4882a593Smuzhiyun 	u8 param[4];
244*4882a593Smuzhiyun 	int r;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	param[0] = 0;
247*4882a593Smuzhiyun 	while (count--) {
248*4882a593Smuzhiyun 		param[1] = p->adr[0];
249*4882a593Smuzhiyun 		param[2] = p->adr[1];
250*4882a593Smuzhiyun 		param[3] = p->value;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 		r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_WRITE,
253*4882a593Smuzhiyun 				     param, 4, &res_skb);
254*4882a593Smuzhiyun 		if (r < 0)
255*4882a593Smuzhiyun 			return r;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 		if (res_skb->len != 1) {
258*4882a593Smuzhiyun 			kfree_skb(res_skb);
259*4882a593Smuzhiyun 			return -EPROTO;
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 		if (res_skb->data[0] != p->value) {
263*4882a593Smuzhiyun 			kfree_skb(res_skb);
264*4882a593Smuzhiyun 			return -EIO;
265*4882a593Smuzhiyun 		}
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 		kfree_skb(res_skb);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 		p++;
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	param[0] = NFC_HCI_UICC_HOST_ID;
273*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE,
274*4882a593Smuzhiyun 			      NFC_HCI_ADMIN_WHITELIST, param, 1);
275*4882a593Smuzhiyun 	if (r < 0)
276*4882a593Smuzhiyun 		return r;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	param[0] = 0x3d;
279*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, PN544_SYS_MGMT_GATE,
280*4882a593Smuzhiyun 			      PN544_SYS_MGMT_INFO_NOTIFICATION, param, 1);
281*4882a593Smuzhiyun 	if (r < 0)
282*4882a593Smuzhiyun 		return r;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	param[0] = 0x0;
285*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, NFC_HCI_RF_READER_A_GATE,
286*4882a593Smuzhiyun 			      PN544_RF_READER_A_AUTO_ACTIVATION, param, 1);
287*4882a593Smuzhiyun 	if (r < 0)
288*4882a593Smuzhiyun 		return r;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
291*4882a593Smuzhiyun 			       NFC_HCI_EVT_END_OPERATION, NULL, 0);
292*4882a593Smuzhiyun 	if (r < 0)
293*4882a593Smuzhiyun 		return r;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	param[0] = 0x1;
296*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
297*4882a593Smuzhiyun 			      PN544_PL_NFCT_DEACTIVATED, param, 1);
298*4882a593Smuzhiyun 	if (r < 0)
299*4882a593Smuzhiyun 		return r;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	param[0] = 0x0;
302*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
303*4882a593Smuzhiyun 			      PN544_PL_RDPHASES, param, 1);
304*4882a593Smuzhiyun 	if (r < 0)
305*4882a593Smuzhiyun 		return r;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
308*4882a593Smuzhiyun 			      PN544_ID_MGMT_FULL_VERSION_SW, &skb);
309*4882a593Smuzhiyun 	if (r < 0)
310*4882a593Smuzhiyun 		return r;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	if (skb->len != FULL_VERSION_LEN) {
313*4882a593Smuzhiyun 		kfree_skb(skb);
314*4882a593Smuzhiyun 		return -EINVAL;
315*4882a593Smuzhiyun 	}
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ",
318*4882a593Smuzhiyun 		       DUMP_PREFIX_NONE, 16, 1,
319*4882a593Smuzhiyun 		       skb->data, FULL_VERSION_LEN, false);
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	kfree_skb(skb);
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	return 0;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
pn544_hci_xmit(struct nfc_hci_dev * hdev,struct sk_buff * skb)326*4882a593Smuzhiyun static int pn544_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	return info->phy_ops->write(info->phy_id, skb);
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
pn544_hci_start_poll(struct nfc_hci_dev * hdev,u32 im_protocols,u32 tm_protocols)333*4882a593Smuzhiyun static int pn544_hci_start_poll(struct nfc_hci_dev *hdev,
334*4882a593Smuzhiyun 				u32 im_protocols, u32 tm_protocols)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	u8 phases = 0;
337*4882a593Smuzhiyun 	int r;
338*4882a593Smuzhiyun 	u8 duration[2];
339*4882a593Smuzhiyun 	u8 activated;
340*4882a593Smuzhiyun 	u8 i_mode = 0x3f; /* Enable all supported modes */
341*4882a593Smuzhiyun 	u8 t_mode = 0x0f;
342*4882a593Smuzhiyun 	u8 t_merge = 0x01; /* Enable merge by default */
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n",
345*4882a593Smuzhiyun 		__func__, im_protocols, tm_protocols);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
348*4882a593Smuzhiyun 			       NFC_HCI_EVT_END_OPERATION, NULL, 0);
349*4882a593Smuzhiyun 	if (r < 0)
350*4882a593Smuzhiyun 		return r;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	duration[0] = 0x18;
353*4882a593Smuzhiyun 	duration[1] = 0x6a;
354*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
355*4882a593Smuzhiyun 			      PN544_PL_EMULATION, duration, 2);
356*4882a593Smuzhiyun 	if (r < 0)
357*4882a593Smuzhiyun 		return r;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	activated = 0;
360*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
361*4882a593Smuzhiyun 			      PN544_PL_NFCT_DEACTIVATED, &activated, 1);
362*4882a593Smuzhiyun 	if (r < 0)
363*4882a593Smuzhiyun 		return r;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	if (im_protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK |
366*4882a593Smuzhiyun 			 NFC_PROTO_JEWEL_MASK))
367*4882a593Smuzhiyun 		phases |= 1;		/* Type A */
368*4882a593Smuzhiyun 	if (im_protocols & NFC_PROTO_FELICA_MASK) {
369*4882a593Smuzhiyun 		phases |= (1 << 2);	/* Type F 212 */
370*4882a593Smuzhiyun 		phases |= (1 << 3);	/* Type F 424 */
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	phases |= (1 << 5);		/* NFC active */
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
376*4882a593Smuzhiyun 			      PN544_PL_RDPHASES, &phases, 1);
377*4882a593Smuzhiyun 	if (r < 0)
378*4882a593Smuzhiyun 		return r;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
381*4882a593Smuzhiyun 		hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
382*4882a593Smuzhiyun 							&hdev->gb_len);
383*4882a593Smuzhiyun 		pr_debug("generate local bytes %p\n", hdev->gb);
384*4882a593Smuzhiyun 		if (hdev->gb == NULL || hdev->gb_len == 0) {
385*4882a593Smuzhiyun 			im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
386*4882a593Smuzhiyun 			tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
387*4882a593Smuzhiyun 		}
388*4882a593Smuzhiyun 	}
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
391*4882a593Smuzhiyun 		r = nfc_hci_send_event(hdev,
392*4882a593Smuzhiyun 				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
393*4882a593Smuzhiyun 				NFC_HCI_EVT_END_OPERATION, NULL, 0);
394*4882a593Smuzhiyun 		if (r < 0)
395*4882a593Smuzhiyun 			return r;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 		r = nfc_hci_set_param(hdev,
398*4882a593Smuzhiyun 				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
399*4882a593Smuzhiyun 				PN544_DEP_MODE, &i_mode, 1);
400*4882a593Smuzhiyun 		if (r < 0)
401*4882a593Smuzhiyun 			return r;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 		r = nfc_hci_set_param(hdev,
404*4882a593Smuzhiyun 				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
405*4882a593Smuzhiyun 				PN544_DEP_ATR_REQ, hdev->gb, hdev->gb_len);
406*4882a593Smuzhiyun 		if (r < 0)
407*4882a593Smuzhiyun 			return r;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 		r = nfc_hci_send_event(hdev,
410*4882a593Smuzhiyun 				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
411*4882a593Smuzhiyun 				NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
412*4882a593Smuzhiyun 		if (r < 0)
413*4882a593Smuzhiyun 			nfc_hci_send_event(hdev,
414*4882a593Smuzhiyun 					PN544_RF_READER_NFCIP1_INITIATOR_GATE,
415*4882a593Smuzhiyun 					NFC_HCI_EVT_END_OPERATION, NULL, 0);
416*4882a593Smuzhiyun 	}
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
419*4882a593Smuzhiyun 		r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
420*4882a593Smuzhiyun 				PN544_DEP_MODE, &t_mode, 1);
421*4882a593Smuzhiyun 		if (r < 0)
422*4882a593Smuzhiyun 			return r;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 		r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
425*4882a593Smuzhiyun 				PN544_DEP_ATR_RES, hdev->gb, hdev->gb_len);
426*4882a593Smuzhiyun 		if (r < 0)
427*4882a593Smuzhiyun 			return r;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 		r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
430*4882a593Smuzhiyun 				PN544_DEP_MERGE, &t_merge, 1);
431*4882a593Smuzhiyun 		if (r < 0)
432*4882a593Smuzhiyun 			return r;
433*4882a593Smuzhiyun 	}
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
436*4882a593Smuzhiyun 			       NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
437*4882a593Smuzhiyun 	if (r < 0)
438*4882a593Smuzhiyun 		nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
439*4882a593Smuzhiyun 				   NFC_HCI_EVT_END_OPERATION, NULL, 0);
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	return r;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
pn544_hci_dep_link_up(struct nfc_hci_dev * hdev,struct nfc_target * target,u8 comm_mode,u8 * gb,size_t gb_len)444*4882a593Smuzhiyun static int pn544_hci_dep_link_up(struct nfc_hci_dev *hdev,
445*4882a593Smuzhiyun 				struct nfc_target *target, u8 comm_mode,
446*4882a593Smuzhiyun 				u8 *gb, size_t gb_len)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun 	struct sk_buff *rgb_skb = NULL;
449*4882a593Smuzhiyun 	int r;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	r = nfc_hci_get_param(hdev, target->hci_reader_gate,
452*4882a593Smuzhiyun 				PN544_DEP_ATR_RES, &rgb_skb);
453*4882a593Smuzhiyun 	if (r < 0)
454*4882a593Smuzhiyun 		return r;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) {
457*4882a593Smuzhiyun 		r = -EPROTO;
458*4882a593Smuzhiyun 		goto exit;
459*4882a593Smuzhiyun 	}
460*4882a593Smuzhiyun 	print_hex_dump(KERN_DEBUG, "remote gb: ", DUMP_PREFIX_OFFSET,
461*4882a593Smuzhiyun 			16, 1, rgb_skb->data, rgb_skb->len, true);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data,
464*4882a593Smuzhiyun 						rgb_skb->len);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	if (r == 0)
467*4882a593Smuzhiyun 		r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode,
468*4882a593Smuzhiyun 					NFC_RF_INITIATOR);
469*4882a593Smuzhiyun exit:
470*4882a593Smuzhiyun 	kfree_skb(rgb_skb);
471*4882a593Smuzhiyun 	return r;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun 
pn544_hci_dep_link_down(struct nfc_hci_dev * hdev)474*4882a593Smuzhiyun static int pn544_hci_dep_link_down(struct nfc_hci_dev *hdev)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE,
478*4882a593Smuzhiyun 					NFC_HCI_EVT_END_OPERATION, NULL, 0);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun 
pn544_hci_target_from_gate(struct nfc_hci_dev * hdev,u8 gate,struct nfc_target * target)481*4882a593Smuzhiyun static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
482*4882a593Smuzhiyun 				      struct nfc_target *target)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun 	switch (gate) {
485*4882a593Smuzhiyun 	case PN544_RF_READER_F_GATE:
486*4882a593Smuzhiyun 		target->supported_protocols = NFC_PROTO_FELICA_MASK;
487*4882a593Smuzhiyun 		break;
488*4882a593Smuzhiyun 	case PN544_RF_READER_JEWEL_GATE:
489*4882a593Smuzhiyun 		target->supported_protocols = NFC_PROTO_JEWEL_MASK;
490*4882a593Smuzhiyun 		target->sens_res = 0x0c00;
491*4882a593Smuzhiyun 		break;
492*4882a593Smuzhiyun 	case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
493*4882a593Smuzhiyun 		target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
494*4882a593Smuzhiyun 		break;
495*4882a593Smuzhiyun 	default:
496*4882a593Smuzhiyun 		return -EPROTO;
497*4882a593Smuzhiyun 	}
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	return 0;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun 
pn544_hci_complete_target_discovered(struct nfc_hci_dev * hdev,u8 gate,struct nfc_target * target)502*4882a593Smuzhiyun static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev,
503*4882a593Smuzhiyun 						u8 gate,
504*4882a593Smuzhiyun 						struct nfc_target *target)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun 	struct sk_buff *uid_skb;
507*4882a593Smuzhiyun 	int r = 0;
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE)
510*4882a593Smuzhiyun 		return r;
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) {
513*4882a593Smuzhiyun 		r = nfc_hci_send_cmd(hdev,
514*4882a593Smuzhiyun 			PN544_RF_READER_NFCIP1_INITIATOR_GATE,
515*4882a593Smuzhiyun 			PN544_HCI_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL);
516*4882a593Smuzhiyun 		if (r < 0)
517*4882a593Smuzhiyun 			return r;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 		target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE;
520*4882a593Smuzhiyun 	} else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
521*4882a593Smuzhiyun 		if (target->nfcid1_len != 4 && target->nfcid1_len != 7 &&
522*4882a593Smuzhiyun 		    target->nfcid1_len != 10)
523*4882a593Smuzhiyun 			return -EPROTO;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 		r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
526*4882a593Smuzhiyun 				     PN544_RF_READER_CMD_ACTIVATE_NEXT,
527*4882a593Smuzhiyun 				     target->nfcid1, target->nfcid1_len, NULL);
528*4882a593Smuzhiyun 	} else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) {
529*4882a593Smuzhiyun 		r = nfc_hci_get_param(hdev, PN544_RF_READER_F_GATE,
530*4882a593Smuzhiyun 				      PN544_FELICA_ID, &uid_skb);
531*4882a593Smuzhiyun 		if (r < 0)
532*4882a593Smuzhiyun 			return r;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 		if (uid_skb->len != 8) {
535*4882a593Smuzhiyun 			kfree_skb(uid_skb);
536*4882a593Smuzhiyun 			return -EPROTO;
537*4882a593Smuzhiyun 		}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 		/* Type F NFC-DEP IDm has prefix 0x01FE */
540*4882a593Smuzhiyun 		if ((uid_skb->data[0] == 0x01) && (uid_skb->data[1] == 0xfe)) {
541*4882a593Smuzhiyun 			kfree_skb(uid_skb);
542*4882a593Smuzhiyun 			r = nfc_hci_send_cmd(hdev,
543*4882a593Smuzhiyun 					PN544_RF_READER_NFCIP1_INITIATOR_GATE,
544*4882a593Smuzhiyun 					PN544_HCI_CMD_CONTINUE_ACTIVATION,
545*4882a593Smuzhiyun 					NULL, 0, NULL);
546*4882a593Smuzhiyun 			if (r < 0)
547*4882a593Smuzhiyun 				return r;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 			target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
550*4882a593Smuzhiyun 			target->hci_reader_gate =
551*4882a593Smuzhiyun 				PN544_RF_READER_NFCIP1_INITIATOR_GATE;
552*4882a593Smuzhiyun 		} else {
553*4882a593Smuzhiyun 			r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE,
554*4882a593Smuzhiyun 					     PN544_RF_READER_CMD_ACTIVATE_NEXT,
555*4882a593Smuzhiyun 					     uid_skb->data, uid_skb->len, NULL);
556*4882a593Smuzhiyun 			kfree_skb(uid_skb);
557*4882a593Smuzhiyun 		}
558*4882a593Smuzhiyun 	} else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) {
559*4882a593Smuzhiyun 		/*
560*4882a593Smuzhiyun 		 * TODO: maybe other ISO 14443 require some kind of continue
561*4882a593Smuzhiyun 		 * activation, but for now we've seen only this one below.
562*4882a593Smuzhiyun 		 */
563*4882a593Smuzhiyun 		if (target->sens_res == 0x4403)	/* Type 4 Mifare DESFire */
564*4882a593Smuzhiyun 			r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
565*4882a593Smuzhiyun 			      PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION,
566*4882a593Smuzhiyun 			      NULL, 0, NULL);
567*4882a593Smuzhiyun 	}
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	return r;
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun #define PN544_CB_TYPE_READER_F 1
573*4882a593Smuzhiyun 
pn544_hci_data_exchange_cb(void * context,struct sk_buff * skb,int err)574*4882a593Smuzhiyun static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb,
575*4882a593Smuzhiyun 				       int err)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun 	struct pn544_hci_info *info = context;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	switch (info->async_cb_type) {
580*4882a593Smuzhiyun 	case PN544_CB_TYPE_READER_F:
581*4882a593Smuzhiyun 		if (err == 0)
582*4882a593Smuzhiyun 			skb_pull(skb, 1);
583*4882a593Smuzhiyun 		info->async_cb(info->async_cb_context, skb, err);
584*4882a593Smuzhiyun 		break;
585*4882a593Smuzhiyun 	default:
586*4882a593Smuzhiyun 		if (err == 0)
587*4882a593Smuzhiyun 			kfree_skb(skb);
588*4882a593Smuzhiyun 		break;
589*4882a593Smuzhiyun 	}
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun #define MIFARE_CMD_AUTH_KEY_A	0x60
593*4882a593Smuzhiyun #define MIFARE_CMD_AUTH_KEY_B	0x61
594*4882a593Smuzhiyun #define MIFARE_CMD_HEADER	2
595*4882a593Smuzhiyun #define MIFARE_UID_LEN		4
596*4882a593Smuzhiyun #define MIFARE_KEY_LEN		6
597*4882a593Smuzhiyun #define MIFARE_CMD_LEN		12
598*4882a593Smuzhiyun /*
599*4882a593Smuzhiyun  * Returns:
600*4882a593Smuzhiyun  * <= 0: driver handled the data exchange
601*4882a593Smuzhiyun  *    1: driver doesn't especially handle, please do standard processing
602*4882a593Smuzhiyun  */
pn544_hci_im_transceive(struct nfc_hci_dev * hdev,struct nfc_target * target,struct sk_buff * skb,data_exchange_cb_t cb,void * cb_context)603*4882a593Smuzhiyun static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev,
604*4882a593Smuzhiyun 				   struct nfc_target *target,
605*4882a593Smuzhiyun 				   struct sk_buff *skb, data_exchange_cb_t cb,
606*4882a593Smuzhiyun 				   void *cb_context)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun 	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	pr_info(DRIVER_DESC ": %s for gate=%d\n", __func__,
611*4882a593Smuzhiyun 		target->hci_reader_gate);
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun 	switch (target->hci_reader_gate) {
614*4882a593Smuzhiyun 	case NFC_HCI_RF_READER_A_GATE:
615*4882a593Smuzhiyun 		if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
616*4882a593Smuzhiyun 			/*
617*4882a593Smuzhiyun 			 * It seems that pn544 is inverting key and UID for
618*4882a593Smuzhiyun 			 * MIFARE authentication commands.
619*4882a593Smuzhiyun 			 */
620*4882a593Smuzhiyun 			if (skb->len == MIFARE_CMD_LEN &&
621*4882a593Smuzhiyun 			    (skb->data[0] == MIFARE_CMD_AUTH_KEY_A ||
622*4882a593Smuzhiyun 			     skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) {
623*4882a593Smuzhiyun 				u8 uid[MIFARE_UID_LEN];
624*4882a593Smuzhiyun 				u8 *data = skb->data + MIFARE_CMD_HEADER;
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 				memcpy(uid, data + MIFARE_KEY_LEN,
627*4882a593Smuzhiyun 				       MIFARE_UID_LEN);
628*4882a593Smuzhiyun 				memmove(data + MIFARE_UID_LEN, data,
629*4882a593Smuzhiyun 					MIFARE_KEY_LEN);
630*4882a593Smuzhiyun 				memcpy(data, uid, MIFARE_UID_LEN);
631*4882a593Smuzhiyun 			}
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 			return nfc_hci_send_cmd_async(hdev,
634*4882a593Smuzhiyun 						      target->hci_reader_gate,
635*4882a593Smuzhiyun 						      PN544_MIFARE_CMD,
636*4882a593Smuzhiyun 						      skb->data, skb->len,
637*4882a593Smuzhiyun 						      cb, cb_context);
638*4882a593Smuzhiyun 		} else
639*4882a593Smuzhiyun 			return 1;
640*4882a593Smuzhiyun 	case PN544_RF_READER_F_GATE:
641*4882a593Smuzhiyun 		*(u8 *)skb_push(skb, 1) = 0;
642*4882a593Smuzhiyun 		*(u8 *)skb_push(skb, 1) = 0;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 		info->async_cb_type = PN544_CB_TYPE_READER_F;
645*4882a593Smuzhiyun 		info->async_cb = cb;
646*4882a593Smuzhiyun 		info->async_cb_context = cb_context;
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
649*4882a593Smuzhiyun 					      PN544_FELICA_RAW, skb->data,
650*4882a593Smuzhiyun 					      skb->len,
651*4882a593Smuzhiyun 					      pn544_hci_data_exchange_cb, info);
652*4882a593Smuzhiyun 	case PN544_RF_READER_JEWEL_GATE:
653*4882a593Smuzhiyun 		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
654*4882a593Smuzhiyun 					      PN544_JEWEL_RAW_CMD, skb->data,
655*4882a593Smuzhiyun 					      skb->len, cb, cb_context);
656*4882a593Smuzhiyun 	case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
657*4882a593Smuzhiyun 		*(u8 *)skb_push(skb, 1) = 0;
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 		return nfc_hci_send_event(hdev, target->hci_reader_gate,
660*4882a593Smuzhiyun 					PN544_HCI_EVT_SND_DATA, skb->data,
661*4882a593Smuzhiyun 					skb->len);
662*4882a593Smuzhiyun 	default:
663*4882a593Smuzhiyun 		return 1;
664*4882a593Smuzhiyun 	}
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun 
pn544_hci_tm_send(struct nfc_hci_dev * hdev,struct sk_buff * skb)667*4882a593Smuzhiyun static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun 	int r;
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun 	/* Set default false for multiple information chaining */
672*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = 0;
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
675*4882a593Smuzhiyun 			       PN544_HCI_EVT_SND_DATA, skb->data, skb->len);
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	kfree_skb(skb);
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	return r;
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun 
pn544_hci_check_presence(struct nfc_hci_dev * hdev,struct nfc_target * target)682*4882a593Smuzhiyun static int pn544_hci_check_presence(struct nfc_hci_dev *hdev,
683*4882a593Smuzhiyun 				   struct nfc_target *target)
684*4882a593Smuzhiyun {
685*4882a593Smuzhiyun 	pr_debug("supported protocol %d\n", target->supported_protocols);
686*4882a593Smuzhiyun 	if (target->supported_protocols & (NFC_PROTO_ISO14443_MASK |
687*4882a593Smuzhiyun 					NFC_PROTO_ISO14443_B_MASK)) {
688*4882a593Smuzhiyun 		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
689*4882a593Smuzhiyun 					PN544_RF_READER_CMD_PRESENCE_CHECK,
690*4882a593Smuzhiyun 					NULL, 0, NULL);
691*4882a593Smuzhiyun 	} else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
692*4882a593Smuzhiyun 		if (target->nfcid1_len != 4 && target->nfcid1_len != 7 &&
693*4882a593Smuzhiyun 		    target->nfcid1_len != 10)
694*4882a593Smuzhiyun 			return -EOPNOTSUPP;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 		return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
697*4882a593Smuzhiyun 				     PN544_RF_READER_CMD_ACTIVATE_NEXT,
698*4882a593Smuzhiyun 				     target->nfcid1, target->nfcid1_len, NULL);
699*4882a593Smuzhiyun 	} else if (target->supported_protocols & (NFC_PROTO_JEWEL_MASK |
700*4882a593Smuzhiyun 						NFC_PROTO_FELICA_MASK)) {
701*4882a593Smuzhiyun 		return -EOPNOTSUPP;
702*4882a593Smuzhiyun 	} else if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) {
703*4882a593Smuzhiyun 		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
704*4882a593Smuzhiyun 					PN544_HCI_CMD_ATTREQUEST,
705*4882a593Smuzhiyun 					NULL, 0, NULL);
706*4882a593Smuzhiyun 	}
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	return 0;
709*4882a593Smuzhiyun }
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun /*
712*4882a593Smuzhiyun  * Returns:
713*4882a593Smuzhiyun  * <= 0: driver handled the event, skb consumed
714*4882a593Smuzhiyun  *    1: driver does not handle the event, please do standard processing
715*4882a593Smuzhiyun  */
pn544_hci_event_received(struct nfc_hci_dev * hdev,u8 pipe,u8 event,struct sk_buff * skb)716*4882a593Smuzhiyun static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
717*4882a593Smuzhiyun 				    struct sk_buff *skb)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	struct sk_buff *rgb_skb = NULL;
720*4882a593Smuzhiyun 	u8 gate = hdev->pipes[pipe].gate;
721*4882a593Smuzhiyun 	int r;
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	pr_debug("hci event %d\n", event);
724*4882a593Smuzhiyun 	switch (event) {
725*4882a593Smuzhiyun 	case PN544_HCI_EVT_ACTIVATED:
726*4882a593Smuzhiyun 		if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) {
727*4882a593Smuzhiyun 			r = nfc_hci_target_discovered(hdev, gate);
728*4882a593Smuzhiyun 		} else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) {
729*4882a593Smuzhiyun 			r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ,
730*4882a593Smuzhiyun 					      &rgb_skb);
731*4882a593Smuzhiyun 			if (r < 0)
732*4882a593Smuzhiyun 				goto exit;
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 			r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
735*4882a593Smuzhiyun 					     NFC_COMM_PASSIVE, rgb_skb->data,
736*4882a593Smuzhiyun 					     rgb_skb->len);
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun 			kfree_skb(rgb_skb);
739*4882a593Smuzhiyun 		} else {
740*4882a593Smuzhiyun 			r = -EINVAL;
741*4882a593Smuzhiyun 		}
742*4882a593Smuzhiyun 		break;
743*4882a593Smuzhiyun 	case PN544_HCI_EVT_DEACTIVATED:
744*4882a593Smuzhiyun 		r = nfc_hci_send_event(hdev, gate, NFC_HCI_EVT_END_OPERATION,
745*4882a593Smuzhiyun 				       NULL, 0);
746*4882a593Smuzhiyun 		break;
747*4882a593Smuzhiyun 	case PN544_HCI_EVT_RCV_DATA:
748*4882a593Smuzhiyun 		if (skb->len < 2) {
749*4882a593Smuzhiyun 			r = -EPROTO;
750*4882a593Smuzhiyun 			goto exit;
751*4882a593Smuzhiyun 		}
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 		if (skb->data[0] != 0) {
754*4882a593Smuzhiyun 			pr_debug("data0 %d\n", skb->data[0]);
755*4882a593Smuzhiyun 			r = -EPROTO;
756*4882a593Smuzhiyun 			goto exit;
757*4882a593Smuzhiyun 		}
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 		skb_pull(skb, 2);
760*4882a593Smuzhiyun 		return nfc_tm_data_received(hdev->ndev, skb);
761*4882a593Smuzhiyun 	default:
762*4882a593Smuzhiyun 		return 1;
763*4882a593Smuzhiyun 	}
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun exit:
766*4882a593Smuzhiyun 	kfree_skb(skb);
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	return r;
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun 
pn544_hci_fw_download(struct nfc_hci_dev * hdev,const char * firmware_name)771*4882a593Smuzhiyun static int pn544_hci_fw_download(struct nfc_hci_dev *hdev,
772*4882a593Smuzhiyun 				 const char *firmware_name)
773*4882a593Smuzhiyun {
774*4882a593Smuzhiyun 	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun 	if (info->fw_download == NULL)
777*4882a593Smuzhiyun 		return -ENOTSUPP;
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	return info->fw_download(info->phy_id, firmware_name, hdev->sw_romlib);
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun 
pn544_hci_discover_se(struct nfc_hci_dev * hdev)782*4882a593Smuzhiyun static int pn544_hci_discover_se(struct nfc_hci_dev *hdev)
783*4882a593Smuzhiyun {
784*4882a593Smuzhiyun 	u32 se_idx = 0;
785*4882a593Smuzhiyun 	u8 ese_mode = 0x01; /* Default mode */
786*4882a593Smuzhiyun 	struct sk_buff *res_skb;
787*4882a593Smuzhiyun 	int r;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_TEST_SWP,
790*4882a593Smuzhiyun 			     NULL, 0, &res_skb);
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	if (r == 0) {
793*4882a593Smuzhiyun 		if (res_skb->len == 2 && res_skb->data[0] == 0x00)
794*4882a593Smuzhiyun 			nfc_add_se(hdev->ndev, se_idx++, NFC_SE_UICC);
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 		kfree_skb(res_skb);
797*4882a593Smuzhiyun 	}
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, PN544_NFC_WI_MGMT_GATE,
800*4882a593Smuzhiyun 				PN544_HCI_EVT_SWITCH_MODE,
801*4882a593Smuzhiyun 				&ese_mode, 1);
802*4882a593Smuzhiyun 	if (r == 0)
803*4882a593Smuzhiyun 		nfc_add_se(hdev->ndev, se_idx++, NFC_SE_EMBEDDED);
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	return !se_idx;
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun #define PN544_SE_MODE_OFF	0x00
809*4882a593Smuzhiyun #define PN544_SE_MODE_ON	0x01
pn544_hci_enable_se(struct nfc_hci_dev * hdev,u32 se_idx)810*4882a593Smuzhiyun static int pn544_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx)
811*4882a593Smuzhiyun {
812*4882a593Smuzhiyun 	struct nfc_se *se;
813*4882a593Smuzhiyun 	u8 enable = PN544_SE_MODE_ON;
814*4882a593Smuzhiyun 	static struct uicc_gatelist {
815*4882a593Smuzhiyun 		u8 head;
816*4882a593Smuzhiyun 		u8 adr[2];
817*4882a593Smuzhiyun 		u8 value;
818*4882a593Smuzhiyun 	} uicc_gatelist[] = {
819*4882a593Smuzhiyun 		{0x00, {0x9e, 0xd9}, 0x23},
820*4882a593Smuzhiyun 		{0x00, {0x9e, 0xda}, 0x21},
821*4882a593Smuzhiyun 		{0x00, {0x9e, 0xdb}, 0x22},
822*4882a593Smuzhiyun 		{0x00, {0x9e, 0xdc}, 0x24},
823*4882a593Smuzhiyun 	};
824*4882a593Smuzhiyun 	struct uicc_gatelist *p = uicc_gatelist;
825*4882a593Smuzhiyun 	int count = ARRAY_SIZE(uicc_gatelist);
826*4882a593Smuzhiyun 	struct sk_buff *res_skb;
827*4882a593Smuzhiyun 	int r;
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	se = nfc_find_se(hdev->ndev, se_idx);
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 	switch (se->type) {
832*4882a593Smuzhiyun 	case NFC_SE_UICC:
833*4882a593Smuzhiyun 		while (count--) {
834*4882a593Smuzhiyun 			r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE,
835*4882a593Smuzhiyun 					PN544_WRITE, (u8 *)p, 4, &res_skb);
836*4882a593Smuzhiyun 			if (r < 0)
837*4882a593Smuzhiyun 				return r;
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun 			if (res_skb->len != 1) {
840*4882a593Smuzhiyun 				kfree_skb(res_skb);
841*4882a593Smuzhiyun 				return -EPROTO;
842*4882a593Smuzhiyun 			}
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun 			if (res_skb->data[0] != p->value) {
845*4882a593Smuzhiyun 				kfree_skb(res_skb);
846*4882a593Smuzhiyun 				return -EIO;
847*4882a593Smuzhiyun 			}
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 			kfree_skb(res_skb);
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 			p++;
852*4882a593Smuzhiyun 		}
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 		return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
855*4882a593Smuzhiyun 			      PN544_SWP_DEFAULT_MODE, &enable, 1);
856*4882a593Smuzhiyun 	case NFC_SE_EMBEDDED:
857*4882a593Smuzhiyun 		return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
858*4882a593Smuzhiyun 			      PN544_NFC_ESE_DEFAULT_MODE, &enable, 1);
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	default:
861*4882a593Smuzhiyun 		return -EINVAL;
862*4882a593Smuzhiyun 	}
863*4882a593Smuzhiyun }
864*4882a593Smuzhiyun 
pn544_hci_disable_se(struct nfc_hci_dev * hdev,u32 se_idx)865*4882a593Smuzhiyun static int pn544_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx)
866*4882a593Smuzhiyun {
867*4882a593Smuzhiyun 	struct nfc_se *se;
868*4882a593Smuzhiyun 	u8 disable = PN544_SE_MODE_OFF;
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	se = nfc_find_se(hdev->ndev, se_idx);
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun 	switch (se->type) {
873*4882a593Smuzhiyun 	case NFC_SE_UICC:
874*4882a593Smuzhiyun 		return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
875*4882a593Smuzhiyun 			      PN544_SWP_DEFAULT_MODE, &disable, 1);
876*4882a593Smuzhiyun 	case NFC_SE_EMBEDDED:
877*4882a593Smuzhiyun 		return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
878*4882a593Smuzhiyun 			      PN544_NFC_ESE_DEFAULT_MODE, &disable, 1);
879*4882a593Smuzhiyun 	default:
880*4882a593Smuzhiyun 		return -EINVAL;
881*4882a593Smuzhiyun 	}
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun static struct nfc_hci_ops pn544_hci_ops = {
885*4882a593Smuzhiyun 	.open = pn544_hci_open,
886*4882a593Smuzhiyun 	.close = pn544_hci_close,
887*4882a593Smuzhiyun 	.hci_ready = pn544_hci_ready,
888*4882a593Smuzhiyun 	.xmit = pn544_hci_xmit,
889*4882a593Smuzhiyun 	.start_poll = pn544_hci_start_poll,
890*4882a593Smuzhiyun 	.dep_link_up = pn544_hci_dep_link_up,
891*4882a593Smuzhiyun 	.dep_link_down = pn544_hci_dep_link_down,
892*4882a593Smuzhiyun 	.target_from_gate = pn544_hci_target_from_gate,
893*4882a593Smuzhiyun 	.complete_target_discovered = pn544_hci_complete_target_discovered,
894*4882a593Smuzhiyun 	.im_transceive = pn544_hci_im_transceive,
895*4882a593Smuzhiyun 	.tm_send = pn544_hci_tm_send,
896*4882a593Smuzhiyun 	.check_presence = pn544_hci_check_presence,
897*4882a593Smuzhiyun 	.event_received = pn544_hci_event_received,
898*4882a593Smuzhiyun 	.fw_download = pn544_hci_fw_download,
899*4882a593Smuzhiyun 	.discover_se = pn544_hci_discover_se,
900*4882a593Smuzhiyun 	.enable_se = pn544_hci_enable_se,
901*4882a593Smuzhiyun 	.disable_se = pn544_hci_disable_se,
902*4882a593Smuzhiyun };
903*4882a593Smuzhiyun 
pn544_hci_probe(void * phy_id,struct nfc_phy_ops * phy_ops,char * llc_name,int phy_headroom,int phy_tailroom,int phy_payload,fw_download_t fw_download,struct nfc_hci_dev ** hdev)904*4882a593Smuzhiyun int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
905*4882a593Smuzhiyun 		    int phy_headroom, int phy_tailroom, int phy_payload,
906*4882a593Smuzhiyun 		    fw_download_t fw_download, struct nfc_hci_dev **hdev)
907*4882a593Smuzhiyun {
908*4882a593Smuzhiyun 	struct pn544_hci_info *info;
909*4882a593Smuzhiyun 	u32 protocols;
910*4882a593Smuzhiyun 	struct nfc_hci_init_data init_data;
911*4882a593Smuzhiyun 	int r;
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 	info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL);
914*4882a593Smuzhiyun 	if (!info) {
915*4882a593Smuzhiyun 		r = -ENOMEM;
916*4882a593Smuzhiyun 		goto err_info_alloc;
917*4882a593Smuzhiyun 	}
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun 	info->phy_ops = phy_ops;
920*4882a593Smuzhiyun 	info->phy_id = phy_id;
921*4882a593Smuzhiyun 	info->fw_download = fw_download;
922*4882a593Smuzhiyun 	info->state = PN544_ST_COLD;
923*4882a593Smuzhiyun 	mutex_init(&info->info_lock);
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 	init_data.gate_count = ARRAY_SIZE(pn544_gates);
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun 	memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates));
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun 	/*
930*4882a593Smuzhiyun 	 * TODO: Session id must include the driver name + some bus addr
931*4882a593Smuzhiyun 	 * persistent info to discriminate 2 identical chips
932*4882a593Smuzhiyun 	 */
933*4882a593Smuzhiyun 	strcpy(init_data.session_id, "ID544HCI");
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun 	protocols = NFC_PROTO_JEWEL_MASK |
936*4882a593Smuzhiyun 		    NFC_PROTO_MIFARE_MASK |
937*4882a593Smuzhiyun 		    NFC_PROTO_FELICA_MASK |
938*4882a593Smuzhiyun 		    NFC_PROTO_ISO14443_MASK |
939*4882a593Smuzhiyun 		    NFC_PROTO_ISO14443_B_MASK |
940*4882a593Smuzhiyun 		    NFC_PROTO_NFC_DEP_MASK;
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun 	info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0,
943*4882a593Smuzhiyun 					     protocols, llc_name,
944*4882a593Smuzhiyun 					     phy_headroom + PN544_CMDS_HEADROOM,
945*4882a593Smuzhiyun 					     phy_tailroom, phy_payload);
946*4882a593Smuzhiyun 	if (!info->hdev) {
947*4882a593Smuzhiyun 		pr_err("Cannot allocate nfc hdev\n");
948*4882a593Smuzhiyun 		r = -ENOMEM;
949*4882a593Smuzhiyun 		goto err_alloc_hdev;
950*4882a593Smuzhiyun 	}
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun 	nfc_hci_set_clientdata(info->hdev, info);
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 	r = nfc_hci_register_device(info->hdev);
955*4882a593Smuzhiyun 	if (r)
956*4882a593Smuzhiyun 		goto err_regdev;
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	*hdev = info->hdev;
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	return 0;
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun err_regdev:
963*4882a593Smuzhiyun 	nfc_hci_free_device(info->hdev);
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun err_alloc_hdev:
966*4882a593Smuzhiyun 	kfree(info);
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun err_info_alloc:
969*4882a593Smuzhiyun 	return r;
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun EXPORT_SYMBOL(pn544_hci_probe);
972*4882a593Smuzhiyun 
pn544_hci_remove(struct nfc_hci_dev * hdev)973*4882a593Smuzhiyun void pn544_hci_remove(struct nfc_hci_dev *hdev)
974*4882a593Smuzhiyun {
975*4882a593Smuzhiyun 	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun 	nfc_hci_unregister_device(hdev);
978*4882a593Smuzhiyun 	nfc_hci_free_device(hdev);
979*4882a593Smuzhiyun 	kfree(info);
980*4882a593Smuzhiyun }
981*4882a593Smuzhiyun EXPORT_SYMBOL(pn544_hci_remove);
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun MODULE_LICENSE("GPL");
984*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
985