diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-03-17 13:16:50 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-03-17 13:16:50 -0400 |
commit | 20d83f2464c0d1e27b24d654aa5495dcc44759c0 (patch) | |
tree | a6c36d9e48920f6d81b7dac9ad6b1f99dfdaf592 /net/nfc | |
parent | 5f667642f4b290b04d88d5ca926fba81fed6180d (diff) | |
parent | 29e27dd86b5c4f8e6feb62d7b6a8491539ff1ef1 (diff) |
Merge tag 'nfc-next-3.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next
Samuel Ortiz <sameo@linux.intel.com> says:
"NFC: 3.15: First pull request
This is the NFC pull request for 3.15. With this one we have:
- Support for ISO 15693 a.k.a. NFC vicinity a.k.a. Type 5 tags. ISO
15693 are long range (1 - 2 meters) vicinity tags/cards. The kernel
now supports those through the NFC netlink and digital APIs.
- Support for TI's trf7970a chipset. This chipset relies on the NFC
digital layer and the driver currently supports type 2, 4A and 5 tags.
- Support for NXP's pn544 secure firmare download. The pn544 C3 chipsets
relies on a different firmware download protocal than the C2 one. We
now support both and use the right one depending on the version we
detect at runtime.
- Support for 4A tags from the NFC digital layer.
- A bunch of cleanups and minor fixes from Axel Lin and Thierry Escande."
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/core.c | 10 | ||||
-rw-r--r-- | net/nfc/digital.h | 6 | ||||
-rw-r--r-- | net/nfc/digital_core.c | 67 | ||||
-rw-r--r-- | net/nfc/digital_technology.c | 247 | ||||
-rw-r--r-- | net/nfc/hci/llc.c | 4 | ||||
-rw-r--r-- | net/nfc/llcp_core.c | 16 | ||||
-rw-r--r-- | net/nfc/nci/core.c | 3 | ||||
-rw-r--r-- | net/nfc/nci/spi.c | 3 | ||||
-rw-r--r-- | net/nfc/netlink.c | 8 |
9 files changed, 331 insertions, 33 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c index ca1e65f4b133..819b87702b70 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -280,9 +280,6 @@ static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx) | |||
280 | { | 280 | { |
281 | int i; | 281 | int i; |
282 | 282 | ||
283 | if (dev->n_targets == 0) | ||
284 | return NULL; | ||
285 | |||
286 | for (i = 0; i < dev->n_targets; i++) { | 283 | for (i = 0; i < dev->n_targets; i++) { |
287 | if (dev->targets[i].idx == target_idx) | 284 | if (dev->targets[i].idx == target_idx) |
288 | return &dev->targets[i]; | 285 | return &dev->targets[i]; |
@@ -546,9 +543,9 @@ error: | |||
546 | 543 | ||
547 | struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx) | 544 | struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx) |
548 | { | 545 | { |
549 | struct nfc_se *se, *n; | 546 | struct nfc_se *se; |
550 | 547 | ||
551 | list_for_each_entry_safe(se, n, &dev->secure_elements, list) | 548 | list_for_each_entry(se, &dev->secure_elements, list) |
552 | if (se->idx == se_idx) | 549 | if (se->idx == se_idx) |
553 | return se; | 550 | return se; |
554 | 551 | ||
@@ -655,9 +652,6 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) | |||
655 | { | 652 | { |
656 | pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); | 653 | pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); |
657 | 654 | ||
658 | if (gb_len > NFC_MAX_GT_LEN) | ||
659 | return -EINVAL; | ||
660 | |||
661 | return nfc_llcp_set_remote_gb(dev, gb, gb_len); | 655 | return nfc_llcp_set_remote_gb(dev, gb, gb_len); |
662 | } | 656 | } |
663 | EXPORT_SYMBOL(nfc_set_remote_general_bytes); | 657 | EXPORT_SYMBOL(nfc_set_remote_general_bytes); |
diff --git a/net/nfc/digital.h b/net/nfc/digital.h index 08b29b55ea63..3759add68b1b 100644 --- a/net/nfc/digital.h +++ b/net/nfc/digital.h | |||
@@ -72,6 +72,12 @@ void digital_poll_next_tech(struct nfc_digital_dev *ddev); | |||
72 | 72 | ||
73 | int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech); | 73 | int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech); |
74 | int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech); | 74 | int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech); |
75 | int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech); | ||
76 | |||
77 | int digital_in_iso_dep_pull_sod(struct nfc_digital_dev *ddev, | ||
78 | struct sk_buff *skb); | ||
79 | int digital_in_iso_dep_push_sod(struct nfc_digital_dev *ddev, | ||
80 | struct sk_buff *skb); | ||
75 | 81 | ||
76 | int digital_target_found(struct nfc_digital_dev *ddev, | 82 | int digital_target_found(struct nfc_digital_dev *ddev, |
77 | struct nfc_target *target, u8 protocol); | 83 | struct nfc_target *target, u8 protocol); |
diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c index c129d1571ca6..e01e15dbf1ab 100644 --- a/net/nfc/digital_core.c +++ b/net/nfc/digital_core.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #define DIGITAL_PROTO_NFCF_RF_TECH \ | 25 | #define DIGITAL_PROTO_NFCF_RF_TECH \ |
26 | (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) | 26 | (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) |
27 | 27 | ||
28 | #define DIGITAL_PROTO_ISO15693_RF_TECH NFC_PROTO_ISO15693_MASK | ||
29 | |||
28 | struct digital_cmd { | 30 | struct digital_cmd { |
29 | struct list_head queue; | 31 | struct list_head queue; |
30 | 32 | ||
@@ -331,6 +333,18 @@ int digital_target_found(struct nfc_digital_dev *ddev, | |||
331 | } | 333 | } |
332 | break; | 334 | break; |
333 | 335 | ||
336 | case NFC_PROTO_ISO15693: | ||
337 | framing = NFC_DIGITAL_FRAMING_ISO15693_T5T; | ||
338 | check_crc = digital_skb_check_crc_b; | ||
339 | add_crc = digital_skb_add_crc_b; | ||
340 | break; | ||
341 | |||
342 | case NFC_PROTO_ISO14443: | ||
343 | framing = NFC_DIGITAL_FRAMING_NFCA_T4T; | ||
344 | check_crc = digital_skb_check_crc_a; | ||
345 | add_crc = digital_skb_add_crc_a; | ||
346 | break; | ||
347 | |||
334 | default: | 348 | default: |
335 | pr_err("Invalid protocol %d\n", protocol); | 349 | pr_err("Invalid protocol %d\n", protocol); |
336 | return -EINVAL; | 350 | return -EINVAL; |
@@ -461,7 +475,7 @@ static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols, | |||
461 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, | 475 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, |
462 | digital_in_send_sens_req); | 476 | digital_in_send_sens_req); |
463 | 477 | ||
464 | if (im_protocols & DIGITAL_PROTO_NFCF_RF_TECH) { | 478 | if (matching_im_protocols & DIGITAL_PROTO_NFCF_RF_TECH) { |
465 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, | 479 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, |
466 | digital_in_send_sensf_req); | 480 | digital_in_send_sensf_req); |
467 | 481 | ||
@@ -469,7 +483,11 @@ static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols, | |||
469 | digital_in_send_sensf_req); | 483 | digital_in_send_sensf_req); |
470 | } | 484 | } |
471 | 485 | ||
472 | if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { | 486 | if (matching_im_protocols & DIGITAL_PROTO_ISO15693_RF_TECH) |
487 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_ISO15693, | ||
488 | digital_in_send_iso15693_inv_req); | ||
489 | |||
490 | if (matching_tm_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
473 | if (ddev->ops->tg_listen_mdaa) { | 491 | if (ddev->ops->tg_listen_mdaa) { |
474 | digital_add_poll_tech(ddev, 0, | 492 | digital_add_poll_tech(ddev, 0, |
475 | digital_tg_listen_mdaa); | 493 | digital_tg_listen_mdaa); |
@@ -607,20 +625,30 @@ static void digital_in_send_complete(struct nfc_digital_dev *ddev, void *arg, | |||
607 | 625 | ||
608 | if (IS_ERR(resp)) { | 626 | if (IS_ERR(resp)) { |
609 | rc = PTR_ERR(resp); | 627 | rc = PTR_ERR(resp); |
628 | resp = NULL; | ||
610 | goto done; | 629 | goto done; |
611 | } | 630 | } |
612 | 631 | ||
613 | if (ddev->curr_protocol == NFC_PROTO_MIFARE) | 632 | if (ddev->curr_protocol == NFC_PROTO_MIFARE) { |
614 | rc = digital_in_recv_mifare_res(resp); | 633 | rc = digital_in_recv_mifare_res(resp); |
615 | else | 634 | /* crc check is done in digital_in_recv_mifare_res() */ |
616 | rc = ddev->skb_check_crc(resp); | 635 | goto done; |
636 | } | ||
617 | 637 | ||
638 | if (ddev->curr_protocol == NFC_PROTO_ISO14443) { | ||
639 | rc = digital_in_iso_dep_pull_sod(ddev, resp); | ||
640 | if (rc) | ||
641 | goto done; | ||
642 | } | ||
643 | |||
644 | rc = ddev->skb_check_crc(resp); | ||
645 | |||
646 | done: | ||
618 | if (rc) { | 647 | if (rc) { |
619 | kfree_skb(resp); | 648 | kfree_skb(resp); |
620 | resp = NULL; | 649 | resp = NULL; |
621 | } | 650 | } |
622 | 651 | ||
623 | done: | ||
624 | data_exch->cb(data_exch->cb_context, resp, rc); | 652 | data_exch->cb(data_exch->cb_context, resp, rc); |
625 | 653 | ||
626 | kfree(data_exch); | 654 | kfree(data_exch); |
@@ -632,6 +660,7 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
632 | { | 660 | { |
633 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 661 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
634 | struct digital_data_exch *data_exch; | 662 | struct digital_data_exch *data_exch; |
663 | int rc; | ||
635 | 664 | ||
636 | data_exch = kzalloc(sizeof(struct digital_data_exch), GFP_KERNEL); | 665 | data_exch = kzalloc(sizeof(struct digital_data_exch), GFP_KERNEL); |
637 | if (!data_exch) { | 666 | if (!data_exch) { |
@@ -642,13 +671,27 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
642 | data_exch->cb = cb; | 671 | data_exch->cb = cb; |
643 | data_exch->cb_context = cb_context; | 672 | data_exch->cb_context = cb_context; |
644 | 673 | ||
645 | if (ddev->curr_protocol == NFC_PROTO_NFC_DEP) | 674 | if (ddev->curr_protocol == NFC_PROTO_NFC_DEP) { |
646 | return digital_in_send_dep_req(ddev, target, skb, data_exch); | 675 | rc = digital_in_send_dep_req(ddev, target, skb, data_exch); |
676 | goto exit; | ||
677 | } | ||
678 | |||
679 | if (ddev->curr_protocol == NFC_PROTO_ISO14443) { | ||
680 | rc = digital_in_iso_dep_push_sod(ddev, skb); | ||
681 | if (rc) | ||
682 | goto exit; | ||
683 | } | ||
647 | 684 | ||
648 | ddev->skb_add_crc(skb); | 685 | ddev->skb_add_crc(skb); |
649 | 686 | ||
650 | return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete, | 687 | rc = digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete, |
651 | data_exch); | 688 | data_exch); |
689 | |||
690 | exit: | ||
691 | if (rc) | ||
692 | kfree(data_exch); | ||
693 | |||
694 | return rc; | ||
652 | } | 695 | } |
653 | 696 | ||
654 | static struct nfc_ops digital_nfc_ops = { | 697 | static struct nfc_ops digital_nfc_ops = { |
@@ -700,6 +743,10 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, | |||
700 | ddev->protocols |= NFC_PROTO_FELICA_MASK; | 743 | ddev->protocols |= NFC_PROTO_FELICA_MASK; |
701 | if (supported_protocols & NFC_PROTO_NFC_DEP_MASK) | 744 | if (supported_protocols & NFC_PROTO_NFC_DEP_MASK) |
702 | ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; | 745 | ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; |
746 | if (supported_protocols & NFC_PROTO_ISO15693_MASK) | ||
747 | ddev->protocols |= NFC_PROTO_ISO15693_MASK; | ||
748 | if (supported_protocols & NFC_PROTO_ISO14443_MASK) | ||
749 | ddev->protocols |= NFC_PROTO_ISO14443_MASK; | ||
703 | 750 | ||
704 | ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; | 751 | ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; |
705 | ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; | 752 | ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; |
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c index 251c8c753ebe..278c3fed27e0 100644 --- a/net/nfc/digital_technology.c +++ b/net/nfc/digital_technology.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) | 31 | #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) |
32 | #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) | 32 | #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) |
33 | #define DIGITAL_SEL_RES_IS_T4T(sel_res) ((sel_res) & 0x20) | ||
33 | #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) | 34 | #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) |
34 | 35 | ||
35 | #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x0C00) == 0x0C00) | 36 | #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x0C00) == 0x0C00) |
@@ -51,6 +52,34 @@ | |||
51 | #define DIGITAL_SENSF_REQ_RC_SC 1 | 52 | #define DIGITAL_SENSF_REQ_RC_SC 1 |
52 | #define DIGITAL_SENSF_REQ_RC_AP 2 | 53 | #define DIGITAL_SENSF_REQ_RC_AP 2 |
53 | 54 | ||
55 | #define DIGITAL_CMD_ISO15693_INVENTORY_REQ 0x01 | ||
56 | |||
57 | #define DIGITAL_ISO15693_REQ_FLAG_DATA_RATE BIT(1) | ||
58 | #define DIGITAL_ISO15693_REQ_FLAG_INVENTORY BIT(2) | ||
59 | #define DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS BIT(5) | ||
60 | #define DIGITAL_ISO15693_RES_FLAG_ERROR BIT(0) | ||
61 | #define DIGITAL_ISO15693_RES_IS_VALID(flags) \ | ||
62 | (!((flags) & DIGITAL_ISO15693_RES_FLAG_ERROR)) | ||
63 | |||
64 | #define DIGITAL_ISO_DEP_I_PCB 0x02 | ||
65 | #define DIGITAL_ISO_DEP_PNI(pni) ((pni) & 0x01) | ||
66 | |||
67 | #define DIGITAL_ISO_DEP_PCB_TYPE(pcb) ((pcb) & 0xC0) | ||
68 | |||
69 | #define DIGITAL_ISO_DEP_I_BLOCK 0x00 | ||
70 | |||
71 | #define DIGITAL_ISO_DEP_BLOCK_HAS_DID(pcb) ((pcb) & 0x08) | ||
72 | |||
73 | static const u8 digital_ats_fsc[] = { | ||
74 | 16, 24, 32, 40, 48, 64, 96, 128, | ||
75 | }; | ||
76 | |||
77 | #define DIGITAL_ATS_FSCI(t0) ((t0) & 0x0F) | ||
78 | #define DIGITAL_ATS_MAX_FSC 256 | ||
79 | |||
80 | #define DIGITAL_RATS_BYTE1 0xE0 | ||
81 | #define DIGITAL_RATS_PARAM 0x80 | ||
82 | |||
54 | struct digital_sdd_res { | 83 | struct digital_sdd_res { |
55 | u8 nfcid1[4]; | 84 | u8 nfcid1[4]; |
56 | u8 bcc; | 85 | u8 bcc; |
@@ -82,9 +111,127 @@ struct digital_sensf_res { | |||
82 | u8 rd[2]; | 111 | u8 rd[2]; |
83 | } __packed; | 112 | } __packed; |
84 | 113 | ||
114 | struct digital_iso15693_inv_req { | ||
115 | u8 flags; | ||
116 | u8 cmd; | ||
117 | u8 mask_len; | ||
118 | u64 mask; | ||
119 | } __packed; | ||
120 | |||
121 | struct digital_iso15693_inv_res { | ||
122 | u8 flags; | ||
123 | u8 dsfid; | ||
124 | u64 uid; | ||
125 | } __packed; | ||
126 | |||
85 | static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, | 127 | static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, |
86 | struct nfc_target *target); | 128 | struct nfc_target *target); |
87 | 129 | ||
130 | int digital_in_iso_dep_pull_sod(struct nfc_digital_dev *ddev, | ||
131 | struct sk_buff *skb) | ||
132 | { | ||
133 | u8 pcb; | ||
134 | u8 block_type; | ||
135 | |||
136 | if (skb->len < 1) | ||
137 | return -EIO; | ||
138 | |||
139 | pcb = *skb->data; | ||
140 | block_type = DIGITAL_ISO_DEP_PCB_TYPE(pcb); | ||
141 | |||
142 | /* No support fo R-block nor S-block */ | ||
143 | if (block_type != DIGITAL_ISO_DEP_I_BLOCK) { | ||
144 | pr_err("ISO_DEP R-block and S-block not supported\n"); | ||
145 | return -EIO; | ||
146 | } | ||
147 | |||
148 | if (DIGITAL_ISO_DEP_BLOCK_HAS_DID(pcb)) { | ||
149 | pr_err("DID field in ISO_DEP PCB not supported\n"); | ||
150 | return -EIO; | ||
151 | } | ||
152 | |||
153 | skb_pull(skb, 1); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | int digital_in_iso_dep_push_sod(struct nfc_digital_dev *ddev, | ||
159 | struct sk_buff *skb) | ||
160 | { | ||
161 | /* | ||
162 | * Chaining not supported so skb->len + 1 PCB byte + 2 CRC bytes must | ||
163 | * not be greater than remote FSC | ||
164 | */ | ||
165 | if (skb->len + 3 > ddev->target_fsc) | ||
166 | return -EIO; | ||
167 | |||
168 | skb_push(skb, 1); | ||
169 | |||
170 | *skb->data = DIGITAL_ISO_DEP_I_PCB | ddev->curr_nfc_dep_pni; | ||
171 | |||
172 | ddev->curr_nfc_dep_pni = | ||
173 | DIGITAL_ISO_DEP_PNI(ddev->curr_nfc_dep_pni + 1); | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static void digital_in_recv_ats(struct nfc_digital_dev *ddev, void *arg, | ||
179 | struct sk_buff *resp) | ||
180 | { | ||
181 | struct nfc_target *target = arg; | ||
182 | u8 fsdi; | ||
183 | int rc; | ||
184 | |||
185 | if (IS_ERR(resp)) { | ||
186 | rc = PTR_ERR(resp); | ||
187 | resp = NULL; | ||
188 | goto exit; | ||
189 | } | ||
190 | |||
191 | if (resp->len < 2) { | ||
192 | rc = -EIO; | ||
193 | goto exit; | ||
194 | } | ||
195 | |||
196 | fsdi = DIGITAL_ATS_FSCI(resp->data[1]); | ||
197 | if (fsdi >= 8) | ||
198 | ddev->target_fsc = DIGITAL_ATS_MAX_FSC; | ||
199 | else | ||
200 | ddev->target_fsc = digital_ats_fsc[fsdi]; | ||
201 | |||
202 | ddev->curr_nfc_dep_pni = 0; | ||
203 | |||
204 | rc = digital_target_found(ddev, target, NFC_PROTO_ISO14443); | ||
205 | |||
206 | exit: | ||
207 | dev_kfree_skb(resp); | ||
208 | kfree(target); | ||
209 | |||
210 | if (rc) | ||
211 | digital_poll_next_tech(ddev); | ||
212 | } | ||
213 | |||
214 | static int digital_in_send_rats(struct nfc_digital_dev *ddev, | ||
215 | struct nfc_target *target) | ||
216 | { | ||
217 | int rc; | ||
218 | struct sk_buff *skb; | ||
219 | |||
220 | skb = digital_skb_alloc(ddev, 2); | ||
221 | if (!skb) | ||
222 | return -ENOMEM; | ||
223 | |||
224 | *skb_put(skb, 1) = DIGITAL_RATS_BYTE1; | ||
225 | *skb_put(skb, 1) = DIGITAL_RATS_PARAM; | ||
226 | |||
227 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_ats, | ||
228 | target); | ||
229 | if (rc) | ||
230 | kfree_skb(skb); | ||
231 | |||
232 | return rc; | ||
233 | } | ||
234 | |||
88 | static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, | 235 | static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, |
89 | struct sk_buff *resp) | 236 | struct sk_buff *resp) |
90 | { | 237 | { |
@@ -122,8 +269,19 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, | |||
122 | goto exit_free_skb; | 269 | goto exit_free_skb; |
123 | } | 270 | } |
124 | 271 | ||
272 | target->sel_res = sel_res; | ||
273 | |||
125 | if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { | 274 | if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { |
126 | nfc_proto = NFC_PROTO_MIFARE; | 275 | nfc_proto = NFC_PROTO_MIFARE; |
276 | } else if (DIGITAL_SEL_RES_IS_T4T(sel_res)) { | ||
277 | rc = digital_in_send_rats(ddev, target); | ||
278 | if (rc) | ||
279 | goto exit; | ||
280 | /* | ||
281 | * Skip target_found and don't free it for now. This will be | ||
282 | * done when receiving the ATS | ||
283 | */ | ||
284 | goto exit_free_skb; | ||
127 | } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { | 285 | } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { |
128 | nfc_proto = NFC_PROTO_NFC_DEP; | 286 | nfc_proto = NFC_PROTO_NFC_DEP; |
129 | } else { | 287 | } else { |
@@ -131,8 +289,6 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, | |||
131 | goto exit; | 289 | goto exit; |
132 | } | 290 | } |
133 | 291 | ||
134 | target->sel_res = sel_res; | ||
135 | |||
136 | rc = digital_target_found(ddev, target, nfc_proto); | 292 | rc = digital_target_found(ddev, target, nfc_proto); |
137 | 293 | ||
138 | exit: | 294 | exit: |
@@ -473,6 +629,93 @@ int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech) | |||
473 | return rc; | 629 | return rc; |
474 | } | 630 | } |
475 | 631 | ||
632 | static void digital_in_recv_iso15693_inv_res(struct nfc_digital_dev *ddev, | ||
633 | void *arg, struct sk_buff *resp) | ||
634 | { | ||
635 | struct digital_iso15693_inv_res *res; | ||
636 | struct nfc_target *target = NULL; | ||
637 | int rc; | ||
638 | |||
639 | if (IS_ERR(resp)) { | ||
640 | rc = PTR_ERR(resp); | ||
641 | resp = NULL; | ||
642 | goto out_free_skb; | ||
643 | } | ||
644 | |||
645 | if (resp->len != sizeof(*res)) { | ||
646 | rc = -EIO; | ||
647 | goto out_free_skb; | ||
648 | } | ||
649 | |||
650 | res = (struct digital_iso15693_inv_res *)resp->data; | ||
651 | |||
652 | if (!DIGITAL_ISO15693_RES_IS_VALID(res->flags)) { | ||
653 | PROTOCOL_ERR("ISO15693 - 10.3.1"); | ||
654 | rc = -EINVAL; | ||
655 | goto out_free_skb; | ||
656 | } | ||
657 | |||
658 | target = kzalloc(sizeof(*target), GFP_KERNEL); | ||
659 | if (!target) { | ||
660 | rc = -ENOMEM; | ||
661 | goto out_free_skb; | ||
662 | } | ||
663 | |||
664 | target->is_iso15693 = 1; | ||
665 | target->iso15693_dsfid = res->dsfid; | ||
666 | memcpy(target->iso15693_uid, &res->uid, sizeof(target->iso15693_uid)); | ||
667 | |||
668 | rc = digital_target_found(ddev, target, NFC_PROTO_ISO15693); | ||
669 | |||
670 | kfree(target); | ||
671 | |||
672 | out_free_skb: | ||
673 | dev_kfree_skb(resp); | ||
674 | |||
675 | if (rc) | ||
676 | digital_poll_next_tech(ddev); | ||
677 | } | ||
678 | |||
679 | int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech) | ||
680 | { | ||
681 | struct digital_iso15693_inv_req *req; | ||
682 | struct sk_buff *skb; | ||
683 | int rc; | ||
684 | |||
685 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, | ||
686 | NFC_DIGITAL_RF_TECH_ISO15693); | ||
687 | if (rc) | ||
688 | return rc; | ||
689 | |||
690 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | ||
691 | NFC_DIGITAL_FRAMING_ISO15693_INVENTORY); | ||
692 | if (rc) | ||
693 | return rc; | ||
694 | |||
695 | skb = digital_skb_alloc(ddev, sizeof(*req)); | ||
696 | if (!skb) | ||
697 | return -ENOMEM; | ||
698 | |||
699 | skb_put(skb, sizeof(*req) - sizeof(req->mask)); /* No mask */ | ||
700 | req = (struct digital_iso15693_inv_req *)skb->data; | ||
701 | |||
702 | /* Single sub-carrier, high data rate, no AFI, single slot | ||
703 | * Inventory command | ||
704 | */ | ||
705 | req->flags = DIGITAL_ISO15693_REQ_FLAG_DATA_RATE | | ||
706 | DIGITAL_ISO15693_REQ_FLAG_INVENTORY | | ||
707 | DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS; | ||
708 | req->cmd = DIGITAL_CMD_ISO15693_INVENTORY_REQ; | ||
709 | req->mask_len = 0; | ||
710 | |||
711 | rc = digital_in_send_cmd(ddev, skb, 30, | ||
712 | digital_in_recv_iso15693_inv_res, NULL); | ||
713 | if (rc) | ||
714 | kfree_skb(skb); | ||
715 | |||
716 | return rc; | ||
717 | } | ||
718 | |||
476 | static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev) | 719 | static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev) |
477 | { | 720 | { |
478 | struct sk_buff *skb; | 721 | struct sk_buff *skb; |
diff --git a/net/nfc/hci/llc.c b/net/nfc/hci/llc.c index a07d2b818487..1b90c0531852 100644 --- a/net/nfc/hci/llc.c +++ b/net/nfc/hci/llc.c | |||
@@ -20,14 +20,12 @@ | |||
20 | 20 | ||
21 | #include "llc.h" | 21 | #include "llc.h" |
22 | 22 | ||
23 | static struct list_head llc_engines; | 23 | static LIST_HEAD(llc_engines); |
24 | 24 | ||
25 | int nfc_llc_init(void) | 25 | int nfc_llc_init(void) |
26 | { | 26 | { |
27 | int r; | 27 | int r; |
28 | 28 | ||
29 | INIT_LIST_HEAD(&llc_engines); | ||
30 | |||
31 | r = nfc_llc_nop_register(); | 29 | r = nfc_llc_nop_register(); |
32 | if (r) | 30 | if (r) |
33 | goto exit; | 31 | goto exit; |
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index 6184bd1fba3a..b486f12ae243 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | static u8 llcp_magic[3] = {0x46, 0x66, 0x6d}; | 28 | static u8 llcp_magic[3] = {0x46, 0x66, 0x6d}; |
29 | 29 | ||
30 | static struct list_head llcp_devices; | 30 | static LIST_HEAD(llcp_devices); |
31 | 31 | ||
32 | static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb); | 32 | static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb); |
33 | 33 | ||
@@ -293,9 +293,9 @@ static void nfc_llcp_sdreq_timer(unsigned long data) | |||
293 | 293 | ||
294 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) | 294 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) |
295 | { | 295 | { |
296 | struct nfc_llcp_local *local, *n; | 296 | struct nfc_llcp_local *local; |
297 | 297 | ||
298 | list_for_each_entry_safe(local, n, &llcp_devices, list) | 298 | list_for_each_entry(local, &llcp_devices, list) |
299 | if (local->dev == dev) | 299 | if (local->dev == dev) |
300 | return local; | 300 | return local; |
301 | 301 | ||
@@ -609,14 +609,16 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len) | |||
609 | 609 | ||
610 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) | 610 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) |
611 | { | 611 | { |
612 | struct nfc_llcp_local *local = nfc_llcp_find_local(dev); | 612 | struct nfc_llcp_local *local; |
613 | |||
614 | if (gb_len < 3 || gb_len > NFC_MAX_GT_LEN) | ||
615 | return -EINVAL; | ||
613 | 616 | ||
617 | local = nfc_llcp_find_local(dev); | ||
614 | if (local == NULL) { | 618 | if (local == NULL) { |
615 | pr_err("No LLCP device\n"); | 619 | pr_err("No LLCP device\n"); |
616 | return -ENODEV; | 620 | return -ENODEV; |
617 | } | 621 | } |
618 | if (gb_len < 3) | ||
619 | return -EINVAL; | ||
620 | 622 | ||
621 | memset(local->remote_gb, 0, NFC_MAX_GT_LEN); | 623 | memset(local->remote_gb, 0, NFC_MAX_GT_LEN); |
622 | memcpy(local->remote_gb, gb, gb_len); | 624 | memcpy(local->remote_gb, gb, gb_len); |
@@ -1622,8 +1624,6 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) | |||
1622 | 1624 | ||
1623 | int __init nfc_llcp_init(void) | 1625 | int __init nfc_llcp_init(void) |
1624 | { | 1626 | { |
1625 | INIT_LIST_HEAD(&llcp_devices); | ||
1626 | |||
1627 | return nfc_llcp_sock_init(); | 1627 | return nfc_llcp_sock_init(); |
1628 | } | 1628 | } |
1629 | 1629 | ||
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 56db888b1cd5..6c34ac978501 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -74,7 +74,7 @@ static int __nci_request(struct nci_dev *ndev, | |||
74 | 74 | ||
75 | ndev->req_status = NCI_REQ_PEND; | 75 | ndev->req_status = NCI_REQ_PEND; |
76 | 76 | ||
77 | init_completion(&ndev->req_completion); | 77 | reinit_completion(&ndev->req_completion); |
78 | req(ndev, opt); | 78 | req(ndev, opt); |
79 | completion_rc = | 79 | completion_rc = |
80 | wait_for_completion_interruptible_timeout(&ndev->req_completion, | 80 | wait_for_completion_interruptible_timeout(&ndev->req_completion, |
@@ -709,6 +709,7 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops, | |||
709 | ndev->ops = ops; | 709 | ndev->ops = ops; |
710 | ndev->tx_headroom = tx_headroom; | 710 | ndev->tx_headroom = tx_headroom; |
711 | ndev->tx_tailroom = tx_tailroom; | 711 | ndev->tx_tailroom = tx_tailroom; |
712 | init_completion(&ndev->req_completion); | ||
712 | 713 | ||
713 | ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, | 714 | ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, |
714 | supported_protocols, | 715 | supported_protocols, |
diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c index f1d426f10cce..ec250e77763a 100644 --- a/net/nfc/nci/spi.c +++ b/net/nfc/nci/spi.c | |||
@@ -105,7 +105,7 @@ int nci_spi_send(struct nci_spi *nspi, | |||
105 | if (ret != 0 || nspi->acknowledge_mode == NCI_SPI_CRC_DISABLED) | 105 | if (ret != 0 || nspi->acknowledge_mode == NCI_SPI_CRC_DISABLED) |
106 | goto done; | 106 | goto done; |
107 | 107 | ||
108 | init_completion(&nspi->req_completion); | 108 | reinit_completion(&nspi->req_completion); |
109 | completion_rc = wait_for_completion_interruptible_timeout( | 109 | completion_rc = wait_for_completion_interruptible_timeout( |
110 | &nspi->req_completion, | 110 | &nspi->req_completion, |
111 | NCI_SPI_SEND_TIMEOUT); | 111 | NCI_SPI_SEND_TIMEOUT); |
@@ -145,6 +145,7 @@ struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi, | |||
145 | 145 | ||
146 | nspi->spi = spi; | 146 | nspi->spi = spi; |
147 | nspi->ndev = ndev; | 147 | nspi->ndev = ndev; |
148 | init_completion(&nspi->req_completion); | ||
148 | 149 | ||
149 | return nspi; | 150 | return nspi; |
150 | } | 151 | } |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index ebbf6fb88b35..43cb1c17e267 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -94,6 +94,14 @@ static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, | |||
94 | target->sensf_res)) | 94 | target->sensf_res)) |
95 | goto nla_put_failure; | 95 | goto nla_put_failure; |
96 | 96 | ||
97 | if (target->is_iso15693) { | ||
98 | if (nla_put_u8(msg, NFC_ATTR_TARGET_ISO15693_DSFID, | ||
99 | target->iso15693_dsfid) || | ||
100 | nla_put(msg, NFC_ATTR_TARGET_ISO15693_UID, | ||
101 | sizeof(target->iso15693_uid), target->iso15693_uid)) | ||
102 | goto nla_put_failure; | ||
103 | } | ||
104 | |||
97 | return genlmsg_end(msg, hdr); | 105 | return genlmsg_end(msg, hdr); |
98 | 106 | ||
99 | nla_put_failure: | 107 | nla_put_failure: |