blob: 31418edbe78ef7bebe45c171af1f38cc93f126ef [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
21
Thierry Escande7d0911c2013-09-19 17:55:29 +020022#define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4
23#define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5
24
25#define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0
26
27#define DIGITAL_CMD_ATR_REQ 0x00
28#define DIGITAL_CMD_ATR_RES 0x01
29#define DIGITAL_CMD_PSL_REQ 0x04
30#define DIGITAL_CMD_PSL_RES 0x05
31#define DIGITAL_CMD_DEP_REQ 0x06
32#define DIGITAL_CMD_DEP_RES 0x07
33
34#define DIGITAL_ATR_REQ_MIN_SIZE 16
35#define DIGITAL_ATR_REQ_MAX_SIZE 64
36
Mark A. Greer05afedc2014-09-23 16:38:05 -070037#define DIGITAL_DID_MAX 14
38
Mark A. Greerb08147c2014-09-23 16:38:08 -070039#define DIGITAL_PAYLOAD_SIZE_MAX 254
40#define DIGITAL_PAYLOAD_BITS_TO_PP(s) (((s) & 0x3) << 4)
41#define DIGITAL_PAYLOAD_PP_TO_BITS(s) (((s) >> 4) & 0x3)
42#define DIGITAL_PAYLOAD_BITS_TO_FSL(s) ((s) & 0x3)
43#define DIGITAL_PAYLOAD_FSL_TO_BITS(s) ((s) & 0x3)
44
Thierry Escande7d0911c2013-09-19 17:55:29 +020045#define DIGITAL_GB_BIT 0x02
46
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070047#define DIGITAL_NFC_DEP_REQ_RES_HEADROOM 2 /* SoD: [SB (NFC-A)] + LEN */
48#define DIGITAL_NFC_DEP_REQ_RES_TAILROOM 2 /* EoD: 2-byte CRC */
49
Thierry Escande7d0911c2013-09-19 17:55:29 +020050#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
51
52#define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070053#define DIGITAL_NFC_DEP_PFB_MI_BIT 0x10
54#define DIGITAL_NFC_DEP_PFB_NACK_BIT 0x10
Mark A. Greer05afedc2014-09-23 16:38:05 -070055#define DIGITAL_NFC_DEP_PFB_DID_BIT 0x04
Thierry Escande7d0911c2013-09-19 17:55:29 +020056
57#define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
58 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -070059#define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_MI_BIT)
60#define DIGITAL_NFC_DEP_NACK_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_NACK_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020061#define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
Mark A. Greer05afedc2014-09-23 16:38:05 -070062#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT)
Thierry Escande7d0911c2013-09-19 17:55:29 +020063#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
64
65#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
66#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
67#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
68
69struct digital_atr_req {
70 u8 dir;
71 u8 cmd;
72 u8 nfcid3[10];
73 u8 did;
74 u8 bs;
75 u8 br;
76 u8 pp;
77 u8 gb[0];
78} __packed;
79
80struct digital_atr_res {
81 u8 dir;
82 u8 cmd;
83 u8 nfcid3[10];
84 u8 did;
85 u8 bs;
86 u8 br;
87 u8 to;
88 u8 pp;
89 u8 gb[0];
90} __packed;
91
92struct digital_psl_req {
93 u8 dir;
94 u8 cmd;
95 u8 did;
96 u8 brs;
97 u8 fsl;
98} __packed;
99
100struct digital_psl_res {
101 u8 dir;
102 u8 cmd;
103 u8 did;
104} __packed;
105
106struct digital_dep_req_res {
107 u8 dir;
108 u8 cmd;
109 u8 pfb;
110} __packed;
111
112static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
113 struct sk_buff *resp);
Mark A. Greerc12715a2014-09-23 16:38:10 -0700114static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
115 struct sk_buff *resp);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200116
Mark A. Greerb08147c2014-09-23 16:38:08 -0700117static const u8 digital_payload_bits_map[4] = {
118 [0] = 64,
119 [1] = 128,
120 [2] = 192,
121 [3] = 254
122};
123
124static u8 digital_payload_bits_to_size(u8 payload_bits)
125{
126 if (payload_bits >= ARRAY_SIZE(digital_payload_bits_map))
127 return 0;
128
129 return digital_payload_bits_map[payload_bits];
130}
131
132static u8 digital_payload_size_to_bits(u8 payload_size)
133{
134 int i;
135
136 for (i = 0; i < ARRAY_SIZE(digital_payload_bits_map); i++)
137 if (digital_payload_bits_map[i] == payload_size)
138 return i;
139
140 return 0xff;
141}
142
Thierry Escande7d0911c2013-09-19 17:55:29 +0200143static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
144 struct sk_buff *skb)
145{
146 skb_push(skb, sizeof(u8));
147
148 skb->data[0] = skb->len;
149
150 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
151 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
152}
153
154static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
155 struct sk_buff *skb)
156{
157 u8 size;
158
159 if (skb->len < 2)
160 return -EIO;
161
162 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
163 skb_pull(skb, sizeof(u8));
164
165 size = skb->data[0];
166 if (size != skb->len)
167 return -EIO;
168
169 skb_pull(skb, sizeof(u8));
170
171 return 0;
172}
173
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700174static struct sk_buff *
175digital_send_dep_data_prep(struct nfc_digital_dev *ddev, struct sk_buff *skb,
176 struct digital_dep_req_res *dep_req_res,
177 struct digital_data_exch *data_exch)
178{
179 struct sk_buff *new_skb;
180
181 if (skb->len > ddev->remote_payload_max) {
182 dep_req_res->pfb |= DIGITAL_NFC_DEP_PFB_MI_BIT;
183
184 new_skb = digital_skb_alloc(ddev, ddev->remote_payload_max);
185 if (!new_skb) {
186 kfree_skb(ddev->chaining_skb);
187 ddev->chaining_skb = NULL;
188
189 return ERR_PTR(-ENOMEM);
190 }
191
192 skb_reserve(new_skb, ddev->tx_headroom + NFC_HEADER_SIZE +
193 DIGITAL_NFC_DEP_REQ_RES_HEADROOM);
194 memcpy(skb_put(new_skb, ddev->remote_payload_max), skb->data,
195 ddev->remote_payload_max);
196 skb_pull(skb, ddev->remote_payload_max);
197
198 ddev->chaining_skb = skb;
199 ddev->data_exch = data_exch;
200 } else {
201 ddev->chaining_skb = NULL;
202 new_skb = skb;
203 }
204
205 return new_skb;
206}
207
Mark A. Greerc12715a2014-09-23 16:38:10 -0700208static struct sk_buff *
209digital_recv_dep_data_gather(struct nfc_digital_dev *ddev, u8 pfb,
210 struct sk_buff *resp,
211 int (*send_ack)(struct nfc_digital_dev *ddev,
212 struct digital_data_exch
213 *data_exch),
214 struct digital_data_exch *data_exch)
215{
216 struct sk_buff *new_skb;
217 int rc;
218
219 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb) && (!ddev->chaining_skb)) {
220 ddev->chaining_skb =
221 nfc_alloc_recv_skb(8 * ddev->local_payload_max,
222 GFP_KERNEL);
223 if (!ddev->chaining_skb) {
224 rc = -ENOMEM;
225 goto error;
226 }
227 }
228
229 if (ddev->chaining_skb) {
230 if (resp->len > skb_tailroom(ddev->chaining_skb)) {
231 new_skb = skb_copy_expand(ddev->chaining_skb,
232 skb_headroom(
233 ddev->chaining_skb),
234 8 * ddev->local_payload_max,
235 GFP_KERNEL);
236 if (!new_skb) {
237 rc = -ENOMEM;
238 goto error;
239 }
240
241 kfree_skb(ddev->chaining_skb);
242 ddev->chaining_skb = new_skb;
243 }
244
245 memcpy(skb_put(ddev->chaining_skb, resp->len), resp->data,
246 resp->len);
247
248 kfree_skb(resp);
249 resp = NULL;
250
251 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
252 rc = send_ack(ddev, data_exch);
253 if (rc)
254 goto error;
255
256 return NULL;
257 }
258
259 resp = ddev->chaining_skb;
260 ddev->chaining_skb = NULL;
261 }
262
263 return resp;
264
265error:
266 kfree_skb(resp);
267
268 kfree_skb(ddev->chaining_skb);
269 ddev->chaining_skb = NULL;
270
271 return ERR_PTR(rc);
272}
273
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700274static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg,
275 struct sk_buff *resp)
276{
277 struct nfc_target *target = arg;
278 struct digital_psl_res *psl_res;
279 int rc;
280
281 if (IS_ERR(resp)) {
282 rc = PTR_ERR(resp);
283 resp = NULL;
284 goto exit;
285 }
286
287 rc = ddev->skb_check_crc(resp);
288 if (rc) {
289 PROTOCOL_ERR("14.4.1.6");
290 goto exit;
291 }
292
293 rc = digital_skb_pull_dep_sod(ddev, resp);
294 if (rc) {
295 PROTOCOL_ERR("14.4.1.2");
296 goto exit;
297 }
298
299 psl_res = (struct digital_psl_res *)resp->data;
300
301 if ((resp->len != sizeof(*psl_res)) ||
302 (psl_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN) ||
303 (psl_res->cmd != DIGITAL_CMD_PSL_RES)) {
304 rc = -EIO;
305 goto exit;
306 }
307
308 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
309 NFC_DIGITAL_RF_TECH_424F);
310 if (rc)
311 goto exit;
312
313 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
314 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
315 if (rc)
316 goto exit;
317
318 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev) &&
319 (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)) {
320 ddev->skb_add_crc = digital_skb_add_crc_f;
321 ddev->skb_check_crc = digital_skb_check_crc_f;
322 }
323
324 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_424F;
325
326 nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
327 NFC_RF_INITIATOR);
328
329 ddev->curr_nfc_dep_pni = 0;
330
331exit:
332 dev_kfree_skb(resp);
333
334 if (rc)
335 ddev->curr_protocol = 0;
336}
337
338static int digital_in_send_psl_req(struct nfc_digital_dev *ddev,
339 struct nfc_target *target)
340{
341 struct sk_buff *skb;
342 struct digital_psl_req *psl_req;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700343 int rc;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700344 u8 payload_size, payload_bits;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700345
346 skb = digital_skb_alloc(ddev, sizeof(*psl_req));
347 if (!skb)
348 return -ENOMEM;
349
350 skb_put(skb, sizeof(*psl_req));
351
352 psl_req = (struct digital_psl_req *)skb->data;
353
354 psl_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
355 psl_req->cmd = DIGITAL_CMD_PSL_REQ;
356 psl_req->did = 0;
357 psl_req->brs = (0x2 << 3) | 0x2; /* 424F both directions */
Mark A. Greerb08147c2014-09-23 16:38:08 -0700358
359 payload_size = min(ddev->local_payload_max, ddev->remote_payload_max);
360 payload_bits = digital_payload_size_to_bits(payload_size);
361 psl_req->fsl = DIGITAL_PAYLOAD_BITS_TO_FSL(payload_bits);
362
363 ddev->local_payload_max = payload_size;
364 ddev->remote_payload_max = payload_size;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700365
366 digital_skb_push_dep_sod(ddev, skb);
367
368 ddev->skb_add_crc(skb);
369
Mark A. Greerb15829b2014-09-23 16:38:02 -0700370 rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res,
371 target);
372 if (rc)
373 kfree_skb(skb);
374
375 return rc;
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700376}
377
Thierry Escande7d0911c2013-09-19 17:55:29 +0200378static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
379 struct sk_buff *resp)
380{
381 struct nfc_target *target = arg;
382 struct digital_atr_res *atr_res;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700383 u8 gb_len, payload_bits;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200384 int rc;
385
386 if (IS_ERR(resp)) {
387 rc = PTR_ERR(resp);
388 resp = NULL;
389 goto exit;
390 }
391
392 rc = ddev->skb_check_crc(resp);
393 if (rc) {
394 PROTOCOL_ERR("14.4.1.6");
395 goto exit;
396 }
397
398 rc = digital_skb_pull_dep_sod(ddev, resp);
399 if (rc) {
400 PROTOCOL_ERR("14.4.1.2");
401 goto exit;
402 }
403
404 if (resp->len < sizeof(struct digital_atr_res)) {
405 rc = -EIO;
406 goto exit;
407 }
408
409 gb_len = resp->len - sizeof(struct digital_atr_res);
410
411 atr_res = (struct digital_atr_res *)resp->data;
412
Mark A. Greerb08147c2014-09-23 16:38:08 -0700413 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_res->pp);
414 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits);
415
416 if (!ddev->remote_payload_max) {
417 rc = -EINVAL;
418 goto exit;
419 }
420
Thierry Escande7d0911c2013-09-19 17:55:29 +0200421 rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
422 if (rc)
423 goto exit;
424
Mark A. Greerdddb3da2014-07-22 20:18:01 -0700425 if ((ddev->protocols & NFC_PROTO_FELICA_MASK) &&
426 (ddev->curr_rf_tech != NFC_DIGITAL_RF_TECH_424F)) {
427 rc = digital_in_send_psl_req(ddev, target);
428 if (!rc)
429 goto exit;
430 }
431
Thierry Escande7d0911c2013-09-19 17:55:29 +0200432 rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
433 NFC_RF_INITIATOR);
434
435 ddev->curr_nfc_dep_pni = 0;
436
437exit:
438 dev_kfree_skb(resp);
439
440 if (rc)
441 ddev->curr_protocol = 0;
442}
443
444int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
445 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
446 size_t gb_len)
447{
448 struct sk_buff *skb;
449 struct digital_atr_req *atr_req;
450 uint size;
Mark A. Greerb15829b2014-09-23 16:38:02 -0700451 int rc;
Mark A. Greerb08147c2014-09-23 16:38:08 -0700452 u8 payload_bits;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200453
454 size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
455
456 if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
457 PROTOCOL_ERR("14.6.1.1");
458 return -EINVAL;
459 }
460
461 skb = digital_skb_alloc(ddev, size);
462 if (!skb)
463 return -ENOMEM;
464
465 skb_put(skb, sizeof(struct digital_atr_req));
466
467 atr_req = (struct digital_atr_req *)skb->data;
468 memset(atr_req, 0, sizeof(struct digital_atr_req));
469
470 atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
471 atr_req->cmd = DIGITAL_CMD_ATR_REQ;
472 if (target->nfcid2_len)
Thierry Escande4f319e32014-01-02 11:58:14 +0100473 memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200474 else
Thierry Escande4f319e32014-01-02 11:58:14 +0100475 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200476
477 atr_req->did = 0;
478 atr_req->bs = 0;
479 atr_req->br = 0;
480
Mark A. Greerb08147c2014-09-23 16:38:08 -0700481 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX;
482 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);
483 atr_req->pp = DIGITAL_PAYLOAD_BITS_TO_PP(payload_bits);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200484
485 if (gb_len) {
486 atr_req->pp |= DIGITAL_GB_BIT;
487 memcpy(skb_put(skb, gb_len), gb, gb_len);
488 }
489
490 digital_skb_push_dep_sod(ddev, skb);
491
492 ddev->skb_add_crc(skb);
493
Mark A. Greerb15829b2014-09-23 16:38:02 -0700494 rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res,
495 target);
496 if (rc)
497 kfree_skb(skb);
498
499 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200500}
501
Mark A. Greerc12715a2014-09-23 16:38:10 -0700502static int digital_in_send_ack(struct nfc_digital_dev *ddev,
503 struct digital_data_exch *data_exch)
504{
505 struct digital_dep_req_res *dep_req;
506 struct sk_buff *skb;
507 int rc;
508
509 skb = digital_skb_alloc(ddev, 1);
510 if (!skb)
511 return -ENOMEM;
512
513 skb_push(skb, sizeof(struct digital_dep_req_res));
514
515 dep_req = (struct digital_dep_req_res *)skb->data;
516
517 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
518 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
519 dep_req->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
520 ddev->curr_nfc_dep_pni;
521
522 digital_skb_push_dep_sod(ddev, skb);
523
524 ddev->skb_add_crc(skb);
525
526 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
527 data_exch);
528 if (rc)
529 kfree_skb(skb);
530
531 return rc;
532}
533
Mark A. Greera80509c2014-09-23 16:38:11 -0700534static int digital_in_send_nack(struct nfc_digital_dev *ddev,
535 struct digital_data_exch *data_exch)
536{
537 struct digital_dep_req_res *dep_req;
538 struct sk_buff *skb;
539 int rc;
540
541 skb = digital_skb_alloc(ddev, 1);
542 if (!skb)
543 return -ENOMEM;
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_ACK_NACK_PDU |
552 DIGITAL_NFC_DEP_PFB_NACK_BIT | ddev->curr_nfc_dep_pni;
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);
560 if (rc)
561 kfree_skb(skb);
562
563 return rc;
564}
565
Thierry Escande7d0911c2013-09-19 17:55:29 +0200566static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
567 struct digital_data_exch *data_exch, u8 rtox)
568{
569 struct digital_dep_req_res *dep_req;
570 struct sk_buff *skb;
571 int rc;
572
573 skb = digital_skb_alloc(ddev, 1);
574 if (!skb)
575 return -ENOMEM;
576
577 *skb_put(skb, 1) = rtox;
578
579 skb_push(skb, sizeof(struct digital_dep_req_res));
580
581 dep_req = (struct digital_dep_req_res *)skb->data;
582
583 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
584 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
585 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
586 DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
587
588 digital_skb_push_dep_sod(ddev, skb);
589
590 ddev->skb_add_crc(skb);
591
592 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
593 data_exch);
Mark A. Greerb15829b2014-09-23 16:38:02 -0700594 if (rc)
595 kfree_skb(skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200596
597 return rc;
598}
599
600static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
601 struct sk_buff *resp)
602{
603 struct digital_data_exch *data_exch = arg;
604 struct digital_dep_req_res *dep_res;
605 u8 pfb;
606 uint size;
607 int rc;
608
609 if (IS_ERR(resp)) {
610 rc = PTR_ERR(resp);
611 resp = NULL;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200612
Mark A. Greera80509c2014-09-23 16:38:11 -0700613 if ((rc != -ETIMEDOUT) &&
614 (ddev->nack_count++ < DIGITAL_NFC_DEP_N_RETRY_NACK)) {
615 rc = digital_in_send_nack(ddev, data_exch);
616 if (rc)
617 goto error;
618
619 return;
620 }
621
622 goto exit;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200623 }
624
625 rc = digital_skb_pull_dep_sod(ddev, resp);
626 if (rc) {
627 PROTOCOL_ERR("14.4.1.2");
628 goto exit;
629 }
630
Mark A. Greera80509c2014-09-23 16:38:11 -0700631 rc = ddev->skb_check_crc(resp);
632 if (rc) {
633 if ((resp->len >= 4) &&
634 (ddev->nack_count++ < DIGITAL_NFC_DEP_N_RETRY_NACK)) {
635 rc = digital_in_send_nack(ddev, data_exch);
636 if (rc)
637 goto error;
638
639 kfree_skb(resp);
640
641 return;
642 }
643
644 PROTOCOL_ERR("14.4.1.6");
645 goto error;
646 }
647
648 ddev->nack_count = 0;
649
Mark A. Greerb08147c2014-09-23 16:38:08 -0700650 if (resp->len > ddev->local_payload_max) {
651 rc = -EMSGSIZE;
652 goto exit;
653 }
654
Mark A. Greer6ce30662014-09-23 16:38:03 -0700655 size = sizeof(struct digital_dep_req_res);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200656 dep_res = (struct digital_dep_req_res *)resp->data;
657
Mark A. Greer6ce30662014-09-23 16:38:03 -0700658 if (resp->len < size || dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
Thierry Escande7d0911c2013-09-19 17:55:29 +0200659 dep_res->cmd != DIGITAL_CMD_DEP_RES) {
660 rc = -EIO;
661 goto error;
662 }
663
664 pfb = dep_res->pfb;
665
Mark A. Greer3bc3f882014-09-23 16:38:04 -0700666 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
667 PROTOCOL_ERR("14.8.2.1");
668 rc = -EIO;
669 goto error;
670 }
Mark A. Greer6ce30662014-09-23 16:38:03 -0700671
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700672 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
673 rc = -EIO;
674 goto exit;
675 }
676
Mark A. Greer6ce30662014-09-23 16:38:03 -0700677 if (size > resp->len) {
678 rc = -EIO;
679 goto error;
680 }
681
682 skb_pull(resp, size);
683
Thierry Escande7d0911c2013-09-19 17:55:29 +0200684 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
685 case DIGITAL_NFC_DEP_PFB_I_PDU:
686 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
687 PROTOCOL_ERR("14.12.3.3");
688 rc = -EIO;
689 goto error;
690 }
691
692 ddev->curr_nfc_dep_pni =
693 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
Mark A. Greerc12715a2014-09-23 16:38:10 -0700694
695 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
696 digital_in_send_ack,
697 data_exch);
698 if (IS_ERR(resp)) {
699 rc = PTR_ERR(resp);
700 resp = NULL;
701 goto error;
702 }
703
704 /* If resp is NULL then we're still chaining so return and
705 * wait for the next part of the PDU. Else, the PDU is
706 * complete so pass it up.
707 */
708 if (!resp)
709 return;
710
Thierry Escande7d0911c2013-09-19 17:55:29 +0200711 rc = 0;
712 break;
713
714 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Mark A. Greer485fdc92014-09-23 16:38:07 -0700715 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
716 PROTOCOL_ERR("14.12.3.3");
717 rc = -EIO;
718 goto exit;
719 }
720
721 ddev->curr_nfc_dep_pni =
722 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
723
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700724 if (ddev->chaining_skb && !DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) {
725 rc = digital_in_send_dep_req(ddev, NULL,
726 ddev->chaining_skb,
727 ddev->data_exch);
728 if (rc)
729 goto error;
730
731 return;
732 }
733
734 pr_err("Received a ACK/NACK PDU\n");
Mark A. Greer485fdc92014-09-23 16:38:07 -0700735 rc = -EINVAL;
736 goto exit;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200737
738 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
739 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
740 rc = -EINVAL;
741 goto error;
742 }
743
Mark A. Greer6ce30662014-09-23 16:38:03 -0700744 rc = digital_in_send_rtox(ddev, data_exch, resp->data[0]);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200745 if (rc)
746 goto error;
747
748 kfree_skb(resp);
749 return;
750 }
751
Thierry Escande7d0911c2013-09-19 17:55:29 +0200752exit:
753 data_exch->cb(data_exch->cb_context, resp, rc);
754
755error:
756 kfree(data_exch);
757
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700758 kfree_skb(ddev->chaining_skb);
759 ddev->chaining_skb = NULL;
760
Thierry Escande7d0911c2013-09-19 17:55:29 +0200761 if (rc)
762 kfree_skb(resp);
763}
764
765int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
766 struct nfc_target *target, struct sk_buff *skb,
767 struct digital_data_exch *data_exch)
768{
769 struct digital_dep_req_res *dep_req;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700770 struct sk_buff *chaining_skb, *tmp_skb;
771 int rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200772
773 skb_push(skb, sizeof(struct digital_dep_req_res));
774
775 dep_req = (struct digital_dep_req_res *)skb->data;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700776
Thierry Escande7d0911c2013-09-19 17:55:29 +0200777 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
778 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
779 dep_req->pfb = ddev->curr_nfc_dep_pni;
780
Mark A. Greera80509c2014-09-23 16:38:11 -0700781 ddev->nack_count = 0;
782
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700783 chaining_skb = ddev->chaining_skb;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200784
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700785 tmp_skb = digital_send_dep_data_prep(ddev, skb, dep_req, data_exch);
786 if (IS_ERR(tmp_skb))
787 return PTR_ERR(tmp_skb);
Thierry Escande7d0911c2013-09-19 17:55:29 +0200788
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700789 digital_skb_push_dep_sod(ddev, tmp_skb);
790
791 ddev->skb_add_crc(tmp_skb);
792
793 rc = digital_in_send_cmd(ddev, tmp_skb, 1500, digital_in_recv_dep_res,
794 data_exch);
795 if (rc) {
796 if (tmp_skb != skb)
797 kfree_skb(tmp_skb);
798
799 kfree_skb(chaining_skb);
800 ddev->chaining_skb = NULL;
801 }
802
803 return rc;
Thierry Escande7d0911c2013-09-19 17:55:29 +0200804}
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200805
Thierry Escandeb711ad52014-01-06 23:34:48 +0100806static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
807{
808 ddev->curr_rf_tech = rf_tech;
809
810 ddev->skb_add_crc = digital_skb_add_crc_none;
811 ddev->skb_check_crc = digital_skb_check_crc_none;
812
813 if (DIGITAL_DRV_CAPS_TG_CRC(ddev))
814 return;
815
816 switch (ddev->curr_rf_tech) {
817 case NFC_DIGITAL_RF_TECH_106A:
818 ddev->skb_add_crc = digital_skb_add_crc_a;
819 ddev->skb_check_crc = digital_skb_check_crc_a;
820 break;
821
822 case NFC_DIGITAL_RF_TECH_212F:
823 case NFC_DIGITAL_RF_TECH_424F:
824 ddev->skb_add_crc = digital_skb_add_crc_f;
825 ddev->skb_check_crc = digital_skb_check_crc_f;
826 break;
827
828 default:
829 break;
830 }
831}
832
Mark A. Greerc12715a2014-09-23 16:38:10 -0700833static int digital_tg_send_ack(struct nfc_digital_dev *ddev,
834 struct digital_data_exch *data_exch)
835{
836 struct digital_dep_req_res *dep_res;
837 struct sk_buff *skb;
838 int rc;
839
840 skb = digital_skb_alloc(ddev, 1);
841 if (!skb)
842 return -ENOMEM;
843
844 skb_push(skb, sizeof(struct digital_dep_req_res));
845
846 dep_res = (struct digital_dep_req_res *)skb->data;
847
848 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
849 dep_res->cmd = DIGITAL_CMD_DEP_RES;
850 dep_res->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
851 ddev->curr_nfc_dep_pni;
852
853 if (ddev->did) {
854 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
855
856 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
857 sizeof(ddev->did));
858 }
859
860 ddev->curr_nfc_dep_pni =
861 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
862
863 digital_skb_push_dep_sod(ddev, skb);
864
865 ddev->skb_add_crc(skb);
866
Mark A. Greer49dbb142014-09-23 16:38:12 -0700867 ddev->saved_skb = skb_get(skb);
868 ddev->saved_skb_len = skb->len;
869
Mark A. Greerc12715a2014-09-23 16:38:10 -0700870 rc = digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
871 data_exch);
Mark A. Greer49dbb142014-09-23 16:38:12 -0700872 if (rc) {
Mark A. Greerc12715a2014-09-23 16:38:10 -0700873 kfree_skb(skb);
Mark A. Greer49dbb142014-09-23 16:38:12 -0700874 kfree_skb(ddev->saved_skb);
875 ddev->saved_skb = NULL;
876 }
Mark A. Greerc12715a2014-09-23 16:38:10 -0700877
878 return rc;
879}
880
Mark A. Greer49dbb142014-09-23 16:38:12 -0700881static int digital_tg_send_saved_skb(struct nfc_digital_dev *ddev)
882{
883 skb_get(ddev->saved_skb);
884 skb_push(ddev->saved_skb, ddev->saved_skb_len);
885
886 return digital_tg_send_cmd(ddev, ddev->saved_skb, 1500,
887 digital_tg_recv_dep_req, NULL);
888}
889
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200890static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
891 struct sk_buff *resp)
892{
893 int rc;
894 struct digital_dep_req_res *dep_req;
Mark A. Greer6ce30662014-09-23 16:38:03 -0700895 u8 pfb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200896 size_t size;
897
898 if (IS_ERR(resp)) {
899 rc = PTR_ERR(resp);
900 resp = NULL;
901 goto exit;
902 }
903
904 rc = ddev->skb_check_crc(resp);
905 if (rc) {
906 PROTOCOL_ERR("14.4.1.6");
907 goto exit;
908 }
909
910 rc = digital_skb_pull_dep_sod(ddev, resp);
911 if (rc) {
912 PROTOCOL_ERR("14.4.1.2");
913 goto exit;
914 }
915
Mark A. Greerb08147c2014-09-23 16:38:08 -0700916 if (resp->len > ddev->local_payload_max) {
917 rc = -EMSGSIZE;
918 goto exit;
919 }
920
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200921 size = sizeof(struct digital_dep_req_res);
922 dep_req = (struct digital_dep_req_res *)resp->data;
923
924 if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
925 dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
926 rc = -EIO;
927 goto exit;
928 }
929
Mark A. Greer6ce30662014-09-23 16:38:03 -0700930 pfb = dep_req->pfb;
931
Mark A. Greer05afedc2014-09-23 16:38:05 -0700932 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) {
933 if (ddev->did && (ddev->did == resp->data[3])) {
934 size++;
935 } else {
936 rc = -EIO;
937 goto exit;
938 }
939 } else if (ddev->did) {
940 rc = -EIO;
941 goto exit;
942 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200943
Mark A. Greer3e6b0de2014-09-23 16:38:06 -0700944 if (DIGITAL_NFC_DEP_NAD_BIT_SET(pfb)) {
945 rc = -EIO;
946 goto exit;
947 }
948
Mark A. Greer6ce30662014-09-23 16:38:03 -0700949 if (size > resp->len) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200950 rc = -EIO;
951 goto exit;
952 }
953
Mark A. Greer6ce30662014-09-23 16:38:03 -0700954 skb_pull(resp, size);
955
956 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200957 case DIGITAL_NFC_DEP_PFB_I_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +0200958 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
Mark A. Greer485fdc92014-09-23 16:38:07 -0700959
960 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
961 PROTOCOL_ERR("14.12.3.4");
962 rc = -EIO;
963 goto exit;
964 }
965
Mark A. Greer49dbb142014-09-23 16:38:12 -0700966 kfree_skb(ddev->saved_skb);
967 ddev->saved_skb = NULL;
968
Mark A. Greerc12715a2014-09-23 16:38:10 -0700969 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
970 digital_tg_send_ack, NULL);
971 if (IS_ERR(resp)) {
972 rc = PTR_ERR(resp);
973 resp = NULL;
974 goto exit;
975 }
976
977 /* If resp is NULL then we're still chaining so return and
978 * wait for the next part of the PDU. Else, the PDU is
979 * complete so pass it up.
980 */
981 if (!resp)
982 return;
983
Mark A. Greer485fdc92014-09-23 16:38:07 -0700984 rc = 0;
Thierry Escande1c7a4c22013-09-19 17:55:30 +0200985 break;
986 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
Mark A. Greer49dbb142014-09-23 16:38:12 -0700987 if (!DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { /* ACK */
988 if ((DIGITAL_NFC_DEP_PFB_PNI(pfb) !=
989 ddev->curr_nfc_dep_pni) ||
990 !ddev->chaining_skb || !ddev->saved_skb) {
991 rc = -EIO;
992 goto exit;
993 }
Mark A. Greer485fdc92014-09-23 16:38:07 -0700994
Mark A. Greer49dbb142014-09-23 16:38:12 -0700995 kfree_skb(ddev->saved_skb);
996 ddev->saved_skb = NULL;
997
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -0700998 rc = digital_tg_send_dep_res(ddev, ddev->chaining_skb);
999 if (rc)
1000 goto exit;
Mark A. Greer49dbb142014-09-23 16:38:12 -07001001 } else { /* NACK */
1002 if ((DIGITAL_NFC_DEP_PFB_PNI(pfb + 1) !=
1003 ddev->curr_nfc_dep_pni) ||
1004 !ddev->saved_skb) {
1005 rc = -EIO;
1006 goto exit;
1007 }
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001008
Mark A. Greer49dbb142014-09-23 16:38:12 -07001009 rc = digital_tg_send_saved_skb(ddev);
1010 if (rc) {
1011 kfree_skb(ddev->saved_skb);
1012 goto exit;
1013 }
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001014 }
1015
Mark A. Greer49dbb142014-09-23 16:38:12 -07001016 return;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001017 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
Samuel Ortiz26042532013-09-20 16:56:40 +02001018 pr_err("Received a SUPERVISOR PDU\n");
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001019 rc = -EINVAL;
1020 goto exit;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001021 }
1022
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001023 rc = nfc_tm_data_received(ddev->nfc_dev, resp);
1024
1025exit:
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001026 kfree_skb(ddev->chaining_skb);
1027 ddev->chaining_skb = NULL;
1028
Mark A. Greer49dbb142014-09-23 16:38:12 -07001029 kfree_skb(ddev->saved_skb);
1030 ddev->saved_skb = NULL;
1031
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001032 if (rc)
1033 kfree_skb(resp);
1034}
1035
1036int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
1037{
1038 struct digital_dep_req_res *dep_res;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001039 struct sk_buff *chaining_skb, *tmp_skb;
1040 int rc;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001041
1042 skb_push(skb, sizeof(struct digital_dep_req_res));
Mark A. Greerb08147c2014-09-23 16:38:08 -07001043
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001044 dep_res = (struct digital_dep_req_res *)skb->data;
1045
1046 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1047 dep_res->cmd = DIGITAL_CMD_DEP_RES;
1048 dep_res->pfb = ddev->curr_nfc_dep_pni;
1049
Mark A. Greer05afedc2014-09-23 16:38:05 -07001050 if (ddev->did) {
1051 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
1052
1053 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
1054 sizeof(ddev->did));
1055 }
1056
Mark A. Greer485fdc92014-09-23 16:38:07 -07001057 ddev->curr_nfc_dep_pni =
1058 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
1059
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001060 chaining_skb = ddev->chaining_skb;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001061
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001062 tmp_skb = digital_send_dep_data_prep(ddev, skb, dep_res, NULL);
1063 if (IS_ERR(tmp_skb))
1064 return PTR_ERR(tmp_skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001065
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001066 digital_skb_push_dep_sod(ddev, tmp_skb);
1067
1068 ddev->skb_add_crc(tmp_skb);
1069
Mark A. Greer49dbb142014-09-23 16:38:12 -07001070 ddev->saved_skb = skb_get(tmp_skb);
1071 ddev->saved_skb_len = tmp_skb->len;
1072
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001073 rc = digital_tg_send_cmd(ddev, tmp_skb, 1500, digital_tg_recv_dep_req,
1074 NULL);
1075 if (rc) {
1076 if (tmp_skb != skb)
1077 kfree_skb(tmp_skb);
1078
1079 kfree_skb(chaining_skb);
1080 ddev->chaining_skb = NULL;
Mark A. Greer49dbb142014-09-23 16:38:12 -07001081
1082 kfree_skb(ddev->saved_skb);
1083 ddev->saved_skb = NULL;
Mark A. Greer3bd2a5b2014-09-23 16:38:09 -07001084 }
1085
1086 return rc;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001087}
1088
1089static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
1090 void *arg, struct sk_buff *resp)
1091{
Thierry Escande67af1d72014-01-02 11:58:13 +01001092 u8 rf_tech = (unsigned long)arg;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001093
1094 if (IS_ERR(resp))
1095 return;
1096
Thierry Escandeb711ad52014-01-06 23:34:48 +01001097 digital_tg_set_rf_tech(ddev, rf_tech);
1098
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001099 digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
1100
1101 digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
1102
1103 dev_kfree_skb(resp);
1104}
1105
1106static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
1107 u8 rf_tech)
1108{
1109 struct digital_psl_res *psl_res;
1110 struct sk_buff *skb;
1111 int rc;
1112
1113 skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
1114 if (!skb)
1115 return -ENOMEM;
1116
1117 skb_put(skb, sizeof(struct digital_psl_res));
1118
1119 psl_res = (struct digital_psl_res *)skb->data;
1120
1121 psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1122 psl_res->cmd = DIGITAL_CMD_PSL_RES;
1123 psl_res->did = did;
1124
1125 digital_skb_push_dep_sod(ddev, skb);
1126
1127 ddev->skb_add_crc(skb);
1128
Mark A. Greer485fdc92014-09-23 16:38:07 -07001129 ddev->curr_nfc_dep_pni = 0;
1130
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001131 rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
Thierry Escande67af1d72014-01-02 11:58:13 +01001132 (void *)(unsigned long)rf_tech);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001133 if (rc)
1134 kfree_skb(skb);
1135
1136 return rc;
1137}
1138
1139static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
1140 struct sk_buff *resp)
1141{
1142 int rc;
1143 struct digital_psl_req *psl_req;
1144 u8 rf_tech;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001145 u8 dsi, payload_size, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001146
1147 if (IS_ERR(resp)) {
1148 rc = PTR_ERR(resp);
1149 resp = NULL;
1150 goto exit;
1151 }
1152
1153 rc = ddev->skb_check_crc(resp);
1154 if (rc) {
1155 PROTOCOL_ERR("14.4.1.6");
1156 goto exit;
1157 }
1158
1159 rc = digital_skb_pull_dep_sod(ddev, resp);
1160 if (rc) {
1161 PROTOCOL_ERR("14.4.1.2");
1162 goto exit;
1163 }
1164
1165 psl_req = (struct digital_psl_req *)resp->data;
1166
1167 if (resp->len != sizeof(struct digital_psl_req) ||
1168 psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
1169 psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
1170 rc = -EIO;
1171 goto exit;
1172 }
1173
1174 dsi = (psl_req->brs >> 3) & 0x07;
1175 switch (dsi) {
1176 case 0:
1177 rf_tech = NFC_DIGITAL_RF_TECH_106A;
1178 break;
1179 case 1:
1180 rf_tech = NFC_DIGITAL_RF_TECH_212F;
1181 break;
1182 case 2:
1183 rf_tech = NFC_DIGITAL_RF_TECH_424F;
1184 break;
1185 default:
Masanari Iida77d84ff2013-12-09 00:22:53 +09001186 pr_err("Unsupported dsi value %d\n", dsi);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001187 goto exit;
1188 }
1189
Mark A. Greerb08147c2014-09-23 16:38:08 -07001190 payload_bits = DIGITAL_PAYLOAD_FSL_TO_BITS(psl_req->fsl);
1191 payload_size = digital_payload_bits_to_size(payload_bits);
1192
1193 if (!payload_size || (payload_size > min(ddev->local_payload_max,
1194 ddev->remote_payload_max))) {
1195 rc = -EINVAL;
1196 goto exit;
1197 }
1198
1199 ddev->local_payload_max = payload_size;
1200 ddev->remote_payload_max = payload_size;
1201
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001202 rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
1203
1204exit:
1205 kfree_skb(resp);
1206}
1207
1208static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
1209 void *arg, struct sk_buff *resp)
1210{
1211 int offset;
1212
1213 if (IS_ERR(resp)) {
1214 digital_poll_next_tech(ddev);
1215 return;
1216 }
1217
1218 offset = 2;
1219 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
1220 offset++;
1221
1222 if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
1223 digital_tg_recv_psl_req(ddev, arg, resp);
1224 else
1225 digital_tg_recv_dep_req(ddev, arg, resp);
1226}
1227
1228static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
1229 struct digital_atr_req *atr_req)
1230{
1231 struct digital_atr_res *atr_res;
1232 struct sk_buff *skb;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001233 u8 *gb, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001234 size_t gb_len;
1235 int rc;
1236
1237 gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
1238 if (!gb)
1239 gb_len = 0;
1240
1241 skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
1242 if (!skb)
1243 return -ENOMEM;
1244
1245 skb_put(skb, sizeof(struct digital_atr_res));
1246 atr_res = (struct digital_atr_res *)skb->data;
1247
1248 memset(atr_res, 0, sizeof(struct digital_atr_res));
1249
1250 atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
1251 atr_res->cmd = DIGITAL_CMD_ATR_RES;
1252 memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
1253 atr_res->to = 8;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001254
1255 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX;
1256 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);
1257 atr_res->pp = DIGITAL_PAYLOAD_BITS_TO_PP(payload_bits);
1258
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001259 if (gb_len) {
1260 skb_put(skb, gb_len);
1261
1262 atr_res->pp |= DIGITAL_GB_BIT;
1263 memcpy(atr_res->gb, gb, gb_len);
1264 }
1265
1266 digital_skb_push_dep_sod(ddev, skb);
1267
1268 ddev->skb_add_crc(skb);
1269
Mark A. Greer485fdc92014-09-23 16:38:07 -07001270 ddev->curr_nfc_dep_pni = 0;
1271
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001272 rc = digital_tg_send_cmd(ddev, skb, 999,
1273 digital_tg_send_atr_res_complete, NULL);
Mark A. Greerb15829b2014-09-23 16:38:02 -07001274 if (rc)
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001275 kfree_skb(skb);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001276
1277 return rc;
1278}
1279
1280void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
1281 struct sk_buff *resp)
1282{
1283 int rc;
1284 struct digital_atr_req *atr_req;
1285 size_t gb_len, min_size;
Mark A. Greerb08147c2014-09-23 16:38:08 -07001286 u8 poll_tech_count, payload_bits;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001287
1288 if (IS_ERR(resp)) {
1289 rc = PTR_ERR(resp);
1290 resp = NULL;
1291 goto exit;
1292 }
1293
1294 if (!resp->len) {
1295 rc = -EIO;
1296 goto exit;
1297 }
1298
1299 if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
1300 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
Thierry Escandeb711ad52014-01-06 23:34:48 +01001301 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_106A);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001302 } else {
1303 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
Thierry Escandeb711ad52014-01-06 23:34:48 +01001304 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_212F);
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001305 }
1306
1307 if (resp->len < min_size) {
1308 rc = -EIO;
1309 goto exit;
1310 }
1311
Thierry Escande48e10442014-01-06 23:34:37 +01001312 ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001313
1314 rc = ddev->skb_check_crc(resp);
1315 if (rc) {
1316 PROTOCOL_ERR("14.4.1.6");
1317 goto exit;
1318 }
1319
1320 rc = digital_skb_pull_dep_sod(ddev, resp);
1321 if (rc) {
1322 PROTOCOL_ERR("14.4.1.2");
1323 goto exit;
1324 }
1325
1326 atr_req = (struct digital_atr_req *)resp->data;
1327
1328 if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
Mark A. Greer05afedc2014-09-23 16:38:05 -07001329 atr_req->cmd != DIGITAL_CMD_ATR_REQ ||
1330 atr_req->did > DIGITAL_DID_MAX) {
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001331 rc = -EINVAL;
1332 goto exit;
1333 }
1334
Mark A. Greerb08147c2014-09-23 16:38:08 -07001335 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_req->pp);
1336 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits);
1337
1338 if (!ddev->remote_payload_max) {
1339 rc = -EINVAL;
1340 goto exit;
1341 }
1342
Mark A. Greer05afedc2014-09-23 16:38:05 -07001343 ddev->did = atr_req->did;
1344
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001345 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
1346 NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
1347 if (rc)
1348 goto exit;
1349
1350 rc = digital_tg_send_atr_res(ddev, atr_req);
1351 if (rc)
1352 goto exit;
1353
1354 gb_len = resp->len - sizeof(struct digital_atr_req);
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001355
1356 poll_tech_count = ddev->poll_tech_count;
1357 ddev->poll_tech_count = 0;
1358
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001359 rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
1360 NFC_COMM_PASSIVE, atr_req->gb, gb_len);
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001361 if (rc) {
1362 ddev->poll_tech_count = poll_tech_count;
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001363 goto exit;
Mark A. Greer0529a7a2014-07-02 09:03:49 -07001364 }
Thierry Escande1c7a4c22013-09-19 17:55:30 +02001365
1366 rc = 0;
1367exit:
1368 if (rc)
1369 digital_poll_next_tech(ddev);
1370
1371 dev_kfree_skb(resp);
1372}