blob: 6cf2eeb2e865037f094f1a01a113db9626f80e30 [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
Mark A. Greera80509c2014-09-23 16:38:11 -070020#define DIGITAL_NFC_DEP_N_RETRY_NACK 2
Mark A. Greer384ab1d2014-09-23 16:38:13 -070021#define DIGITAL_NFC_DEP_N_RETRY_ATN 2
Mark A. Greera80509c2014-09-23 16:38:11 -070022
Thierry Escande7d0911c2013-09-19 17:55:29 +020023#define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4
24#define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5
25
26#define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0
27
28#define DIGITAL_CMD_ATR_REQ 0x00
29#define DIGITAL_CMD_ATR_RES 0x01
30#define DIGITAL_CMD_PSL_REQ 0x04
31#define DIGITAL_CMD_PSL_RES 0x05
32#define DIGITAL_CMD_DEP_REQ 0x06
33#define DIGITAL_CMD_DEP_RES 0x07
34
35#define DIGITAL_ATR_REQ_MIN_SIZE 16
36#define DIGITAL_ATR_REQ_MAX_SIZE 64
37
Thierry Escande1a09c562016-07-08 15:52:45 +020038#define DIGITAL_ATR_RES_TO_WT(s) ((s) & 0xF)
39
Mark A. Greer05afedc2014-09-23 16:38:05 -070040#define DIGITAL_DID_MAX 14
41
Mark A. Greerb08147c2014-09-23 16:38:08 -070042#define DIGITAL_PAYLOAD_SIZE_MAX 254
43#define DIGITAL_PAYLOAD_BITS_TO_PP(s) (((s) & 0x3) << 4)
44#define DIGITAL_PAYLOAD_PP_TO_BITS(s) (((s) >> 4) & 0x3)
45#define DIGITAL_PAYLOAD_BITS_TO_FSL(s) ((s) & 0x3)
46#define DIGITAL_PAYLOAD_FSL_TO_BITS(s) ((s) & 0x3)
47
Thierry Escande7d0911c2013-09-19 17:55:29 +020048#define DIGITAL_GB_BIT 0x02
49
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070050#define DIGITAL_NFC_DEP_REQ_RES_HEADROOM 2 /* SoD: [SB (NFC-A)] + LEN */
51#define DIGITAL_NFC_DEP_REQ_RES_TAILROOM 2 /* EoD: 2-byte CRC */
52
Thierry Escande7d0911c2013-09-19 17:55:29 +020053#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
54
55#define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070056#define DIGITAL_NFC_DEP_PFB_MI_BIT 0x10
57#define DIGITAL_NFC_DEP_PFB_NACK_BIT 0x10
Mark A. Greer05afedc2014-09-23 16:38:05 -070058#define DIGITAL_NFC_DEP_PFB_DID_BIT 0x04
Thierry Escande7d0911c2013-09-19 17:55:29 +020059
60#define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
61 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070062#define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_MI_BIT)
63#define DIGITAL_NFC_DEP_NACK_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_NACK_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020064#define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
Mark A. Greer05afedc2014-09-23 16:38:05 -070065#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020066#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
67
68#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
69#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
70#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
71
72struct digital_atr_req {
73 u8 dir;
74 u8 cmd;
75 u8 nfcid3[10];
76 u8 did;
77 u8 bs;
78 u8 br;
79 u8 pp;
80 u8 gb[0];
81} __packed;
82
83struct digital_atr_res {
84 u8 dir;
85 u8 cmd;
86 u8 nfcid3[10];
87 u8 did;
88 u8 bs;
89 u8 br;
90 u8 to;
91 u8 pp;
92 u8 gb[0];
93} __packed;
94
95struct digital_psl_req {
96 u8 dir;
97 u8 cmd;
98 u8 did;
99 u8 brs;
100 u8 fsl;
101} __packed;
102
103struct digital_psl_res {
104 u8 dir;
105 u8 cmd;
106 u8 did;
107} __packed;
108
109struct digital_dep_req_res {
110 u8 dir;
111 u8 cmd;
112 u8 pfb;
113} __packed;
114
115static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
116 struct sk_buff *resp);
Mark A. Greerc12715a2014-09-23 16:38:10 -0700117static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
118 struct sk_buff *resp);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200119
Mark A. Greerb08147c2014-09-23 16:38:08 -0700120static const u8 digital_payload_bits_map[4] = {
121 [0] = 64,
122 [1] = 128,
123 [2] = 192,
124 [3] = 254
125};
126
Thierry Escande1a09c562016-07-08 15:52:45 +0200127/* Response Waiting Time for ATR_RES PDU in ms
128 *
129 * RWT(ATR_RES) = RWT(nfcdep,activation) + dRWT(nfcdep) + dT(nfcdep,initiator)
130 *
131 * with:
132 * RWT(nfcdep,activation) = 4096 * 2^12 / f(c) s
133 * dRWT(nfcdep) = 16 / f(c) s
134 * dT(nfcdep,initiator) = 100 ms
135 * f(c) = 13560000 Hz
136 */
137#define DIGITAL_ATR_RES_RWT 1337
138
139/* Response Waiting Time for other DEP PDUs in ms
140 *
141 * max_rwt = rwt + dRWT(nfcdep) + dT(nfcdep,initiator)
142 *
143 * with:
144 * rwt = (256 * 16 / f(c)) * 2^wt s
145 * dRWT(nfcdep) = 16 / f(c) s
146 * dT(nfcdep,initiator) = 100 ms
147 * f(c) = 13560000 Hz
148 * 0 <= wt <= 14 (given by the target by the TO field of ATR_RES response)
149 */
150#define DIGITAL_NFC_DEP_IN_MAX_WT 14
151#define DIGITAL_NFC_DEP_TG_MAX_WT 8
152static const u16 digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT + 1] = {
153 100, 101, 101, 102, 105,
154 110, 119, 139, 177, 255,
155 409, 719, 1337, 2575, 5049,
156};
157
Mark A. Greerb08147c2014-09-23 16:38:08 -0700158static u8 digital_payload_bits_to_size(u8 payload_bits)
159{
160 if (payload_bits >= ARRAY_SIZE(digital_payload_bits_map))
161 return 0;
162
163 return digital_payload_bits_map[payload_bits];
164}
165
166static u8 digital_payload_size_to_bits(u8 payload_size)
167{
168 int i;
169
170 for (i = 0; i < ARRAY_SIZE(digital_payload_bits_map); i++)
171 if (digital_payload_bits_map[i] == payload_size)
172 return i;
173
174 return 0xff;
175}
176
Thierry Escande7d0911c2013-09-19 17:55:29 +0200177static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
178 struct sk_buff *skb)
179{
180 skb_push(skb, sizeof(u8));
181
182 skb->data[0] = skb->len;
183
184 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
185 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
186}
187
188static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
189 struct sk_buff *skb)
190{
191 u8 size;
192
193 if (skb->len < 2)
194 return -EIO;
195
196 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
197 skb_pull(skb, sizeof(u8));
198
199 size = skb->data[0];
200 if (size != skb->len)
201 return -EIO;
202
203 skb_pull(skb, sizeof(u8));
204
205 return 0;
206}
207
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700208static struct sk_buff *
209digital_send_dep_data_prep(struct nfc_digital_dev *ddev, struct sk_buff *skb,
210 struct digital_dep_req_res *dep_req_res,
211 struct digital_data_exch *data_exch)
212{
213 struct sk_buff *new_skb;
214
215 if (skb->len > ddev->remote_payload_max) {
216 dep_req_res->pfb |= DIGITAL_NFC_DEP_PFB_MI_BIT;
217
218 new_skb = digital_skb_alloc(ddev, ddev->remote_payload_max);
219 if (!new_skb) {
220 kfree_skb(ddev->chaining_skb);
221 ddev->chaining_skb = NULL;
222
223 return ERR_PTR(-ENOMEM);
224 }
225
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700226 memcpy(skb_put(new_skb, ddev->remote_payload_max), skb->data,
227 ddev->remote_payload_max);
228 skb_pull(skb, ddev->remote_payload_max);
229
230 ddev->chaining_skb = skb;
231 ddev->data_exch = data_exch;
232 } else {
233 ddev->chaining_skb = NULL;
234 new_skb = skb;
235 }
236
237 return new_skb;
238}
239
Mark A. Greerc12715a2014-09-23 16:38:10 -0700240static struct sk_buff *
241digital_recv_dep_data_gather(struct nfc_digital_dev *ddev, u8 pfb,
242 struct sk_buff *resp,
243 int (*send_ack)(struct nfc_digital_dev *ddev,
244 struct digital_data_exch
245 *data_exch),
246 struct digital_data_exch *data_exch)
247{
248 struct sk_buff *new_skb;
249 int rc;
250
251 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb) && (!ddev->chaining_skb)) {
252 ddev->chaining_skb =
253 nfc_alloc_recv_skb(8 * ddev->local_payload_max,
254 GFP_KERNEL);
255 if (!ddev->chaining_skb) {
256 rc = -ENOMEM;
257 goto error;
258 }
259 }
260
261 if (ddev->chaining_skb) {
262 if (resp->len > skb_tailroom(ddev->chaining_skb)) {
263 new_skb = skb_copy_expand(ddev->chaining_skb,
264 skb_headroom(
265 ddev->chaining_skb),
266 8 * ddev->local_payload_max,
267 GFP_KERNEL);
268 if (!new_skb) {
269 rc = -ENOMEM;
270 goto error;
271 }
272
273 kfree_skb(ddev->chaining_skb);
274 ddev->chaining_skb = new_skb;
275 }
276
277 memcpy(skb_put(ddev->chaining_skb, resp->len), resp->data,
278 resp->len);
279
280 kfree_skb(resp);
281 resp = NULL;
282
283 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
284 rc = send_ack(ddev, data_exch);
285 if (rc)
286 goto error;
287
288 return NULL;
289 }
290
291 resp = ddev->chaining_skb;
292 ddev->chaining_skb = NULL;
293 }
294
295 return resp;
296
297error:
298 kfree_skb(resp);
299
300 kfree_skb(ddev->chaining_skb);
301 ddev->chaining_skb = NULL;
302
303 return ERR_PTR(rc);
304}
305
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700306static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg,
307 struct sk_buff *resp)
308{
309 struct nfc_target *target = arg;
310 struct digital_psl_res *psl_res;
311 int rc;
312
313 if (IS_ERR(resp)) {
314 rc = PTR_ERR(resp);
315 resp = NULL;
316 goto exit;
317 }
318
319 rc = ddev->skb_check_crc(resp);
320 if (rc) {
321 PROTOCOL_ERR("14.4.1.6");
322 goto exit;
323 }
324
325 rc = digital_skb_pull_dep_sod(ddev, resp);
326 if (rc) {
327 PROTOCOL_ERR("14.4.1.2");
328 goto exit;
329 }
330
331 psl_res = (struct digital_psl_res *)resp->data;
332
333 if ((resp->len != sizeof(*psl_res)) ||
334 (psl_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN) ||
335 (psl_res->cmd != DIGITAL_CMD_PSL_RES)) {
336 rc = -EIO;
337 goto exit;
338 }
339
340 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
341 NFC_DIGITAL_RF_TECH_424F);
342 if (rc)
343 goto exit;
344
345 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
346 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
347 if (rc)
348 goto exit;
349
350 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev) &&
351 (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)) {
352 ddev->skb_add_crc = digital_skb_add_crc_f;
353 ddev->skb_check_crc = digital_skb_check_crc_f;
354 }
355
356 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_424F;
357
358 nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
359 NFC_RF_INITIATOR);
360
361 ddev->curr_nfc_dep_pni = 0;
362
363exit:
364 dev_kfree_skb(resp);
365
366 if (rc)
367 ddev->curr_protocol = 0;
368}
369
370static int digital_in_send_psl_req(struct nfc_digital_dev *ddev,
371 struct nfc_target *target)
372{
373 struct sk_buff *skb;
374 struct digital_psl_req *psl_req;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700375 int rc;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700376 u8 payload_size, payload_bits;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700377
378 skb = digital_skb_alloc(ddev, sizeof(*psl_req));
379 if (!skb)
380 return -ENOMEM;
381
382 skb_put(skb, sizeof(*psl_req));
383
384 psl_req = (struct digital_psl_req *)skb->data;
385
386 psl_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
387 psl_req->cmd = DIGITAL_CMD_PSL_REQ;
388 psl_req->did = 0;
389 psl_req->brs = (0x2 << 3) | 0x2; /* 424F both directions */
Mark A. Greerb08147c2014-09-23 16:38:08 -0700390
391 payload_size = min(ddev->local_payload_max, ddev->remote_payload_max);
392 payload_bits = digital_payload_size_to_bits(payload_size);
393 psl_req->fsl = DIGITAL_PAYLOAD_BITS_TO_FSL(payload_bits);
394
395 ddev->local_payload_max = payload_size;
396 ddev->remote_payload_max = payload_size;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700397
398 digital_skb_push_dep_sod(ddev, skb);
399
400 ddev->skb_add_crc(skb);
401
Thierry Escande1a09c562016-07-08 15:52:45 +0200402 rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt,
403 digital_in_recv_psl_res, target);
Mark A. Greerb15829b2014-09-23 16:38:02 -0700404 if (rc)
405 kfree_skb(skb);
406
407 return rc;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700408}
409
Thierry Escande7d0911c2013-09-19 17:55:29 +0200410static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
411 struct sk_buff *resp)
412{
413 struct nfc_target *target = arg;
414 struct digital_atr_res *atr_res;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700415 u8 gb_len, payload_bits;
Thierry Escande1a09c562016-07-08 15:52:45 +0200416 u8 wt;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200417 int rc;
418
419 if (IS_ERR(resp)) {
420 rc = PTR_ERR(resp);
421 resp = NULL;
422 goto exit;
423 }
424
425 rc = ddev->skb_check_crc(resp);
426 if (rc) {
427 PROTOCOL_ERR("14.4.1.6");
428 goto exit;
429 }
430
431 rc = digital_skb_pull_dep_sod(ddev, resp);
432 if (rc) {
433 PROTOCOL_ERR("14.4.1.2");
434 goto exit;
435 }
436
437 if (resp->len < sizeof(struct digital_atr_res)) {
438 rc = -EIO;
439 goto exit;
440 }
441
442 gb_len = resp->len - sizeof(struct digital_atr_res);
443
444 atr_res = (struct digital_atr_res *)resp->data;
445
Thierry Escande1a09c562016-07-08 15:52:45 +0200446 wt = DIGITAL_ATR_RES_TO_WT(atr_res->to);
447 if (wt > DIGITAL_NFC_DEP_IN_MAX_WT)
448 wt = DIGITAL_NFC_DEP_IN_MAX_WT;
449 ddev->dep_rwt = digital_rwt_map[wt];
450
Mark A. Greerb08147c2014-09-23 16:38:08 -0700451 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_res->pp);
452 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits);
453
454 if (!ddev->remote_payload_max) {
455 rc = -EINVAL;
456 goto exit;
457 }
458
Thierry Escande7d0911c2013-09-19 17:55:29 +0200459 rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
460 if (rc)
461 goto exit;
462
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700463 if ((ddev->protocols & NFC_PROTO_FELICA_MASK) &&
464 (ddev->curr_rf_tech != NFC_DIGITAL_RF_TECH_424F)) {
465 rc = digital_in_send_psl_req(ddev, target);
466 if (!rc)
467 goto exit;
468 }
469
Thierry Escande7d0911c2013-09-19 17:55:29 +0200470 rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
471 NFC_RF_INITIATOR);
472
473 ddev->curr_nfc_dep_pni = 0;
474
475exit:
476 dev_kfree_skb(resp);
477
478 if (rc)
479 ddev->curr_protocol = 0;
480}
481
482int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
483 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
484 size_t gb_len)
485{
486 struct sk_buff *skb;
487 struct digital_atr_req *atr_req;
488 uint size;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700489 int rc;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700490 u8 payload_bits;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200491
492 size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
493
494 if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
495 PROTOCOL_ERR("14.6.1.1");
496 return -EINVAL;
497 }
498
499 skb = digital_skb_alloc(ddev, size);
500 if (!skb)
501 return -ENOMEM;
502
503 skb_put(skb, sizeof(struct digital_atr_req));
504
505 atr_req = (struct digital_atr_req *)skb->data;
506 memset(atr_req, 0, sizeof(struct digital_atr_req));
507
508 atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
509 atr_req->cmd = DIGITAL_CMD_ATR_REQ;
510 if (target->nfcid2_len)
Thierry Escande4f319e32014-01-02 11:58:14 +0100511 memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200512 else
Thierry Escande4f319e32014-01-02 11:58:14 +0100513 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200514
515 atr_req->did = 0;
516 atr_req->bs = 0;
517 atr_req->br = 0;
518
Mark A. Greerb08147c2014-09-23 16:38:08 -0700519 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX;
520 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);
521 atr_req->pp = DIGITAL_PAYLOAD_BITS_TO_PP(payload_bits);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200522
523 if (gb_len) {
524 atr_req->pp |= DIGITAL_GB_BIT;
525 memcpy(skb_put(skb, gb_len), gb, gb_len);
526 }
527
528 digital_skb_push_dep_sod(ddev, skb);
529
530 ddev->skb_add_crc(skb);
531
Thierry Escande1a09c562016-07-08 15:52:45 +0200532 rc = digital_in_send_cmd(ddev, skb, DIGITAL_ATR_RES_RWT,
533 digital_in_recv_atr_res, target);
Mark A. Greerb15829b2014-09-23 16:38:02 -0700534 if (rc)
535 kfree_skb(skb);
536
537 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200538}
539
Mark A. Greerc12715a2014-09-23 16:38:10 -0700540static int digital_in_send_ack(struct nfc_digital_dev *ddev,
541 struct digital_data_exch *data_exch)
542{
543 struct digital_dep_req_res *dep_req;
544 struct sk_buff *skb;
545 int rc;
546
547 skb = digital_skb_alloc(ddev, 1);
548 if (!skb)
549 return -ENOMEM;
550
551 skb_push(skb, sizeof(struct digital_dep_req_res));
552
553 dep_req = (struct digital_dep_req_res *)skb->data;
554
555 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
556 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
557 dep_req->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
558 ddev->curr_nfc_dep_pni;
559
560 digital_skb_push_dep_sod(ddev, skb);
561
562 ddev->skb_add_crc(skb);
563
Thierry Escande1d984c22016-07-08 15:52:39 +0200564 ddev->saved_skb = pskb_copy(skb, GFP_KERNEL);
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700565
Thierry Escande1a09c562016-07-08 15:52:45 +0200566 rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt,
567 digital_in_recv_dep_res, data_exch);
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700568 if (rc) {
Mark A. Greerc12715a2014-09-23 16:38:10 -0700569 kfree_skb(skb);
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700570 kfree_skb(ddev->saved_skb);
571 ddev->saved_skb = NULL;
572 }
Mark A. Greerc12715a2014-09-23 16:38:10 -0700573
574 return rc;
575}
576
Mark A. Greera80509c2014-09-23 16:38:11 -0700577static int digital_in_send_nack(struct nfc_digital_dev *ddev,
578 struct digital_data_exch *data_exch)
579{
580 struct digital_dep_req_res *dep_req;
581 struct sk_buff *skb;
582 int rc;
583
584 skb = digital_skb_alloc(ddev, 1);
585 if (!skb)
586 return -ENOMEM;
587
588 skb_push(skb, sizeof(struct digital_dep_req_res));
589
590 dep_req = (struct digital_dep_req_res *)skb->data;
591
592 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
593 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
594 dep_req->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
595 DIGITAL_NFC_DEP_PFB_NACK_BIT | ddev->curr_nfc_dep_pni;
596
597 digital_skb_push_dep_sod(ddev, skb);
598
599 ddev->skb_add_crc(skb);
600
Thierry Escande1a09c562016-07-08 15:52:45 +0200601 rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt,
602 digital_in_recv_dep_res, data_exch);
Mark A. Greera80509c2014-09-23 16:38:11 -0700603 if (rc)
604 kfree_skb(skb);
605
606 return rc;
607}
608
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700609static int digital_in_send_atn(struct nfc_digital_dev *ddev,
610 struct digital_data_exch *data_exch)
611{
612 struct digital_dep_req_res *dep_req;
613 struct sk_buff *skb;
614 int rc;
615
616 skb = digital_skb_alloc(ddev, 1);
617 if (!skb)
618 return -ENOMEM;
619
620 skb_push(skb, sizeof(struct digital_dep_req_res));
621
622 dep_req = (struct digital_dep_req_res *)skb->data;
623
624 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
625 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
626 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU;
627
628 digital_skb_push_dep_sod(ddev, skb);
629
630 ddev->skb_add_crc(skb);
631
Thierry Escande1a09c562016-07-08 15:52:45 +0200632 rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt,
633 digital_in_recv_dep_res, data_exch);
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700634 if (rc)
635 kfree_skb(skb);
636
637 return rc;
638}
639
Thierry Escande7d0911c2013-09-19 17:55:29 +0200640static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
641 struct digital_data_exch *data_exch, u8 rtox)
642{
643 struct digital_dep_req_res *dep_req;
644 struct sk_buff *skb;
645 int rc;
646
647 skb = digital_skb_alloc(ddev, 1);
648 if (!skb)
649 return -ENOMEM;
650
651 *skb_put(skb, 1) = rtox;
652
653 skb_push(skb, sizeof(struct digital_dep_req_res));
654
655 dep_req = (struct digital_dep_req_res *)skb->data;
656
657 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
658 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
659 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
660 DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
661
662 digital_skb_push_dep_sod(ddev, skb);
663
664 ddev->skb_add_crc(skb);
665
Thierry Escande1a09c562016-07-08 15:52:45 +0200666 rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt,
667 digital_in_recv_dep_res, data_exch);
Thierry Escande1d984c22016-07-08 15:52:39 +0200668 if (rc)
Mark A. Greerb15829b2014-09-23 16:38:02 -0700669 kfree_skb(skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200670
671 return rc;
672}
673
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700674static int digital_in_send_saved_skb(struct nfc_digital_dev *ddev,
675 struct digital_data_exch *data_exch)
676{
Thierry Escande1d984c22016-07-08 15:52:39 +0200677 int rc;
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700678
Thierry Escande1d984c22016-07-08 15:52:39 +0200679 if (!ddev->saved_skb)
680 return -EINVAL;
681
682 skb_get(ddev->saved_skb);
683
Thierry Escande1a09c562016-07-08 15:52:45 +0200684 rc = digital_in_send_cmd(ddev, ddev->saved_skb, ddev->dep_rwt,
Thierry Escande1d984c22016-07-08 15:52:39 +0200685 digital_in_recv_dep_res, data_exch);
686 if (rc)
687 kfree_skb(ddev->saved_skb);
688
689 return rc;
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700690}
691
Thierry Escande7d0911c2013-09-19 17:55:29 +0200692static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
693 struct sk_buff *resp)
694{
695 struct digital_data_exch *data_exch = arg;
696 struct digital_dep_req_res *dep_res;
697 u8 pfb;
698 uint size;
699 int rc;
700
701 if (IS_ERR(resp)) {
702 rc = PTR_ERR(resp);
703 resp = NULL;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200704
Thierry Escande3f89fea2016-06-16 20:24:42 +0200705 if ((rc == -EIO || (rc == -ETIMEDOUT && ddev->nack_count)) &&
Mark A. Greera80509c2014-09-23 16:38:11 -0700706 (ddev->nack_count++ < DIGITAL_NFC_DEP_N_RETRY_NACK)) {
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700707 ddev->atn_count = 0;
708
Mark A. Greera80509c2014-09-23 16:38:11 -0700709 rc = digital_in_send_nack(ddev, data_exch);
710 if (rc)
711 goto error;
712
713 return;
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700714 } else if ((rc == -ETIMEDOUT) &&
715 (ddev->atn_count++ < DIGITAL_NFC_DEP_N_RETRY_ATN)) {
716 ddev->nack_count = 0;
717
718 rc = digital_in_send_atn(ddev, data_exch);
719 if (rc)
720 goto error;
721
722 return;
Mark A. Greera80509c2014-09-23 16:38:11 -0700723 }
724
725 goto exit;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200726 }
727
728 rc = digital_skb_pull_dep_sod(ddev, resp);
729 if (rc) {
730 PROTOCOL_ERR("14.4.1.2");
731 goto exit;
732 }
733
Mark A. Greera80509c2014-09-23 16:38:11 -0700734 rc = ddev->skb_check_crc(resp);
735 if (rc) {
736 if ((resp->len >= 4) &&
737 (ddev->nack_count++ < DIGITAL_NFC_DEP_N_RETRY_NACK)) {
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700738 ddev->atn_count = 0;
739
Mark A. Greera80509c2014-09-23 16:38:11 -0700740 rc = digital_in_send_nack(ddev, data_exch);
741 if (rc)
742 goto error;
743
744 kfree_skb(resp);
745
746 return;
747 }
748
749 PROTOCOL_ERR("14.4.1.6");
750 goto error;
751 }
752
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700753 ddev->atn_count = 0;
Mark A. Greera80509c2014-09-23 16:38:11 -0700754 ddev->nack_count = 0;
755
Mark A. Greerb08147c2014-09-23 16:38:08 -0700756 if (resp->len > ddev->local_payload_max) {
757 rc = -EMSGSIZE;
758 goto exit;
759 }
760
Mark A. Greer6ce30662014-09-23 16:38:03 -0700761 size = sizeof(struct digital_dep_req_res);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200762 dep_res = (struct digital_dep_req_res *)resp->data;
763
Mark A. Greer6ce30662014-09-23 16:38:03 -0700764 if (resp->len < size || dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
Thierry Escande7d0911c2013-09-19 17:55:29 +0200765 dep_res->cmd != DIGITAL_CMD_DEP_RES) {
766 rc = -EIO;
767 goto error;
768 }
769
770 pfb = dep_res->pfb;
771
Mark A. Greer3bc3f882014-09-23 16:38:04 -0700772 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
773 PROTOCOL_ERR("14.8.2.1");
774 rc = -EIO;
775 goto error;
776 }
Mark A. Greer6ce30662014-09-23 16:38:03 -0700777
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700778 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
779 rc = -EIO;
780 goto exit;
781 }
782
Mark A. Greer6ce30662014-09-23 16:38:03 -0700783 if (size > resp->len) {
784 rc = -EIO;
785 goto error;
786 }
787
788 skb_pull(resp, size);
789
Thierry Escande7d0911c2013-09-19 17:55:29 +0200790 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
791 case DIGITAL_NFC_DEP_PFB_I_PDU:
792 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
793 PROTOCOL_ERR("14.12.3.3");
794 rc = -EIO;
795 goto error;
796 }
797
798 ddev->curr_nfc_dep_pni =
799 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
Mark A. Greerc12715a2014-09-23 16:38:10 -0700800
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700801 kfree_skb(ddev->saved_skb);
802 ddev->saved_skb = NULL;
803
Mark A. Greerc12715a2014-09-23 16:38:10 -0700804 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
805 digital_in_send_ack,
806 data_exch);
807 if (IS_ERR(resp)) {
808 rc = PTR_ERR(resp);
809 resp = NULL;
810 goto error;
811 }
812
813 /* If resp is NULL then we're still chaining so return and
814 * wait for the next part of the PDU. Else, the PDU is
815 * complete so pass it up.
816 */
817 if (!resp)
818 return;
819
Thierry Escande7d0911c2013-09-19 17:55:29 +0200820 rc = 0;
821 break;
822
823 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Thierry Escandee073eb62016-07-08 15:52:43 +0200824 if (DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) {
825 PROTOCOL_ERR("14.12.4.5");
826 rc = -EIO;
827 goto exit;
828 }
829
Mark A. Greer485fdc92014-09-23 16:38:07 -0700830 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
831 PROTOCOL_ERR("14.12.3.3");
832 rc = -EIO;
833 goto exit;
834 }
835
836 ddev->curr_nfc_dep_pni =
837 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
838
Thierry Escandee073eb62016-07-08 15:52:43 +0200839 if (!ddev->chaining_skb) {
840 PROTOCOL_ERR("14.12.4.3");
841 rc = -EIO;
842 goto exit;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700843 }
844
Thierry Escandee073eb62016-07-08 15:52:43 +0200845 /* The initiator has received a valid ACK. Free the last sent
846 * PDU and keep on sending chained skb.
847 */
848 kfree_skb(ddev->saved_skb);
849 ddev->saved_skb = NULL;
850
851 rc = digital_in_send_dep_req(ddev, NULL,
852 ddev->chaining_skb,
853 ddev->data_exch);
854 if (rc)
855 goto error;
856
857 goto free_resp;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200858
859 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700860 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { /* ATN */
861 rc = digital_in_send_saved_skb(ddev, data_exch);
Thierry Escande1d984c22016-07-08 15:52:39 +0200862 if (rc)
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700863 goto error;
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700864
Thierry Escandee200f002016-07-08 15:52:44 +0200865 goto free_resp;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200866 }
867
Mark A. Greer6ce30662014-09-23 16:38:03 -0700868 rc = digital_in_send_rtox(ddev, data_exch, resp->data[0]);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200869 if (rc)
870 goto error;
871
Thierry Escandee200f002016-07-08 15:52:44 +0200872 goto free_resp;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200873 }
874
Thierry Escande7d0911c2013-09-19 17:55:29 +0200875exit:
876 data_exch->cb(data_exch->cb_context, resp, rc);
877
878error:
879 kfree(data_exch);
880
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700881 kfree_skb(ddev->chaining_skb);
882 ddev->chaining_skb = NULL;
883
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700884 kfree_skb(ddev->saved_skb);
885 ddev->saved_skb = NULL;
886
Thierry Escande7d0911c2013-09-19 17:55:29 +0200887 if (rc)
888 kfree_skb(resp);
Thierry Escandee073eb62016-07-08 15:52:43 +0200889
890 return;
891
892free_resp:
893 dev_kfree_skb(resp);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200894}
895
896int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
897 struct nfc_target *target, struct sk_buff *skb,
898 struct digital_data_exch *data_exch)
899{
900 struct digital_dep_req_res *dep_req;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700901 struct sk_buff *chaining_skb, *tmp_skb;
902 int rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200903
904 skb_push(skb, sizeof(struct digital_dep_req_res));
905
906 dep_req = (struct digital_dep_req_res *)skb->data;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700907
Thierry Escande7d0911c2013-09-19 17:55:29 +0200908 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
909 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
910 dep_req->pfb = ddev->curr_nfc_dep_pni;
911
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700912 ddev->atn_count = 0;
Mark A. Greera80509c2014-09-23 16:38:11 -0700913 ddev->nack_count = 0;
914
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700915 chaining_skb = ddev->chaining_skb;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200916
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700917 tmp_skb = digital_send_dep_data_prep(ddev, skb, dep_req, data_exch);
918 if (IS_ERR(tmp_skb))
919 return PTR_ERR(tmp_skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200920
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700921 digital_skb_push_dep_sod(ddev, tmp_skb);
922
923 ddev->skb_add_crc(tmp_skb);
924
Thierry Escande1d984c22016-07-08 15:52:39 +0200925 ddev->saved_skb = pskb_copy(tmp_skb, GFP_KERNEL);
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700926
Thierry Escande1a09c562016-07-08 15:52:45 +0200927 rc = digital_in_send_cmd(ddev, tmp_skb, ddev->dep_rwt,
928 digital_in_recv_dep_res, data_exch);
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700929 if (rc) {
930 if (tmp_skb != skb)
931 kfree_skb(tmp_skb);
932
933 kfree_skb(chaining_skb);
934 ddev->chaining_skb = NULL;
Mark A. Greer384ab1d2014-09-23 16:38:13 -0700935
936 kfree_skb(ddev->saved_skb);
937 ddev->saved_skb = NULL;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700938 }
939
940 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200941}
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200942
Thierry Escandeb711ad52014-01-06 23:34:48 +0100943static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
944{
945 ddev->curr_rf_tech = rf_tech;
946
947 ddev->skb_add_crc = digital_skb_add_crc_none;
948 ddev->skb_check_crc = digital_skb_check_crc_none;
949
950 if (DIGITAL_DRV_CAPS_TG_CRC(ddev))
951 return;
952
953 switch (ddev->curr_rf_tech) {
954 case NFC_DIGITAL_RF_TECH_106A:
955 ddev->skb_add_crc = digital_skb_add_crc_a;
956 ddev->skb_check_crc = digital_skb_check_crc_a;
957 break;
958
959 case NFC_DIGITAL_RF_TECH_212F:
960 case NFC_DIGITAL_RF_TECH_424F:
961 ddev->skb_add_crc = digital_skb_add_crc_f;
962 ddev->skb_check_crc = digital_skb_check_crc_f;
963 break;
964
965 default:
966 break;
967 }
968}
969
Mark A. Greerc12715a2014-09-23 16:38:10 -0700970static int digital_tg_send_ack(struct nfc_digital_dev *ddev,
971 struct digital_data_exch *data_exch)
972{
973 struct digital_dep_req_res *dep_res;
974 struct sk_buff *skb;
975 int rc;
976
977 skb = digital_skb_alloc(ddev, 1);
978 if (!skb)
979 return -ENOMEM;
980
981 skb_push(skb, sizeof(struct digital_dep_req_res));
982
983 dep_res = (struct digital_dep_req_res *)skb->data;
984
985 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
986 dep_res->cmd = DIGITAL_CMD_DEP_RES;
987 dep_res->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
988 ddev->curr_nfc_dep_pni;
989
990 if (ddev->did) {
991 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
992
993 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
994 sizeof(ddev->did));
995 }
996
997 ddev->curr_nfc_dep_pni =
998 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
999
1000 digital_skb_push_dep_sod(ddev, skb);
1001
1002 ddev->skb_add_crc(skb);
1003
Thierry Escande1d984c22016-07-08 15:52:39 +02001004 ddev->saved_skb = pskb_copy(skb, GFP_KERNEL);
Mark A. Greer49dbb142014-09-23 16:38:12 -07001005
Mark A. Greerc12715a2014-09-23 16:38:10 -07001006 rc = digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
1007 data_exch);
Mark A. Greer49dbb142014-09-23 16:38:12 -07001008 if (rc) {
Mark A. Greerc12715a2014-09-23 16:38:10 -07001009 kfree_skb(skb);
Mark A. Greer49dbb142014-09-23 16:38:12 -07001010 kfree_skb(ddev->saved_skb);
1011 ddev->saved_skb = NULL;
1012 }
Mark A. Greerc12715a2014-09-23 16:38:10 -07001013
1014 return rc;
1015}
1016
Mark A. Greer9b5ec0f2014-09-23 16:38:14 -07001017static int digital_tg_send_atn(struct nfc_digital_dev *ddev)
1018{
1019 struct digital_dep_req_res *dep_res;
1020 struct sk_buff *skb;
1021 int rc;
1022
1023 skb = digital_skb_alloc(ddev, 1);
1024 if (!skb)
1025 return -ENOMEM;
1026
1027 skb_push(skb, sizeof(struct digital_dep_req_res));
1028
1029 dep_res = (struct digital_dep_req_res *)skb->data;
1030
1031 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1032 dep_res->cmd = DIGITAL_CMD_DEP_RES;
1033 dep_res->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU;
1034
1035 if (ddev->did) {
1036 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
1037
1038 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
1039 sizeof(ddev->did));
1040 }
1041
1042 digital_skb_push_dep_sod(ddev, skb);
1043
1044 ddev->skb_add_crc(skb);
1045
1046 rc = digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
1047 NULL);
1048 if (rc)
1049 kfree_skb(skb);
1050
1051 return rc;
1052}
1053
Mark A. Greer49dbb142014-09-23 16:38:12 -07001054static int digital_tg_send_saved_skb(struct nfc_digital_dev *ddev)
1055{
Thierry Escande1d984c22016-07-08 15:52:39 +02001056 int rc;
Mark A. Greer49dbb142014-09-23 16:38:12 -07001057
Thierry Escande1d984c22016-07-08 15:52:39 +02001058 if (!ddev->saved_skb)
1059 return -EINVAL;
1060
1061 skb_get(ddev->saved_skb);
1062
1063 rc = digital_tg_send_cmd(ddev, ddev->saved_skb, 1500,
1064 digital_tg_recv_dep_req, NULL);
1065 if (rc)
1066 kfree_skb(ddev->saved_skb);
1067
1068 return rc;
Mark A. Greer49dbb142014-09-23 16:38:12 -07001069}
1070
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001071static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
1072 struct sk_buff *resp)
1073{
1074 int rc;
1075 struct digital_dep_req_res *dep_req;
Mark A. Greer6ce30662014-09-23 16:38:03 -07001076 u8 pfb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001077 size_t size;
1078
1079 if (IS_ERR(resp)) {
1080 rc = PTR_ERR(resp);
1081 resp = NULL;
1082 goto exit;
1083 }
1084
1085 rc = ddev->skb_check_crc(resp);
1086 if (rc) {
1087 PROTOCOL_ERR("14.4.1.6");
1088 goto exit;
1089 }
1090
1091 rc = digital_skb_pull_dep_sod(ddev, resp);
1092 if (rc) {
1093 PROTOCOL_ERR("14.4.1.2");
1094 goto exit;
1095 }
1096
Mark A. Greerb08147c2014-09-23 16:38:08 -07001097 if (resp->len > ddev->local_payload_max) {
1098 rc = -EMSGSIZE;
1099 goto exit;
1100 }
1101
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001102 size = sizeof(struct digital_dep_req_res);
1103 dep_req = (struct digital_dep_req_res *)resp->data;
1104
1105 if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
1106 dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
1107 rc = -EIO;
1108 goto exit;
1109 }
1110
Mark A. Greer6ce30662014-09-23 16:38:03 -07001111 pfb = dep_req->pfb;
1112
Mark A. Greer05afedc2014-09-23 16:38:05 -07001113 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
1114 if (ddev->did && (ddev->did == resp->data[3])) {
1115 size++;
1116 } else {
1117 rc = -EIO;
1118 goto exit;
1119 }
1120 } else if (ddev->did) {
1121 rc = -EIO;
1122 goto exit;
1123 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001124
Mark A. Greer3e6b0de2014-09-23 16:38:06 -07001125 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
1126 rc = -EIO;
1127 goto exit;
1128 }
1129
Mark A. Greer6ce30662014-09-23 16:38:03 -07001130 if (size > resp->len) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001131 rc = -EIO;
1132 goto exit;
1133 }
1134
Mark A. Greer6ce30662014-09-23 16:38:03 -07001135 skb_pull(resp, size);
1136
1137 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001138 case DIGITAL_NFC_DEP_PFB_I_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +02001139 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
Mark A. Greer485fdc92014-09-23 16:38:07 -07001140
Thierry Escandef23a9862016-07-08 15:52:41 +02001141 if (ddev->atn_count) {
1142 /* The target has received (and replied to) at least one
1143 * ATN DEP_REQ.
1144 */
1145 ddev->atn_count = 0;
1146
1147 /* pni of resp PDU equal to the target current pni - 1
1148 * means resp is the previous DEP_REQ PDU received from
1149 * the initiator so the target replies with saved_skb
1150 * which is the previous DEP_RES saved in
1151 * digital_tg_send_dep_res().
1152 */
1153 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) ==
1154 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni - 1)) {
1155 rc = digital_tg_send_saved_skb(ddev);
1156 if (rc)
1157 goto exit;
1158
1159 goto free_resp;
1160 }
1161
1162 /* atn_count > 0 and PDU pni != curr_nfc_dep_pni - 1
1163 * means the target probably did not received the last
1164 * DEP_REQ PDU sent by the initiator. The target
1165 * fallbacks to normal processing then.
1166 */
1167 }
1168
1169 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
Mark A. Greer485fdc92014-09-23 16:38:07 -07001170 PROTOCOL_ERR("14.12.3.4");
1171 rc = -EIO;
1172 goto exit;
1173 }
1174
Mark A. Greer49dbb142014-09-23 16:38:12 -07001175 kfree_skb(ddev->saved_skb);
1176 ddev->saved_skb = NULL;
1177
Mark A. Greerc12715a2014-09-23 16:38:10 -07001178 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
1179 digital_tg_send_ack, NULL);
1180 if (IS_ERR(resp)) {
1181 rc = PTR_ERR(resp);
1182 resp = NULL;
1183 goto exit;
1184 }
1185
1186 /* If resp is NULL then we're still chaining so return and
1187 * wait for the next part of the PDU. Else, the PDU is
1188 * complete so pass it up.
1189 */
1190 if (!resp)
1191 return;
1192
Mark A. Greer485fdc92014-09-23 16:38:07 -07001193 rc = 0;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001194 break;
1195 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Thierry Escande482333b2016-07-08 15:52:42 +02001196 if (DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { /* NACK */
1197 if (DIGITAL_NFC_DEP_PFB_PNI(pfb + 1) !=
1198 ddev->curr_nfc_dep_pni) {
Mark A. Greer49dbb142014-09-23 16:38:12 -07001199 rc = -EIO;
1200 goto exit;
1201 }
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001202
Mark A. Greer9b5ec0f2014-09-23 16:38:14 -07001203 ddev->atn_count = 0;
1204
Mark A. Greer49dbb142014-09-23 16:38:12 -07001205 rc = digital_tg_send_saved_skb(ddev);
Thierry Escande1d984c22016-07-08 15:52:39 +02001206 if (rc)
Mark A. Greer49dbb142014-09-23 16:38:12 -07001207 goto exit;
Thierry Escande482333b2016-07-08 15:52:42 +02001208
1209 goto free_resp;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001210 }
1211
Thierry Escande482333b2016-07-08 15:52:42 +02001212 /* ACK */
1213 if (ddev->atn_count) {
1214 /* The target has previously recevied one or more ATN
1215 * PDUs.
1216 */
1217 ddev->atn_count = 0;
1218
1219 /* If the ACK PNI is equal to the target PNI - 1 means
1220 * that the initiator did not receive the previous PDU
1221 * sent by the target so re-send it.
1222 */
1223 if (DIGITAL_NFC_DEP_PFB_PNI(pfb + 1) ==
1224 ddev->curr_nfc_dep_pni) {
1225 rc = digital_tg_send_saved_skb(ddev);
1226 if (rc)
1227 goto exit;
1228
1229 goto free_resp;
1230 }
1231
1232 /* Otherwise, the target did not receive the previous
1233 * ACK PDU from the initiator. Fallback to normal
1234 * processing of chained PDU then.
1235 */
1236 }
1237
1238 /* Keep on sending chained PDU */
1239 if (!ddev->chaining_skb ||
1240 DIGITAL_NFC_DEP_PFB_PNI(pfb) !=
1241 ddev->curr_nfc_dep_pni) {
1242 rc = -EIO;
1243 goto exit;
1244 }
1245
1246 kfree_skb(ddev->saved_skb);
1247 ddev->saved_skb = NULL;
1248
1249 rc = digital_tg_send_dep_res(ddev, ddev->chaining_skb);
1250 if (rc)
1251 goto exit;
1252
1253 goto free_resp;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001254 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
Mark A. Greer9b5ec0f2014-09-23 16:38:14 -07001255 if (DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
1256 rc = -EINVAL;
1257 goto exit;
1258 }
1259
1260 rc = digital_tg_send_atn(ddev);
1261 if (rc)
1262 goto exit;
1263
1264 ddev->atn_count++;
1265
Thierry Escandee200f002016-07-08 15:52:44 +02001266 goto free_resp;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001267 }
1268
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001269 rc = nfc_tm_data_received(ddev->nfc_dev, resp);
1270
1271exit:
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001272 kfree_skb(ddev->chaining_skb);
1273 ddev->chaining_skb = NULL;
1274
Mark A. Greer9b5ec0f2014-09-23 16:38:14 -07001275 ddev->atn_count = 0;
1276
Mark A. Greer49dbb142014-09-23 16:38:12 -07001277 kfree_skb(ddev->saved_skb);
1278 ddev->saved_skb = NULL;
1279
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001280 if (rc)
1281 kfree_skb(resp);
Thierry Escandef23a9862016-07-08 15:52:41 +02001282
1283 return;
1284
1285free_resp:
1286 dev_kfree_skb(resp);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001287}
1288
1289int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
1290{
1291 struct digital_dep_req_res *dep_res;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001292 struct sk_buff *chaining_skb, *tmp_skb;
1293 int rc;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001294
1295 skb_push(skb, sizeof(struct digital_dep_req_res));
Mark A. Greerb08147c2014-09-23 16:38:08 -07001296
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001297 dep_res = (struct digital_dep_req_res *)skb->data;
1298
1299 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1300 dep_res->cmd = DIGITAL_CMD_DEP_RES;
1301 dep_res->pfb = ddev->curr_nfc_dep_pni;
1302
Mark A. Greer05afedc2014-09-23 16:38:05 -07001303 if (ddev->did) {
1304 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
1305
1306 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
1307 sizeof(ddev->did));
1308 }
1309
Mark A. Greer485fdc92014-09-23 16:38:07 -07001310 ddev->curr_nfc_dep_pni =
1311 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
1312
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001313 chaining_skb = ddev->chaining_skb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001314
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001315 tmp_skb = digital_send_dep_data_prep(ddev, skb, dep_res, NULL);
1316 if (IS_ERR(tmp_skb))
1317 return PTR_ERR(tmp_skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001318
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001319 digital_skb_push_dep_sod(ddev, tmp_skb);
1320
1321 ddev->skb_add_crc(tmp_skb);
1322
Thierry Escande1d984c22016-07-08 15:52:39 +02001323 ddev->saved_skb = pskb_copy(tmp_skb, GFP_KERNEL);
Mark A. Greer49dbb142014-09-23 16:38:12 -07001324
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001325 rc = digital_tg_send_cmd(ddev, tmp_skb, 1500, digital_tg_recv_dep_req,
1326 NULL);
1327 if (rc) {
1328 if (tmp_skb != skb)
1329 kfree_skb(tmp_skb);
1330
1331 kfree_skb(chaining_skb);
1332 ddev->chaining_skb = NULL;
Mark A. Greer49dbb142014-09-23 16:38:12 -07001333
1334 kfree_skb(ddev->saved_skb);
1335 ddev->saved_skb = NULL;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001336 }
1337
1338 return rc;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001339}
1340
1341static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
1342 void *arg, struct sk_buff *resp)
1343{
Thierry Escande67af1d72014-01-02 11:58:13 +01001344 u8 rf_tech = (unsigned long)arg;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001345
1346 if (IS_ERR(resp))
1347 return;
1348
Thierry Escandeb711ad52014-01-06 23:34:48 +01001349 digital_tg_set_rf_tech(ddev, rf_tech);
1350
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001351 digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
1352
1353 digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
1354
1355 dev_kfree_skb(resp);
1356}
1357
1358static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
1359 u8 rf_tech)
1360{
1361 struct digital_psl_res *psl_res;
1362 struct sk_buff *skb;
1363 int rc;
1364
1365 skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
1366 if (!skb)
1367 return -ENOMEM;
1368
1369 skb_put(skb, sizeof(struct digital_psl_res));
1370
1371 psl_res = (struct digital_psl_res *)skb->data;
1372
1373 psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1374 psl_res->cmd = DIGITAL_CMD_PSL_RES;
1375 psl_res->did = did;
1376
1377 digital_skb_push_dep_sod(ddev, skb);
1378
1379 ddev->skb_add_crc(skb);
1380
Mark A. Greer485fdc92014-09-23 16:38:07 -07001381 ddev->curr_nfc_dep_pni = 0;
1382
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001383 rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
Thierry Escande67af1d72014-01-02 11:58:13 +01001384 (void *)(unsigned long)rf_tech);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001385 if (rc)
1386 kfree_skb(skb);
1387
1388 return rc;
1389}
1390
1391static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
1392 struct sk_buff *resp)
1393{
1394 int rc;
1395 struct digital_psl_req *psl_req;
1396 u8 rf_tech;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001397 u8 dsi, payload_size, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001398
1399 if (IS_ERR(resp)) {
1400 rc = PTR_ERR(resp);
1401 resp = NULL;
1402 goto exit;
1403 }
1404
1405 rc = ddev->skb_check_crc(resp);
1406 if (rc) {
1407 PROTOCOL_ERR("14.4.1.6");
1408 goto exit;
1409 }
1410
1411 rc = digital_skb_pull_dep_sod(ddev, resp);
1412 if (rc) {
1413 PROTOCOL_ERR("14.4.1.2");
1414 goto exit;
1415 }
1416
1417 psl_req = (struct digital_psl_req *)resp->data;
1418
1419 if (resp->len != sizeof(struct digital_psl_req) ||
1420 psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
1421 psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
1422 rc = -EIO;
1423 goto exit;
1424 }
1425
1426 dsi = (psl_req->brs >> 3) & 0x07;
1427 switch (dsi) {
1428 case 0:
1429 rf_tech = NFC_DIGITAL_RF_TECH_106A;
1430 break;
1431 case 1:
1432 rf_tech = NFC_DIGITAL_RF_TECH_212F;
1433 break;
1434 case 2:
1435 rf_tech = NFC_DIGITAL_RF_TECH_424F;
1436 break;
1437 default:
Masanari Iida77d84ff2013-12-09 00:22:53 +09001438 pr_err("Unsupported dsi value %d\n", dsi);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001439 goto exit;
1440 }
1441
Mark A. Greerb08147c2014-09-23 16:38:08 -07001442 payload_bits = DIGITAL_PAYLOAD_FSL_TO_BITS(psl_req->fsl);
1443 payload_size = digital_payload_bits_to_size(payload_bits);
1444
1445 if (!payload_size || (payload_size > min(ddev->local_payload_max,
1446 ddev->remote_payload_max))) {
1447 rc = -EINVAL;
1448 goto exit;
1449 }
1450
1451 ddev->local_payload_max = payload_size;
1452 ddev->remote_payload_max = payload_size;
1453
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001454 rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
1455
1456exit:
1457 kfree_skb(resp);
1458}
1459
1460static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
1461 void *arg, struct sk_buff *resp)
1462{
1463 int offset;
1464
1465 if (IS_ERR(resp)) {
1466 digital_poll_next_tech(ddev);
1467 return;
1468 }
1469
1470 offset = 2;
1471 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
1472 offset++;
1473
Mark A. Greer9b5ec0f2014-09-23 16:38:14 -07001474 ddev->atn_count = 0;
1475
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001476 if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
1477 digital_tg_recv_psl_req(ddev, arg, resp);
1478 else
1479 digital_tg_recv_dep_req(ddev, arg, resp);
1480}
1481
1482static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
1483 struct digital_atr_req *atr_req)
1484{
1485 struct digital_atr_res *atr_res;
1486 struct sk_buff *skb;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001487 u8 *gb, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001488 size_t gb_len;
1489 int rc;
1490
1491 gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
1492 if (!gb)
1493 gb_len = 0;
1494
1495 skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
1496 if (!skb)
1497 return -ENOMEM;
1498
1499 skb_put(skb, sizeof(struct digital_atr_res));
1500 atr_res = (struct digital_atr_res *)skb->data;
1501
1502 memset(atr_res, 0, sizeof(struct digital_atr_res));
1503
1504 atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1505 atr_res->cmd = DIGITAL_CMD_ATR_RES;
1506 memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
Thierry Escande1a09c562016-07-08 15:52:45 +02001507 atr_res->to = DIGITAL_NFC_DEP_TG_MAX_WT;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001508
1509 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX;
1510 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);
1511 atr_res->pp = DIGITAL_PAYLOAD_BITS_TO_PP(payload_bits);
1512
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001513 if (gb_len) {
1514 skb_put(skb, gb_len);
1515
1516 atr_res->pp |= DIGITAL_GB_BIT;
1517 memcpy(atr_res->gb, gb, gb_len);
1518 }
1519
1520 digital_skb_push_dep_sod(ddev, skb);
1521
1522 ddev->skb_add_crc(skb);
1523
Mark A. Greer485fdc92014-09-23 16:38:07 -07001524 ddev->curr_nfc_dep_pni = 0;
1525
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001526 rc = digital_tg_send_cmd(ddev, skb, 999,
1527 digital_tg_send_atr_res_complete, NULL);
Mark A. Greerb15829b2014-09-23 16:38:02 -07001528 if (rc)
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001529 kfree_skb(skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001530
1531 return rc;
1532}
1533
1534void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
1535 struct sk_buff *resp)
1536{
1537 int rc;
1538 struct digital_atr_req *atr_req;
1539 size_t gb_len, min_size;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001540 u8 poll_tech_count, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001541
1542 if (IS_ERR(resp)) {
1543 rc = PTR_ERR(resp);
1544 resp = NULL;
1545 goto exit;
1546 }
1547
1548 if (!resp->len) {
1549 rc = -EIO;
1550 goto exit;
1551 }
1552
1553 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
1554 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
Thierry Escandeb711ad52014-01-06 23:34:48 +01001555 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_106A);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001556 } else {
1557 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
Thierry Escandeb711ad52014-01-06 23:34:48 +01001558 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_212F);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001559 }
1560
1561 if (resp->len < min_size) {
1562 rc = -EIO;
1563 goto exit;
1564 }
1565
Thierry Escande48e10442014-01-06 23:34:37 +01001566 ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001567
1568 rc = ddev->skb_check_crc(resp);
1569 if (rc) {
1570 PROTOCOL_ERR("14.4.1.6");
1571 goto exit;
1572 }
1573
1574 rc = digital_skb_pull_dep_sod(ddev, resp);
1575 if (rc) {
1576 PROTOCOL_ERR("14.4.1.2");
1577 goto exit;
1578 }
1579
1580 atr_req = (struct digital_atr_req *)resp->data;
1581
1582 if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
Mark A. Greer05afedc2014-09-23 16:38:05 -07001583 atr_req->cmd != DIGITAL_CMD_ATR_REQ ||
1584 atr_req->did > DIGITAL_DID_MAX) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001585 rc = -EINVAL;
1586 goto exit;
1587 }
1588
Mark A. Greerb08147c2014-09-23 16:38:08 -07001589 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_req->pp);
1590 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits);
1591
1592 if (!ddev->remote_payload_max) {
1593 rc = -EINVAL;
1594 goto exit;
1595 }
1596
Mark A. Greer05afedc2014-09-23 16:38:05 -07001597 ddev->did = atr_req->did;
1598
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001599 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
1600 NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
1601 if (rc)
1602 goto exit;
1603
1604 rc = digital_tg_send_atr_res(ddev, atr_req);
1605 if (rc)
1606 goto exit;
1607
1608 gb_len = resp->len - sizeof(struct digital_atr_req);
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001609
1610 poll_tech_count = ddev->poll_tech_count;
1611 ddev->poll_tech_count = 0;
1612
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001613 rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
1614 NFC_COMM_PASSIVE, atr_req->gb, gb_len);
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001615 if (rc) {
1616 ddev->poll_tech_count = poll_tech_count;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001617 goto exit;
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001618 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001619
1620 rc = 0;
1621exit:
1622 if (rc)
1623 digital_poll_next_tech(ddev);
1624
1625 dev_kfree_skb(resp);
1626}