aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc/st21nfca
diff options
context:
space:
mode:
authorChristophe Ricard <christophe.ricard@gmail.com>2014-05-20 16:21:59 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-07-22 19:14:41 -0400
commit1892bf844ea0261736bd5e75546fc996e9daeedf (patch)
treed86f6354b212c50f75225b1bc8524ef70c243bda /drivers/nfc/st21nfca
parentd57d74eb7626a2aeefad47a8d4246e9daf2199f5 (diff)
NFC: st21nfca: Adding P2P support to st21nfca in Initiator & Target mode
Support for Initiator and Target mode with ISO18092 commands support: - ATR_REQ/ATR_RES - PSL_REQ/PSL_RES - DEP_REQ/DEP_RES Work based on net/nfc/digital_dep.c. st21nfca is using: - Gate reader F for P2P in initiator mode. - Gate card F for P2P in target mode. Felica tag and p2p are differentiated with NFCID2. When starting with 01FE it is acting in p2p mode. On complete_target_discovered on ST21NFCA_RF_READER_F_GATE supported_protocols is set to NFC_PROTO_NFC_DEP_MASK for P2P. Tested against: Nexus S, Galaxy S2, Galaxy S3, Galaxy S3 Mini, Nexus 4 & Nexus 5. Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc/st21nfca')
-rw-r--r--drivers/nfc/st21nfca/Makefile2
-rw-r--r--drivers/nfc/st21nfca/st21nfca.c264
-rw-r--r--drivers/nfc/st21nfca/st21nfca.h26
-rw-r--r--drivers/nfc/st21nfca/st21nfca_dep.c661
-rw-r--r--drivers/nfc/st21nfca/st21nfca_dep.h43
5 files changed, 993 insertions, 3 deletions
diff --git a/drivers/nfc/st21nfca/Makefile b/drivers/nfc/st21nfca/Makefile
index 038ed093a119..db7a38ae05f7 100644
--- a/drivers/nfc/st21nfca/Makefile
+++ b/drivers/nfc/st21nfca/Makefile
@@ -4,5 +4,5 @@
4 4
5st21nfca_i2c-objs = i2c.o 5st21nfca_i2c-objs = i2c.o
6 6
7obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o 7obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o st21nfca_dep.o
8obj-$(CONFIG_NFC_ST21NFCA_I2C) += st21nfca_i2c.o 8obj-$(CONFIG_NFC_ST21NFCA_I2C) += st21nfca_i2c.o
diff --git a/drivers/nfc/st21nfca/st21nfca.c b/drivers/nfc/st21nfca/st21nfca.c
index 7ff1dcdd16ba..a902b0551c86 100644
--- a/drivers/nfc/st21nfca/st21nfca.c
+++ b/drivers/nfc/st21nfca/st21nfca.c
@@ -22,6 +22,7 @@
22#include <net/nfc/llc.h> 22#include <net/nfc/llc.h>
23 23
24#include "st21nfca.h" 24#include "st21nfca.h"
25#include "st21nfca_dep.h"
25 26
26#define DRIVER_DESC "HCI NFC driver for ST21NFCA" 27#define DRIVER_DESC "HCI NFC driver for ST21NFCA"
27 28
@@ -73,6 +74,7 @@ static struct nfc_hci_gate st21nfca_gates[] = {
73 {ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE}, 74 {ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
74 {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, 75 {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE},
75 {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, 76 {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
77 {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE},
76}; 78};
77 79
78struct st21nfca_pipe_info { 80struct st21nfca_pipe_info {
@@ -300,6 +302,9 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
300 u32 im_protocols, u32 tm_protocols) 302 u32 im_protocols, u32 tm_protocols)
301{ 303{
302 int r; 304 int r;
305 u32 pol_req;
306 u8 param[19];
307 struct sk_buff *datarate_skb;
303 308
304 pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", 309 pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n",
305 __func__, im_protocols, tm_protocols); 310 __func__, im_protocols, tm_protocols);
@@ -332,6 +337,31 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
332 ST21NFCA_RF_READER_F_GATE); 337 ST21NFCA_RF_READER_F_GATE);
333 if (r < 0) 338 if (r < 0)
334 return r; 339 return r;
340 } else {
341 hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
342 &hdev->gb_len);
343
344 if (hdev->gb == NULL || hdev->gb_len == 0) {
345 im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
346 tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
347 }
348
349 param[0] = ST21NFCA_RF_READER_F_DATARATE_106 |
350 ST21NFCA_RF_READER_F_DATARATE_212 |
351 ST21NFCA_RF_READER_F_DATARATE_424;
352 r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
353 ST21NFCA_RF_READER_F_DATARATE,
354 param, 1);
355 if (r < 0)
356 return r;
357
358 pol_req =
359 be32_to_cpu(ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
360 r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
361 ST21NFCA_RF_READER_F_POL_REQ,
362 (u8 *) &pol_req, 4);
363 if (r < 0)
364 return r;
335 } 365 }
336 366
337 if ((ST21NFCA_RF_READER_14443_3_A_GATE & im_protocols) == 0) { 367 if ((ST21NFCA_RF_READER_14443_3_A_GATE & im_protocols) == 0) {
@@ -354,6 +384,95 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
354 nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, 384 nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
355 NFC_HCI_EVT_END_OPERATION, NULL, 0); 385 NFC_HCI_EVT_END_OPERATION, NULL, 0);
356 } 386 }
387
388 if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
389 r = nfc_hci_get_param(hdev, ST21NFCA_RF_CARD_F_GATE,
390 ST21NFCA_RF_CARD_F_DATARATE,
391 &datarate_skb);
392 if (r < 0)
393 return r;
394
395 /* Configure the maximum supported datarate to 424Kbps */
396 if (datarate_skb->len > 0 &&
397 datarate_skb->data[0] !=
398 ST21NFCA_RF_CARD_F_DATARATE_212_424) {
399 param[0] = ST21NFCA_RF_CARD_F_DATARATE_212_424;
400 r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
401 ST21NFCA_RF_CARD_F_DATARATE,
402 param, 1);
403 if (r < 0)
404 return r;
405 }
406
407 /*
408 * Configure sens_res
409 *
410 * NFC Forum Digital Spec Table 7:
411 * NFCID1 size: triple (10 bytes)
412 */
413 param[0] = 0x00;
414 param[1] = 0x08;
415 r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
416 ST21NFCA_RF_CARD_F_SENS_RES, param, 2);
417 if (r < 0)
418 return r;
419
420 /*
421 * Configure sel_res
422 *
423 * NFC Forum Digistal Spec Table 17:
424 * b3 set to 0b (value b7-b6):
425 * - 10b: Configured for NFC-DEP Protocol
426 */
427 param[0] = 0x40;
428 r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
429 ST21NFCA_RF_CARD_F_SEL_RES, param, 1);
430 if (r < 0)
431 return r;
432
433 /* Configure NFCID1 Random uid */
434 r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
435 ST21NFCA_RF_CARD_F_NFCID1, NULL, 0);
436 if (r < 0)
437 return r;
438
439 /* Configure NFCID2_LIST */
440 /* System Code */
441 param[0] = 0x00;
442 param[1] = 0x00;
443 /* NFCID2 */
444 param[2] = 0x01;
445 param[3] = 0xfe;
446 param[4] = 'S';
447 param[5] = 'T';
448 param[6] = 'M';
449 param[7] = 'i';
450 param[8] = 'c';
451 param[9] = 'r';
452 /* 8 byte Pad bytes used for polling respone frame */
453
454 /*
455 * Configuration byte:
456 * - bit 0: define the default NFCID2 entry used when the
457 * system code is equal to 'FFFF'
458 * - bit 1: use a random value for lowest 6 bytes of
459 * NFCID2 value
460 * - bit 2: ignore polling request frame if request code
461 * is equal to '01'
462 * - Other bits are RFU
463 */
464 param[18] = 0x01;
465 r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
466 ST21NFCA_RF_CARD_F_NFCID2_LIST, param,
467 19);
468 if (r < 0)
469 return r;
470
471 param[0] = 0x02;
472 r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
473 ST21NFCA_RF_CARD_F_MODE, param, 1);
474 }
475
357 return r; 476 return r;
358} 477}
359 478
@@ -458,6 +577,26 @@ exit:
458 return r; 577 return r;
459} 578}
460 579
580static int st21nfca_hci_dep_link_up(struct nfc_hci_dev *hdev,
581 struct nfc_target *target, u8 comm_mode,
582 u8 *gb, size_t gb_len)
583{
584 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
585
586 info->dep_info.idx = target->idx;
587 return st21nfca_im_send_atr_req(hdev, gb, gb_len);
588}
589
590static int st21nfca_hci_dep_link_down(struct nfc_hci_dev *hdev)
591{
592 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
593
594 info->state = ST21NFCA_ST_READY;
595
596 return nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
597 ST21NFCA_DM_DISCONNECT, NULL, 0, NULL);
598}
599
461static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, 600static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
462 struct nfc_target *target) 601 struct nfc_target *target)
463{ 602{
@@ -512,6 +651,69 @@ static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
512 return 0; 651 return 0;
513} 652}
514 653
654static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev,
655 u8 gate,
656 struct nfc_target *target)
657{
658 int r;
659 struct sk_buff *nfcid2_skb = NULL, *nfcid1_skb;
660
661 if (gate == ST21NFCA_RF_READER_F_GATE) {
662 r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
663 ST21NFCA_RF_READER_F_NFCID2, &nfcid2_skb);
664 if (r < 0)
665 goto exit;
666
667 if (nfcid2_skb->len > NFC_SENSF_RES_MAXSIZE) {
668 r = -EPROTO;
669 goto exit;
670 }
671
672 /*
673 * - After the recepton of polling response for type F frame
674 * at 212 or 424 Kbit/s, NFCID2 registry parameters will be
675 * updated.
676 * - After the reception of SEL_RES with NFCIP-1 compliant bit
677 * set for type A frame NFCID1 will be updated
678 */
679 if (nfcid2_skb->len > 0) {
680 /* P2P in type F */
681 memcpy(target->sensf_res, nfcid2_skb->data,
682 nfcid2_skb->len);
683 target->sensf_res_len = nfcid2_skb->len;
684 /* NFC Forum Digital Protocol Table 44 */
685 if (target->sensf_res[0] == 0x01 &&
686 target->sensf_res[1] == 0xfe)
687 target->supported_protocols =
688 NFC_PROTO_NFC_DEP_MASK;
689 else
690 target->supported_protocols =
691 NFC_PROTO_FELICA_MASK;
692 } else {
693 /* P2P in type A */
694 r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
695 ST21NFCA_RF_READER_F_NFCID1,
696 &nfcid1_skb);
697 if (r < 0)
698 goto exit;
699
700 if (nfcid1_skb->len > NFC_NFCID1_MAXSIZE) {
701 r = -EPROTO;
702 goto exit;
703 }
704 memcpy(target->sensf_res, nfcid1_skb->data,
705 nfcid1_skb->len);
706 target->sensf_res_len = nfcid1_skb->len;
707 target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
708 }
709 target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE;
710 }
711 r = 1;
712exit:
713 kfree_skb(nfcid2_skb);
714 return r;
715}
716
515#define ST21NFCA_CB_TYPE_READER_ISO15693 1 717#define ST21NFCA_CB_TYPE_READER_ISO15693 1
516static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb, 718static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb,
517 int err) 719 int err)
@@ -548,6 +750,9 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
548 750
549 switch (target->hci_reader_gate) { 751 switch (target->hci_reader_gate) {
550 case ST21NFCA_RF_READER_F_GATE: 752 case ST21NFCA_RF_READER_F_GATE:
753 if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK)
754 return st21nfca_im_send_dep_req(hdev, skb);
755
551 *skb_push(skb, 1) = 0x1a; 756 *skb_push(skb, 1) = 0x1a;
552 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, 757 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
553 ST21NFCA_WR_XCHG_DATA, skb->data, 758 ST21NFCA_WR_XCHG_DATA, skb->data,
@@ -576,6 +781,11 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
576 } 781 }
577} 782}
578 783
784static int st21nfca_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
785{
786 return st21nfca_tm_send_dep_res(hdev, skb);
787}
788
579static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev, 789static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
580 struct nfc_target *target) 790 struct nfc_target *target)
581{ 791{
@@ -601,6 +811,50 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
601 } 811 }
602} 812}
603 813
814/*
815 * Returns:
816 * <= 0: driver handled the event, skb consumed
817 * 1: driver does not handle the event, please do standard processing
818 */
819static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate,
820 u8 event, struct sk_buff *skb)
821{
822 int r;
823 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
824
825 pr_debug("hci event: %d\n", event);
826
827 switch (event) {
828 case ST21NFCA_EVT_CARD_ACTIVATED:
829 if (gate == ST21NFCA_RF_CARD_F_GATE)
830 info->dep_info.curr_nfc_dep_pni = 0;
831 break;
832 case ST21NFCA_EVT_CARD_DEACTIVATED:
833 break;
834 case ST21NFCA_EVT_FIELD_ON:
835 break;
836 case ST21NFCA_EVT_FIELD_OFF:
837 break;
838 case ST21NFCA_EVT_SEND_DATA:
839 if (gate == ST21NFCA_RF_CARD_F_GATE) {
840 r = st21nfca_tm_event_send_data(hdev, skb, gate);
841 if (r < 0)
842 goto exit;
843 return 0;
844 } else {
845 info->dep_info.curr_nfc_dep_pni = 0;
846 return 1;
847 }
848 break;
849 default:
850 return 1;
851 }
852 kfree_skb(skb);
853 return 0;
854exit:
855 return r;
856}
857
604static struct nfc_hci_ops st21nfca_hci_ops = { 858static struct nfc_hci_ops st21nfca_hci_ops = {
605 .open = st21nfca_hci_open, 859 .open = st21nfca_hci_open,
606 .close = st21nfca_hci_close, 860 .close = st21nfca_hci_close,
@@ -609,9 +863,14 @@ static struct nfc_hci_ops st21nfca_hci_ops = {
609 .xmit = st21nfca_hci_xmit, 863 .xmit = st21nfca_hci_xmit,
610 .start_poll = st21nfca_hci_start_poll, 864 .start_poll = st21nfca_hci_start_poll,
611 .stop_poll = st21nfca_hci_stop_poll, 865 .stop_poll = st21nfca_hci_stop_poll,
866 .dep_link_up = st21nfca_hci_dep_link_up,
867 .dep_link_down = st21nfca_hci_dep_link_down,
612 .target_from_gate = st21nfca_hci_target_from_gate, 868 .target_from_gate = st21nfca_hci_target_from_gate,
869 .complete_target_discovered = st21nfca_hci_complete_target_discovered,
613 .im_transceive = st21nfca_hci_im_transceive, 870 .im_transceive = st21nfca_hci_im_transceive,
871 .tm_send = st21nfca_hci_tm_send,
614 .check_presence = st21nfca_hci_check_presence, 872 .check_presence = st21nfca_hci_check_presence,
873 .event_received = st21nfca_hci_event_received,
615}; 874};
616 875
617int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, 876int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
@@ -656,7 +915,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
656 NFC_PROTO_FELICA_MASK | 915 NFC_PROTO_FELICA_MASK |
657 NFC_PROTO_ISO14443_MASK | 916 NFC_PROTO_ISO14443_MASK |
658 NFC_PROTO_ISO14443_B_MASK | 917 NFC_PROTO_ISO14443_B_MASK |
659 NFC_PROTO_ISO15693_MASK; 918 NFC_PROTO_ISO15693_MASK |
919 NFC_PROTO_NFC_DEP_MASK;
660 920
661 set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); 921 set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);
662 922
@@ -679,6 +939,7 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
679 goto err_regdev; 939 goto err_regdev;
680 940
681 *hdev = info->hdev; 941 *hdev = info->hdev;
942 st21nfca_dep_init(info->hdev);
682 943
683 return 0; 944 return 0;
684 945
@@ -696,6 +957,7 @@ void st21nfca_hci_remove(struct nfc_hci_dev *hdev)
696{ 957{
697 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); 958 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
698 959
960 st21nfca_dep_deinit(hdev);
699 nfc_hci_unregister_device(hdev); 961 nfc_hci_unregister_device(hdev);
700 nfc_hci_free_device(hdev); 962 nfc_hci_free_device(hdev);
701 kfree(info); 963 kfree(info);
diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h
index 334cd90bcc8c..96fe5a62dc0d 100644
--- a/drivers/nfc/st21nfca/st21nfca.h
+++ b/drivers/nfc/st21nfca/st21nfca.h
@@ -19,6 +19,8 @@
19 19
20#include <net/nfc/hci.h> 20#include <net/nfc/hci.h>
21 21
22#include "st21nfca_dep.h"
23
22#define HCI_MODE 0 24#define HCI_MODE 0
23 25
24/* framing in HCI mode */ 26/* framing in HCI mode */
@@ -73,7 +75,8 @@ struct st21nfca_hci_info {
73 data_exchange_cb_t async_cb; 75 data_exchange_cb_t async_cb;
74 void *async_cb_context; 76 void *async_cb_context;
75 77
76} __packed; 78 struct st21nfca_dep_info dep_info;
79};
77 80
78/* Reader RF commands */ 81/* Reader RF commands */
79#define ST21NFCA_WR_XCHG_DATA 0x10 82#define ST21NFCA_WR_XCHG_DATA 0x10
@@ -83,5 +86,26 @@ struct st21nfca_hci_info {
83#define ST21NFCA_RF_READER_F_DATARATE_106 0x01 86#define ST21NFCA_RF_READER_F_DATARATE_106 0x01
84#define ST21NFCA_RF_READER_F_DATARATE_212 0x02 87#define ST21NFCA_RF_READER_F_DATARATE_212 0x02
85#define ST21NFCA_RF_READER_F_DATARATE_424 0x04 88#define ST21NFCA_RF_READER_F_DATARATE_424 0x04
89#define ST21NFCA_RF_READER_F_POL_REQ 0x02
90#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000
91#define ST21NFCA_RF_READER_F_NFCID2 0x03
92#define ST21NFCA_RF_READER_F_NFCID1 0x04
93#define ST21NFCA_RF_READER_F_SENS_RES 0x05
94
95#define ST21NFCA_RF_CARD_F_GATE 0x24
96#define ST21NFCA_RF_CARD_F_MODE 0x01
97#define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04
98#define ST21NFCA_RF_CARD_F_NFCID1 0x05
99#define ST21NFCA_RF_CARD_F_SENS_RES 0x06
100#define ST21NFCA_RF_CARD_F_SEL_RES 0x07
101#define ST21NFCA_RF_CARD_F_DATARATE 0x08
102#define ST21NFCA_RF_CARD_F_DATARATE_106 0x00
103#define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01
104
105#define ST21NFCA_EVT_SEND_DATA 0x10
106#define ST21NFCA_EVT_FIELD_ON 0x11
107#define ST21NFCA_EVT_CARD_DEACTIVATED 0x12
108#define ST21NFCA_EVT_CARD_ACTIVATED 0x13
109#define ST21NFCA_EVT_FIELD_OFF 0x14
86 110
87#endif /* __LOCAL_ST21NFCA_H_ */ 111#endif /* __LOCAL_ST21NFCA_H_ */
diff --git a/drivers/nfc/st21nfca/st21nfca_dep.c b/drivers/nfc/st21nfca/st21nfca_dep.c
new file mode 100644
index 000000000000..b2d9957b57f8
--- /dev/null
+++ b/drivers/nfc/st21nfca/st21nfca_dep.c
@@ -0,0 +1,661 @@
1/*
2 * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <net/nfc/hci.h>
18
19#include "st21nfca.h"
20#include "st21nfca_dep.h"
21
22#define ST21NFCA_NFCIP1_INITIATOR 0x00
23#define ST21NFCA_NFCIP1_REQ 0xd4
24#define ST21NFCA_NFCIP1_RES 0xd5
25#define ST21NFCA_NFCIP1_ATR_REQ 0x00
26#define ST21NFCA_NFCIP1_ATR_RES 0x01
27#define ST21NFCA_NFCIP1_PSL_REQ 0x04
28#define ST21NFCA_NFCIP1_PSL_RES 0x05
29#define ST21NFCA_NFCIP1_DEP_REQ 0x06
30#define ST21NFCA_NFCIP1_DEP_RES 0x07
31
32#define ST21NFCA_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
33#define ST21NFCA_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
34#define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
35 ((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
36#define ST21NFCA_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
37#define ST21NFCA_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
38#define ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT 0x10
39
40#define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
41 ((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
42
43#define ST21NFCA_NFC_DEP_PFB_I_PDU 0x00
44#define ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU 0x40
45#define ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
46
47#define ST21NFCA_ATR_REQ_MIN_SIZE 17
48#define ST21NFCA_ATR_REQ_MAX_SIZE 65
49#define ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B 0x30
50#define ST21NFCA_GB_BIT 0x02
51
52#define ST21NFCA_EVT_CARD_F_BITRATE 0x16
53#define ST21NFCA_EVT_READER_F_BITRATE 0x13
54#define ST21NFCA_PSL_REQ_SEND_SPEED(brs) (brs & 0x38)
55#define ST21NFCA_PSL_REQ_RECV_SPEED(brs) (brs & 0x07)
56#define ST21NFCA_PP2LRI(pp) ((pp & 0x30) >> 4)
57#define ST21NFCA_CARD_BITRATE_212 0x01
58#define ST21NFCA_CARD_BITRATE_424 0x02
59
60#define ST21NFCA_DEFAULT_TIMEOUT 0x0a
61
62
63#define PROTOCOL_ERR(req) pr_err("%d: ST21NFCA Protocol error: %s\n", \
64 __LINE__, req)
65
66struct st21nfca_atr_req {
67 u8 length;
68 u8 cmd0;
69 u8 cmd1;
70 u8 nfcid3[NFC_NFCID3_MAXSIZE];
71 u8 did;
72 u8 bsi;
73 u8 bri;
74 u8 ppi;
75 u8 gbi[0];
76} __packed;
77
78struct st21nfca_atr_res {
79 u8 length;
80 u8 cmd0;
81 u8 cmd1;
82 u8 nfcid3[NFC_NFCID3_MAXSIZE];
83 u8 did;
84 u8 bsi;
85 u8 bri;
86 u8 to;
87 u8 ppi;
88 u8 gbi[0];
89} __packed;
90
91struct st21nfca_psl_req {
92 u8 length;
93 u8 cmd0;
94 u8 cmd1;
95 u8 did;
96 u8 brs;
97 u8 fsl;
98} __packed;
99
100struct st21nfca_psl_res {
101 u8 length;
102 u8 cmd0;
103 u8 cmd1;
104 u8 did;
105} __packed;
106
107struct st21nfca_dep_req_res {
108 u8 length;
109 u8 cmd0;
110 u8 cmd1;
111 u8 pfb;
112 u8 did;
113 u8 nad;
114} __packed;
115
116static void st21nfca_tx_work(struct work_struct *work)
117{
118 struct st21nfca_hci_info *info = container_of(work,
119 struct st21nfca_hci_info,
120 dep_info.tx_work);
121
122 struct nfc_dev *dev;
123 struct sk_buff *skb;
124 if (info) {
125 dev = info->hdev->ndev;
126 skb = info->dep_info.tx_pending;
127
128 device_lock(&dev->dev);
129
130 nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
131 ST21NFCA_WR_XCHG_DATA,
132 skb->data, skb->len,
133 info->async_cb, info);
134 device_unlock(&dev->dev);
135 kfree_skb(skb);
136 }
137}
138
139static void st21nfca_im_send_pdu(struct st21nfca_hci_info *info,
140 struct sk_buff *skb)
141{
142 info->dep_info.tx_pending = skb;
143 schedule_work(&info->dep_info.tx_work);
144}
145
146static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
147 struct st21nfca_atr_req *atr_req)
148{
149 struct st21nfca_atr_res *atr_res;
150 struct sk_buff *skb;
151 size_t gb_len;
152 int r;
153 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
154
155 gb_len = atr_req->length - sizeof(struct st21nfca_atr_req);
156 skb = alloc_skb(atr_req->length + 1, GFP_KERNEL);
157 if (!skb)
158 return -ENOMEM;
159
160 skb_put(skb, sizeof(struct st21nfca_atr_res));
161
162 atr_res = (struct st21nfca_atr_res *)skb->data;
163 memset(atr_res, 0, sizeof(struct st21nfca_atr_res));
164
165 atr_res->length = atr_req->length + 1;
166 atr_res->cmd0 = ST21NFCA_NFCIP1_RES;
167 atr_res->cmd1 = ST21NFCA_NFCIP1_ATR_RES;
168
169 memcpy(atr_res->nfcid3, atr_req->nfcid3, 6);
170 atr_res->bsi = 0x00;
171 atr_res->bri = 0x00;
172 atr_res->to = ST21NFCA_DEFAULT_TIMEOUT;
173 atr_res->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
174
175 if (gb_len) {
176 skb_put(skb, gb_len);
177
178 atr_res->ppi |= ST21NFCA_GB_BIT;
179 memcpy(atr_res->gbi, atr_req->gbi, gb_len);
180 r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi,
181 gb_len);
182 if (r < 0)
183 return r;
184 }
185
186 info->dep_info.curr_nfc_dep_pni = 0;
187
188 return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
189 ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
190}
191
192static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
193 struct sk_buff *skb)
194{
195 struct st21nfca_atr_req *atr_req;
196 size_t gb_len;
197 int r;
198
199 skb_trim(skb, skb->len - 1);
200 if (IS_ERR(skb)) {
201 r = PTR_ERR(skb);
202 goto exit;
203 }
204
205 if (!skb->len) {
206 r = -EIO;
207 goto exit;
208 }
209
210 if (skb->len < ST21NFCA_ATR_REQ_MIN_SIZE) {
211 r = -EPROTO;
212 goto exit;
213 }
214
215 atr_req = (struct st21nfca_atr_req *)skb->data;
216
217 r = st21nfca_tm_send_atr_res(hdev, atr_req);
218 if (r)
219 goto exit;
220
221 gb_len = skb->len - sizeof(struct st21nfca_atr_req);
222
223 r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
224 NFC_COMM_PASSIVE, atr_req->gbi, gb_len);
225 if (r)
226 goto exit;
227
228 r = 0;
229
230exit:
231 return r;
232}
233
234static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
235 struct st21nfca_psl_req *psl_req)
236{
237 struct st21nfca_psl_res *psl_res;
238 struct sk_buff *skb;
239 u8 bitrate[2] = {0, 0};
240
241 int r;
242
243 skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
244 if (!skb)
245 return -ENOMEM;
246 skb_put(skb, sizeof(struct st21nfca_psl_res));
247
248 psl_res = (struct st21nfca_psl_res *)skb->data;
249
250 psl_res->length = sizeof(struct st21nfca_psl_res);
251 psl_res->cmd0 = ST21NFCA_NFCIP1_RES;
252 psl_res->cmd1 = ST21NFCA_NFCIP1_PSL_RES;
253 psl_res->did = psl_req->did;
254
255 r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
256 ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
257
258 /*
259 * ST21NFCA only support P2P passive.
260 * PSL_REQ BRS value != 0 has only a meaning to
261 * change technology to type F.
262 * We change to BITRATE 424Kbits.
263 * In other case switch to BITRATE 106Kbits.
264 */
265 if (ST21NFCA_PSL_REQ_SEND_SPEED(psl_req->brs) &&
266 ST21NFCA_PSL_REQ_RECV_SPEED(psl_req->brs)) {
267 bitrate[0] = ST21NFCA_CARD_BITRATE_424;
268 bitrate[1] = ST21NFCA_CARD_BITRATE_424;
269 }
270
271 /* Send an event to change bitrate change event to card f */
272 return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
273 ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
274}
275
276static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
277 struct sk_buff *skb)
278{
279 struct st21nfca_psl_req *psl_req;
280 int r;
281
282 skb_trim(skb, skb->len - 1);
283 if (IS_ERR(skb)) {
284 r = PTR_ERR(skb);
285 skb = NULL;
286 goto exit;
287 }
288
289 if (!skb->len) {
290 r = -EIO;
291 goto exit;
292 }
293
294 psl_req = (struct st21nfca_psl_req *)skb->data;
295
296 if (skb->len < sizeof(struct st21nfca_psl_req)) {
297 r = -EIO;
298 goto exit;
299 }
300
301 r = st21nfca_tm_send_psl_res(hdev, psl_req);
302exit:
303 return r;
304}
305
306int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
307{
308 int r;
309 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
310
311 *skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
312 *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_RES;
313 *skb_push(skb, 1) = ST21NFCA_NFCIP1_RES;
314 *skb_push(skb, 1) = skb->len;
315
316 r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
317 ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
318 kfree_skb(skb);
319
320 return r;
321}
322EXPORT_SYMBOL(st21nfca_tm_send_dep_res);
323
324static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
325 struct sk_buff *skb)
326{
327 struct st21nfca_dep_req_res *dep_req;
328 u8 size;
329 int r;
330 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
331
332 skb_trim(skb, skb->len - 1);
333 if (IS_ERR(skb)) {
334 r = PTR_ERR(skb);
335 skb = NULL;
336 goto exit;
337 }
338
339 size = 4;
340
341 dep_req = (struct st21nfca_dep_req_res *)skb->data;
342 if (skb->len < size) {
343 r = -EIO;
344 goto exit;
345 }
346
347 if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_req->pfb))
348 size++;
349 if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_req->pfb))
350 size++;
351
352 if (skb->len < size) {
353 r = -EIO;
354 goto exit;
355 }
356
357 /* Receiving DEP_REQ - Decoding */
358 switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
359 case ST21NFCA_NFC_DEP_PFB_I_PDU:
360 info->dep_info.curr_nfc_dep_pni =
361 ST21NFCA_NFC_DEP_PFB_PNI(dep_req->pfb);
362 break;
363 case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
364 pr_err("Received a ACK/NACK PDU\n");
365 break;
366 case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
367 pr_err("Received a SUPERVISOR PDU\n");
368 break;
369 }
370
371 if (IS_ERR(skb)) {
372 r = PTR_ERR(skb);
373 skb = NULL;
374 goto exit;
375 }
376
377 skb_pull(skb, size);
378
379 return nfc_tm_data_received(hdev->ndev, skb);
380exit:
381 return r;
382}
383
384int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev, struct sk_buff *skb,
385 u8 gate)
386{
387 u8 cmd0, cmd1;
388 int r;
389
390 cmd0 = skb->data[1];
391 switch (cmd0) {
392 case ST21NFCA_NFCIP1_REQ:
393 cmd1 = skb->data[2];
394 switch (cmd1) {
395 case ST21NFCA_NFCIP1_ATR_REQ:
396 r = st21nfca_tm_recv_atr_req(hdev, skb);
397 break;
398 case ST21NFCA_NFCIP1_PSL_REQ:
399 r = st21nfca_tm_recv_psl_req(hdev, skb);
400 break;
401 case ST21NFCA_NFCIP1_DEP_REQ:
402 r = st21nfca_tm_recv_dep_req(hdev, skb);
403 break;
404 default:
405 return 1;
406 }
407 default:
408 return 1;
409 }
410 return r;
411}
412EXPORT_SYMBOL(st21nfca_tm_event_send_data);
413
414static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
415 u8 bri, u8 lri)
416{
417 struct sk_buff *skb;
418 struct st21nfca_psl_req *psl_req;
419 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
420
421 skb =
422 alloc_skb(sizeof(struct st21nfca_psl_req) + 1, GFP_KERNEL);
423 if (!skb)
424 return;
425 skb_reserve(skb, 1);
426
427 skb_put(skb, sizeof(struct st21nfca_psl_req));
428 psl_req = (struct st21nfca_psl_req *) skb->data;
429
430 psl_req->length = sizeof(struct st21nfca_psl_req);
431 psl_req->cmd0 = ST21NFCA_NFCIP1_REQ;
432 psl_req->cmd1 = ST21NFCA_NFCIP1_PSL_REQ;
433 psl_req->did = did;
434 psl_req->brs = (0x30 & bsi << 4) | (bri & 0x03);
435 psl_req->fsl = lri;
436
437 *skb_push(skb, 1) = info->dep_info.to | 0x10;
438
439 st21nfca_im_send_pdu(info, skb);
440
441 kfree_skb(skb);
442}
443
444#define ST21NFCA_CB_TYPE_READER_F 1
445static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
446 int err)
447{
448 struct st21nfca_hci_info *info = context;
449 struct st21nfca_atr_res *atr_res;
450 int r;
451
452 if (err != 0)
453 return;
454
455 if (IS_ERR(skb))
456 return;
457
458 switch (info->async_cb_type) {
459 case ST21NFCA_CB_TYPE_READER_F:
460 skb_trim(skb, skb->len - 1);
461 atr_res = (struct st21nfca_atr_res *)skb->data;
462 r = nfc_set_remote_general_bytes(info->hdev->ndev,
463 atr_res->gbi,
464 skb->len - sizeof(struct st21nfca_atr_res));
465 if (r < 0)
466 return;
467
468 if (atr_res->to >= 0x0e)
469 info->dep_info.to = 0x0e;
470 else
471 info->dep_info.to = atr_res->to + 1;
472
473 info->dep_info.to |= 0x10;
474
475 r = nfc_dep_link_is_up(info->hdev->ndev, info->dep_info.idx,
476 NFC_COMM_PASSIVE, NFC_RF_INITIATOR);
477 if (r < 0)
478 return;
479
480 info->dep_info.curr_nfc_dep_pni = 0;
481 if (ST21NFCA_PP2LRI(atr_res->ppi) != info->dep_info.lri)
482 st21nfca_im_send_psl_req(info->hdev, atr_res->did,
483 atr_res->bsi, atr_res->bri,
484 ST21NFCA_PP2LRI(atr_res->ppi));
485 break;
486 default:
487 if (err == 0)
488 kfree_skb(skb);
489 break;
490 }
491}
492
493int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
494{
495 struct sk_buff *skb;
496 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
497 struct st21nfca_atr_req *atr_req;
498 struct nfc_target *target;
499 uint size;
500
501 info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
502 size = ST21NFCA_ATR_REQ_MIN_SIZE + gb_len;
503 if (size > ST21NFCA_ATR_REQ_MAX_SIZE) {
504 PROTOCOL_ERR("14.6.1.1");
505 return -EINVAL;
506 }
507
508 skb =
509 alloc_skb(sizeof(struct st21nfca_atr_req) + gb_len + 1, GFP_KERNEL);
510 if (!skb)
511 return -ENOMEM;
512
513 skb_reserve(skb, 1);
514
515 skb_put(skb, sizeof(struct st21nfca_atr_req));
516
517 atr_req = (struct st21nfca_atr_req *)skb->data;
518 memset(atr_req, 0, sizeof(struct st21nfca_atr_req));
519
520 atr_req->cmd0 = ST21NFCA_NFCIP1_REQ;
521 atr_req->cmd1 = ST21NFCA_NFCIP1_ATR_REQ;
522 memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
523 target = hdev->ndev->targets;
524
525 if (target->sensf_res)
526 memcpy(atr_req->nfcid3, target->sensf_res,
527 target->sensf_res_len);
528 else
529 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
530
531 atr_req->did = 0x0;
532
533 atr_req->bsi = 0x00;
534 atr_req->bri = 0x00;
535 atr_req->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
536 if (gb_len) {
537 atr_req->ppi |= ST21NFCA_GB_BIT;
538 memcpy(skb_put(skb, gb_len), gb, gb_len);
539 }
540 atr_req->length = sizeof(struct st21nfca_atr_req) + hdev->gb_len;
541
542 *skb_push(skb, 1) = info->dep_info.to | 0x10; /* timeout */
543
544 info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
545 info->async_cb_context = info;
546 info->async_cb = st21nfca_im_recv_atr_res_cb;
547 info->dep_info.bri = atr_req->bri;
548 info->dep_info.bsi = atr_req->bsi;
549 info->dep_info.lri = ST21NFCA_PP2LRI(atr_req->ppi);
550
551 return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
552 ST21NFCA_WR_XCHG_DATA, skb->data,
553 skb->len, info->async_cb, info);
554}
555EXPORT_SYMBOL(st21nfca_im_send_atr_req);
556
557static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
558 int err)
559{
560 struct st21nfca_hci_info *info = context;
561 struct st21nfca_dep_req_res *dep_res;
562
563 int size;
564
565 if (err != 0)
566 return;
567
568 if (IS_ERR(skb))
569 return;
570
571 switch (info->async_cb_type) {
572 case ST21NFCA_CB_TYPE_READER_F:
573 dep_res = (struct st21nfca_dep_req_res *)skb->data;
574
575 size = 3;
576 if (skb->len < size)
577 goto exit;
578
579 if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_res->pfb))
580 size++;
581 if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_res->pfb))
582 size++;
583
584 if (skb->len < size)
585 goto exit;
586
587 skb_trim(skb, skb->len - 1);
588
589 /* Receiving DEP_REQ - Decoding */
590 switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_res->pfb)) {
591 case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
592 pr_err("Received a ACK/NACK PDU\n");
593 case ST21NFCA_NFC_DEP_PFB_I_PDU:
594 info->dep_info.curr_nfc_dep_pni =
595 ST21NFCA_NFC_DEP_PFB_PNI(dep_res->pfb + 1);
596 size++;
597 skb_pull(skb, size);
598 nfc_tm_data_received(info->hdev->ndev, skb);
599 break;
600 case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
601 pr_err("Received a SUPERVISOR PDU\n");
602 skb_pull(skb, size);
603 *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
604 *skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
605 *skb_push(skb, 1) = skb->len;
606 *skb_push(skb, 1) = info->dep_info.to | 0x10;
607
608 st21nfca_im_send_pdu(info, skb);
609 break;
610 }
611
612 return;
613 default:
614 break;
615 }
616
617exit:
618 if (err == 0)
619 kfree_skb(skb);
620}
621
622int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)
623{
624 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
625
626 info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
627 info->async_cb_context = info;
628 info->async_cb = st21nfca_im_recv_dep_res_cb;
629
630 *skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
631 *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
632 *skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
633 *skb_push(skb, 1) = skb->len;
634
635 *skb_push(skb, 1) = info->dep_info.to | 0x10;
636
637 return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
638 ST21NFCA_WR_XCHG_DATA,
639 skb->data, skb->len,
640 info->async_cb, info);
641}
642EXPORT_SYMBOL(st21nfca_im_send_dep_req);
643
644void st21nfca_dep_init(struct nfc_hci_dev *hdev)
645{
646 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
647
648 INIT_WORK(&info->dep_info.tx_work, st21nfca_tx_work);
649 info->dep_info.curr_nfc_dep_pni = 0;
650 info->dep_info.idx = 0;
651 info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
652}
653EXPORT_SYMBOL(st21nfca_dep_init);
654
655void st21nfca_dep_deinit(struct nfc_hci_dev *hdev)
656{
657 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
658
659 cancel_work_sync(&info->dep_info.tx_work);
660}
661EXPORT_SYMBOL(st21nfca_dep_deinit);
diff --git a/drivers/nfc/st21nfca/st21nfca_dep.h b/drivers/nfc/st21nfca/st21nfca_dep.h
new file mode 100644
index 000000000000..ca213dee9c6e
--- /dev/null
+++ b/drivers/nfc/st21nfca/st21nfca_dep.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __ST21NFCA_DEP_H
18#define __ST21NFCA_DEP_H
19
20#include <linux/skbuff.h>
21#include <linux/workqueue.h>
22
23struct st21nfca_dep_info {
24 struct sk_buff *tx_pending;
25 struct work_struct tx_work;
26 u8 curr_nfc_dep_pni;
27 u32 idx;
28 u8 to;
29 u8 did;
30 u8 bsi;
31 u8 bri;
32 u8 lri;
33} __packed;
34
35int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev, struct sk_buff *skb,
36 u8 gate);
37int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb);
38
39int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len);
40int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb);
41void st21nfca_dep_init(struct nfc_hci_dev *hdev);
42void st21nfca_dep_deinit(struct nfc_hci_dev *hdev);
43#endif /* __ST21NFCA_DEP_H */