xref: /OK3568_Linux_fs/kernel/drivers/nfc/st21nfca/dep.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2014  STMicroelectronics SAS. All rights reserved.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <net/nfc/hci.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include "st21nfca.h"
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_INITIATOR 0x00
11*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_REQ 0xd4
12*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_RES 0xd5
13*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_ATR_REQ 0x00
14*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_ATR_RES 0x01
15*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_PSL_REQ 0x04
16*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_PSL_RES 0x05
17*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_DEP_REQ 0x06
18*4882a593Smuzhiyun #define ST21NFCA_NFCIP1_DEP_RES 0x07
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_PNI(pfb)     ((pfb) & 0x03)
21*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
22*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
23*4882a593Smuzhiyun 				((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
24*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
25*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
26*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT 0x10
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
29*4882a593Smuzhiyun 				((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_I_PDU          0x00
32*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU   0x40
33*4882a593Smuzhiyun #define ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define ST21NFCA_ATR_REQ_MIN_SIZE 17
36*4882a593Smuzhiyun #define ST21NFCA_ATR_REQ_MAX_SIZE 65
37*4882a593Smuzhiyun #define ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B 0x30
38*4882a593Smuzhiyun #define ST21NFCA_GB_BIT  0x02
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define ST21NFCA_EVT_SEND_DATA		0x10
41*4882a593Smuzhiyun #define ST21NFCA_EVT_FIELD_ON           0x11
42*4882a593Smuzhiyun #define ST21NFCA_EVT_CARD_DEACTIVATED   0x12
43*4882a593Smuzhiyun #define ST21NFCA_EVT_CARD_ACTIVATED     0x13
44*4882a593Smuzhiyun #define ST21NFCA_EVT_FIELD_OFF          0x14
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define ST21NFCA_EVT_CARD_F_BITRATE 0x16
47*4882a593Smuzhiyun #define ST21NFCA_EVT_READER_F_BITRATE 0x13
48*4882a593Smuzhiyun #define	ST21NFCA_PSL_REQ_SEND_SPEED(brs) (brs & 0x38)
49*4882a593Smuzhiyun #define ST21NFCA_PSL_REQ_RECV_SPEED(brs) (brs & 0x07)
50*4882a593Smuzhiyun #define ST21NFCA_PP2LRI(pp) ((pp & 0x30) >> 4)
51*4882a593Smuzhiyun #define ST21NFCA_CARD_BITRATE_212 0x01
52*4882a593Smuzhiyun #define ST21NFCA_CARD_BITRATE_424 0x02
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define ST21NFCA_DEFAULT_TIMEOUT 0x0a
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #define PROTOCOL_ERR(req) pr_err("%d: ST21NFCA Protocol error: %s\n", \
58*4882a593Smuzhiyun 				 __LINE__, req)
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun struct st21nfca_atr_req {
61*4882a593Smuzhiyun 	u8 length;
62*4882a593Smuzhiyun 	u8 cmd0;
63*4882a593Smuzhiyun 	u8 cmd1;
64*4882a593Smuzhiyun 	u8 nfcid3[NFC_NFCID3_MAXSIZE];
65*4882a593Smuzhiyun 	u8 did;
66*4882a593Smuzhiyun 	u8 bsi;
67*4882a593Smuzhiyun 	u8 bri;
68*4882a593Smuzhiyun 	u8 ppi;
69*4882a593Smuzhiyun 	u8 gbi[];
70*4882a593Smuzhiyun } __packed;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun struct st21nfca_atr_res {
73*4882a593Smuzhiyun 	u8 length;
74*4882a593Smuzhiyun 	u8 cmd0;
75*4882a593Smuzhiyun 	u8 cmd1;
76*4882a593Smuzhiyun 	u8 nfcid3[NFC_NFCID3_MAXSIZE];
77*4882a593Smuzhiyun 	u8 did;
78*4882a593Smuzhiyun 	u8 bsi;
79*4882a593Smuzhiyun 	u8 bri;
80*4882a593Smuzhiyun 	u8 to;
81*4882a593Smuzhiyun 	u8 ppi;
82*4882a593Smuzhiyun 	u8 gbi[];
83*4882a593Smuzhiyun } __packed;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun struct st21nfca_psl_req {
86*4882a593Smuzhiyun 	u8 length;
87*4882a593Smuzhiyun 	u8 cmd0;
88*4882a593Smuzhiyun 	u8 cmd1;
89*4882a593Smuzhiyun 	u8 did;
90*4882a593Smuzhiyun 	u8 brs;
91*4882a593Smuzhiyun 	u8 fsl;
92*4882a593Smuzhiyun } __packed;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun struct st21nfca_psl_res {
95*4882a593Smuzhiyun 	u8 length;
96*4882a593Smuzhiyun 	u8 cmd0;
97*4882a593Smuzhiyun 	u8 cmd1;
98*4882a593Smuzhiyun 	u8 did;
99*4882a593Smuzhiyun } __packed;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun struct st21nfca_dep_req_res {
102*4882a593Smuzhiyun 	u8 length;
103*4882a593Smuzhiyun 	u8 cmd0;
104*4882a593Smuzhiyun 	u8 cmd1;
105*4882a593Smuzhiyun 	u8 pfb;
106*4882a593Smuzhiyun 	u8 did;
107*4882a593Smuzhiyun 	u8 nad;
108*4882a593Smuzhiyun } __packed;
109*4882a593Smuzhiyun 
st21nfca_tx_work(struct work_struct * work)110*4882a593Smuzhiyun static void st21nfca_tx_work(struct work_struct *work)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = container_of(work,
113*4882a593Smuzhiyun 						struct st21nfca_hci_info,
114*4882a593Smuzhiyun 						dep_info.tx_work);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	struct nfc_dev *dev;
117*4882a593Smuzhiyun 	struct sk_buff *skb;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	if (info) {
120*4882a593Smuzhiyun 		dev = info->hdev->ndev;
121*4882a593Smuzhiyun 		skb = info->dep_info.tx_pending;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 		device_lock(&dev->dev);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 		nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
126*4882a593Smuzhiyun 				ST21NFCA_WR_XCHG_DATA, skb->data, skb->len,
127*4882a593Smuzhiyun 				info->async_cb, info);
128*4882a593Smuzhiyun 		device_unlock(&dev->dev);
129*4882a593Smuzhiyun 		kfree_skb(skb);
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
st21nfca_im_send_pdu(struct st21nfca_hci_info * info,struct sk_buff * skb)133*4882a593Smuzhiyun static void st21nfca_im_send_pdu(struct st21nfca_hci_info *info,
134*4882a593Smuzhiyun 						struct sk_buff *skb)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	info->dep_info.tx_pending = skb;
137*4882a593Smuzhiyun 	schedule_work(&info->dep_info.tx_work);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun 
st21nfca_tm_send_atr_res(struct nfc_hci_dev * hdev,struct st21nfca_atr_req * atr_req)140*4882a593Smuzhiyun static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
141*4882a593Smuzhiyun 				    struct st21nfca_atr_req *atr_req)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	struct st21nfca_atr_res *atr_res;
144*4882a593Smuzhiyun 	struct sk_buff *skb;
145*4882a593Smuzhiyun 	size_t gb_len;
146*4882a593Smuzhiyun 	int r;
147*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	gb_len = atr_req->length - sizeof(struct st21nfca_atr_req);
150*4882a593Smuzhiyun 	skb = alloc_skb(atr_req->length + 1, GFP_KERNEL);
151*4882a593Smuzhiyun 	if (!skb)
152*4882a593Smuzhiyun 		return -ENOMEM;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	skb_put(skb, sizeof(struct st21nfca_atr_res));
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	atr_res = (struct st21nfca_atr_res *)skb->data;
157*4882a593Smuzhiyun 	memset(atr_res, 0, sizeof(struct st21nfca_atr_res));
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	atr_res->length = atr_req->length + 1;
160*4882a593Smuzhiyun 	atr_res->cmd0 = ST21NFCA_NFCIP1_RES;
161*4882a593Smuzhiyun 	atr_res->cmd1 = ST21NFCA_NFCIP1_ATR_RES;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	memcpy(atr_res->nfcid3, atr_req->nfcid3, 6);
164*4882a593Smuzhiyun 	atr_res->bsi = 0x00;
165*4882a593Smuzhiyun 	atr_res->bri = 0x00;
166*4882a593Smuzhiyun 	atr_res->to = ST21NFCA_DEFAULT_TIMEOUT;
167*4882a593Smuzhiyun 	atr_res->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	if (gb_len) {
170*4882a593Smuzhiyun 		skb_put(skb, gb_len);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 		atr_res->ppi |= ST21NFCA_GB_BIT;
173*4882a593Smuzhiyun 		memcpy(atr_res->gbi, atr_req->gbi, gb_len);
174*4882a593Smuzhiyun 		r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi,
175*4882a593Smuzhiyun 						  gb_len);
176*4882a593Smuzhiyun 		if (r < 0) {
177*4882a593Smuzhiyun 			kfree_skb(skb);
178*4882a593Smuzhiyun 			return r;
179*4882a593Smuzhiyun 		}
180*4882a593Smuzhiyun 	}
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	info->dep_info.curr_nfc_dep_pni = 0;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
185*4882a593Smuzhiyun 				ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
186*4882a593Smuzhiyun 	kfree_skb(skb);
187*4882a593Smuzhiyun 	return r;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun 
st21nfca_tm_recv_atr_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)190*4882a593Smuzhiyun static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
191*4882a593Smuzhiyun 				    struct sk_buff *skb)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	struct st21nfca_atr_req *atr_req;
194*4882a593Smuzhiyun 	size_t gb_len;
195*4882a593Smuzhiyun 	int r;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	skb_trim(skb, skb->len - 1);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	if (!skb->len) {
200*4882a593Smuzhiyun 		r = -EIO;
201*4882a593Smuzhiyun 		goto exit;
202*4882a593Smuzhiyun 	}
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	if (skb->len < ST21NFCA_ATR_REQ_MIN_SIZE) {
205*4882a593Smuzhiyun 		r = -EPROTO;
206*4882a593Smuzhiyun 		goto exit;
207*4882a593Smuzhiyun 	}
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	atr_req = (struct st21nfca_atr_req *)skb->data;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	if (atr_req->length < sizeof(struct st21nfca_atr_req)) {
212*4882a593Smuzhiyun 		r = -EPROTO;
213*4882a593Smuzhiyun 		goto exit;
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	r = st21nfca_tm_send_atr_res(hdev, atr_req);
217*4882a593Smuzhiyun 	if (r)
218*4882a593Smuzhiyun 		goto exit;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	gb_len = skb->len - sizeof(struct st21nfca_atr_req);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
223*4882a593Smuzhiyun 			      NFC_COMM_PASSIVE, atr_req->gbi, gb_len);
224*4882a593Smuzhiyun 	if (r)
225*4882a593Smuzhiyun 		goto exit;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	r = 0;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun exit:
230*4882a593Smuzhiyun 	return r;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
st21nfca_tm_send_psl_res(struct nfc_hci_dev * hdev,struct st21nfca_psl_req * psl_req)233*4882a593Smuzhiyun static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
234*4882a593Smuzhiyun 				    struct st21nfca_psl_req *psl_req)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun 	struct st21nfca_psl_res *psl_res;
237*4882a593Smuzhiyun 	struct sk_buff *skb;
238*4882a593Smuzhiyun 	u8 bitrate[2] = {0, 0};
239*4882a593Smuzhiyun 	int r;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
242*4882a593Smuzhiyun 	if (!skb)
243*4882a593Smuzhiyun 		return -ENOMEM;
244*4882a593Smuzhiyun 	skb_put(skb, sizeof(struct st21nfca_psl_res));
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	psl_res = (struct st21nfca_psl_res *)skb->data;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	psl_res->length = sizeof(struct st21nfca_psl_res);
249*4882a593Smuzhiyun 	psl_res->cmd0 = ST21NFCA_NFCIP1_RES;
250*4882a593Smuzhiyun 	psl_res->cmd1 = ST21NFCA_NFCIP1_PSL_RES;
251*4882a593Smuzhiyun 	psl_res->did = psl_req->did;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
254*4882a593Smuzhiyun 				ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
255*4882a593Smuzhiyun 	if (r < 0)
256*4882a593Smuzhiyun 		goto error;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	/*
259*4882a593Smuzhiyun 	 * ST21NFCA only support P2P passive.
260*4882a593Smuzhiyun 	 * PSL_REQ BRS value != 0 has only a meaning to
261*4882a593Smuzhiyun 	 * change technology to type F.
262*4882a593Smuzhiyun 	 * We change to BITRATE 424Kbits.
263*4882a593Smuzhiyun 	 * In other case switch to BITRATE 106Kbits.
264*4882a593Smuzhiyun 	 */
265*4882a593Smuzhiyun 	if (ST21NFCA_PSL_REQ_SEND_SPEED(psl_req->brs) &&
266*4882a593Smuzhiyun 	    ST21NFCA_PSL_REQ_RECV_SPEED(psl_req->brs)) {
267*4882a593Smuzhiyun 		bitrate[0] = ST21NFCA_CARD_BITRATE_424;
268*4882a593Smuzhiyun 		bitrate[1] = ST21NFCA_CARD_BITRATE_424;
269*4882a593Smuzhiyun 	}
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	/* Send an event to change bitrate change event to card f */
272*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
273*4882a593Smuzhiyun 			ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
274*4882a593Smuzhiyun error:
275*4882a593Smuzhiyun 	kfree_skb(skb);
276*4882a593Smuzhiyun 	return r;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun 
st21nfca_tm_recv_psl_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)279*4882a593Smuzhiyun static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
280*4882a593Smuzhiyun 				    struct sk_buff *skb)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun 	struct st21nfca_psl_req *psl_req;
283*4882a593Smuzhiyun 	int r;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	skb_trim(skb, skb->len - 1);
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	if (!skb->len) {
288*4882a593Smuzhiyun 		r = -EIO;
289*4882a593Smuzhiyun 		goto exit;
290*4882a593Smuzhiyun 	}
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	psl_req = (struct st21nfca_psl_req *)skb->data;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	if (skb->len < sizeof(struct st21nfca_psl_req)) {
295*4882a593Smuzhiyun 		r = -EIO;
296*4882a593Smuzhiyun 		goto exit;
297*4882a593Smuzhiyun 	}
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	r = st21nfca_tm_send_psl_res(hdev, psl_req);
300*4882a593Smuzhiyun exit:
301*4882a593Smuzhiyun 	return r;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
st21nfca_tm_send_dep_res(struct nfc_hci_dev * hdev,struct sk_buff * skb)304*4882a593Smuzhiyun int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun 	int r;
307*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
310*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_RES;
311*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_RES;
312*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = skb->len;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
315*4882a593Smuzhiyun 			ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
316*4882a593Smuzhiyun 	kfree_skb(skb);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	return r;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun EXPORT_SYMBOL(st21nfca_tm_send_dep_res);
321*4882a593Smuzhiyun 
st21nfca_tm_recv_dep_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)322*4882a593Smuzhiyun static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
323*4882a593Smuzhiyun 				    struct sk_buff *skb)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun 	struct st21nfca_dep_req_res *dep_req;
326*4882a593Smuzhiyun 	u8 size;
327*4882a593Smuzhiyun 	int r;
328*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	skb_trim(skb, skb->len - 1);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	size = 4;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	dep_req = (struct st21nfca_dep_req_res *)skb->data;
335*4882a593Smuzhiyun 	if (skb->len < size) {
336*4882a593Smuzhiyun 		r = -EIO;
337*4882a593Smuzhiyun 		goto exit;
338*4882a593Smuzhiyun 	}
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_req->pfb))
341*4882a593Smuzhiyun 		size++;
342*4882a593Smuzhiyun 	if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_req->pfb))
343*4882a593Smuzhiyun 		size++;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (skb->len < size) {
346*4882a593Smuzhiyun 		r = -EIO;
347*4882a593Smuzhiyun 		goto exit;
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	/* Receiving DEP_REQ - Decoding */
351*4882a593Smuzhiyun 	switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
352*4882a593Smuzhiyun 	case ST21NFCA_NFC_DEP_PFB_I_PDU:
353*4882a593Smuzhiyun 		info->dep_info.curr_nfc_dep_pni =
354*4882a593Smuzhiyun 				ST21NFCA_NFC_DEP_PFB_PNI(dep_req->pfb);
355*4882a593Smuzhiyun 		break;
356*4882a593Smuzhiyun 	case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
357*4882a593Smuzhiyun 		pr_err("Received a ACK/NACK PDU\n");
358*4882a593Smuzhiyun 		break;
359*4882a593Smuzhiyun 	case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
360*4882a593Smuzhiyun 		pr_err("Received a SUPERVISOR PDU\n");
361*4882a593Smuzhiyun 		break;
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	skb_pull(skb, size);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	return nfc_tm_data_received(hdev->ndev, skb);
367*4882a593Smuzhiyun exit:
368*4882a593Smuzhiyun 	return r;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
st21nfca_tm_event_send_data(struct nfc_hci_dev * hdev,struct sk_buff * skb)371*4882a593Smuzhiyun static int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev,
372*4882a593Smuzhiyun 				struct sk_buff *skb)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	u8 cmd0, cmd1;
375*4882a593Smuzhiyun 	int r;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	cmd0 = skb->data[1];
378*4882a593Smuzhiyun 	switch (cmd0) {
379*4882a593Smuzhiyun 	case ST21NFCA_NFCIP1_REQ:
380*4882a593Smuzhiyun 		cmd1 = skb->data[2];
381*4882a593Smuzhiyun 		switch (cmd1) {
382*4882a593Smuzhiyun 		case ST21NFCA_NFCIP1_ATR_REQ:
383*4882a593Smuzhiyun 			r = st21nfca_tm_recv_atr_req(hdev, skb);
384*4882a593Smuzhiyun 			break;
385*4882a593Smuzhiyun 		case ST21NFCA_NFCIP1_PSL_REQ:
386*4882a593Smuzhiyun 			r = st21nfca_tm_recv_psl_req(hdev, skb);
387*4882a593Smuzhiyun 			break;
388*4882a593Smuzhiyun 		case ST21NFCA_NFCIP1_DEP_REQ:
389*4882a593Smuzhiyun 			r = st21nfca_tm_recv_dep_req(hdev, skb);
390*4882a593Smuzhiyun 			break;
391*4882a593Smuzhiyun 		default:
392*4882a593Smuzhiyun 			return 1;
393*4882a593Smuzhiyun 		}
394*4882a593Smuzhiyun 		break;
395*4882a593Smuzhiyun 	default:
396*4882a593Smuzhiyun 		return 1;
397*4882a593Smuzhiyun 	}
398*4882a593Smuzhiyun 	return r;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun /*
402*4882a593Smuzhiyun  * Returns:
403*4882a593Smuzhiyun  * <= 0: driver handled the event, skb consumed
404*4882a593Smuzhiyun  *    1: driver does not handle the event, please do standard processing
405*4882a593Smuzhiyun  */
st21nfca_dep_event_received(struct nfc_hci_dev * hdev,u8 event,struct sk_buff * skb)406*4882a593Smuzhiyun int st21nfca_dep_event_received(struct nfc_hci_dev *hdev,
407*4882a593Smuzhiyun 				u8 event, struct sk_buff *skb)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	int r = 0;
410*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	pr_debug("dep event: %d\n", event);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	switch (event) {
415*4882a593Smuzhiyun 	case ST21NFCA_EVT_CARD_ACTIVATED:
416*4882a593Smuzhiyun 		info->dep_info.curr_nfc_dep_pni = 0;
417*4882a593Smuzhiyun 		break;
418*4882a593Smuzhiyun 	case ST21NFCA_EVT_CARD_DEACTIVATED:
419*4882a593Smuzhiyun 		break;
420*4882a593Smuzhiyun 	case ST21NFCA_EVT_FIELD_ON:
421*4882a593Smuzhiyun 		break;
422*4882a593Smuzhiyun 	case ST21NFCA_EVT_FIELD_OFF:
423*4882a593Smuzhiyun 		break;
424*4882a593Smuzhiyun 	case ST21NFCA_EVT_SEND_DATA:
425*4882a593Smuzhiyun 		r = st21nfca_tm_event_send_data(hdev, skb);
426*4882a593Smuzhiyun 		if (r < 0)
427*4882a593Smuzhiyun 			return r;
428*4882a593Smuzhiyun 		return 0;
429*4882a593Smuzhiyun 	default:
430*4882a593Smuzhiyun 		nfc_err(&hdev->ndev->dev, "Unexpected event on card f gate\n");
431*4882a593Smuzhiyun 		return 1;
432*4882a593Smuzhiyun 	}
433*4882a593Smuzhiyun 	kfree_skb(skb);
434*4882a593Smuzhiyun 	return r;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun EXPORT_SYMBOL(st21nfca_dep_event_received);
437*4882a593Smuzhiyun 
st21nfca_im_send_psl_req(struct nfc_hci_dev * hdev,u8 did,u8 bsi,u8 bri,u8 lri)438*4882a593Smuzhiyun static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
439*4882a593Smuzhiyun 				     u8 bri, u8 lri)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun 	struct sk_buff *skb;
442*4882a593Smuzhiyun 	struct st21nfca_psl_req *psl_req;
443*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	skb =
446*4882a593Smuzhiyun 	    alloc_skb(sizeof(struct st21nfca_psl_req) + 1, GFP_KERNEL);
447*4882a593Smuzhiyun 	if (!skb)
448*4882a593Smuzhiyun 		return;
449*4882a593Smuzhiyun 	skb_reserve(skb, 1);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	skb_put(skb, sizeof(struct st21nfca_psl_req));
452*4882a593Smuzhiyun 	psl_req = (struct st21nfca_psl_req *) skb->data;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	psl_req->length = sizeof(struct st21nfca_psl_req);
455*4882a593Smuzhiyun 	psl_req->cmd0 = ST21NFCA_NFCIP1_REQ;
456*4882a593Smuzhiyun 	psl_req->cmd1 = ST21NFCA_NFCIP1_PSL_REQ;
457*4882a593Smuzhiyun 	psl_req->did = did;
458*4882a593Smuzhiyun 	psl_req->brs = (0x30 & bsi << 4) | (bri & 0x03);
459*4882a593Smuzhiyun 	psl_req->fsl = lri;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	st21nfca_im_send_pdu(info, skb);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun #define ST21NFCA_CB_TYPE_READER_F 1
st21nfca_im_recv_atr_res_cb(void * context,struct sk_buff * skb,int err)467*4882a593Smuzhiyun static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
468*4882a593Smuzhiyun 					int err)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = context;
471*4882a593Smuzhiyun 	struct st21nfca_atr_res *atr_res;
472*4882a593Smuzhiyun 	int r;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	if (err != 0)
475*4882a593Smuzhiyun 		return;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	if (!skb)
478*4882a593Smuzhiyun 		return;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	switch (info->async_cb_type) {
481*4882a593Smuzhiyun 	case ST21NFCA_CB_TYPE_READER_F:
482*4882a593Smuzhiyun 		skb_trim(skb, skb->len - 1);
483*4882a593Smuzhiyun 		atr_res = (struct st21nfca_atr_res *)skb->data;
484*4882a593Smuzhiyun 		r = nfc_set_remote_general_bytes(info->hdev->ndev,
485*4882a593Smuzhiyun 				atr_res->gbi,
486*4882a593Smuzhiyun 				skb->len - sizeof(struct st21nfca_atr_res));
487*4882a593Smuzhiyun 		if (r < 0)
488*4882a593Smuzhiyun 			return;
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 		if (atr_res->to >= 0x0e)
491*4882a593Smuzhiyun 			info->dep_info.to = 0x0e;
492*4882a593Smuzhiyun 		else
493*4882a593Smuzhiyun 			info->dep_info.to = atr_res->to + 1;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 		info->dep_info.to |= 0x10;
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 		r = nfc_dep_link_is_up(info->hdev->ndev, info->dep_info.idx,
498*4882a593Smuzhiyun 					NFC_COMM_PASSIVE, NFC_RF_INITIATOR);
499*4882a593Smuzhiyun 		if (r < 0)
500*4882a593Smuzhiyun 			return;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 		info->dep_info.curr_nfc_dep_pni = 0;
503*4882a593Smuzhiyun 		if (ST21NFCA_PP2LRI(atr_res->ppi) != info->dep_info.lri)
504*4882a593Smuzhiyun 			st21nfca_im_send_psl_req(info->hdev, atr_res->did,
505*4882a593Smuzhiyun 						atr_res->bsi, atr_res->bri,
506*4882a593Smuzhiyun 						ST21NFCA_PP2LRI(atr_res->ppi));
507*4882a593Smuzhiyun 		break;
508*4882a593Smuzhiyun 	default:
509*4882a593Smuzhiyun 		kfree_skb(skb);
510*4882a593Smuzhiyun 		break;
511*4882a593Smuzhiyun 	}
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun 
st21nfca_im_send_atr_req(struct nfc_hci_dev * hdev,u8 * gb,size_t gb_len)514*4882a593Smuzhiyun int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
515*4882a593Smuzhiyun {
516*4882a593Smuzhiyun 	struct sk_buff *skb;
517*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
518*4882a593Smuzhiyun 	struct st21nfca_atr_req *atr_req;
519*4882a593Smuzhiyun 	struct nfc_target *target;
520*4882a593Smuzhiyun 	uint size;
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
523*4882a593Smuzhiyun 	size = ST21NFCA_ATR_REQ_MIN_SIZE + gb_len;
524*4882a593Smuzhiyun 	if (size > ST21NFCA_ATR_REQ_MAX_SIZE) {
525*4882a593Smuzhiyun 		PROTOCOL_ERR("14.6.1.1");
526*4882a593Smuzhiyun 		return -EINVAL;
527*4882a593Smuzhiyun 	}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	skb =
530*4882a593Smuzhiyun 	    alloc_skb(sizeof(struct st21nfca_atr_req) + gb_len + 1, GFP_KERNEL);
531*4882a593Smuzhiyun 	if (!skb)
532*4882a593Smuzhiyun 		return -ENOMEM;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	skb_reserve(skb, 1);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	skb_put(skb, sizeof(struct st21nfca_atr_req));
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	atr_req = (struct st21nfca_atr_req *)skb->data;
539*4882a593Smuzhiyun 	memset(atr_req, 0, sizeof(struct st21nfca_atr_req));
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	atr_req->cmd0 = ST21NFCA_NFCIP1_REQ;
542*4882a593Smuzhiyun 	atr_req->cmd1 = ST21NFCA_NFCIP1_ATR_REQ;
543*4882a593Smuzhiyun 	memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
544*4882a593Smuzhiyun 	target = hdev->ndev->targets;
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	if (target->sensf_res_len > 0)
547*4882a593Smuzhiyun 		memcpy(atr_req->nfcid3, target->sensf_res,
548*4882a593Smuzhiyun 				target->sensf_res_len);
549*4882a593Smuzhiyun 	else
550*4882a593Smuzhiyun 		get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	atr_req->did = 0x0;
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	atr_req->bsi = 0x00;
555*4882a593Smuzhiyun 	atr_req->bri = 0x00;
556*4882a593Smuzhiyun 	atr_req->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
557*4882a593Smuzhiyun 	if (gb_len) {
558*4882a593Smuzhiyun 		atr_req->ppi |= ST21NFCA_GB_BIT;
559*4882a593Smuzhiyun 		skb_put_data(skb, gb, gb_len);
560*4882a593Smuzhiyun 	}
561*4882a593Smuzhiyun 	atr_req->length = sizeof(struct st21nfca_atr_req) + hdev->gb_len;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10; /* timeout */
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
566*4882a593Smuzhiyun 	info->async_cb_context = info;
567*4882a593Smuzhiyun 	info->async_cb = st21nfca_im_recv_atr_res_cb;
568*4882a593Smuzhiyun 	info->dep_info.bri = atr_req->bri;
569*4882a593Smuzhiyun 	info->dep_info.bsi = atr_req->bsi;
570*4882a593Smuzhiyun 	info->dep_info.lri = ST21NFCA_PP2LRI(atr_req->ppi);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
573*4882a593Smuzhiyun 				ST21NFCA_WR_XCHG_DATA, skb->data,
574*4882a593Smuzhiyun 				skb->len, info->async_cb, info);
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun EXPORT_SYMBOL(st21nfca_im_send_atr_req);
577*4882a593Smuzhiyun 
st21nfca_im_recv_dep_res_cb(void * context,struct sk_buff * skb,int err)578*4882a593Smuzhiyun static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
579*4882a593Smuzhiyun 					int err)
580*4882a593Smuzhiyun {
581*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = context;
582*4882a593Smuzhiyun 	struct st21nfca_dep_req_res *dep_res;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	int size;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	if (err != 0)
587*4882a593Smuzhiyun 		return;
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	if (!skb)
590*4882a593Smuzhiyun 		return;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	switch (info->async_cb_type) {
593*4882a593Smuzhiyun 	case ST21NFCA_CB_TYPE_READER_F:
594*4882a593Smuzhiyun 		dep_res = (struct st21nfca_dep_req_res *)skb->data;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 		size = 3;
597*4882a593Smuzhiyun 		if (skb->len < size)
598*4882a593Smuzhiyun 			goto exit;
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 		if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_res->pfb))
601*4882a593Smuzhiyun 			size++;
602*4882a593Smuzhiyun 		if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_res->pfb))
603*4882a593Smuzhiyun 			size++;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 		if (skb->len < size)
606*4882a593Smuzhiyun 			goto exit;
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 		skb_trim(skb, skb->len - 1);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 		/* Receiving DEP_REQ - Decoding */
611*4882a593Smuzhiyun 		switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_res->pfb)) {
612*4882a593Smuzhiyun 		case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
613*4882a593Smuzhiyun 			pr_err("Received a ACK/NACK PDU\n");
614*4882a593Smuzhiyun 			fallthrough;
615*4882a593Smuzhiyun 		case ST21NFCA_NFC_DEP_PFB_I_PDU:
616*4882a593Smuzhiyun 			info->dep_info.curr_nfc_dep_pni =
617*4882a593Smuzhiyun 			    ST21NFCA_NFC_DEP_PFB_PNI(dep_res->pfb + 1);
618*4882a593Smuzhiyun 			size++;
619*4882a593Smuzhiyun 			skb_pull(skb, size);
620*4882a593Smuzhiyun 			nfc_tm_data_received(info->hdev->ndev, skb);
621*4882a593Smuzhiyun 			break;
622*4882a593Smuzhiyun 		case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
623*4882a593Smuzhiyun 			pr_err("Received a SUPERVISOR PDU\n");
624*4882a593Smuzhiyun 			skb_pull(skb, size);
625*4882a593Smuzhiyun 			*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
626*4882a593Smuzhiyun 			*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
627*4882a593Smuzhiyun 			*(u8 *)skb_push(skb, 1) = skb->len;
628*4882a593Smuzhiyun 			*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10;
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 			st21nfca_im_send_pdu(info, skb);
631*4882a593Smuzhiyun 			break;
632*4882a593Smuzhiyun 		}
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 		return;
635*4882a593Smuzhiyun 	default:
636*4882a593Smuzhiyun 		break;
637*4882a593Smuzhiyun 	}
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun exit:
640*4882a593Smuzhiyun 	kfree_skb(skb);
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun 
st21nfca_im_send_dep_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)643*4882a593Smuzhiyun int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
648*4882a593Smuzhiyun 	info->async_cb_context = info;
649*4882a593Smuzhiyun 	info->async_cb = st21nfca_im_recv_dep_res_cb;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
652*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
653*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
654*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = skb->len;
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 	*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10;
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
659*4882a593Smuzhiyun 				      ST21NFCA_WR_XCHG_DATA,
660*4882a593Smuzhiyun 				      skb->data, skb->len,
661*4882a593Smuzhiyun 				      info->async_cb, info);
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun EXPORT_SYMBOL(st21nfca_im_send_dep_req);
664*4882a593Smuzhiyun 
st21nfca_dep_init(struct nfc_hci_dev * hdev)665*4882a593Smuzhiyun void st21nfca_dep_init(struct nfc_hci_dev *hdev)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	INIT_WORK(&info->dep_info.tx_work, st21nfca_tx_work);
670*4882a593Smuzhiyun 	info->dep_info.curr_nfc_dep_pni = 0;
671*4882a593Smuzhiyun 	info->dep_info.idx = 0;
672*4882a593Smuzhiyun 	info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun EXPORT_SYMBOL(st21nfca_dep_init);
675*4882a593Smuzhiyun 
st21nfca_dep_deinit(struct nfc_hci_dev * hdev)676*4882a593Smuzhiyun void st21nfca_dep_deinit(struct nfc_hci_dev *hdev)
677*4882a593Smuzhiyun {
678*4882a593Smuzhiyun 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	cancel_work_sync(&info->dep_info.tx_work);
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun EXPORT_SYMBOL(st21nfca_dep_deinit);
683