blob: 562bec9ad8d9db7f3e964950920539ea90e5acd4 [file] [log] [blame]
Thierry Escande7d0911c2013-09-19 17:55:29 +02001/*
2 * NFC Digital Protocol stack
3 * Copyright (c) 2013, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
Samuel Ortizc5da0e42013-09-20 09:05:48 +020016#define pr_fmt(fmt) "digital: %s: " fmt, __func__
17
Thierry Escande7d0911c2013-09-19 17:55:29 +020018#include "digital.h"
19
20#define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4
21#define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5
22
23#define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0
24
25#define DIGITAL_CMD_ATR_REQ 0x00
26#define DIGITAL_CMD_ATR_RES 0x01
27#define DIGITAL_CMD_PSL_REQ 0x04
28#define DIGITAL_CMD_PSL_RES 0x05
29#define DIGITAL_CMD_DEP_REQ 0x06
30#define DIGITAL_CMD_DEP_RES 0x07
31
32#define DIGITAL_ATR_REQ_MIN_SIZE 16
33#define DIGITAL_ATR_REQ_MAX_SIZE 64
34
Thierry Escande7d0911c2013-09-19 17:55:29 +020035#define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30
36#define DIGITAL_GB_BIT 0x02
37
38#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
39
40#define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
41
42#define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
43 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
44#define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & 0x10)
45#define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
46#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
47#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
48
49#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
50#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
51#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
52
53struct digital_atr_req {
54 u8 dir;
55 u8 cmd;
56 u8 nfcid3[10];
57 u8 did;
58 u8 bs;
59 u8 br;
60 u8 pp;
61 u8 gb[0];
62} __packed;
63
64struct digital_atr_res {
65 u8 dir;
66 u8 cmd;
67 u8 nfcid3[10];
68 u8 did;
69 u8 bs;
70 u8 br;
71 u8 to;
72 u8 pp;
73 u8 gb[0];
74} __packed;
75
76struct digital_psl_req {
77 u8 dir;
78 u8 cmd;
79 u8 did;
80 u8 brs;
81 u8 fsl;
82} __packed;
83
84struct digital_psl_res {
85 u8 dir;
86 u8 cmd;
87 u8 did;
88} __packed;
89
90struct digital_dep_req_res {
91 u8 dir;
92 u8 cmd;
93 u8 pfb;
94} __packed;
95
96static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
97 struct sk_buff *resp);
98
99static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
100 struct sk_buff *skb)
101{
102 skb_push(skb, sizeof(u8));
103
104 skb->data[0] = skb->len;
105
106 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
107 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
108}
109
110static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
111 struct sk_buff *skb)
112{
113 u8 size;
114
115 if (skb->len < 2)
116 return -EIO;
117
118 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
119 skb_pull(skb, sizeof(u8));
120
121 size = skb->data[0];
122 if (size != skb->len)
123 return -EIO;
124
125 skb_pull(skb, sizeof(u8));
126
127 return 0;
128}
129
130static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
131 struct sk_buff *resp)
132{
133 struct nfc_target *target = arg;
134 struct digital_atr_res *atr_res;
135 u8 gb_len;
136 int rc;
137
138 if (IS_ERR(resp)) {
139 rc = PTR_ERR(resp);
140 resp = NULL;
141 goto exit;
142 }
143
144 rc = ddev->skb_check_crc(resp);
145 if (rc) {
146 PROTOCOL_ERR("14.4.1.6");
147 goto exit;
148 }
149
150 rc = digital_skb_pull_dep_sod(ddev, resp);
151 if (rc) {
152 PROTOCOL_ERR("14.4.1.2");
153 goto exit;
154 }
155
156 if (resp->len < sizeof(struct digital_atr_res)) {
157 rc = -EIO;
158 goto exit;
159 }
160
161 gb_len = resp->len - sizeof(struct digital_atr_res);
162
163 atr_res = (struct digital_atr_res *)resp->data;
164
165 rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
166 if (rc)
167 goto exit;
168
169 rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
170 NFC_RF_INITIATOR);
171
172 ddev->curr_nfc_dep_pni = 0;
173
174exit:
175 dev_kfree_skb(resp);
176
177 if (rc)
178 ddev->curr_protocol = 0;
179}
180
181int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
182 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
183 size_t gb_len)
184{
185 struct sk_buff *skb;
186 struct digital_atr_req *atr_req;
187 uint size;
188
189 size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
190
191 if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
192 PROTOCOL_ERR("14.6.1.1");
193 return -EINVAL;
194 }
195
196 skb = digital_skb_alloc(ddev, size);
197 if (!skb)
198 return -ENOMEM;
199
200 skb_put(skb, sizeof(struct digital_atr_req));
201
202 atr_req = (struct digital_atr_req *)skb->data;
203 memset(atr_req, 0, sizeof(struct digital_atr_req));
204
205 atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
206 atr_req->cmd = DIGITAL_CMD_ATR_REQ;
207 if (target->nfcid2_len)
Thierry Escande4f319e32014-01-02 11:58:14 +0100208 memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200209 else
Thierry Escande4f319e32014-01-02 11:58:14 +0100210 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200211
212 atr_req->did = 0;
213 atr_req->bs = 0;
214 atr_req->br = 0;
215
216 atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
217
218 if (gb_len) {
219 atr_req->pp |= DIGITAL_GB_BIT;
220 memcpy(skb_put(skb, gb_len), gb, gb_len);
221 }
222
223 digital_skb_push_dep_sod(ddev, skb);
224
225 ddev->skb_add_crc(skb);
226
227 digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, target);
228
229 return 0;
230}
231
232static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
233 struct digital_data_exch *data_exch, u8 rtox)
234{
235 struct digital_dep_req_res *dep_req;
236 struct sk_buff *skb;
237 int rc;
238
239 skb = digital_skb_alloc(ddev, 1);
240 if (!skb)
241 return -ENOMEM;
242
243 *skb_put(skb, 1) = rtox;
244
245 skb_push(skb, sizeof(struct digital_dep_req_res));
246
247 dep_req = (struct digital_dep_req_res *)skb->data;
248
249 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
250 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
251 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
252 DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
253
254 digital_skb_push_dep_sod(ddev, skb);
255
256 ddev->skb_add_crc(skb);
257
258 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
259 data_exch);
260
261 return rc;
262}
263
264static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
265 struct sk_buff *resp)
266{
267 struct digital_data_exch *data_exch = arg;
268 struct digital_dep_req_res *dep_res;
269 u8 pfb;
270 uint size;
271 int rc;
272
273 if (IS_ERR(resp)) {
274 rc = PTR_ERR(resp);
275 resp = NULL;
276 goto exit;
277 }
278
279 rc = ddev->skb_check_crc(resp);
280 if (rc) {
281 PROTOCOL_ERR("14.4.1.6");
282 goto error;
283 }
284
285 rc = digital_skb_pull_dep_sod(ddev, resp);
286 if (rc) {
287 PROTOCOL_ERR("14.4.1.2");
288 goto exit;
289 }
290
291 dep_res = (struct digital_dep_req_res *)resp->data;
292
293 if (resp->len < sizeof(struct digital_dep_req_res) ||
294 dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
295 dep_res->cmd != DIGITAL_CMD_DEP_RES) {
296 rc = -EIO;
297 goto error;
298 }
299
300 pfb = dep_res->pfb;
301
302 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
303 case DIGITAL_NFC_DEP_PFB_I_PDU:
304 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
305 PROTOCOL_ERR("14.12.3.3");
306 rc = -EIO;
307 goto error;
308 }
309
310 ddev->curr_nfc_dep_pni =
311 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
312 rc = 0;
313 break;
314
315 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200316 pr_err("Received a ACK/NACK PDU\n");
Thierry Escande7d0911c2013-09-19 17:55:29 +0200317 rc = -EIO;
318 goto error;
319
320 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
321 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
322 rc = -EINVAL;
323 goto error;
324 }
325
326 rc = digital_in_send_rtox(ddev, data_exch, resp->data[3]);
327 if (rc)
328 goto error;
329
330 kfree_skb(resp);
331 return;
332 }
333
334 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
Samuel Ortiz26042532013-09-20 16:56:40 +0200335 pr_err("MI bit set. Chained PDU not supported\n");
Thierry Escande7d0911c2013-09-19 17:55:29 +0200336 rc = -EIO;
337 goto error;
338 }
339
340 size = sizeof(struct digital_dep_req_res);
341
342 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb))
343 size++;
344
345 if (size > resp->len) {
346 rc = -EIO;
347 goto error;
348 }
349
350 skb_pull(resp, size);
351
352exit:
353 data_exch->cb(data_exch->cb_context, resp, rc);
354
355error:
356 kfree(data_exch);
357
358 if (rc)
359 kfree_skb(resp);
360}
361
362int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
363 struct nfc_target *target, struct sk_buff *skb,
364 struct digital_data_exch *data_exch)
365{
366 struct digital_dep_req_res *dep_req;
367
368 skb_push(skb, sizeof(struct digital_dep_req_res));
369
370 dep_req = (struct digital_dep_req_res *)skb->data;
371 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
372 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
373 dep_req->pfb = ddev->curr_nfc_dep_pni;
374
375 digital_skb_push_dep_sod(ddev, skb);
376
377 ddev->skb_add_crc(skb);
378
379 return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
380 data_exch);
381}
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200382
383static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
384 struct sk_buff *resp)
385{
386 int rc;
387 struct digital_dep_req_res *dep_req;
388 size_t size;
389
390 if (IS_ERR(resp)) {
391 rc = PTR_ERR(resp);
392 resp = NULL;
393 goto exit;
394 }
395
396 rc = ddev->skb_check_crc(resp);
397 if (rc) {
398 PROTOCOL_ERR("14.4.1.6");
399 goto exit;
400 }
401
402 rc = digital_skb_pull_dep_sod(ddev, resp);
403 if (rc) {
404 PROTOCOL_ERR("14.4.1.2");
405 goto exit;
406 }
407
408 size = sizeof(struct digital_dep_req_res);
409 dep_req = (struct digital_dep_req_res *)resp->data;
410
411 if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
412 dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
413 rc = -EIO;
414 goto exit;
415 }
416
417 if (DIGITAL_NFC_DEP_DID_BIT_SET(dep_req->pfb))
418 size++;
419
420 if (resp->len < size) {
421 rc = -EIO;
422 goto exit;
423 }
424
425 switch (DIGITAL_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
426 case DIGITAL_NFC_DEP_PFB_I_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200427 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200428 ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(dep_req->pfb);
429 break;
430 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200431 pr_err("Received a ACK/NACK PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200432 rc = -EINVAL;
433 goto exit;
434 break;
435 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200436 pr_err("Received a SUPERVISOR PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200437 rc = -EINVAL;
438 goto exit;
439 break;
440 }
441
442 skb_pull(resp, size);
443
444 rc = nfc_tm_data_received(ddev->nfc_dev, resp);
445
446exit:
447 if (rc)
448 kfree_skb(resp);
449}
450
451int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
452{
453 struct digital_dep_req_res *dep_res;
454
455 skb_push(skb, sizeof(struct digital_dep_req_res));
456 dep_res = (struct digital_dep_req_res *)skb->data;
457
458 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
459 dep_res->cmd = DIGITAL_CMD_DEP_RES;
460 dep_res->pfb = ddev->curr_nfc_dep_pni;
461
462 digital_skb_push_dep_sod(ddev, skb);
463
464 ddev->skb_add_crc(skb);
465
466 return digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
467 NULL);
468}
469
470static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
471 void *arg, struct sk_buff *resp)
472{
Thierry Escande67af1d72014-01-02 11:58:13 +0100473 u8 rf_tech = (unsigned long)arg;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200474
475 if (IS_ERR(resp))
476 return;
477
478 digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
479
480 digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
481
482 dev_kfree_skb(resp);
483}
484
485static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
486 u8 rf_tech)
487{
488 struct digital_psl_res *psl_res;
489 struct sk_buff *skb;
490 int rc;
491
492 skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
493 if (!skb)
494 return -ENOMEM;
495
496 skb_put(skb, sizeof(struct digital_psl_res));
497
498 psl_res = (struct digital_psl_res *)skb->data;
499
500 psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
501 psl_res->cmd = DIGITAL_CMD_PSL_RES;
502 psl_res->did = did;
503
504 digital_skb_push_dep_sod(ddev, skb);
505
506 ddev->skb_add_crc(skb);
507
508 rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
Thierry Escande67af1d72014-01-02 11:58:13 +0100509 (void *)(unsigned long)rf_tech);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200510
511 if (rc)
512 kfree_skb(skb);
513
514 return rc;
515}
516
517static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
518 struct sk_buff *resp)
519{
520 int rc;
521 struct digital_psl_req *psl_req;
522 u8 rf_tech;
523 u8 dsi;
524
525 if (IS_ERR(resp)) {
526 rc = PTR_ERR(resp);
527 resp = NULL;
528 goto exit;
529 }
530
531 rc = ddev->skb_check_crc(resp);
532 if (rc) {
533 PROTOCOL_ERR("14.4.1.6");
534 goto exit;
535 }
536
537 rc = digital_skb_pull_dep_sod(ddev, resp);
538 if (rc) {
539 PROTOCOL_ERR("14.4.1.2");
540 goto exit;
541 }
542
543 psl_req = (struct digital_psl_req *)resp->data;
544
545 if (resp->len != sizeof(struct digital_psl_req) ||
546 psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
547 psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
548 rc = -EIO;
549 goto exit;
550 }
551
552 dsi = (psl_req->brs >> 3) & 0x07;
553 switch (dsi) {
554 case 0:
555 rf_tech = NFC_DIGITAL_RF_TECH_106A;
556 break;
557 case 1:
558 rf_tech = NFC_DIGITAL_RF_TECH_212F;
559 break;
560 case 2:
561 rf_tech = NFC_DIGITAL_RF_TECH_424F;
562 break;
563 default:
Samuel Ortiz26042532013-09-20 16:56:40 +0200564 pr_err("Unsuported dsi value %d\n", dsi);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200565 goto exit;
566 }
567
568 rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
569
570exit:
571 kfree_skb(resp);
572}
573
574static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
575 void *arg, struct sk_buff *resp)
576{
577 int offset;
578
579 if (IS_ERR(resp)) {
580 digital_poll_next_tech(ddev);
581 return;
582 }
583
584 offset = 2;
585 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
586 offset++;
587
588 if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
589 digital_tg_recv_psl_req(ddev, arg, resp);
590 else
591 digital_tg_recv_dep_req(ddev, arg, resp);
592}
593
594static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
595 struct digital_atr_req *atr_req)
596{
597 struct digital_atr_res *atr_res;
598 struct sk_buff *skb;
599 u8 *gb;
600 size_t gb_len;
601 int rc;
602
603 gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
604 if (!gb)
605 gb_len = 0;
606
607 skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
608 if (!skb)
609 return -ENOMEM;
610
611 skb_put(skb, sizeof(struct digital_atr_res));
612 atr_res = (struct digital_atr_res *)skb->data;
613
614 memset(atr_res, 0, sizeof(struct digital_atr_res));
615
616 atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
617 atr_res->cmd = DIGITAL_CMD_ATR_RES;
618 memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
619 atr_res->to = 8;
620 atr_res->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
621 if (gb_len) {
622 skb_put(skb, gb_len);
623
624 atr_res->pp |= DIGITAL_GB_BIT;
625 memcpy(atr_res->gb, gb, gb_len);
626 }
627
628 digital_skb_push_dep_sod(ddev, skb);
629
630 ddev->skb_add_crc(skb);
631
632 rc = digital_tg_send_cmd(ddev, skb, 999,
633 digital_tg_send_atr_res_complete, NULL);
634 if (rc) {
635 kfree_skb(skb);
636 return rc;
637 }
638
639 return rc;
640}
641
642void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
643 struct sk_buff *resp)
644{
645 int rc;
646 struct digital_atr_req *atr_req;
647 size_t gb_len, min_size;
648
649 if (IS_ERR(resp)) {
650 rc = PTR_ERR(resp);
651 resp = NULL;
652 goto exit;
653 }
654
655 if (!resp->len) {
656 rc = -EIO;
657 goto exit;
658 }
659
660 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
661 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
662
663 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_106A;
664 ddev->skb_add_crc = digital_skb_add_crc_a;
665 ddev->skb_check_crc = digital_skb_check_crc_a;
666 } else {
667 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
668
669 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_212F;
670 ddev->skb_add_crc = digital_skb_add_crc_f;
671 ddev->skb_check_crc = digital_skb_check_crc_f;
672 }
673
674 if (resp->len < min_size) {
675 rc = -EIO;
676 goto exit;
677 }
678
679 if (DIGITAL_DRV_CAPS_TG_CRC(ddev)) {
680 ddev->skb_add_crc = digital_skb_add_crc_none;
681 ddev->skb_check_crc = digital_skb_check_crc_none;
682 }
683
Thierry Escande48e10442014-01-06 23:34:37 +0100684 ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
685
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200686 rc = ddev->skb_check_crc(resp);
687 if (rc) {
688 PROTOCOL_ERR("14.4.1.6");
689 goto exit;
690 }
691
692 rc = digital_skb_pull_dep_sod(ddev, resp);
693 if (rc) {
694 PROTOCOL_ERR("14.4.1.2");
695 goto exit;
696 }
697
698 atr_req = (struct digital_atr_req *)resp->data;
699
700 if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
701 atr_req->cmd != DIGITAL_CMD_ATR_REQ) {
702 rc = -EINVAL;
703 goto exit;
704 }
705
706 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
707 NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
708 if (rc)
709 goto exit;
710
711 rc = digital_tg_send_atr_res(ddev, atr_req);
712 if (rc)
713 goto exit;
714
715 gb_len = resp->len - sizeof(struct digital_atr_req);
716 rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
717 NFC_COMM_PASSIVE, atr_req->gb, gb_len);
718 if (rc)
719 goto exit;
720
721 ddev->poll_tech_count = 0;
722
723 rc = 0;
724exit:
725 if (rc)
726 digital_poll_next_tech(ddev);
727
728 dev_kfree_skb(resp);
729}