~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/nfc/digital_dep.c

Version: ~ [ linux-5.6-rc1 ] ~ [ linux-5.5.2 ] ~ [ linux-5.4.17 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.102 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.170 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.213 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.213 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 #define pr_fmt(fmt) "digital: %s: " fmt, __func__
 17 
 18 #include "digital.h"
 19 
 20 #define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4
 21 #define DIGITAL_NFC_DEP_FRAME_DIR_IN  0xD5
 22 
 23 #define DIGITAL_NFC_DEP_NFCA_SOD_SB   0xF0
 24 
 25 #define DIGITAL_CMD_ATR_REQ 0x00
 26 #define DIGITAL_CMD_ATR_RES 0x01
 27 #define DIGITAL_CMD_PSL_REQ 0x04
 28 #define DIGITAL_CMD_PSL_RES 0x05
 29 #define DIGITAL_CMD_DEP_REQ 0x06
 30 #define DIGITAL_CMD_DEP_RES 0x07
 31 
 32 #define DIGITAL_ATR_REQ_MIN_SIZE 16
 33 #define DIGITAL_ATR_REQ_MAX_SIZE 64
 34 
 35 #define DIGITAL_NFCID3_LEN ((u8)8)
 36 #define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30
 37 #define DIGITAL_GB_BIT  0x02
 38 
 39 #define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
 40 
 41 #define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
 42 
 43 #define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
 44                                 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
 45 #define DIGITAL_NFC_DEP_MI_BIT_SET(pfb)  ((pfb) & 0x10)
 46 #define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
 47 #define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
 48 #define DIGITAL_NFC_DEP_PFB_PNI(pfb)     ((pfb) & 0x03)
 49 
 50 #define DIGITAL_NFC_DEP_PFB_I_PDU          0x00
 51 #define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU   0x40
 52 #define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
 53 
 54 struct digital_atr_req {
 55         u8 dir;
 56         u8 cmd;
 57         u8 nfcid3[10];
 58         u8 did;
 59         u8 bs;
 60         u8 br;
 61         u8 pp;
 62         u8 gb[0];
 63 } __packed;
 64 
 65 struct digital_atr_res {
 66         u8 dir;
 67         u8 cmd;
 68         u8 nfcid3[10];
 69         u8 did;
 70         u8 bs;
 71         u8 br;
 72         u8 to;
 73         u8 pp;
 74         u8 gb[0];
 75 } __packed;
 76 
 77 struct digital_psl_req {
 78         u8 dir;
 79         u8 cmd;
 80         u8 did;
 81         u8 brs;
 82         u8 fsl;
 83 } __packed;
 84 
 85 struct digital_psl_res {
 86         u8 dir;
 87         u8 cmd;
 88         u8 did;
 89 } __packed;
 90 
 91 struct digital_dep_req_res {
 92         u8 dir;
 93         u8 cmd;
 94         u8 pfb;
 95 } __packed;
 96 
 97 static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
 98                                     struct sk_buff *resp);
 99 
