aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/nci/ntf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/nci/ntf.c')
-rw-r--r--net/nfc/nci/ntf.c77
1 files changed, 67 insertions, 10 deletions
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 22e453cb787d..3218071072ac 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -43,6 +43,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
43 struct sk_buff *skb) 43 struct sk_buff *skb)
44{ 44{
45 struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; 45 struct nci_core_conn_credit_ntf *ntf = (void *) skb->data;
46 struct nci_conn_info *conn_info;
46 int i; 47 int i;
47 48
48 pr_debug("num_entries %d\n", ntf->num_entries); 49 pr_debug("num_entries %d\n", ntf->num_entries);
@@ -59,11 +60,13 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
59 i, ntf->conn_entries[i].conn_id, 60 i, ntf->conn_entries[i].conn_id,
60 ntf->conn_entries[i].credits); 61 ntf->conn_entries[i].credits);
61 62
62 if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { 63 conn_info = nci_get_conn_info_by_conn_id(ndev,
63 /* found static rf connection */ 64 ntf->conn_entries[i].conn_id);
64 atomic_add(ntf->conn_entries[i].credits, 65 if (!conn_info)
65 &ndev->credits_cnt); 66 return;
66 } 67
68 atomic_add(ntf->conn_entries[i].credits,
69 &conn_info->credits_cnt);
67 } 70 }
68 71
69 /* trigger the next tx */ 72 /* trigger the next tx */
@@ -96,7 +99,7 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
96 99
97 /* complete the data exchange transaction, if exists */ 100 /* complete the data exchange transaction, if exists */
98 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) 101 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
99 nci_data_exchange_complete(ndev, NULL, -EIO); 102 nci_data_exchange_complete(ndev, NULL, ntf->conn_id, -EIO);
100} 103}
101 104
102static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, 105static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
@@ -513,6 +516,7 @@ static int nci_store_general_bytes_nfc_dep(struct nci_dev *ndev,
513static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, 516static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
514 struct sk_buff *skb) 517 struct sk_buff *skb)
515{ 518{
519 struct nci_conn_info *conn_info;
516 struct nci_rf_intf_activated_ntf ntf; 520 struct nci_rf_intf_activated_ntf ntf;
517 __u8 *data = skb->data; 521 __u8 *data = skb->data;
518 int err = NCI_STATUS_OK; 522 int err = NCI_STATUS_OK;
@@ -537,6 +541,13 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
537 pr_debug("rf_tech_specific_params_len %d\n", 541 pr_debug("rf_tech_specific_params_len %d\n",
538 ntf.rf_tech_specific_params_len); 542 ntf.rf_tech_specific_params_len);
539 543
544 /* If this contains a value of 0x00 (NFCEE Direct RF
545 * Interface) then all following parameters SHALL contain a
546 * value of 0 and SHALL be ignored.
547 */
548 if (ntf.rf_interface == NCI_RF_INTERFACE_NFCEE_DIRECT)
549 goto listen;
550
540 if (ntf.rf_tech_specific_params_len > 0) { 551 if (ntf.rf_tech_specific_params_len > 0) {
541 switch (ntf.activation_rf_tech_and_mode) { 552 switch (ntf.activation_rf_tech_and_mode) {
542 case NCI_NFC_A_PASSIVE_POLL_MODE: 553 case NCI_NFC_A_PASSIVE_POLL_MODE:
@@ -614,11 +625,16 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
614 625
615exit: 626exit:
616 if (err == NCI_STATUS_OK) { 627 if (err == NCI_STATUS_OK) {
617 ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size; 628 conn_info = ndev->rf_conn_info;
618 ndev->initial_num_credits = ntf.initial_num_credits; 629 if (!conn_info)
630 return;
631
632 conn_info->max_pkt_payload_len = ntf.max_data_pkt_payload_size;
633 conn_info->initial_num_credits = ntf.initial_num_credits;
619 634
620 /* set the available credits to initial value */ 635 /* set the available credits to initial value */
621 atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); 636 atomic_set(&conn_info->credits_cnt,
637 conn_info->initial_num_credits);
622 638
623 /* store general bytes to be reported later in dep_link_up */ 639 /* store general bytes to be reported later in dep_link_up */
624 if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) { 640 if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) {
@@ -643,6 +659,7 @@ exit:
643 nci_req_complete(ndev, err); 659 nci_req_complete(ndev, err);
644 } 660 }
645 } else { 661 } else {
662listen:
646 /* Listen mode */ 663 /* Listen mode */
647 atomic_set(&ndev->state, NCI_LISTEN_ACTIVE); 664 atomic_set(&ndev->state, NCI_LISTEN_ACTIVE);
648 if (err == NCI_STATUS_OK && 665 if (err == NCI_STATUS_OK &&
@@ -661,10 +678,15 @@ exit:
661static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, 678static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
662 struct sk_buff *skb) 679 struct sk_buff *skb)
663{ 680{
681 struct nci_conn_info *conn_info;
664 struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; 682 struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
665 683
666 pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason); 684 pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
667 685
686 conn_info = ndev->rf_conn_info;
687 if (!conn_info)
688 return;
689
668 /* drop tx data queue */ 690 /* drop tx data queue */
669 skb_queue_purge(&ndev->tx_q); 691 skb_queue_purge(&ndev->tx_q);
670 692
@@ -676,7 +698,8 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
676 698
677 /* complete the data exchange transaction, if exists */ 699 /* complete the data exchange transaction, if exists */
678 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) 700 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
679 nci_data_exchange_complete(ndev, NULL, -EIO); 701 nci_data_exchange_complete(ndev, NULL, NCI_STATIC_RF_CONN_ID,
702 -EIO);
680 703
681 switch (ntf->type) { 704 switch (ntf->type) {
682 case NCI_DEACTIVATE_TYPE_IDLE_MODE: 705 case NCI_DEACTIVATE_TYPE_IDLE_MODE:
@@ -696,6 +719,32 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
696 nci_req_complete(ndev, NCI_STATUS_OK); 719 nci_req_complete(ndev, NCI_STATUS_OK);
697} 720}
698 721
722static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev,
723 struct sk_buff *skb)
724{
725 u8 status = NCI_STATUS_OK;
726 struct nci_nfcee_discover_ntf *nfcee_ntf =
727 (struct nci_nfcee_discover_ntf *)skb->data;
728
729 pr_debug("\n");
730
731 /* NFCForum NCI 9.2.1 HCI Network Specific Handling
732 * If the NFCC supports the HCI Network, it SHALL return one,
733 * and only one, NFCEE_DISCOVER_NTF with a Protocol type of
734 * “HCI Access”, even if the HCI Network contains multiple NFCEEs.
735 */
736 ndev->hci_dev->nfcee_id = nfcee_ntf->nfcee_id;
737 ndev->cur_id = nfcee_ntf->nfcee_id;
738
739 nci_req_complete(ndev, status);
740}
741
742static void nci_nfcee_action_ntf_packet(struct nci_dev *ndev,
743 struct sk_buff *skb)
744{
745 pr_debug("\n");
746}
747
699void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) 748void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
700{ 749{
701 __u16 ntf_opcode = nci_opcode(skb->data); 750 __u16 ntf_opcode = nci_opcode(skb->data);
@@ -734,6 +783,14 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
734 nci_rf_deactivate_ntf_packet(ndev, skb); 783 nci_rf_deactivate_ntf_packet(ndev, skb);
735 break; 784 break;
736 785
786 case NCI_OP_NFCEE_DISCOVER_NTF:
787 nci_nfcee_discover_ntf_packet(ndev, skb);
788 break;
789
790 case NCI_OP_RF_NFCEE_ACTION_NTF:
791 nci_nfcee_action_ntf_packet(ndev, skb);
792 break;
793
737 default: 794 default:
738 pr_err("unknown ntf opcode 0x%x\n", ntf_opcode); 795 pr_err("unknown ntf opcode 0x%x\n", ntf_opcode);
739 break; 796 break;