]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/nfc/digital_technology.c
NFC: port100: Fix possible buffer overflow
[mirror_ubuntu-jammy-kernel.git] / net / nfc / digital_technology.c
CommitLineData
59ee2361
TE
1/*
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
c5da0e4a
SO
16#define pr_fmt(fmt) "digital: %s: " fmt, __func__
17
59ee2361
TE
18#include "digital.h"
19
20#define DIGITAL_CMD_SENS_REQ 0x26
21#define DIGITAL_CMD_ALL_REQ 0x52
22#define DIGITAL_CMD_SEL_REQ_CL1 0x93
23#define DIGITAL_CMD_SEL_REQ_CL2 0x95
24#define DIGITAL_CMD_SEL_REQ_CL3 0x97
25
26#define DIGITAL_SDD_REQ_SEL_PAR 0x20
27
28#define DIGITAL_SDD_RES_CT 0x88
29#define DIGITAL_SDD_RES_LEN 5
30
2c66daec
TE
31#define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04))
32#define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60))
7d0911c0 33#define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40)
2c66daec 34
13292c9a 35#define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x0C00) == 0x0C00)
2c66daec 36#define DIGITAL_SENS_RES_IS_VALID(sens_res) \
13292c9a
TE
37 ((!((sens_res) & 0x001F) && (((sens_res) & 0x0C00) == 0x0C00)) || \
38 (((sens_res) & 0x001F) && ((sens_res) & 0x0C00) != 0x0C00))
2c66daec
TE
39
40#define DIGITAL_MIFARE_READ_RES_LEN 16
41#define DIGITAL_MIFARE_ACK_RES 0x0A
42
8c0695e4
TE
43#define DIGITAL_CMD_SENSF_REQ 0x00
44#define DIGITAL_CMD_SENSF_RES 0x01
45
46#define DIGITAL_SENSF_RES_MIN_LENGTH 17
47#define DIGITAL_SENSF_RES_RD_AP_B1 0x00
48#define DIGITAL_SENSF_RES_RD_AP_B2 0x8F
49
50#define DIGITAL_SENSF_REQ_RC_NONE 0
51#define DIGITAL_SENSF_REQ_RC_SC 1
52#define DIGITAL_SENSF_REQ_RC_AP 2
53
a381d482
MG
54#define DIGITAL_CMD_ISO15693_INVENTORY_REQ 0x01
55
56#define DIGITAL_ISO15693_REQ_FLAG_DATA_RATE BIT(1)
57#define DIGITAL_ISO15693_REQ_FLAG_INVENTORY BIT(2)
58#define DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS BIT(5)
59#define DIGITAL_ISO15693_RES_FLAG_ERROR BIT(0)
60#define DIGITAL_ISO15693_RES_IS_VALID(flags) \
61 (!((flags) & DIGITAL_ISO15693_RES_FLAG_ERROR))
62
2c66daec
TE
63struct digital_sdd_res {
64 u8 nfcid1[4];
65 u8 bcc;
66} __packed;
67
68struct digital_sel_req {
69 u8 sel_cmd;
70 u8 b2;
71 u8 nfcid1[4];
72 u8 bcc;
73} __packed;
74
8c0695e4
TE
75struct digital_sensf_req {
76 u8 cmd;
77 u8 sc1;
78 u8 sc2;
79 u8 rc;
80 u8 tsn;
81} __packed;
82
83struct digital_sensf_res {
84 u8 cmd;
85 u8 nfcid2[8];
86 u8 pad0[2];
87 u8 pad1[3];
88 u8 mrti_check;
89 u8 mrti_update;
90 u8 pad2;
91 u8 rd[2];
92} __packed;
93
a381d482
MG
94struct digital_iso15693_inv_req {
95 u8 flags;
96 u8 cmd;
97 u8 mask_len;
98 u64 mask;
99} __packed;
100
101struct digital_iso15693_inv_res {
102 u8 flags;
103 u8 dsfid;
104 u64 uid;
105} __packed;
106
2c66daec
TE
107static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev,
108 struct nfc_target *target);
109
110static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg,
111 struct sk_buff *resp)
112{
113 struct nfc_target *target = arg;
114 int rc;
115 u8 sel_res;
116 u8 nfc_proto;
117
118 if (IS_ERR(resp)) {
119 rc = PTR_ERR(resp);
120 resp = NULL;
121 goto exit;
122 }
123
124 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) {
125 rc = digital_skb_check_crc_a(resp);
126 if (rc) {
127 PROTOCOL_ERR("4.4.1.3");
128 goto exit;
129 }
130 }
131
132 if (!resp->len) {
133 rc = -EIO;
134 goto exit;
135 }
136
137 sel_res = resp->data[0];
138
139 if (!DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res)) {
140 rc = digital_in_send_sdd_req(ddev, target);
141 if (rc)
142 goto exit;
143
144 goto exit_free_skb;
145 }
146
147 if (DIGITAL_SEL_RES_IS_T2T(sel_res)) {
148 nfc_proto = NFC_PROTO_MIFARE;
7d0911c0
TE
149 } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) {
150 nfc_proto = NFC_PROTO_NFC_DEP;
2c66daec
TE
151 } else {
152 rc = -EOPNOTSUPP;
153 goto exit;
154 }
155
156 target->sel_res = sel_res;
157
158 rc = digital_target_found(ddev, target, nfc_proto);
159
160exit:
161 kfree(target);
162
163exit_free_skb:
164 dev_kfree_skb(resp);
165
166 if (rc)
167 digital_poll_next_tech(ddev);
168}
169
170static int digital_in_send_sel_req(struct nfc_digital_dev *ddev,
171 struct nfc_target *target,
172 struct digital_sdd_res *sdd_res)
173{
174 struct sk_buff *skb;
175 struct digital_sel_req *sel_req;
176 u8 sel_cmd;
177 int rc;
178
179 skb = digital_skb_alloc(ddev, sizeof(struct digital_sel_req));
180 if (!skb)
181 return -ENOMEM;
182
183 skb_put(skb, sizeof(struct digital_sel_req));
184 sel_req = (struct digital_sel_req *)skb->data;
185
186 if (target->nfcid1_len <= 4)
187 sel_cmd = DIGITAL_CMD_SEL_REQ_CL1;
188 else if (target->nfcid1_len < 10)
189 sel_cmd = DIGITAL_CMD_SEL_REQ_CL2;
190 else
191 sel_cmd = DIGITAL_CMD_SEL_REQ_CL3;
192
193 sel_req->sel_cmd = sel_cmd;
194 sel_req->b2 = 0x70;
195 memcpy(sel_req->nfcid1, sdd_res->nfcid1, 4);
196 sel_req->bcc = sdd_res->bcc;
197
198 if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) {
199 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
200 NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A);
201 if (rc)
202 goto exit;
203 } else {
204 digital_skb_add_crc_a(skb);
205 }
206
207 rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sel_res,
208 target);
209exit:
210 if (rc)
211 kfree_skb(skb);
212
213 return rc;
214}
215
216static void digital_in_recv_sdd_res(struct nfc_digital_dev *ddev, void *arg,
217 struct sk_buff *resp)
218{
219 struct nfc_target *target = arg;
220 struct digital_sdd_res *sdd_res;
221 int rc;
222 u8 offset, size;
223 u8 i, bcc;
224
225 if (IS_ERR(resp)) {
226 rc = PTR_ERR(resp);
227 resp = NULL;
228 goto exit;
229 }
230
231 if (resp->len < DIGITAL_SDD_RES_LEN) {
232 PROTOCOL_ERR("4.7.2.8");
233 rc = -EINVAL;
234 goto exit;
235 }
236
237 sdd_res = (struct digital_sdd_res *)resp->data;
238
239 for (i = 0, bcc = 0; i < 4; i++)
240 bcc ^= sdd_res->nfcid1[i];
241
242 if (bcc != sdd_res->bcc) {
243 PROTOCOL_ERR("4.7.2.6");
244 rc = -EINVAL;
245 goto exit;
246 }
247
248 if (sdd_res->nfcid1[0] == DIGITAL_SDD_RES_CT) {
249 offset = 1;
250 size = 3;
251 } else {
252 offset = 0;
253 size = 4;
254 }
255
256 memcpy(target->nfcid1 + target->nfcid1_len, sdd_res->nfcid1 + offset,
257 size);
258 target->nfcid1_len += size;
259
260 rc = digital_in_send_sel_req(ddev, target, sdd_res);
261
262exit:
263 dev_kfree_skb(resp);
264
265 if (rc) {
266 kfree(target);
267 digital_poll_next_tech(ddev);
268 }
269}
270
271static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev,
272 struct nfc_target *target)
273{
274 int rc;
275 struct sk_buff *skb;
276 u8 sel_cmd;
277
278 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
279 NFC_DIGITAL_FRAMING_NFCA_STANDARD);
280 if (rc)
281 return rc;
282
283 skb = digital_skb_alloc(ddev, 2);
26042530 284 if (!skb)
2c66daec 285 return -ENOMEM;
2c66daec
TE
286
287 if (target->nfcid1_len == 0)
288 sel_cmd = DIGITAL_CMD_SEL_REQ_CL1;
289 else if (target->nfcid1_len == 3)
290 sel_cmd = DIGITAL_CMD_SEL_REQ_CL2;
291 else
292 sel_cmd = DIGITAL_CMD_SEL_REQ_CL3;
293
294 *skb_put(skb, sizeof(u8)) = sel_cmd;
295 *skb_put(skb, sizeof(u8)) = DIGITAL_SDD_REQ_SEL_PAR;
296
297 return digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res,
298 target);
299}
300
59ee2361
TE
301static void digital_in_recv_sens_res(struct nfc_digital_dev *ddev, void *arg,
302 struct sk_buff *resp)
303{
2c66daec 304 struct nfc_target *target = NULL;
2c66daec
TE
305 int rc;
306
307 if (IS_ERR(resp)) {
308 rc = PTR_ERR(resp);
309 resp = NULL;
310 goto exit;
311 }
312
313 if (resp->len < sizeof(u16)) {
314 rc = -EIO;
315 goto exit;
316 }
317
318 target = kzalloc(sizeof(struct nfc_target), GFP_KERNEL);
319 if (!target) {
320 rc = -ENOMEM;
321 goto exit;
322 }
323
13292c9a 324 target->sens_res = __le16_to_cpu(*(__le16 *)resp->data);
59ee2361 325
13292c9a 326 if (!DIGITAL_SENS_RES_IS_VALID(target->sens_res)) {
2c66daec
TE
327 PROTOCOL_ERR("4.6.3.3");
328 rc = -EINVAL;
329 goto exit;
330 }
331
13292c9a 332 if (DIGITAL_SENS_RES_IS_T1T(target->sens_res))
2c66daec
TE
333 rc = digital_target_found(ddev, target, NFC_PROTO_JEWEL);
334 else
335 rc = digital_in_send_sdd_req(ddev, target);
336
337exit:
338 dev_kfree_skb(resp);
339
340 if (rc) {
341 kfree(target);
342 digital_poll_next_tech(ddev);
343 }
59ee2361
TE
344}
345
346int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech)
347{
348 struct sk_buff *skb;
349 int rc;
350
351 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
352 NFC_DIGITAL_RF_TECH_106A);
353 if (rc)
354 return rc;
355
356 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
357 NFC_DIGITAL_FRAMING_NFCA_SHORT);
358 if (rc)
359 return rc;
360
361 skb = digital_skb_alloc(ddev, 1);
362 if (!skb)
363 return -ENOMEM;
364
365 *skb_put(skb, sizeof(u8)) = DIGITAL_CMD_SENS_REQ;
366
367 rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sens_res, NULL);
368 if (rc)
369 kfree_skb(skb);
370
371 return rc;
372}
2c66daec
TE
373
374int digital_in_recv_mifare_res(struct sk_buff *resp)
375{
376 /* Successful READ command response is 16 data bytes + 2 CRC bytes long.
377 * Since the driver can't differentiate a ACK/NACK response from a valid
378 * READ response, the CRC calculation must be handled at digital level
379 * even if the driver supports it for this technology.
380 */
381 if (resp->len == DIGITAL_MIFARE_READ_RES_LEN + DIGITAL_CRC_LEN) {
382 if (digital_skb_check_crc_a(resp)) {
383 PROTOCOL_ERR("9.4.1.2");
384 return -EIO;
385 }
386
387 return 0;
388 }
389
390 /* ACK response (i.e. successful WRITE). */
391 if (resp->len == 1 && resp->data[0] == DIGITAL_MIFARE_ACK_RES) {
392 resp->data[0] = 0;
393 return 0;
394 }
395
396 /* NACK and any other responses are treated as error. */
397 return -EIO;
398}
8c0695e4
TE
399
400static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg,
401 struct sk_buff *resp)
402{
403 int rc;
7d0911c0 404 u8 proto;
8c0695e4
TE
405 struct nfc_target target;
406 struct digital_sensf_res *sensf_res;
407
408 if (IS_ERR(resp)) {
409 rc = PTR_ERR(resp);
410 resp = NULL;
411 goto exit;
412 }
413
414 if (resp->len < DIGITAL_SENSF_RES_MIN_LENGTH) {
415 rc = -EIO;
416 goto exit;
417 }
418
419 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) {
420 rc = digital_skb_check_crc_f(resp);
421 if (rc) {
422 PROTOCOL_ERR("6.4.1.8");
423 goto exit;
424 }
425 }
426
427 skb_pull(resp, 1);
428
429 memset(&target, 0, sizeof(struct nfc_target));
430
431 sensf_res = (struct digital_sensf_res *)resp->data;
432
433 memcpy(target.sensf_res, sensf_res, resp->len);
434 target.sensf_res_len = resp->len;
435
436 memcpy(target.nfcid2, sensf_res->nfcid2, NFC_NFCID2_MAXSIZE);
437 target.nfcid2_len = NFC_NFCID2_MAXSIZE;
438
7d0911c0
TE
439 if (target.nfcid2[0] == DIGITAL_SENSF_NFCID2_NFC_DEP_B1 &&
440 target.nfcid2[1] == DIGITAL_SENSF_NFCID2_NFC_DEP_B2)
441 proto = NFC_PROTO_NFC_DEP;
442 else
443 proto = NFC_PROTO_FELICA;
444
445 rc = digital_target_found(ddev, &target, proto);
8c0695e4
TE
446
447exit:
448 dev_kfree_skb(resp);
449
450 if (rc)
451 digital_poll_next_tech(ddev);
452}
453
454int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech)
455{
456 struct digital_sensf_req *sensf_req;
457 struct sk_buff *skb;
458 int rc;
459 u8 size;
460
461 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
462 if (rc)
463 return rc;
464
465 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
466 NFC_DIGITAL_FRAMING_NFCF);
467 if (rc)
468 return rc;
469
470 size = sizeof(struct digital_sensf_req);
471
472 skb = digital_skb_alloc(ddev, size);
473 if (!skb)
474 return -ENOMEM;
475
476 skb_put(skb, size);
477
478 sensf_req = (struct digital_sensf_req *)skb->data;
479 sensf_req->cmd = DIGITAL_CMD_SENSF_REQ;
480 sensf_req->sc1 = 0xFF;
481 sensf_req->sc2 = 0xFF;
482 sensf_req->rc = 0;
483 sensf_req->tsn = 0;
484
485 *skb_push(skb, 1) = size + 1;
486
487 if (!DIGITAL_DRV_CAPS_IN_CRC(ddev))
488 digital_skb_add_crc_f(skb);
489
490 rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sensf_res,
491 NULL);
492 if (rc)
493 kfree_skb(skb);
494
495 return rc;
496}
1c7a4c24 497
a381d482
MG
498static void digital_in_recv_iso15693_inv_res(struct nfc_digital_dev *ddev,
499 void *arg, struct sk_buff *resp)
500{
501 struct digital_iso15693_inv_res *res;
502 struct nfc_target *target = NULL;
503 int rc;
504
505 if (IS_ERR(resp)) {
506 rc = PTR_ERR(resp);
507 resp = NULL;
508 goto out_free_skb;
509 }
510
511 if (resp->len != sizeof(*res)) {
512 rc = -EIO;
513 goto out_free_skb;
514 }
515
516 res = (struct digital_iso15693_inv_res *)resp->data;
517
518 if (!DIGITAL_ISO15693_RES_IS_VALID(res->flags)) {
519 PROTOCOL_ERR("ISO15693 - 10.3.1");
520 rc = -EINVAL;
521 goto out_free_skb;
522 }
523
524 target = kzalloc(sizeof(*target), GFP_KERNEL);
525 if (!target) {
526 rc = -ENOMEM;
527 goto out_free_skb;
528 }
529
530 target->is_iso15693 = 1;
531 target->iso15693_dsfid = res->dsfid;
532 memcpy(target->iso15693_uid, &res->uid, sizeof(target->iso15693_uid));
533
534 rc = digital_target_found(ddev, target, NFC_PROTO_ISO15693);
535
536 kfree(target);
537
538out_free_skb:
539 dev_kfree_skb(resp);
540
541 if (rc)
542 digital_poll_next_tech(ddev);
543}
544
545int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech)
546{
547 struct digital_iso15693_inv_req *req;
548 struct sk_buff *skb;
549 int rc;
550
551 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
552 NFC_DIGITAL_RF_TECH_ISO15693);
553 if (rc)
554 return rc;
555
556 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
557 NFC_DIGITAL_FRAMING_ISO15693_INVENTORY);
558 if (rc)
559 return rc;
560
561 skb = digital_skb_alloc(ddev, sizeof(*req));
562 if (!skb)
563 return -ENOMEM;
564
565 skb_put(skb, sizeof(*req) - sizeof(req->mask)); /* No mask */
566 req = (struct digital_iso15693_inv_req *)skb->data;
567
568 /* Single sub-carrier, high data rate, no AFI, single slot
569 * Inventory command
570 */
571 req->flags = DIGITAL_ISO15693_REQ_FLAG_DATA_RATE |
572 DIGITAL_ISO15693_REQ_FLAG_INVENTORY |
573 DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS;
574 req->cmd = DIGITAL_CMD_ISO15693_INVENTORY_REQ;
575 req->mask_len = 0;
576
577 rc = digital_in_send_cmd(ddev, skb, 30,
578 digital_in_recv_iso15693_inv_res, NULL);
579 if (rc)
580 kfree_skb(skb);
581
582 return rc;
583}
584
1c7a4c24
TE
585static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev)
586{
587 struct sk_buff *skb;
588 int rc;
589
590 skb = digital_skb_alloc(ddev, 1);
591 if (!skb)
592 return -ENOMEM;
593
594 *skb_put(skb, 1) = DIGITAL_SEL_RES_NFC_DEP;
595
596 if (!DIGITAL_DRV_CAPS_TG_CRC(ddev))
597 digital_skb_add_crc_a(skb);
598
599 rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_atr_req,
600 NULL);
601 if (rc)
602 kfree_skb(skb);
603
604 return rc;
605}
606
607static void digital_tg_recv_sel_req(struct nfc_digital_dev *ddev, void *arg,
608 struct sk_buff *resp)
609{
610 int rc;
611
612 if (IS_ERR(resp)) {
613 rc = PTR_ERR(resp);
614 resp = NULL;
615 goto exit;
616 }
617
618 if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) {
619 rc = digital_skb_check_crc_a(resp);
620 if (rc) {
621 PROTOCOL_ERR("4.4.1.3");
622 goto exit;
623 }
624 }
625
626 /* Silently ignore SEL_REQ content and send a SEL_RES for NFC-DEP */
627
628 rc = digital_tg_send_sel_res(ddev);
629
630exit:
631 if (rc)
632 digital_poll_next_tech(ddev);
633
634 dev_kfree_skb(resp);
635}
636
637static int digital_tg_send_sdd_res(struct nfc_digital_dev *ddev)
638{
639 struct sk_buff *skb;
640 struct digital_sdd_res *sdd_res;
641 int rc, i;
642
643 skb = digital_skb_alloc(ddev, sizeof(struct digital_sdd_res));
644 if (!skb)
645 return -ENOMEM;
646
647 skb_put(skb, sizeof(struct digital_sdd_res));
648 sdd_res = (struct digital_sdd_res *)skb->data;
649
650 sdd_res->nfcid1[0] = 0x08;
651 get_random_bytes(sdd_res->nfcid1 + 1, 3);
652
653 sdd_res->bcc = 0;
654 for (i = 0; i < 4; i++)
655 sdd_res->bcc ^= sdd_res->nfcid1[i];
656
657 rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_sel_req,
658 NULL);
659 if (rc)
660 kfree_skb(skb);
661
662 return rc;
663}
664
665static void digital_tg_recv_sdd_req(struct nfc_digital_dev *ddev, void *arg,
666 struct sk_buff *resp)
667{
668 u8 *sdd_req;
669 int rc;
670
671 if (IS_ERR(resp)) {
672 rc = PTR_ERR(resp);
673 resp = NULL;
674 goto exit;
675 }
676
677 sdd_req = resp->data;
678
679 if (resp->len < 2 || sdd_req[0] != DIGITAL_CMD_SEL_REQ_CL1 ||
680 sdd_req[1] != DIGITAL_SDD_REQ_SEL_PAR) {
681 rc = -EINVAL;
682 goto exit;
683 }
684
685 rc = digital_tg_send_sdd_res(ddev);
686
687exit:
688 if (rc)
689 digital_poll_next_tech(ddev);
690
691 dev_kfree_skb(resp);
692}
693
694static int digital_tg_send_sens_res(struct nfc_digital_dev *ddev)
695{
696 struct sk_buff *skb;
697 u8 *sens_res;
698 int rc;
699
700 skb = digital_skb_alloc(ddev, 2);
701 if (!skb)
702 return -ENOMEM;
703
704 sens_res = skb_put(skb, 2);
705
706 sens_res[0] = (DIGITAL_SENS_RES_NFC_DEP >> 8) & 0xFF;
707 sens_res[1] = DIGITAL_SENS_RES_NFC_DEP & 0xFF;
708
709 rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_sdd_req,
710 NULL);
711 if (rc)
712 kfree_skb(skb);
713
714 return rc;
715}
716
717void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg,
718 struct sk_buff *resp)
719{
720 u8 sens_req;
721 int rc;
722
723 if (IS_ERR(resp)) {
724 rc = PTR_ERR(resp);
725 resp = NULL;
726 goto exit;
727 }
728
729 sens_req = resp->data[0];
730
731 if (!resp->len || (sens_req != DIGITAL_CMD_SENS_REQ &&
732 sens_req != DIGITAL_CMD_ALL_REQ)) {
733 rc = -EINVAL;
734 goto exit;
735 }
736
737 rc = digital_tg_send_sens_res(ddev);
738
739exit:
740 if (rc)
741 digital_poll_next_tech(ddev);
742
743 dev_kfree_skb(resp);
744}
745
180106bd 746static int digital_tg_send_sensf_res(struct nfc_digital_dev *ddev,
1c7a4c24
TE
747 struct digital_sensf_req *sensf_req)
748{
749 struct sk_buff *skb;
750 u8 size;
751 int rc;
752 struct digital_sensf_res *sensf_res;
753
754 size = sizeof(struct digital_sensf_res);
755
756 if (sensf_req->rc != DIGITAL_SENSF_REQ_RC_NONE)
757 size -= sizeof(sensf_res->rd);
758
759 skb = digital_skb_alloc(ddev, size);
760 if (!skb)
761 return -ENOMEM;
762
763 skb_put(skb, size);
764
765 sensf_res = (struct digital_sensf_res *)skb->data;
766
767 memset(sensf_res, 0, size);
768
769 sensf_res->cmd = DIGITAL_CMD_SENSF_RES;
770 sensf_res->nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1;
771 sensf_res->nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2;
772 get_random_bytes(&sensf_res->nfcid2[2], 6);
773
774 switch (sensf_req->rc) {
775 case DIGITAL_SENSF_REQ_RC_SC:
776 sensf_res->rd[0] = sensf_req->sc1;
777 sensf_res->rd[1] = sensf_req->sc2;
778 break;
779 case DIGITAL_SENSF_REQ_RC_AP:
780 sensf_res->rd[0] = DIGITAL_SENSF_RES_RD_AP_B1;
781 sensf_res->rd[1] = DIGITAL_SENSF_RES_RD_AP_B2;
782 break;
783 }
784
785 *skb_push(skb, sizeof(u8)) = size + 1;
786
787 if (!DIGITAL_DRV_CAPS_TG_CRC(ddev))
788 digital_skb_add_crc_f(skb);
789
790 rc = digital_tg_send_cmd(ddev, skb, 300,
791 digital_tg_recv_atr_req, NULL);
792 if (rc)
793 kfree_skb(skb);
794
795 return rc;
796}
797
798void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg,
799 struct sk_buff *resp)
800{
801 struct digital_sensf_req *sensf_req;
802 int rc;
803
804 if (IS_ERR(resp)) {
805 rc = PTR_ERR(resp);
806 resp = NULL;
807 goto exit;
808 }
809
810 if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) {
811 rc = digital_skb_check_crc_f(resp);
812 if (rc) {
813 PROTOCOL_ERR("6.4.1.8");
814 goto exit;
815 }
816 }
817
818 if (resp->len != sizeof(struct digital_sensf_req) + 1) {
819 rc = -EINVAL;
820 goto exit;
821 }
822
823 skb_pull(resp, 1);
824 sensf_req = (struct digital_sensf_req *)resp->data;
825
826 if (sensf_req->cmd != DIGITAL_CMD_SENSF_REQ) {
827 rc = -EINVAL;
828 goto exit;
829 }
830
831 rc = digital_tg_send_sensf_res(ddev, sensf_req);
832
833exit:
834 if (rc)
835 digital_poll_next_tech(ddev);
836
837 dev_kfree_skb(resp);
838}
839
840int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech)
841{
842 int rc;
843
844 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
845 if (rc)
846 return rc;
847
848 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
849 NFC_DIGITAL_FRAMING_NFCA_NFC_DEP);
850 if (rc)
851 return rc;
852
853 return digital_tg_listen(ddev, 300, digital_tg_recv_sens_req, NULL);
854}
855
856int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech)
857{
858 int rc;
859 u8 *nfcid2;
860
861 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
862 if (rc)
863 return rc;
864
865 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
866 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
867 if (rc)
868 return rc;
869
870 nfcid2 = kzalloc(NFC_NFCID2_MAXSIZE, GFP_KERNEL);
871 if (!nfcid2)
872 return -ENOMEM;
873
874 nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1;
875 nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2;
876 get_random_bytes(nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2);
877
878 return digital_tg_listen(ddev, 300, digital_tg_recv_sensf_req, nfcid2);
879}