100 static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
101                                      struct sk_buff *skb)
102 {
103         skb_push(skb, sizeof(u8));
104 
105         skb->data[0] = skb->len;
106 
107         if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
108                 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
109 }
110 
111 static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
112                                     struct sk_buff *skb)
113 {
114         u8 size;
115 
116         if (skb->len < 2)
117                 return -EIO;
118 
119         if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
120                 skb_pull(skb, sizeof(u8));
121 
122         size = skb->data[0];
123         if (size != skb->len)
124                 return -EIO;
125 
126         skb_pull(skb, sizeof(u8));
127 
128         return 0;
129 }
130 
131 static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
132                                  struct sk_buff *resp)
133 {
134         struct nfc_target *target = arg;
135         struct digital_atr_res *atr_res;
136         u8 gb_len;
137         int rc;
138 
139         if (IS_ERR(resp)) {
140                 rc = PTR_ERR(resp);
141                 resp = NULL;
142                 goto exit;
143         }
144 
145         rc = ddev->skb_check_crc(resp);
146         if (rc) {
147                 PROTOCOL_ERR("14.4.1.6");
148                 goto exit;
149         }
150 
151         rc = digital_skb_pull_dep_sod(ddev, resp);
152         if (rc) {
153                 PROTOCOL_ERR("14.4.1.2");
154                 goto exit;
155         }
156 
157         if (resp->len < sizeof(struct digital_atr_res)) {
158                 rc = -EIO;
159                 goto exit;
160         }
161 
162         gb_len = resp->len - sizeof(struct digital_atr_res);
163 
164         atr_res = (struct digital_atr_res *)resp->data;
165 
166         rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
167         if (rc)
168                 goto exit;
169 
170         rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
171                                 NFC_RF_INITIATOR);
172 
173         ddev->curr_nfc_dep_pni = 0;
174 
175 exit:
176         dev_kfree_skb(resp);
177 
178         if (rc)
179                 ddev->curr_protocol = 0;
180 }
181 
182 int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
183                             struct nfc_target *target, __u8 comm_mode, __u8 *gb,
184                             size_t gb_len)
185 {
186         struct sk_buff *skb;
187         struct digital_atr_req *atr_req;
188         uint size;
189 
190         size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
191 
192         if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
193                 PROTOCOL_ERR("14.6.1.1");
194                 return -EINVAL;
195         }
196 
197         skb = digital_skb_alloc(ddev, size);
198         if (!skb)
199                 return -ENOMEM;
200 
201         skb_put(skb, sizeof(struct digital_atr_req));
202 
203         atr_req = (struct digital_atr_req *)skb->data;
204         memset(atr_req, 0, sizeof(struct digital_atr_req));
205 
206         atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
207         atr_req->cmd = DIGITAL_CMD_ATR_REQ;
208         if (target->nfcid2_len)
209                 memcpy(atr_req->nfcid3, target->nfcid2,
210                        max(target->nfcid2_len, DIGITAL_NFCID3_LEN));
211         else
212                 get_random_bytes(atr_req->nfcid3, DIGITAL_NFCID3_LEN);
213 
214         atr_req->did = 0;
215         atr_req->bs = 0;
216         atr_req->br = 0;
217 
218         atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
219 
220         if (gb_len) {
221                 atr_req->pp |= DIGITAL_GB_BIT;
222                 memcpy(skb_put(skb, gb_len), gb, gb_len);
223         }
224 
225         digital_skb_push_dep_sod(ddev, skb);
226 
227         ddev->skb_add_crc(skb);
228 
229         digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, target);
230 
231         return 0;
232 }
233 
234 static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
235                                 struct digital_data_exch *data_exch, u8 rtox)
236 {
237         struct digital_dep_req_res *dep_req;
238         struct sk_buff *skb;
239         int rc;
240 
241         skb = digital_skb_alloc(ddev, 1);
242         if (!skb)
243                 return -ENOMEM;
244 
245         *skb_put(skb, 1) = rtox;
246 
247         skb_push(skb, sizeof(struct digital_dep_req_res));
248 
249         dep_req = (struct digital_dep_req_res *)skb->data;
250 
251         dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
252         dep_req->cmd = DIGITAL_CMD_DEP_REQ;
253         dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU |
254                        DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT;
255 
256         digital_skb_push_dep_sod(ddev, skb);
257 
258         ddev->skb_add_crc(skb);
259 
260         rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
261                                  data_exch);
262 
263         return rc;
264 }
265 
266 static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
267                                     struct sk_buff *resp)
268 {
269         struct digital_data_exch *data_exch = arg;
270         struct digital_dep_req_res *dep_res;
271         u8 pfb;
272         uint size;
273         int rc;
274 
275         if (IS_ERR(resp)) {
276                 rc = PTR_ERR(resp);
277                 resp = NULL;
278                 goto exit;
279         }
280 
281         rc = ddev->skb_check_crc(resp);
282         if (rc) {
283                 PROTOCOL_ERR("14.4.1.6");
284                 goto error;
285         }
286 
287         rc = digital_skb_pull_dep_sod(ddev, resp);
288         if (rc) {
289                 PROTOCOL_ERR("14.4.1.2");
290                 goto exit;
291         }
292 
293         dep_res = (struct digital_dep_req_res *)resp->data;
294 
295         if (resp->len < sizeof(struct digital_dep_req_res) ||
296             dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN ||
297             dep_res->cmd != DIGITAL_CMD_DEP_RES) {
298                 rc = -EIO;
299                 goto error;
300         }
301 
302         pfb = dep_res->pfb;
303 
304         switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
305         case DIGITAL_NFC_DEP_PFB_I_PDU:
306                 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
307                         PROTOCOL_ERR("14.12.3.3");
308                         rc = -EIO;
309                         goto error;
310                 }
311 
312                 ddev->curr_nfc_dep_pni =
313                         DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
314                 rc = 0;
315                 break;
316 
317         case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
318                 pr_err("Received a ACK/NACK PDU\n");
319                 rc = -EIO;
320                 goto error;
321 
322         case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
323                 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
324                         rc = -EINVAL;
325                         goto error;
326                 }
327 
328                 rc = digital_in_send_rtox(ddev, data_exch, resp->data[3]);
329                 if (rc)
330                         goto error;
331 
332                 kfree_skb(resp);
333                 return;
334         }
335 
336         if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
337                 pr_err("MI bit set. Chained PDU not supported\n");
338                 rc = -EIO;
339                 goto error;
340         }
341 
342         size = sizeof(struct digital_dep_req_res);
343 
344         if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb))
345                 size++;
346 
347         if (size > resp->len) {
348                 rc = -EIO;
349                 goto error;
350         }
351 
352         skb_pull(resp, size);
353 
354 exit:
355         data_exch->cb(data_exch->cb_context, resp, rc);
356 
357 error:
358         kfree(data_exch);
359 
360         if (rc)
361                 kfree_skb(resp);
362 }
363 
364 int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
365                             struct nfc_target *target, struct sk_buff *skb,
366                             struct digital_data_exch *data_exch)
367 {
368         struct digital_dep_req_res *dep_req;
369 
370         skb_push(skb, sizeof(struct digital_dep_req_res));
371 
372         dep_req = (struct digital_dep_req_res *)skb->data;
373         dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
374         dep_req->cmd = DIGITAL_CMD_DEP_REQ;
375         dep_req->pfb = ddev->curr_nfc_dep_pni;
376 
377         digital_skb_push_dep_sod(ddev, skb);
378 
379         ddev->skb_add_crc(skb);
380 
381         return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
382                                    data_exch);
383 }
384 
385 static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
386                                     struct sk_buff *resp)
387 {
388         int rc;
389         struct digital_dep_req_res *dep_req;
390         size_t size;
391 
392         if (IS_ERR(resp)) {
393                 rc = PTR_ERR(resp);
394                 resp = NULL;
395                 goto exit;
396         }
397 
398         rc = ddev->skb_check_crc(resp);
399         if (rc) {
400                 PROTOCOL_ERR("14.4.1.6");
401                 goto exit;
402         }
403 
404         rc = digital_skb_pull_dep_sod(ddev, resp);
405         if (rc) {
406                 PROTOCOL_ERR("14.4.1.2");
407                 goto exit;
408         }
409 
410         size = sizeof(struct digital_dep_req_res);
411         dep_req = (struct digital_dep_req_res *)resp->data;
412 
413         if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
414             dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
415                 rc = -EIO;
416                 goto exit;
417         }
418 
419         if (DIGITAL_NFC_DEP_DID_BIT_SET(dep_req->pfb))
420                 size++;
421 
422         if (resp->len < size) {
423                 rc = -EIO;
424                 goto exit;
425         }
426 
427         switch (DIGITAL_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
428         case DIGITAL_NFC_DEP_PFB_I_PDU:
429                 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
430                 ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(dep_req->pfb);
431                 break;
432         case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
433                 pr_err("Received a ACK/NACK PDU\n");
434                 rc = -EINVAL;
435                 goto exit;
436                 break;
437         case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
438                 pr_err("Received a SUPERVISOR PDU\n");
439                 rc = -EINVAL;
440                 goto exit;
441                 break;
442         }
443 
444         skb_pull(resp, size);
445 
446         rc = nfc_tm_data_received(ddev->nfc_dev, resp);
447 
448 exit:
449         if (rc)
450                 kfree_skb(resp);
451 }
452 
453 int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
454 {
455         struct digital_dep_req_res *dep_res;
456 
457         skb_push(skb, sizeof(struct digital_dep_req_res));
458         dep_res = (struct digital_dep_req_res *)skb->data;
459 
460         dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
461         dep_res->cmd = DIGITAL_CMD_DEP_RES;
462         dep_res->pfb = ddev->curr_nfc_dep_pni;
463 
464         digital_skb_push_dep_sod(ddev, skb);
465 
466         ddev->skb_add_crc(skb);
467 
468         return digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
469                                    NULL);
470 }
471 
472 static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
473                                              void *arg, struct sk_buff *resp)
474 {
475         u8 rf_tech = PTR_ERR(arg);
476 
477         if (IS_ERR(resp))
478                 return;
479 
480         digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
481 
482         digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
483 
484         dev_kfree_skb(resp);
485 }
486 
487 static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
488                                    u8 rf_tech)
489 {
490         struct digital_psl_res *psl_res;
491         struct sk_buff *skb;
492         int rc;
493 
494         skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
495         if (!skb)
496                 return -ENOMEM;
497 
498         skb_put(skb, sizeof(struct digital_psl_res));
499 
500         psl_res = (struct digital_psl_res *)skb->data;
501 
502         psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
503         psl_res->cmd = DIGITAL_CMD_PSL_RES;
504         psl_res->did = did;
505 
506         digital_skb_push_dep_sod(ddev, skb);
507 
508         ddev->skb_add_crc(skb);
509 
510         rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
511                                  ERR_PTR(rf_tech));
512 
513         if (rc)
514                 kfree_skb(skb);
515 
516         return rc;
517 }
518 
519 static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
520                                     struct sk_buff *resp)
521 {
522         int rc;
523         struct digital_psl_req *psl_req;
524         u8 rf_tech;
525         u8 dsi;
526 
527         if (IS_ERR(resp)) {
528                 rc = PTR_ERR(resp);
529                 resp = NULL;
530                 goto exit;
531         }
532 
533         rc = ddev->skb_check_crc(resp);
534         if (rc) {
535                 PROTOCOL_ERR("14.4.1.6");
536                 goto exit;
537         }
538 
539         rc = digital_skb_pull_dep_sod(ddev, resp);
540         if (rc) {
541                 PROTOCOL_ERR("14.4.1.2");
542                 goto exit;
543         }
544 
545         psl_req = (struct digital_psl_req *)resp->data;
546 
547         if (resp->len != sizeof(struct digital_psl_req) ||
548             psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
549             psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
550                 rc = -EIO;
551                 goto exit;
552         }
553 
554         dsi = (psl_req->brs >> 3) & 0x07;
555         switch (dsi) {
556         case 0:
557                 rf_tech = NFC_DIGITAL_RF_TECH_106A;
558                 break;
559         case 1:
560                 rf_tech = NFC_DIGITAL_RF_TECH_212F;
561                 break;
562         case 2:
563                 rf_tech = NFC_DIGITAL_RF_TECH_424F;
564                 break;
565         default:
566                 pr_err("Unsuported dsi value %d\n", dsi);
567                 goto exit;
568         }
569 
570         rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
571 
572 exit:
573         kfree_skb(resp);
574 }
575 
576 static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
577                                              void *arg, struct sk_buff *resp)
578 {
579         int offset;
580 
581         if (IS_ERR(resp)) {
582                 digital_poll_next_tech(ddev);
583                 return;
584         }
585 
586         offset = 2;
587         if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
588                 offset++;
589 
590         if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
591                 digital_tg_recv_psl_req(ddev, arg, resp);
592         else
593                 digital_tg_recv_dep_req(ddev, arg, resp);
594 }
595 
596 static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
597                                    struct digital_atr_req *atr_req)
598 {
599         struct digital_atr_res *atr_res;
600         struct sk_buff *skb;
601         u8 *gb;
602         size_t gb_len;
603         int rc;
604 
605         gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
606         if (!gb)
607                 gb_len = 0;
608 
609         skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
610         if (!skb)
611                 return -ENOMEM;
612 
613         skb_put(skb, sizeof(struct digital_atr_res));
614         atr_res = (struct digital_atr_res *)skb->data;
615 
616         memset(atr_res, 0, sizeof(struct digital_atr_res));
617 
618         atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
619         atr_res->cmd = DIGITAL_CMD_ATR_RES;
620         memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
621         atr_res->to = 8;
622         atr_res->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
623         if (gb_len) {
624                 skb_put(skb, gb_len);
625 
626                 atr_res->pp |= DIGITAL_GB_BIT;
627                 memcpy(atr_res->gb, gb, gb_len);
628         }
629 
630         digital_skb_push_dep_sod(ddev, skb);
631 
632         ddev->skb_add_crc(skb);
633 
634         rc = digital_tg_send_cmd(ddev, skb, 999,
635                                  digital_tg_send_atr_res_complete, NULL);
636         if (rc) {
637                 kfree_skb(skb);
638                 return rc;
639         }
640 
641         return rc;
642 }
643 
644 void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
645                              struct sk_buff *resp)
646 {
647         int rc;
648         struct digital_atr_req *atr_req;
649         size_t gb_len, min_size;
650 
651         if (IS_ERR(resp)) {
652                 rc = PTR_ERR(resp);
653                 resp = NULL;
654                 goto exit;
655         }
656 
657         if (!resp->len) {
658                 rc = -EIO;
659                 goto exit;
660         }
661 
662         if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
663                 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
664 
665                 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_106A;
666                 ddev->skb_add_crc = digital_skb_add_crc_a;
667                 ddev->skb_check_crc = digital_skb_check_crc_a;
668         } else {
669                 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
670 
671                 ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_212F;
672                 ddev->skb_add_crc = digital_skb_add_crc_f;
673                 ddev->skb_check_crc = digital_skb_check_crc_f;
674         }
675 
676         if (resp->len < min_size) {
677                 rc = -EIO;
678                 goto exit;
679         }
680 
681         if (DIGITAL_DRV_CAPS_TG_CRC(ddev)) {
682                 ddev->skb_add_crc = digital_skb_add_crc_none;
683                 ddev->skb_check_crc = digital_skb_check_crc_none;
684         }
685 
686         rc = ddev->skb_check_crc(resp);
687         if (rc) {
688                 PROTOCOL_ERR("14.4.1.6");
689                 goto exit;
690         }
691 
692         rc = digital_skb_pull_dep_sod(ddev, resp);
693         if (rc) {
694                 PROTOCOL_ERR("14.4.1.2");
695                 goto exit;
696         }
697 
698         atr_req = (struct digital_atr_req *)resp->data;
699 
700         if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
701             atr_req->cmd != DIGITAL_CMD_ATR_REQ) {
702                 rc = -EINVAL;
703                 goto exit;
704         }
705 
706         rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
707                                      NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
708         if (rc)
709                 goto exit;
710 
711         rc = digital_tg_send_atr_res(ddev, atr_req);
712         if (rc)
713                 goto exit;
714 
715         gb_len = resp->len - sizeof(struct digital_atr_req);
716         rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
717                               NFC_COMM_PASSIVE, atr_req->gb, gb_len);
718         if (rc)
719                 goto exit;
720 
721         ddev->poll_tech_count = 0;
722 
723         rc = 0;
724 exit:
725         if (rc)
726                 digital_poll_next_tech(ddev);
727 
728         dev_kfree_skb(resp);
729 }
730 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp