aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@animalcreek.com>2014-01-21 18:23:59 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2014-02-16 17:49:53 -0500
commita381d4828625f526d290b296a829f8549b14ce49 (patch)
treec4b3b6c4df55c7a7660f0e48557409a2f900f583 /net
parente487e4dc2eb227c52fc71eae683181fa917163b8 (diff)
NFC: digital: Add Digital Layer support for ISO/IEC 15693
Add support for ISO/IEC 15693 to the digital layer. The code currently uses single-slot anticollision only since the digital layer infrastructure only supports one tag per adapter (making it pointless to do 16-slot anticollision). The code uses two new framing types: 'NFC_DIGITAL_FRAMING_ISO15693_INVENTORY' and 'NFC_DIGITAL_FRAMING_ISO15693_TVT'. The former is used to tell the driver to prepare for an Inventory command and the ensuing anticollision sequence. The latter is used to tell the driver that the anticollision sequence is over and to prepare for non-inventory commands. Signed-off-by: Mark A. Greer <mgreer@animalcreek.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/nfc/digital.h1
-rw-r--r--net/nfc/digital_core.c14
-rw-r--r--net/nfc/digital_technology.c109
3 files changed, 124 insertions, 0 deletions
diff --git a/net/nfc/digital.h b/net/nfc/digital.h
index 08b29b55ea63..3c757dc7d44f 100644
--- a/net/nfc/digital.h
+++ b/net/nfc/digital.h
@@ -72,6 +72,7 @@ void 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_sensf_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_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech);
75 76
76int digital_target_found(struct nfc_digital_dev *ddev, 77int digital_target_found(struct nfc_digital_dev *ddev,
77 struct nfc_target *target, u8 protocol); 78 struct nfc_target *target, u8 protocol);
diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c
index c129d1571ca6..48906ca60540 100644
--- a/net/nfc/digital_core.c
+++ b/net/nfc/digital_core.c
@@ -25,6 +25,8 @@
25#define DIGITAL_PROTO_NFCF_RF_TECH \ 25#define DIGITAL_PROTO_NFCF_RF_TECH \
26 (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) 26 (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK)
27 27
28#define DIGITAL_PROTO_ISO15693_RF_TECH NFC_PROTO_ISO15693_MASK
29
28struct digital_cmd { 30struct digital_cmd {
29 struct list_head queue; 31 struct list_head queue;
30 32
@@ -331,6 +333,12 @@ int digital_target_found(struct nfc_digital_dev *ddev,
331 } 333 }
332 break; 334 break;
333 335
336 case NFC_PROTO_ISO15693:
337 framing = NFC_DIGITAL_FRAMING_ISO15693_TVT;
338 check_crc = digital_skb_check_crc_b;
339 add_crc = digital_skb_add_crc_b;
340 break;
341
334 default: 342 default:
335 pr_err("Invalid protocol %d\n", protocol); 343 pr_err("Invalid protocol %d\n", protocol);
336 return -EINVAL; 344 return -EINVAL;
@@ -469,6 +477,10 @@ static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols,
469 digital_in_send_sensf_req); 477 digital_in_send_sensf_req);
470 } 478 }
471 479
480 if (matching_im_protocols & DIGITAL_PROTO_ISO15693_RF_TECH)
481 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_ISO15693,
482 digital_in_send_iso15693_inv_req);
483
472 if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { 484 if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
473 if (ddev->ops->tg_listen_mdaa) { 485 if (ddev->ops->tg_listen_mdaa) {
474 digital_add_poll_tech(ddev, 0, 486 digital_add_poll_tech(ddev, 0,
@@ -700,6 +712,8 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
700 ddev->protocols |= NFC_PROTO_FELICA_MASK; 712 ddev->protocols |= NFC_PROTO_FELICA_MASK;
701 if (supported_protocols & NFC_PROTO_NFC_DEP_MASK) 713 if (supported_protocols & NFC_PROTO_NFC_DEP_MASK)
702 ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; 714 ddev->protocols |= NFC_PROTO_NFC_DEP_MASK;
715 if (supported_protocols & NFC_PROTO_ISO15693_MASK)
716 ddev->protocols |= NFC_PROTO_ISO15693_MASK;
703 717
704 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; 718 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN;
705 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; 719 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN;
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index 251c8c753ebe..97d3f602fc06 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -51,6 +51,15 @@
51#define DIGITAL_SENSF_REQ_RC_SC 1 51#define DIGITAL_SENSF_REQ_RC_SC 1
52#define DIGITAL_SENSF_REQ_RC_AP 2 52#define DIGITAL_SENSF_REQ_RC_AP 2
53 53
54#define DIGITAL_CMD_ISO15693_INVENTORY_REQ 0x01
55
56#define DIGITAL_ISO15693_REQ_FLAG_DATA_RATE BIT(1)
57#define DIGITAL_ISO15693_REQ_FLAG_INVENTORY BIT(2)
58#define DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS BIT(5)
59#define DIGITAL_ISO15693_RES_FLAG_ERROR BIT(0)
60#define DIGITAL_ISO15693_RES_IS_VALID(flags) \
61 (!((flags) & DIGITAL_ISO15693_RES_FLAG_ERROR))
62
54struct digital_sdd_res { 63struct digital_sdd_res {
55 u8 nfcid1[4]; 64 u8 nfcid1[4];
56 u8 bcc; 65 u8 bcc;
@@ -82,6 +91,19 @@ struct digital_sensf_res {
82 u8 rd[2]; 91 u8 rd[2];
83} __packed; 92} __packed;
84 93
94struct digital_iso15693_inv_req {
95 u8 flags;
96 u8 cmd;
97 u8 mask_len;
98 u64 mask;
99} __packed;
100
101struct digital_iso15693_inv_res {
102 u8 flags;
103 u8 dsfid;
104 u64 uid;
105} __packed;
106
85static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, 107static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev,
86 struct nfc_target *target); 108 struct nfc_target *target);
87 109
@@ -473,6 +495,93 @@ int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech)
473 return rc; 495 return rc;
474} 496}
475 497
498static void digital_in_recv_iso15693_inv_res(struct nfc_digital_dev *ddev,
499 void *arg, struct sk_buff *resp)
500{
501 struct digital_iso15693_inv_res *res;
502 struct nfc_target *target = NULL;
503 int rc;
504
505 if (IS_ERR(resp)) {
506 rc = PTR_ERR(resp);
507 resp = NULL;
508 goto out_free_skb;
509 }
510
511 if (resp->len != sizeof(*res)) {
512 rc = -EIO;
513 goto out_free_skb;
514 }
515
516 res = (struct digital_iso15693_inv_res *)resp->data;
517
518 if (!DIGITAL_ISO15693_RES_IS_VALID(res->flags)) {
519 PROTOCOL_ERR("ISO15693 - 10.3.1");
520 rc = -EINVAL;
521 goto out_free_skb;
522 }
523
524 target = kzalloc(sizeof(*target), GFP_KERNEL);
525 if (!target) {
526 rc = -ENOMEM;
527 goto out_free_skb;
528 }
529
530 target->is_iso15693 = 1;
531 target->iso15693_dsfid = res->dsfid;
532 memcpy(target->iso15693_uid, &res->uid, sizeof(target->iso15693_uid));
533
534 rc = digital_target_found(ddev, target, NFC_PROTO_ISO15693);
535
536 kfree(target);
537
538out_free_skb:
539 dev_kfree_skb(resp);
540
541 if (rc)
542 digital_poll_next_tech(ddev);
543}
544
545int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech)
546{
547 struct digital_iso15693_inv_req *req;
548 struct sk_buff *skb;
549 int rc;
550
551 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
552 NFC_DIGITAL_RF_TECH_ISO15693);
553 if (rc)
554 return rc;
555
556 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
557 NFC_DIGITAL_FRAMING_ISO15693_INVENTORY);
558 if (rc)
559 return rc;
560
561 skb = digital_skb_alloc(ddev, sizeof(*req));
562 if (!skb)
563 return -ENOMEM;
564
565 skb_put(skb, sizeof(*req) - sizeof(req->mask)); /* No mask */
566 req = (struct digital_iso15693_inv_req *)skb->data;
567
568 /* Single sub-carrier, high data rate, no AFI, single slot
569 * Inventory command
570 */
571 req->flags = DIGITAL_ISO15693_REQ_FLAG_DATA_RATE |
572 DIGITAL_ISO15693_REQ_FLAG_INVENTORY |
573 DIGITAL_ISO15693_REQ_FLAG_NB_SLOTS;
574 req->cmd = DIGITAL_CMD_ISO15693_INVENTORY_REQ;
575 req->mask_len = 0;
576
577 rc = digital_in_send_cmd(ddev, skb, 30,
578 digital_in_recv_iso15693_inv_res, NULL);
579 if (rc)
580 kfree_skb(skb);
581
582 return rc;
583}
584
476static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev) 585static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev)
477{ 586{
478 struct sk_buff *skb; 587 struct sk_buff *skb;