blob: 35a9edf0e36066c4a811f4fe7a7c2776db22ff56 [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
Mark A. Greerb08147c2014-09-23 16:38:08 -070037#define DIGITAL_PAYLOAD_SIZE_MAX 254
38#define DIGITAL_PAYLOAD_BITS_TO_PP(s) (((s) & 0x3) << 4)
39#define DIGITAL_PAYLOAD_PP_TO_BITS(s) (((s) >> 4) & 0x3)
40#define DIGITAL_PAYLOAD_BITS_TO_FSL(s) ((s) & 0x3)
41#define DIGITAL_PAYLOAD_FSL_TO_BITS(s) ((s) & 0x3)
42
Thierry Escande7d0911c2013-09-19 17:55:29 +020043#define DIGITAL_GB_BIT 0x02
44
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070045#define DIGITAL_NFC_DEP_REQ_RES_HEADROOM 2 /* SoD: [SB (NFC-A)] + LEN */
46#define DIGITAL_NFC_DEP_REQ_RES_TAILROOM 2 /* EoD: 2-byte CRC */
47
Thierry Escande7d0911c2013-09-19 17:55:29 +020048#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
49
50#define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070051#define DIGITAL_NFC_DEP_PFB_MI_BIT 0x10
52#define DIGITAL_NFC_DEP_PFB_NACK_BIT 0x10
Mark A. Greer05afedc2014-09-23 16:38:05 -070053#define DIGITAL_NFC_DEP_PFB_DID_BIT 0x04
Thierry Escande7d0911c2013-09-19 17:55:29 +020054
55#define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
56 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070057#define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_MI_BIT)
58#define DIGITAL_NFC_DEP_NACK_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_NACK_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020059#define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
Mark A. Greer05afedc2014-09-23 16:38:05 -070060#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020061#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
62
63#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
64#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
65#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
66
67struct digital_atr_req {
68 u8 dir;
69 u8 cmd;
70 u8 nfcid3[10];
71 u8 did;
72 u8 bs;
73 u8 br;
74 u8 pp;
75 u8 gb[0];
76} __packed;
77
78struct digital_atr_res {
79 u8 dir;
80 u8 cmd;
81 u8 nfcid3[10];
82 u8 did;
83 u8 bs;
84 u8 br;
85 u8 to;
86 u8 pp;
87 u8 gb[0];
88} __packed;
89
90struct digital_psl_req {
91 u8 dir;
92 u8 cmd;
93 u8 did;
94 u8 brs;
95 u8 fsl;
96} __packed;
97
98struct digital_psl_res {
99 u8 dir;
100 u8 cmd;
101 u8 did;
102} __packed;
103
104struct digital_dep_req_res {
105 u8 dir;
106 u8 cmd;
107 u8 pfb;
108} __packed;
109
110static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
111 struct sk_buff *resp);
Mark A. Greerc12715a2014-09-23 16:38:10 -0700112static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
113 struct sk_buff *resp);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200114
Mark A. Greerb08147c2014-09-23 16:38:08 -0700115static const u8 digital_payload_bits_map[4] = {
116 [0] = 64,
117 [1] = 128,
118 [2] = 192,
119 [3] = 254
120};
121
122static u8 digital_payload_bits_to_size(u8 payload_bits)
123{
124 if (payload_bits >= ARRAY_SIZE(digital_payload_bits_map))
125 return 0;
126
127 return digital_payload_bits_map[payload_bits];
128}
129
130static u8 digital_payload_size_to_bits(u8 payload_size)
131{
132 int i;
133
134 for (i = 0; i < ARRAY_SIZE(digital_payload_bits_map); i++)
135 if (digital_payload_bits_map[i] == payload_size)
136 return i;
137
138 return 0xff;
139}
140
Thierry Escande7d0911c2013-09-19 17:55:29 +0200141static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
142 struct sk_buff *skb)
143{
144 skb_push(skb, sizeof(u8));
145
146 skb->data[0] = skb->len;
147
148 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
149 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
150}
151
152static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
153 struct sk_buff *skb)
154{
155 u8 size;
156
157 if (skb->len < 2)
158 return -EIO;
159
160 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
161 skb_pull(skb, sizeof(u8));
162
163 size = skb->data[0];
164 if (size != skb->len)
165 return -EIO;
166
167 skb_pull(skb, sizeof(u8));
168
169 return 0;
170}
171
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700172static struct sk_buff *
173digital_send_dep_data_prep(struct nfc_digital_dev *ddev, struct sk_buff *skb,
174 struct digital_dep_req_res *dep_req_res,
175 struct digital_data_exch *data_exch)
176{
177 struct sk_buff *new_skb;
178
179 if (skb->len > ddev->remote_payload_max) {
180 dep_req_res->pfb |= DIGITAL_NFC_DEP_PFB_MI_BIT;
181
182 new_skb = digital_skb_alloc(ddev, ddev->remote_payload_max);
183 if (!new_skb) {
184 kfree_skb(ddev->chaining_skb);
185 ddev->chaining_skb = NULL;
186
187 return ERR_PTR(-ENOMEM);
188 }
189
190 skb_reserve(new_skb, ddev->tx_headroom + NFC_HEADER_SIZE +
191 DIGITAL_NFC_DEP_REQ_RES_HEADROOM);
192 memcpy(skb_put(new_skb, ddev->remote_payload_max), skb->data,
193 ddev->remote_payload_max);
194 skb_pull(skb, ddev->remote_payload_max);
195
196 ddev->chaining_skb = skb;
197 ddev->data_exch = data_exch;
198 } else {
199 ddev->chaining_skb = NULL;
200 new_skb = skb;
201 }
202
203 return new_skb;
204}
205
Mark A. Greerc12715a2014-09-23 16:38:10 -0700206static struct sk_buff *
207digital_recv_dep_data_gather(struct nfc_digital_dev *ddev, u8 pfb,
208 struct sk_buff *resp,
209 int (*send_ack)(struct nfc_digital_dev *ddev,
210 struct digital_data_exch
211 *data_exch),
212 struct digital_data_exch *data_exch)
213{
214 struct sk_buff *new_skb;
215 int rc;
216
217 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb) && (!ddev->chaining_skb)) {
218 ddev->chaining_skb =
219 nfc_alloc_recv_skb(8 * ddev->local_payload_max,
220 GFP_KERNEL);
221 if (!ddev->chaining_skb) {
222 rc = -ENOMEM;
223 goto error;
224 }
225 }
226
227 if (ddev->chaining_skb) {
228 if (resp->len > skb_tailroom(ddev->chaining_skb)) {
229 new_skb = skb_copy_expand(ddev->chaining_skb,
230 skb_headroom(
231 ddev->chaining_skb),
232 8 * ddev->local_payload_max,
233 GFP_KERNEL);
234 if (!new_skb) {
235 rc = -ENOMEM;
236 goto error;
237 }
238
239 kfree_skb(ddev->chaining_skb);
240 ddev->chaining_skb = new_skb;
241 }
242
243 memcpy(skb_put(ddev->chaining_skb, resp->len), resp->data,
244 resp->len);
245
246 kfree_skb(resp);
247 resp = NULL;
248
249 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
250 rc = send_ack(ddev, data_exch);
251 if (rc)
252 goto error;
253
254 return NULL;
255 }
256
257 resp = ddev->chaining_skb;
258 ddev->chaining_skb = NULL;
259 }
260
261 return resp;
262
263error:
264 kfree_skb(resp);
265
266 kfree_skb(ddev->chaining_skb);
267 ddev->chaining_skb = NULL;
268
269 return ERR_PTR(rc);
270}
271
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700272static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg,
273 struct sk_buff *resp)
274{
275 struct nfc_target *target = arg;
276 struct digital_psl_res *psl_res;
277 int rc;
278
279 if (IS_ERR(resp)) {
280 rc = PTR_ERR(resp);
281 resp = NULL;
282 goto exit;
283 }
284
285 rc = ddev->skb_check_crc(resp);
286 if (rc) {
287 PROTOCOL_ERR("14.4.1.6");
288 goto exit;
289 }
290
291 rc = digital_skb_pull_dep_sod(ddev, resp);
292 if (rc) {
293 PROTOCOL_ERR("14.4.1.2");
294 goto exit;
295 }
296
297 psl_res = (struct digital_psl_res *)resp->data;
298
299 if ((resp->len != sizeof(*psl_res)) ||
300 (psl_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN) ||
301 (psl_res->cmd != DIGITAL_CMD_PSL_RES)) {
302 rc = -EIO;
303 goto exit;
304 }
305
306 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
307 NFC_DIGITAL_RF_TECH_424F);
308 if (rc)
309 goto exit;
310
311 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
312 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
313 if (rc)
314 goto exit;
315
316 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev) &&
317 (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)) {
318 ddev->skb_add_crc = digital_skb_add_crc_f;
319 ddev->skb_check_crc = digital_skb_check_crc_f;
320 }
321
322 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_424F;
323
324 nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
325 NFC_RF_INITIATOR);
326
327 ddev->curr_nfc_dep_pni = 0;
328
329exit:
330 dev_kfree_skb(resp);
331
332 if (rc)
333 ddev->curr_protocol = 0;
334}
335
336static int digital_in_send_psl_req(struct nfc_digital_dev *ddev,
337 struct nfc_target *target)
338{
339 struct sk_buff *skb;
340 struct digital_psl_req *psl_req;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700341 int rc;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700342 u8 payload_size, payload_bits;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700343
344 skb = digital_skb_alloc(ddev, sizeof(*psl_req));
345 if (!skb)
346 return -ENOMEM;
347
348 skb_put(skb, sizeof(*psl_req));
349
350 psl_req = (struct digital_psl_req *)skb->data;
351
352 psl_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
353 psl_req->cmd = DIGITAL_CMD_PSL_REQ;
354 psl_req->did = 0;
355 psl_req->brs = (0x2 << 3) | 0x2; /* 424F both directions */
Mark A. Greerb08147c2014-09-23 16:38:08 -0700356
357 payload_size = min(ddev->local_payload_max, ddev->remote_payload_max);
358 payload_bits = digital_payload_size_to_bits(payload_size);
359 psl_req->fsl = DIGITAL_PAYLOAD_BITS_TO_FSL(payload_bits);
360
361 ddev->local_payload_max = payload_size;
362 ddev->remote_payload_max = payload_size;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700363
364 digital_skb_push_dep_sod(ddev, skb);
365
366 ddev->skb_add_crc(skb);
367
Mark A. Greerb15829b2014-09-23 16:38:02 -0700368 rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res,
369 target);
370 if (rc)
371 kfree_skb(skb);
372
373 return rc;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700374}
375
Thierry Escande7d0911c2013-09-19 17:55:29 +0200376static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
377 struct sk_buff *resp)
378{
379 struct nfc_target *target = arg;
380 struct digital_atr_res *atr_res;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700381 u8 gb_len, payload_bits;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200382 int rc;
383
384 if (IS_ERR(resp)) {
385 rc = PTR_ERR(resp);
386 resp = NULL;
387 goto exit;
388 }
389
390 rc = ddev->skb_check_crc(resp);
391 if (rc) {
392 PROTOCOL_ERR("14.4.1.6");
393 goto exit;
394 }
395
396 rc = digital_skb_pull_dep_sod(ddev, resp);
397 if (rc) {
398 PROTOCOL_ERR("14.4.1.2");
399 goto exit;
400 }
401
402 if (resp->len < sizeof(struct digital_atr_res)) {
403 rc = -EIO;
404 goto exit;
405 }
406
407 gb_len = resp->len - sizeof(struct digital_atr_res);
408
409 atr_res = (struct digital_atr_res *)resp->data;
410
Mark A. Greerb08147c2014-09-23 16:38:08 -0700411 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_res->pp);
412 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits);
413
414 if (!ddev->remote_payload_max) {
415 rc = -EINVAL;
416 goto exit;
417 }
418
Thierry Escande7d0911c2013-09-19 17:55:29 +0200419 rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
420 if (rc)
421 goto exit;
422
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700423 if ((ddev->protocols & NFC_PROTO_FELICA_MASK) &&
424 (ddev->curr_rf_tech != NFC_DIGITAL_RF_TECH_424F)) {
425 rc = digital_in_send_psl_req(ddev, target);
426 if (!rc)
427 goto exit;
428 }
429
Thierry Escande7d0911c2013-09-19 17:55:29 +0200430 rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
431 NFC_RF_INITIATOR);
432
433 ddev->curr_nfc_dep_pni = 0;
434
435exit:
436 dev_kfree_skb(resp);
437
438 if (rc)
439 ddev->curr_protocol = 0;
440}
441
442int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
443 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
444 size_t gb_len)
445{
446 struct sk_buff *skb;
447 struct digital_atr_req *atr_req;
448 uint size;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700449 int rc;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700450 u8 payload_bits;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200451
452 size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
453
454 if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
455 PROTOCOL_ERR("14.6.1.1");
456 return -EINVAL;
457 }
458
459 skb = digital_skb_alloc(ddev, size);
460 if (!skb)
461 return -ENOMEM;
462
463 skb_put(skb, sizeof(struct digital_atr_req));
464
465 atr_req = (struct digital_atr_req *)skb->data;
466 memset(atr_req, 0, sizeof(struct digital_atr_req));
467
468 atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
469 atr_req->cmd = DIGITAL_CMD_ATR_REQ;
470 if (target->nfcid2_len)
Thierry Escande4f319e32014-01-02 11:58:14 +0100471 memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200472 else
Thierry Escande4f319e32014-01-02 11:58:14 +0100473 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200474
475 atr_req->did = 0;
476 atr_req->bs = 0;
477 atr_req->br = 0;
478
Mark A. Greerb08147c2014-09-23 16:38:08 -0700479 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX;
480 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);
481 atr_req->pp = DIGITAL_PAYLOAD_BITS_TO_PP(payload_bits);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200482
483 if (gb_len) {
484 atr_req->pp |= DIGITAL_GB_BIT;
485 memcpy(skb_put(skb, gb_len), gb, gb_len);
486 }
487
488 digital_skb_push_dep_sod(ddev, skb);
489
490 ddev->skb_add_crc(skb);
491
Mark A. Greerb15829b2014-09-23 16:38:02 -0700492 rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res,
493 target);
494 if (rc)
495 kfree_skb(skb);
496
497 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200498}
499
Mark A. Greerc12715a2014-09-23 16:38:10 -0700500static int digital_in_send_ack(struct nfc_digital_dev *ddev,
501 struct digital_data_exch *data_exch)
502{
503 struct digital_dep_req_res *dep_req;
504 struct sk_buff *skb;
505 int rc;
506
507 skb = digital_skb_alloc(ddev, 1);
508 if (!skb)
509 return -ENOMEM;
510
511 skb_push(skb, sizeof(struct digital_dep_req_res));
512
513 dep_req = (struct digital_dep_req_res *)skb->data;
514
515 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
516 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
517 dep_req->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
518 ddev->curr_nfc_dep_pni;
519
520 digital_skb_push_dep_sod(ddev, skb);
521
522 ddev->skb_add_crc(skb);
523
524 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
525 data_exch);
526 if (rc)
527 kfree_skb(skb);
528
529 return rc;
530}
531
Thierry Escande7d0911c2013-09-19 17:55:29 +0200532static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
533 struct digital_data_exch *data_exch, u8 rtox)
534{
535 struct digital_dep_req_res *dep_req;
536 struct sk_buff *skb;
537 int rc;
538
539 skb = digital_skb_alloc(ddev, 1);
540 if (!skb)
541 return -ENOMEM;
542
543 *skb_put(skb, 1) = rtox;
544
545 skb_push(skb, sizeof(struct digital_dep_req_res));
546
547 dep_req = (struct digital_dep_req_res *)skb->data;
548
549 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
550 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
551 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
552 DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
553
554 digital_skb_push_dep_sod(ddev, skb);
555
556 ddev->skb_add_crc(skb);
557
558 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
559 data_exch);
Mark A. Greerb15829b2014-09-23 16:38:02 -0700560 if (rc)
561 kfree_skb(skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200562
563 return rc;
564}
565
566static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
567 struct sk_buff *resp)
568{
569 struct digital_data_exch *data_exch = arg;
570 struct digital_dep_req_res *dep_res;
571 u8 pfb;
572 uint size;
573 int rc;
574
575 if (IS_ERR(resp)) {
576 rc = PTR_ERR(resp);
577 resp = NULL;
578 goto exit;
579 }
580
581 rc = ddev->skb_check_crc(resp);
582 if (rc) {
583 PROTOCOL_ERR("14.4.1.6");
584 goto error;
585 }
586
587 rc = digital_skb_pull_dep_sod(ddev, resp);
588 if (rc) {
589 PROTOCOL_ERR("14.4.1.2");
590 goto exit;
591 }
592
Mark A. Greerb08147c2014-09-23 16:38:08 -0700593 if (resp->len > ddev->local_payload_max) {
594 rc = -EMSGSIZE;
595 goto exit;
596 }
597
Mark A. Greer6ce30662014-09-23 16:38:03 -0700598 size = sizeof(struct digital_dep_req_res);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200599 dep_res = (struct digital_dep_req_res *)resp->data;
600
Mark A. Greer6ce30662014-09-23 16:38:03 -0700601 if (resp->len < size || dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
Thierry Escande7d0911c2013-09-19 17:55:29 +0200602 dep_res->cmd != DIGITAL_CMD_DEP_RES) {
603 rc = -EIO;
604 goto error;
605 }
606
607 pfb = dep_res->pfb;
608
Mark A. Greer3bc3f882014-09-23 16:38:04 -0700609 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
610 PROTOCOL_ERR("14.8.2.1");
611 rc = -EIO;
612 goto error;
613 }
Mark A. Greer6ce30662014-09-23 16:38:03 -0700614
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700615 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
616 rc = -EIO;
617 goto exit;
618 }
619
Mark A. Greer6ce30662014-09-23 16:38:03 -0700620 if (size > resp->len) {
621 rc = -EIO;
622 goto error;
623 }
624
625 skb_pull(resp, size);
626
Thierry Escande7d0911c2013-09-19 17:55:29 +0200627 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
628 case DIGITAL_NFC_DEP_PFB_I_PDU:
629 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
630 PROTOCOL_ERR("14.12.3.3");
631 rc = -EIO;
632 goto error;
633 }
634
635 ddev->curr_nfc_dep_pni =
636 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
Mark A. Greerc12715a2014-09-23 16:38:10 -0700637
638 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
639 digital_in_send_ack,
640 data_exch);
641 if (IS_ERR(resp)) {
642 rc = PTR_ERR(resp);
643 resp = NULL;
644 goto error;
645 }
646
647 /* If resp is NULL then we're still chaining so return and
648 * wait for the next part of the PDU. Else, the PDU is
649 * complete so pass it up.
650 */
651 if (!resp)
652 return;
653
Thierry Escande7d0911c2013-09-19 17:55:29 +0200654 rc = 0;
655 break;
656
657 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Mark A. Greer485fdc92014-09-23 16:38:07 -0700658 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
659 PROTOCOL_ERR("14.12.3.3");
660 rc = -EIO;
661 goto exit;
662 }
663
664 ddev->curr_nfc_dep_pni =
665 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
666
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700667 if (ddev->chaining_skb && !DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) {
668 rc = digital_in_send_dep_req(ddev, NULL,
669 ddev->chaining_skb,
670 ddev->data_exch);
671 if (rc)
672 goto error;
673
674 return;
675 }
676
677 pr_err("Received a ACK/NACK PDU\n");
Mark A. Greer485fdc92014-09-23 16:38:07 -0700678 rc = -EINVAL;
679 goto exit;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200680
681 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
682 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
683 rc = -EINVAL;
684 goto error;
685 }
686
Mark A. Greer6ce30662014-09-23 16:38:03 -0700687 rc = digital_in_send_rtox(ddev, data_exch, resp->data[0]);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200688 if (rc)
689 goto error;
690
691 kfree_skb(resp);
692 return;
693 }
694
Thierry Escande7d0911c2013-09-19 17:55:29 +0200695exit:
696 data_exch->cb(data_exch->cb_context, resp, rc);
697
698error:
699 kfree(data_exch);
700
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700701 kfree_skb(ddev->chaining_skb);
702 ddev->chaining_skb = NULL;
703
Thierry Escande7d0911c2013-09-19 17:55:29 +0200704 if (rc)
705 kfree_skb(resp);
706}
707
708int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
709 struct nfc_target *target, struct sk_buff *skb,
710 struct digital_data_exch *data_exch)
711{
712 struct digital_dep_req_res *dep_req;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700713 struct sk_buff *chaining_skb, *tmp_skb;
714 int rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200715
716 skb_push(skb, sizeof(struct digital_dep_req_res));
717
718 dep_req = (struct digital_dep_req_res *)skb->data;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700719
Thierry Escande7d0911c2013-09-19 17:55:29 +0200720 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
721 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
722 dep_req->pfb = ddev->curr_nfc_dep_pni;
723
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700724 chaining_skb = ddev->chaining_skb;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200725
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700726 tmp_skb = digital_send_dep_data_prep(ddev, skb, dep_req, data_exch);
727 if (IS_ERR(tmp_skb))
728 return PTR_ERR(tmp_skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200729
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700730 digital_skb_push_dep_sod(ddev, tmp_skb);
731
732 ddev->skb_add_crc(tmp_skb);
733
734 rc = digital_in_send_cmd(ddev, tmp_skb, 1500, digital_in_recv_dep_res,
735 data_exch);
736 if (rc) {
737 if (tmp_skb != skb)
738 kfree_skb(tmp_skb);
739
740 kfree_skb(chaining_skb);
741 ddev->chaining_skb = NULL;
742 }
743
744 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200745}
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200746
Thierry Escandeb711ad52014-01-06 23:34:48 +0100747static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
748{
749 ddev->curr_rf_tech = rf_tech;
750
751 ddev->skb_add_crc = digital_skb_add_crc_none;
752 ddev->skb_check_crc = digital_skb_check_crc_none;
753
754 if (DIGITAL_DRV_CAPS_TG_CRC(ddev))
755 return;
756
757 switch (ddev->curr_rf_tech) {
758 case NFC_DIGITAL_RF_TECH_106A:
759 ddev->skb_add_crc = digital_skb_add_crc_a;
760 ddev->skb_check_crc = digital_skb_check_crc_a;
761 break;
762
763 case NFC_DIGITAL_RF_TECH_212F:
764 case NFC_DIGITAL_RF_TECH_424F:
765 ddev->skb_add_crc = digital_skb_add_crc_f;
766 ddev->skb_check_crc = digital_skb_check_crc_f;
767 break;
768
769 default:
770 break;
771 }
772}
773
Mark A. Greerc12715a2014-09-23 16:38:10 -0700774static int digital_tg_send_ack(struct nfc_digital_dev *ddev,
775 struct digital_data_exch *data_exch)
776{
777 struct digital_dep_req_res *dep_res;
778 struct sk_buff *skb;
779 int rc;
780
781 skb = digital_skb_alloc(ddev, 1);
782 if (!skb)
783 return -ENOMEM;
784
785 skb_push(skb, sizeof(struct digital_dep_req_res));
786
787 dep_res = (struct digital_dep_req_res *)skb->data;
788
789 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
790 dep_res->cmd = DIGITAL_CMD_DEP_RES;
791 dep_res->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
792 ddev->curr_nfc_dep_pni;
793
794 if (ddev->did) {
795 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
796
797 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
798 sizeof(ddev->did));
799 }
800
801 ddev->curr_nfc_dep_pni =
802 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
803
804 digital_skb_push_dep_sod(ddev, skb);
805
806 ddev->skb_add_crc(skb);
807
808 rc = digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
809 data_exch);
810 if (rc)
811 kfree_skb(skb);
812
813 return rc;
814}
815
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200816static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
817 struct sk_buff *resp)
818{
819 int rc;
820 struct digital_dep_req_res *dep_req;
Mark A. Greer6ce30662014-09-23 16:38:03 -0700821 u8 pfb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200822 size_t size;
823
824 if (IS_ERR(resp)) {
825 rc = PTR_ERR(resp);
826 resp = NULL;
827 goto exit;
828 }
829
830 rc = ddev->skb_check_crc(resp);
831 if (rc) {
832 PROTOCOL_ERR("14.4.1.6");
833 goto exit;
834 }
835
836 rc = digital_skb_pull_dep_sod(ddev, resp);
837 if (rc) {
838 PROTOCOL_ERR("14.4.1.2");
839 goto exit;
840 }
841
Mark A. Greerb08147c2014-09-23 16:38:08 -0700842 if (resp->len > ddev->local_payload_max) {
843 rc = -EMSGSIZE;
844 goto exit;
845 }
846
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200847 size = sizeof(struct digital_dep_req_res);
848 dep_req = (struct digital_dep_req_res *)resp->data;
849
850 if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
851 dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
852 rc = -EIO;
853 goto exit;
854 }
855
Mark A. Greer6ce30662014-09-23 16:38:03 -0700856 pfb = dep_req->pfb;
857
Mark A. Greer05afedc2014-09-23 16:38:05 -0700858 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
859 if (ddev->did && (ddev->did == resp->data[3])) {
860 size++;
861 } else {
862 rc = -EIO;
863 goto exit;
864 }
865 } else if (ddev->did) {
866 rc = -EIO;
867 goto exit;
868 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200869
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700870 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
871 rc = -EIO;
872 goto exit;
873 }
874
Mark A. Greer6ce30662014-09-23 16:38:03 -0700875 if (size > resp->len) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200876 rc = -EIO;
877 goto exit;
878 }
879
Mark A. Greer6ce30662014-09-23 16:38:03 -0700880 skb_pull(resp, size);
881
882 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200883 case DIGITAL_NFC_DEP_PFB_I_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200884 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
Mark A. Greer485fdc92014-09-23 16:38:07 -0700885
886 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
887 PROTOCOL_ERR("14.12.3.4");
888 rc = -EIO;
889 goto exit;
890 }
891
Mark A. Greerc12715a2014-09-23 16:38:10 -0700892 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
893 digital_tg_send_ack, NULL);
894 if (IS_ERR(resp)) {
895 rc = PTR_ERR(resp);
896 resp = NULL;
897 goto exit;
898 }
899
900 /* If resp is NULL then we're still chaining so return and
901 * wait for the next part of the PDU. Else, the PDU is
902 * complete so pass it up.
903 */
904 if (!resp)
905 return;
906
Mark A. Greer485fdc92014-09-23 16:38:07 -0700907 rc = 0;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200908 break;
909 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Mark A. Greer485fdc92014-09-23 16:38:07 -0700910 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
911 PROTOCOL_ERR("14.12.3.4");
912 rc = -EIO;
913 goto exit;
914 }
915
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700916 if (ddev->chaining_skb && !DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) {
917 rc = digital_tg_send_dep_res(ddev, ddev->chaining_skb);
918 if (rc)
919 goto exit;
920
921 return;
922 }
923
Samuel Ortiz26042532013-09-20 16:56:40 +0200924 pr_err("Received a ACK/NACK PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200925 rc = -EINVAL;
926 goto exit;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200927 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200928 pr_err("Received a SUPERVISOR PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200929 rc = -EINVAL;
930 goto exit;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200931 }
932
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200933 rc = nfc_tm_data_received(ddev->nfc_dev, resp);
934
935exit:
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700936 kfree_skb(ddev->chaining_skb);
937 ddev->chaining_skb = NULL;
938
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200939 if (rc)
940 kfree_skb(resp);
941}
942
943int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
944{
945 struct digital_dep_req_res *dep_res;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700946 struct sk_buff *chaining_skb, *tmp_skb;
947 int rc;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200948
949 skb_push(skb, sizeof(struct digital_dep_req_res));
Mark A. Greerb08147c2014-09-23 16:38:08 -0700950
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200951 dep_res = (struct digital_dep_req_res *)skb->data;
952
953 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
954 dep_res->cmd = DIGITAL_CMD_DEP_RES;
955 dep_res->pfb = ddev->curr_nfc_dep_pni;
956
Mark A. Greer05afedc2014-09-23 16:38:05 -0700957 if (ddev->did) {
958 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
959
960 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
961 sizeof(ddev->did));
962 }
963
Mark A. Greer485fdc92014-09-23 16:38:07 -0700964 ddev->curr_nfc_dep_pni =
965 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
966
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700967 chaining_skb = ddev->chaining_skb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200968
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700969 tmp_skb = digital_send_dep_data_prep(ddev, skb, dep_res, NULL);
970 if (IS_ERR(tmp_skb))
971 return PTR_ERR(tmp_skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200972
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700973 digital_skb_push_dep_sod(ddev, tmp_skb);
974
975 ddev->skb_add_crc(tmp_skb);
976
977 rc = digital_tg_send_cmd(ddev, tmp_skb, 1500, digital_tg_recv_dep_req,
978 NULL);
979 if (rc) {
980 if (tmp_skb != skb)
981 kfree_skb(tmp_skb);
982
983 kfree_skb(chaining_skb);
984 ddev->chaining_skb = NULL;
985 }
986
987 return rc;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200988}
989
990static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
991 void *arg, struct sk_buff *resp)
992{
Thierry Escande67af1d72014-01-02 11:58:13 +0100993 u8 rf_tech = (unsigned long)arg;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200994
995 if (IS_ERR(resp))
996 return;
997
Thierry Escandeb711ad52014-01-06 23:34:48 +0100998 digital_tg_set_rf_tech(ddev, rf_tech);
999
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001000 digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
1001
1002 digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
1003
1004 dev_kfree_skb(resp);
1005}
1006
1007static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
1008 u8 rf_tech)
1009{
1010 struct digital_psl_res *psl_res;
1011 struct sk_buff *skb;
1012 int rc;
1013
1014 skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
1015 if (!skb)
1016 return -ENOMEM;
1017
1018 skb_put(skb, sizeof(struct digital_psl_res));
1019
1020 psl_res = (struct digital_psl_res *)skb->data;
1021
1022 psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1023 psl_res->cmd = DIGITAL_CMD_PSL_RES;
1024 psl_res->did = did;
1025
1026 digital_skb_push_dep_sod(ddev, skb);
1027
1028 ddev->skb_add_crc(skb);
1029
Mark A. Greer485fdc92014-09-23 16:38:07 -07001030 ddev->curr_nfc_dep_pni = 0;
1031
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001032 rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
Thierry Escande67af1d72014-01-02 11:58:13 +01001033 (void *)(unsigned long)rf_tech);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001034 if (rc)
1035 kfree_skb(skb);
1036
1037 return rc;
1038}
1039
1040static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
1041 struct sk_buff *resp)
1042{
1043 int rc;
1044 struct digital_psl_req *psl_req;
1045 u8 rf_tech;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001046 u8 dsi, payload_size, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001047
1048 if (IS_ERR(resp)) {
1049 rc = PTR_ERR(resp);
1050 resp = NULL;
1051 goto exit;
1052 }
1053
1054 rc = ddev->skb_check_crc(resp);
1055 if (rc) {
1056 PROTOCOL_ERR("14.4.1.6");
1057 goto exit;
1058 }
1059
1060 rc = digital_skb_pull_dep_sod(ddev, resp);
1061 if (rc) {
1062 PROTOCOL_ERR("14.4.1.2");
1063 goto exit;
1064 }
1065
1066 psl_req = (struct digital_psl_req *)resp->data;
1067
1068 if (resp->len != sizeof(struct digital_psl_req) ||
1069 psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
1070 psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
1071 rc = -EIO;
1072 goto exit;
1073 }
1074
1075 dsi = (psl_req->brs >> 3) & 0x07;
1076 switch (dsi) {
1077 case 0:
1078 rf_tech = NFC_DIGITAL_RF_TECH_106A;
1079 break;
1080 case 1:
1081 rf_tech = NFC_DIGITAL_RF_TECH_212F;
1082 break;
1083 case 2:
1084 rf_tech = NFC_DIGITAL_RF_TECH_424F;
1085 break;
1086 default:
Masanari Iida77d84ff2013-12-09 00:22:53 +09001087 pr_err("Unsupported dsi value %d\n", dsi);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001088 goto exit;
1089 }
1090
Mark A. Greerb08147c2014-09-23 16:38:08 -07001091 payload_bits = DIGITAL_PAYLOAD_FSL_TO_BITS(psl_req->fsl);
1092 payload_size = digital_payload_bits_to_size(payload_bits);
1093
1094 if (!payload_size || (payload_size > min(ddev->local_payload_max,
1095 ddev->remote_payload_max))) {
1096 rc = -EINVAL;
1097 goto exit;
1098 }
1099
1100 ddev->local_payload_max = payload_size;
1101 ddev->remote_payload_max = payload_size;
1102
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001103 rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
1104
1105exit:
1106 kfree_skb(resp);
1107}
1108
1109static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
1110 void *arg, struct sk_buff *resp)
1111{
1112 int offset;
1113
1114 if (IS_ERR(resp)) {
1115 digital_poll_next_tech(ddev);
1116 return;
1117 }
1118
1119 offset = 2;
1120 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
1121 offset++;
1122
1123 if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
1124 digital_tg_recv_psl_req(ddev, arg, resp);
1125 else
1126 digital_tg_recv_dep_req(ddev, arg, resp);
1127}
1128
1129static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
1130 struct digital_atr_req *atr_req)
1131{
1132 struct digital_atr_res *atr_res;
1133 struct sk_buff *skb;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001134 u8 *gb, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001135 size_t gb_len;
1136 int rc;
1137
1138 gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
1139 if (!gb)
1140 gb_len = 0;
1141
1142 skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
1143 if (!skb)
1144 return -ENOMEM;
1145
1146 skb_put(skb, sizeof(struct digital_atr_res));
1147 atr_res = (struct digital_atr_res *)skb->data;
1148
1149 memset(atr_res, 0, sizeof(struct digital_atr_res));
1150
1151 atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1152 atr_res->cmd = DIGITAL_CMD_ATR_RES;
1153 memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
1154 atr_res->to = 8;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001155
1156 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX;
1157 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);
1158 atr_res->pp = DIGITAL_PAYLOAD_BITS_TO_PP(payload_bits);
1159
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001160 if (gb_len) {
1161 skb_put(skb, gb_len);
1162
1163 atr_res->pp |= DIGITAL_GB_BIT;
1164 memcpy(atr_res->gb, gb, gb_len);
1165 }
1166
1167 digital_skb_push_dep_sod(ddev, skb);
1168
1169 ddev->skb_add_crc(skb);
1170
Mark A. Greer485fdc92014-09-23 16:38:07 -07001171 ddev->curr_nfc_dep_pni = 0;
1172
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001173 rc = digital_tg_send_cmd(ddev, skb, 999,
1174 digital_tg_send_atr_res_complete, NULL);
Mark A. Greerb15829b2014-09-23 16:38:02 -07001175 if (rc)
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001176 kfree_skb(skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001177
1178 return rc;
1179}
1180
1181void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
1182 struct sk_buff *resp)
1183{
1184 int rc;
1185 struct digital_atr_req *atr_req;
1186 size_t gb_len, min_size;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001187 u8 poll_tech_count, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001188
1189 if (IS_ERR(resp)) {
1190 rc = PTR_ERR(resp);
1191 resp = NULL;
1192 goto exit;
1193 }
1194
1195 if (!resp->len) {
1196 rc = -EIO;
1197 goto exit;
1198 }
1199
1200 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
1201 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
Thierry Escandeb711ad52014-01-06 23:34:48 +01001202 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_106A);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001203 } else {
1204 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
Thierry Escandeb711ad52014-01-06 23:34:48 +01001205 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_212F);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001206 }
1207
1208 if (resp->len < min_size) {
1209 rc = -EIO;
1210 goto exit;
1211 }
1212
Thierry Escande48e10442014-01-06 23:34:37 +01001213 ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001214
1215 rc = ddev->skb_check_crc(resp);
1216 if (rc) {
1217 PROTOCOL_ERR("14.4.1.6");
1218 goto exit;
1219 }
1220
1221 rc = digital_skb_pull_dep_sod(ddev, resp);
1222 if (rc) {
1223 PROTOCOL_ERR("14.4.1.2");
1224 goto exit;
1225 }
1226
1227 atr_req = (struct digital_atr_req *)resp->data;
1228
1229 if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
Mark A. Greer05afedc2014-09-23 16:38:05 -07001230 atr_req->cmd != DIGITAL_CMD_ATR_REQ ||
1231 atr_req->did > DIGITAL_DID_MAX) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001232 rc = -EINVAL;
1233 goto exit;
1234 }
1235
Mark A. Greerb08147c2014-09-23 16:38:08 -07001236 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_req->pp);
1237 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits);
1238
1239 if (!ddev->remote_payload_max) {
1240 rc = -EINVAL;
1241 goto exit;
1242 }
1243
Mark A. Greer05afedc2014-09-23 16:38:05 -07001244 ddev->did = atr_req->did;
1245
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001246 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
1247 NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
1248 if (rc)
1249 goto exit;
1250
1251 rc = digital_tg_send_atr_res(ddev, atr_req);
1252 if (rc)
1253 goto exit;
1254
1255 gb_len = resp->len - sizeof(struct digital_atr_req);
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001256
1257 poll_tech_count = ddev->poll_tech_count;
1258 ddev->poll_tech_count = 0;
1259
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001260 rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
1261 NFC_COMM_PASSIVE, atr_req->gb, gb_len);
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001262 if (rc) {
1263 ddev->poll_tech_count = poll_tech_count;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001264 goto exit;
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001265 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001266
1267 rc = 0;
1268exit:
1269 if (rc)
1270 digital_poll_next_tech(ddev);
1271
1272 dev_kfree_skb(resp);
1273}