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

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

Version: ~ [ linux-5.5-rc1 ] ~ [ linux-5.4.2 ] ~ [ linux-5.3.15 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.88 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.158 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.206 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.206 ] ~ [ 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.78 ] ~ [ 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_LR_BITS_PAYLOAD_SIZE_254B 0x30
 36 #define DIGITAL_GB_BIT  0x02
 37 
 38 #define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
 39 
 40 #define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10
 41 
 42 #define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
 43                                 ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT)
 44 #define DIGITAL_NFC_DEP_MI_BIT_SET(pfb)  ((pfb) & 0x10)
 45 #define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
 46 #define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
 47 #define DIGITAL_NFC_DEP_PFB_PNI(pfb)     ((pfb) & 0x03)
 48 
 49 #define DIGITAL_NFC_DEP_PFB_I_PDU          0x00
 50 #define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU   0x40
 51 #define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
 52 
 53 struct digital_atr_req {
 54         u8 dir;
 55         u8 cmd;
 56         u8 nfcid3[10];
 57         u8 did;
 58         u8 bs;
 59         u8 br;
 60         u8 pp;
 61         u8 gb[0];
 62 } __packed;
 63 
 64 struct digital_atr_res {
 65         u8 dir;
 66         u8 cmd;
 67         u8 nfcid3[10];
 68         u8 did;
 69         u8 bs;
 70         u8 br;
 71         u8 to;
 72         u8 pp;
 73         u8 gb[0];
 74 } __packed;
 75 
 76 struct digital_psl_req {
 77         u8 dir;
 78         u8 cmd;
 79         u8 did;
 80         u8 brs;
 81         u8 fsl;
 82 } __packed;
 83 
 84 struct digital_psl_res {
 85         u8 dir;
 86         u8 cmd;
 87         u8 did;
 88 } __packed;
 89 
 90 struct digital_dep_req_res {
 91         u8 dir;
 92         u8 cmd;
 93         u8 pfb;
 94 } __packed;
 95 
 96 static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
 97                                     struct sk_buff *resp);
 98 
 99 static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev,
