aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/digital.h1
-rw-r--r--net/nfc/digital_core.c20
-rw-r--r--net/nfc/digital_technology.c214
3 files changed, 233 insertions, 2 deletions
diff --git a/net/nfc/digital.h b/net/nfc/digital.h
index 3759add68b1b..71ad7eefddd4 100644
--- a/net/nfc/digital.h
+++ b/net/nfc/digital.h
@@ -71,6 +71,7 @@ static inline int digital_in_send_cmd(struct nfc_digital_dev *ddev,
71void digital_poll_next_tech(struct nfc_digital_dev *ddev); 71void digital_poll_next_tech(struct nfc_digital_dev *ddev);
72 72
73int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech); 73int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech);
74int digital_in_send_sensb_req(struct nfc_digital_dev *ddev, u8 rf_tech);
74int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech); 75int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech);
75int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech); 76int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech);
76 77
diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c
index e01e15dbf1ab..b105cfb00e76 100644
--- a/net/nfc/digital_core.c
+++ b/net/nfc/digital_core.c
@@ -22,6 +22,8 @@
22#define DIGITAL_PROTO_NFCA_RF_TECH \ 22#define DIGITAL_PROTO_NFCA_RF_TECH \
23 (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK) 23 (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK)
24 24
25#define DIGITAL_PROTO_NFCB_RF_TECH NFC_PROTO_ISO14443_B_MASK
26
25#define DIGITAL_PROTO_NFCF_RF_TECH \ 27#define DIGITAL_PROTO_NFCF_RF_TECH \
26 (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) 28 (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK)
27 29
@@ -345,6 +347,12 @@ int digital_target_found(struct nfc_digital_dev *ddev,
345 add_crc = digital_skb_add_crc_a; 347 add_crc = digital_skb_add_crc_a;
346 break; 348 break;
347 349
350 case NFC_PROTO_ISO14443_B:
351 framing = NFC_DIGITAL_FRAMING_NFCB_T4T;
352 check_crc = digital_skb_check_crc_b;
353 add_crc = digital_skb_add_crc_b;
354 break;
355
348 default: 356 default:
349 pr_err("Invalid protocol %d\n", protocol); 357 pr_err("Invalid protocol %d\n", protocol);
350 return -EINVAL; 358 return -EINVAL;
@@ -475,6 +483,10 @@ static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols,
475 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, 483 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A,
476 digital_in_send_sens_req); 484 digital_in_send_sens_req);
477 485
486 if (matching_im_protocols & DIGITAL_PROTO_NFCB_RF_TECH)
487 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106B,
488 digital_in_send_sensb_req);
489
478 if (matching_im_protocols & DIGITAL_PROTO_NFCF_RF_TECH) { 490 if (matching_im_protocols & DIGITAL_PROTO_NFCF_RF_TECH) {
479 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, 491 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F,
480 digital_in_send_sensf_req); 492 digital_in_send_sensf_req);
@@ -635,7 +647,8 @@ static void digital_in_send_complete(struct nfc_digital_dev *ddev, void *arg,
635 goto done; 647 goto done;
636 } 648 }
637 649
638 if (ddev->curr_protocol == NFC_PROTO_ISO14443) { 650 if ((ddev->curr_protocol == NFC_PROTO_ISO14443) ||
651 (ddev->curr_protocol == NFC_PROTO_ISO14443_B)) {
639 rc = digital_in_iso_dep_pull_sod(ddev, resp); 652 rc = digital_in_iso_dep_pull_sod(ddev, resp);
640 if (rc) 653 if (rc)
641 goto done; 654 goto done;
@@ -676,7 +689,8 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target,
676 goto exit; 689 goto exit;
677 } 690 }
678 691
679 if (ddev->curr_protocol == NFC_PROTO_ISO14443) { 692 if ((ddev->curr_protocol == NFC_PROTO_ISO14443) ||
693 (ddev->curr_protocol == NFC_PROTO_ISO14443_B)) {
680 rc = digital_in_iso_dep_push_sod(ddev, skb); 694 rc = digital_in_iso_dep_push_sod(ddev, skb);
681 if (rc) 695 if (rc)
682 goto exit; 696 goto exit;
@@ -747,6 +761,8 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
747 ddev->protocols |= NFC_PROTO_ISO15693_MASK; 761 ddev->protocols |= NFC_PROTO_ISO15693_MASK;
748 if (supported_protocols & NFC_PROTO_ISO14443_MASK) 762 if (supported_protocols & NFC_PROTO_ISO14443_MASK)
749 ddev->protocols |= NFC_PROTO_ISO14443_MASK; 763 ddev->protocols |= NFC_PROTO_ISO14443_MASK;
764 if (supported_protocols & NFC_PROTO_ISO14443_B_MASK)
765 ddev->protocols |= NFC_PROTO_ISO14443_B_MASK;
750 766
751 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; 767 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN;
752 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; 768 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN;
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index 278c3fed27e0..88e946adb7bf 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -41,6 +41,24 @@
41#define DIGITAL_MIFARE_READ_RES_LEN 16 41#define DIGITAL_MIFARE_READ_RES_LEN 16
42#define DIGITAL_MIFARE_ACK_RES 0x0A 42#define DIGITAL_MIFARE_ACK_RES 0x0A
43 43
44#define DIGITAL_CMD_SENSB_REQ 0x05
45#define DIGITAL_SENSB_ADVANCED BIT(5)
46#define DIGITAL_SENSB_EXTENDED BIT(4)
47#define DIGITAL_SENSB_ALLB_REQ BIT(3)
48#define DIGITAL_SENSB_N(n) ((n) & 0x7)
49
50#define DIGITAL_CMD_SENSB_RES 0x50
51
52#define DIGITAL_CMD_ATTRIB_REQ 0x1D
53#define DIGITAL_ATTRIB_P1_TR0_DEFAULT (0x0 << 6)
54#define DIGITAL_ATTRIB_P1_TR1_DEFAULT (0x0 << 4)
55#define DIGITAL_ATTRIB_P1_SUPRESS_EOS BIT(3)
56#define DIGITAL_ATTRIB_P1_SUPRESS_SOS BIT(2)
57#define DIGITAL_ATTRIB_P2_LISTEN_POLL_1 (0x0 << 6)
58#define DIGITAL_ATTRIB_P2_POLL_LISTEN_1 (0x0 << 4)
59#define DIGITAL_ATTRIB_P2_MAX_FRAME_256 0x8
60#define DIGITAL_ATTRIB_P4_DID(n) ((n) & 0xf)
61
44#define DIGITAL_CMD_SENSF_REQ 0x00 62#define DIGITAL_CMD_SENSF_REQ 0x00
45#define DIGITAL_CMD_SENSF_RES 0x01 63#define DIGITAL_CMD_SENSF_RES 0x01
46 64
@@ -75,6 +93,7 @@ static const u8 digital_ats_fsc[] = {
75}; 93};
76 94
77#define DIGITAL_ATS_FSCI(t0) ((t0) & 0x0F) 95#define DIGITAL_ATS_FSCI(t0) ((t0) & 0x0F)
96#define DIGITAL_SENSB_FSCI(pi2) (((pi2) & 0xF0) >> 4)
78#define DIGITAL_ATS_MAX_FSC 256 97#define DIGITAL_ATS_MAX_FSC 256
79 98
80#define DIGITAL_RATS_BYTE1 0xE0 99#define DIGITAL_RATS_BYTE1 0xE0
@@ -92,6 +111,32 @@ struct digital_sel_req {
92 u8 bcc; 111 u8 bcc;
93} __packed; 112} __packed;
94 113
114struct digital_sensb_req {
115 u8 cmd;
116 u8 afi;
117 u8 param;
118} __packed;
119
120struct digital_sensb_res {
121 u8 cmd;
122 u8 nfcid0[4];
123 u8 app_data[4];
124 u8 proto_info[3];
125} __packed;
126
127struct digital_attrib_req {
128 u8 cmd;
129 u8 nfcid0[4];
130 u8 param1;
131 u8 param2;
132 u8 param3;
133 u8 param4;
134} __packed;
135
136struct digital_attrib_res {
137 u8 mbli_did;
138} __packed;
139
95struct digital_sensf_req { 140struct digital_sensf_req {
96 u8 cmd; 141 u8 cmd;
97 u8 sc1; 142 u8 sc1;
@@ -531,6 +576,175 @@ int digital_in_recv_mifare_res(struct sk_buff *resp)
531 return -EIO; 576 return -EIO;
532} 577}
533 578
579static void digital_in_recv_attrib_res(struct nfc_digital_dev *ddev, void *arg,
580 struct sk_buff *resp)
581{
582 struct nfc_target *target = arg;
583 struct digital_attrib_res *attrib_res;
584 int rc;
585
586 if (IS_ERR(resp)) {
587 rc = PTR_ERR(resp);
588 resp = NULL;
589 goto exit;
590 }
591
592 if (resp->len < sizeof(*attrib_res)) {
593 PROTOCOL_ERR("12.6.2");
594 rc = -EIO;
595 goto exit;
596 }
597
598 attrib_res = (struct digital_attrib_res *)resp->data;
599
600 if (attrib_res->mbli_did & 0x0f) {
601 PROTOCOL_ERR("12.6.2.1");
602 rc = -EIO;
603 goto exit;
604 }
605
606 rc = digital_target_found(ddev, target, NFC_PROTO_ISO14443_B);
607
608exit:
609 dev_kfree_skb(resp);
610 kfree(target);
611
612 if (rc)
613 digital_poll_next_tech(ddev);
614}
615
616int digital_in_send_attrib_req(struct nfc_digital_dev *ddev,
617 struct nfc_target *target,
618 struct digital_sensb_res *sensb_res)
619{
620 struct digital_attrib_req *attrib_req;
621 struct sk_buff *skb;
622 int rc;
623
624 skb = digital_skb_alloc(ddev, sizeof(*attrib_req));
625 if (!skb)
626 return -ENOMEM;
627
628 attrib_req = (struct digital_attrib_req *)skb_put(skb,
629 sizeof(*attrib_req));
630
631 attrib_req->cmd = DIGITAL_CMD_ATTRIB_REQ;
632 memcpy(attrib_req->nfcid0, sensb_res->nfcid0,
633 sizeof(attrib_req->nfcid0));
634 attrib_req->param1 = DIGITAL_ATTRIB_P1_TR0_DEFAULT |
635 DIGITAL_ATTRIB_P1_TR1_DEFAULT;
636 attrib_req->param2 = DIGITAL_ATTRIB_P2_LISTEN_POLL_1 |
637 DIGITAL_ATTRIB_P2_POLL_LISTEN_1 |
638 DIGITAL_ATTRIB_P2_MAX_FRAME_256;
639 attrib_req->param3 = sensb_res->proto_info[1] & 0x07;
640 attrib_req->param4 = DIGITAL_ATTRIB_P4_DID(0);
641
642 rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_attrib_res,
643 target);
644 if (rc)
645 kfree_skb(skb);
646
647 return rc;
648}
649
650static void digital_in_recv_sensb_res(struct nfc_digital_dev *ddev, void *arg,
651 struct sk_buff *resp)
652{
653 struct nfc_target *target = NULL;
654 struct digital_sensb_res *sensb_res;
655 u8 fsci;
656 int rc;
657
658 if (IS_ERR(resp)) {
659 rc = PTR_ERR(resp);
660 resp = NULL;
661 goto exit;
662 }
663
664 if (resp->len != sizeof(*sensb_res)) {
665 PROTOCOL_ERR("5.6.2.1");
666 rc = -EIO;
667 goto exit;
668 }
669
670 sensb_res = (struct digital_sensb_res *)resp->data;
671
672 if (sensb_res->cmd != DIGITAL_CMD_SENSB_RES) {
673 PROTOCOL_ERR("5.6.2");
674 rc = -EIO;
675 goto exit;
676 }
677
678 if (!(sensb_res->proto_info[1] & BIT(0))) {
679 PROTOCOL_ERR("5.6.2.12");
680 rc = -EIO;
681 goto exit;
682 }
683
684 if (sensb_res->proto_info[1] & BIT(3)) {
685 PROTOCOL_ERR("5.6.2.16");
686 rc = -EIO;
687 goto exit;
688 }
689
690 fsci = DIGITAL_SENSB_FSCI(sensb_res->proto_info[1]);
691 if (fsci >= 8)
692 ddev->target_fsc = DIGITAL_ATS_MAX_FSC;
693 else
694 ddev->target_fsc = digital_ats_fsc[fsci];
695
696 target = kzalloc(sizeof(struct nfc_target), GFP_KERNEL);
697 if (!target) {
698 rc = -ENOMEM;
699 goto exit;
700 }
701
702 rc = digital_in_send_attrib_req(ddev, target, sensb_res);
703
704exit:
705 dev_kfree_skb(resp);
706
707 if (rc) {
708 kfree(target);
709 digital_poll_next_tech(ddev);
710 }
711}
712
713int digital_in_send_sensb_req(struct nfc_digital_dev *ddev, u8 rf_tech)
714{
715 struct digital_sensb_req *sensb_req;
716 struct sk_buff *skb;
717 int rc;
718
719 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
720 NFC_DIGITAL_RF_TECH_106B);
721 if (rc)
722 return rc;
723
724 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
725 NFC_DIGITAL_FRAMING_NFCB);
726 if (rc)
727 return rc;
728
729 skb = digital_skb_alloc(ddev, sizeof(*sensb_req));
730 if (!skb)
731 return -ENOMEM;
732
733 sensb_req = (struct digital_sensb_req *)skb_put(skb,
734 sizeof(*sensb_req));
735
736 sensb_req->cmd = DIGITAL_CMD_SENSB_REQ;
737 sensb_req->afi = 0x00; /* All families and sub-families */
738 sensb_req->param = DIGITAL_SENSB_N(0);
739
740 rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sensb_res,
741 NULL);
742 if (rc)
743 kfree_skb(skb);
744
745 return rc;
746}
747
534static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg, 748static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg,
535 struct sk_buff *resp) 749 struct sk_buff *resp)
536{ 750{