aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorThierry Escande <thierry.escande@linux.intel.com>2013-09-19 11:55:29 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-09-24 20:02:27 -0400
commit7d0911c02fa2a448a28d7844d2a0c439ff8397b1 (patch)
treec9638f5b6ebab6323c51037a8e871d6cf91d8efd /net/nfc
parent8c0695e4998dd268ff2a05951961247b7e015651 (diff)
NFC Digital: Add initiator NFC-DEP support
This adds support for NFC-DEP protocol in initiator mode for NFC-A and NFC-F technologies. When a target is detected, the process flow is as follow: For NFC-A technology: 1 - The digital stack receives a SEL_RES as the reply of the SEL_REQ command. 2 - If b7 of SEL_RES is set, the peer device is configure for NFC-DEP protocol. NFC core is notified through nfc_targets_found(). Execution continues at step 4. 3 - Otherwise, it's a tag and the NFC core is notified. Detection ends. 4 - The digital stacks sends an ATR_REQ command containing a randomly generated NFCID3 and the general bytes obtained from the LLCP layer of NFC core. For NFC-F technology: 1 - The digital stack receives a SENSF_RES as the reply of the SENSF_REQ command. 2 - If B1 and B2 of NFCID2 are 0x01 and 0xFE respectively, the peer device is configured for NFC-DEP protocol. NFC core is notified through nfc_targets_found(). Execution continues at step 4. 3 - Otherwise it's a type 3 tag. NFC core is notified. Detection ends. 4 - The digital stacks sends an ATR_REQ command containing the NFC-F NFCID2 as NFCID3 and the general bytes obtained from the LLCP layer of NFC core. For both technologies: 5 - The digital stacks receives the ATR_RES response containing the NFCID3 and the general bytes of the peer device. 6 - The digital stack notifies NFC core that the DEP link is up through nfc_dep_link_up(). 7 - The NFC core performs data exchange through tm_transceive(). 8 - The digital stack sends a DEP_REQ command containing an I PDU with the data from NFC core. 9 - The digital stack receives a DEP_RES command 10 - If the DEP_RES response contains a supervisor PDU with timeout extension request (RTOX) the digital stack sends a DEP_REQ command containing a supervisor PDU acknowledging the RTOX request. The execution continues at step 9. 11 - If the DEP_RES response contains an I PDU, the response data is passed back to NFC core through the response callback. The execution continues at step 8. Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/Makefile2
-rw-r--r--net/nfc/digital.h14
-rw-r--r--net/nfc/digital_core.c32
-rw-r--r--net/nfc/digital_dep.c381
-rw-r--r--net/nfc/digital_technology.c12
5 files changed, 435 insertions, 6 deletions
diff --git a/net/nfc/Makefile b/net/nfc/Makefile
index 2db39713a907..2555ff8e7219 100644
--- a/net/nfc/Makefile
+++ b/net/nfc/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_NFC_DIGITAL) += nfc_digital.o
10nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ 10nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
11 llcp_sock.o 11 llcp_sock.o
12 12
13nfc_digital-objs := digital_core.o digital_technology.o 13nfc_digital-objs := digital_core.o digital_technology.o digital_dep.o
diff --git a/net/nfc/digital.h b/net/nfc/digital.h
index 85bc74c988f8..5254a872522b 100644
--- a/net/nfc/digital.h
+++ b/net/nfc/digital.h
@@ -35,6 +35,13 @@
35#define DIGITAL_MAX_HEADER_LEN 7 35#define DIGITAL_MAX_HEADER_LEN 7
36#define DIGITAL_CRC_LEN 2 36#define DIGITAL_CRC_LEN 2
37 37
38#define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01
39#define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE
40
41#define DIGITAL_SENS_RES_NFC_DEP 0x0100
42#define DIGITAL_SEL_RES_NFC_DEP 0x40
43#define DIGITAL_SENSF_FELICA_SC 0xFFFF
44
38#define DIGITAL_DRV_CAPS_IN_CRC(ddev) \ 45#define DIGITAL_DRV_CAPS_IN_CRC(ddev) \
39 ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC) 46 ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC)
40#define DIGITAL_DRV_CAPS_TG_CRC(ddev) \ 47#define DIGITAL_DRV_CAPS_TG_CRC(ddev) \
@@ -72,6 +79,13 @@ int digital_target_found(struct nfc_digital_dev *ddev,
72 79
73int digital_in_recv_mifare_res(struct sk_buff *resp); 80int digital_in_recv_mifare_res(struct sk_buff *resp);
74 81
82int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
83 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
84 size_t gb_len);
85int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
86 struct nfc_target *target, struct sk_buff *skb,
87 struct digital_data_exch *data_exch);
88
75typedef u16 (*crc_func_t)(u16, const u8 *, size_t); 89typedef u16 (*crc_func_t)(u16, const u8 *, size_t);
76 90
77#define CRC_A_INIT 0x6363 91#define CRC_A_INIT 0x6363
diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c
index 25e5bcb946e0..dccfcccf6998 100644
--- a/net/nfc/digital_core.c
+++ b/net/nfc/digital_core.c
@@ -18,9 +18,10 @@
18#include "digital.h" 18#include "digital.h"
19 19
20#define DIGITAL_PROTO_NFCA_RF_TECH \ 20#define DIGITAL_PROTO_NFCA_RF_TECH \
21 (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK) 21 (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK)
22 22
23#define DIGITAL_PROTO_NFCF_RF_TECH (NFC_PROTO_FELICA_MASK) 23#define DIGITAL_PROTO_NFCF_RF_TECH \
24 (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK)
24 25
25struct digital_cmd { 26struct digital_cmd {
26 struct list_head queue; 27 struct list_head queue;
@@ -260,6 +261,18 @@ int digital_target_found(struct nfc_digital_dev *ddev,
260 add_crc = digital_skb_add_crc_f; 261 add_crc = digital_skb_add_crc_f;
261 break; 262 break;
262 263
264 case NFC_PROTO_NFC_DEP:
265 if (rf_tech == NFC_DIGITAL_RF_TECH_106A) {
266 framing = NFC_DIGITAL_FRAMING_NFCA_NFC_DEP;
267 check_crc = digital_skb_check_crc_a;
268 add_crc = digital_skb_add_crc_a;
269 } else {
270 framing = NFC_DIGITAL_FRAMING_NFCF_NFC_DEP;
271 check_crc = digital_skb_check_crc_f;
272 add_crc = digital_skb_add_crc_f;
273 }
274 break;
275
263 default: 276 default:
264 PR_ERR("Invalid protocol %d", protocol); 277 PR_ERR("Invalid protocol %d", protocol);
265 return -EINVAL; 278 return -EINVAL;
@@ -453,12 +466,18 @@ static int digital_dep_link_up(struct nfc_dev *nfc_dev,
453 struct nfc_target *target, 466 struct nfc_target *target,
454 __u8 comm_mode, __u8 *gb, size_t gb_len) 467 __u8 comm_mode, __u8 *gb, size_t gb_len)
455{ 468{
456 return -EOPNOTSUPP; 469 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
470
471 return digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len);
457} 472}
458 473
459static int digital_dep_link_down(struct nfc_dev *nfc_dev) 474static int digital_dep_link_down(struct nfc_dev *nfc_dev)
460{ 475{
461 return -EOPNOTSUPP; 476 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
477
478 ddev->curr_protocol = 0;
479
480 return 0;
462} 481}
463 482
464static int digital_activate_target(struct nfc_dev *nfc_dev, 483static int digital_activate_target(struct nfc_dev *nfc_dev,
@@ -523,6 +542,9 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target,
523 data_exch->cb = cb; 542 data_exch->cb = cb;
524 data_exch->cb_context = cb_context; 543 data_exch->cb_context = cb_context;
525 544
545 if (ddev->curr_protocol == NFC_PROTO_NFC_DEP)
546 return digital_in_send_dep_req(ddev, target, skb, data_exch);
547
526 ddev->skb_add_crc(skb); 548 ddev->skb_add_crc(skb);
527 549
528 return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete, 550 return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete,
@@ -578,6 +600,8 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
578 ddev->protocols |= NFC_PROTO_MIFARE_MASK; 600 ddev->protocols |= NFC_PROTO_MIFARE_MASK;
579 if (supported_protocols & NFC_PROTO_FELICA_MASK) 601 if (supported_protocols & NFC_PROTO_FELICA_MASK)
580 ddev->protocols |= NFC_PROTO_FELICA_MASK; 602 ddev->protocols |= NFC_PROTO_FELICA_MASK;
603 if (supported_protocols & NFC_PROTO_NFC_DEP_MASK)
604 ddev->protocols |= NFC_PROTO_NFC_DEP_MASK;
581 605
582 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; 606 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN;
583 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; 607 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN;
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c
new file mode 100644
index 000000000000..be984c4204d2
--- /dev/null
+++ b/net/nfc/digital_dep.c
@@ -0,0 +1,381 @@
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
16#include "digital.h"
17
18#define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4
19#define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5
20
21#define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0
22
23#define DIGITAL_CMD_ATR_REQ 0x00
24#define DIGITAL_CMD_ATR_RES 0x01
25#define DIGITAL_CMD_PSL_REQ 0x04
26#define DIGITAL_CMD_PSL_RES 0x05
27#define DIGITAL_CMD_DEP_REQ 0x06
28#define DIGITAL_CMD_DEP_RES 0x07
29
30#define DIGITAL_ATR_REQ_MIN_SIZE 16
31#define DIGITAL_ATR_REQ_MAX_SIZE 64
32
33#define DIGITAL_NFCID3_LEN ((u8)8)
34#define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30
35#define DIGITAL_GB_BIT 0x02
36
37#define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
38
39#define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
40
41#define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
42 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
43#define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & 0x10)
44#define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
45#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
46#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
47
48#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
49#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
50#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
51
52struct digital_atr_req {
53 u8 dir;
54 u8 cmd;
55 u8 nfcid3[10];
56 u8 did;
57 u8 bs;
58 u8 br;
59 u8 pp;
60 u8 gb[0];
61} __packed;
62
63struct digital_atr_res {
64 u8 dir;
65 u8 cmd;
66 u8 nfcid3[10];
67 u8 did;
68 u8 bs;
69 u8 br;
70 u8 to;
71 u8 pp;
72 u8 gb[0];
73} __packed;
74
75struct digital_psl_req {
76 u8 dir;
77 u8 cmd;
78 u8 did;
79 u8 brs;
80 u8 fsl;
81} __packed;
82
83struct digital_psl_res {
84 u8 dir;
85 u8 cmd;
86 u8 did;
87} __packed;
88
89struct digital_dep_req_res {
90 u8 dir;
91 u8 cmd;
92 u8 pfb;
93} __packed;
94
95static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
96 struct sk_buff *resp);
97
98static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
99 struct sk_buff *skb)
100{
101 skb_push(skb, sizeof(u8));
102
103 skb->data[0] = skb->len;
104
105 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
106 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
107}
108
109static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
110 struct sk_buff *skb)
111{
112 u8 size;
113
114 if (skb->len < 2)
115 return -EIO;
116
117 if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
118 skb_pull(skb, sizeof(u8));
119
120 size = skb->data[0];
121 if (size != skb->len)
122 return -EIO;
123
124 skb_pull(skb, sizeof(u8));
125
126 return 0;
127}
128
129static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
130 struct sk_buff *resp)
131{
132 struct nfc_target *target = arg;
133 struct digital_atr_res *atr_res;
134 u8 gb_len;
135 int rc;
136
137 if (IS_ERR(resp)) {
138 rc = PTR_ERR(resp);
139 resp = NULL;
140 goto exit;
141 }
142
143 rc = ddev->skb_check_crc(resp);
144 if (rc) {
145 PROTOCOL_ERR("14.4.1.6");
146 goto exit;
147 }
148
149 rc = digital_skb_pull_dep_sod(ddev, resp);
150 if (rc) {
151 PROTOCOL_ERR("14.4.1.2");
152 goto exit;
153 }
154
155 if (resp->len < sizeof(struct digital_atr_res)) {
156 rc = -EIO;
157 goto exit;
158 }
159
160 gb_len = resp->len - sizeof(struct digital_atr_res);
161
162 atr_res = (struct digital_atr_res *)resp->data;
163
164 rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
165 if (rc)
166 goto exit;
167
168 rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
169 NFC_RF_INITIATOR);
170
171 ddev->curr_nfc_dep_pni = 0;
172
173exit:
174 dev_kfree_skb(resp);
175
176 if (rc)
177 ddev->curr_protocol = 0;
178}
179
180int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
181 struct nfc_target *target, __u8 comm_mode, __u8 *gb,
182 size_t gb_len)
183{
184 struct sk_buff *skb;
185 struct digital_atr_req *atr_req;
186 uint size;
187
188 size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
189
190 if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
191 PROTOCOL_ERR("14.6.1.1");
192 return -EINVAL;
193 }
194
195 skb = digital_skb_alloc(ddev, size);
196 if (!skb)
197 return -ENOMEM;
198
199 skb_put(skb, sizeof(struct digital_atr_req));
200
201 atr_req = (struct digital_atr_req *)skb->data;
202 memset(atr_req, 0, sizeof(struct digital_atr_req));
203
204 atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
205 atr_req->cmd = DIGITAL_CMD_ATR_REQ;
206 if (target->nfcid2_len)
207 memcpy(atr_req->nfcid3, target->nfcid2,
208 max(target->nfcid2_len, DIGITAL_NFCID3_LEN));
209 else
210 get_random_bytes(atr_req->nfcid3, DIGITAL_NFCID3_LEN);
211
212 atr_req->did = 0;
213 atr_req->bs = 0;
214 atr_req->br = 0;
215
216 atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
217
218 if (gb_len) {
219 atr_req->pp |= DIGITAL_GB_BIT;
220 memcpy(skb_put(skb, gb_len), gb, gb_len);
221 }
222
223 digital_skb_push_dep_sod(ddev, skb);
224
225 ddev->skb_add_crc(skb);
226
227 digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, target);
228
229 return 0;
230}
231
232static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
233 struct digital_data_exch *data_exch, u8 rtox)
234{
235 struct digital_dep_req_res *dep_req;
236 struct sk_buff *skb;
237 int rc;
238
239 skb = digital_skb_alloc(ddev, 1);
240 if (!skb)
241 return -ENOMEM;
242
243 *skb_put(skb, 1) = rtox;
244
245 skb_push(skb, sizeof(struct digital_dep_req_res));
246
247 dep_req = (struct digital_dep_req_res *)skb->data;
248
249 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
250 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
251 dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
252 DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
253
254 digital_skb_push_dep_sod(ddev, skb);
255
256 ddev->skb_add_crc(skb);
257
258 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
259 data_exch);
260
261 return rc;
262}
263
264static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
265 struct sk_buff *resp)
266{
267 struct digital_data_exch *data_exch = arg;
268 struct digital_dep_req_res *dep_res;
269 u8 pfb;
270 uint size;
271 int rc;
272
273 if (IS_ERR(resp)) {
274 rc = PTR_ERR(resp);
275 resp = NULL;
276 goto exit;
277 }
278
279 rc = ddev->skb_check_crc(resp);
280 if (rc) {
281 PROTOCOL_ERR("14.4.1.6");
282 goto error;
283 }
284
285 rc = digital_skb_pull_dep_sod(ddev, resp);
286 if (rc) {
287 PROTOCOL_ERR("14.4.1.2");
288 goto exit;
289 }
290
291 dep_res = (struct digital_dep_req_res *)resp->data;
292
293 if (resp->len < sizeof(struct digital_dep_req_res) ||
294 dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
295 dep_res->cmd != DIGITAL_CMD_DEP_RES) {
296 rc = -EIO;
297 goto error;
298 }
299
300 pfb = dep_res->pfb;
301
302 switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
303 case DIGITAL_NFC_DEP_PFB_I_PDU:
304 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
305 PROTOCOL_ERR("14.12.3.3");
306 rc = -EIO;
307 goto error;
308 }
309
310 ddev->curr_nfc_dep_pni =
311 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
312 rc = 0;
313 break;
314
315 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
316 PR_ERR("Received a ACK/NACK PDU");
317 rc = -EIO;
318 goto error;
319
320 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
321 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
322 rc = -EINVAL;
323 goto error;
324 }
325
326 rc = digital_in_send_rtox(ddev, data_exch, resp->data[3]);
327 if (rc)
328 goto error;
329
330 kfree_skb(resp);
331 return;
332 }
333
334 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
335 PR_ERR("MI bit set. Chained PDU not supported.");
336 rc = -EIO;
337 goto error;
338 }
339
340 size = sizeof(struct digital_dep_req_res);
341
342 if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb))
343 size++;
344
345 if (size > resp->len) {
346 rc = -EIO;
347 goto error;
348 }
349
350 skb_pull(resp, size);
351
352exit:
353 data_exch->cb(data_exch->cb_context, resp, rc);
354
355error:
356 kfree(data_exch);
357
358 if (rc)
359 kfree_skb(resp);
360}
361
362int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
363 struct nfc_target *target, struct sk_buff *skb,
364 struct digital_data_exch *data_exch)
365{
366 struct digital_dep_req_res *dep_req;
367
368 skb_push(skb, sizeof(struct digital_dep_req_res));
369
370 dep_req = (struct digital_dep_req_res *)skb->data;
371 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
372 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
373 dep_req->pfb = ddev->curr_nfc_dep_pni;
374
375 digital_skb_push_dep_sod(ddev, skb);
376
377 ddev->skb_add_crc(skb);
378
379 return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
380 data_exch);
381}
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index bfe5ae17909e..0c28f600fd1c 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -28,6 +28,7 @@
28 28
29#define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) 29#define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04))
30#define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) 30#define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60))
31#define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40)
31 32
32#define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x000C) == 0x000C) 33#define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x000C) == 0x000C)
33#define DIGITAL_SENS_RES_IS_VALID(sens_res) \ 34#define DIGITAL_SENS_RES_IS_VALID(sens_res) \
@@ -121,6 +122,8 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg,
121 122
122 if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { 123 if (DIGITAL_SEL_RES_IS_T2T(sel_res)) {
123 nfc_proto = NFC_PROTO_MIFARE; 124 nfc_proto = NFC_PROTO_MIFARE;
125 } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) {
126 nfc_proto = NFC_PROTO_NFC_DEP;
124 } else { 127 } else {
125 rc = -EOPNOTSUPP; 128 rc = -EOPNOTSUPP;
126 goto exit; 129 goto exit;
@@ -379,6 +382,7 @@ static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg,
379 struct sk_buff *resp) 382 struct sk_buff *resp)
380{ 383{
381 int rc; 384 int rc;
385 u8 proto;
382 struct nfc_target target; 386 struct nfc_target target;
383 struct digital_sensf_res *sensf_res; 387 struct digital_sensf_res *sensf_res;
384 388
@@ -413,7 +417,13 @@ static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg,
413 memcpy(target.nfcid2, sensf_res->nfcid2, NFC_NFCID2_MAXSIZE); 417 memcpy(target.nfcid2, sensf_res->nfcid2, NFC_NFCID2_MAXSIZE);
414 target.nfcid2_len = NFC_NFCID2_MAXSIZE; 418 target.nfcid2_len = NFC_NFCID2_MAXSIZE;
415 419
416 rc = digital_target_found(ddev, &target, NFC_PROTO_FELICA); 420 if (target.nfcid2[0] == DIGITAL_SENSF_NFCID2_NFC_DEP_B1 &&
421 target.nfcid2[1] == DIGITAL_SENSF_NFCID2_NFC_DEP_B2)
422 proto = NFC_PROTO_NFC_DEP;
423 else
424 proto = NFC_PROTO_FELICA;
425
426 rc = digital_target_found(ddev, &target, proto);
417 427
418exit: 428exit:
419 dev_kfree_skb(resp); 429 dev_kfree_skb(resp);