100                                      struct sk_buff *skb)
101 {
102         skb_push(skb, sizeof(u8));
103 
104         skb->data[0] = skb->len;
105 
106         if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
107                 *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB;
108 }
109 
110 static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev,
111                                     struct sk_buff *skb)
112 {
113         u8 size;
114 
115         if (skb->len < 2)
116                 return -EIO;
117 
118         if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A)
119                 skb_pull(skb, sizeof(u8));
120 
121         size = skb->data[0];
122         if (size != skb->len)
123                 return -EIO;
124 
125         skb_pull(skb, sizeof(u8));
126 
127         return 0;
128 }
129 
130 static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg,
131                                  struct sk_buff *resp)
132 {
133         struct nfc_target *target = arg;
134         struct digital_atr_res *atr_res;
135         u8 gb_len;
136         int rc;
137 
138         if (IS_ERR(resp)) {
139                 rc = PTR_ERR(resp);
140                 resp = NULL;
141                 goto exit;
142         }
143 
144         rc = ddev->skb_check_crc(resp);
145         if (rc) {
146                 PROTOCOL_ERR("14.4.1.6");
147                 goto exit;
148         }
149 
150         rc = digital_skb_pull_dep_sod(ddev, resp);
151         if (rc) {
152                 PROTOCOL_ERR("14.4.1.2");
153                 goto exit;
154         }
155 
156         if (resp->len < sizeof(struct digital_atr_res)) {
157                 rc = -EIO;
158                 goto exit;
159         }
160 
161         gb_len = resp->len - sizeof(struct digital_atr_res);
162 
163         atr_res = (struct digital_atr_res *)resp->data;
164 
165         rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len);
166         if (rc)
167                 goto exit;
168 
169         rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE,
170                                 NFC_RF_INITIATOR);
171 
172         ddev->curr_nfc_dep_pni = 0;
173 
174 exit:
175         dev_kfree_skb(resp);
176 
177         if (rc)
178                 ddev->curr_protocol = 0;
179 }
180 
181 int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
182                             struct nfc_target *target, __u8 comm_mode, __u8 *gb,
183                             size_t gb_len)
184 {
185         struct sk_buff *skb;
186         struct digital_atr_req *atr_req;
187         uint size;
188 
189         size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len;
190 
191         if (size > DIGITAL_ATR_REQ_MAX_SIZE) {
192                 PROTOCOL_ERR("14.6.1.1");
193                 return -EINVAL;
194         }
195 
196         skb = digital_skb_alloc(ddev, size);
197         if (!skb)
198                 return -ENOMEM;
199 
200         skb_put(skb, sizeof(struct digital_atr_req));
201 
202         atr_req = (struct digital_atr_req *)skb->data;
203         memset(atr_req, 0, sizeof(struct digital_atr_req));
204 
205         atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
206         atr_req->cmd = DIGITAL_CMD_ATR_REQ;
207         if (target->nfcid2_len)
208                 memcpy(atr_req->nfcid3, target->nfcid2, NFC_NFCID2_MAXSIZE);
209         else
210                 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
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 
232 static 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 
264 static 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\n");
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\n");
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 
352 exit:
353         data_exch->cb(data_exch->cb_context, resp, rc);
354 
355 error:
356         kfree(data_exch);
357 
358         if (rc)
359                 kfree_skb(resp);
360 }
361 
362 int 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 }
382 
383 static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
384 {
385         ddev->curr_rf_tech = rf_tech;
386 
387         ddev->skb_add_crc = digital_skb_add_crc_none;
388         ddev->skb_check_crc = digital_skb_check_crc_none;
389 
390         if (DIGITAL_DRV_CAPS_TG_CRC(ddev))
391                 return;
392 
393         switch (ddev->curr_rf_tech) {
394         case NFC_DIGITAL_RF_TECH_106A:
395                 ddev->skb_add_crc = digital_skb_add_crc_a;
396                 ddev->skb_check_crc = digital_skb_check_crc_a;
397                 break;
398 
399         case NFC_DIGITAL_RF_TECH_212F:
400         case NFC_DIGITAL_RF_TECH_424F:
401                 ddev->skb_add_crc = digital_skb_add_crc_f;
402                 ddev->skb_check_crc = digital_skb_check_crc_f;
403                 break;
404 
405         default:
406                 break;
407         }
408 }
409 
410 static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
411                                     struct sk_buff *resp)
412 {
413         int rc;
414         struct digital_dep_req_res *dep_req;
415         size_t size;
416 
417         if (IS_ERR(resp)) {
418                 rc = PTR_ERR(resp);
419                 resp = NULL;
420                 goto exit;
421         }
422 
423         rc = ddev->skb_check_crc(resp);
424         if (rc) {
425                 PROTOCOL_ERR("14.4.1.6");
426                 goto exit;
427         }
428 
429         rc = digital_skb_pull_dep_sod(ddev, resp);
430         if (rc) {
431                 PROTOCOL_ERR("14.4.1.2");
432                 goto exit;
433         }
434 
435         size = sizeof(struct digital_dep_req_res);
436         dep_req = (struct digital_dep_req_res *)resp->data;
437 
438         if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
439             dep_req->cmd != DIGITAL_CMD_DEP_REQ) {
440                 rc = -EIO;
441                 goto exit;
442         }
443 
444         if (DIGITAL_NFC_DEP_DID_BIT_SET(dep_req->pfb))
445                 size++;
446 
447         if (resp->len < size) {
448                 rc = -EIO;
449                 goto exit;
450         }
451 
452         switch (DIGITAL_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
453         case DIGITAL_NFC_DEP_PFB_I_PDU:
454                 pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
455                 ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(dep_req->pfb);
456                 break;
457         case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
458                 pr_err("Received a ACK/NACK PDU\n");
459                 rc = -EINVAL;
460                 goto exit;
461                 break;
462         case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
463                 pr_err("Received a SUPERVISOR PDU\n");
464                 rc = -EINVAL;
465                 goto exit;
466                 break;
467         }
468 
469         skb_pull(resp, size);
470 
471         rc = nfc_tm_data_received(ddev->nfc_dev, resp);
472 
473 exit:
474         if (rc)
475                 kfree_skb(resp);
476 }
477 
478 int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
479 {
480         struct digital_dep_req_res *dep_res;
481 
482         skb_push(skb, sizeof(struct digital_dep_req_res));
483         dep_res = (struct digital_dep_req_res *)skb->data;
484 
485         dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
486         dep_res->cmd = DIGITAL_CMD_DEP_RES;
487         dep_res->pfb = ddev->curr_nfc_dep_pni;
488 
489         digital_skb_push_dep_sod(ddev, skb);
490 
491         ddev->skb_add_crc(skb);
492 
493         return digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
494                                    NULL);
495 }
496 
497 static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev,
498                                              void *arg, struct sk_buff *resp)
499 {
500         u8 rf_tech = (unsigned long)arg;
501 
502         if (IS_ERR(resp))
503                 return;
504 
505         digital_tg_set_rf_tech(ddev, rf_tech);
506 
507         digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
508 
509         digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL);
510 
511         dev_kfree_skb(resp);
512 }
513 
514 static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
515                                    u8 rf_tech)
516 {
517         struct digital_psl_res *psl_res;
518         struct sk_buff *skb;
519         int rc;
520 
521         skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res));
522         if (!skb)
523                 return -ENOMEM;
524 
525         skb_put(skb, sizeof(struct digital_psl_res));
526 
527         psl_res = (struct digital_psl_res *)skb->data;
528 
529         psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
530         psl_res->cmd = DIGITAL_CMD_PSL_RES;
531         psl_res->did = did;
532 
533         digital_skb_push_dep_sod(ddev, skb);
534 
535         ddev->skb_add_crc(skb);
536 
537         rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
538                                  (void *)(unsigned long)rf_tech);
539 
540         if (rc)
541                 kfree_skb(skb);
542 
543         return rc;
544 }
545 
546 static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
547                                     struct sk_buff *resp)
548 {
549         int rc;
550         struct digital_psl_req *psl_req;
551         u8 rf_tech;
552         u8 dsi;
553 
554         if (IS_ERR(resp)) {
555                 rc = PTR_ERR(resp);
556                 resp = NULL;
557                 goto exit;
558         }
559 
560         rc = ddev->skb_check_crc(resp);
561         if (rc) {
562                 PROTOCOL_ERR("14.4.1.6");
563                 goto exit;
564         }
565 
566         rc = digital_skb_pull_dep_sod(ddev, resp);
567         if (rc) {
568                 PROTOCOL_ERR("14.4.1.2");
569                 goto exit;
570         }
571 
572         psl_req = (struct digital_psl_req *)resp->data;
573 
574         if (resp->len != sizeof(struct digital_psl_req) ||
575             psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
576             psl_req->cmd != DIGITAL_CMD_PSL_REQ) {
577                 rc = -EIO;
578                 goto exit;
579         }
580 
581         dsi = (psl_req->brs >> 3) & 0x07;
582         switch (dsi) {
583         case 0:
584                 rf_tech = NFC_DIGITAL_RF_TECH_106A;
585                 break;
586         case 1:
587                 rf_tech = NFC_DIGITAL_RF_TECH_212F;
588                 break;
589         case 2:
590                 rf_tech = NFC_DIGITAL_RF_TECH_424F;
591                 break;
592         default:
593                 pr_err("Unsupported dsi value %d\n", dsi);
594                 goto exit;
595         }
596 
597         rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech);
598 
599 exit:
600         kfree_skb(resp);
601 }
602 
603 static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
604                                              void *arg, struct sk_buff *resp)
605 {
606         int offset;
607 
608         if (IS_ERR(resp)) {
609                 digital_poll_next_tech(ddev);
610                 return;
611         }
612 
613         offset = 2;
614         if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
615                 offset++;
616 
617         if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
618                 digital_tg_recv_psl_req(ddev, arg, resp);
619         else
620                 digital_tg_recv_dep_req(ddev, arg, resp);
621 }
622 
623 static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
624                                    struct digital_atr_req *atr_req)
625 {
626         struct digital_atr_res *atr_res;
627         struct sk_buff *skb;
628         u8 *gb;
629         size_t gb_len;
630         int rc;
631 
632         gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
633         if (!gb)
634                 gb_len = 0;
635 
636         skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
637         if (!skb)
638                 return -ENOMEM;
639 
640         skb_put(skb, sizeof(struct digital_atr_res));
641         atr_res = (struct digital_atr_res *)skb->data;
642 
643         memset(atr_res, 0, sizeof(struct digital_atr_res));
644 
645         atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
646         atr_res->cmd = DIGITAL_CMD_ATR_RES;
647         memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3));
648         atr_res->to = 8;
649         atr_res->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B;
650         if (gb_len) {
651                 skb_put(skb, gb_len);
652 
653                 atr_res->pp |= DIGITAL_GB_BIT;
654                 memcpy(atr_res->gb, gb, gb_len);
655         }
656 
657         digital_skb_push_dep_sod(ddev, skb);
658 
659         ddev->skb_add_crc(skb);
660 
661         rc = digital_tg_send_cmd(ddev, skb, 999,
662                                  digital_tg_send_atr_res_complete, NULL);
663         if (rc) {
664                 kfree_skb(skb);
665                 return rc;
666         }
667 
668         return rc;
669 }
670 
671 void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
672                              struct sk_buff *resp)
673 {
674         int rc;
675         struct digital_atr_req *atr_req;
676         size_t gb_len, min_size;
677 
678         if (IS_ERR(resp)) {
679                 rc = PTR_ERR(resp);
680                 resp = NULL;
681                 goto exit;
682         }
683 
684         if (!resp->len) {
685                 rc = -EIO;
686                 goto exit;
687         }
688 
689         if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) {
690                 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2;
691                 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_106A);
692         } else {
693                 min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1;
694                 digital_tg_set_rf_tech(ddev, NFC_DIGITAL_RF_TECH_212F);
695         }
696 
697         if (resp->len < min_size) {
698                 rc = -EIO;
699                 goto exit;
700         }
701 
702         ddev->curr_protocol = NFC_PROTO_NFC_DEP_MASK;
703 
704         rc = ddev->skb_check_crc(resp);
705         if (rc) {
706                 PROTOCOL_ERR("14.4.1.6");
707                 goto exit;
708         }
709 
710         rc = digital_skb_pull_dep_sod(ddev, resp);
711         if (rc) {
712                 PROTOCOL_ERR("14.4.1.2");
713                 goto exit;
714         }
715 
716         atr_req = (struct digital_atr_req *)resp->data;
717 
718         if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT ||
719             atr_req->cmd != DIGITAL_CMD_ATR_REQ) {
720                 rc = -EINVAL;
721                 goto exit;
722         }
723 
724         rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
725                                      NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED);
726         if (rc)
727                 goto exit;
728 
729         rc = digital_tg_send_atr_res(ddev, atr_req);
730         if (rc)
731                 goto exit;
732 
733         gb_len = resp->len - sizeof(struct digital_atr_req);
734         rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
735                               NFC_COMM_PASSIVE, atr_req->gb, gb_len);
736         if (rc)
737                 goto exit;
738 
739         ddev->poll_tech_count = 0;
740 
741         rc = 0;
742 exit:
743         if (rc)
744                 digital_poll_next_tech(ddev);
745 
746         dev_kfree_skb(resp);
747 }
748 

~ [ 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