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