NFC: nci: Move logical connection structure allocation
[firefly-linux-kernel-4.4.55.git] / net / nfc / nci / ntf.c
index 22e453cb787d4d62e3246919f32ae5db14557ef3..3218071072ac698a85e88fdb5c1b7e6d55a6217d 100644 (file)
@@ -43,6 +43,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
                                             struct sk_buff *skb)
 {
        struct nci_core_conn_credit_ntf *ntf = (void *) skb->data;
+       struct nci_conn_info    *conn_info;
        int i;
 
        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,
                         i, ntf->conn_entries[i].conn_id,
                         ntf->conn_entries[i].credits);
 
-               if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
-                       /* found static rf connection */
-                       atomic_add(ntf->conn_entries[i].credits,
-                                  &ndev->credits_cnt);
-               }
+               conn_info = nci_get_conn_info_by_conn_id(ndev,
+                                                        ntf->conn_entries[i].conn_id);
+               if (!conn_info)
+                       return;
+
+               atomic_add(ntf->conn_entries[i].credits,
+                          &conn_info->credits_cnt);
        }
 
        /* trigger the next tx */
@@ -96,7 +99,7 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
 
        /* complete the data exchange transaction, if exists */
        if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
-               nci_data_exchange_complete(ndev, NULL, -EIO);
+               nci_data_exchange_complete(ndev, NULL, ntf->conn_id, -EIO);
 }
 
 static __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,
 static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
                                             struct sk_buff *skb)
 {
+       struct nci_conn_info    *conn_info;
        struct nci_rf_intf_activated_ntf ntf;
        __u8 *data = skb->data;
        int err = NCI_STATUS_OK;
@@ -537,6 +541,13 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
        pr_debug("rf_tech_specific_params_len %d\n",
                 ntf.rf_tech_specific_params_len);
 
+       /* If this contains a value of 0x00 (NFCEE Direct RF
+        * Interface) then all following parameters SHALL contain a
+        * value of 0 and SHALL be ignored.
+        */
+       if (ntf.rf_interface == NCI_RF_INTERFACE_NFCEE_DIRECT)
+               goto listen;
+
        if (ntf.rf_tech_specific_params_len > 0) {
                switch (ntf.activation_rf_tech_and_mode) {
                case NCI_NFC_A_PASSIVE_POLL_MODE:
@@ -614,11 +625,16 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 
 exit:
        if (err == NCI_STATUS_OK) {
-               ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size;
-               ndev->initial_num_credits = ntf.initial_num_credits;
+               conn_info = ndev->rf_conn_info;
+               if (!conn_info)
+                       return;
+
+               conn_info->max_pkt_payload_len = ntf.max_data_pkt_payload_size;
+               conn_info->initial_num_credits = ntf.initial_num_credits;
 
                /* set the available credits to initial value */
-               atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+               atomic_set(&conn_info->credits_cnt,
+                          conn_info->initial_num_credits);
 
                /* store general bytes to be reported later in dep_link_up */
                if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) {
@@ -643,6 +659,7 @@ exit:
                        nci_req_complete(ndev, err);
                }
        } else {
+listen:
                /* Listen mode */
                atomic_set(&ndev->state, NCI_LISTEN_ACTIVE);
                if (err == NCI_STATUS_OK &&
@@ -661,10 +678,15 @@ exit:
 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
                                         struct sk_buff *skb)
 {
+       struct nci_conn_info    *conn_info;
        struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
 
        pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
 
+       conn_info = ndev->rf_conn_info;
+       if (!conn_info)
+               return;
+
        /* drop tx data queue */
        skb_queue_purge(&ndev->tx_q);
 
@@ -676,7 +698,8 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
 
        /* complete the data exchange transaction, if exists */
        if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
-               nci_data_exchange_complete(ndev, NULL, -EIO);
+               nci_data_exchange_complete(ndev, NULL, NCI_STATIC_RF_CONN_ID,
+                                          -EIO);
 
        switch (ntf->type) {
        case NCI_DEACTIVATE_TYPE_IDLE_MODE:
@@ -696,6 +719,32 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
        nci_req_complete(ndev, NCI_STATUS_OK);
 }
 
+static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev,
+                                         struct sk_buff *skb)
+{
+       u8 status = NCI_STATUS_OK;
+       struct nci_nfcee_discover_ntf   *nfcee_ntf =
+                               (struct nci_nfcee_discover_ntf *)skb->data;
+
+       pr_debug("\n");
+
+       /* NFCForum NCI 9.2.1 HCI Network Specific Handling
+        * If the NFCC supports the HCI Network, it SHALL return one,
+        * and only one, NFCEE_DISCOVER_NTF with a Protocol type of
+        * “HCI Access”, even if the HCI Network contains multiple NFCEEs.
+        */
+       ndev->hci_dev->nfcee_id = nfcee_ntf->nfcee_id;
+       ndev->cur_id = nfcee_ntf->nfcee_id;
+
+       nci_req_complete(ndev, status);
+}
+
+static void nci_nfcee_action_ntf_packet(struct nci_dev *ndev,
+                                       struct sk_buff *skb)
+{
+       pr_debug("\n");
+}
+
 void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
 {
        __u16 ntf_opcode = nci_opcode(skb->data);
@@ -734,6 +783,14 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
                nci_rf_deactivate_ntf_packet(ndev, skb);
                break;
 
+       case NCI_OP_NFCEE_DISCOVER_NTF:
+               nci_nfcee_discover_ntf_packet(ndev, skb);
+               break;
+
+       case NCI_OP_RF_NFCEE_ACTION_NTF:
+               nci_nfcee_action_ntf_packet(ndev, skb);
+               break;
+
        default:
                pr_err("unknown ntf opcode 0x%x\n", ntf_opcode);
                break;