NFC: Extend and fix the internal secure element API
authorSamuel Ortiz <sameo@linux.intel.com>
Fri, 10 May 2013 09:57:06 +0000 (11:57 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 14 Jun 2013 11:44:53 +0000 (13:44 +0200)
Secure elements need to be discovered after enabling the NFC controller.
This is typically done by the NCI core and the HCI drivers (HCI does not
specify how to discover SEs, it is left to the specific drivers).
Also, the SE enable/disable API explicitely takes a SE index as its
argument.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
include/net/nfc/hci.h
include/net/nfc/nfc.h
net/nfc/core.c
net/nfc/hci/core.c
net/nfc/nci/core.c

index eca8846a63d6ebca22568040c965c740733091a7..0af851c3b038186357b8576ec4025bb5193ee1fd 100644 (file)
@@ -59,9 +59,10 @@ struct nfc_hci_ops {
                              struct nfc_target *target);
        int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
                              struct sk_buff *skb);
-       int (*enable_se)(struct nfc_dev *dev, u32 secure_element);
-       int (*disable_se)(struct nfc_dev *dev, u32 secure_element);
        int (*fw_upload)(struct nfc_hci_dev *hdev, const char *firmware_name);
+       int (*discover_se)(struct nfc_hci_dev *dev);
+       int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx);
+       int (*disable_se)(struct nfc_hci_dev *dev, u32 se_idx);
 };
 
 /* Pipes */
index 9900c0f5d6bde9857df8afac5eca4271184193e0..5187ec70b66a710fd34ca7d69938d23b8784d597 100644 (file)
@@ -68,9 +68,12 @@ struct nfc_ops {
                             void *cb_context);
        int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb);
        int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target);
-       int (*enable_se)(struct nfc_dev *dev, u32 secure_element);
-       int (*disable_se)(struct nfc_dev *dev, u32 secure_element);
        int (*fw_upload)(struct nfc_dev *dev, const char *firmware_name);
+
+       /* Secure Element API */
+       int (*discover_se)(struct nfc_dev *dev);
+       int (*enable_se)(struct nfc_dev *dev, u32 se_idx);
+       int (*disable_se)(struct nfc_dev *dev, u32 se_idx);
 };
 
 #define NFC_TARGET_IDX_ANY -1
index 334954a1d6e86476b5bb04505d20f157ed820bef..a43a56d7f4beea5d5d16d9bd0ac4763e8511eb3a 100644 (file)
@@ -126,6 +126,13 @@ int nfc_dev_up(struct nfc_dev *dev)
        if (!rc)
                dev->dev_up = true;
 
+       /* We have to enable the device before discovering SEs */
+       if (dev->ops->discover_se) {
+               rc = dev->ops->discover_se(dev);
+               if (!rc)
+                       pr_warn("SE discovery failed\n");
+       }
+
 error:
        device_unlock(&dev->dev);
        return rc;
index 9c8a63d341d3abc9d191207a7048137142836c3d..7b1c186736ebf924977ed8eb9040357ab88f3c3c 100644 (file)
@@ -692,6 +692,36 @@ static int hci_check_presence(struct nfc_dev *nfc_dev,
        return hdev->ops->check_presence(hdev, target);
 }
 
+static int hci_discover_se(struct nfc_dev *nfc_dev)
+{
+       struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
+
+       if (hdev->ops->discover_se)
+               return hdev->ops->discover_se(hdev);
+
+       return 0;
+}
+
+static int hci_enable_se(struct nfc_dev *nfc_dev, u32 se_idx)
+{
+       struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
+
+       if (hdev->ops->enable_se)
+               return hdev->ops->enable_se(hdev, se_idx);
+
+       return 0;
+}
+
+static int hci_disable_se(struct nfc_dev *nfc_dev, u32 se_idx)
+{
+       struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
+
+       if (hdev->ops->disable_se)
+               return hdev->ops->enable_se(hdev, se_idx);
+
+       return 0;
+}
+
 static void nfc_hci_failure(struct nfc_hci_dev *hdev, int err)
 {
        mutex_lock(&hdev->msg_tx_mutex);
@@ -802,6 +832,9 @@ static struct nfc_ops hci_nfc_ops = {
        .tm_send = hci_tm_send,
        .check_presence = hci_check_presence,
        .fw_upload = hci_fw_upload,
+       .discover_se = hci_discover_se,
+       .enable_se = hci_enable_se,
+       .disable_se = hci_disable_se,
 };
 
 struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
index 145bad15e1131bd23f327abb0b8b45b22e56405b..b943d46a1644324757bd60950a07eb02cc50f7ac 100644 (file)
@@ -636,6 +636,21 @@ static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
        return rc;
 }
 
+static int nci_enable_se(struct nfc_dev *nfc_dev, u32 se_idx)
+{
+       return 0;
+}
+
+static int nci_disable_se(struct nfc_dev *nfc_dev, u32 se_idx)
+{
+       return 0;
+}
+
+static int nci_discover_se(struct nfc_dev *nfc_dev)
+{
+       return 0;
+}
+
 static struct nfc_ops nci_nfc_ops = {
        .dev_up = nci_dev_up,
        .dev_down = nci_dev_down,
@@ -646,6 +661,9 @@ static struct nfc_ops nci_nfc_ops = {
        .activate_target = nci_activate_target,
        .deactivate_target = nci_deactivate_target,
        .im_transceive = nci_transceive,
+       .enable_se = nci_enable_se,
+       .disable_se = nci_disable_se,
+       .discover_se = nci_discover_se,
 };
 
 /* ---- Interface to NCI drivers ---- */