blob: d5e669b0dedf2b4d3db9bf79a6fcb0b42b05c9c0 [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
Mark A. Greer05afedc2014-09-23 16:38:05 -070035#define DIGITAL_DID_MAX 14
36
Thierry Escande7d0911c2013-09-19 17:55:29 +020037#define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30
Mark A. Greerdddb3da2014-07-22 20:18:01 -070038#define DIGITAL_FSL_BITS_PAYLOAD_SIZE_254B \
39 (DIGITAL_LR_BITS_PAYLOAD_SIZE_254B >> 4)
Thierry Escande7d0911c2013-09-19 17:55:29 +020040#define DIGITAL_GB_BIT 0x02
41
42#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
43
44#define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
Mark A. Greer05afedc2014-09-23 16:38:05 -070045#define DIGITAL_NFC_DEP_PFB_DID_BIT 0x04
Thierry Escande7d0911c2013-09-19 17:55:29 +020046
47#define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
48 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
49#define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & 0x10)
50#define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
Mark A. Greer05afedc2014-09-23 16:38:05 -070051#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020052#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
53
54#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
55#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
56#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
57
58struct digital_atr_req {
59 u8 dir;
60 u8 cmd;
61 u8 nfcid3[10];
62 u8 did;
63 u8 bs;
64 u8 br;
65 u8 pp;
66 u8 gb[0];
67} __packed;
68
69struct digital_atr_res {
70 u8 dir;
71 u8 cmd;
72 u8 nfcid3[10];
73 u8 did;
74 u8 bs;
75 u8 br;
76 u8 to;
77 u8 pp;
78 u8 gb[0];
79} __packed;
80
81struct digital_psl_req {
82 u8 dir;
83 u8 cmd;
84 u8 did;
85 u8 brs;
86 u8 fsl;
87} __packed;
88
89struct digital_psl_res {
90 u8 dir;
91 u8 cmd;
92 u8 did;
93} __packed;
94
95struct digital_dep_req_res {
96 u8 dir;
97 u8 cmd;
98 u8 pfb;
99} __packed;
100
101static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
102 struct sk_buff *resp);
103
104static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
105 struct sk_buff *skb)
106{
107 skb_push(skb, sizeof(u8));
108
109 skb->data[0] = skb->len;
110
111 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
112 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
113}
114
115static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
116 struct sk_buff *skb)
117{
118 u8 size;
119
120 if (skb->len < 2)
121 return -EIO;
122
123 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
124 skb_pull(skb, sizeof(u8));
125
126 size = skb->data[0];
127 if (size != skb->len)
128 return -EIO;
129
130 skb_pull(skb, sizeof(u8));
131
132 return 0;
133}
134
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700135static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg,
136 struct sk_buff *resp)
137{
138 struct nfc_target *target = arg;
139 struct digital_psl_res *psl_res;
140 int rc;
141
142 if (IS_ERR(resp)) {
143 rc = PTR_ERR(resp);
144 resp = NULL;
145 goto exit;
146 }
147
148 rc = ddev->skb_check_crc(resp);
149 if (rc) {
150 PROTOCOL_ERR("14.4.1.6");
151 goto exit;
152 }
153
154 rc = digital_skb_pull_dep_sod(ddev, resp);
155 if (rc) {
156 PROTOCOL_ERR("14.4.1.2");
157 goto exit;
158 }
159
160 psl_res = (struct digital_psl_res *)resp->data;
161
162 if ((resp->len != sizeof(*psl_res)) ||
163 (psl_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN) ||
164 (psl_res->cmd != DIGITAL_CMD_PSL_RES)) {
165 rc = -EIO;
166 goto exit;
167 }
168
169 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
170 NFC_DIGITAL_RF_TECH_424F);
171 if (rc)
172 goto exit;
173
174 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
175 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
176 if (rc)
177 goto exit;
178
179 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev) &&
180 (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)) {
181 ddev->skb_add_crc = digital_skb_add_crc_f;
182 ddev->skb_check_crc = digital_skb_check_crc_f;
183 }
184
185 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_424F;
186
187 nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
188 NFC_RF_INITIATOR);
189
190 ddev->curr_nfc_dep_pni = 0;
191
192exit:
193 dev_kfree_skb(resp);
194
195 if (rc)
196 ddev->curr_protocol = 0;
197}
198
199static int digital_in_send_psl_req(struct nfc_digital_dev *ddev,
200 struct nfc_target *target)
201{
202 struct sk_buff *skb;
203 struct digital_psl_req *psl_req;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700204 int rc;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700205
206 skb = digital_skb_alloc(ddev, sizeof(*psl_req));
207 if (!skb)
208 return -ENOMEM;
209
210 skb_put(skb, sizeof(*psl_req));
211
212 psl_req = (struct digital_psl_req *)skb->data;
213
214 psl_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
215 psl_req->cmd = DIGITAL_CMD_PSL_REQ;
216 psl_req->did = 0;
217 psl_req->brs = (0x2 << 3) | 0x2; /* 424F both directions */
218 psl_req->fsl = DIGITAL_FSL_BITS_PAYLOAD_SIZE_254B;
219
220 digital_skb_push_dep_sod(ddev, skb);
221
222 ddev->skb_add_crc(skb);
223
Mark A. Greerb15829b2014-09-23 16:38:02 -0700224 rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res,
225 target);
226 if (rc)
227 kfree_skb(skb);
228
229 return rc;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700230}
231
Thierry Escande7d0911c2013-09-19 17:55:29 +0200232static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
233 struct sk_buff *resp)
234{
235 struct nfc_target *target = arg;
236 struct digital_atr_res *atr_res;
237 u8 gb_len;
238 int rc;
239
240 if (IS_ERR(resp)) {
241 rc = PTR_ERR(resp);
242 resp = NULL;
243 goto exit;
244 }
245
246 rc = ddev->skb_check_crc(resp);
247 if (rc) {
248 PROTOCOL_ERR("14.4.1.6");
249 goto exit;
250 }
251
252 rc = digital_skb_pull_dep_sod(ddev, resp);
253 if (rc) {
254 PROTOCOL_ERR("14.4.1.2");
255 goto exit;
256 }
257
258 if (resp->len < sizeof(struct digital_atr_res)) {
259 rc = -EIO;
260 goto exit;
261 }
262
263 gb_len = resp->len - sizeof(struct digital_atr_res);
264
265 atr_res = (struct digital_atr_res *)resp->data;
266
267 rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
268 if (rc)
269 goto exit;
270
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700271 if ((ddev->protocols & NFC_PROTO_FELICA_MASK) &&
272 (ddev->curr_rf_tech != NFC_DIGITAL_RF_TECH_424F)) {
273 rc = digital_in_send_psl_req(ddev, target);
274 if (!rc)
275 goto exit;
276 }
277
Thierry Escande7d0911c2013-09-19 17:55:29 +0200278 rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
279 NFC_RF_INITIATOR);
280
281 ddev->curr_nfc_dep_pni = 0;
282
283exit:
284 dev_kfree_skb(resp);
285
286 if (rc)
287 ddev->curr_protocol = 0;
288}
289
290int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
291 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
292 size_t gb_len)
293{
294 struct sk_buff *skb;
295 struct digital_atr_req *atr_req;
296 uint size;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700297 int rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200298
299 size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
300
301 if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
302 PROTOCOL_ERR("14.6.1.1");
303 return -EINVAL;
304 }
305
306 skb = digital_skb_alloc(ddev, size);
307 if (!skb)
308 return -ENOMEM;
309
310 skb_put(skb, sizeof(struct digital_atr_req));
311
312 atr_req = (struct digital_atr_req *)skb->data;
313 memset(atr_req, 0, sizeof(struct digital_atr_req));
314
315 atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
316 atr_req->cmd = DIGITAL_CMD_ATR_REQ;
317 if (target->nfcid2_len)
Thierry Escande4f319e32014-01-02 11:58:14 +0100318 memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200319 else
Thierry Escande4f319e32014-01-02 11:58:14 +0100320 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200321
322 atr_req->did = 0;
323 atr_req->bs = 0;
324 atr_req->br = 0;
325
326 atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
327
328 if (gb_len) {
329 atr_req->pp |= DIGITAL_GB_BIT;
330 memcpy(skb_put(skb, gb_len), gb, gb_len);
331 }
332
333 digital_skb_push_dep_sod(ddev, skb);
334
335 ddev->skb_add_crc(skb);
336
Mark A. Greerb15829b2014-09-23 16:38:02 -0700337 rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res,
338 target);
339 if (rc)
340 kfree_skb(skb);
341
342 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200343}
344
345static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
346 struct digital_data_exch *data_exch, u8 rtox)
347{
348 struct digital_dep_req_res *dep_req;
349 struct sk_buff *skb;
350 int rc;
351
352 skb = digital_skb_alloc(ddev, 1);
353 if (!skb)
354 return -ENOMEM;
355
356 *skb_put(skb, 1) = rtox;
357
358 skb_push(skb, sizeof(struct digital_dep_req_res));
359
360 dep_req = (struct digital_dep_req_res *)skb->data;
361
362 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
363 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
364 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
365 DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
366
367 digital_skb_push_dep_sod(ddev, skb);
368
369 ddev->skb_add_crc(skb);
370
371 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
372 data_exch);
Mark A. Greerb15829b2014-09-23 16:38:02 -0700373 if (rc)
374 kfree_skb(skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200375
376 return rc;
377}
378
379static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
380 struct sk_buff *resp)
381{
382 struct digital_data_exch *data_exch = arg;
383 struct digital_dep_req_res *dep_res;
384 u8 pfb;
385 uint size;
386 int rc;
387
388 if (IS_ERR(resp)) {
389 rc = PTR_ERR(resp);
390 resp = NULL;
391 goto exit;
392 }
393
394 rc = ddev->skb_check_crc(resp);
395 if (rc) {
396 PROTOCOL_ERR("14.4.1.6");
397 goto error;
398 }
399
400 rc = digital_skb_pull_dep_sod(ddev, resp);
401 if (rc) {
402 PROTOCOL_ERR("14.4.1.2");
403 goto exit;
404 }
405
Mark A. Greer6ce30662014-09-23 16:38:03 -0700406 size = sizeof(struct digital_dep_req_res);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200407 dep_res = (struct digital_dep_req_res *)resp->data;
408
Mark A. Greer6ce30662014-09-23 16:38:03 -0700409 if (resp->len < size || dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
Thierry Escande7d0911c2013-09-19 17:55:29 +0200410 dep_res->cmd != DIGITAL_CMD_DEP_RES) {
411 rc = -EIO;
412 goto error;
413 }
414
415 pfb = dep_res->pfb;
416
Mark A. Greer3bc3f882014-09-23 16:38:04 -0700417 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
418 PROTOCOL_ERR("14.8.2.1");
419 rc = -EIO;
420 goto error;
421 }
Mark A. Greer6ce30662014-09-23 16:38:03 -0700422
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700423 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
424 rc = -EIO;
425 goto exit;
426 }
427
Mark A. Greer6ce30662014-09-23 16:38:03 -0700428 if (size > resp->len) {
429 rc = -EIO;
430 goto error;
431 }
432
433 skb_pull(resp, size);
434
Thierry Escande7d0911c2013-09-19 17:55:29 +0200435 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
436 case DIGITAL_NFC_DEP_PFB_I_PDU:
437 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
438 PROTOCOL_ERR("14.12.3.3");
439 rc = -EIO;
440 goto error;
441 }
442
443 ddev->curr_nfc_dep_pni =
444 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
445 rc = 0;
446 break;
447
448 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200449 pr_err("Received a ACK/NACK PDU\n");
Thierry Escande7d0911c2013-09-19 17:55:29 +0200450 rc = -EIO;
451 goto error;
452
453 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
454 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
455 rc = -EINVAL;
456 goto error;
457 }
458
Mark A. Greer6ce30662014-09-23 16:38:03 -0700459 rc = digital_in_send_rtox(ddev, data_exch, resp->data[0]);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200460 if (rc)
461 goto error;
462
463 kfree_skb(resp);
464 return;
465 }
466
467 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
Samuel Ortiz26042532013-09-20 16:56:40 +0200468 pr_err("MI bit set. Chained PDU not supported\n");
Thierry Escande7d0911c2013-09-19 17:55:29 +0200469 rc = -EIO;
470 goto error;
471 }
472
Thierry Escande7d0911c2013-09-19 17:55:29 +0200473exit:
474 data_exch->cb(data_exch->cb_context, resp, rc);
475
476error:
477 kfree(data_exch);
478
479 if (rc)
480 kfree_skb(resp);
481}
482
483int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
484 struct nfc_target *target, struct sk_buff *skb,
485 struct digital_data_exch *data_exch)
486{
487 struct digital_dep_req_res *dep_req;
488
489 skb_push(skb, sizeof(struct digital_dep_req_res));
490
491 dep_req = (struct digital_dep_req_res *)skb->data;
492 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
493 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
494 dep_req->pfb = ddev->curr_nfc_dep_pni;
495
496 digital_skb_push_dep_sod(ddev, skb);
497
498 ddev->skb_add_crc(skb);
499
500 return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
501 data_exch);
502}
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200503
Thierry Escandeb711ad52014-01-06 23:34:48 +0100504static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
505{
506 ddev->curr_rf_tech = rf_tech;
507
508 ddev->skb_add_crc = digital_skb_add_crc_none;
509 ddev->skb_check_crc = digital_skb_check_crc_none;
510
511 if (DIGITAL_DRV_CAPS_TG_CRC(ddev))
512 return;
513
514 switch (ddev->curr_rf_tech) {
515 case NFC_DIGITAL_RF_TECH_106A:
516 ddev->skb_add_crc = digital_skb_add_crc_a;
517 ddev->skb_check_crc = digital_skb_check_crc_a;
518 break;
519
520 case NFC_DIGITAL_RF_TECH_212F:
521 case NFC_DIGITAL_RF_TECH_424F:
522 ddev->skb_add_crc = digital_skb_add_crc_f;
523 ddev->skb_check_crc = digital_skb_check_crc_f;
524 break;
525
526 default:
527 break;
528 }
529}
530
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200531static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
532 struct sk_buff *resp)
533{
534 int rc;
535 struct digital_dep_req_res *dep_req;
Mark A. Greer6ce30662014-09-23 16:38:03 -0700536 u8 pfb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200537 size_t size;
538
539 if (IS_ERR(resp)) {
540 rc = PTR_ERR(resp);
541 resp = NULL;
542 goto exit;
543 }
544
545 rc = ddev->skb_check_crc(resp);
546 if (rc) {
547 PROTOCOL_ERR("14.4.1.6");
548 goto exit;
549 }
550
551 rc = digital_skb_pull_dep_sod(ddev, resp);
552 if (rc) {
553 PROTOCOL_ERR("14.4.1.2");
554 goto exit;
555 }
556
557 size = sizeof(struct digital_dep_req_res);
558 dep_req = (struct digital_dep_req_res *)resp->data;
559
560 if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
561 dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
562 rc = -EIO;
563 goto exit;
564 }
565
Mark A. Greer6ce30662014-09-23 16:38:03 -0700566 pfb = dep_req->pfb;
567
Mark A. Greer05afedc2014-09-23 16:38:05 -0700568 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
569 if (ddev->did && (ddev->did == resp->data[3])) {
570 size++;
571 } else {
572 rc = -EIO;
573 goto exit;
574 }
575 } else if (ddev->did) {
576 rc = -EIO;
577 goto exit;
578 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200579
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700580 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
581 rc = -EIO;
582 goto exit;
583 }
584
Mark A. Greer6ce30662014-09-23 16:38:03 -0700585 if (size > resp->len) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200586 rc = -EIO;
587 goto exit;
588 }
589
Mark A. Greer6ce30662014-09-23 16:38:03 -0700590 skb_pull(resp, size);
591
592 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200593 case DIGITAL_NFC_DEP_PFB_I_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200594 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
Mark A. Greer6ce30662014-09-23 16:38:03 -0700595 ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(pfb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200596 break;
597 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200598 pr_err("Received a ACK/NACK PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200599 rc = -EINVAL;
600 goto exit;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200601 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200602 pr_err("Received a SUPERVISOR PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200603 rc = -EINVAL;
604 goto exit;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200605 }
606
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200607 rc = nfc_tm_data_received(ddev->nfc_dev, resp);
608
609exit:
610 if (rc)
611 kfree_skb(resp);
612}
613
614int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
615{
616 struct digital_dep_req_res *dep_res;
617
618 skb_push(skb, sizeof(struct digital_dep_req_res));
619 dep_res = (struct digital_dep_req_res *)skb->data;
620
621 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
622 dep_res->cmd = DIGITAL_CMD_DEP_RES;
623 dep_res->pfb = ddev->curr_nfc_dep_pni;
624
Mark A. Greer05afedc2014-09-23 16:38:05 -0700625 if (ddev->did) {
626 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
627
628 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
629 sizeof(ddev->did));
630 }
631
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200632 digital_skb_push_dep_sod(ddev, skb);
633
634 ddev->skb_add_crc(skb);
635
636 return digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
637 NULL);
638}
639
640static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
641 void *arg, struct sk_buff *resp)
642{
Thierry Escande67af1d72014-01-02 11:58:13 +0100643 u8 rf_tech = (unsigned long)arg;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200644
645 if (IS_ERR(resp))
646 return;
647
Thierry Escandeb711ad52014-01-06 23:34:48 +0100648 digital_tg_set_rf_tech(ddev, rf_tech);
649
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200650 digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
651
652 digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
653
654 dev_kfree_skb(resp);
655}
656
657static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
658 u8 rf_tech)
659{
660 struct digital_psl_res *psl_res;
661 struct sk_buff *skb;
662 int rc;
663
664 skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
665 if (!skb)
666 return -ENOMEM;
667
668 skb_put(skb, sizeof(struct digital_psl_res));
669
670 psl_res = (struct digital_psl_res *)skb->data;
671
672 psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
673 psl_res->cmd = DIGITAL_CMD_PSL_RES;
674 psl_res->did = did;
675
676 digital_skb_push_dep_sod(ddev, skb);
677
678 ddev->skb_add_crc(skb);
679
680 rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
Thierry Escande67af1d72014-01-02 11:58:13 +0100681 (void *)(unsigned long)rf_tech);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200682 if (rc)
683 kfree_skb(skb);
684
685 return rc;
686}
687
688static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
689 struct sk_buff *resp)
690{
691 int rc;
692 struct digital_psl_req *psl_req;
693 u8 rf_tech;
694 u8 dsi;
695
696 if (IS_ERR(resp)) {
697 rc = PTR_ERR(resp);
698 resp = NULL;
699 goto exit;
700 }
701
702 rc = ddev->skb_check_crc(resp);
703 if (rc) {
704 PROTOCOL_ERR("14.4.1.6");
705 goto exit;
706 }
707
708 rc = digital_skb_pull_dep_sod(ddev, resp);
709 if (rc) {
710 PROTOCOL_ERR("14.4.1.2");
711 goto exit;
712 }
713
714 psl_req = (struct digital_psl_req *)resp->data;
715
716 if (resp->len != sizeof(struct digital_psl_req) ||
717 psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
718 psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
719 rc = -EIO;
720 goto exit;
721 }
722
723 dsi = (psl_req->brs >> 3) & 0x07;
724 switch (dsi) {
725 case 0:
726 rf_tech = NFC_DIGITAL_RF_TECH_106A;
727 break;
728 case 1:
729 rf_tech = NFC_DIGITAL_RF_TECH_212F;
730 break;
731 case 2:
732 rf_tech = NFC_DIGITAL_RF_TECH_424F;
733 break;
734 default:
Masanari Iida77d84ff2013-12-09 00:22:53 +0900735 pr_err("Unsupported dsi value %d\n", dsi);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200736 goto exit;
737 }
738
739 rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
740
741exit:
742 kfree_skb(resp);
743}
744
745static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
746 void *arg, struct sk_buff *resp)
747{
748 int offset;
749
750 if (IS_ERR(resp)) {
751 digital_poll_next_tech(ddev);
752 return;
753 }
754
755 offset = 2;
756 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
757 offset++;
758
759 if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
760 digital_tg_recv_psl_req(ddev, arg, resp);
761 else
762 digital_tg_recv_dep_req(ddev, arg, resp);
763}
764
765static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
766 struct digital_atr_req *atr_req)
767{
768 struct digital_atr_res *atr_res;
769 struct sk_buff *skb;
770 u8 *gb;
771 size_t gb_len;
772 int rc;
773
774 gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
775 if (!gb)
776 gb_len = 0;
777
778 skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
779 if (!skb)
780 return -ENOMEM;
781
782 skb_put(skb, sizeof(struct digital_atr_res));
783 atr_res = (struct digital_atr_res *)skb->data;
784
785 memset(atr_res, 0, sizeof(struct digital_atr_res));
786
787 atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
788 atr_res->cmd = DIGITAL_CMD_ATR_RES;
789 memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
790 atr_res->to = 8;
791 atr_res->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
792 if (gb_len) {
793 skb_put(skb, gb_len);
794
795 atr_res->pp |= DIGITAL_GB_BIT;
796 memcpy(atr_res->gb, gb, gb_len);
797 }
798
799 digital_skb_push_dep_sod(ddev, skb);
800
801 ddev->skb_add_crc(skb);
802
803 rc = digital_tg_send_cmd(ddev, skb, 999,
804 digital_tg_send_atr_res_complete, NULL);
Mark A. Greerb15829b2014-09-23 16:38:02 -0700805 if (rc)
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200806 kfree_skb(skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200807
808 return rc;
809}
810
811void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
812 struct sk_buff *resp)
813{
814 int rc;
815 struct digital_atr_req *atr_req;
816 size_t gb_len, min_size;
Mark A. Greer0529a7a2014-07-02 09:03:49 -0700817 u8 poll_tech_count;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200818
819 if (IS_ERR(resp)) {
820 rc = PTR_ERR(resp);
821 resp = NULL;
822 goto exit;
823 }
824
825 if (!resp->len) {
826 rc = -EIO;
827 goto exit;
828 }
829
830 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
831 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
Thierry Escandeb711ad52014-01-06 23:34:48 +0100832 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_106A);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200833 } else {
834 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
Thierry Escandeb711ad52014-01-06 23:34:48 +0100835 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_212F);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200836 }
837
838 if (resp->len < min_size) {
839 rc = -EIO;
840 goto exit;
841 }
842
Thierry Escande48e10442014-01-06 23:34:37 +0100843 ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200844
845 rc = ddev->skb_check_crc(resp);
846 if (rc) {
847 PROTOCOL_ERR("14.4.1.6");
848 goto exit;
849 }
850
851 rc = digital_skb_pull_dep_sod(ddev, resp);
852 if (rc) {
853 PROTOCOL_ERR("14.4.1.2");
854 goto exit;
855 }
856
857 atr_req = (struct digital_atr_req *)resp->data;
858
859 if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
Mark A. Greer05afedc2014-09-23 16:38:05 -0700860 atr_req->cmd != DIGITAL_CMD_ATR_REQ ||
861 atr_req->did > DIGITAL_DID_MAX) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200862 rc = -EINVAL;
863 goto exit;
864 }
865
Mark A. Greer05afedc2014-09-23 16:38:05 -0700866 ddev->did = atr_req->did;
867
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200868 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
869 NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
870 if (rc)
871 goto exit;
872
873 rc = digital_tg_send_atr_res(ddev, atr_req);
874 if (rc)
875 goto exit;
876
877 gb_len = resp->len - sizeof(struct digital_atr_req);
Mark A. Greer0529a7a2014-07-02 09:03:49 -0700878
879 poll_tech_count = ddev->poll_tech_count;
880 ddev->poll_tech_count = 0;
881
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200882 rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
883 NFC_COMM_PASSIVE, atr_req->gb, gb_len);
Mark A. Greer0529a7a2014-07-02 09:03:49 -0700884 if (rc) {
885 ddev->poll_tech_count = poll_tech_count;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200886 goto exit;
Mark A. Greer0529a7a2014-07-02 09:03:49 -0700887 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200888
889 rc = 0;
890exit:
891 if (rc)
892 digital_poll_next_tech(ddev);
893
894 dev_kfree_skb(resp);
895}