NFC: Implement HCI DEP send and receive data
authorArron Wang <arron.wang@intel.com>
Thu, 27 Sep 2012 09:32:58 +0000 (17:32 +0800)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 26 Oct 2012 16:26:46 +0000 (18:26 +0200)
And implement the corresponding hooks for pn544.

Signed-off-by: Arron Wang <arron.wang@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/nfc/pn544_hci.c
include/net/nfc/hci.h
net/nfc/hci/core.c

index 4ed2b8356017dc70c870f899742510bbd87cf252..554faf0a92d7fa5b1ef66deba6ac32a63f4c80b2 100644 (file)
@@ -900,7 +900,7 @@ static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb,
  * <= 0: driver handled the data exchange
  *    1: driver doesn't especially handle, please do standard processing
  */
-static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev,
+static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev,
                                   struct nfc_target *target,
                                   struct sk_buff *skb, data_exchange_cb_t cb,
                                   void *cb_context)
@@ -953,11 +953,26 @@ static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev,
                return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
                                              PN544_JEWEL_RAW_CMD, skb->data,
                                              skb->len, cb, cb_context);
+       case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
+               *skb_push(skb, 1) = 0;
+
+               return nfc_hci_send_event(hdev, target->hci_reader_gate,
+                                       PN544_HCI_EVT_SND_DATA, skb->data,
+                                       skb->len);
        default:
                return 1;
        }
 }
 
+static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
+{
+       /* Set default false for multiple information chaining */
+       *skb_push(skb, 1) = 0;
+
+       return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
+                               PN544_HCI_EVT_SND_DATA, skb->data, skb->len);
+}
+
 static int pn544_hci_check_presence(struct nfc_hci_dev *hdev,
                                   struct nfc_target *target)
 {
@@ -996,6 +1011,22 @@ void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event,
                nfc_hci_send_event(hdev, gate,
                        NFC_HCI_EVT_END_OPERATION, NULL, 0);
                break;
+       case PN544_HCI_EVT_RCV_DATA:
+               if (skb->len < 2) {
+                       r = -EPROTO;
+                       goto exit;
+               }
+
+               if (skb->data[0] != 0) {
+                       pr_debug("data0 %d", skb->data[0]);
+                       r = -EPROTO;
+                       goto exit;
+               }
+
+               skb_pull(skb, 2);
+               nfc_tm_data_received(hdev->ndev, skb);
+
+               return;
        default:
                break;
        }
@@ -1014,7 +1045,8 @@ static struct nfc_hci_ops pn544_hci_ops = {
        .dep_link_down = pn544_hci_dep_link_down,
        .target_from_gate = pn544_hci_target_from_gate,
        .complete_target_discovered = pn544_hci_complete_target_discovered,
-       .data_exchange = pn544_hci_data_exchange,
+       .im_transceive = pn544_hci_im_transceive,
+       .tm_send = pn544_hci_tm_send,
        .check_presence = pn544_hci_check_presence,
        .event_received = pn544_hci_event_received,
 };
index 6b2d75dc7c01c9a21c781469c08355731045ffec..bc87b8f2d692f4d862a45c0f623f6c2a431ce524 100644 (file)
@@ -45,9 +45,10 @@ struct nfc_hci_ops {
                                 struct nfc_target *target);
        int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
                                           struct nfc_target *target);
-       int (*data_exchange) (struct nfc_hci_dev *hdev,
+       int (*im_transceive) (struct nfc_hci_dev *hdev,
                              struct nfc_target *target, struct sk_buff *skb,
                              data_exchange_cb_t cb, void *cb_context);
+       int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
        int (*check_presence)(struct nfc_hci_dev *hdev,
                              struct nfc_target *target);
        void (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
index 777deb84aa7358c048e3323a46bf5b1e3250e5bd..c2339c468d917dbd04b39e15cad86cd225ea85b0 100644 (file)
@@ -616,8 +616,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
        switch (target->hci_reader_gate) {
        case NFC_HCI_RF_READER_A_GATE:
        case NFC_HCI_RF_READER_B_GATE:
-               if (hdev->ops->data_exchange) {
-                       r = hdev->ops->data_exchange(hdev, target, skb, cb,
+               if (hdev->ops->im_transceive) {
+                       r = hdev->ops->im_transceive(hdev, target, skb, cb,
                                                     cb_context);
                        if (r <= 0)     /* handled */
                                break;
@@ -634,8 +634,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
                                           skb->len, hci_transceive_cb, hdev);
                break;
        default:
-               if (hdev->ops->data_exchange) {
-                       r = hdev->ops->data_exchange(hdev, target, skb, cb,
+               if (hdev->ops->im_transceive) {
+                       r = hdev->ops->im_transceive(hdev, target, skb, cb,
                                                     cb_context);
                        if (r == 1)
                                r = -ENOTSUPP;
@@ -650,6 +650,16 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
        return r;
 }
 
+int hci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
+{
+       struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
+
+       if (hdev->ops->tm_send)
+               return hdev->ops->tm_send(hdev, skb);
+       else
+               return -ENOTSUPP;
+}
+
 static int hci_check_presence(struct nfc_dev *nfc_dev,
                              struct nfc_target *target)
 {
@@ -758,6 +768,7 @@ static struct nfc_ops hci_nfc_ops = {
        .activate_target = hci_activate_target,
        .deactivate_target = hci_deactivate_target,
        .im_transceive = hci_transceive,
+       .tm_send = hci_tm_send,
        .check_presence = hci_check_presence,
 };